From 1e9c6bd76fac1a0b721b14ecbc9a72d8f04183bd Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 9 Apr 2018 07:58:54 +0200 Subject: [PATCH 01/21] Implement extractors for TASTY trees * Define TASTY data types in scala.tasty * Add method get a TASTY term from a quoted.Expr[T] * Implement TASTY tree extractors --- .../dotty/tools/dotc/core/Definitions.scala | 6 + .../dotc/core/quoted/PickledQuotes.scala | 4 +- .../tools/dotc/core/tasty/TreeUnpickler.scala | 5 +- ...ExprCompiler.scala => QuoteCompiler.scala} | 19 +- ...Decompiler.scala => QuoteDecompiler.scala} | 8 +- .../dotty/tools/dotc/quoted/QuoteDriver.scala | 18 +- .../src/dotty/tools/dotc/quoted/Toolbox.scala | 16 - .../dotc/quoted/TypeCompilationUnit.scala | 11 + .../tasty/internal/AnnotationModifier.scala | 20 + .../tools/dotc/tasty/internal/CaseDef.scala | 22 + .../tools/dotc/tasty/internal/ClassDef.scala | 48 ++ .../tools/dotc/tasty/internal/Constant.scala | 58 ++ .../tools/dotc/tasty/internal/DefDef.scala | 29 + .../dotc/tasty/internal/Definition.scala | 56 ++ .../dotc/tasty/internal/FlagsModifier.scala | 82 +++ .../dotty/tools/dotc/tasty/internal/Id.scala | 18 + .../tools/dotc/tasty/internal/Import.scala | 22 + .../dotc/tasty/internal/ImportSelector.scala | 35 ++ .../dotc/tasty/internal/LambdaType.scala | 16 + .../tools/dotc/tasty/internal/MaybeType.scala | 15 + .../dotc/tasty/internal/MethodType.scala | 27 + .../tools/dotc/tasty/internal/Modifiers.scala | 17 + .../tools/dotc/tasty/internal/Name.scala | 14 + .../dotc/tasty/internal/PackageClause.scala | 27 + .../dotc/tasty/internal/PackageDef.scala | 36 ++ .../tools/dotc/tasty/internal/Pattern.scala | 49 ++ .../tools/dotc/tasty/internal/PolyType.scala | 23 + .../tools/dotc/tasty/internal/Position.scala | 18 + .../dotc/tasty/internal/Positioned.scala | 9 + .../tasty/internal/PossiblySignedName.scala | 13 + .../tasty/internal/QualifiedModifier.scala | 28 + .../dotc/tasty/internal/RecursiveType.scala | 21 + .../dotc/tasty/internal/SignedName.scala | 25 + .../tools/dotc/tasty/internal/Statement.scala | 15 + .../dotc/tasty/internal/TastyContext.scala | 19 + .../tools/dotc/tasty/internal/Term.scala | 129 +++++ .../tools/dotc/tasty/internal/TermName.scala | 63 +++ .../tools/dotc/tasty/internal/Toolbox.scala | 217 +++++++ .../tasty/internal/TopLevelStatement.scala | 13 + .../dotc/tasty/internal/TreeWithContext.scala | 10 + .../tools/dotc/tasty/internal/Type.scala | 100 ++++ .../dotc/tasty/internal/TypeBounds.scala | 20 + .../dotc/tasty/internal/TypeBoundsTree.scala | 26 + .../tools/dotc/tasty/internal/TypeDef.scala | 31 + .../dotc/tasty/internal/TypeLambda.scala | 23 + .../tools/dotc/tasty/internal/TypeName.scala | 20 + .../dotc/tasty/internal/TypeOrNoPrefix.scala | 12 + .../tools/dotc/tasty/internal/TypeTree.scala | 76 +++ .../tools/dotc/tasty/internal/ValDef.scala | 31 + .../tools/dotc/transform/ReifyQuotes.scala | 21 +- .../dotty/tools/dotc/transform/Splicer.scala | 9 +- library/src/scala/quoted/Constant.scala | 13 +- library/src/scala/quoted/Expr.scala | 3 + library/src/scala/quoted/Type.scala | 5 +- .../src/scala/runtime/quoted/Toolbox.scala | 6 +- library/src/scala/runtime/tasty/Toolbox.scala | 140 +++++ library/src/scala/tasty/Context.scala | 19 + library/src/scala/tasty/ContextProvider.scala | 13 + library/src/scala/tasty/Id.scala | 5 + library/src/scala/tasty/Position.scala | 13 + library/src/scala/tasty/Positioned.scala | 5 + .../src/scala/tasty/constants/Constant.scala | 5 + .../src/scala/tasty/constants/package.scala | 48 ++ .../scala/tasty/modifiers/Annotation.scala | 9 + .../src/scala/tasty/modifiers/FlagSet.scala | 30 + library/src/scala/tasty/modifiers/Flags.scala | 9 + .../src/scala/tasty/modifiers/Modifier.scala | 3 + .../src/scala/tasty/modifiers/Qualified.scala | 14 + library/src/scala/tasty/names/Name.scala | 3 + .../tasty/names/PossiblySignedName.scala | 3 + .../src/scala/tasty/names/SignedName.scala | 9 + library/src/scala/tasty/names/TermName.scala | 3 + library/src/scala/tasty/names/TypeName.scala | 9 + library/src/scala/tasty/names/package.scala | 52 ++ library/src/scala/tasty/trees/CaseDef.scala | 9 + library/src/scala/tasty/trees/ClassDef.scala | 13 + library/src/scala/tasty/trees/DefDef.scala | 13 + .../src/scala/tasty/trees/Definition.scala | 7 + library/src/scala/tasty/trees/Import.scala | 9 + .../scala/tasty/trees/ImportSelector.scala | 19 + .../src/scala/tasty/trees/PackageClause.scala | 11 + .../src/scala/tasty/trees/PackageDef.scala | 9 + library/src/scala/tasty/trees/Pattern.scala | 33 ++ library/src/scala/tasty/trees/Statement.scala | 3 + library/src/scala/tasty/trees/Term.scala | 9 + .../scala/tasty/trees/TopLevelStatement.scala | 3 + library/src/scala/tasty/trees/Tree.scala | 5 + .../scala/tasty/trees/TypeBoundsTree.scala | 13 + library/src/scala/tasty/trees/TypeDef.scala | 13 + library/src/scala/tasty/trees/TypeTree.scala | 8 + library/src/scala/tasty/trees/ValDef.scala | 13 + library/src/scala/tasty/trees/package.scala | 160 ++++++ .../src/scala/tasty/types/LambdaType.scala | 25 + library/src/scala/tasty/types/MaybeType.scala | 3 + library/src/scala/tasty/types/NoPrefix.scala | 5 + .../src/scala/tasty/types/RecursiveType.scala | 9 + library/src/scala/tasty/types/Type.scala | 3 + .../src/scala/tasty/types/TypeBounds.scala | 9 + library/src/scala/tasty/types/package.scala | 72 +++ .../src/scala/tasty/util/TastyPrinter.scala | 533 ++++++++++++++++++ .../scala/tasty/util/TreeAccumulator.scala | 108 ++++ .../src/scala/tasty/util/TreeTraverser.scala | 14 + .../quote-run-constants-extract-1.scala | 15 - .../quote-run-constants-extract-2.check | 5 - .../quote-run-constants-extract-2.scala | 30 - .../quote-run-constants-extract-3.check | 5 - .../quote-run-constants-extract-3.scala | 30 - .../quote-run-constants-extract-4.check | 5 - .../quote-run-constants-extract-4.scala | 31 - .../quote-run-constants-extract-5.check | 5 - .../quote-run-constants-extract-5.scala | 30 - .../quote-run-constants-extract-6.check | 8 - .../quote-run-constants-extract-6.scala | 31 - tests/run/tasty-extractors-1.check | 120 ++++ tests/run/tasty-extractors-1/quoted_1.scala | 23 + tests/run/tasty-extractors-1/quoted_2.scala | 48 ++ tests/run/tasty-extractors-2.check | 111 ++++ tests/run/tasty-extractors-2/quoted_1.scala | 23 + tests/run/tasty-extractors-2/quoted_2.scala | 50 ++ tests/run/tasty-extractors-3.check | 42 ++ tests/run/tasty-extractors-3/quoted_1.scala | 34 ++ tests/run/tasty-extractors-3/quoted_2.scala | 19 + .../tasty-extractors-constants-1.check} | 0 .../quoted_1.scala | 27 + .../quoted_2.scala | 4 + tests/run/tasty-extractors-constants-2.check | 17 + .../quoted_1.scala | 66 +++ .../quoted_2.scala | 4 + tests/run/tasty-extractors-owners.check | 27 + .../tasty-extractors-owners/quoted_1.scala | 39 ++ .../tasty-extractors-owners/quoted_2.scala | 24 + tests/run/tasty-extractors-types.check | 12 + .../run/tasty-extractors-types/quoted_1.scala | 22 + .../run/tasty-extractors-types/quoted_2.scala | 12 + tests/run/tasty-linenumber.check | 4 + tests/run/tasty-linenumber/quoted_1.scala | 19 + tests/run/tasty-linenumber/quoted_2.scala | 16 + tests/run/tasty-location.check | 6 + tests/run/tasty-location/quoted_1.scala | 38 ++ tests/run/tasty-location/quoted_2.scala | 24 + tests/run/tasty-macro-assert.check | 7 + tests/run/tasty-macro-assert/quoted_1.scala | 78 +++ tests/run/tasty-macro-assert/quoted_2.scala | 11 + tests/run/tasty-positioned.check | 8 + tests/run/tasty-positioned/quoted_1.scala | 30 + tests/run/tasty-positioned/quoted_2.scala | 23 + 146 files changed, 4143 insertions(+), 240 deletions(-) rename compiler/src/dotty/tools/dotc/quoted/{ExprCompiler.scala => QuoteCompiler.scala} (82%) rename compiler/src/dotty/tools/dotc/quoted/{ExprDecompiler.scala => QuoteDecompiler.scala} (57%) create mode 100644 compiler/src/dotty/tools/dotc/quoted/TypeCompilationUnit.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/AnnotationModifier.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/CaseDef.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/ClassDef.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Constant.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/DefDef.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Definition.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/FlagsModifier.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Id.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Import.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/ImportSelector.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/LambdaType.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/MaybeType.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/MethodType.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Modifiers.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Name.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/PackageClause.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/PackageDef.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Pattern.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/PolyType.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Position.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Positioned.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/PossiblySignedName.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/QualifiedModifier.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/RecursiveType.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/SignedName.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Statement.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TastyContext.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Term.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TermName.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Toolbox.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TopLevelStatement.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TreeWithContext.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Type.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeBounds.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeBoundsTree.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeDef.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeLambda.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeName.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeOrNoPrefix.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeTree.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/ValDef.scala create mode 100644 library/src/scala/runtime/tasty/Toolbox.scala create mode 100644 library/src/scala/tasty/Context.scala create mode 100644 library/src/scala/tasty/ContextProvider.scala create mode 100644 library/src/scala/tasty/Id.scala create mode 100644 library/src/scala/tasty/Position.scala create mode 100644 library/src/scala/tasty/Positioned.scala create mode 100644 library/src/scala/tasty/constants/Constant.scala create mode 100644 library/src/scala/tasty/constants/package.scala create mode 100644 library/src/scala/tasty/modifiers/Annotation.scala create mode 100644 library/src/scala/tasty/modifiers/FlagSet.scala create mode 100644 library/src/scala/tasty/modifiers/Flags.scala create mode 100644 library/src/scala/tasty/modifiers/Modifier.scala create mode 100644 library/src/scala/tasty/modifiers/Qualified.scala create mode 100644 library/src/scala/tasty/names/Name.scala create mode 100644 library/src/scala/tasty/names/PossiblySignedName.scala create mode 100644 library/src/scala/tasty/names/SignedName.scala create mode 100644 library/src/scala/tasty/names/TermName.scala create mode 100644 library/src/scala/tasty/names/TypeName.scala create mode 100644 library/src/scala/tasty/names/package.scala create mode 100644 library/src/scala/tasty/trees/CaseDef.scala create mode 100644 library/src/scala/tasty/trees/ClassDef.scala create mode 100644 library/src/scala/tasty/trees/DefDef.scala create mode 100644 library/src/scala/tasty/trees/Definition.scala create mode 100644 library/src/scala/tasty/trees/Import.scala create mode 100644 library/src/scala/tasty/trees/ImportSelector.scala create mode 100644 library/src/scala/tasty/trees/PackageClause.scala create mode 100644 library/src/scala/tasty/trees/PackageDef.scala create mode 100644 library/src/scala/tasty/trees/Pattern.scala create mode 100644 library/src/scala/tasty/trees/Statement.scala create mode 100644 library/src/scala/tasty/trees/Term.scala create mode 100644 library/src/scala/tasty/trees/TopLevelStatement.scala create mode 100644 library/src/scala/tasty/trees/Tree.scala create mode 100644 library/src/scala/tasty/trees/TypeBoundsTree.scala create mode 100644 library/src/scala/tasty/trees/TypeDef.scala create mode 100644 library/src/scala/tasty/trees/TypeTree.scala create mode 100644 library/src/scala/tasty/trees/ValDef.scala create mode 100644 library/src/scala/tasty/trees/package.scala create mode 100644 library/src/scala/tasty/types/LambdaType.scala create mode 100644 library/src/scala/tasty/types/MaybeType.scala create mode 100644 library/src/scala/tasty/types/NoPrefix.scala create mode 100644 library/src/scala/tasty/types/RecursiveType.scala create mode 100644 library/src/scala/tasty/types/Type.scala create mode 100644 library/src/scala/tasty/types/TypeBounds.scala create mode 100644 library/src/scala/tasty/types/package.scala create mode 100644 library/src/scala/tasty/util/TastyPrinter.scala create mode 100644 library/src/scala/tasty/util/TreeAccumulator.scala create mode 100644 library/src/scala/tasty/util/TreeTraverser.scala delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-1.scala delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-2.check delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-2.scala delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-3.check delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-3.scala delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-4.check delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-4.scala delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-5.check delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-5.scala delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-6.check delete mode 100644 tests/run-with-compiler/quote-run-constants-extract-6.scala create mode 100644 tests/run/tasty-extractors-1.check create mode 100644 tests/run/tasty-extractors-1/quoted_1.scala create mode 100644 tests/run/tasty-extractors-1/quoted_2.scala create mode 100644 tests/run/tasty-extractors-2.check create mode 100644 tests/run/tasty-extractors-2/quoted_1.scala create mode 100644 tests/run/tasty-extractors-2/quoted_2.scala create mode 100644 tests/run/tasty-extractors-3.check create mode 100644 tests/run/tasty-extractors-3/quoted_1.scala create mode 100644 tests/run/tasty-extractors-3/quoted_2.scala rename tests/{run-with-compiler/quote-run-constants-extract-1.check => run/tasty-extractors-constants-1.check} (100%) create mode 100644 tests/run/tasty-extractors-constants-1/quoted_1.scala create mode 100644 tests/run/tasty-extractors-constants-1/quoted_2.scala create mode 100644 tests/run/tasty-extractors-constants-2.check create mode 100644 tests/run/tasty-extractors-constants-2/quoted_1.scala create mode 100644 tests/run/tasty-extractors-constants-2/quoted_2.scala create mode 100644 tests/run/tasty-extractors-owners.check create mode 100644 tests/run/tasty-extractors-owners/quoted_1.scala create mode 100644 tests/run/tasty-extractors-owners/quoted_2.scala create mode 100644 tests/run/tasty-extractors-types.check create mode 100644 tests/run/tasty-extractors-types/quoted_1.scala create mode 100644 tests/run/tasty-extractors-types/quoted_2.scala create mode 100644 tests/run/tasty-linenumber.check create mode 100644 tests/run/tasty-linenumber/quoted_1.scala create mode 100644 tests/run/tasty-linenumber/quoted_2.scala create mode 100644 tests/run/tasty-location.check create mode 100644 tests/run/tasty-location/quoted_1.scala create mode 100644 tests/run/tasty-location/quoted_2.scala create mode 100644 tests/run/tasty-macro-assert.check create mode 100644 tests/run/tasty-macro-assert/quoted_1.scala create mode 100644 tests/run/tasty-macro-assert/quoted_2.scala create mode 100644 tests/run/tasty-positioned.check create mode 100644 tests/run/tasty-positioned/quoted_1.scala create mode 100644 tests/run/tasty-positioned/quoted_2.scala diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index b0b847da4e4d..e631b06f0f42 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -667,6 +667,12 @@ class Definitions { def Unpickler_liftedExpr = ctx.requiredMethod("scala.runtime.quoted.Unpickler.liftedExpr") def Unpickler_unpickleType = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType") + lazy val TastyContextModule = ctx.requiredModule("scala.tasty.Context") + def TastyContextModuleClass(implicit ctx: Context) = TastyContextModule.symbol.asClass + + lazy val TastyContext_compilationContextR = TastyContextModule.requiredMethod("compilationContext") + def TastyContext_compilationContext(implicit ctx: Context) = TastyContext_compilationContextR.symbol + lazy val EqType = ctx.requiredClassRef("scala.Eq") def EqClass(implicit ctx: Context) = EqType.symbol.asClass def EqModule(implicit ctx: Context) = EqClass.companionModule diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 717dc343e201..1b87a7547000 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -57,7 +57,7 @@ object PickledQuotes { case expr: LiftedExpr[T] => expr.value match { case value: Class[_] => ref(defn.Predef_classOf).appliedToType(classToType(value)) - case value=> Literal(Constant(value)) + case value => Literal(Constant(value)) } case expr: TreeExpr[Tree] @unchecked => expr.tree case expr: FunctionAppliedTo[_, _] => @@ -68,7 +68,7 @@ object PickledQuotes { def quotedTypeToTree(expr: quoted.Type[_])(implicit ctx: Context): Tree = expr match { case expr: TastyType[_] => unpickleType(expr) case expr: TaggedType[_] => classTagToTypeTree(expr.ct) - case expr: TreeType[Tree] @unchecked => expr.tree + case expr: TreeType[Tree] @unchecked => expr.typeTree } /** Unpickle the tree contained in the TastyExpr */ diff --git a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala index 620dd44f84e9..ce0edf52a31c 100644 --- a/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala +++ b/compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala @@ -1149,7 +1149,10 @@ class TreeUnpickler(reader: TastyReader, val idx = readNat() val args = until(end)(readTerm()) val splice = splices(idx) - val reifiedArgs = args.map(arg => if (arg.isTerm) new TreeExpr(arg, PickledQuotes.pickleExpr(arg)) else new TreeType(arg)) + def wrap(arg: Tree) = + if (arg.isTerm) new TreeExpr(arg, PickledQuotes.pickleExpr(arg)) + else new TreeType(arg) + val reifiedArgs = args.map(wrap) if (isType) { val quotedType = splice.asInstanceOf[Seq[Any] => quoted.Type[_]](reifiedArgs) PickledQuotes.quotedTypeToTree(quotedType) diff --git a/compiler/src/dotty/tools/dotc/quoted/ExprCompiler.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala similarity index 82% rename from compiler/src/dotty/tools/dotc/quoted/ExprCompiler.scala rename to compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala index fb782c031543..1b478fcc4aba 100644 --- a/compiler/src/dotty/tools/dotc/quoted/ExprCompiler.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteCompiler.scala @@ -20,12 +20,12 @@ import dotty.tools.dotc.util.Positions.Position import dotty.tools.dotc.util.SourceFile import dotty.tools.io.{AbstractFile, Path, PlainFile} -import scala.quoted.Expr +import scala.quoted.{Expr, Type} /** Compiler that takes the contents of a quoted expression `expr` and produces * a class file with `class ' { def apply: Object = expr }`. */ -class ExprCompiler(directory: AbstractFile) extends Compiler { +class QuoteCompiler(directory: AbstractFile) extends Compiler { import tpd._ /** A GenBCode phase that outputs to a virtual directory */ @@ -35,7 +35,7 @@ class ExprCompiler(directory: AbstractFile) extends Compiler { } override protected def frontendPhases: List[List[Phase]] = - List(List(new ExprFrontend(putInClass = true))) + List(List(new QuotedFrontend(putInClass = true))) override protected def picklerPhases: List[List[Phase]] = List(List(new ReifyQuotes)) @@ -50,8 +50,8 @@ class ExprCompiler(directory: AbstractFile) extends Compiler { def outputClassName: TypeName = "Quoted".toTypeName - /** Frontend that receives scala.quoted.Expr as input */ - class ExprFrontend(putInClass: Boolean) extends FrontEnd { + /** Frontend that receives a scala.quoted.Expr or scala.quoted.Type as input */ + class QuotedFrontend(putInClass: Boolean) extends FrontEnd { import tpd._ override def isTyper = false @@ -64,6 +64,11 @@ class ExprCompiler(directory: AbstractFile) extends Compiler { else PickledQuotes.quotedExprToTree(exprUnit.expr) val source = new SourceFile("", Seq()) CompilationUnit.mkCompilationUnit(source, tree, forceTrees = true) + case typeUnit: TypeCompilationUnit => + assert(!putInClass) + val tree = PickledQuotes.quotedTypeToTree(typeUnit.tpe) + val source = new SourceFile("", Seq()) + CompilationUnit.mkCompilationUnit(source, tree, forceTrees = true) } } @@ -93,6 +98,10 @@ class ExprCompiler(directory: AbstractFile) extends Compiler { val units = new ExprCompilationUnit(expr) :: Nil compileUnits(units) } + def compileType(tpe: Type[_]): Unit = { + val units = new TypeCompilationUnit(tpe) :: Nil + compileUnits(units) + } } } diff --git a/compiler/src/dotty/tools/dotc/quoted/ExprDecompiler.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteDecompiler.scala similarity index 57% rename from compiler/src/dotty/tools/dotc/quoted/ExprDecompiler.scala rename to compiler/src/dotty/tools/dotc/quoted/QuoteDecompiler.scala index 94813330815c..01d16a3bd596 100644 --- a/compiler/src/dotty/tools/dotc/quoted/ExprDecompiler.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteDecompiler.scala @@ -4,15 +4,15 @@ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Phases.Phase -/** Compiler that takes the contents of a quoted expression `expr` and outputs it's tree. */ -class ExprDecompiler(output: tpd.Tree => Context => Unit) extends ExprCompiler(null) { +/** Compiler that takes the contents of a quoted expression (or type) and outputs it's tree. */ +class QuoteDecompiler(output: tpd.Tree => Context => Unit) extends QuoteCompiler(null) { override def phases: List[List[Phase]] = List( - List(new ExprFrontend(putInClass = false)), // Create class from Expr + List(new QuotedFrontend(putInClass = false)), // Create class from Expr List(new QuoteTreeOutput(output)) ) class QuoteTreeOutput(output: tpd.Tree => Context => Unit) extends Phase { - override def phaseName: String = "quotePrinter" + override def phaseName: String = "quoteOutput" override def run(implicit ctx: Context): Unit = output(ctx.compilationUnit.tpdTree)(ctx) } } diff --git a/compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala index d0077b540107..37361ba2008d 100644 --- a/compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteDriver.scala @@ -7,7 +7,7 @@ import dotty.tools.io.{AbstractFile, Directory, PlainDirectory, VirtualDirectory import dotty.tools.repl.AbstractFileClassLoader import dotty.tools.dotc.printing.DecompilerPrinter -import scala.quoted.Expr +import scala.quoted.{Expr, Type} import java.net.URLClassLoader @@ -28,7 +28,7 @@ class QuoteDriver extends Driver { new VirtualDirectory("(memory)", None) } - val driver = new ExprCompiler(outDir) + val driver = new QuoteCompiler(outDir) driver.newRun(ctx).compileExpr(expr) val classLoader = new AbstractFileClassLoader(outDir, this.getClass.getClassLoader) @@ -58,10 +58,22 @@ class QuoteDriver extends Driver { assert(output.isEmpty) output = Some(f(tree, ctx)) } - new ExprDecompiler(registerTree).newRun(ctx).compileExpr(expr) + new QuoteDecompiler(registerTree).newRun(ctx).compileExpr(expr) output.getOrElse(throw new Exception("Could not extract " + expr)) } + def withTypeTree[T](tpe: Type[_], f: (TypTree, Context) => T, settings: Settings[_]): T = { + val (_, ctx: Context) = setup(settings.compilerArgs.toArray :+ "dummy.scala", initCtx.fresh) + + var output: Option[T] = None + def registerTree(tree: tpd.Tree)(ctx: Context): Unit = { + assert(output.isEmpty) + output = Some(f(tree.asInstanceOf[TypTree], ctx)) + } + new QuoteDecompiler(registerTree).newRun(ctx).compileType(tpe) + output.getOrElse(throw new Exception("Could not extract " + tpe)) + } + override def initCtx: Context = { val ictx = super.initCtx.fresh var classpath = System.getProperty("java.class.path") diff --git a/compiler/src/dotty/tools/dotc/quoted/Toolbox.scala b/compiler/src/dotty/tools/dotc/quoted/Toolbox.scala index b223f63bcb65..59ad7a5070be 100644 --- a/compiler/src/dotty/tools/dotc/quoted/Toolbox.scala +++ b/compiler/src/dotty/tools/dotc/quoted/Toolbox.scala @@ -1,10 +1,7 @@ package dotty.tools.dotc.quoted -import dotty.tools.dotc.ast.Trees._ import dotty.tools.dotc.ast.tpd import dotty.tools.dotc.core.Constants._ -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.quoted.PickledQuotes import dotty.tools.dotc.printing.RefinedPrinter import scala.quoted.Expr @@ -48,19 +45,6 @@ object Toolbox { case _ => new QuoteDriver().show(expr, showSettings) } - def toConstantOpt(expr: Expr[T]): Option[T] = { - def toConstantOpt(tree: Tree): Option[T] = tree match { - case Literal(Constant(c)) => Some(c.asInstanceOf[T]) - case Block(Nil, e) => toConstantOpt(e) - case Inlined(_, Nil, e) => toConstantOpt(e) - case _ => None - } - expr match { - case expr: LiftedExpr[T] => Some(expr.value) - case _ => new QuoteDriver().withTree(expr, (tree, _) => toConstantOpt(tree), Settings.run()) - } - } - } class Settings[T] private (val outDir: Option[String], val rawTree: Boolean, val compilerArgs: List[String]) diff --git a/compiler/src/dotty/tools/dotc/quoted/TypeCompilationUnit.scala b/compiler/src/dotty/tools/dotc/quoted/TypeCompilationUnit.scala new file mode 100644 index 000000000000..d2090b9ec336 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/quoted/TypeCompilationUnit.scala @@ -0,0 +1,11 @@ +package dotty.tools.dotc.quoted + +import dotty.tools.dotc.CompilationUnit +import dotty.tools.dotc.util.NoSource + +import scala.quoted.Type + +/* Compilation unit containing the contents of a quoted type */ +class TypeCompilationUnit(val tpe: Type[_]) extends CompilationUnit(NoSource) { + override def toString = s"Type($tpe)" +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/AnnotationModifier.scala b/compiler/src/dotty/tools/dotc/tasty/internal/AnnotationModifier.scala new file mode 100644 index 000000000000..6d51b20ee9dd --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/AnnotationModifier.scala @@ -0,0 +1,20 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Annotations.Annotation + +import scala.tasty.modifiers + +object AnnotationModifier { + + def apply(tree: Annotation): modifiers.Annotation = new Impl(tree) + + def unapplyAnnotation(arg: Impl)(implicit ctx: Context): Option[modifiers.Annotation.Data] = { + Some(Term(arg.annot.tree)) + } + + private[tasty] class Impl(val annot: Annotation) extends modifiers.Annotation { + override def toString: String = "Annotation" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/CaseDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/CaseDef.scala new file mode 100644 index 000000000000..3f551b5ea171 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/CaseDef.scala @@ -0,0 +1,22 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.Trees +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context + +import scala.tasty.trees + +object CaseDef { + + def apply(tree: tpd.CaseDef): trees.CaseDef = new Impl(tree) + + def unapplyCaseDef(arg: Impl)(implicit ctx: Context): Option[trees.CaseDef.Data] = { + val Trees.CaseDef(pat, guard, body) = arg.tree + Some(Pattern(pat), if (guard.isEmpty) None else Some(Term(guard)), Term(body)) + } + + private[tasty] class Impl(val tree: tpd.CaseDef) extends trees.CaseDef with Positioned { + override def toString: String = "CaseDef" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/ClassDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/ClassDef.scala new file mode 100644 index 000000000000..839a8fa0dc1e --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/ClassDef.scala @@ -0,0 +1,48 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.{Trees, tpd} +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Flags._ +import dotty.tools.dotc.core.Symbols.ClassSymbol + +import scala.tasty.modifiers +import scala.tasty.trees +import scala.tasty.types + +object ClassDef { + + def apply(tree: tpd.TypeDef): trees.ClassDef = new Impl(tree) + + def apply(sym: ClassSymbol)(implicit ctx: Context): trees.ClassDef = { + def toTree(sym: ClassSymbol): tpd.TypeDef = { + val constr = tpd.DefDef(sym.unforcedDecls.find(_.isPrimaryConstructor).asTerm) + val body = sym.unforcedDecls.filter(!_.isPrimaryConstructor).map(s => + if (s.isClass) toTree(s.asClass) + else if (s.isType) tpd.TypeDef(s.asType) + else if (s.is(Method)) tpd.DefDef(s.asTerm) + else tpd.ValDef(s.asTerm) + ) + val superArgs = Nil // TODO + tpd.ClassDef(sym, constr, body, superArgs) + } + new Impl(toTree(sym)) + } + + def unapplyClassDef(arg: Impl)(implicit ctx: Context): Option[trees.ClassDef.Data] = { + val Trees.TypeDef(name, impl@Trees.Template(constr, parents, self, _)) = arg.tree + val className = TypeName(name) + val constructor = DefDef(constr) + val classParents = parents.map(p => if (!p.isType) Term(p) else TypeTree(p)) + val selfVal = if (self.isEmpty) None else Some(ValDef(self)) + val body = impl.body.map(Statement(_)) + Some((className, constructor, classParents, selfVal, body)) + } + + private[tasty] class Impl(val tree: tpd.TypeDef) extends trees.ClassDef with Definition with Positioned { + def tpe: types.Type = Type(tree.tpe) + def mods(implicit ctx: scala.tasty.Context): List[modifiers.Modifier] = Modifiers(tree) + override def toString: String = "ClassDef" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Constant.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Constant.scala new file mode 100644 index 000000000000..300735782cb7 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Constant.scala @@ -0,0 +1,58 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Constants + +import scala.tasty.constants + +object Constant { + + def apply(constant: Constants.Constant): constants.Constant = new Impl(constant) + + def unapplyUnit(arg: Impl): Boolean = arg.const.tag == Constants.UnitTag + + def unapplyNull(arg: Impl): Boolean = arg.const.tag == Constants.NullTag + + def unapplyBoolean(arg: Impl): Option[Boolean] = + if (arg.const.tag == Constants.BooleanTag) Some(arg.const.booleanValue) + else None + + def unapplyByte(arg: Impl): Option[Byte] = + if (arg.const.tag == Constants.ByteTag) Some(arg.const.byteValue) + else None + + def unapplyChar(arg: Impl): Option[Char] = + if (arg.const.tag == Constants.CharTag) Some(arg.const.charValue) + else None + + def unapplyShort(arg: Impl): Option[Short] = + if (arg.const.tag == Constants.ShortTag) Some(arg.const.shortValue) + else None + + def unapplyInt(arg: Impl): Option[Int] = + if (arg.const.tag == Constants.IntTag) Some(arg.const.intValue) + else None + + def unapplyLong(arg: Impl): Option[Long] = + if (arg.const.tag == Constants.LongTag) Some(arg.const.longValue) + else None + + def unapplyFloat(arg: Impl): Option[Float] = + if (arg.const.tag == Constants.FloatTag) Some(arg.const.floatValue) + else None + + def unapplyDouble(arg: Impl): Option[Double] = + if (arg.const.tag == Constants.DoubleTag) Some(arg.const.doubleValue) + else None + + def unapplyString(arg: Impl): Option[String] = + if (arg.const.tag == Constants.StringTag) Some(arg.const.stringValue) + else None + + private[tasty] class Impl(val const: Constants.Constant) extends constants.Constant { + + def value: Any = const.value + + override def toString: String = "Constant" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/DefDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/DefDef.scala new file mode 100644 index 000000000000..996fdce6e6df --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/DefDef.scala @@ -0,0 +1,29 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Symbols.TermSymbol + +import scala.tasty.modifiers +import scala.tasty.trees +import scala.tasty.types + +object DefDef { + + def apply(tree: tpd.DefDef): trees.DefDef = new Impl(tree) + + def apply(sym: TermSymbol)(implicit ctx: Context): trees.DefDef = new Impl(tpd.DefDef(sym)) + + def unapplyDefDef(arg: Impl)(implicit ctx: Context): Option[trees.DefDef.Data] = { + val ddef = arg.tree + Some((TermName(ddef.name), ddef.tparams.map(TypeDef(_)), ddef.vparamss.map(_.map(ValDef(_))), TypeTree(ddef.tpt), if (ddef.rhs.isEmpty) None else Some(Term(ddef.rhs)))) + } + + private[tasty] class Impl(val tree: tpd.DefDef) extends trees.DefDef with Definition with Positioned { + def tpe: types.Type = Type(tree.tpe) + def mods(implicit ctx: scala.tasty.Context): List[modifiers.Modifier] = Modifiers(tree) + override def toString: String = "DefDef" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Definition.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Definition.scala new file mode 100644 index 000000000000..ddaf6e82478d --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Definition.scala @@ -0,0 +1,56 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Symbols.{defn, Symbol} +import dotty.tools.dotc.core.Flags._ + +import scala.tasty +import scala.tasty.trees + +trait Definition extends trees.Definition { + + protected def tree: tpd.Tree + + def owner(implicit tctx: scala.tasty.Context): trees.Definition = { + implicit val ctx = tctx.asInstanceOf[TastyContext].ctx + Definition(tree.symbol.owner) + } + + def localContext(implicit tctx: tasty.Context): tasty.Context = { + implicit val ctx = tctx.asInstanceOf[TastyContext].ctx + new TastyContext( + if (tree.hasType && tree.symbol.exists) ctx.withOwner(tree.symbol) + else ctx + ) + } +} + +object Definition { + + def apply(tree: tpd.Tree)(implicit ctx: Context): trees.Definition = tree match { + case tree: tpd.ValDef => ValDef(tree) + case tree: tpd.DefDef => DefDef(tree) + case tree: tpd.TypeDef => + if (tree.symbol.isClass) ClassDef(tree) + else TypeDef(tree) + } + + def apply(sym: Symbol)(implicit ctx: Context): trees.Definition = { + if (sym.is(Package)) PackageDef(sym) + else if (sym == defn.AnyClass) NoDefinition // FIXME + else if (sym == defn.NothingClass) NoDefinition // FIXME + else if (sym.isClass) ClassDef(sym.asClass) + else if (sym.isType) TypeDef(sym.asType) + else if (sym.is(Method)) DefDef(sym.asTerm) + else ValDef(sym.asTerm) + } + + private[tasty] object NoDefinition extends trees.Definition { + def owner(implicit tctx: scala.tasty.Context): trees.Definition = NoDefinition + def localContext(implicit ctx: tasty.Context): tasty.Context = ctx + def pos(implicit ctx: scala.tasty.Context): scala.tasty.Position = ??? + override def toString: String = "NoDefinition" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/FlagsModifier.scala b/compiler/src/dotty/tools/dotc/tasty/internal/FlagsModifier.scala new file mode 100644 index 000000000000..1fa61e7ab1b7 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/FlagsModifier.scala @@ -0,0 +1,82 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Symbols.Symbol +import dotty.tools.dotc.core.Flags._ + +import scala.tasty.modifiers + +object FlagsModifier { + + // TODO make sure all flags are tested + + def apply(sym: Symbol): modifiers.Flags = new Impl(sym) + + def unapplyFlags(arg: Impl)(implicit ctx: Context): Option[modifiers.Flags.Data] = { + val sym = arg.sym + Some(new modifiers.FlagSet { + override def isProtected: Boolean = sym.is(Protected) + override def isAbstract: Boolean = sym.is(Abstract) + override def isFinal: Boolean = sym.is(Final) + override def isSealed: Boolean = sym.is(Sealed) + override def isCase: Boolean = sym.is(Case) + override def isImplicit: Boolean = sym.is(Implicit) + override def isErased: Boolean = sym.is(Erased) + override def isLazy: Boolean = sym.is(Lazy) + override def isOverride: Boolean = sym.is(Override) + override def isInline: Boolean = sym.is(Inline) + override def isMacro: Boolean = sym.is(Macro) + override def isStatic: Boolean = sym.is(JavaStatic) + override def isObject: Boolean = sym.is(Module) + override def isTrait: Boolean = sym.is(Trait) + override def isLocal: Boolean = sym.is(Local) + override def isSynthetic: Boolean = sym.is(Synthetic) + override def isArtifact: Boolean = sym.is(Artifact) + override def isMutable: Boolean = sym.is(Mutable) + override def isLabel: Boolean = sym.is(Label) + override def isFieldAccessor: Boolean = sym.is(Accessor) + override def isCaseAcessor: Boolean = sym.is(CaseAccessor) + override def isCovariant: Boolean = sym.is(Covariant) + override def isContravariant: Boolean = sym.is(Contravariant) + override def isScala2X: Boolean = sym.is(Scala2x) + override def isDefaultParameterized: Boolean = sym.is(DefaultParameterized) + override def isStable: Boolean = sym.is(Stable) + + override def toString: String = { + val flags = List.newBuilder[String] + if (isProtected) flags += "protected " + if (isAbstract) flags += "abstract" + if (isFinal) flags += "final" + if (isSealed) flags += "sealed" + if (isCase) flags += "case" + if (isImplicit) flags += "implicit" + if (isErased) flags += "erased" + if (isLazy) flags += "lazy" + if (isOverride) flags += "override" + if (isInline) flags += "inline" + if (isMacro) flags += "macro" + if (isStatic) flags += "javaStatic" + if (isObject) flags += "module" + if (isTrait) flags += "trait" + if (isLocal) flags += "local" + if (isSynthetic) flags += "synthetic" + if (isArtifact) flags += "artifact" + if (isMutable) flags += "mutable" + if (isLabel) flags += "label" + if (isFieldAccessor) flags += "accessor" + if (isCaseAcessor) flags += "caseAccessor" + if (isCovariant) flags += "covariant" + if (isContravariant) flags += "contravariant" + if (isScala2X) flags += "scala2x" + if (isDefaultParameterized) flags += "defaultParameterized" + if (isStable) flags += "stable" + flags.result().mkString("<", ",", ">") + } + }) + } + + private[tasty] class Impl(val sym: Symbol) extends modifiers.Flags { + override def toString: String = "Flags" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Id.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Id.scala new file mode 100644 index 000000000000..dc2a2b85a8f7 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Id.scala @@ -0,0 +1,18 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.ast.untpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Decorators.sourcePos + +object Id { + + def apply(tree: untpd.Ident)(implicit ctx: Context): scala.tasty.Id = + Impl(tree, new Position(tree.pos)) + + private case class Impl(tree: untpd.Ident, pos: scala.tasty.Position) extends scala.tasty.Id with Positioned { + + def name: String = tree.name.toString + + override def toString: String = s"Id($name)" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Import.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Import.scala new file mode 100644 index 000000000000..507e4b71b8b3 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Import.scala @@ -0,0 +1,22 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.{Trees, tpd, untpd} +import dotty.tools.dotc.core.Contexts.Context + +import scala.tasty.trees + +object Import { + + def apply(tree: tpd.Tree): trees.Import = new Impl(tree) + + def unapplyImport(arg: Impl)(implicit ctx: Context) : Option[trees.Import.Data] = { + val Trees.Import(expr, selectors) = arg.tree + Some(Term(expr), selectors.map(ImportSelector(_))) + } + + private[tasty] class Impl(val tree: tpd.Tree)extends trees.Import with Positioned { + override def toString: String = "Import" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/ImportSelector.scala b/compiler/src/dotty/tools/dotc/tasty/internal/ImportSelector.scala new file mode 100644 index 000000000000..8d6bf65f8231 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/ImportSelector.scala @@ -0,0 +1,35 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.{Trees, tpd, untpd} +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.StdNames.nme + +import scala.tasty.trees + +object ImportSelector { + + def apply(tree: untpd.Tree): trees.ImportSelector = new Impl(tree) + + def unapplySimpleSelector(arg: Impl)(implicit ctx: Context): Option[trees.SimpleSelector.Data] = arg.tree match { + case id@Trees.Ident(_) => Some(Id(id)) + case _ => None + } + + def unapplyRenameSelector(arg: Impl)(implicit ctx: Context): Option[trees.RenameSelector.Data] = arg.tree match { + case Trees.Thicket((id1@Trees.Ident(_)) :: (id2@Trees.Ident(_)) :: Nil) if id2.name != nme.WILDCARD => + Some(Id(id1), Id(id2)) + case _ => None + } + + def unapplyOmitSelector(arg: Impl)(implicit ctx: Context): Option[trees.OmitSelector.Data] = arg.tree match { + case Trees.Thicket((id@Trees.Ident(_)) :: Trees.Ident(nme.WILDCARD) :: Nil) => + Some(Id(id)) + case _ => None + } + + private[tasty] class Impl(val tree: untpd.Tree) extends trees.ImportSelector { + override def toString: String = "ImportSelector" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/LambdaType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/LambdaType.scala new file mode 100644 index 000000000000..c33e43bcdada --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/LambdaType.scala @@ -0,0 +1,16 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Types + +import scala.tasty.types + +object LambdaType { + + def apply(tpe: Types.LambdaType): types.LambdaType[_, _] = tpe match { + case tpe: Types.MethodType => MethodType(tpe) + case tpe: Types.PolyType => PolyType(tpe) + case tpe: Types.TypeLambda => TypeLambda(tpe) + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/MaybeType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/MaybeType.scala new file mode 100644 index 000000000000..c1f45e265c04 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/MaybeType.scala @@ -0,0 +1,15 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Types + +import scala.tasty.types + +object MaybeType { + + def apply(tpe: Types.Type)(implicit ctx: Context): types.MaybeType = tpe match { + case tpe: Types.TypeBounds => TypeBounds(tpe) + case _ => Type(tpe) + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/MethodType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/MethodType.scala new file mode 100644 index 000000000000..c0c2a9403542 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/MethodType.scala @@ -0,0 +1,27 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.{Flags, Types} + +import scala.tasty.types + +object MethodType { + + // TODO make sure all extractors are tested + + def apply(tpe: Types.MethodType): types.MethodType = new Impl(tpe) + + def unapplyMethodType(arg: Impl)(implicit ctx: Context): Option[types.MethodType.Data] = { + val meth = arg.meth + Some((meth.paramNames.map(TermName(_)), meth.paramInfos.map(Type(_)), Type(meth.resType))) + } + + private[tasty] class Impl(val meth: Types.MethodType) extends types.MethodType { + + override def isImplicit: Boolean = meth.isImplicitMethod + override def isErased: Boolean = meth.isErasedMethod + + override def toString: String = "MethodType" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Modifiers.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Modifiers.scala new file mode 100644 index 000000000000..3f29f0cc2030 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Modifiers.scala @@ -0,0 +1,17 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context + +import scala.tasty.modifiers + +object Modifiers { + + def apply(tree: tpd.MemberDef)(implicit tctx: scala.tasty.Context): List[modifiers.Modifier] = { + implicit val ctx = tctx.asInstanceOf[TastyContext].ctx + FlagsModifier(tree.symbol) :: + QualifiedModifier(tree).toList ::: + tree.symbol.annotations.map(AnnotationModifier(_)) + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Name.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Name.scala new file mode 100644 index 000000000000..e86a56693469 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Name.scala @@ -0,0 +1,14 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.core.Names + +import scala.tasty.names + +object Name { + + def apply(name: Names.Name): names.Name = name match { + case name: Names.TermName => TermName(name) + case name: Names.TypeName => TypeName(name) + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/PackageClause.scala b/compiler/src/dotty/tools/dotc/tasty/internal/PackageClause.scala new file mode 100644 index 000000000000..99cf94f0b59e --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/PackageClause.scala @@ -0,0 +1,27 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context + +import scala.tasty.trees + +object PackageClause { + + // TODO make sure all extractors are tested + + def apply(tree: tpd.PackageDef): trees.PackageClause = new Impl(tree) + + def unapplyPackageClause(arg: Impl)(implicit ctx: Context): Option[trees.PackageClause.Data] = + Some(Term(arg.tree.pid), arg.tree.stats.map(TopLevelStatement(_))) + + private[tasty] class Impl(val tree: tpd.PackageDef) extends trees.PackageClause with Positioned { + + def definition(implicit tctx: scala.tasty.Context): trees.Definition = { + implicit val ctx = tctx.asInstanceOf[TastyContext].ctx + PackageDef(tree.symbol) + } + + override def toString: String = "PackageClause" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/PackageDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/PackageDef.scala new file mode 100644 index 000000000000..239682bb07d5 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/PackageDef.scala @@ -0,0 +1,36 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Symbols.Symbol + +import scala.tasty +import scala.tasty.trees + +object PackageDef { + + // TODO make sure all extractors are tested + + def apply(sym: Symbol): trees.PackageDef = new Impl(sym) + + def unapplyPackageDef(arg: Impl)(implicit ctx: Context): Option[trees.PackageDef.Data] = { + Some(Name(arg.sym.name), Nil) // FIXME + } + + private[tasty] class Impl(val sym: Symbol) extends trees.PackageDef { + + override def pos(implicit ctx: tasty.Context): tasty.Position = ??? // FIXME: A packageDef should not have a position, maybe Definition should not have positions + + def owner(implicit tctx: tasty.Context): trees.Definition = { + implicit val ctx = tctx.asInstanceOf[TastyContext].ctx + Definition(sym.owner) + } + + def localContext(implicit tctx: tasty.Context): tasty.Context = { + implicit val ctx = tctx.asInstanceOf[TastyContext].ctx + new TastyContext(ctx.withOwner(sym)) + } + + override def toString: String = "PackageDef" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Pattern.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Pattern.scala new file mode 100644 index 000000000000..fd32b75d9e0c --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Pattern.scala @@ -0,0 +1,49 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.{Trees, tpd} +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Names + +import scala.tasty.trees +import scala.tasty.types + +object Pattern { + + def apply(tree: tpd.Tree): trees.Pattern = new Impl(tree) + + def unapplyValue(arg: Impl)(implicit ctx: Context): Option[trees.Value.Data] = arg.tree match { + case lit: tpd.Literal => Some(Term(lit)) + case ident: tpd.Ident => Some(Term(ident)) + case _ => None + } + + def unapplyBind(arg: Impl)(implicit ctx: Context): Option[trees.Bind.Data] = arg.tree match { + case Trees.Bind(name: Names.TermName, body) => Some(TermName(name), Pattern(body)) + case _ => None + } + + def unapplyUnapply(arg: Impl)(implicit ctx: Context): Option[trees.Unapply.Data] = arg.tree match { + case Trees.UnApply(fun, implicits, patterns) => + Some((Term(fun), implicits.map(Term(_)), patterns.map(Pattern(_)))) + case _ => None + } + + def unapplyAlternative(arg: Impl)(implicit ctx: Context): Option[trees.Alternative.Data] = arg.tree match { + case Trees.Alternative(patterns) => Some(patterns.map(Pattern(_))) + case _ => None + } + + def unapplyTypeTest(arg: Impl)(implicit ctx: Context): Option[trees.TypeTest.Data] = arg.tree match { + case Trees.Typed(_, tpt) => Some(TypeTree(tpt)) + case _ => None + } + + private[tasty] class Impl(val tree: tpd.Tree) extends trees.Pattern with Positioned { + + def tpe: types.Type = Type(tree.tpe) + + override def toString: String = "Pattern" + } +} + diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/PolyType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/PolyType.scala new file mode 100644 index 000000000000..1e3cb791e548 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/PolyType.scala @@ -0,0 +1,23 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Types + +import scala.tasty.types + +object PolyType { + + // TODO make sure all extractors are tested + + def apply(tpe: Types.PolyType): types.PolyType = new Impl(tpe) + + def unapplyPolyType(arg: Impl)(implicit ctx: Context): Option[types.PolyType.Data] = { + val meth = arg.meth + Some((meth.paramNames.map(TypeName(_)), meth.paramInfos.map(TypeBounds(_)), Type(meth.resType))) + } + + private[tasty] class Impl(val meth: Types.PolyType) extends types.PolyType { + override def toString: String = "PolyType" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Position.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Position.scala new file mode 100644 index 000000000000..939cd5f3177d --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Position.scala @@ -0,0 +1,18 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.util.SourcePosition + +private[tasty] class Position(val pos: SourcePosition) extends scala.tasty.Position { + override def start = pos.start + override def end = pos.end + + override def sourceFile = pos.source.file.jpath + + override def startLine = pos.startLine + override def endLine = pos.endLine + + override def startColumn = pos.startColumn + override def endColumn = pos.endColumn + + override def toString: String = s"Position(${pos.line}, ${pos.column})" +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Positioned.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Positioned.scala new file mode 100644 index 000000000000..a0508424f21f --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Positioned.scala @@ -0,0 +1,9 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.core.Decorators.sourcePos + +private[tasty] trait Positioned extends scala.tasty.Positioned with TreeWithContext { + def pos(implicit ctx: scala.tasty.Context): scala.tasty.Position = { + new Position(sourcePos(tree.pos)(ctx.asInstanceOf[TastyContext].ctx)) + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/PossiblySignedName.scala b/compiler/src/dotty/tools/dotc/tasty/internal/PossiblySignedName.scala new file mode 100644 index 000000000000..90208ace205d --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/PossiblySignedName.scala @@ -0,0 +1,13 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.core.{NameKinds, Names} + +import scala.tasty.names + +object PossiblySignedName { + + def apply(name: Names.TermName): names.PossiblySignedName = + if (name.is(NameKinds.SignedName)) SignedName(name) + else TermName(name) + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/QualifiedModifier.scala b/compiler/src/dotty/tools/dotc/tasty/internal/QualifiedModifier.scala new file mode 100644 index 000000000000..83cc934b2f13 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/QualifiedModifier.scala @@ -0,0 +1,28 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Flags + +import scala.tasty.modifiers + +object QualifiedModifier { + + def apply(tree: tpd.DefTree)(implicit ctx: Context): Option[modifiers.Qualified] = + if (tree.symbol.privateWithin.exists) Some(new Impl(tree)) else None + + def unapplyQualifiedPrivate(arg: Impl)(implicit ctx: Context): Option[modifiers.QualifiedPrivate.Data] = { + if (arg.tree.symbol.is(Flags.Protected)) None + else Some(Type(arg.tree.symbol.privateWithin.typeRef)) + } + + def unapplyQualifiedProtected(arg: Impl)(implicit ctx: Context): Option[modifiers.QualifiedProtected.Data] = { + if (arg.tree.symbol.is(Flags.Protected)) Some(Type(arg.tree.symbol.privateWithin.typeRef)) + else None + } + + private[tasty] class Impl(val tree: tpd.DefTree) extends modifiers.Qualified { + override def toString: String = "Qualified" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/RecursiveType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/RecursiveType.scala new file mode 100644 index 000000000000..917dc5e06d23 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/RecursiveType.scala @@ -0,0 +1,21 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Types + +import scala.tasty.types + +object RecursiveType { + + // TODO make sure all extractors are tested + + def apply(binder: Types.RecType): types.RecursiveType = new Impl(binder) + + def unapplyRecursiveType(arg: Impl)(implicit ctx: Context): Option[types.RecursiveType.Data] = + Some(Type(arg.binder.underlying)) + + private[tasty] class Impl(val binder: Types.RecType) extends types.RecursiveType { + override def toString: String = "RecursiveType" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/SignedName.scala b/compiler/src/dotty/tools/dotc/tasty/internal/SignedName.scala new file mode 100644 index 000000000000..96fd9fb94b4b --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/SignedName.scala @@ -0,0 +1,25 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.NameKinds +import dotty.tools.dotc.core.Names + +import scala.tasty.names + +object SignedName { + + // TODO make sure all extractors are tested + + def apply(name: Names.TermName): names.SignedName = new Impl(name) + + def unapplySignedName(arg: Impl): Option[names.SignedName.Data] = { + val name = arg.name + val NameKinds.SignedName.SignedInfo(sig) = name.info + Some(TermName(name.underlying), TypeName(sig.resSig), sig.paramsSig.map(TypeName(_))) + } + + private[tasty] class Impl(val name: Names.TermName) extends names.SignedName { + override def toString: String = s"SignedName<$name>" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Statement.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Statement.scala new file mode 100644 index 000000000000..1d0cfb3284b3 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Statement.scala @@ -0,0 +1,15 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context + +import scala.tasty.trees + +object Statement { + def apply(tree: tpd.Tree)(implicit ctx: Context): trees.Statement = tree match { + case tree: tpd.Import => Import(tree) + case tree: tpd.DefTree => Definition(tree)(ctx) + case _ => Term(tree) + } +} + diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TastyContext.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TastyContext.scala new file mode 100644 index 000000000000..7114c2b49859 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TastyContext.scala @@ -0,0 +1,19 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.quoted.PickledQuotes + +import scala.tasty.trees + +private[dotc] class TastyContext(val ctx: Context) extends scala.tasty.Context { + def owner: trees.Definition = Definition(ctx.owner)(ctx) + + def toTasty[T](expr: quoted.Expr[T]): trees.Term = + internal.Term(PickledQuotes.quotedExprToTree(expr)(ctx)) + + def toTasty[T](tpe: quoted.Type[T]): trees.TypeTree = + internal.TypeTree(PickledQuotes.quotedTypeToTree(tpe)(ctx)) + + def toolbox: scala.runtime.tasty.Toolbox = Toolbox +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Term.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Term.scala new file mode 100644 index 000000000000..db786f7cdcbd --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Term.scala @@ -0,0 +1,129 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.{Trees, tpd} +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.NameKinds._ +import dotty.tools.dotc.core.Names + +import scala.tasty.trees +import scala.tasty.types + +object Term { + + // TODO make sure all extractors are tested + + def apply(arg: tpd.Tree): trees.Term = new Impl(arg) + + def unapplyIdent(arg: Impl)(implicit ctx: Context): Option[trees.Ident.Data] = arg.tree match { + case Trees.Ident(name: Names.TermName) if arg.tree.isTerm => Some(TermName(name)) + case _ => None + } + + def unapplySelect(arg: Impl)(implicit ctx: Context): Option[trees.Select.Data] = arg.tree match { + case id@Trees.Select(qual, name: Names.TermName) if id.isTerm => Some(Term(qual), PossiblySignedName(name)) + case _ => None + } + + def unapplyLiteral(arg: Impl)(implicit ctx: Context): Option[trees.Literal.Data] = arg.tree match { + case Trees.Literal(const) => Some(Constant(const)) + case _ => None + } + + def unapplyThis(arg: Impl)(implicit ctx: Context): Option[trees.This.Data] = arg.tree match { + case Trees.This(qual) => Some(if (qual.isEmpty) None else Some(Id(qual))) + case _ => None + } + + def unapplyNew(arg: Impl)(implicit ctx: Context): Option[trees.New.Data] = arg.tree match { + case Trees.New(tpt) => Some(TypeTree(tpt)) + case _ => None + } + + def unapplyNamedArg(arg: Impl)(implicit ctx: Context): Option[trees.NamedArg.Data] = arg.tree match { + case Trees.NamedArg(name: Names.TermName, argument) => Some(TermName(name), Term(argument)) + case _ => None + } + + def unapplyApply(arg: Impl)(implicit ctx: Context): Option[trees.Apply.Data] = arg.tree match { + case Trees.Apply(fn, args) => Some((Term(fn), args.map(arg => Term(arg)))) + case _ => None + } + + def unapplyTypeApply(arg: Impl)(implicit ctx: Context): Option[trees.TypeApply.Data] = arg.tree match { + case Trees.TypeApply(fn, args) => Some((Term(fn), args.map(arg => TypeTree(arg)))) + case _ => None + } + + def unapplySuper(arg: Impl)(implicit ctx: Context): Option[trees.Super.Data] = arg.tree match { + case Trees.Super(qual, mixin) => Some((Term(qual), if (mixin.isEmpty) None else Some(Id(mixin)))) + case _ => None + } + + def unapplyTyped(arg: Impl)(implicit ctx: Context): Option[trees.Typed.Data] = arg.tree match { + case Trees.Typed(expr, tpt) => Some((Term(expr), TypeTree(tpt))) + case _ => None + } + + def unapplyAssign(arg: Impl)(implicit ctx: Context): Option[trees.Assign.Data] = arg.tree match { + case Trees.Assign(lhs, rhs) => Some((Term(lhs), Term(rhs))) + case _ => None + } + + def unapplyBlock(arg: Impl)(implicit ctx: Context): Option[trees.Block.Data] = arg.tree match { + case Trees.Block(stats, expr) => Some((stats.map(stat => Statement(stat)), Term(expr))) + case _ => None + } + + def unapplyInlined(arg: Impl)(implicit ctx: Context): Option[trees.Inlined.Data] = arg.tree match { + case Trees.Inlined(call, bindings, expansion) => + Some((Term(call), bindings.map(Definition(_)), Term(expansion))) + case _ => None + } + + def unapplyLambda(arg: Impl)(implicit ctx: Context): Option[trees.Lambda.Data] = arg.tree match { + case Trees.Closure(_, meth, tpt) => Some((Term(meth), if (tpt.isEmpty) None else Some(TypeTree(tpt)))) + case _ => None + } + + def unapplyIf(arg: Impl)(implicit ctx: Context): Option[trees.If.Data] = arg.tree match { + case Trees.If(cond, thenp, elsep) => Some((Term(cond), Term(thenp), Term(elsep))) + case _ => None + } + + def unapplyMatch(arg: Impl)(implicit ctx: Context): Option[trees.Match.Data] = arg.tree match { + case Trees.Match(selector, cases) => Some((Term(selector), cases.map(c => CaseDef(c)))) + case _ => None + } + + def unapplyTry(arg: Impl)(implicit ctx: Context): Option[trees.Try.Data] = arg.tree match { + case Trees.Try(body, catches, finalizer) => Some((Term(body), catches.map(c => CaseDef(c)), if (finalizer.isEmpty) None else Some(Term(finalizer)))) + case _ => None + } + + def unapplyReturn(arg: Impl)(implicit ctx: Context): Option[trees.Return.Data] = arg.tree match { + case Trees.Return(expr, from) => Some(Term(expr)) // TODO use `from` or remove it + case _ => None + } + + def unapplyRepeated(arg: Impl)(implicit ctx: Context): Option[trees.Repeated.Data] = arg.tree match { + case Trees.SeqLiteral(args, elemtpt) => Some(args.map(arg => Term(arg))) // TODO use `elemtpt`? + case _ => None + } + + def unapplySelectOuter(arg: Impl)(implicit ctx: Context): Option[trees.SelectOuter.Data] = arg.tree match { + case sel@Trees.Select(qual, OuterSelectName(_, levels)) => Some((Term(qual), levels, Type(sel.tpe))) + case _ => None + } + + def tree(term: trees.Term): tpd.Tree = term.asInstanceOf[Impl].tree + + private[tasty] class Impl(val tree: tpd.Tree) extends trees.Term with Positioned { + + assert(tree.isTerm || tree.isInstanceOf[Trees.NamedArg[_]] || tree.isInstanceOf[Trees.SeqLiteral[_]]) + + def tpe: types.Type = Type(tree.tpe) + + override def toString: String = "Term" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TermName.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TermName.scala new file mode 100644 index 000000000000..18e3cd1f04c5 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TermName.scala @@ -0,0 +1,63 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Names +import dotty.tools.dotc.core.NameKinds._ +import dotty.tools.dotc.core.NameKinds + +import scala.tasty.names + +object TermName { + + // TODO make sure all extractors are tested + + def apply(name: Names.TermName): names.TermName = new Impl(name) + + def unapplySimple(arg: Impl): Option[names.Simple.Data] = arg.name match { + case name: Names.SimpleName => Some(name.toString) + case _ => None + } + + def unapplyQualified(arg: Impl): Option[names.Qualified.Data] = arg.name match { + case name: Names.DerivedName if name.is(QualifiedName) => + Some(TermName(name.underlying), name.lastPart.toString) + case _ => None + } + + def unapplyDefaultGetter(arg: Impl): Option[names.DefaultGetter.Data] = arg.name match { + case name: Names.DerivedName if name.is(DefaultGetterName) => + Some(TermName(name.underlying), name.lastPart.toString) + case _ => None + } + + def unapplyVariant(arg: Impl): Option[names.Variant.Data] = arg.name match { + case name: Names.DerivedName if name.is(VariantName) => + Some(TermName(name.underlying), name.info.asInstanceOf[NumberedInfo].num == 1) + case _ => None + } + + def unapplySuperAccessor(arg: Impl): Option[names.SuperAccessor.Data] = arg.name match { + case name: Names.DerivedName if name.is(SuperAccessorName) => Some(TermName(name.underlying)) + case _ => None + } + + def unapplyProtectedAccessor(arg: Impl): Option[names.ProtectedAccessor.Data] = arg.name match { + case name: Names.DerivedName if name.is(ProtectedAccessorName) => Some(TermName(name.underlying)) + case _ => None + } + + def unapplyProtectedSetter(arg: Impl): Option[names.ProtectedSetter.Data] = arg.name match { + case name: Names.DerivedName if name.is(ProtectedSetterName) => Some(TermName(name.underlying)) + case _ => None + } + + def unapplyObjectClass(arg: Impl): Option[names.ObjectClass.Data] = arg.name match { + case name: Names.DerivedName if name.is(NameKinds.ModuleClassName) => Some(TermName(name.underlying)) + case _ => None + } + + private[tasty] class Impl(val name: Names.TermName) extends names.TermName { + override def toString: String = s"TermName<$name>" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Toolbox.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Toolbox.scala new file mode 100644 index 000000000000..11e31a444d27 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Toolbox.scala @@ -0,0 +1,217 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.core.Contexts.Context + +import scala.reflect.ClassTag + +import scala.tasty.{constants, names, modifiers, trees, types} + +object Toolbox extends scala.runtime.tasty.Toolbox { + + // Statements + + override def unapplyPackageClause(arg: trees.PackageClause)(implicit ctx: scala.tasty.Context) = PackageClause.unapplyPackageClause(impl(arg))(ictx) + + override def unapplyImport(arg: trees.Import)(implicit ctx: scala.tasty.Context) = Import.unapplyImport(impl(arg))(ictx) + + override def unapplyValDef(arg: trees.ValDef)(implicit ctx: scala.tasty.Context) = ValDef.unapplyValDef(impl(arg))(ictx) + + override def unapplyDefDef(arg: trees.DefDef)(implicit ctx: scala.tasty.Context) = DefDef.unapplyDefDef(impl(arg))(ictx) + + override def unapplyTypeDef(arg: trees.TypeDef)(implicit ctx: scala.tasty.Context) = TypeDef.unapplyTypeDef(impl(arg))(ictx) + + override def unapplyClassDef(arg: trees.ClassDef)(implicit ctx: scala.tasty.Context) = ClassDef.unapplyClassDef(impl(arg))(ictx) + + override def unapplyPackageDef(arg: trees.PackageDef)(implicit ctx: scala.tasty.Context) = PackageDef.unapplyPackageDef(impl(arg))(ictx) + + // Terms + + override def unapplyIdent(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyIdent(impl(arg))(ictx) + + override def unapplySelect(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplySelect(impl(arg))(ictx) + + override def unapplyLiteral(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyLiteral(impl(arg))(ictx) + + override def unapplyThis(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyThis(impl(arg))(ictx) + + override def unapplyNew(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyNew(impl(arg))(ictx) + + override def unapplyNamedArg(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyNamedArg(impl(arg))(ictx) + + override def unapplyApply(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyApply(impl(arg))(ictx) + + override def unapplyTypeApply(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyTypeApply(impl(arg))(ictx) + + override def unapplySuper(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplySuper(impl(arg))(ictx) + + override def unapplyTyped(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyTyped(impl(arg))(ictx) + + override def unapplyAssign(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyAssign(impl(arg))(ictx) + + override def unapplyBlock(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyBlock(impl(arg))(ictx) + + override def unapplyInlined(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyInlined(impl(arg))(ictx) + + override def unapplyLambda(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyLambda(impl(arg))(ictx) + + override def unapplyIf(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyIf(impl(arg))(ictx) + + override def unapplyMatch(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyMatch(impl(arg))(ictx) + + override def unapplyTry(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyTry(impl(arg))(ictx) + + override def unapplyReturn(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyReturn(impl(arg))(ictx) + + override def unapplyRepeated(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyRepeated(impl(arg))(ictx) + + override def unapplySelectOuter(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplySelectOuter(impl(arg))(ictx) + + + // Pattern + + override def unapplyCaseDef(arg: trees.CaseDef)(implicit ctx: scala.tasty.Context) = CaseDef.unapplyCaseDef(impl(arg))(ictx) + + override def unapplyValue(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyValue(impl(arg))(ictx) + + override def unapplyBind(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyBind(impl(arg))(ictx) + + override def unapplyUnapply(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyUnapply(impl(arg))(ictx) + + override def unapplyAlternative(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyAlternative(impl(arg))(ictx) + + override def unapplyTypeTest(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyTypeTest(impl(arg))(ictx) + + // Type trees + + override def unapplySynthetic(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplySynthetic(impl(arg))(ictx) + + override def unapplyTypeIdent(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyTypeIdent(impl(arg))(ictx) + + override def unapplyTypeSelect(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyTypeSelect(impl(arg))(ictx) + + override def unapplySingleton(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplySingleton(impl(arg))(ictx) + + override def unapplyRefined(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyRefined(impl(arg))(ictx) + + override def unapplyApplied(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyApplied(impl(arg))(ictx) + + override def unapplyAnnotated(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyAnnotated(impl(arg))(ictx) + + override def unapplyAnd(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyAnd(impl(arg))(ictx) + + override def unapplyOr(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyOr(impl(arg))(ictx) + + override def unapplyByName(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyByName(impl(arg))(ictx) + + override def unapplyTypeBoundsTree(arg: trees.TypeBoundsTree)(implicit ctx: scala.tasty.Context) = TypeBoundsTree.unapplyTypeBounds(impl(arg))(ictx) + + // Names + + override def unapplySimple(arg: names.TermName) = TermName.unapplySimple(impl(arg)) + + override def unapplyQualified(arg: names.TermName) = TermName.unapplyQualified(impl(arg)) + + override def unapplyDefaultGetter(arg: names.TermName) = TermName.unapplyDefaultGetter(impl(arg)) + + override def unapplyVariant(arg: names.TermName) = TermName.unapplyVariant(impl(arg)) + + override def unapplySuperAccessor(arg: names.TermName) = TermName.unapplySuperAccessor(impl(arg)) + + override def unapplyProtectedAccessor(arg: names.TermName) = TermName.unapplyProtectedAccessor(impl(arg)) + + override def unapplyProtectedSetter(arg: names.TermName) = TermName.unapplyProtectedSetter(impl(arg)) + + override def unapplyObjectClass(arg: names.TermName) = TermName.unapplyObjectClass(impl(arg)) + + override def unapplySignedName(arg: names.SignedName) = SignedName.unapplySignedName(impl(arg)) + + override def unapplyTypeName(arg: names.TypeName) = TypeName.unapplyTypeName(impl(arg)) + + // Constants + + override def unapplyUnit(arg: constants.Constant) = Constant.unapplyUnit(impl(arg)) + + override def unapplyNull(arg: constants.Constant) = Constant.unapplyNull(impl(arg)) + + override def unapplyBoolean(arg: constants.Constant) = Constant.unapplyBoolean(impl(arg)) + + override def unapplyByte(arg: constants.Constant) = Constant.unapplyByte(impl(arg)) + + override def unapplyChar(arg: constants.Constant) = Constant.unapplyChar(impl(arg)) + + override def unapplyShort(arg: constants.Constant) = Constant.unapplyShort(impl(arg)) + + override def unapplyInt(arg: constants.Constant) = Constant.unapplyInt(impl(arg)) + + override def unapplyLong(arg: constants.Constant) = Constant.unapplyLong(impl(arg)) + + override def unapplyFloat(arg: constants.Constant) = Constant.unapplyFloat(impl(arg)) + + override def unapplyDouble(arg: constants.Constant) = Constant.unapplyDouble(impl(arg)) + + override def unapplyString(arg: constants.Constant) = Constant.unapplyString(impl(arg)) + + // Types + + override def unapplyConstantType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyConstantType(impl(arg))(ictx) + + override def unapplySymRef(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplySymRef(impl(arg))(ictx) + + override def unapplyNameRef(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyNameRef(impl(arg))(ictx) + + override def unapplySuperType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplySuperType(impl(arg))(ictx) + + override def unapplyRefinement(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyRefinement(impl(arg))(ictx) + + override def unapplyAppliedType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyAppliedType(impl(arg))(ictx) + + override def unapplyAnnotatedType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyAnnotatedType(impl(arg))(ictx) + + override def unapplyAndType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyAndType(impl(arg))(ictx) + + override def unapplyOrType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyOrType(impl(arg))(ictx) + + override def unapplyByNameType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyByNameType(impl(arg))(ictx) + + override def unapplyParamRef(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyParamRef(impl(arg))(ictx) + + override def unapplyThisType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyThisType(impl(arg))(ictx) + + override def unapplyRecursiveThis(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyRecursiveThis(impl(arg))(ictx) + + override def unapplyRecursiveType(arg: types.RecursiveType)(implicit ctx: scala.tasty.Context) = RecursiveType.unapplyRecursiveType(impl(arg))(ictx) + + override def unapplyMethodType(arg: types.MethodType)(implicit ctx: scala.tasty.Context) = MethodType.unapplyMethodType(impl(arg))(ictx) + + override def unapplyPolyType(arg: types.PolyType)(implicit ctx: scala.tasty.Context) = PolyType.unapplyPolyType(impl(arg))(ictx) + + override def unapplyTypeLambda(arg: types.TypeLambda)(implicit ctx: scala.tasty.Context) = TypeLambda.unapplyTypeLambda(impl(arg))(ictx) + + override def unapplyTypeBounds(arg: types.TypeBounds)(implicit ctx: scala.tasty.Context) = TypeBounds.unapplyTypeBounds(impl(arg))(ictx) + + // Modifiers + + override def unapplyFlags(arg: modifiers.Flags)(implicit ctx: scala.tasty.Context) = FlagsModifier.unapplyFlags(impl(arg))(ictx) + + override def unapplyQualifiedPrivate(arg: modifiers.Qualified)(implicit ctx: scala.tasty.Context) = QualifiedModifier.unapplyQualifiedPrivate(impl(arg))(ictx) + + override def unapplyQualifiedProtected(arg: modifiers.Qualified)(implicit ctx: scala.tasty.Context) = QualifiedModifier.unapplyQualifiedProtected(impl(arg))(ictx) + + override def unapplyAnnotation(arg: modifiers.Annotation)(implicit ctx: scala.tasty.Context) = AnnotationModifier.unapplyAnnotation(impl(arg))(ictx) + + // Import Selectors + + override def unapplySimpleSelector(arg: trees.ImportSelector)(implicit ctx: scala.tasty.Context) = ImportSelector.unapplySimpleSelector(impl(arg))(ictx) + + override def unapplyRenameSelector(arg: trees.ImportSelector)(implicit ctx: scala.tasty.Context) = ImportSelector.unapplyRenameSelector(impl(arg))(ictx) + + override def unapplyOmitSelector(arg: trees.ImportSelector)(implicit ctx: scala.tasty.Context) = ImportSelector.unapplyOmitSelector(impl(arg))(ictx) + + private def ictx(implicit ctx: scala.tasty.Context): Context = { + val tcxt: TastyContext = impl(ctx) + tcxt.ctx + } + + // TODO emit better error message when tasty trait was not implemented by the compiler + private def impl[T, U <: T](arg: T): U = arg.asInstanceOf[U] +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TopLevelStatement.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TopLevelStatement.scala new file mode 100644 index 000000000000..6f2bc72a7824 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TopLevelStatement.scala @@ -0,0 +1,13 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context + +import scala.tasty.trees + +object TopLevelStatement { + def apply(tree: tpd.Tree)(implicit ctx: Context): trees.TopLevelStatement = tree match { + case tree: tpd.PackageDef => PackageClause(tree) + case _ => Statement(tree) + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TreeWithContext.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TreeWithContext.scala new file mode 100644 index 000000000000..66bcaa37d487 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TreeWithContext.scala @@ -0,0 +1,10 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.ast.Trees +import dotty.tools.dotc.core.Contexts.Context + +// TODO delete this trait +private[tasty] trait TreeWithContext { + def tree: Trees.Tree[_] +// def ctx: Context +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Type.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Type.scala new file mode 100644 index 000000000000..4791524233fb --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/Type.scala @@ -0,0 +1,100 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Symbols.Symbol +import dotty.tools.dotc.core.Types +import dotty.tools.dotc.core.Names + +import scala.tasty.types + +object Type { + + def apply(arg: Types.Type): types.Type = arg match { + case arg: Types.LambdaType => LambdaType(arg) + case _ => new Impl(arg) + } + + def unapplyConstantType(arg: Impl)(implicit ctx: Context): Option[types.ConstantType.Data] = arg.tpe match { + case Types.ConstantType(value) => Some(Constant(value)) + case _ => None + } + + def unapplySymRef(arg: Impl)(implicit ctx: Context): Option[types.SymRef.Data] = arg.tpe match { + case tp: Types.NamedType => + tp.designator match { + case sym: Symbol => Some(Definition(sym), TypeOrNoPrefix(tp.prefix)) + case _ => None + } + case _ => None + } + + def unapplyNameRef(arg: Impl)(implicit ctx: Context): Option[types.NameRef.Data] = arg.tpe match { + case tp: Types.NamedType => + tp.designator match { + case name: Names.Name => Some(Name(name), TypeOrNoPrefix(tp.prefix)) + case _ => None + } + case _ => None + } + + def unapplySuperType(arg: Impl)(implicit ctx: Context): Option[types.SuperType.Data] = arg.tpe match { + case Types.SuperType(thistpe, supertpe) => Some(Type(thistpe), Type(supertpe)) + case _ => None + } + + def unapplyRefinement(arg: Impl)(implicit ctx: Context): Option[types.Refinement.Data] = arg.tpe match { + case Types.RefinedType(parent, name, info) => + Some((Type(parent), if (name.isTermName) TermName(name.asTermName) else TypeName(name.asTypeName), MaybeType(info))) + case _ => None + } + + def unapplyAppliedType(arg: Impl)(implicit ctx: Context): Option[types.AppliedType.Data] = arg.tpe match { + case Types.AppliedType(tycon, args) => + Some((Type(tycon), args.map { case arg: Types.TypeBounds => TypeBounds(arg); case arg => Type(arg) })) + case _ => None + } + + def unapplyAnnotatedType(arg: Impl)(implicit ctx: Context): Option[types.AnnotatedType.Data] = arg.tpe match { + case Types.AnnotatedType(underlying, annot) => Some((Type(underlying), Term(annot.tree))) + case _ => None + } + + def unapplyAndType(arg: Impl)(implicit ctx: Context): Option[types.AndType.Data] = arg.tpe match { + case Types.AndType(left, right) => Some(Type(left), Type(right)) + case _ => None + } + + def unapplyOrType(arg: Impl)(implicit ctx: Context): Option[types.OrType.Data] = arg.tpe match { + case Types.OrType(left, right) => Some(Type(left), Type(right)) + case _ => None + } + + def unapplyByNameType(arg: Impl)(implicit ctx: Context): Option[types.ByNameType.Data] = arg.tpe match { + case Types.ExprType(resType) => Some(Type(resType)) + case _ => None + } + + def unapplyParamRef(arg: Impl)(implicit ctx: Context): Option[types.ParamRef.Data] = arg.tpe match { + case Types.TypeParamRef(binder, idx) => Some(TypeLambda(binder), idx) + case _ => None + } + + def unapplyThisType(arg: Impl)(implicit ctx: Context): Option[types.ThisType.Data] = arg.tpe match { + case Types.ThisType(tp) => Some(Type(tp)) + case _ => None + } + + def unapplyRecursiveThis(arg: Impl)(implicit ctx: Context): Option[types.RecursiveThis.Data] = arg.tpe match { + case Types.RecThis(binder) => Some(RecursiveType(binder)) + case _ => None + } + + private[tasty] class Impl(val tpe: Types.Type) extends types.Type { + + assert(!tpe.isInstanceOf[Types.TypeBounds]) + + override def toString: String = "Type" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeBounds.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeBounds.scala new file mode 100644 index 000000000000..077c69eadba2 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TypeBounds.scala @@ -0,0 +1,20 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Types + +import scala.tasty.types + +object TypeBounds { + + def apply(bounds: Types.TypeBounds): types.TypeBounds = new Impl(bounds) + + def unapplyTypeBounds(arg: Impl)(implicit ctx: Context): Option[types.TypeBounds.Data] = { + Some(Type(arg.bounds.lo), Type(arg.bounds.hi)) + } + + private[tasty] class Impl(val bounds: Types.TypeBounds) extends types.TypeBounds { + override def toString: String = "TypeBounds" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeBoundsTree.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeBoundsTree.scala new file mode 100644 index 000000000000..3357ff384eff --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TypeBoundsTree.scala @@ -0,0 +1,26 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.ast.Trees +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Types + +import scala.tasty.trees +import scala.tasty.types + +object TypeBoundsTree { + + def apply(bounds: tpd.TypeBoundsTree): trees.TypeBoundsTree = new Impl(bounds) + + def unapplyTypeBounds(arg: Impl)(implicit ctx: Context): Option[trees.TypeBoundsTree.Data] = { + Some(TypeTree(arg.tree.lo), TypeTree(arg.tree.hi)) + } + + private[tasty] class Impl(val tree: tpd.TypeBoundsTree) extends trees.TypeBoundsTree with Positioned { + + override def tpe: types.TypeBounds = TypeBounds(tree.tpe.asInstanceOf[Types.TypeBounds]) + + override def toString: String = "TypeBoundsTree" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeDef.scala new file mode 100644 index 000000000000..f95069b184b2 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TypeDef.scala @@ -0,0 +1,31 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Symbols.TypeSymbol + +import scala.tasty.{modifiers, trees, types} + +object TypeDef { + + def apply(tree: tpd.TypeDef): trees.TypeDef = new Impl(tree) + + def apply(sym: TypeSymbol)(implicit ctx: Context): trees.TypeDef = new Impl(tpd.TypeDef(sym)) + + def unapplyTypeDef(arg: Impl)(implicit ctx: Context): Option[trees.TypeDef.Data] = { + val tdef = arg.tree + val rhs = tdef.rhs match { + case rhs: tpd.TypeBoundsTree => TypeBoundsTree(rhs) + case rhs => TypeTree(rhs) + } + Some((TypeName(tdef.name), rhs)) + } + + private[tasty] class Impl(val tree: tpd.TypeDef) extends trees.TypeDef with Definition with Positioned { + def tpe: types.Type = Type(tree.tpe) + def mods(implicit ctx: scala.tasty.Context): List[modifiers.Modifier] = Modifiers(tree) + override def toString: String = "TypeDef" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeLambda.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeLambda.scala new file mode 100644 index 000000000000..8066bd8aa294 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TypeLambda.scala @@ -0,0 +1,23 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Types + +import scala.tasty.types + +object TypeLambda { + + // TODO make sure all extractors are tested + + def apply(tpe: Types.TypeLambda): types.TypeLambda = new Impl(tpe) + + def unapplyTypeLambda(arg: Impl)(implicit ctx: Context): Option[types.TypeLambda.Data] = { + val meth = arg.meth + Some((meth.paramNames.map(TypeName(_)), meth.paramInfos.map(TypeBounds(_)), Type(meth.resType))) + } + + private[tasty] class Impl(val meth: Types.TypeLambda) extends types.TypeLambda { + override def toString: String = "TypeLambda" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeName.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeName.scala new file mode 100644 index 000000000000..dca189e8cf9c --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TypeName.scala @@ -0,0 +1,20 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.core.Names + +import scala.tasty.names + +object TypeName { + + def apply(name: Names.TypeName): names.TypeName = new Impl(name) + + def unapplyTypeName(arg: Impl): Option[names.TypeName.Data] = { + Some(TermName(arg.name.toTermName)) + } + + private[tasty] class Impl(val name: Names.TypeName) extends names.TypeName { + override def toString: String = s"TypeName<$name>" + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeOrNoPrefix.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeOrNoPrefix.scala new file mode 100644 index 000000000000..8701edd4bd9d --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TypeOrNoPrefix.scala @@ -0,0 +1,12 @@ +package dotty.tools.dotc.tasty.internal + +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Types + +import scala.tasty.types + +object TypeOrNoPrefix { + def apply(tpe: Types.Type)(implicit ctx: Context): types.MaybeType = + if (tpe == Types.NoPrefix) types.NoPrefix + else Type(tpe) +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeTree.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeTree.scala new file mode 100644 index 000000000000..f8557a30e855 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/TypeTree.scala @@ -0,0 +1,76 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.Trees +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Names + +import scala.tasty.trees +import scala.tasty.types + +object TypeTree { + + def apply(tree: tpd.Tree): trees.TypeTree = new Impl(tree) + + def unapplySynthetic(arg: Impl)(implicit ctx: Context): Boolean = arg.tree match { + case Trees.TypeTree() => true + case _ => false + } + + def unapplyTypeIdent(arg: Impl)(implicit ctx: Context): Option[trees.TypeIdent.Data] = arg.tree match { + case id@Trees.Ident(name: Names.TypeName) if id.isType => Some(TypeName(name)) + case _ => None + } + + def unapplyTypeSelect(arg: Impl)(implicit ctx: Context): Option[trees.TypeSelect.Data] = arg.tree match { + case id@Trees.Select(qual, name: Names.TypeName) if id.isType => Some(Term(qual), TypeName(name)) + case _ => None + } + + def unapplySingleton(arg: Impl)(implicit ctx: Context): Option[trees.Singleton.Data] = arg.tree match { + case Trees.SingletonTypeTree(ref) => Some(Term(ref)) + case _ => None + } + + def unapplyRefined(arg: Impl)(implicit ctx: Context): Option[trees.Refined.Data] = arg.tree match { + case Trees.RefinedTypeTree(tpt, refinements) => Some(TypeTree(tpt), refinements.map(Definition(_))) + case _ => None + } + + def unapplyApplied(arg: Impl)(implicit ctx: Context): Option[trees.Applied.Data] = arg.tree match { + case Trees.AppliedTypeTree(tycon, args) => Some(TypeTree(tycon), args.map(TypeTree(_))) + case _ => None + } + + def unapplyAnnotated(arg: Impl)(implicit ctx: Context): Option[trees.Annotated.Data] = arg.tree match { + case Trees.Annotated(argument, annot) => Some(TypeTree(argument), Term(annot)) + case _ => None + } + + def unapplyAnd(arg: Impl)(implicit ctx: Context): Option[trees.And.Data] = arg.tree match { + case Trees.AndTypeTree(left, right) => Some(TypeTree(left), TypeTree(right)) + case _ => None + } + + def unapplyOr(arg: Impl)(implicit ctx: Context): Option[trees.Or.Data] = arg.tree match { + case Trees.OrTypeTree(left, right) => Some(TypeTree(left), TypeTree(right)) + case _ => None + } + + def unapplyByName(arg: Impl)(implicit ctx: Context): Option[trees.ByName.Data] = arg.tree match { + case Trees.ByNameTypeTree(tpt) => Some(TypeTree(tpt)) + case _ => None + } + + def tree(tpe: trees.TypeTree)(implicit ctx: Context): tpd.Tree = tpe.asInstanceOf[Impl].tree + + private[tasty] class Impl(val tree: tpd.Tree) extends trees.TypeTree with Positioned { + + assert(!tree.isInstanceOf[Trees.TypeBoundsTree[_]]) + + def tpe: types.Type = Type(tree.tpe) + + override def toString: String = "TypeTree" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/ValDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/ValDef.scala new file mode 100644 index 000000000000..9635e62d5bc2 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/internal/ValDef.scala @@ -0,0 +1,31 @@ +package dotty.tools.dotc.tasty +package internal + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Symbols.TermSymbol + +import scala.tasty.{modifiers, trees, types} + +object ValDef { + + def apply(tree: tpd.ValDef): trees.ValDef = new Impl(tree) + + def apply(sym: TermSymbol)(implicit ctx: Context): trees.ValDef = new Impl(tpd.ValDef(sym)) + + def unapplyValDef(arg: Impl)(implicit ctx: Context): Option[trees.ValDef.Data] = { + val vdef = arg.tree + val rhs = if (vdef.rhs.isEmpty) None else Some(Term(vdef.rhs)) + Some((TermName(vdef.name), TypeTree(vdef.tpt), rhs)) + } + + private def localContext(tree: tpd.Tree)(implicit ctx: Context): Context = + if (tree.hasType && tree.symbol.exists) ctx.withOwner(tree.symbol) else ctx + + private[tasty] class Impl(val tree: tpd.ValDef) extends trees.ValDef with Definition with Positioned { + def tpe: types.Type = Type(tree.tpe) + def mods(implicit ctx: scala.tasty.Context): List[modifiers.Modifier] = Modifiers(tree) + override def toString: String = "ValDef" + } + +} diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index de81b63c9691..f701e5c65c92 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -509,11 +509,23 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { private def transformWithCapturer(tree: Tree)(capturer: mutable.Map[Symbol, Tree] => Tree => Tree)(implicit ctx: Context): Tree = { val captured = mutable.LinkedHashMap.empty[Symbol, Tree] val captured2 = capturer(captured) - outer.enteredSyms.foreach(s => capturers.put(s, captured2)) - if (ctx.owner.owner.is(Macro)) - outer.enteredSyms.reverse.foreach(s => captured2(ref(s))) + + def registerCapturer(sym: Symbol): Unit = capturers.put(sym, captured2) + def forceCapture(sym: Symbol): Unit = captured2(ref(sym)) + + outer.enteredSyms.foreach(registerCapturer) + + if (ctx.owner.owner.is(Macro)) { + registerCapturer(defn.TastyContext_compilationContext) + // Force a macro to have the context in first position + forceCapture(defn.TastyContext_compilationContext) + // Force all parameters of the macro to be created in the definition order + outer.enteredSyms.reverse.foreach(forceCapture) + } + val tree2 = transform(tree) capturers --= outer.enteredSyms + seq(captured.result().valuesIterator.toList, tree2) } @@ -636,7 +648,8 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { } private def isStage0Value(sym: Symbol)(implicit ctx: Context): Boolean = - sym.is(Inline) && sym.owner.is(Macro) && !defn.isFunctionType(sym.info) + (sym.is(Inline) && sym.owner.is(Macro) && !defn.isFunctionType(sym.info)) || + sym == defn.TastyContext_compilationContext // intrinsic value at stage 0 private def liftList(list: List[Tree], tpe: Type)(implicit ctx: Context): Tree = { list.foldRight[Tree](ref(defn.NilModule)) { (x, acc) => diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index db624c7f25f1..e11b4613ca3b 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -36,9 +36,10 @@ object Splicer { val liftedArgs = getLiftedArgs(call, bindings) val interpreter = new Interpreter(pos, classLoader) val interpreted = interpreter.interpretCallToSymbol[Seq[Any] => Object](call.symbol) + val tctx = new tasty.internal.TastyContext(ctx) evaluateMacro(pos) { // Some parts of the macro are evaluated during the unpickling performed in quotedExprToTree - val evaluated = interpreted.map(lambda => lambda(liftedArgs).asInstanceOf[scala.quoted.Expr[Nothing]]) + val evaluated = interpreted.map(lambda => lambda(tctx :: liftedArgs).asInstanceOf[scala.quoted.Expr[Nothing]]) evaluated.fold(tree)(PickledQuotes.quotedExprToTree) } } @@ -50,7 +51,7 @@ object Splicer { */ private def getLiftedArgs(call: Tree, bindings: List[Tree])(implicit ctx: Context): List[Any] = { val bindMap = bindings.collect { - case vdef: ValDef => (vdef.rhs, ref(vdef.symbol)) + case vdef: ValDef => (vdef.rhs, ref(vdef.symbol).withPos(vdef.rhs.pos)) }.toMap def allArgs(call: Tree, acc: List[List[Tree]]): List[List[Tree]] = call match { case call: Apply => allArgs(call.fun, call.args :: acc) @@ -154,8 +155,8 @@ object Splicer { } } - private def extraMsg = ". The most common reason for that is that you cannot use inline macro implementations in the same compilation run that defines them" - + private def extraMsg = ". The most common reason for that is that you cannot use inline macro implementations in the same compilation run that defines them" + private def stopIfRuntimeException[T](thunk: => T): T = { try thunk catch { diff --git a/library/src/scala/quoted/Constant.scala b/library/src/scala/quoted/Constant.scala index 3e8ea180eaae..8b068c07201e 100644 --- a/library/src/scala/quoted/Constant.scala +++ b/library/src/scala/quoted/Constant.scala @@ -1,7 +1,16 @@ package scala.quoted -import scala.runtime.quoted.Toolbox +import scala.tasty.trees._ +import scala.tasty.Context object Constant { - def unapply[T](expr: Expr[T])(implicit runner: Toolbox[T]): Option[T] = runner.toConstantOpt(expr) + def unapply[T](expr: Expr[T])(implicit ctx: Context): Option[T] = { + def const(tree: Tree): Option[T] = tree match { + case Literal(c) => Some(c.value.asInstanceOf[T]) + case Block(Nil, e) => const(e) + case Inlined(_, Nil, e) => const(e) + case _ => None + } + const(expr.toTasty) + } } diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 7e9fd0e9d9f1..06b45b00aaa3 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -2,6 +2,8 @@ package scala.quoted import scala.runtime.quoted.Toolbox import scala.runtime.quoted.Unpickler.Pickled +import scala.tasty.trees.Term +import scala.tasty.Context sealed abstract class Expr[T] { final def unary_~ : T = throw new Error("~ should have been compiled away") @@ -14,6 +16,7 @@ sealed abstract class Expr[T] { /** Show a source code like representation of this expression */ final def show(implicit toolbox: Toolbox[T]): String = toolbox.show(this) + final def toTasty(implicit ctx: Context): Term = ctx.toTasty(this) } object Expr { diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 99457263c79a..19cbbf90c765 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -3,9 +3,12 @@ package scala.quoted import scala.quoted.Types.TaggedType import scala.reflect.ClassTag import scala.runtime.quoted.Unpickler.Pickled +import scala.tasty.trees.TypeTree +import scala.tasty.Context sealed abstract class Type[T] { type unary_~ = T + final def toTasty(implicit ctx: Context): TypeTree = ctx.toTasty(this) } /** Some basic type tags, currently incomplete */ @@ -40,7 +43,7 @@ object Types { } /** An Type backed by a tree */ - final class TreeType[Tree](val tree: Tree) extends quoted.Type[Any] { + final class TreeType[Tree](val typeTree: Tree) extends quoted.Type[Any] { override def toString: String = s"Type()" } } diff --git a/library/src/scala/runtime/quoted/Toolbox.scala b/library/src/scala/runtime/quoted/Toolbox.scala index 9fd6c5a18fe4..1f8c43c61c1d 100644 --- a/library/src/scala/runtime/quoted/Toolbox.scala +++ b/library/src/scala/runtime/quoted/Toolbox.scala @@ -1,11 +1,11 @@ package scala.runtime.quoted import scala.annotation.implicitNotFound -import scala.quoted.Expr +import scala.quoted.{Expr, Type} +import scala.tasty -@implicitNotFound("Could not find implicit Toolbox. Default runner can be imported with `import dotty.tools.dotc.quoted.Toolbox._`") +@implicitNotFound("Could not find implicit quoted.Toolbox. Default toolbox can be imported with `import dotty.tools.dotc.quoted.Toolbox._`") trait Toolbox[T] { def run(expr: Expr[T]): T def show(expr: Expr[T]): String - def toConstantOpt(expr: Expr[T]): Option[T] } diff --git a/library/src/scala/runtime/tasty/Toolbox.scala b/library/src/scala/runtime/tasty/Toolbox.scala new file mode 100644 index 000000000000..60995029d355 --- /dev/null +++ b/library/src/scala/runtime/tasty/Toolbox.scala @@ -0,0 +1,140 @@ +package scala.runtime.tasty + +import scala.tasty.constants.Constant +import scala.tasty.modifiers._ +import scala.tasty.names._ +import scala.tasty.trees._ +import scala.tasty.types._ +import scala.tasty.Context + +trait Toolbox { + + // Statements + + def unapplyPackageClause(arg: PackageClause)(implicit ctx: Context): Option[PackageClause.Data] + def unapplyImport(arg: Import)(implicit ctx: Context): Option[Import.Data] + + // Definitions + + def unapplyValDef(arg: ValDef)(implicit ctx: Context): Option[ValDef.Data] + def unapplyDefDef(arg: DefDef)(implicit ctx: Context): Option[DefDef.Data] + def unapplyTypeDef(arg: TypeDef)(implicit ctx: Context): Option[TypeDef.Data] + def unapplyClassDef(arg: ClassDef)(implicit ctx: Context): Option[ClassDef.Data] + def unapplyPackageDef(arg: PackageDef)(implicit ctx: Context): Option[PackageDef.Data] + + // Terms + + def unapplyIdent(arg: Term)(implicit ctx: Context): Option[Ident.Data] + def unapplySelect(arg: Term)(implicit ctx: Context): Option[Select.Data] + def unapplyLiteral(arg: Term)(implicit ctx: Context): Option[Literal.Data] + def unapplyThis(arg: Term)(implicit ctx: Context): Option[This.Data] + def unapplyNew(arg: Term)(implicit ctx: Context): Option[New.Data] + def unapplyNamedArg(arg: Term)(implicit ctx: Context): Option[NamedArg.Data] + def unapplyApply(arg: Term)(implicit ctx: Context): Option[Apply.Data] + def unapplyTypeApply(arg: Term)(implicit ctx: Context): Option[TypeApply.Data] + def unapplySuper(arg: Term)(implicit ctx: Context): Option[Super.Data] + def unapplyTyped(arg: Term)(implicit ctx: Context): Option[Typed.Data] + def unapplyAssign(arg: Term)(implicit ctx: Context): Option[Assign.Data] + def unapplyBlock(arg: Term)(implicit ctx: Context): Option[Block.Data] + def unapplyInlined(arg: Term)(implicit ctx: Context): Option[Inlined.Data] + def unapplyLambda(arg: Term)(implicit ctx: Context): Option[Lambda.Data] + def unapplyIf(arg: Term)(implicit ctx: Context): Option[If.Data] + def unapplyMatch(arg: Term)(implicit ctx: Context): Option[Match.Data] + def unapplyTry(arg: Term)(implicit ctx: Context): Option[Try.Data] + def unapplyReturn(arg: Term)(implicit ctx: Context): Option[Return.Data] + def unapplyRepeated(arg: Term)(implicit ctx: Context): Option[Repeated.Data] + def unapplySelectOuter(arg: Term)(implicit ctx: Context): Option[SelectOuter.Data] + + // Patterns + + def unapplyCaseDef(arg: CaseDef)(implicit ctx: Context): Option[CaseDef.Data] + + def unapplyValue(arg: Pattern)(implicit ctx: Context): Option[Value.Data] + def unapplyBind(arg: Pattern)(implicit ctx: Context): Option[Bind.Data] + def unapplyUnapply(arg: Pattern)(implicit ctx: Context): Option[Unapply.Data] + def unapplyAlternative(arg: Pattern)(implicit ctx: Context): Option[Alternative.Data] + def unapplyTypeTest(arg: Pattern)(implicit ctx: Context): Option[TypeTest.Data] + + // Type trees + + def unapplySynthetic(arg: TypeTree)(implicit ctx: Context): Boolean + def unapplyTypeIdent(arg: TypeTree)(implicit ctx: Context): Option[TypeIdent.Data] + def unapplyTypeSelect(arg: TypeTree)(implicit ctx: Context): Option[TypeSelect.Data] + def unapplySingleton(arg: TypeTree)(implicit ctx: Context): Option[Singleton.Data] + def unapplyRefined(arg: TypeTree)(implicit ctx: Context): Option[Refined.Data] + def unapplyApplied(arg: TypeTree)(implicit ctx: Context): Option[Applied.Data] + def unapplyAnnotated(arg: TypeTree)(implicit ctx: Context): Option[Annotated.Data] + def unapplyAnd(arg: TypeTree)(implicit ctx: Context): Option[And.Data] + def unapplyOr(arg: TypeTree)(implicit ctx: Context): Option[Or.Data] + def unapplyByName(arg: TypeTree)(implicit ctx: Context): Option[ByName.Data] + + def unapplyTypeBoundsTree(arg: TypeBoundsTree)(implicit ctx: Context): Option[TypeBoundsTree.Data] + + // Names + + def unapplySimple(arg: TermName): Option[Simple.Data] + def unapplyQualified(arg: TermName): Option[Qualified.Data] + + def unapplyDefaultGetter(arg: TermName): Option[DefaultGetter.Data] + def unapplyVariant(arg: TermName): Option[Variant.Data] + def unapplySuperAccessor(arg: TermName): Option[SuperAccessor.Data] + def unapplyProtectedAccessor(arg: TermName): Option[ProtectedAccessor.Data] + def unapplyProtectedSetter(arg: TermName): Option[ProtectedSetter.Data] + def unapplyObjectClass(arg: TermName): Option[ObjectClass.Data] + + def unapplySignedName(arg: SignedName): Option[SignedName.Data] + + def unapplyTypeName(arg: TypeName): Option[TypeName.Data] + + // Constants + + def unapplyUnit(arg: Constant): Boolean + def unapplyNull(arg: Constant): Boolean + def unapplyBoolean(arg: Constant): Option[Boolean] + def unapplyByte(arg: Constant): Option[Byte] + def unapplyChar(arg: Constant): Option[Char] + def unapplyShort(arg: Constant): Option[Short] + def unapplyInt(arg: Constant): Option[Int] + def unapplyLong(arg: Constant): Option[Long] + def unapplyFloat(arg: Constant): Option[Float] + def unapplyDouble(arg: Constant): Option[Double] + def unapplyString(arg: Constant): Option[String] + + // Types + + def unapplyConstantType(arg: Type)(implicit ctx: Context): Option[ConstantType.Data] + def unapplySymRef(arg: Type)(implicit ctx: Context): Option[SymRef.Data] + def unapplyNameRef(arg: Type)(implicit ctx: Context): Option[NameRef.Data] + def unapplySuperType(arg: Type)(implicit ctx: Context): Option[SuperType.Data] + def unapplyRefinement(arg: Type)(implicit ctx: Context): Option[Refinement.Data] + def unapplyAppliedType(arg: Type)(implicit ctx: Context): Option[AppliedType.Data] + def unapplyAnnotatedType(arg: Type)(implicit ctx: Context): Option[AnnotatedType.Data] + def unapplyAndType(arg: Type)(implicit ctx: Context): Option[AndType.Data] + def unapplyOrType(arg: Type)(implicit ctx: Context): Option[OrType.Data] + def unapplyByNameType(arg: Type)(implicit ctx: Context): Option[ByNameType.Data] + def unapplyParamRef(arg: Type)(implicit ctx: Context): Option[ParamRef.Data] + def unapplyThisType(arg: Type)(implicit ctx: Context): Option[ThisType.Data] + def unapplyRecursiveThis(arg: Type)(implicit ctx: Context): Option[RecursiveThis.Data] + + def unapplyRecursiveType(arg: RecursiveType)(implicit ctx: scala.tasty.Context): Option[RecursiveType.Data] + + def unapplyMethodType(arg: MethodType)(implicit ctx: scala.tasty.Context): Option[MethodType.Data] + def unapplyPolyType(arg: PolyType)(implicit ctx: scala.tasty.Context): Option[PolyType.Data] + def unapplyTypeLambda(arg: TypeLambda)(implicit ctx: scala.tasty.Context): Option[TypeLambda.Data] + + def unapplyTypeBounds(arg: TypeBounds)(implicit ctx: scala.tasty.Context): Option[TypeBounds.Data] + + // Modifiers + + def unapplyFlags(arg: Flags)(implicit ctx: Context): Option[Flags.Data] + def unapplyQualifiedPrivate(arg: Qualified)(implicit ctx: Context): Option[QualifiedPrivate.Data] + def unapplyQualifiedProtected(arg: Qualified)(implicit ctx: Context): Option[QualifiedProtected.Data] + def unapplyAnnotation(arg: Annotation)(implicit ctx: Context): Option[Annotation.Data] + + // Import selectors + + def unapplySimpleSelector(arg: ImportSelector)(implicit ctx: Context): Option[SimpleSelector.Data] + def unapplyRenameSelector(arg: ImportSelector)(implicit ctx: Context): Option[RenameSelector.Data] + def unapplyOmitSelector(arg: ImportSelector)(implicit ctx: Context): Option[OmitSelector.Data] + +} diff --git a/library/src/scala/tasty/Context.scala b/library/src/scala/tasty/Context.scala new file mode 100644 index 000000000000..afb71b8b10ec --- /dev/null +++ b/library/src/scala/tasty/Context.scala @@ -0,0 +1,19 @@ +package scala.tasty + +import scala.runtime.tasty.Toolbox +import scala.tasty.trees._ + +trait Context { + def owner: Definition + + def toTasty[T](expr: quoted.Expr[T]): Term + def toTasty[T](expr: quoted.Type[T]): TypeTree + + protected[tasty] def toolbox: Toolbox +} + +object Context { + // TODO move to some other place + /** Compiler context available in a ~ at inline site */ + def compilationContext: Context = throw new Exception("Not in inline macro") +} diff --git a/library/src/scala/tasty/ContextProvider.scala b/library/src/scala/tasty/ContextProvider.scala new file mode 100644 index 000000000000..0b5bf1aaf302 --- /dev/null +++ b/library/src/scala/tasty/ContextProvider.scala @@ -0,0 +1,13 @@ +package scala.tasty + +import scala.annotation.implicitNotFound + +@implicitNotFound("Could not find implicit tasty.ContextProvider. Default ContextProvider can be imported with `import dotty.tools.dotc.tasty.ContextProvider._`") +trait ContextProvider { + + /** Provides a Contexts that is valid during the execution of `code`. + * DO NOT use this context of tasty trees that where generated from a different context. + */ + def provide[T](code: Context => T): T + +} diff --git a/library/src/scala/tasty/Id.scala b/library/src/scala/tasty/Id.scala new file mode 100644 index 000000000000..6aae233364c1 --- /dev/null +++ b/library/src/scala/tasty/Id.scala @@ -0,0 +1,5 @@ +package scala.tasty + +trait Id extends Positioned { // untyped ident + def name: String +} diff --git a/library/src/scala/tasty/Position.scala b/library/src/scala/tasty/Position.scala new file mode 100644 index 000000000000..f5071a0a5567 --- /dev/null +++ b/library/src/scala/tasty/Position.scala @@ -0,0 +1,13 @@ +package scala.tasty + +trait Position { + def start: Int + def end: Int + + def sourceFile: java.nio.file.Path + + def startLine: Int + def startColumn: Int + def endLine: Int + def endColumn: Int +} diff --git a/library/src/scala/tasty/Positioned.scala b/library/src/scala/tasty/Positioned.scala new file mode 100644 index 000000000000..18ebc462472f --- /dev/null +++ b/library/src/scala/tasty/Positioned.scala @@ -0,0 +1,5 @@ +package scala.tasty + +trait Positioned { + def pos(implicit ctx: Context): Position +} diff --git a/library/src/scala/tasty/constants/Constant.scala b/library/src/scala/tasty/constants/Constant.scala new file mode 100644 index 000000000000..9e55c48d402e --- /dev/null +++ b/library/src/scala/tasty/constants/Constant.scala @@ -0,0 +1,5 @@ +package scala.tasty.constants + +trait Constant { + def value: Any +} diff --git a/library/src/scala/tasty/constants/package.scala b/library/src/scala/tasty/constants/package.scala new file mode 100644 index 000000000000..d54c2fb3e017 --- /dev/null +++ b/library/src/scala/tasty/constants/package.scala @@ -0,0 +1,48 @@ +package scala.tasty + +package object constants { + + object Unit { + def unapply(arg: Constant)(implicit ctx: Context): Boolean = ctx.toolbox.unapplyUnit(arg) + } + + object Null { + def unapply(arg: Constant)(implicit ctx: Context): Boolean = ctx.toolbox.unapplyNull(arg) + } + + object Boolean { + def unapply(arg: Constant)(implicit ctx: Context): Option[Boolean] = ctx.toolbox.unapplyBoolean(arg) + } + + object Byte { + def unapply(arg: Constant)(implicit ctx: Context): Option[Byte] = ctx.toolbox.unapplyByte(arg) + } + + object Char { + def unapply(arg: Constant)(implicit ctx: Context): Option[Char] = ctx.toolbox.unapplyChar(arg) + } + + object Short { + def unapply(arg: Constant)(implicit ctx: Context): Option[Short] = ctx.toolbox.unapplyShort(arg) + } + + object Int { + def unapply(arg: Constant)(implicit ctx: Context): Option[Int] = ctx.toolbox.unapplyInt(arg) + } + + object Long { + def unapply(arg: Constant)(implicit ctx: Context): Option[Long] = ctx.toolbox.unapplyLong(arg) + } + + object Float { + def unapply(arg: Constant)(implicit ctx: Context): Option[Float] = ctx.toolbox.unapplyFloat(arg) + } + + object Double { + def unapply(arg: Constant)(implicit ctx: Context): Option[Double] = ctx.toolbox.unapplyDouble(arg) + } + + object String { + def unapply(arg: Constant)(implicit ctx: Context): Option[String] = ctx.toolbox.unapplyString(arg) + } +} diff --git a/library/src/scala/tasty/modifiers/Annotation.scala b/library/src/scala/tasty/modifiers/Annotation.scala new file mode 100644 index 000000000000..f107567f2051 --- /dev/null +++ b/library/src/scala/tasty/modifiers/Annotation.scala @@ -0,0 +1,9 @@ +package scala.tasty +package modifiers + +trait Annotation extends Modifier + +object Annotation { + type Data = trees.Term + def unapply(arg: Annotation)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAnnotation(arg) +} diff --git a/library/src/scala/tasty/modifiers/FlagSet.scala b/library/src/scala/tasty/modifiers/FlagSet.scala new file mode 100644 index 000000000000..d7d7b87f10cc --- /dev/null +++ b/library/src/scala/tasty/modifiers/FlagSet.scala @@ -0,0 +1,30 @@ +package scala.tasty.modifiers + +trait FlagSet { + def isProtected: Boolean + def isAbstract: Boolean + def isFinal: Boolean + def isSealed: Boolean + def isCase: Boolean + def isImplicit: Boolean + def isErased: Boolean + def isLazy: Boolean + def isOverride: Boolean + def isInline: Boolean + def isMacro: Boolean // inline method containing toplevel splices + def isStatic: Boolean // mapped to static Java member + def isObject: Boolean // an object or its class (used for a ValDef or a ClassDef extends Modifier respectively) + def isTrait: Boolean // a trait (used for a ClassDef) + def isLocal: Boolean // used in conjunction with Private/private[Type] to mean private[this] extends Modifier proctected[this] + def isSynthetic: Boolean // generated by Scala compiler + def isArtifact: Boolean // to be tagged Java Synthetic + def isMutable: Boolean // when used on a ValDef: a var + def isLabel: Boolean // method generated as a label + def isFieldAccessor: Boolean // a getter or setter + def isCaseAcessor: Boolean // getter for class parameter + def isCovariant: Boolean // type parameter marked “+” + def isContravariant: Boolean // type parameter marked “-” + def isScala2X: Boolean // Imported from Scala2.x + def isDefaultParameterized: Boolean // Method with default parameters + def isStable: Boolean // Method that is assumed to be stable +} diff --git a/library/src/scala/tasty/modifiers/Flags.scala b/library/src/scala/tasty/modifiers/Flags.scala new file mode 100644 index 000000000000..71fc99efb304 --- /dev/null +++ b/library/src/scala/tasty/modifiers/Flags.scala @@ -0,0 +1,9 @@ +package scala.tasty +package modifiers + +trait Flags extends Modifier + +object Flags { + type Data = FlagSet + def unapply(arg: Flags)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyFlags(arg) +} diff --git a/library/src/scala/tasty/modifiers/Modifier.scala b/library/src/scala/tasty/modifiers/Modifier.scala new file mode 100644 index 000000000000..8f8bdb99d2cb --- /dev/null +++ b/library/src/scala/tasty/modifiers/Modifier.scala @@ -0,0 +1,3 @@ +package scala.tasty.modifiers + +trait Modifier diff --git a/library/src/scala/tasty/modifiers/Qualified.scala b/library/src/scala/tasty/modifiers/Qualified.scala new file mode 100644 index 000000000000..daf1decce5fb --- /dev/null +++ b/library/src/scala/tasty/modifiers/Qualified.scala @@ -0,0 +1,14 @@ +package scala.tasty +package modifiers + +trait Qualified extends Modifier + +object QualifiedPrivate { + type Data = types.Type + def unapply(arg: Qualified)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyQualifiedPrivate(arg) +} + +object QualifiedProtected { + type Data = types.Type + def unapply(arg: Qualified)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyQualifiedProtected(arg) +} diff --git a/library/src/scala/tasty/names/Name.scala b/library/src/scala/tasty/names/Name.scala new file mode 100644 index 000000000000..5666b9fde07b --- /dev/null +++ b/library/src/scala/tasty/names/Name.scala @@ -0,0 +1,3 @@ +package scala.tasty.names + +trait Name diff --git a/library/src/scala/tasty/names/PossiblySignedName.scala b/library/src/scala/tasty/names/PossiblySignedName.scala new file mode 100644 index 000000000000..d32347808731 --- /dev/null +++ b/library/src/scala/tasty/names/PossiblySignedName.scala @@ -0,0 +1,3 @@ +package scala.tasty.names + +trait PossiblySignedName diff --git a/library/src/scala/tasty/names/SignedName.scala b/library/src/scala/tasty/names/SignedName.scala new file mode 100644 index 000000000000..d2691f73ba0e --- /dev/null +++ b/library/src/scala/tasty/names/SignedName.scala @@ -0,0 +1,9 @@ +package scala.tasty +package names + +trait SignedName extends PossiblySignedName + +object SignedName { + type Data = (TermName, TypeName, List[TypeName]) + def unapply(arg: SignedName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySignedName(arg) +} diff --git a/library/src/scala/tasty/names/TermName.scala b/library/src/scala/tasty/names/TermName.scala new file mode 100644 index 000000000000..9274b39538dc --- /dev/null +++ b/library/src/scala/tasty/names/TermName.scala @@ -0,0 +1,3 @@ +package scala.tasty.names + +trait TermName extends Name with PossiblySignedName diff --git a/library/src/scala/tasty/names/TypeName.scala b/library/src/scala/tasty/names/TypeName.scala new file mode 100644 index 000000000000..0a7908f2867f --- /dev/null +++ b/library/src/scala/tasty/names/TypeName.scala @@ -0,0 +1,9 @@ +package scala.tasty +package names + +trait TypeName extends Name + +object TypeName { + type Data = TermName + def unapply(arg: TypeName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeName(arg) +} diff --git a/library/src/scala/tasty/names/package.scala b/library/src/scala/tasty/names/package.scala new file mode 100644 index 000000000000..225de9da4346 --- /dev/null +++ b/library/src/scala/tasty/names/package.scala @@ -0,0 +1,52 @@ +package scala.tasty + +package object names { + + object Simple { + type Data = String + def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySimple(arg) + } + + // s"$prefix.$name" + object Qualified { + type Data = (TermName, String) + def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyQualified(arg) + } + + // s"$methodName${"$default$"}${idx+1}" + object DefaultGetter { + type Data = (TermName, String) + def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyDefaultGetter(arg) + } + + // s"${if (covariant) "+" else "-"}$underlying" + object Variant { + type Data = (TermName, Boolean) + def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyVariant(arg) + } + + // s"${"super$"}$underlying" + object SuperAccessor { + type Data = TermName + def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySuperAccessor(arg) + } + + // s"${"protected$"}$underlying" + object ProtectedAccessor { + type Data = TermName + def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyProtectedAccessor(arg) + } + + // s"${"protected$set"}$underlying" + object ProtectedSetter { + type Data = TermName + def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyProtectedSetter(arg) + } + + // s"$underlying${"$"}" + object ObjectClass { + type Data = TermName + def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyObjectClass(arg) + } + +} diff --git a/library/src/scala/tasty/trees/CaseDef.scala b/library/src/scala/tasty/trees/CaseDef.scala new file mode 100644 index 000000000000..d269e00b7958 --- /dev/null +++ b/library/src/scala/tasty/trees/CaseDef.scala @@ -0,0 +1,9 @@ +package scala.tasty +package trees + +trait CaseDef extends Tree + +object CaseDef { + type Data = (Pattern, Option[Term], Term) + def unapply(arg: CaseDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyCaseDef(arg) +} diff --git a/library/src/scala/tasty/trees/ClassDef.scala b/library/src/scala/tasty/trees/ClassDef.scala new file mode 100644 index 000000000000..92dcba8d0f04 --- /dev/null +++ b/library/src/scala/tasty/trees/ClassDef.scala @@ -0,0 +1,13 @@ +package scala.tasty +package trees + +import scala.tasty.modifiers.Modifier + +trait ClassDef extends Definition { + def mods(implicit ctx: Context): List[Modifier] +} + +object ClassDef { + type Data = (names.TypeName, DefDef, List[Tree] /* List[Term | TypeTree] */, Option[ValDef], List[Statement]) + def unapply(arg: ClassDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyClassDef(arg) +} diff --git a/library/src/scala/tasty/trees/DefDef.scala b/library/src/scala/tasty/trees/DefDef.scala new file mode 100644 index 000000000000..72afe2a032f4 --- /dev/null +++ b/library/src/scala/tasty/trees/DefDef.scala @@ -0,0 +1,13 @@ +package scala.tasty +package trees + +import scala.tasty.modifiers.Modifier + +trait DefDef extends Definition { + def mods(implicit ctx: Context): List[Modifier] +} + +object DefDef { + type Data = (names.TermName, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term]) + def unapply(arg: DefDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyDefDef(arg) +} diff --git a/library/src/scala/tasty/trees/Definition.scala b/library/src/scala/tasty/trees/Definition.scala new file mode 100644 index 000000000000..9fc800a2cedd --- /dev/null +++ b/library/src/scala/tasty/trees/Definition.scala @@ -0,0 +1,7 @@ +package scala.tasty +package trees + +trait Definition extends Statement { + def owner(implicit ctx: Context): Definition + def localContext(implicit ctx: Context): Context +} diff --git a/library/src/scala/tasty/trees/Import.scala b/library/src/scala/tasty/trees/Import.scala new file mode 100644 index 000000000000..9d7ceef03173 --- /dev/null +++ b/library/src/scala/tasty/trees/Import.scala @@ -0,0 +1,9 @@ +package scala.tasty +package trees + +trait Import extends Statement + +object Import { + type Data = (Term, List[ImportSelector]) + def unapply(arg: Import)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyImport(arg) +} diff --git a/library/src/scala/tasty/trees/ImportSelector.scala b/library/src/scala/tasty/trees/ImportSelector.scala new file mode 100644 index 000000000000..4a24ba5cc996 --- /dev/null +++ b/library/src/scala/tasty/trees/ImportSelector.scala @@ -0,0 +1,19 @@ +package scala.tasty +package trees + +trait ImportSelector + +object SimpleSelector { + type Data = Id + def unapply(arg: ImportSelector)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySimpleSelector(arg) +} + +object RenameSelector { + type Data = (Id, Id) + def unapply(arg: ImportSelector)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRenameSelector(arg) +} + +object OmitSelector { + type Data = Id + def unapply(arg: ImportSelector)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyOmitSelector(arg) +} diff --git a/library/src/scala/tasty/trees/PackageClause.scala b/library/src/scala/tasty/trees/PackageClause.scala new file mode 100644 index 000000000000..6b5a15011d72 --- /dev/null +++ b/library/src/scala/tasty/trees/PackageClause.scala @@ -0,0 +1,11 @@ +package scala.tasty +package trees + +trait PackageClause extends TopLevelStatement { + def definition(implicit ctx: Context): Definition +} + +object PackageClause { + type Data = (Term, List[TopLevelStatement]) + def unapply(arg: PackageClause)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyPackageClause(arg) +} diff --git a/library/src/scala/tasty/trees/PackageDef.scala b/library/src/scala/tasty/trees/PackageDef.scala new file mode 100644 index 000000000000..36b4b2466b15 --- /dev/null +++ b/library/src/scala/tasty/trees/PackageDef.scala @@ -0,0 +1,9 @@ +package scala.tasty +package trees + +trait PackageDef extends Definition + +object PackageDef { + type Data = (names.Name, List[Statement]) + def unapply(arg: PackageDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyPackageDef(arg) +} diff --git a/library/src/scala/tasty/trees/Pattern.scala b/library/src/scala/tasty/trees/Pattern.scala new file mode 100644 index 000000000000..eeba5b4c5ce2 --- /dev/null +++ b/library/src/scala/tasty/trees/Pattern.scala @@ -0,0 +1,33 @@ +package scala.tasty +package trees + +import scala.tasty.types.Type + +trait Pattern extends Tree { + def tpe: Type +} + +object Value { + type Data = Term + def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyValue(arg) +} + +object Bind { + type Data = (names.TermName, Pattern) + def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyBind(arg) +} + +object Unapply { + type Data = (Term, List[Term], List[Pattern]) + def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyUnapply(arg) +} + +object Alternative { + type Data = List[Pattern] + def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAlternative(arg) +} + +object TypeTest { + type Data = TypeTree + def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeTest(arg) +} diff --git a/library/src/scala/tasty/trees/Statement.scala b/library/src/scala/tasty/trees/Statement.scala new file mode 100644 index 000000000000..918e8226104c --- /dev/null +++ b/library/src/scala/tasty/trees/Statement.scala @@ -0,0 +1,3 @@ +package scala.tasty.trees + +trait Statement extends TopLevelStatement diff --git a/library/src/scala/tasty/trees/Term.scala b/library/src/scala/tasty/trees/Term.scala new file mode 100644 index 000000000000..75cc6347b059 --- /dev/null +++ b/library/src/scala/tasty/trees/Term.scala @@ -0,0 +1,9 @@ +package scala.tasty.trees + +import scala.tasty.types.Type + +trait Term extends Statement { + def tpe: Type +} + + diff --git a/library/src/scala/tasty/trees/TopLevelStatement.scala b/library/src/scala/tasty/trees/TopLevelStatement.scala new file mode 100644 index 000000000000..96ffdac8b3f8 --- /dev/null +++ b/library/src/scala/tasty/trees/TopLevelStatement.scala @@ -0,0 +1,3 @@ +package scala.tasty.trees + +trait TopLevelStatement extends Tree diff --git a/library/src/scala/tasty/trees/Tree.scala b/library/src/scala/tasty/trees/Tree.scala new file mode 100644 index 000000000000..3aae962cc8da --- /dev/null +++ b/library/src/scala/tasty/trees/Tree.scala @@ -0,0 +1,5 @@ +package scala.tasty.trees + +import scala.tasty.Positioned + +trait Tree extends Positioned diff --git a/library/src/scala/tasty/trees/TypeBoundsTree.scala b/library/src/scala/tasty/trees/TypeBoundsTree.scala new file mode 100644 index 000000000000..ea4023049e8f --- /dev/null +++ b/library/src/scala/tasty/trees/TypeBoundsTree.scala @@ -0,0 +1,13 @@ +package scala.tasty +package trees + +import scala.tasty.types.TypeBounds + +trait TypeBoundsTree extends Tree { + def tpe: TypeBounds +} + +object TypeBoundsTree { + type Data = (TypeTree, TypeTree) + def unapply(arg: TypeBoundsTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeBoundsTree(arg) +} diff --git a/library/src/scala/tasty/trees/TypeDef.scala b/library/src/scala/tasty/trees/TypeDef.scala new file mode 100644 index 000000000000..6d05bcb0d21d --- /dev/null +++ b/library/src/scala/tasty/trees/TypeDef.scala @@ -0,0 +1,13 @@ +package scala.tasty +package trees + +import scala.tasty.modifiers.Modifier + +trait TypeDef extends Definition { + def mods(implicit ctx: Context): List[Modifier] +} + +object TypeDef { + type Data = (names.TypeName, Tree /* Type | TypeBounds */) + def unapply(arg: TypeDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeDef(arg) +} diff --git a/library/src/scala/tasty/trees/TypeTree.scala b/library/src/scala/tasty/trees/TypeTree.scala new file mode 100644 index 000000000000..623b989fc08c --- /dev/null +++ b/library/src/scala/tasty/trees/TypeTree.scala @@ -0,0 +1,8 @@ +package scala.tasty.trees + +import scala.tasty.types + +/** Trees denoting types */ +trait TypeTree extends Tree { + def tpe: types.Type +} diff --git a/library/src/scala/tasty/trees/ValDef.scala b/library/src/scala/tasty/trees/ValDef.scala new file mode 100644 index 000000000000..6be0a4c416fa --- /dev/null +++ b/library/src/scala/tasty/trees/ValDef.scala @@ -0,0 +1,13 @@ +package scala.tasty +package trees + +import scala.tasty.modifiers.Modifier + +trait ValDef extends Definition { + def mods(implicit ctx: Context): List[Modifier] +} + +object ValDef { + type Data = (names.TermName, TypeTree, Option[Term]) + def unapply(arg: ValDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyValDef(arg) +} diff --git a/library/src/scala/tasty/trees/package.scala b/library/src/scala/tasty/trees/package.scala new file mode 100644 index 000000000000..df8220071956 --- /dev/null +++ b/library/src/scala/tasty/trees/package.scala @@ -0,0 +1,160 @@ +package scala.tasty + +import scala.runtime.tasty.Toolbox + +package object trees { + + // Term trees + + object Ident { + type Data = (names.TermName) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyIdent(arg) + } + + object Select { + type Data = (Term, names.PossiblySignedName) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySelect(arg) + } + + object Literal { + type Data = constants.Constant + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyLiteral(arg) + } + + object This { + type Data = Option[Id] + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyThis(arg) + } + + object New { + type Data = TypeTree + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyNew(arg) + } + + object NamedArg { + type Data = (names.TermName, Term) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyNamedArg(arg) + } + + object Apply { + type Data = (Term, List[Term]) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyApply(arg) + } + + object TypeApply { + type Data = (Term, List[TypeTree]) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeApply(arg) + } + + object Super { + type Data = (Term, Option[Id]) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySuper(arg) + } + + object Typed { + type Data = (Term, TypeTree) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTyped(arg) + } + + object Assign { + type Data = (Term, Term) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAssign(arg) + } + + object Block { + type Data = (List[Statement], Term) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyBlock(arg) + } + + object Inlined { + type Data = (Term, List[Definition], Term) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyInlined(arg) + } + + object Lambda { + type Data = (Term, Option[TypeTree]) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyLambda(arg) + } + + object If { + type Data = (Term, Term, Term) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyIf(arg) + } + + object Match { + type Data = (Term, List[CaseDef]) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyMatch(arg) + } + + object Try { + type Data = (Term, List[CaseDef], Option[Term]) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTry(arg) + } + + object Return { + type Data = Term + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyReturn(arg) + } + + object Repeated { + type Data = List[Term] + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRepeated(arg) + } + + object SelectOuter { + type Data = (Term, Int, types.Type) + def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySelectOuter(arg) + } + + // Type trees + + object Synthetic { + def unapply(arg: TypeTree)(implicit ctx: Context): Boolean = ctx.toolbox.unapplySynthetic(arg) + } + + object TypeIdent { + type Data = names.TypeName + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeIdent(arg) + } + + object TypeSelect { + type Data = (Term, names.TypeName) + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeSelect(arg) + } + + object Singleton { + type Data = Term + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySingleton(arg) + } + + object Refined { + type Data = (TypeTree, List[Definition]) + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRefined(arg) + } + + object Applied { + type Data = (TypeTree, List[TypeTree]) + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyApplied(arg) + } + + object Annotated { + type Data = (TypeTree, Term) + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAnnotated(arg) + } + + object And { + type Data = (TypeTree, TypeTree) + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAnd(arg) + } + + object Or { + type Data = (TypeTree, TypeTree) + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyOr(arg) + } + + object ByName { + type Data = TypeTree + def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyByName(arg) + } + +} diff --git a/library/src/scala/tasty/types/LambdaType.scala b/library/src/scala/tasty/types/LambdaType.scala new file mode 100644 index 000000000000..f4f2b61ef938 --- /dev/null +++ b/library/src/scala/tasty/types/LambdaType.scala @@ -0,0 +1,25 @@ +package scala.tasty +package types + +trait LambdaType[ParamName <: names.Name, ParamInfo <: MaybeType] extends Type + +trait MethodType extends LambdaType[names.TermName, Type] { + def isImplicit: Boolean + def isErased: Boolean +} +object MethodType { + type Data = (List[names.TermName], List[Type], Type) + def unapply(arg: MethodType)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyMethodType(arg) +} + +trait PolyType extends LambdaType[names.TypeName, TypeBounds] +object PolyType { + type Data = (List[names.TypeName], List[TypeBounds], Type) + def unapply(arg: PolyType)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyPolyType(arg) +} + +trait TypeLambda extends LambdaType[names.TypeName, TypeBounds] +object TypeLambda { + type Data = (List[names.TypeName], List[TypeBounds], Type) + def unapply(arg: TypeLambda)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeLambda(arg) +} diff --git a/library/src/scala/tasty/types/MaybeType.scala b/library/src/scala/tasty/types/MaybeType.scala new file mode 100644 index 000000000000..992c66fec277 --- /dev/null +++ b/library/src/scala/tasty/types/MaybeType.scala @@ -0,0 +1,3 @@ +package scala.tasty.types + +trait MaybeType diff --git a/library/src/scala/tasty/types/NoPrefix.scala b/library/src/scala/tasty/types/NoPrefix.scala new file mode 100644 index 000000000000..3b1b56dc7514 --- /dev/null +++ b/library/src/scala/tasty/types/NoPrefix.scala @@ -0,0 +1,5 @@ +package scala.tasty.types + +sealed trait NoPrefix extends MaybeType + +case object NoPrefix extends NoPrefix diff --git a/library/src/scala/tasty/types/RecursiveType.scala b/library/src/scala/tasty/types/RecursiveType.scala new file mode 100644 index 000000000000..085f8bf9ec58 --- /dev/null +++ b/library/src/scala/tasty/types/RecursiveType.scala @@ -0,0 +1,9 @@ +package scala.tasty +package types + +trait RecursiveType extends Type + +object RecursiveType { + type Data = Type + def unapply(arg: RecursiveType)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRecursiveType(arg) +} diff --git a/library/src/scala/tasty/types/Type.scala b/library/src/scala/tasty/types/Type.scala new file mode 100644 index 000000000000..4d9d2f1f6e1e --- /dev/null +++ b/library/src/scala/tasty/types/Type.scala @@ -0,0 +1,3 @@ +package scala.tasty.types + +trait Type extends MaybeType diff --git a/library/src/scala/tasty/types/TypeBounds.scala b/library/src/scala/tasty/types/TypeBounds.scala new file mode 100644 index 000000000000..0e1f69abdc0a --- /dev/null +++ b/library/src/scala/tasty/types/TypeBounds.scala @@ -0,0 +1,9 @@ +package scala.tasty +package types + +trait TypeBounds extends MaybeType + +object TypeBounds { + type Data = (Type, Type) + def unapply(arg: TypeBounds)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeBounds(arg) +} diff --git a/library/src/scala/tasty/types/package.scala b/library/src/scala/tasty/types/package.scala new file mode 100644 index 000000000000..811f08b998d9 --- /dev/null +++ b/library/src/scala/tasty/types/package.scala @@ -0,0 +1,72 @@ +package scala.tasty + +import scala.tasty.trees.Term + +package object types { + + object ConstantType { + type Data = constants.Constant + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyConstantType(arg) + } + + object SymRef { + type Data = (trees.Definition, MaybeType /* Type | NoPrefix */) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySymRef(arg) + } + + object NameRef { + type Data = (names.Name, MaybeType /* Type | NoPrefix */) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyNameRef(arg) + } + + object SuperType { + type Data = (Type, Type) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySuperType(arg) + } + + object Refinement { + type Data = (Type, names.Name, MaybeType /* Type | TypeBounds */) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRefinement(arg) + } + + object AppliedType { + type Data = (Type, List[types.MaybeType /* Type | TypeBounds */]) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAppliedType(arg) + } + + object AnnotatedType { + type Data = (Type, Term) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAnnotatedType(arg) + } + + object AndType { + type Data = (Type, Type) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAndType(arg) + } + + object OrType { + type Data = (Type, Type) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyOrType(arg) + } + + object ByNameType { + type Data = Type + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyByNameType(arg) + } + + object ParamRef { + type Data = (LambdaType[_, _], Int) + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyParamRef(arg) + } + + object ThisType { + type Data = Type + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyThisType(arg) + } + + object RecursiveThis { + type Data = RecursiveType + def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRecursiveThis(arg) + } + +} diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala new file mode 100644 index 000000000000..57b6c103749c --- /dev/null +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -0,0 +1,533 @@ +package scala.tasty +package util + +import scala.tasty.constants._ +import scala.tasty.names._ +import scala.tasty.modifiers._ +import scala.tasty.trees._ +import scala.tasty.types._ + +object TastyPrinter { + + def stringOf(tree: Tree)(implicit ctx: Context): String = { + implicit val buff: StringBuilder = new StringBuilder + visit(tree) + buff.toString() + } + + def stringOf(tpe: MaybeType)(implicit ctx: Context): String = { + implicit val buff: StringBuilder = new StringBuilder + visit(tpe) + buff.toString() + } + + def stringOf(name: Name)(implicit ctx: Context): String = { + implicit val buff: StringBuilder = new StringBuilder + visit(name) + buff.toString() + } + + def stringOf(name: PossiblySignedName)(implicit ctx: Context): String = { + implicit val buff: StringBuilder = new StringBuilder + visit(name) + buff.toString() + } + + def stringOf(mod: Modifier)(implicit ctx: Context): String = { + implicit val buff: StringBuilder = new StringBuilder + visit(mod) + buff.toString() + } + + def stringOf(mod: Constant)(implicit ctx: Context): String = { + implicit val buff: StringBuilder = new StringBuilder + visit(mod) + buff.toString() + } + + private def visit(tree: Tree)(implicit buff: StringBuilder, ctx: Context): Unit = tree match { + case Ident(name) => + buff append "Ident(" + visit(name: Name) + buff append ")" + case Select(qualifier, name) => + buff append "Select(" + visit(qualifier) + buff append ", " + visit(name) + buff append ")" + case This(qual) => + buff append "This(" append qual append ")" + case Super(qual, mix) => + buff append "TypeApply(" + visit(qual) + buff append ", " + buff append mix + buff append ")" + case Apply(fun, args) => + buff append "Apply(" + visit(fun) + buff append ", " + visitAny(args) + buff append ")" + case TypeApply(fun, args) => + buff append "TypeApply(" + visit(fun) + buff append ", " + visitAny(args) + buff append ")" + case Literal(const) => + buff append "Literal(" + visit(const) + buff append ")" + case New(tpt) => + buff append "New(" + visit(tpt) + buff append ")" + case Typed(expr, tpt) => + buff append "Typed(" + visit(expr) + buff append ", " + visit(tpt) + buff append ")" + case NamedArg(name, arg) => + buff append "NamedArg(" + visit(name: Name) + buff append ", " + visit(arg) + buff append ")" + case Assign(lhs, rhs) => + buff append "Assign(" + visit(lhs) + buff append ", " + visit(rhs) + buff append ")" + case Block(stats, expr) => + buff append "Block(" + visitAny(stats) + buff append ", " + visit(expr) + buff append ")" + case If(cond, thenp, elsep) => + buff append "If(" + visit(cond) + buff append ", " + visit(thenp) + buff append ", " + visit(elsep) + buff append ")" + case Lambda(meth, tpt) => + buff append "Lambda(" + visit(meth) + buff append ", " + visitAny(tpt) + buff append ")" + case Match(selector, cases) => + buff append "Match(" + visit(selector) + buff append ", " + visitAny(cases) + buff append ")" + case CaseDef(pat, guard, body) => + buff append "CaseDef(" + visit(pat) + buff append ", " + visitAny(guard) + buff append ", " + visit(body) + buff append ")" + case Return(expr) => + buff append "Return(" + visit(expr) + buff append ")" + case Try(block, handlers, finalizer) => + buff append "Try(" + visit(block) + buff append ", " + visitAny(handlers) + buff append ", " + visitAny(finalizer) + buff append ")" + case Repeated(elems) => + buff append "Repeated(" + visitAny(elems) + buff append ")" + case Inlined(call, bindings, expansion) => + buff append "Inlined(" + visit(call) + buff append ", " + visitAny(bindings) + buff append ", " + visit(expansion) + buff append ")" + case Synthetic() => + buff append "Synthetic()" + case TypeIdent(name) => + buff append "Ident(" // FIXME print as TypeIdent + visit(name) + buff append ")" + case TypeSelect(qualifier, name) => + buff append "TypeSelect(" + visit(qualifier) + buff append ", " + visit(name) + buff append ")" + case Singleton(ref) => + buff append "Singleton(" + visit(ref) + buff append ")" + case And(left, right) => + buff append "And(" + visit(left) + buff append ", " + visit(right) + buff append ")" + case Or(left, right) => + buff append "Or(" + visit(left) + buff append ", " + visit(right) + buff append ")" + case Refined(tpt, refinements) => + buff append "Refined(" + visit(tpt) + buff append ", " + visitAny(refinements) + buff append ")" + case Applied(tpt, args) => + buff append "Applied(" + visit(tpt) + buff append ", " + visitAny(args) + buff append ")" + case ByName(result) => + buff append "ByName(" + visit(result) + buff append ")" + case TypeBoundsTree(lo, hi) => + buff append "TypeBoundsTree(" + visit(lo) + buff append ", " + visit(hi) + buff append ")" + case Annotated(arg, annot) => + buff append "Annotated(" + visit(arg) + buff append ", " + visit(annot) + buff append ")" + case Value(v) => + buff append "Value(" + visit(v) + buff append ")" + case Bind(name, body) => + buff append "Bind(" + visit(name: Name) + buff append ", " + visit(body) + buff append ")" + case Unapply(fun, implicits, patterns) => + buff append "Unapply(" + visit(fun) + buff append ", " + visitAny(implicits) + buff append ", " + visitAny(patterns) + buff append ")" + case Alternative(patterns) => + buff append "Alternative(" + visitAny(patterns) + buff append ")" + case TypeTest(tpt) => + buff append "TypeTest(" + visit(tpt) + buff append ")" + case ValDef(name, tpt, rhs) => + buff append "ValDef(" + visit(name: Name) + buff append ", " + visit(tpt) + buff append ", " + visitAny(rhs) + buff append ")" + case DefDef(name, typeParams, paramss, returnTpt, rhs) => + buff append "DefDef(" + visit(name: Name) + buff append ", " + visitAny(typeParams) + buff append ", " + visitAny(paramss) + buff append ", " + visit(returnTpt) + buff append ", " + visitAny(rhs) + buff append ")" + case TypeDef(name, rhs) => + buff append "TypeDef(" + visit(name: Name) + buff append ", " + visit(rhs) + buff append ")" + case ClassDef(name, constr, parents, self, body) => + buff append "ClassDef(" + visit(name: Name) + buff append ", " + visit(constr) + buff append ", " + visitAny(parents) + buff append ", " + visitAny(self) + buff append ", " + visitAny(body) + buff append ")" + case PackageDef(name, members) => + buff append "PackageDef(" + visit(name: Name) + buff append ", " + visitAny(members) + buff append ")" + case Import(expr, selectors) => + buff append "Import(" + visit(expr) + buff append ", " + visitAny(selectors) + buff append ")" + case PackageClause(pid, stats) => + buff append "PackageClause(" + visit(pid) + buff append ", " + visitAny(stats) + buff append ")" + } + + private def visitAny(x: Any)(implicit buff: StringBuilder, ctx: Context): Unit = x match { + case x: Tree => visit(x) + case x: MaybeType => visit(x) + case x: Name => visit(x) + case x: PossiblySignedName => visit(x) + case x: Constant => visit(x) + case x: Modifier => visit(x) + case x: ImportSelector => visit(x) + case x0 :: xs => + buff append "List(" + visitAny(x0) + def visitNext(xs: List[_]): Unit = xs match { + case y :: ys => + buff append ", " + visitAny(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + case Some(y) => + buff append "Some(" + visitAny(y) + buff append ")" + case None => buff append "None" + } + + private def visit(const: Constant)(implicit buff: StringBuilder, ctx: Context): Unit = const match { + case constants.Unit() => buff append "Unit()" + case constants.Null() => buff append "Null()" + case constants.Boolean(value) => buff append "Boolean(" append value append ")" + case constants.Byte(value) => buff append "Byte(" append value append ")" + case constants.Short(value) => buff append "Short(" append value append ")" + case constants.Char(value) => buff append "Char('" append value append "')" + case constants.Int(value) => buff append "Int(" append value append ")" + case constants.Long(value) => buff append "Long(" append value append ")" + case constants.Float(value) => buff append "Float(" append value append ")" + case constants.Double(value) => buff append "Double(" append value append ")" + case constants.String(value) => buff append "String(\"" append value append "\")" // TODO escape string characters? + } + + private def visit(name: PossiblySignedName)(implicit buff: StringBuilder, ctx: Context): Unit = name match { + case SignedName(underlying, resSig, paramsSigs) => + buff append "SignedName(" + visit(underlying: Name) + buff append ", " + visit(resSig) + buff append ", " + visitAny(paramsSigs) + buff append ")" + case name: TermName => visit(name: Name) + } + + private def visit(name: Name)(implicit buff: StringBuilder, ctx: Context): Unit = name match { + case TypeName(underlying) => + buff append "TypeName(" + visit(underlying: Name) + buff append ")" + case Simple(strName) => + buff append "Simple(" append strName append ")" + case Qualified(qual, strName) => + buff append "Qualified(" + visit(qual: Name) + buff append "," + buff append strName + buff append ")" + case DefaultGetter(underlying, strName) => + buff append "DefaultGetter(" + visit(underlying: Name) + buff append "," + buff append strName + buff append ")" + case Variant(underlying, variance) => + buff append "Variant(" + visit(underlying: Name) + buff append "," + buff append variance + buff append ")" + case SuperAccessor(underlying) => + buff append "SuperAccessor(" + visit(underlying: Name) + buff append ")" + case ProtectedAccessor(underlying) => + buff append "ProtectedAccessor(" + visit(underlying: Name) + buff append ")" + case ProtectedSetter(underlying) => + buff append "ProtectedSetter(" + visit(underlying: Name) + buff append ")" + case ObjectClass(underlying) => + buff append "ObjectClass(" + visit(underlying: Name) + buff append ")" + } + + private def visit(selector: ImportSelector)(implicit buff: StringBuilder, ctx: Context): Unit = selector match { + case SimpleSelector(id) => buff append "SimpleSelector(" append id append ")" + case OmitSelector(id) => buff append "OmitSelector(" append id append ")" + case RenameSelector(id1, id2) => + buff append "RenameSelector(" append id1 append ", " append id2 append ")" + } + + private def visit(tpe: MaybeType)(implicit buff: StringBuilder, ctx: Context): Unit = { + def visitName(sym: Definition): Unit = sym match { + case ValDef(name, _, _) => visit(name: Name) + case DefDef(name, _, _, _, _) => visit(name: Name) + case TypeDef(name, _) => visit(name: Name) + case ClassDef(name, _, _, _, _) => visit(name: Name) + case PackageDef(name, _) => visit(name: Name) + case _ => buff append "NoDefinition" + } + + tpe match { + case types.ConstantType(value) => + buff append "ConstantType(" + visit(value) + buff append ")" + case types.SymRef(sym, qual) => + buff append "SymRef(<" + visitName(sym) + buff append ">, " + visit(qual) + buff append ")" + case types.NameRef(name, qual) => + buff append "NameRef(" + visit(name) + buff append ", " + visit(qual) + buff append ")" + case types.Refinement(parent, name, info) => + buff append "Refinement(" + visit(parent) + buff append ", " + visit(name) + buff append ", " + visit(info) + buff append ")" + case types.AppliedType(tycon, args) => + buff append "AppliedType(" + visit(tycon) + buff append ", " + visitAny(args) + buff append ")" + case types.AnnotatedType(underlying, annot) => + buff append "AnnotatedType(" + visit(underlying) + buff append ", " + visit(annot) + buff append ")" + case types.AndType(left, right) => + buff append "AndType(" + visit(left) + buff append ", " + visit(right) + buff append ")" + case types.OrType(left, right) => + buff append "OrType(" + visit(left) + buff append ", " + visit(right) + buff append ")" + case types.ByNameType(underlying) => + buff append "ByNameType(" + visit(underlying) + buff append ")" + case types.ParamRef(binder, idx) => + buff append "ParamRef(" + visit(binder) + buff append ", " append idx append ")" + case types.ThisType(tp) => + buff append "ThisType(" + visit(tp) + buff append ")" + case types.RecursiveThis(binder) => + buff append "RecursiveThis(" + visit(binder) + buff append ")" + case types.MethodType(argNames, argTypes, resType) => + buff append "MethodType(" + visitAny(argNames) + buff append ", " + visitAny(argTypes) + buff append ", " + visitAny(resType) + buff append ")" + case types.PolyType(argNames, argBounds, resType) => + buff append "PolyType(" + visitAny(argNames) + buff append ", " + visitAny(argBounds) + buff append ", " + visitAny(resType) + buff append ")" + case types.TypeLambda(argNames, argBounds, resType) => + buff append "TypeLambda(" + visitAny(argNames) + buff append ", " + visitAny(argBounds) + buff append ", " + visitAny(resType) + buff append ")" + case TypeBounds(lo, hi) => + buff append "TypeBounds(" + visit(lo) + buff append ", " + visit(hi) + buff append ")" + case tp: NoPrefix => + buff append "NoPrefix" + } + } + + private def visit(mod: Modifier)(implicit buff: StringBuilder, ctx: Context): Unit = mod match { + case Flags(flags) => + buff append "Flags(" append flags append ")" + case QualifiedPrivate(tp) => + buff append "QualifiedPrivate(" + visit(tp) + buff append ")" + case QualifiedProtected(tp) => + buff append "QualifiedProtected(" + visit(tp) + buff append ")" + case Annotation(tree) => + buff append "Annotation(" + visit(tree) + buff append ")" + } +} diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala new file mode 100644 index 000000000000..c510860a4e96 --- /dev/null +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -0,0 +1,108 @@ +package scala.tasty.util + +import scala.tasty.trees._ +import scala.tasty.Context + +abstract class TreeAccumulator[X] { + + // Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node. + def apply(x: X, tree: Tree)(implicit ctx: Context): X + + def apply(x: X, trees: Traversable[Tree])(implicit ctx: Context): X = (x /: trees)(apply) + + def foldOver(x: X, tree: Tree)(implicit ctx: Context): X = { + def localCtx(definition: Definition): Context = definition.localContext + tree match { + case Ident(name) => + x + case Select(qualifier, name) => + this(x, qualifier) + case This(qual) => + x + case Super(qual, mix) => + this(x, qual) + case Apply(fun, args) => + this(this(x, fun), args) + case TypeApply(fun, args) => + this(this(x, fun), args) + case Literal(const) => + x + case New(tpt) => + this(x, tpt) + case Typed(expr, tpt) => + this(this(x, expr), tpt) + case NamedArg(name, arg) => + this(x, arg) + case Assign(lhs, rhs) => + this(this(x, lhs), rhs) + case Block(stats, expr) => + this(this(x, stats), expr) + case If(cond, thenp, elsep) => + this(this(this(x, cond), thenp), elsep) + case Lambda(meth, tpt) => + val a = this(x, meth) + tpt.fold(a)(b => this(a, b)) + case Match(selector, cases) => + this(this(x, selector), cases) + case CaseDef(pat, guard, body) => + this(this(this(x, pat), guard), body) + case Return(expr) => + this(x, expr) + case Try(block, handler, finalizer) => + this(this(this(x, block), handler), finalizer) + case Repeated(elems) => + this(x, elems) + case Inlined(call, bindings, expansion) => + this(this(x, bindings), expansion) + case TypeIdent(name) => + x + case TypeSelect(qualifier, name) => + this(x, qualifier) + case Singleton(ref) => + this(x, ref) + case And(left, right) => + this(this(x, left), right) + case Or(left, right) => + this(this(x, left), right) + case Refined(tpt, refinements) => + this(this(x, tpt), refinements) + case Applied(tpt, args) => + this(this(x, tpt), args) + case ByName(result) => + this(x, result) + case TypeBoundsTree(lo, hi) => + this(this(x, lo), hi) + case Annotated(arg, annot) => + this(this(x, arg), annot) + case Value(v) => + this(x, v) + case Bind(_, body) => + this(x, body) + case Unapply(fun, implicits, patterns) => + this(this(this(x, fun), implicits), patterns) + case Alternative(patterns) => + this(x, patterns) + case TypeTest(tpt) => + this(x, tpt) + case vdef @ ValDef(_, tpt, rhs) => + implicit val ctx = localCtx(vdef) + this(this(x, tpt), rhs) + case ddef @ DefDef(_, tparams, vparamss, tpt, rhs) => + implicit val ctx = localCtx(ddef) + this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs) + case tdef @ TypeDef(name, rhs) => + implicit val ctx = localCtx(tdef) + this(x, rhs) + case cdef @ ClassDef(_, constr, parents, self, body) => + implicit val ctx = localCtx(cdef) + this(this(this(this(x, constr), parents), self), body) + case Import(expr, selectors) => + this(x, expr) + case clause @ PackageClause(pid, stats) => + this(this(x, pid), stats)(localCtx(clause.definition)) + case _ => + x + } + } + +} diff --git a/library/src/scala/tasty/util/TreeTraverser.scala b/library/src/scala/tasty/util/TreeTraverser.scala new file mode 100644 index 000000000000..d305aa868a20 --- /dev/null +++ b/library/src/scala/tasty/util/TreeTraverser.scala @@ -0,0 +1,14 @@ +package scala.tasty.util + +import scala.tasty.Context +import scala.tasty.trees.Tree + +abstract class TreeTraverser extends TreeAccumulator[Unit] { + + def traverse(tree: Tree)(implicit ctx: Context): Unit + + def apply(x: Unit, tree: Tree)(implicit ctx: Context): Unit = traverse(tree) + + protected def traverseChildren(tree: Tree)(implicit ctx: Context): Unit = foldOver((), tree) + +} diff --git a/tests/run-with-compiler/quote-run-constants-extract-1.scala b/tests/run-with-compiler/quote-run-constants-extract-1.scala deleted file mode 100644 index e019defeba11..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-1.scala +++ /dev/null @@ -1,15 +0,0 @@ -import scala.quoted._ - -import dotty.tools.dotc.quoted.Toolbox._ - -object Test { - - def main(args: Array[String]): Unit = { - 3.toExpr match { case Constant(n) => println(n) } - '(4) match { case Constant(n) => println(n) } - '("abc") match { case Constant(n) => println(n) } - '(null) match { case Constant(n) => println(n) } - - '(new Object) match { case Constant(n) => println(n); case _ => println("OK") } - } -} diff --git a/tests/run-with-compiler/quote-run-constants-extract-2.check b/tests/run-with-compiler/quote-run-constants-extract-2.check deleted file mode 100644 index 1cc77395177a..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-2.check +++ /dev/null @@ -1,5 +0,0 @@ -{ - val y: Double = 3.0.*(3.0) - y -} -9.0 \ No newline at end of file diff --git a/tests/run-with-compiler/quote-run-constants-extract-2.scala b/tests/run-with-compiler/quote-run-constants-extract-2.scala deleted file mode 100644 index 8c3edbb72cfd..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-2.scala +++ /dev/null @@ -1,30 +0,0 @@ -import scala.quoted._ - -import dotty.tools.dotc.quoted.Toolbox._ - -object Test { - - def main(args: Array[String]): Unit = { - // 2 is a lifted constant - println(power(2.toExpr, 3.0.toExpr).show) - println(power(2.toExpr, 3.0.toExpr).run) - } - - def power(n: Expr[Int], x: Expr[Double]): Expr[Double] = { - n match { - case Constant(n1) => powerCode(n1, x) - case _ => '{ dynamicPower(~n, ~x) } - } - } - - private def powerCode(n: Int, x: Expr[Double]): Expr[Double] = - if (n == 0) '(1.0) - else if (n == 1) x - else if (n % 2 == 0) '{ { val y = ~x * ~x; ~powerCode(n / 2, '(y)) } } - else '{ ~x * ~powerCode(n - 1, x) } - - def dynamicPower(n: Int, x: Double): Double = - if (n == 0) 1.0 - else if (n % 2 == 0) dynamicPower(n / 2, x * x) - else x * dynamicPower(n - 1, x) -} diff --git a/tests/run-with-compiler/quote-run-constants-extract-3.check b/tests/run-with-compiler/quote-run-constants-extract-3.check deleted file mode 100644 index fadb88febacc..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-3.check +++ /dev/null @@ -1,5 +0,0 @@ -{ - val y: Double = 3.0.*(3.0) - y -} -9.0 diff --git a/tests/run-with-compiler/quote-run-constants-extract-3.scala b/tests/run-with-compiler/quote-run-constants-extract-3.scala deleted file mode 100644 index 8c3edbb72cfd..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-3.scala +++ /dev/null @@ -1,30 +0,0 @@ -import scala.quoted._ - -import dotty.tools.dotc.quoted.Toolbox._ - -object Test { - - def main(args: Array[String]): Unit = { - // 2 is a lifted constant - println(power(2.toExpr, 3.0.toExpr).show) - println(power(2.toExpr, 3.0.toExpr).run) - } - - def power(n: Expr[Int], x: Expr[Double]): Expr[Double] = { - n match { - case Constant(n1) => powerCode(n1, x) - case _ => '{ dynamicPower(~n, ~x) } - } - } - - private def powerCode(n: Int, x: Expr[Double]): Expr[Double] = - if (n == 0) '(1.0) - else if (n == 1) x - else if (n % 2 == 0) '{ { val y = ~x * ~x; ~powerCode(n / 2, '(y)) } } - else '{ ~x * ~powerCode(n - 1, x) } - - def dynamicPower(n: Int, x: Double): Double = - if (n == 0) 1.0 - else if (n % 2 == 0) dynamicPower(n / 2, x * x) - else x * dynamicPower(n - 1, x) -} diff --git a/tests/run-with-compiler/quote-run-constants-extract-4.check b/tests/run-with-compiler/quote-run-constants-extract-4.check deleted file mode 100644 index a446942980e1..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-4.check +++ /dev/null @@ -1,5 +0,0 @@ -{ - val y: Double = 4.0.*(4.0) - y -} -16.0 diff --git a/tests/run-with-compiler/quote-run-constants-extract-4.scala b/tests/run-with-compiler/quote-run-constants-extract-4.scala deleted file mode 100644 index 330549fb6f8e..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-4.scala +++ /dev/null @@ -1,31 +0,0 @@ -import scala.quoted._ - -import dotty.tools.dotc.quoted.Toolbox._ - -object Test { - - def main(args: Array[String]): Unit = { - // n is a lifted constant - val n = 2 - println(power(n.toExpr, 4.0.toExpr).show) - println(power(n.toExpr, 4.0.toExpr).run) - } - - def power(n: Expr[Int], x: Expr[Double]): Expr[Double] = { - n match { - case Constant(n1) => powerCode(n1, x) - case _ => '{ dynamicPower(~n, ~x) } - } - } - - private def powerCode(n: Int, x: Expr[Double]): Expr[Double] = - if (n == 0) '(1.0) - else if (n == 1) x - else if (n % 2 == 0) '{ { val y = ~x * ~x; ~powerCode(n / 2, '(y)) } } - else '{ ~x * ~powerCode(n - 1, x) } - - def dynamicPower(n: Int, x: Double): Double = - if (n == 0) 1.0 - else if (n % 2 == 0) dynamicPower(n / 2, x * x) - else x * dynamicPower(n - 1, x) -} diff --git a/tests/run-with-compiler/quote-run-constants-extract-5.check b/tests/run-with-compiler/quote-run-constants-extract-5.check deleted file mode 100644 index 4f9d9a7de996..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-5.check +++ /dev/null @@ -1,5 +0,0 @@ -{ - val y: Double = 5.0.*(5.0) - y -} -25.0 diff --git a/tests/run-with-compiler/quote-run-constants-extract-5.scala b/tests/run-with-compiler/quote-run-constants-extract-5.scala deleted file mode 100644 index 3362a82ee4fe..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-5.scala +++ /dev/null @@ -1,30 +0,0 @@ -import scala.quoted._ - -import dotty.tools.dotc.quoted.Toolbox._ - -object Test { - - def main(args: Array[String]): Unit = { - // n is a constant in a quote - println(power('(2), 5.0.toExpr).show) - println(power('(2), 5.0.toExpr).run) - } - - def power(n: Expr[Int], x: Expr[Double]): Expr[Double] = { - n match { - case Constant(n1) => powerCode(n1, x) - case _ => '{ dynamicPower(~n, ~x) } - } - } - - private def powerCode(n: Int, x: Expr[Double]): Expr[Double] = - if (n == 0) '(1.0) - else if (n == 1) x - else if (n % 2 == 0) '{ { val y = ~x * ~x; ~powerCode(n / 2, '(y)) } } - else '{ ~x * ~powerCode(n - 1, x) } - - def dynamicPower(n: Int, x: Double): Double = - if (n == 0) 1.0 - else if (n % 2 == 0) dynamicPower(n / 2, x * x) - else x * dynamicPower(n - 1, x) -} diff --git a/tests/run-with-compiler/quote-run-constants-extract-6.check b/tests/run-with-compiler/quote-run-constants-extract-6.check deleted file mode 100644 index da9e8c9732aa..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-6.check +++ /dev/null @@ -1,8 +0,0 @@ -Test.dynamicPower( - { - println("foo") - 2 - } -, 6.0) -foo -36.0 diff --git a/tests/run-with-compiler/quote-run-constants-extract-6.scala b/tests/run-with-compiler/quote-run-constants-extract-6.scala deleted file mode 100644 index 50110602c844..000000000000 --- a/tests/run-with-compiler/quote-run-constants-extract-6.scala +++ /dev/null @@ -1,31 +0,0 @@ -import scala.quoted._ - -import dotty.tools.dotc.quoted.Toolbox._ - -object Test { - - def main(args: Array[String]): Unit = { - // n2 is clearly not a constant - val n2 = '{ println("foo"); 2 } - println(power(n2, 6.0.toExpr).show) - println(power(n2, 6.0.toExpr).run) - } - - def power(n: Expr[Int], x: Expr[Double]): Expr[Double] = { - n match { - case Constant(n1) => powerCode(n1, x) - case _ => '{ dynamicPower(~n, ~x) } - } - } - - private def powerCode(n: Int, x: Expr[Double]): Expr[Double] = - if (n == 0) '(1.0) - else if (n == 1) x - else if (n % 2 == 0) '{ { val y = ~x * ~x; ~powerCode(n / 2, '(y)) } } - else '{ ~x * ~powerCode(n - 1, x) } - - def dynamicPower(n: Int, x: Double): Double = - if (n == 0) 1.0 - else if (n % 2 == 0) dynamicPower(n / 2, x * x) - else x * dynamicPower(n - 1, x) -} diff --git a/tests/run/tasty-extractors-1.check b/tests/run/tasty-extractors-1.check new file mode 100644 index 000000000000..725e762be608 --- /dev/null +++ b/tests/run/tasty-extractors-1.check @@ -0,0 +1,120 @@ +Literal(Boolean(true)) +ConstantType(Boolean(true)) + +Literal(Int(1)) +ConstantType(Int(1)) + +Literal(Long(2)) +ConstantType(Long(2)) + +Literal(Float(2.1)) +ConstantType(Float(2.1)) + +Literal(Double(2.2)) +ConstantType(Double(2.2)) + +Literal(String("abc")) +ConstantType(String("abc")) + +Apply(Ident(Simple(println)), List(Literal(String("abc")))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Typed(Literal(Int(8)), Ident(TypeName(Simple(Int)))) +SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) + +Typed(Literal(Byte(8)), Ident(TypeName(Simple(Byte)))) +SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) + +Typed(Literal(Short(8)), Ident(TypeName(Simple(Short)))) +SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) + +Literal(Char('a')) +ConstantType(Char('a')) + +Block(List(Literal(Int(1)), Literal(Int(2))), Literal(Int(3))) +ConstantType(Int(3)) + +If(Typed(Literal(Boolean(true)), Ident(TypeName(Simple(Boolean)))), Literal(Int(1)), Literal(Int(2))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Match(Literal(String("a")), List(CaseDef(Value(Literal(String("a"))), None, Block(Nil, Literal(Unit()))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Match(Literal(String("b")), List(CaseDef(Bind(Simple(n), Value(Ident(Simple(_)))), None, Block(Nil, Literal(Unit()))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Match(Literal(String("c")), List(CaseDef(Bind(Simple(n), TypeTest(Ident(TypeName(Simple(String))))), None, Block(Nil, Literal(Unit()))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Match(Literal(String("e")), List(CaseDef(Value(Ident(Simple(_))), None, Block(Nil, Literal(Unit()))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Match(Literal(String("f")), List(CaseDef(TypeTest(Ident(TypeName(Simple(String)))), None, Block(Nil, Literal(Unit()))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Match(Typed(Literal(String("g")), Ident(TypeName(Simple(Any)))), List(CaseDef(Alternative(List(TypeTest(Ident(TypeName(Simple(String)))), TypeTest(Ident(TypeName(Simple(Int)))))), None, Block(Nil, Literal(Unit()))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Match(Literal(String("h")), List(CaseDef(Value(Ident(Simple(_))), Some(Literal(Boolean(false))), Block(Nil, Literal(Unit()))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ValDef(Simple(a), Synthetic(), Some(Literal(String("o"))))), Match(Literal(String("i")), List(CaseDef(Bind(Simple(a), Value(Ident(Simple(_)))), None, Block(Nil, Literal(Unit())))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Match(Ident(Simple(Nil)), List(CaseDef(Unapply(TypeApply(Select(Ident(Simple(List)), Simple(unapplySeq)), List(Synthetic())), Nil, List(Bind(Simple(a), Value(Ident(Simple(_)))), Bind(Simple(b), Value(Ident(Simple(_)))), Bind(Simple(c), Value(Ident(Simple(_)))))), None, Block(Nil, Literal(Unit()))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Try(Literal(Int(1)), List(CaseDef(Value(Ident(Simple(_))), None, Block(Nil, Literal(Unit())))), None) +OrType(SymRef(, ThisType(SymRef(, NoPrefix))), SymRef(, ThisType(SymRef(, NoPrefix)))) + +Try(Literal(Int(2)), Nil, Some(Literal(Unit()))) +ConstantType(Int(2)) + +Try(Literal(Int(3)), List(CaseDef(Value(Ident(Simple(_))), None, Block(Nil, Literal(Unit())))), Some(Literal(Unit()))) +OrType(SymRef(, ThisType(SymRef(, NoPrefix))), SymRef(, ThisType(SymRef(, NoPrefix)))) + +Apply(Select(Literal(String("a")), Simple(==)), List(Literal(String("b")))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Apply(Select(New(Ident(TypeName(Simple(Object)))), Simple()), Nil) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Apply(Select(Ident(Simple(Int)), Simple(box)), List(NamedArg(Simple(x), Literal(Int(9))))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Apply(TypeApply(Select(Ident(Simple(Ordering)), Simple(apply)), List(Ident(TypeName(Simple(Int))))), List(Ident(Simple(Int)))) +AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))))) + +Block(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), Some(Literal(Int(3))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ValDef(Simple(b), Ident(TypeName(Simple(Int))), Some(Literal(Int(3))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple(f1), Nil, Nil, Ident(TypeName(Simple(Int))), Some(Literal(Int(3))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple(f2), Nil, Nil, Ident(TypeName(Simple(Int))), Some(Return(Literal(Int(4)))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple(f3), Nil, List(List(ValDef(Simple(i), Ident(TypeName(Simple(Int))), None))), Ident(TypeName(Simple(Int))), Some(Ident(Simple(i))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple(f4), Nil, List(List(ValDef(Simple(i), Ident(TypeName(Simple(Int))), None)), List(ValDef(Simple(j), Ident(TypeName(Simple(Int))), None))), Ident(TypeName(Simple(Int))), Some(Apply(Select(Ident(Simple(i)), Simple(+)), List(Ident(Simple(j))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple(f5), Nil, List(List(ValDef(Simple(i), Ident(TypeName(Simple(Int))), None))), Ident(TypeName(Simple(Int))), Some(Ident(Simple(i)))), DefDef(DefaultGetter(Simple(f5),f5), Nil, Nil, Synthetic(), Some(Literal(Int(9))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple(f6), List(TypeDef(TypeName(Simple(T)), TypeBoundsTree(Synthetic(), Synthetic()))), List(List(ValDef(Simple(x), Ident(TypeName(Simple(T))), None))), Ident(TypeName(Simple(T))), Some(Ident(Simple(x))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple(f7), List(TypeDef(TypeName(Simple(T)), TypeBoundsTree(Synthetic(), Synthetic()))), List(List(ValDef(Simple(x), Ident(TypeName(Simple(T))), None))), Singleton(Ident(Simple(x))), Some(Ident(Simple(x))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple(f8), Nil, List(List(ValDef(Simple(i), Annotated(Applied(Synthetic(), List(Ident(TypeName(Simple(Int))))), Apply(Select(New(Synthetic()), Simple()), Nil)), None))), Ident(TypeName(Simple(Int))), Some(Literal(Int(9))))), Apply(Ident(Simple(f8)), List(Typed(Repeated(List(Literal(Int(1)), Literal(Int(2)), Literal(Int(3)))), Synthetic())))) +SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) + +Block(List(DefDef(Simple(f9), Nil, List(List(ValDef(Simple(i), ByName(Ident(TypeName(Simple(Int)))), None))), Ident(TypeName(Simple(Int))), Some(Ident(Simple(i))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + diff --git a/tests/run/tasty-extractors-1/quoted_1.scala b/tests/run/tasty-extractors-1/quoted_1.scala new file mode 100644 index 000000000000..996e397f94f3 --- /dev/null +++ b/tests/run/tasty-extractors-1/quoted_1.scala @@ -0,0 +1,23 @@ +import scala.quoted._ +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context +import scala.tasty.util.TastyPrinter + +object Macros { + + implicit inline def printTree[T](x: => T): Unit = + ~impl('(x))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl[T](x: Expr[T])(implicit ctx: Context): Expr[Unit] = { + val tree = x.toTasty + val treeStr = TastyPrinter.stringOf(tree) + val treeTpeStr = TastyPrinter.stringOf(tree.tpe) + + '{ + println(~treeStr.toExpr) + println(~treeTpeStr.toExpr) + println() + } + } +} diff --git a/tests/run/tasty-extractors-1/quoted_2.scala b/tests/run/tasty-extractors-1/quoted_2.scala new file mode 100644 index 000000000000..b0c052366225 --- /dev/null +++ b/tests/run/tasty-extractors-1/quoted_2.scala @@ -0,0 +1,48 @@ + +import Macros._ + +object Test { + def main(args: Array[String]): Unit = { + printTree(true) + printTree(1) + printTree(2L) + printTree(2.1f) + printTree(2.2d) + printTree("abc") + printTree(println("abc")) + printTree(8: Int) + printTree(8: Byte) + printTree(8: Short) + printTree('a') + printTree { 1; 2; 3 } + printTree(if (true: Boolean) 1 else 2) + printTree("a" match { case "a" => () }) + printTree("b" match { case n => () }) + printTree("c" match { case n: String => () }) + printTree("e" match { case _ => () }) + printTree("f" match { case _: String => () }) + printTree(("g": Any) match { case _: String | _: Int => () }) + printTree("h" match { case _ if false => () }) + printTree { val a = "o"; "i" match { case a => () } } + // printTree(Option(4) match { case Some(a) => a; case None => 1 }) + printTree(Nil match { case List(a, b, c) => }) + printTree(try 1 catch { case _ => }) + printTree(try 2 finally ()) + printTree(try 3 catch { case _ => } finally ()) + printTree("a" == "b") + printTree(new Object) + printTree(Int.box(x = 9)) + printTree(Ordering.apply[Int]) + printTree { val a: Int = 3 } + printTree { lazy val b: Int = 3 } + printTree { def f1: Int = 3 } + printTree { def f2: Int = return 4 } + printTree { def f3(i: Int): Int = i } + printTree { def f4(i: Int)(j: Int): Int = i + j } + printTree { def f5(i: Int = 9): Int = i } + printTree { def f6[T](x: T): T = x } + printTree { def f7[T](x: T): x.type = x } + printTree { def f8(i: Int*): Int = 9; f8(1, 2, 3) } + printTree { def f9(i: => Int): Int = i } + } +} diff --git a/tests/run/tasty-extractors-2.check b/tests/run/tasty-extractors-2.check new file mode 100644 index 000000000000..9a7c9f9b78f0 --- /dev/null +++ b/tests/run/tasty-extractors-2.check @@ -0,0 +1,111 @@ +Block(List(ValDef(Simple(x), Synthetic(), Some(Literal(Int(1))))), Assign(Ident(Simple(x)), Literal(Int(2)))) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(DefDef(Simple($anonfun), Nil, List(List(ValDef(Simple(x), Ident(TypeName(Simple(Int))), None))), Synthetic(), Some(Ident(Simple(x))))), Lambda(Ident(Simple($anonfun)), None)) +AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))))) + +Ident(Simple(???)) +SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))) + +Typed(Literal(Int(1)), Singleton(Literal(Int(1)))) +ConstantType(Int(1)) + +Typed(Literal(Int(1)), Ident(TypeName(Simple(Int)))) +SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) + +Typed(Ident(Simple(Nil)), Applied(Ident(TypeName(Simple(List))), List(Ident(TypeName(Simple(Int)))))) +AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))))) + +Typed(Apply(Select(New(Ident(TypeName(Simple(Baz)))), Simple()), Nil), And(Ident(TypeName(Simple(Foo))), Ident(TypeName(Simple(Bar))))) +AndType(SymRef(, ThisType(SymRef())>, NoPrefix))), SymRef(, ThisType(SymRef())>, NoPrefix)))) + +Typed(Literal(Int(1)), Or(Ident(TypeName(Simple(Int))), Ident(TypeName(Simple(String))))) +OrType(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef(, NoPrefix))))) + +Block(List(Import(Select(Ident(Simple(scala)), Simple(collection)), List(SimpleSelector(Id(mutable))))), Literal(Int(1))) +ConstantType(Int(1)) + +Block(List(Import(Select(Ident(Simple(scala)), Simple(collection)), List(SimpleSelector(Id(mutable)), SimpleSelector(Id(immutable))))), Literal(Int(2))) +ConstantType(Int(2)) + +Block(List(Import(Select(Ident(Simple(scala)), Simple(collection)), List(RenameSelector(Id(mutable), Id(mut))))), Literal(Int(3))) +ConstantType(Int(3)) + +Block(List(Import(Select(Ident(Simple(scala)), Simple(collection)), List(OmitSelector(Id(mutable))))), Literal(Int(4))) +ConstantType(Int(4)) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, Nil)), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ValDef(Simple(Foo), Ident(TypeName(ObjectClass(Simple(Foo)))), Some(Apply(Select(New(Ident(TypeName(ObjectClass(Simple(Foo))))), Simple()), Nil))), ClassDef(TypeName(ObjectClass(Simple(Foo))), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), Some(ValDef(Simple(_), Singleton(Ident(Simple(Foo))), None)), Nil)), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(TypeDef(TypeName(Simple(Foo)), TypeBoundsTree(Synthetic(), Synthetic()))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(TypeDef(TypeName(Simple(Foo)), Ident(TypeName(Simple(Int))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(TypeDef(TypeName(Simple(Foo)), TypeBoundsTree(Ident(TypeName(Simple(Null))), Ident(TypeName(Simple(Object)))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), Some(Literal(Int(0)))), DefDef(Simple(a_=), Nil, List(List(ValDef(Simple(x$1), Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(DefDef(Simple(a), Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(DefDef(Simple(a), Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(DefDef(Simple(a), Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo1)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None)))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo2)), DefDef(Simple(), Nil, List(List(ValDef(Simple(b), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(b), Synthetic(), None)))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo3)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None))), ValDef(Simple(Foo3), Ident(TypeName(ObjectClass(Simple(Foo3)))), Some(Apply(Select(New(Ident(TypeName(ObjectClass(Simple(Foo3))))), Simple()), Nil))), ClassDef(TypeName(ObjectClass(Simple(Foo3))), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), Some(ValDef(Simple(_), Singleton(Ident(Simple(Foo3))), None)), List(DefDef(DefaultGetter(Simple(),), Nil, Nil, Synthetic(), Some(Literal(Int(5))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo4)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None)), List(ValDef(Simple(b), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None), ValDef(Simple(b), Synthetic(), None)))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo5)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None)), List(ValDef(Simple(b), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None), ValDef(Simple(b), Synthetic(), None))), ValDef(Simple(Foo5), Ident(TypeName(ObjectClass(Simple(Foo5)))), Some(Apply(Select(New(Ident(TypeName(ObjectClass(Simple(Foo5))))), Simple()), Nil))), ClassDef(TypeName(ObjectClass(Simple(Foo5))), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), Some(ValDef(Simple(_), Singleton(Ident(Simple(Foo5))), None)), List(DefDef(DefaultGetter(Simple(),), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None))), Synthetic(), Some(Ident(Simple(a))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo6)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None)), List(ValDef(Simple(b), Singleton(Ident(Simple(a))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None), ValDef(Simple(b), Synthetic(), None)))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo8)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(Apply(Ident(Simple(println)), List(Literal(Int(0))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo10)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), Some(Literal(Int(9))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo11)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), Some(Literal(Int(10)))), DefDef(Simple(a_=), Nil, List(List(ValDef(Simple(x$1), Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo12)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), Some(Literal(Int(11))))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, Nil), ClassDef(TypeName(Simple(Bar)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, Nil)), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo2)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Synthetic()), None, Nil), ClassDef(TypeName(Simple(Bar)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil), Ident(TypeName(Simple(Foo2)))), None, Nil)), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(List(ValDef(Simple(i), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(i), Synthetic(), None))), ClassDef(TypeName(Simple(Bar)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Ident(TypeName(Simple(Foo)))), Simple()), List(Literal(Int(1))))), None, Nil)), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(X)), Ident(TypeName(Simple(Int)))))), DefDef(Simple(f), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Foo))), None))), TypeSelect(Ident(Simple(a)), TypeName(Simple(X))), Some(Ident(Simple(???))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(X)), TypeBoundsTree(Synthetic(), Synthetic())))), DefDef(Simple(f), Nil, List(List(ValDef(Simple(a), Refined(Ident(TypeName(Simple(Foo))), List(TypeDef(TypeName(Simple(X)), Ident(TypeName(Simple(Int)))))), None))), TypeSelect(Ident(Simple(a)), TypeName(Simple(X))), Some(Ident(Simple(???))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + +Block(List(ValDef(Simple(lambda), Applied(Synthetic(), List(Ident(TypeName(Simple(Int))), Ident(TypeName(Simple(Int))))), Some(Block(List(DefDef(Simple($anonfun), Nil, List(List(ValDef(Simple(x), Synthetic(), None))), Synthetic(), Some(Ident(Simple(x))))), Lambda(Ident(Simple($anonfun)), None))))), Literal(Unit())) +SymRef(, ThisType(SymRef(, NoPrefix))) + diff --git a/tests/run/tasty-extractors-2/quoted_1.scala b/tests/run/tasty-extractors-2/quoted_1.scala new file mode 100644 index 000000000000..996e397f94f3 --- /dev/null +++ b/tests/run/tasty-extractors-2/quoted_1.scala @@ -0,0 +1,23 @@ +import scala.quoted._ +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context +import scala.tasty.util.TastyPrinter + +object Macros { + + implicit inline def printTree[T](x: => T): Unit = + ~impl('(x))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl[T](x: Expr[T])(implicit ctx: Context): Expr[Unit] = { + val tree = x.toTasty + val treeStr = TastyPrinter.stringOf(tree) + val treeTpeStr = TastyPrinter.stringOf(tree.tpe) + + '{ + println(~treeStr.toExpr) + println(~treeTpeStr.toExpr) + println() + } + } +} diff --git a/tests/run/tasty-extractors-2/quoted_2.scala b/tests/run/tasty-extractors-2/quoted_2.scala new file mode 100644 index 000000000000..d55a9daa7000 --- /dev/null +++ b/tests/run/tasty-extractors-2/quoted_2.scala @@ -0,0 +1,50 @@ + +import Macros._ + +object Test { + def main(args: Array[String]): Unit = { + printTree { var x = 1; x = 2 } + printTree((x: Int) => x) + printTree(???) + printTree(1: 1) + printTree(1: Int) + printTree(Nil: List[Int]) + printTree(new Baz: Foo & Bar) + printTree(1: Int | String) + printTree { import scala.collection.mutable; 1 } + printTree { import scala.collection.{mutable, immutable}; 2 } + printTree { import scala.collection.{mutable => mut}; 3 } + printTree { import scala.collection.{mutable => _}; 4 } + printTree { class Foo } + printTree { object Foo } + printTree { type Foo } + printTree { type Foo = Int } + printTree { type Foo >: Null <: Object } + printTree { class Foo { @volatile var a = 0 } } + printTree { class Foo { final def a = 0 } } + printTree { class Foo { private[Foo] def a = 0 } } + printTree { class Foo { protected[Foo] def a = 0 } } + // printTree { case class Foo() } // FIXME: issue #4396 + printTree { class Foo1(a: Int) } + printTree { class Foo2(val b: Int) } + printTree { class Foo3(a: Int = 5) } + printTree { class Foo4(a: Int)(b: Int) } + printTree { class Foo5(a: Int)(b: Int = a) } + printTree { class Foo6(a: Int)(b: a.type) } + // printTree { class Foo7(a: Int) { def this() = this(6) } } + printTree { class Foo8 { println(0) } } + printTree { class Foo10 { val a = 9 } } + printTree { class Foo11 { var a = 10 } } + printTree { class Foo12 { lazy val a = 11 } } + printTree { class Foo; class Bar extends Foo } + printTree { trait Foo2; class Bar extends Foo2 } + printTree { class Foo(i: Int); class Bar extends Foo(1) } + printTree { class Foo { type X = Int }; def f(a: Foo): a.X = ??? } + printTree { class Foo { type X }; def f(a: Foo { type X = Int }): a.X = ??? } + printTree { val lambda: Int => Int = x => x } + } +} + +trait Foo +trait Bar +class Baz extends Foo with Bar diff --git a/tests/run/tasty-extractors-3.check b/tests/run/tasty-extractors-3.check new file mode 100644 index 000000000000..ae10423620ec --- /dev/null +++ b/tests/run/tasty-extractors-3.check @@ -0,0 +1,42 @@ +SymRef(, ThisType(SymRef(, NoPrefix))) + +SymRef(, NoPrefix) + +TypeBounds(SymRef(, ThisType(SymRef(, NoPrefix))), SymRef(, ThisType(SymRef(, NoPrefix)))) + +SymRef(, ThisType(SymRef(, NoPrefix))) + +SymRef(, ThisType(SymRef(, NoPrefix))) + +SymRef(, NoPrefix) + +TypeBounds(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix))))) + +SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) + +SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) + +SymRef(, NoPrefix) + +SymRef(, ThisType(SymRef(, NoPrefix))) + +SymRef(, ThisType(SymRef(, NoPrefix))) + +TypeBounds(SymRef(, ThisType(SymRef(, NoPrefix))), SymRef(, ThisType(SymRef(, NoPrefix)))) + +SymRef(, ThisType(SymRef(, NoPrefix))) + +SymRef(, ThisType(SymRef(, NoPrefix))) + +Refinement(SymRef(, NoPrefix), TypeName(Simple(X)), TypeBounds(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))))) + +SymRef(, ThisType(SymRef(, NoPrefix))) + +SymRef(, NoPrefix) + +SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))) + +SymRef(, NoPrefix) + +Refinement(SymRef(, NoPrefix), TypeName(Simple(X)), TypeBounds(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))))) + diff --git a/tests/run/tasty-extractors-3/quoted_1.scala b/tests/run/tasty-extractors-3/quoted_1.scala new file mode 100644 index 000000000000..5ae4b1930679 --- /dev/null +++ b/tests/run/tasty-extractors-3/quoted_1.scala @@ -0,0 +1,34 @@ +import scala.quoted._ +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context +import scala.tasty.trees.{Tree, TypeBoundsTree, TypeTree} +import scala.tasty.util.{TastyPrinter, TreeTraverser} + +object Macros { + + implicit inline def printTypes[T](x: => T): Unit = + ~impl('(x))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl[T](x: Expr[T])(implicit ctx: Context): Expr[Unit] = { + val buff = new StringBuilder + val traverser = new TreeTraverser { + override def traverse(tree: Tree)(implicit ctx: Context): Unit = { + tree match { + case tree: TypeTree => + buff.append(TastyPrinter.stringOf(tree.tpe)) + buff.append("\n\n") + case tree: TypeBoundsTree => + buff.append(TastyPrinter.stringOf(tree.tpe)) + buff.append("\n\n") + case _ => + } + traverseChildren(tree) + } + } + + val tree = x.toTasty + traverser.traverse(tree)(ctx) + '(print(~buff.result().toExpr)) + } +} diff --git a/tests/run/tasty-extractors-3/quoted_2.scala b/tests/run/tasty-extractors-3/quoted_2.scala new file mode 100644 index 000000000000..1f4d1de11855 --- /dev/null +++ b/tests/run/tasty-extractors-3/quoted_2.scala @@ -0,0 +1,19 @@ + +import Macros._ + +object Test { + def main(args: Array[String]): Unit = { + printTypes { + val x = 1 + val y: x.type = x + def f1[T](): T = ??? + def f2[T >: Int <: Int](): T = ??? + class Foo { type X } + val foo = new Foo { type X = String } + } + } +} + +trait Foo +trait Bar +class Baz extends Foo with Bar diff --git a/tests/run-with-compiler/quote-run-constants-extract-1.check b/tests/run/tasty-extractors-constants-1.check similarity index 100% rename from tests/run-with-compiler/quote-run-constants-extract-1.check rename to tests/run/tasty-extractors-constants-1.check diff --git a/tests/run/tasty-extractors-constants-1/quoted_1.scala b/tests/run/tasty-extractors-constants-1/quoted_1.scala new file mode 100644 index 000000000000..807d23c8b755 --- /dev/null +++ b/tests/run/tasty-extractors-constants-1/quoted_1.scala @@ -0,0 +1,27 @@ +import scala.quoted._ +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context +import scala.tasty.names.Name +import scala.tasty.trees._ +import scala.tasty.util.{TastyPrinter, TreeTraverser} + +object Macros { + + implicit inline def testMacro: Unit = + ~impl(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl(implicit ctx: Context): Expr[Unit] = { + val buff = new StringBuilder + def stagedPrintln(x: Any): Unit = buff append java.util.Objects.toString(x) append "\n" + + 3.toExpr match { case Constant(n) => stagedPrintln(n) } + '(4) match { case Constant(n) => stagedPrintln(n) } + '("abc") match { case Constant(n) => stagedPrintln(n) } + '(null) match { case Constant(n) => stagedPrintln(n) } + + '(new Object) match { case Constant(n) => println(n); case _ => stagedPrintln("OK") } + + '(print(~buff.result().toExpr)) + } +} diff --git a/tests/run/tasty-extractors-constants-1/quoted_2.scala b/tests/run/tasty-extractors-constants-1/quoted_2.scala new file mode 100644 index 000000000000..197b61bb5c98 --- /dev/null +++ b/tests/run/tasty-extractors-constants-1/quoted_2.scala @@ -0,0 +1,4 @@ + +object Test { + def main(args: Array[String]): Unit = Macros.testMacro +} diff --git a/tests/run/tasty-extractors-constants-2.check b/tests/run/tasty-extractors-constants-2.check new file mode 100644 index 000000000000..00657feabf5c --- /dev/null +++ b/tests/run/tasty-extractors-constants-2.check @@ -0,0 +1,17 @@ +{ + val y: Double = 3.0.*(3.0) + y +} +9.0 + +{ + val y: Double = 4.0.*(4.0) + y +} +16.0 + +{ + val y: Double = 5.0.*(5.0) + y +} +25.0 diff --git a/tests/run/tasty-extractors-constants-2/quoted_1.scala b/tests/run/tasty-extractors-constants-2/quoted_1.scala new file mode 100644 index 000000000000..4747e67911b5 --- /dev/null +++ b/tests/run/tasty-extractors-constants-2/quoted_1.scala @@ -0,0 +1,66 @@ +import scala.quoted._ +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context +import scala.tasty.names.Name +import scala.tasty.trees._ +import scala.tasty.util.{TastyPrinter, TreeTraverser} + +object Macros { + + inline def testMacro: Unit = + ~impl(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl(implicit ctx: Context): Expr[Unit] = { + // 2 is a lifted constant + val show1 = power(2.toExpr, 3.0.toExpr).show + val run1 = power(2.toExpr, 3.0.toExpr).run + + // n is a lifted constant + val n = 2 + val show2 = power(n.toExpr, 4.0.toExpr).show + val run2 = power(n.toExpr, 4.0.toExpr).run + + // n is a constant in a quote + val show3 = power('(2), 5.0.toExpr).show + val run3 = power('(2), 5.0.toExpr).run + + // n2 is clearly not a constant + // FIXME +// val n2 = '{ println("foo"); 2 } +// val show4 = (power(n2, 6.0.toExpr).show) +// val run4 = (power(n2, 6.0.toExpr).run) + + '{ + println(~show1.toExpr) + println(~run1.toExpr) + println() + println(~show2.toExpr) + println(~run2.toExpr) + println() + println(~show3.toExpr) + println(~run3.toExpr) +// println() +// println(~show4.toExpr) +// println(~run4.toExpr) + } + } + + def power(n: Expr[Int], x: Expr[Double])(implicit ctx: Context): Expr[Double] = { + n match { + case Constant(n1) => powerCode(n1, x) + case _ => '{ dynamicPower(~n, ~x) } + } + } + + def powerCode(n: Int, x: Expr[Double]): Expr[Double] = + if (n == 0) '(1.0) + else if (n == 1) x + else if (n % 2 == 0) '{ { val y = ~x * ~x; ~powerCode(n / 2, '(y)) } } + else '{ ~x * ~powerCode(n - 1, x) } + + def dynamicPower(n: Int, x: Double): Double = + if (n == 0) 1.0 + else if (n % 2 == 0) dynamicPower(n / 2, x * x) + else x * dynamicPower(n - 1, x) +} diff --git a/tests/run/tasty-extractors-constants-2/quoted_2.scala b/tests/run/tasty-extractors-constants-2/quoted_2.scala new file mode 100644 index 000000000000..197b61bb5c98 --- /dev/null +++ b/tests/run/tasty-extractors-constants-2/quoted_2.scala @@ -0,0 +1,4 @@ + +object Test { + def main(args: Array[String]): Unit = Macros.testMacro +} diff --git a/tests/run/tasty-extractors-owners.check b/tests/run/tasty-extractors-owners.check new file mode 100644 index 000000000000..a6e05b47e0cf --- /dev/null +++ b/tests/run/tasty-extractors-owners.check @@ -0,0 +1,27 @@ +Simple(foo) +DefDef(Simple(main), Nil, List(List(ValDef(Simple(args), Synthetic(), None))), Synthetic(), None) + +Simple(bar) +DefDef(Simple(foo), Nil, Nil, Synthetic(), None) + +Simple(bar2) +DefDef(Simple(foo), Nil, Nil, Synthetic(), None) + +Simple(foo2) +DefDef(Simple(main), Nil, List(List(ValDef(Simple(args), Synthetic(), None))), Synthetic(), None) + +Simple(baz) +ValDef(Simple(foo2), Synthetic(), None) + +Simple(baz2) +ValDef(Simple(foo2), Synthetic(), None) + +Simple() +ClassDef(TypeName(Simple(A)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(B)), Synthetic()), DefDef(Simple(b), Nil, Nil, Synthetic(), None), ValDef(Simple(b2), Synthetic(), None))) + +Simple(b) +ClassDef(TypeName(Simple(A)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(B)), Synthetic()), DefDef(Simple(b), Nil, Nil, Synthetic(), None), ValDef(Simple(b2), Synthetic(), None))) + +Simple(b2) +ClassDef(TypeName(Simple(A)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(B)), Synthetic()), DefDef(Simple(b), Nil, Nil, Synthetic(), None), ValDef(Simple(b2), Synthetic(), None))) + diff --git a/tests/run/tasty-extractors-owners/quoted_1.scala b/tests/run/tasty-extractors-owners/quoted_1.scala new file mode 100644 index 000000000000..c225bfaef664 --- /dev/null +++ b/tests/run/tasty-extractors-owners/quoted_1.scala @@ -0,0 +1,39 @@ +import scala.quoted._ +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context +import scala.tasty.names.Name +import scala.tasty.trees._ +import scala.tasty.util.{TastyPrinter, TreeTraverser} + +object Macros { + + implicit inline def printOwners[T](x: => T): Unit = + ~impl('(x))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl[T](x: Expr[T])(implicit ctx: Context): Expr[Unit] = { + val buff = new StringBuilder + val traverser = new TreeTraverser { + override def traverse(tree: Tree)(implicit ctx: Context): Unit = { + tree match { + case tree @ DefDef(name: Name, _, _, _, _) => + buff.append(TastyPrinter.stringOf(name)) + buff.append("\n") + buff.append(TastyPrinter.stringOf(tree.owner)) + buff.append("\n\n") + case tree @ ValDef(name: Name, _, _) => + buff.append(TastyPrinter.stringOf(name)) + buff.append("\n") + buff.append(TastyPrinter.stringOf(tree.owner)) + buff.append("\n\n") + case _ => + } + traverseChildren(tree) + } + } + + val tree = x.toTasty + traverser.traverse(tree)(ctx) + '(print(~buff.result().toExpr)) + } +} diff --git a/tests/run/tasty-extractors-owners/quoted_2.scala b/tests/run/tasty-extractors-owners/quoted_2.scala new file mode 100644 index 000000000000..cc13d81ae03b --- /dev/null +++ b/tests/run/tasty-extractors-owners/quoted_2.scala @@ -0,0 +1,24 @@ + +import Macros._ + +object Test { + def main(args: Array[String]): Unit = { + printOwners { + def foo = { + def bar = 1 + val bar2 = 2 + bar + } + val foo2 = { + def baz = 3 + val baz2 = 4 + baz + } + class A { + type B = Int + def b = 5 + val b2 = 6 + } + } + } +} diff --git a/tests/run/tasty-extractors-types.check b/tests/run/tasty-extractors-types.check new file mode 100644 index 000000000000..b9cb6a572e4e --- /dev/null +++ b/tests/run/tasty-extractors-types.check @@ -0,0 +1,12 @@ +Ident(TypeName(Simple(Int))) +SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) + +Applied(Ident(TypeName(Simple(List))), List(Ident(TypeName(Simple(String))))) +AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))))) + +Applied(Ident(TypeName(Simple(Map))), List(Ident(TypeName(Simple(String))), Ident(TypeName(Simple(Int))))) +AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))))) + +Applied(Ident(TypeName(Simple(Map))), List(Ident(TypeName(Simple(String))), Ident(TypeName(Simple(I))))) +AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))), SymRef(, NoPrefix))) + diff --git a/tests/run/tasty-extractors-types/quoted_1.scala b/tests/run/tasty-extractors-types/quoted_1.scala new file mode 100644 index 000000000000..3f722c5618fa --- /dev/null +++ b/tests/run/tasty-extractors-types/quoted_1.scala @@ -0,0 +1,22 @@ +import scala.quoted._ +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context +import scala.tasty.names.Name +import scala.tasty.trees._ +import scala.tasty.util.{TastyPrinter, TreeTraverser} + +object Macros { + + implicit inline def printType[T]: Unit = + ~impl('[T])(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl[T](x: Type[T])(implicit ctx: Context): Expr[Unit] = { + val tree = x.toTasty + '{ + println(~TastyPrinter.stringOf(tree).toExpr) + println(~TastyPrinter.stringOf(tree.tpe).toExpr) + println() + } + } +} diff --git a/tests/run/tasty-extractors-types/quoted_2.scala b/tests/run/tasty-extractors-types/quoted_2.scala new file mode 100644 index 000000000000..6e19f6cb53a8 --- /dev/null +++ b/tests/run/tasty-extractors-types/quoted_2.scala @@ -0,0 +1,12 @@ + +import Macros._ + +object Test { + def main(args: Array[String]): Unit = { + type I = Int + printType[Int] + printType[List[String]] + printType[Map[String, Int]] + printType[Map[String, I]] + } +} diff --git a/tests/run/tasty-linenumber.check b/tests/run/tasty-linenumber.check new file mode 100644 index 000000000000..7f936437beb7 --- /dev/null +++ b/tests/run/tasty-linenumber.check @@ -0,0 +1,4 @@ +foo 5 +foo 6 +foo 8 +foo 9 \ No newline at end of file diff --git a/tests/run/tasty-linenumber/quoted_1.scala b/tests/run/tasty-linenumber/quoted_1.scala new file mode 100644 index 000000000000..3dcfdf327947 --- /dev/null +++ b/tests/run/tasty-linenumber/quoted_1.scala @@ -0,0 +1,19 @@ +import scala.quoted._ + +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context + +class LineNumber(val value: Int) { + override def toString: String = value.toString +} + +object LineNumber { + + implicit inline def line[T >: Unit <: Unit]: LineNumber = + ~lineImpl('[T])(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def lineImpl(x: Type[Unit])(implicit ctx: Context): Expr[LineNumber] = + '(new LineNumber(~x.toTasty.pos.startLine.toExpr)) + +} diff --git a/tests/run/tasty-linenumber/quoted_2.scala b/tests/run/tasty-linenumber/quoted_2.scala new file mode 100644 index 000000000000..253f4f85ead9 --- /dev/null +++ b/tests/run/tasty-linenumber/quoted_2.scala @@ -0,0 +1,16 @@ + +import LineNumber._ + +object Test { + def main(args: Array[String]): Unit = { + foo(line) + foo + + foo + foo + } + + def foo(implicit line: LineNumber): Unit = { + println("foo " + line) + } +} diff --git a/tests/run/tasty-location.check b/tests/run/tasty-location.check new file mode 100644 index 000000000000..be2c79195a2d --- /dev/null +++ b/tests/run/tasty-location.check @@ -0,0 +1,6 @@ +foo Location(List(Test, loc1)) +foo Location(List(Test, main)) +foo Location(List(Test, main)) +foo Location(List(Test, main, bar)) +foo Location(List(Test, main, bar, baz)) +foo Location(List(Test, main, f, $anonfun)) diff --git a/tests/run/tasty-location/quoted_1.scala b/tests/run/tasty-location/quoted_1.scala new file mode 100644 index 000000000000..b322a425a738 --- /dev/null +++ b/tests/run/tasty-location/quoted_1.scala @@ -0,0 +1,38 @@ +import scala.quoted._ + +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context +import scala.tasty.names._ +import scala.tasty.trees._ + +case class Location(owners: List[String]) + +object Location { + + implicit inline def location: Location = + ~impl(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl(implicit ctx: Context): Expr[Location] = { + val list = listOwnerNames(ctx.owner, Nil)(ctx) + '(new Location(~list.toExpr)) + } + + private def listOwnerNames(definition: Definition, acc: List[String])(implicit ctx: Context): List[String] = definition match { + case ValDef(name, _, _) => listOwnerNames(definition.owner, nameString(name) :: acc) + case DefDef(name, _, _, _, _) => listOwnerNames(definition.owner, nameString(name) :: acc) + case ClassDef(name, _, _, _, _) => listOwnerNames(definition.owner, nameString(name) :: acc) + case _ => acc + } + + private def nameString(name: Name)(implicit ctx: Context): String = name match { + case Simple(nme) => nme + case ObjectClass(underlying) => nameString(underlying) + case TypeName(underlying) => nameString(underlying) + } + + private implicit def ListIsLiftable[T : Liftable : Type]: Liftable[List[T]] = { + case x :: xs => '{ ~x.toExpr :: ~xs.toExpr } + case Nil => '{ List.empty[T] } + } +} diff --git a/tests/run/tasty-location/quoted_2.scala b/tests/run/tasty-location/quoted_2.scala new file mode 100644 index 000000000000..42589dc32db5 --- /dev/null +++ b/tests/run/tasty-location/quoted_2.scala @@ -0,0 +1,24 @@ + +import Location._ + +object Test { + val loc1 = location + def main(args: Array[String]): Unit = { + foo(loc1) + foo(location) + foo + + def bar = { + foo + val baz = foo + } + bar + + val f = (i: Int) => foo + f(0) + } + + def foo(implicit location: Location): Unit = { + println("foo " + location) + } +} diff --git a/tests/run/tasty-macro-assert.check b/tests/run/tasty-macro-assert.check new file mode 100644 index 000000000000..9cb0fa36e224 --- /dev/null +++ b/tests/run/tasty-macro-assert.check @@ -0,0 +1,7 @@ +Condition was false +Error left did not equal right: + left = Literal(String("acb")) + right = Literal(String("cde")) +Error left was equal to right: + left = Literal(String("acb")) + right = Literal(String("acb")) diff --git a/tests/run/tasty-macro-assert/quoted_1.scala b/tests/run/tasty-macro-assert/quoted_1.scala new file mode 100644 index 000000000000..46e9469762a3 --- /dev/null +++ b/tests/run/tasty-macro-assert/quoted_1.scala @@ -0,0 +1,78 @@ +import scala.quoted._ +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.trees._ +import scala.tasty.types._ +import scala.tasty.names._ +import scala.tasty.Context +import scala.tasty.util.TastyPrinter + +object Asserts { + + implicit class Ops[T](left: T) { + def ===(right: T): Boolean = left == right + def !==(right: T): Boolean = left != right + } + + object Ops + + inline def macroAssert(cond: Boolean): Unit = + ~impl('(cond))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl(cond: Expr[Boolean])(implicit ctx: Context): Expr[Unit] = { + val tree = cond.toTasty + + def isOps(tpe: MaybeType): Boolean = tpe match { + case SymRef(DefDef(Simple("Ops"), _, _, _, _), _) => true // TODO check that the parent is Asserts + case _ => false + } + + object OpsTree { + def unapply(arg: Term): Option[Term] = arg match { + case Apply(TypeApply(term, _), left :: Nil) if isOps(term.tpe) => + Some(left) + case _ => None + } + } + + tree match { + case Apply(Select(OpsTree(left), Simple(op)), right :: Nil) => + // FIXME splice the threes directly + val lExpr = TastyPrinter.stringOf(left).toExpr + val rExpr = TastyPrinter.stringOf(right).toExpr + op match { + case "===" => '(assertEquals(~lExpr, ~rExpr)) + case "!==" => '(assertNotEquals(~lExpr, ~rExpr)) + } + case _ => + '(assertTrue(~cond)) + } + + } + + def assertEquals[T](left: T, right: T): Unit = { + if (left != right) { + println( + s"""Error left did not equal right: + | left = $left + | right = $right""".stripMargin) + } + + } + + def assertNotEquals[T](left: T, right: T): Unit = { + if (left == right) { + println( + s"""Error left was equal to right: + | left = $left + | right = $right""".stripMargin) + } + + } + + def assertTrue(cond: Boolean): Unit = { + if (!cond) + println("Condition was false") + } + +} diff --git a/tests/run/tasty-macro-assert/quoted_2.scala b/tests/run/tasty-macro-assert/quoted_2.scala new file mode 100644 index 000000000000..06fb973ca4bd --- /dev/null +++ b/tests/run/tasty-macro-assert/quoted_2.scala @@ -0,0 +1,11 @@ + +import Asserts._ + +object Test { + def main(args: Array[String]): Unit = { + macroAssert("acb" == "cde") + macroAssert("acb" === "cde") + macroAssert("acb" !== "acb") + } + +} diff --git a/tests/run/tasty-positioned.check b/tests/run/tasty-positioned.check new file mode 100644 index 000000000000..0c43c2d3a4f1 --- /dev/null +++ b/tests/run/tasty-positioned.check @@ -0,0 +1,8 @@ +0 columns:24-25 lines:9-9 +10 columns:13-15 lines:10-10 +4530 columns:13-17 lines:11-11 +acbvasdfa columns:24-35 lines:12-12 +acbvasdfa columns:13-24 lines:13-13 +a +b columns:6-25 lines:15-16 +Foo columns:16-19 lines:17-17 diff --git a/tests/run/tasty-positioned/quoted_1.scala b/tests/run/tasty-positioned/quoted_1.scala new file mode 100644 index 000000000000..63ccf76f9f21 --- /dev/null +++ b/tests/run/tasty-positioned/quoted_1.scala @@ -0,0 +1,30 @@ +import scala.quoted._ + +import dotty.tools.dotc.quoted.Toolbox._ + +import scala.tasty.Context + +case class Position(path: String, start: Int, end: Int, + startLine: Int, startColumn: Int, endLine: Int, endColumn: Int) + +case class Positioned[T](value: T, position: Position) + +object Positioned { + + implicit inline def apply[T](x: T): Positioned[T] = + ~impl('(x))('[T], Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + + def impl[T](x: Expr[T])(implicit ev: Type[T], ctx: Context): Expr[Positioned[T]] = { + val pos = x.toTasty.pos + + val path = pos.sourceFile.toString.toExpr + val start = pos.start.toExpr + val end = pos.end.toExpr + val startLine = pos.startLine.toExpr + val endLine = pos.endLine.toExpr + val startColumn = pos.startColumn.toExpr + val endColumn = pos.endColumn.toExpr + + '(Positioned[T](~x, new Position(~path, ~start, ~end, ~startLine, ~startColumn, ~endLine, ~endColumn))) + } +} diff --git a/tests/run/tasty-positioned/quoted_2.scala b/tests/run/tasty-positioned/quoted_2.scala new file mode 100644 index 000000000000..4026b53b3ff2 --- /dev/null +++ b/tests/run/tasty-positioned/quoted_2.scala @@ -0,0 +1,23 @@ + +import Positioned._ + +object Test { + def main(args: Array[String]): Unit = { + def printPos[T](x: Positioned[T]) = { + val pos = x.position + println(s"${x.value} columns:${pos.startColumn}-${pos.endColumn} lines:${pos.startLine}-${pos.endLine}") + } + printPos(Positioned(0)) + printPos(10) + printPos(4530) + printPos(Positioned("acbvasdfa")) + printPos("acbvasdfa") + printPos( + """a + |b""".stripMargin) + printPos(new Foo) + } + class Foo { + override def toString: String = "Foo" + } +} From f3f3d3c61f9649a87e16c720072beee8b4084bf0 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Mon, 30 Apr 2018 17:15:37 +0200 Subject: [PATCH 02/21] Use direct extractors for tasty trees --- .../dotty/tools/dotc/core/Definitions.scala | 8 +- .../dotc/tasty/CompilationUniverse.scala | 7 + .../src/dotty/tools/dotc/tasty/FlagSet.scala | 66 ++ .../dotty/tools/dotc/tasty/FromSymbol.scala | 37 + .../dotty/tools/dotc/tasty/TastyImpl.scala | 899 +++++++++++++++ .../tasty/internal/AnnotationModifier.scala | 20 - .../tools/dotc/tasty/internal/CaseDef.scala | 22 - .../tools/dotc/tasty/internal/ClassDef.scala | 48 - .../tools/dotc/tasty/internal/Constant.scala | 58 - .../tools/dotc/tasty/internal/DefDef.scala | 29 - .../dotc/tasty/internal/Definition.scala | 56 - .../dotc/tasty/internal/FlagsModifier.scala | 82 -- .../dotty/tools/dotc/tasty/internal/Id.scala | 18 - .../tools/dotc/tasty/internal/Import.scala | 22 - .../dotc/tasty/internal/ImportSelector.scala | 35 - .../dotc/tasty/internal/LambdaType.scala | 16 - .../tools/dotc/tasty/internal/MaybeType.scala | 15 - .../dotc/tasty/internal/MethodType.scala | 27 - .../tools/dotc/tasty/internal/Modifiers.scala | 17 - .../tools/dotc/tasty/internal/Name.scala | 14 - .../dotc/tasty/internal/PackageClause.scala | 27 - .../dotc/tasty/internal/PackageDef.scala | 36 - .../tools/dotc/tasty/internal/Pattern.scala | 49 - .../tools/dotc/tasty/internal/PolyType.scala | 23 - .../tools/dotc/tasty/internal/Position.scala | 18 - .../dotc/tasty/internal/Positioned.scala | 9 - .../tasty/internal/PossiblySignedName.scala | 13 - .../tasty/internal/QualifiedModifier.scala | 28 - .../dotc/tasty/internal/RecursiveType.scala | 21 - .../dotc/tasty/internal/SignedName.scala | 25 - .../tools/dotc/tasty/internal/Statement.scala | 15 - .../dotc/tasty/internal/TastyContext.scala | 19 - .../tools/dotc/tasty/internal/Term.scala | 129 --- .../tools/dotc/tasty/internal/TermName.scala | 63 - .../tools/dotc/tasty/internal/Toolbox.scala | 217 ---- .../tasty/internal/TopLevelStatement.scala | 13 - .../dotc/tasty/internal/TreeWithContext.scala | 10 - .../tools/dotc/tasty/internal/Type.scala | 100 -- .../dotc/tasty/internal/TypeBounds.scala | 20 - .../dotc/tasty/internal/TypeBoundsTree.scala | 26 - .../tools/dotc/tasty/internal/TypeDef.scala | 31 - .../dotc/tasty/internal/TypeLambda.scala | 23 - .../tools/dotc/tasty/internal/TypeName.scala | 20 - .../dotc/tasty/internal/TypeOrNoPrefix.scala | 12 - .../tools/dotc/tasty/internal/TypeTree.scala | 76 -- .../tools/dotc/tasty/internal/ValDef.scala | 31 - .../tools/dotc/transform/ReifyQuotes.scala | 6 +- .../dotty/tools/dotc/transform/Splicer.scala | 3 +- library/src/scala/quoted/Constant.scala | 16 - library/src/scala/quoted/Expr.scala | 3 - library/src/scala/quoted/Type.scala | 3 - .../src/scala/runtime/quoted/Toolbox.scala | 3 +- library/src/scala/runtime/tasty/Toolbox.scala | 140 --- library/src/scala/tasty/Context.scala | 19 - library/src/scala/tasty/ContextProvider.scala | 13 - .../scala/tasty/{modifiers => }/FlagSet.scala | 2 +- library/src/scala/tasty/Id.scala | 5 - library/src/scala/tasty/Position.scala | 13 - library/src/scala/tasty/Positioned.scala | 5 - library/src/scala/tasty/Tasty.scala | 685 +++++++++++ library/src/scala/tasty/Universe.scala | 11 + .../src/scala/tasty/constants/Constant.scala | 5 - .../src/scala/tasty/constants/package.scala | 48 - .../scala/tasty/modifiers/Annotation.scala | 9 - library/src/scala/tasty/modifiers/Flags.scala | 9 - .../src/scala/tasty/modifiers/Modifier.scala | 3 - .../src/scala/tasty/modifiers/Qualified.scala | 14 - library/src/scala/tasty/names/Name.scala | 3 - .../tasty/names/PossiblySignedName.scala | 3 - .../src/scala/tasty/names/SignedName.scala | 9 - library/src/scala/tasty/names/TermName.scala | 3 - library/src/scala/tasty/names/TypeName.scala | 9 - library/src/scala/tasty/names/package.scala | 52 - library/src/scala/tasty/trees/CaseDef.scala | 9 - library/src/scala/tasty/trees/ClassDef.scala | 13 - library/src/scala/tasty/trees/DefDef.scala | 13 - .../src/scala/tasty/trees/Definition.scala | 7 - library/src/scala/tasty/trees/Import.scala | 9 - .../scala/tasty/trees/ImportSelector.scala | 19 - .../src/scala/tasty/trees/PackageClause.scala | 11 - .../src/scala/tasty/trees/PackageDef.scala | 9 - library/src/scala/tasty/trees/Pattern.scala | 33 - library/src/scala/tasty/trees/Statement.scala | 3 - library/src/scala/tasty/trees/Term.scala | 9 - .../scala/tasty/trees/TopLevelStatement.scala | 3 - library/src/scala/tasty/trees/Tree.scala | 5 - .../scala/tasty/trees/TypeBoundsTree.scala | 13 - library/src/scala/tasty/trees/TypeDef.scala | 13 - library/src/scala/tasty/trees/TypeTree.scala | 8 - library/src/scala/tasty/trees/ValDef.scala | 13 - library/src/scala/tasty/trees/package.scala | 160 --- .../src/scala/tasty/types/LambdaType.scala | 25 - library/src/scala/tasty/types/MaybeType.scala | 3 - library/src/scala/tasty/types/NoPrefix.scala | 5 - .../src/scala/tasty/types/RecursiveType.scala | 9 - library/src/scala/tasty/types/Type.scala | 3 - .../src/scala/tasty/types/TypeBounds.scala | 9 - library/src/scala/tasty/types/package.scala | 72 -- .../scala/tasty/util/ConstantExtractor.scala | 30 + .../src/scala/tasty/util/TastyPrinter.scala | 1015 ++++++++++------- .../scala/tasty/util/TreeAccumulator.scala | 142 +-- .../src/scala/tasty/util/TreeTraverser.scala | 24 +- tests/pos/tasty/definitions.scala | 9 +- tests/run/tasty-extractors-1.check | 132 +-- tests/run/tasty-extractors-1/quoted_1.scala | 12 +- tests/run/tasty-extractors-2.check | 136 +-- tests/run/tasty-extractors-2/quoted_1.scala | 12 +- tests/run/tasty-extractors-3.check | 42 +- tests/run/tasty-extractors-3/quoted_1.scala | 29 +- .../quoted_1.scala | 15 +- .../quoted_1.scala | 27 +- tests/run/tasty-extractors-owners.check | 36 +- .../tasty-extractors-owners/quoted_1.scala | 35 +- tests/run/tasty-extractors-types.check | 16 +- .../run/tasty-extractors-types/quoted_1.scala | 14 +- tests/run/tasty-linenumber/quoted_1.scala | 9 +- tests/run/tasty-location.check | 12 +- tests/run/tasty-location/quoted_1.scala | 31 +- tests/run/tasty-macro-assert.check | 8 +- tests/run/tasty-macro-assert/quoted_1.scala | 20 +- tests/run/tasty-positioned/quoted_1.scala | 9 +- 121 files changed, 2719 insertions(+), 3216 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/tasty/CompilationUniverse.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/FlagSet.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/FromSymbol.scala create mode 100644 compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/AnnotationModifier.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/CaseDef.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/ClassDef.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Constant.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/DefDef.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Definition.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/FlagsModifier.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Id.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Import.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/ImportSelector.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/LambdaType.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/MaybeType.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/MethodType.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Modifiers.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Name.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/PackageClause.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/PackageDef.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Pattern.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/PolyType.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Position.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Positioned.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/PossiblySignedName.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/QualifiedModifier.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/RecursiveType.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/SignedName.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Statement.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TastyContext.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Term.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TermName.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Toolbox.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TopLevelStatement.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TreeWithContext.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/Type.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeBounds.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeBoundsTree.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeDef.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeLambda.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeName.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeOrNoPrefix.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/TypeTree.scala delete mode 100644 compiler/src/dotty/tools/dotc/tasty/internal/ValDef.scala delete mode 100644 library/src/scala/quoted/Constant.scala delete mode 100644 library/src/scala/runtime/tasty/Toolbox.scala delete mode 100644 library/src/scala/tasty/Context.scala delete mode 100644 library/src/scala/tasty/ContextProvider.scala rename library/src/scala/tasty/{modifiers => }/FlagSet.scala (98%) delete mode 100644 library/src/scala/tasty/Id.scala delete mode 100644 library/src/scala/tasty/Position.scala delete mode 100644 library/src/scala/tasty/Positioned.scala create mode 100644 library/src/scala/tasty/Tasty.scala create mode 100644 library/src/scala/tasty/Universe.scala delete mode 100644 library/src/scala/tasty/constants/Constant.scala delete mode 100644 library/src/scala/tasty/constants/package.scala delete mode 100644 library/src/scala/tasty/modifiers/Annotation.scala delete mode 100644 library/src/scala/tasty/modifiers/Flags.scala delete mode 100644 library/src/scala/tasty/modifiers/Modifier.scala delete mode 100644 library/src/scala/tasty/modifiers/Qualified.scala delete mode 100644 library/src/scala/tasty/names/Name.scala delete mode 100644 library/src/scala/tasty/names/PossiblySignedName.scala delete mode 100644 library/src/scala/tasty/names/SignedName.scala delete mode 100644 library/src/scala/tasty/names/TermName.scala delete mode 100644 library/src/scala/tasty/names/TypeName.scala delete mode 100644 library/src/scala/tasty/names/package.scala delete mode 100644 library/src/scala/tasty/trees/CaseDef.scala delete mode 100644 library/src/scala/tasty/trees/ClassDef.scala delete mode 100644 library/src/scala/tasty/trees/DefDef.scala delete mode 100644 library/src/scala/tasty/trees/Definition.scala delete mode 100644 library/src/scala/tasty/trees/Import.scala delete mode 100644 library/src/scala/tasty/trees/ImportSelector.scala delete mode 100644 library/src/scala/tasty/trees/PackageClause.scala delete mode 100644 library/src/scala/tasty/trees/PackageDef.scala delete mode 100644 library/src/scala/tasty/trees/Pattern.scala delete mode 100644 library/src/scala/tasty/trees/Statement.scala delete mode 100644 library/src/scala/tasty/trees/Term.scala delete mode 100644 library/src/scala/tasty/trees/TopLevelStatement.scala delete mode 100644 library/src/scala/tasty/trees/Tree.scala delete mode 100644 library/src/scala/tasty/trees/TypeBoundsTree.scala delete mode 100644 library/src/scala/tasty/trees/TypeDef.scala delete mode 100644 library/src/scala/tasty/trees/TypeTree.scala delete mode 100644 library/src/scala/tasty/trees/ValDef.scala delete mode 100644 library/src/scala/tasty/trees/package.scala delete mode 100644 library/src/scala/tasty/types/LambdaType.scala delete mode 100644 library/src/scala/tasty/types/MaybeType.scala delete mode 100644 library/src/scala/tasty/types/NoPrefix.scala delete mode 100644 library/src/scala/tasty/types/RecursiveType.scala delete mode 100644 library/src/scala/tasty/types/Type.scala delete mode 100644 library/src/scala/tasty/types/TypeBounds.scala delete mode 100644 library/src/scala/tasty/types/package.scala create mode 100644 library/src/scala/tasty/util/ConstantExtractor.scala diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index e631b06f0f42..64d9bab3f17e 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -667,11 +667,11 @@ class Definitions { def Unpickler_liftedExpr = ctx.requiredMethod("scala.runtime.quoted.Unpickler.liftedExpr") def Unpickler_unpickleType = ctx.requiredMethod("scala.runtime.quoted.Unpickler.unpickleType") - lazy val TastyContextModule = ctx.requiredModule("scala.tasty.Context") - def TastyContextModuleClass(implicit ctx: Context) = TastyContextModule.symbol.asClass + lazy val TastyUniverseModule = ctx.requiredModule("scala.tasty.Universe") + def TastyUniverseModuleClass(implicit ctx: Context) = TastyUniverseModule.symbol.asClass - lazy val TastyContext_compilationContextR = TastyContextModule.requiredMethod("compilationContext") - def TastyContext_compilationContext(implicit ctx: Context) = TastyContext_compilationContextR.symbol + lazy val TastyUniverse_compilationUniverseR = TastyUniverseModule.requiredMethod("compilationUniverse") + def TastyUniverse_compilationUniverse(implicit ctx: Context) = TastyUniverse_compilationUniverseR.symbol lazy val EqType = ctx.requiredClassRef("scala.Eq") def EqClass(implicit ctx: Context) = EqType.symbol.asClass diff --git a/compiler/src/dotty/tools/dotc/tasty/CompilationUniverse.scala b/compiler/src/dotty/tools/dotc/tasty/CompilationUniverse.scala new file mode 100644 index 000000000000..f1863ead499a --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/CompilationUniverse.scala @@ -0,0 +1,7 @@ +package dotty.tools.dotc.tasty + +import dotty.tools.dotc.core.Contexts.Context + +class CompilationUniverse(val context: Context) extends scala.tasty.Universe { + val tasty: TastyImpl.type = TastyImpl +} diff --git a/compiler/src/dotty/tools/dotc/tasty/FlagSet.scala b/compiler/src/dotty/tools/dotc/tasty/FlagSet.scala new file mode 100644 index 000000000000..483bd3e242f7 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/FlagSet.scala @@ -0,0 +1,66 @@ +package dotty.tools.dotc.tasty + +import dotty.tools.dotc.core.Flags +import dotty.tools.dotc.core.Flags._ + +class FlagSet(flags: Flags.FlagSet) extends scala.tasty.FlagSet { + + def isProtected: Boolean = flags.is(Protected) + def isAbstract: Boolean = flags.is(Abstract) + def isFinal: Boolean = flags.is(Final) + def isSealed: Boolean = flags.is(Sealed) + def isCase: Boolean = flags.is(Case) + def isImplicit: Boolean = flags.is(Implicit) + def isErased: Boolean = flags.is(Erased) + def isLazy: Boolean = flags.is(Lazy) + def isOverride: Boolean = flags.is(Override) + def isInline: Boolean = flags.is(Inline) + def isMacro: Boolean = flags.is(Macro) + def isStatic: Boolean = flags.is(JavaStatic) + def isObject: Boolean = flags.is(Module) + def isTrait: Boolean = flags.is(Trait) + def isLocal: Boolean = flags.is(Local) + def isSynthetic: Boolean = flags.is(Synthetic) + def isArtifact: Boolean = flags.is(Artifact) + def isMutable: Boolean = flags.is(Mutable) + def isLabel: Boolean = flags.is(Label) + def isFieldAccessor: Boolean = flags.is(Accessor) + def isCaseAcessor: Boolean = flags.is(CaseAccessor) + def isCovariant: Boolean = flags.is(Covariant) + def isContravariant: Boolean = flags.is(Contravariant) + def isScala2X: Boolean = flags.is(Scala2x) + def isDefaultParameterized: Boolean = flags.is(DefaultParameterized) + def isStable: Boolean = flags.is(Stable) + + override def toString: String = { + val flags = List.newBuilder[String] + if (isProtected) flags += "protected " + if (isAbstract) flags += "abstract" + if (isFinal) flags += "final" + if (isSealed) flags += "sealed" + if (isCase) flags += "case" + if (isImplicit) flags += "implicit" + if (isErased) flags += "erased" + if (isLazy) flags += "lazy" + if (isOverride) flags += "override" + if (isInline) flags += "inline" + if (isMacro) flags += "macro" + if (isStatic) flags += "javaStatic" + if (isObject) flags += "module" + if (isTrait) flags += "trait" + if (isLocal) flags += "local" + if (isSynthetic) flags += "synthetic" + if (isArtifact) flags += "artifact" + if (isMutable) flags += "mutable" + if (isLabel) flags += "label" + if (isFieldAccessor) flags += "accessor" + if (isCaseAcessor) flags += "caseAccessor" + if (isCovariant) flags += "covariant" + if (isContravariant) flags += "contravariant" + if (isScala2X) flags += "scala2x" + if (isDefaultParameterized) flags += "defaultParameterized" + if (isStable) flags += "stable" + flags.result().mkString("<", ",", ">") + } + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/FromSymbol.scala b/compiler/src/dotty/tools/dotc/tasty/FromSymbol.scala new file mode 100644 index 000000000000..576808e4d391 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/FromSymbol.scala @@ -0,0 +1,37 @@ +package dotty.tools.dotc.tasty + +import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.core.Contexts.Context +import dotty.tools.dotc.core.Symbols._ +import dotty.tools.dotc.core.Flags._ + + +object FromSymbol { + + def definition(sym: Symbol)(implicit ctx: Context): tpd.Tree = { + if (sym.is(Package)) packageDef(sym) + else if (sym == defn.AnyClass) tpd.EmptyTree // FIXME + else if (sym == defn.NothingClass) tpd.EmptyTree // FIXME + else if (sym.isClass) classDef(sym.asClass) + else if (sym.isType) typeDef(sym.asType) + else if (sym.is(Method)) defDef(sym.asTerm) + else valDef(sym.asTerm) + } + + def packageDef(sym: Symbol)(implicit ctx: Context): tpd.PackageDef = + tpd.PackageDef(tpd.Ident(sym.typeRef), Nil) + + def classDef(cls: ClassSymbol)(implicit ctx: Context): tpd.Tree = { + val constr = tpd.DefDef(cls.unforcedDecls.find(_.isPrimaryConstructor).asTerm) + val body = cls.unforcedDecls.filter(!_.isPrimaryConstructor).map(s => definition(s)) + val superArgs = Nil // TODO + tpd.ClassDef(cls, constr, body, superArgs) + } + + def typeDef(sym: TypeSymbol)(implicit ctx: Context): tpd.TypeDef = tpd.TypeDef(sym) + + def defDef(sym: TermSymbol)(implicit ctx: Context): tpd.DefDef = tpd.DefDef(sym) + + def valDef(sym: TermSymbol)(implicit ctx: Context): tpd.ValDef = tpd.ValDef(sym) + +} diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala new file mode 100644 index 000000000000..9afff553a488 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -0,0 +1,899 @@ +package dotty.tools.dotc.tasty + +import dotty.tools.dotc.ast.{Trees, tpd, untpd} +import dotty.tools.dotc.core +import dotty.tools.dotc.core._ +import dotty.tools.dotc.core.StdNames.nme +import dotty.tools.dotc.core.Symbols.Symbol +import dotty.tools.dotc.core.Decorators._ +import dotty.tools.dotc.core.quoted.PickledQuotes +import dotty.tools.dotc.util.SourcePosition + +import scala.quoted +import scala.reflect.ClassTag + +object TastyImpl extends scala.tasty.Tasty { + + // ===== Quotes =================================================== + + implicit def QuotedExprDeco[T](x: quoted.Expr[T]): AbstractQuotedExpr = new AbstractQuotedExpr { + def toTasty(implicit ctx: Context): Term = PickledQuotes.quotedExprToTree(x) + } + + implicit def QuotedTypeDeco[T](x: quoted.Type[T]): AbstractQuotedType = new AbstractQuotedType { + def toTasty(implicit ctx: Context): TypeTree = PickledQuotes.quotedTypeToTree(x) + } + + // ===== Contexts ================================================= + + type Context = Contexts.Context + + implicit def ContextDeco(ctx: Context): AbstractContext = new AbstractContext { + def owner: Definition = FromSymbol.definition(ctx.owner)(ctx) + } + + // ===== Id ======================================================= + + type Id = untpd.Ident + + implicit def IdDeco(x: Id): AbstractId = new AbstractId { + def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) + } + + def idClassTag: ClassTag[Id] = implicitly[ClassTag[Id]] + + val Id: IdExtractor = new IdExtractor { + def unapply(x: Id) = 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 + } + } + + // ===== Trees ==================================================== + + + // ----- Top Level Statements ----------------------------------------------- + + type TopLevelStatement = tpd.Tree + + implicit def TopLevelStatementDeco(t: TopLevelStatement): AbstractTopLevelStatement = new AbstractTopLevelStatement { + def pos(implicit ctx: Context): Position = new TastyPosition(t.pos) + } + + type PackageClause = tpd.PackageDef + + def packageClauseClassTag: ClassTag[PackageClause] = implicitly[ClassTag[PackageClause]] + + val PackageClause: PackageClauseExtractor = new PackageClauseExtractor { + def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[TopLevelStatement])] = x match { + case x: tpd.PackageDef @unchecked => Some((x.pid, x.stats)) + case _ => None + } + } + + implicit def PackageClauseDeco(x: PackageClause): AbstractPackageClause = new AbstractPackageClause { + override def definition: Definition = ??? + } + + // ----- Statements ----------------------------------------------- + + type Statement = tpd.Tree + + type Import = tpd.Import + + def importClassTag: ClassTag[Import] = implicitly[ClassTag[Import]] + + val Import: ImportExtractor = new ImportExtractor { + def unapply(x: Import)(implicit ctx: Context): Option[(Term, List[ImportSelector])] = x match { + case x: tpd.Import @unchecked => Some((x.expr, x.selectors)) + case _ => None + } + } + + type ImportSelector = untpd.Tree + + def importSelectorClassTag: ClassTag[ImportSelector] = implicitly[ClassTag[ImportSelector]] + + val SimpleSelector: SimpleSelectorExtractor = new 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 _ => None + } + } + + val RenameSelector: RenameSelectorExtractor = new RenameSelectorExtractor { + def unapply(x: ImportSelector)(implicit ctx: Context): Option[(Id, Id)] = x match { + case Trees.Thicket((id1: untpd.Ident) :: (id2: untpd.Ident) :: Nil) if id2.name != nme.WILDCARD => Some(id1, id2) + case _ => None + } + } + + val OmitSelector: OmitSelectorExtractor = new OmitSelectorExtractor { + def unapply(x: ImportSelector)(implicit ctx: Context): Option[Id] = x match { + case Trees.Thicket((id: untpd.Ident) :: Trees.Ident(nme.WILDCARD) :: Nil) => Some(id) + case _ => None + } + } + + // ----- Definitions ---------------------------------------------- + + type Definition = tpd.Tree + + implicit def DefinitionDeco(x: Definition): AbstractDefinition = new AbstractDefinition { + + def owner(implicit ctx: Context): Definition = FromSymbol.definition(x.symbol.owner) + + def mods(implicit ctx: Context): List[Modifier] = { + val privateWithin = x.symbol.privateWithin + val isProtected = x.symbol.is(core.Flags.Protected) + ModFlags(new FlagSet(x.symbol.flags)) :: + (if (privateWithin.exists) List(ModQual(privateWithin.typeRef, isProtected)) else Nil) ::: + x.symbol.annotations.map(t => ModAnnot(t.tree)) + } + + def localContext(implicit ctx: Context): Context = + if (x.hasType && x.symbol.exists) ctx.withOwner(x.symbol) + else ctx + } + + def definitionClassTag: ClassTag[Definition] = implicitly[ClassTag[Definition]] + + // ClassDef + + type ClassDef = tpd.TypeDef + + def classDefClassTag: ClassTag[ClassDef] = implicitly[ClassTag[ClassDef]] + + val ClassDef: ClassDefExtractor = new ClassDefExtractor { + def unapply(x: ClassDef)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] = x match { + case x: tpd.TypeDef @unchecked if x.isClassDef => + val temp @ Trees.Template(constr, parents, self, _) = x.rhs + val selfVal = if (self.isEmpty) None else Some(self) + Some((x.name.toString, constr, parents, selfVal, temp.body)) + case _ => None + } + } + + // DefDef + + type DefDef = tpd.DefDef + + def defDefClassTag: ClassTag[DefDef] = implicitly[ClassTag[DefDef]] + + val DefDef: DefDefExtractor = new DefDefExtractor { + def unapply(x: DefDef)(implicit ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] = x match { + case x: tpd.DefDef @unchecked => + Some((x.name.toString, x.tparams, x.vparamss, x.tpt, if (x.rhs.isEmpty) None else Some(x.rhs))) + case _ => None + } + } + + // ValDef + + type ValDef = tpd.ValDef + + def valDefClassTag: ClassTag[ValDef] = implicitly[ClassTag[ValDef]] + + val ValDef: ValDefExtractor = new ValDefExtractor { + def unapply(x: ValDef)(implicit ctx: Context): Option[(String, TypeTree, Option[Term])] = x match { + case x: tpd.ValDef @unchecked => + Some((x.name.toString, x.tpt, if (x.rhs.isEmpty) None else Some(x.rhs))) + case _ => None + } + } + + // TypeDef + + type TypeDef = tpd.TypeDef + + def typeDefClassTag: ClassTag[TypeDef] = implicitly[ClassTag[TypeDef]] + + val TypeDef: TypeDefExtractor = new TypeDefExtractor { + def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, MaybeTypeTree /* TypeTree | TypeBoundsTree */)] = x match { + case x: tpd.TypeDef @unchecked if !x.symbol.isClass => Some((x.name.toString, x.rhs)) + case _ => None + } + } + + type PackageDef = tpd.Tree + + def packageDefClassTag: ClassTag[PackageDef] = implicitly[ClassTag[PackageDef]] + + val PackageDef: PackageDefExtractor = new PackageDefExtractor { + def unapply(x: PackageDef)(implicit ctx: Context): Option[(String, List[Statement])] = x match { + case x: tpd.PackageDef => + // FIXME Do not do this eagerly as it forces everithing in the package to be loaded. + // An alternative would be to add it as an extension method instead. + val definitions = + if (x.symbol.is(core.Flags.JavaDefined)) Nil // FIXME should also support java packages + else x.symbol.info.decls.iterator.map(FromSymbol.definition).toList + Some(x.symbol.name.toString, definitions) + case _ => None + } + } + + // ----- Parents -------------------------------------------------- + + type Parent = tpd.Tree + + def parentClassTag: ClassTag[Parent] = implicitly[ClassTag[Parent]] + + val TermParent: TermParentExtractor = new TermParentExtractor { + def unapply(x: Parent)(implicit ctx: Context): Option[Term] = + if (x.isTerm) Some(x) else None + } + + val TypeParent: TypeParentExtractor = new TypeParentExtractor { + def unapply(x: Parent)(implicit ctx: Context): Option[TypeTree] = + if (x.isTerm) None else Some(x) + } + + // ----- Terms ---------------------------------------------------- + + type Term = tpd.Tree + + implicit def TermDeco(t: Term): AbstractTerm = new AbstractTerm { + def pos(implicit ctx: Context): Position = new TastyPosition(t.pos) + def tpe: Types.Type = t.tpe + } + + def termClassTag: ClassTag[Term] = implicitly[ClassTag[Term]] + + val Ident: IdentExtractor = new 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 _ => None + } + } + + val Select: SelectExtractor = new SelectExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, String, Option[Signature])] = x match { + case x: tpd.Select @unchecked if x.isTerm => + val sig = + if (x.symbol.signature == core.Signature.NotAMethod) None + else Some(x.symbol.signature) + Some((x.qualifier, x.name.toString, sig)) + case _ => None + } + } + + val Literal: LiteralExtractor = new LiteralExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Constant] = x match { + case Trees.Literal(const) => Some(const) + case _ => None + } + } + + val This: ThisExtractor = new ThisExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Option[Id]] = x match { + case Trees.This(qual) => Some(if (qual.isEmpty) None else Some(qual)) + case _ => None + } + } + + val New: NewExtractor = new NewExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[TypeTree] = x match { + case x: tpd.New @unchecked => Some(x.tpt) + case _ => None + } + } + + val NamedArg: NamedArgExtractor = new 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 _ => None + } + } + + val Apply: ApplyExtractor = new 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 _ => None + } + } + + val TypeApply: TypeApplyExtractor = new 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 _ => None + } + } + + val Super: SuperExtractor = new 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 _ => None + } + } + + val Typed: TypedExtractor = new TypedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, TypeTree)] = x match { + case x: tpd.Typed @unchecked => Some((x.expr, x.tpt)) + case _ => None + } + } + + val Assign: AssignExtractor = new AssignExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] = x match { + case x: tpd.Assign @unchecked => Some((x.lhs, x.rhs)) + case _ => None + } + } + + val Block: BlockExtractor = new BlockExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(List[Statement], Term)] = x match { + case x: tpd.Block @unchecked => Some((x.stats, x.expr)) + case _ => None + } + } + + val Inlined: InlinedExtractor = new InlinedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Statement], Term)] = x match { + case x: tpd.Inlined @unchecked => + Some((x.call, x.bindings, x.expansion)) + case _ => None + } + } + + val Lambda: LambdaExtractor = new LambdaExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[TypeTree])] = x match { + case x: tpd.Closure @unchecked => Some((x.meth, if (x.tpt.isEmpty) None else Some(x.tpt))) + case _ => None + } + } + + val If: IfExtractor = new 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 _ => None + } + } + + val Match: MatchExtractor = new 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 _ => None + } + } + + val Try: TryExtractor = new 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, if (x.finalizer.isEmpty) None else Some(x.finalizer))) + case _ => None + } + } + + val Return: ReturnExtractor = new ReturnExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Term] = x match { + case x: tpd.Return @unchecked => Some(x.expr) + case _ => None + } + } + + val Repeated: RepeatedExtractor = new RepeatedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[List[Term]] = x match { + case x: tpd.SeqLiteral @unchecked => Some(x.elems) + case _ => None + } + } + + val SelectOuter: SelectOuterExtractor = new SelectOuterExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] = x match { + case x: tpd.Select @unchecked => + x.name match { + case NameKinds.OuterSelectName(_, levels) => Some((x.qualifier, levels, x.tpe)) + case _ => None + } + case _ => None + } + } + + // ----- CaseDef -------------------------------------------------- + + type CaseDef = tpd.CaseDef + + def caseDefClassTag: ClassTag[CaseDef] = implicitly[ClassTag[CaseDef]] + + val CaseDef: CaseDefExtractor = new CaseDefExtractor { + def unapply(x: CaseDef): Option[(Pattern, Option[Term], Term)] = x match { + case x: tpd.CaseDef @unchecked => + Some(x.pat, if (x.guard.isEmpty) None else Some(x.guard), x.body) + case _ => None + } + } + + // ----- Patterns ------------------------------------------------- + + type Pattern = tpd.Tree + + implicit def PatternDeco(x: Pattern): AbstractPattern = new AbstractPattern { + def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) + def tpe: Types.Type = x.tpe + } + + def patternClassTag: ClassTag[Pattern] = implicitly[ClassTag[Pattern]] + + val Value: ValueExtractor = new ValueExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[Term] = x match { + case lit: tpd.Literal @unchecked => Some(lit) + case ident: tpd.Ident @unchecked if ident.isTerm => Some(ident) + case _ => None + } + } + + val Bind: BindExtractor = new BindExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[(String, Pattern)] = x match { + case x: tpd.Bind @unchecked if x.name.isInstanceOf[Names.TermName] => Some(x.name.toString, x.body) + case _ => None + } + } + + val Unapply: UnapplyExtractor = new UnapplyExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[(Term, List[Term], List[Pattern])] = x match { + case x: tpd.UnApply @unchecked => Some(x.fun, x.implicits, x.patterns) + case _ => None + } + } + + val Alternative: AlternativeExtractor = new AlternativeExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[List[Pattern]] = x match { + case x: tpd.Alternative @unchecked => Some(x.trees) + case _ => None + } + } + + val TypeTest: TypeTestExtractor = new TypeTestExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[TypeTree] = x match { + case x: tpd.Typed @unchecked => Some(x.tpt) + case _ => None + } + } + + // ----- MaybeTypeTree ------------------------------------------------ + + type MaybeTypeTree = tpd.Tree + + implicit def MaybeTypeTreeDeco(x: MaybeTypeTree): AbstractMaybeTypeTree = new AbstractMaybeTypeTree { + def tpe: Type = x.tpe + } + + // ----- TypeTrees ------------------------------------------------ + + type TypeTree = tpd.Tree + + def typeTreeClassTag: ClassTag[TypeTree] = implicitly[ClassTag[TypeTree]] + + implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree = new AbstractTypeTree { + def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) + def tpe: Types.Type = x.tpe + } + + val Synthetic: SyntheticExtractor = new SyntheticExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Boolean = x match { + case Trees.TypeTree() => true + case _ => false + } + } + + val TypeIdent: TypeIdentExtractor = new 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 _ => None + } + } + + val TypeSelect: TypeSelectExtractor = new TypeSelectExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] = x match { + case x: tpd.Select @unchecked if x.isType => Some(x.qualifier, x.name.toString) + case _ => None + } + } + + val Singleton: SingletonExtractor = new SingletonExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[Term] = x match { + case x: tpd.SingletonTypeTree @unchecked => Some(x.ref) + case _ => None + } + } + + val Refined: RefinedExtractor = new 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 _ => None + } + } + + val Applied: AppliedExtractor = new AppliedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[TypeTree])] = x match { + case x: tpd.AppliedTypeTree @unchecked => Some(x.tpt, x.args) + case _ => None + } + } + + val Annotated: AnnotatedExtractor = new AnnotatedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, Term)] = x match { + case x: tpd.Annotated @unchecked => Some(x.arg, x.annot) + case _ => None + } + } + + val And: AndExtractor = new AndExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { + case x: tpd.AndTypeTree @unchecked => Some(x.left, x.right) + case _ => None + } + } + + val Or: OrExtractor = new OrExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { + case x: tpd.OrTypeTree @unchecked => Some(x.left, x.right) + case _ => None + } + } + + val ByName: ByNameExtractor = new ByNameExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree] = x match { + case x: tpd.ByNameTypeTree @unchecked => Some(x.result) + case _ => None + } + } + + // ----- TypeBoundsTrees ------------------------------------------------ + + type TypeBoundsTree = tpd.TypeBoundsTree + + implicit def TypeBoundsTreeDeco(x: TypeBoundsTree): AbstractTypeBoundsTree = ??? + + def typeBoundsTreeClassTag: ClassTag[TypeBoundsTree] = implicitly[ClassTag[TypeBoundsTree]] + + val TypeBoundsTree: TypeBoundsTreeExtractor = new TypeBoundsTreeExtractor { + def unapply(x: TypeBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { + case x: tpd.TypeBoundsTree @unchecked => Some(x.lo, x.hi) + case _ => None + } + } + + // ===== Types ==================================================== + + type MaybeType = Types.Type + + // ----- Types ---------------------------------------------------- + + type Type = Types.Type + + def typeClassTag: ClassTag[Type] = implicitly[ClassTag[Type]] + + val ConstantType: ConstantTypeExtractor = new ConstantTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Constant] = x match { + case Types.ConstantType(value) => Some(value) + case _ => None + } + } + + val SymRef: SymRefExtractor = new SymRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Definition, MaybeType /* Type | NoPrefix */)] = x match { + case tp: Types.NamedType => + tp.designator match { + case sym: Symbol => Some((FromSymbol.definition(sym), tp.prefix)) + case _ => None + } + case _ => None + } + } + + val NameRef: NameRefExtractor = new NameRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(String, MaybeType /* Type | NoPrefix */)] = x match { + case tp: Types.NamedType => + tp.designator match { + case name: Names.Name => Some(name.toString, tp.prefix) + case _ => None + } + case _ => None + } + } + + val SuperType: SuperTypeExtractor = new SuperTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + case Types.SuperType(thistpe, supertpe) => Some(thistpe, supertpe) + case _ => None + } + } + + val Refinement: RefinementExtractor = new RefinementExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, MaybeType /* Type | TypeBounds */)] = x match { + case Types.RefinedType(parent, name, info) => Some(parent, name.toString, info) + case _ => None + } + } + + val AppliedType: AppliedTypeExtractor = new AppliedTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[MaybeType /* Type | TypeBounds */])] = x match { + case Types.AppliedType(tycon, args) => Some((tycon, args)) + case _ => None + } + } + + val AnnotatedType: AnnotatedTypeExtractor = new AnnotatedTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] = x match { + case Types.AnnotatedType(underlying, annot) => Some((underlying, annot.tree)) + case _ => None + } + } + + val AndType: AndTypeExtractor = new AndTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + case Types.AndType(left, right) => Some(left, right) + case _ => None + } + } + + val OrType: OrTypeExtractor = new OrTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + case Types.OrType(left, right) => Some(left, right) + case _ => None + } + } + + val ByNameType: ByNameTypeExtractor = new ByNameTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { + case Types.ExprType(resType) => Some(resType) + case _ => None + } + } + + val ParamRef: ParamRefExtractor = new ParamRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[MaybeType], Int)] = x match { + case Types.TypeParamRef(binder, idx) => + Some(( + binder.asInstanceOf[LambdaType[MaybeType]], // Cast to tpd + idx)) + case _ => None + } + } + + val ThisType: ThisTypeExtractor = new ThisTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { + case Types.ThisType(tp) => Some(tp) + case _ => None + } + } + + val RecursiveThis: RecursiveThisExtractor = new RecursiveThisExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[RecursiveType] = x match { + case Types.RecThis(binder) => Some(binder) + case _ => None + } + } + + type RecursiveType = Types.RecType + + def recursiveTypeClassTag: ClassTag[RecursiveType] = implicitly[ClassTag[RecursiveType]] + + val RecursiveType: RecursiveTypeExtractor = new RecursiveTypeExtractor { + def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] = x match { + case tp: Types.RecType => Some(tp.underlying) + case _ => None + } + } + + // ----- Methodic Types ------------------------------------------- + + type LambdaType[ParamInfo <: MaybeType] = Types.LambdaType { type PInfo = ParamInfo } + + type MethodType = Types.MethodType + + implicit def MethodTypeDeco(x: MethodType): AbstractMethodType = new AbstractMethodType { + def isErased: Boolean = x.isErasedMethod + def isImplicit: Boolean = x.isImplicitMethod + } + + def methodTypeClassTag: ClassTag[MethodType] = implicitly[ClassTag[MethodType]] + + val MethodType: MethodTypeExtractor = new MethodTypeExtractor { + def unapply(x: MethodType)(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 + } + } + + type PolyType = Types.PolyType + + def polyTypeClassTag: ClassTag[PolyType] = implicitly[ClassTag[PolyType]] + + val PolyType: PolyTypeExtractor = new PolyTypeExtractor { + def unapply(x: PolyType)(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 + } + } + + type TypeLambda = Types.TypeLambda + + def typeLambdaClassTag: ClassTag[TypeLambda] = implicitly[ClassTag[TypeLambda]] + + val TypeLambda: TypeLambdaExtractor = new TypeLambdaExtractor { + def unapply(x: TypeLambda)(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 + } + } + + // ----- TypeBounds ------------------------------------------------ + + type TypeBounds = Types.TypeBounds + + def typeBoundsClassTag: ClassTag[TypeBounds] = implicitly[ClassTag[TypeBounds]] + + val TypeBounds: TypeBoundsExtractor = new TypeBoundsExtractor { + def unapply(x: TypeBounds)(implicit ctx: Context): Option[(Type, Type)] = x match { + case x: Types.TypeBounds => Some(x.lo, x.hi) + case _ => None + } + } + + // ----- NoPrefix -------------------------------------------------- + + type NoPrefix = Types.NoPrefix.type + + def noPrefixClassTag: ClassTag[NoPrefix] = implicitly[ClassTag[NoPrefix]] + + val NoPrefix: NoPrefixExtractor = new NoPrefixExtractor { + def unapply(x: NoPrefix)(implicit ctx: Context): Boolean = x == Types.NoPrefix + } + + // ===== Constants ================================================ + + type Constant = Constants.Constant + + implicit def ConstantDeco(x: Constant): AbstractConstant = new AbstractConstant { + def value: Any = x.value + } + + def constantClassTag: ClassTag[Constant] = implicitly[ClassTag[Constant]] + + val UnitConstant: UnitExtractor = new UnitExtractor { + def unapply(x: Constant): Boolean = x match { + case x: Constants.Constant => x.tag == Constants.UnitTag + case _ => false + } + } + + val NullConstant: NullExtractor = new NullExtractor { + def unapply(x: Constant): Boolean = x match { + case x: Constants.Constant => x.tag == Constants.NullTag + case _ => false + } + } + + val BooleanConstant: BooleanExtractor = new BooleanExtractor { + def unapply(x: Constant): Option[Boolean] = x match { + case x: Constants.Constant if x.tag == Constants.BooleanTag => Some(x.booleanValue) + case _ => None + } + } + + val ByteConstant: ByteExtractor = new ByteExtractor { + def unapply(x: Constant): Option[Byte] = x match { + case x: Constants.Constant if x.tag == Constants.ByteTag => Some(x.byteValue) + case _ => None + } + } + + val ShortConstant: ShortExtractor = new ShortExtractor { + def unapply(x: Constant): Option[Short] = x match { + case x: Constants.Constant if x.tag == Constants.ShortTag => Some(x.shortValue) + case _ => None + } + } + + val CharConstant: CharExtractor = new CharExtractor { + def unapply(x: Constant): Option[Char] = x match { + case x: Constants.Constant if x.tag == Constants.CharTag => Some(x.charValue) + case _ => None + } + } + + val IntConstant: IntExtractor = new IntExtractor { + def unapply(x: Constant): Option[Int] = x match { + case x: Constants.Constant if x.tag == Constants.IntTag => Some(x.intValue) + case _ => None + } + } + + val LongConstant: LongExtractor = new LongExtractor { + def unapply(x: Constant): Option[Long] = x match { + case x: Constants.Constant if x.tag == Constants.LongTag => Some(x.longValue) + case _ => None + } + } + + val FloatConstant: FloatExtractor = new FloatExtractor { + def unapply(x: Constant): Option[Float] = x match { + case x: Constants.Constant if x.tag == Constants.FloatTag => Some(x.floatValue) + case _ => None + } + } + + val DoubleConstant: DoubleExtractor = new DoubleExtractor { + def unapply(x: Constant): Option[Double] = x match { + case x: Constants.Constant if x.tag == Constants.DoubleTag => Some(x.doubleValue) + case _ => None + } + } + + val StringConstant: StringExtractor = new StringExtractor { + def unapply(x: Constant): Option[String] = x match { + case x: Constants.Constant if x.tag == Constants.StringTag => Some(x.stringValue) + case _ => None + } + } + + // ===== Modifier ================================================= + + type Modifier = ModImpl + + trait ModImpl + case class ModAnnot(tree: Term) extends ModImpl + case class ModFlags(flags: FlagSet) extends ModImpl + case class ModQual(tp: Type, protect: Boolean) extends ModImpl + + def modifierClassTag: ClassTag[Modifier] = implicitly[ClassTag[Modifier]] + + val Annotation: AnnotationExtractor = new AnnotationExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Term] = x match { + case ModAnnot(tree) => Some(tree) + case _ => None + } + } + + val Flags: FlagsExtractor = new FlagsExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[FlagSet] = x match { + case ModFlags(flags) => Some(flags) + case _ => None + } + } + + val QualifiedPrivate: QualifiedPrivateExtractor = new QualifiedPrivateExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Type] = x match { + case ModQual(tp, false) => Some(tp) + case _ => None + } + } + + val QualifiedProtected: QualifiedProtectedExtractor = new QualifiedProtectedExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Type] = x match { + case ModQual(tp, true) => Some(tp) + case _ => None + } + } + + // ===== Signature ================================================ + + type Signature = core.Signature + + def signatureClassTag: ClassTag[Signature] = implicitly[ClassTag[Signature]] + + val Signature: SignatureExtractor = new SignatureExtractor { + def unapply(x: Signature)(implicit ctx: Context): Option[(List[String], String)] = { + Some((x.paramsSig.map(_.toString), x.resSig.toString)) + } + } + + + // ===== Private Methods ========================================== + + private class TastyPosition(val pos: SourcePosition) extends Position { + def start = pos.start + def end = pos.end + + def sourceFile = pos.source.file.jpath + + def startLine = pos.startLine + def endLine = pos.endLine + + def startColumn = pos.startColumn + def endColumn = pos.endColumn + + override def toString: String = s"Position(${pos.line}, ${pos.column})" + } +} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/AnnotationModifier.scala b/compiler/src/dotty/tools/dotc/tasty/internal/AnnotationModifier.scala deleted file mode 100644 index 6d51b20ee9dd..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/AnnotationModifier.scala +++ /dev/null @@ -1,20 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Annotations.Annotation - -import scala.tasty.modifiers - -object AnnotationModifier { - - def apply(tree: Annotation): modifiers.Annotation = new Impl(tree) - - def unapplyAnnotation(arg: Impl)(implicit ctx: Context): Option[modifiers.Annotation.Data] = { - Some(Term(arg.annot.tree)) - } - - private[tasty] class Impl(val annot: Annotation) extends modifiers.Annotation { - override def toString: String = "Annotation" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/CaseDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/CaseDef.scala deleted file mode 100644 index 3f551b5ea171..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/CaseDef.scala +++ /dev/null @@ -1,22 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.Trees -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context - -import scala.tasty.trees - -object CaseDef { - - def apply(tree: tpd.CaseDef): trees.CaseDef = new Impl(tree) - - def unapplyCaseDef(arg: Impl)(implicit ctx: Context): Option[trees.CaseDef.Data] = { - val Trees.CaseDef(pat, guard, body) = arg.tree - Some(Pattern(pat), if (guard.isEmpty) None else Some(Term(guard)), Term(body)) - } - - private[tasty] class Impl(val tree: tpd.CaseDef) extends trees.CaseDef with Positioned { - override def toString: String = "CaseDef" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/ClassDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/ClassDef.scala deleted file mode 100644 index 839a8fa0dc1e..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/ClassDef.scala +++ /dev/null @@ -1,48 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.{Trees, tpd} -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Flags._ -import dotty.tools.dotc.core.Symbols.ClassSymbol - -import scala.tasty.modifiers -import scala.tasty.trees -import scala.tasty.types - -object ClassDef { - - def apply(tree: tpd.TypeDef): trees.ClassDef = new Impl(tree) - - def apply(sym: ClassSymbol)(implicit ctx: Context): trees.ClassDef = { - def toTree(sym: ClassSymbol): tpd.TypeDef = { - val constr = tpd.DefDef(sym.unforcedDecls.find(_.isPrimaryConstructor).asTerm) - val body = sym.unforcedDecls.filter(!_.isPrimaryConstructor).map(s => - if (s.isClass) toTree(s.asClass) - else if (s.isType) tpd.TypeDef(s.asType) - else if (s.is(Method)) tpd.DefDef(s.asTerm) - else tpd.ValDef(s.asTerm) - ) - val superArgs = Nil // TODO - tpd.ClassDef(sym, constr, body, superArgs) - } - new Impl(toTree(sym)) - } - - def unapplyClassDef(arg: Impl)(implicit ctx: Context): Option[trees.ClassDef.Data] = { - val Trees.TypeDef(name, impl@Trees.Template(constr, parents, self, _)) = arg.tree - val className = TypeName(name) - val constructor = DefDef(constr) - val classParents = parents.map(p => if (!p.isType) Term(p) else TypeTree(p)) - val selfVal = if (self.isEmpty) None else Some(ValDef(self)) - val body = impl.body.map(Statement(_)) - Some((className, constructor, classParents, selfVal, body)) - } - - private[tasty] class Impl(val tree: tpd.TypeDef) extends trees.ClassDef with Definition with Positioned { - def tpe: types.Type = Type(tree.tpe) - def mods(implicit ctx: scala.tasty.Context): List[modifiers.Modifier] = Modifiers(tree) - override def toString: String = "ClassDef" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Constant.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Constant.scala deleted file mode 100644 index 300735782cb7..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Constant.scala +++ /dev/null @@ -1,58 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Constants - -import scala.tasty.constants - -object Constant { - - def apply(constant: Constants.Constant): constants.Constant = new Impl(constant) - - def unapplyUnit(arg: Impl): Boolean = arg.const.tag == Constants.UnitTag - - def unapplyNull(arg: Impl): Boolean = arg.const.tag == Constants.NullTag - - def unapplyBoolean(arg: Impl): Option[Boolean] = - if (arg.const.tag == Constants.BooleanTag) Some(arg.const.booleanValue) - else None - - def unapplyByte(arg: Impl): Option[Byte] = - if (arg.const.tag == Constants.ByteTag) Some(arg.const.byteValue) - else None - - def unapplyChar(arg: Impl): Option[Char] = - if (arg.const.tag == Constants.CharTag) Some(arg.const.charValue) - else None - - def unapplyShort(arg: Impl): Option[Short] = - if (arg.const.tag == Constants.ShortTag) Some(arg.const.shortValue) - else None - - def unapplyInt(arg: Impl): Option[Int] = - if (arg.const.tag == Constants.IntTag) Some(arg.const.intValue) - else None - - def unapplyLong(arg: Impl): Option[Long] = - if (arg.const.tag == Constants.LongTag) Some(arg.const.longValue) - else None - - def unapplyFloat(arg: Impl): Option[Float] = - if (arg.const.tag == Constants.FloatTag) Some(arg.const.floatValue) - else None - - def unapplyDouble(arg: Impl): Option[Double] = - if (arg.const.tag == Constants.DoubleTag) Some(arg.const.doubleValue) - else None - - def unapplyString(arg: Impl): Option[String] = - if (arg.const.tag == Constants.StringTag) Some(arg.const.stringValue) - else None - - private[tasty] class Impl(val const: Constants.Constant) extends constants.Constant { - - def value: Any = const.value - - override def toString: String = "Constant" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/DefDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/DefDef.scala deleted file mode 100644 index 996fdce6e6df..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/DefDef.scala +++ /dev/null @@ -1,29 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Symbols.TermSymbol - -import scala.tasty.modifiers -import scala.tasty.trees -import scala.tasty.types - -object DefDef { - - def apply(tree: tpd.DefDef): trees.DefDef = new Impl(tree) - - def apply(sym: TermSymbol)(implicit ctx: Context): trees.DefDef = new Impl(tpd.DefDef(sym)) - - def unapplyDefDef(arg: Impl)(implicit ctx: Context): Option[trees.DefDef.Data] = { - val ddef = arg.tree - Some((TermName(ddef.name), ddef.tparams.map(TypeDef(_)), ddef.vparamss.map(_.map(ValDef(_))), TypeTree(ddef.tpt), if (ddef.rhs.isEmpty) None else Some(Term(ddef.rhs)))) - } - - private[tasty] class Impl(val tree: tpd.DefDef) extends trees.DefDef with Definition with Positioned { - def tpe: types.Type = Type(tree.tpe) - def mods(implicit ctx: scala.tasty.Context): List[modifiers.Modifier] = Modifiers(tree) - override def toString: String = "DefDef" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Definition.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Definition.scala deleted file mode 100644 index ddaf6e82478d..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Definition.scala +++ /dev/null @@ -1,56 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Symbols.{defn, Symbol} -import dotty.tools.dotc.core.Flags._ - -import scala.tasty -import scala.tasty.trees - -trait Definition extends trees.Definition { - - protected def tree: tpd.Tree - - def owner(implicit tctx: scala.tasty.Context): trees.Definition = { - implicit val ctx = tctx.asInstanceOf[TastyContext].ctx - Definition(tree.symbol.owner) - } - - def localContext(implicit tctx: tasty.Context): tasty.Context = { - implicit val ctx = tctx.asInstanceOf[TastyContext].ctx - new TastyContext( - if (tree.hasType && tree.symbol.exists) ctx.withOwner(tree.symbol) - else ctx - ) - } -} - -object Definition { - - def apply(tree: tpd.Tree)(implicit ctx: Context): trees.Definition = tree match { - case tree: tpd.ValDef => ValDef(tree) - case tree: tpd.DefDef => DefDef(tree) - case tree: tpd.TypeDef => - if (tree.symbol.isClass) ClassDef(tree) - else TypeDef(tree) - } - - def apply(sym: Symbol)(implicit ctx: Context): trees.Definition = { - if (sym.is(Package)) PackageDef(sym) - else if (sym == defn.AnyClass) NoDefinition // FIXME - else if (sym == defn.NothingClass) NoDefinition // FIXME - else if (sym.isClass) ClassDef(sym.asClass) - else if (sym.isType) TypeDef(sym.asType) - else if (sym.is(Method)) DefDef(sym.asTerm) - else ValDef(sym.asTerm) - } - - private[tasty] object NoDefinition extends trees.Definition { - def owner(implicit tctx: scala.tasty.Context): trees.Definition = NoDefinition - def localContext(implicit ctx: tasty.Context): tasty.Context = ctx - def pos(implicit ctx: scala.tasty.Context): scala.tasty.Position = ??? - override def toString: String = "NoDefinition" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/FlagsModifier.scala b/compiler/src/dotty/tools/dotc/tasty/internal/FlagsModifier.scala deleted file mode 100644 index 1fa61e7ab1b7..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/FlagsModifier.scala +++ /dev/null @@ -1,82 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Symbols.Symbol -import dotty.tools.dotc.core.Flags._ - -import scala.tasty.modifiers - -object FlagsModifier { - - // TODO make sure all flags are tested - - def apply(sym: Symbol): modifiers.Flags = new Impl(sym) - - def unapplyFlags(arg: Impl)(implicit ctx: Context): Option[modifiers.Flags.Data] = { - val sym = arg.sym - Some(new modifiers.FlagSet { - override def isProtected: Boolean = sym.is(Protected) - override def isAbstract: Boolean = sym.is(Abstract) - override def isFinal: Boolean = sym.is(Final) - override def isSealed: Boolean = sym.is(Sealed) - override def isCase: Boolean = sym.is(Case) - override def isImplicit: Boolean = sym.is(Implicit) - override def isErased: Boolean = sym.is(Erased) - override def isLazy: Boolean = sym.is(Lazy) - override def isOverride: Boolean = sym.is(Override) - override def isInline: Boolean = sym.is(Inline) - override def isMacro: Boolean = sym.is(Macro) - override def isStatic: Boolean = sym.is(JavaStatic) - override def isObject: Boolean = sym.is(Module) - override def isTrait: Boolean = sym.is(Trait) - override def isLocal: Boolean = sym.is(Local) - override def isSynthetic: Boolean = sym.is(Synthetic) - override def isArtifact: Boolean = sym.is(Artifact) - override def isMutable: Boolean = sym.is(Mutable) - override def isLabel: Boolean = sym.is(Label) - override def isFieldAccessor: Boolean = sym.is(Accessor) - override def isCaseAcessor: Boolean = sym.is(CaseAccessor) - override def isCovariant: Boolean = sym.is(Covariant) - override def isContravariant: Boolean = sym.is(Contravariant) - override def isScala2X: Boolean = sym.is(Scala2x) - override def isDefaultParameterized: Boolean = sym.is(DefaultParameterized) - override def isStable: Boolean = sym.is(Stable) - - override def toString: String = { - val flags = List.newBuilder[String] - if (isProtected) flags += "protected " - if (isAbstract) flags += "abstract" - if (isFinal) flags += "final" - if (isSealed) flags += "sealed" - if (isCase) flags += "case" - if (isImplicit) flags += "implicit" - if (isErased) flags += "erased" - if (isLazy) flags += "lazy" - if (isOverride) flags += "override" - if (isInline) flags += "inline" - if (isMacro) flags += "macro" - if (isStatic) flags += "javaStatic" - if (isObject) flags += "module" - if (isTrait) flags += "trait" - if (isLocal) flags += "local" - if (isSynthetic) flags += "synthetic" - if (isArtifact) flags += "artifact" - if (isMutable) flags += "mutable" - if (isLabel) flags += "label" - if (isFieldAccessor) flags += "accessor" - if (isCaseAcessor) flags += "caseAccessor" - if (isCovariant) flags += "covariant" - if (isContravariant) flags += "contravariant" - if (isScala2X) flags += "scala2x" - if (isDefaultParameterized) flags += "defaultParameterized" - if (isStable) flags += "stable" - flags.result().mkString("<", ",", ">") - } - }) - } - - private[tasty] class Impl(val sym: Symbol) extends modifiers.Flags { - override def toString: String = "Flags" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Id.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Id.scala deleted file mode 100644 index dc2a2b85a8f7..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Id.scala +++ /dev/null @@ -1,18 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.ast.untpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Decorators.sourcePos - -object Id { - - def apply(tree: untpd.Ident)(implicit ctx: Context): scala.tasty.Id = - Impl(tree, new Position(tree.pos)) - - private case class Impl(tree: untpd.Ident, pos: scala.tasty.Position) extends scala.tasty.Id with Positioned { - - def name: String = tree.name.toString - - override def toString: String = s"Id($name)" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Import.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Import.scala deleted file mode 100644 index 507e4b71b8b3..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Import.scala +++ /dev/null @@ -1,22 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.{Trees, tpd, untpd} -import dotty.tools.dotc.core.Contexts.Context - -import scala.tasty.trees - -object Import { - - def apply(tree: tpd.Tree): trees.Import = new Impl(tree) - - def unapplyImport(arg: Impl)(implicit ctx: Context) : Option[trees.Import.Data] = { - val Trees.Import(expr, selectors) = arg.tree - Some(Term(expr), selectors.map(ImportSelector(_))) - } - - private[tasty] class Impl(val tree: tpd.Tree)extends trees.Import with Positioned { - override def toString: String = "Import" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/ImportSelector.scala b/compiler/src/dotty/tools/dotc/tasty/internal/ImportSelector.scala deleted file mode 100644 index 8d6bf65f8231..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/ImportSelector.scala +++ /dev/null @@ -1,35 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.{Trees, tpd, untpd} -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.StdNames.nme - -import scala.tasty.trees - -object ImportSelector { - - def apply(tree: untpd.Tree): trees.ImportSelector = new Impl(tree) - - def unapplySimpleSelector(arg: Impl)(implicit ctx: Context): Option[trees.SimpleSelector.Data] = arg.tree match { - case id@Trees.Ident(_) => Some(Id(id)) - case _ => None - } - - def unapplyRenameSelector(arg: Impl)(implicit ctx: Context): Option[trees.RenameSelector.Data] = arg.tree match { - case Trees.Thicket((id1@Trees.Ident(_)) :: (id2@Trees.Ident(_)) :: Nil) if id2.name != nme.WILDCARD => - Some(Id(id1), Id(id2)) - case _ => None - } - - def unapplyOmitSelector(arg: Impl)(implicit ctx: Context): Option[trees.OmitSelector.Data] = arg.tree match { - case Trees.Thicket((id@Trees.Ident(_)) :: Trees.Ident(nme.WILDCARD) :: Nil) => - Some(Id(id)) - case _ => None - } - - private[tasty] class Impl(val tree: untpd.Tree) extends trees.ImportSelector { - override def toString: String = "ImportSelector" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/LambdaType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/LambdaType.scala deleted file mode 100644 index c33e43bcdada..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/LambdaType.scala +++ /dev/null @@ -1,16 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Types - -import scala.tasty.types - -object LambdaType { - - def apply(tpe: Types.LambdaType): types.LambdaType[_, _] = tpe match { - case tpe: Types.MethodType => MethodType(tpe) - case tpe: Types.PolyType => PolyType(tpe) - case tpe: Types.TypeLambda => TypeLambda(tpe) - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/MaybeType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/MaybeType.scala deleted file mode 100644 index c1f45e265c04..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/MaybeType.scala +++ /dev/null @@ -1,15 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types - -import scala.tasty.types - -object MaybeType { - - def apply(tpe: Types.Type)(implicit ctx: Context): types.MaybeType = tpe match { - case tpe: Types.TypeBounds => TypeBounds(tpe) - case _ => Type(tpe) - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/MethodType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/MethodType.scala deleted file mode 100644 index c0c2a9403542..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/MethodType.scala +++ /dev/null @@ -1,27 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.{Flags, Types} - -import scala.tasty.types - -object MethodType { - - // TODO make sure all extractors are tested - - def apply(tpe: Types.MethodType): types.MethodType = new Impl(tpe) - - def unapplyMethodType(arg: Impl)(implicit ctx: Context): Option[types.MethodType.Data] = { - val meth = arg.meth - Some((meth.paramNames.map(TermName(_)), meth.paramInfos.map(Type(_)), Type(meth.resType))) - } - - private[tasty] class Impl(val meth: Types.MethodType) extends types.MethodType { - - override def isImplicit: Boolean = meth.isImplicitMethod - override def isErased: Boolean = meth.isErasedMethod - - override def toString: String = "MethodType" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Modifiers.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Modifiers.scala deleted file mode 100644 index 3f29f0cc2030..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Modifiers.scala +++ /dev/null @@ -1,17 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context - -import scala.tasty.modifiers - -object Modifiers { - - def apply(tree: tpd.MemberDef)(implicit tctx: scala.tasty.Context): List[modifiers.Modifier] = { - implicit val ctx = tctx.asInstanceOf[TastyContext].ctx - FlagsModifier(tree.symbol) :: - QualifiedModifier(tree).toList ::: - tree.symbol.annotations.map(AnnotationModifier(_)) - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Name.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Name.scala deleted file mode 100644 index e86a56693469..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Name.scala +++ /dev/null @@ -1,14 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.core.Names - -import scala.tasty.names - -object Name { - - def apply(name: Names.Name): names.Name = name match { - case name: Names.TermName => TermName(name) - case name: Names.TypeName => TypeName(name) - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/PackageClause.scala b/compiler/src/dotty/tools/dotc/tasty/internal/PackageClause.scala deleted file mode 100644 index 99cf94f0b59e..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/PackageClause.scala +++ /dev/null @@ -1,27 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context - -import scala.tasty.trees - -object PackageClause { - - // TODO make sure all extractors are tested - - def apply(tree: tpd.PackageDef): trees.PackageClause = new Impl(tree) - - def unapplyPackageClause(arg: Impl)(implicit ctx: Context): Option[trees.PackageClause.Data] = - Some(Term(arg.tree.pid), arg.tree.stats.map(TopLevelStatement(_))) - - private[tasty] class Impl(val tree: tpd.PackageDef) extends trees.PackageClause with Positioned { - - def definition(implicit tctx: scala.tasty.Context): trees.Definition = { - implicit val ctx = tctx.asInstanceOf[TastyContext].ctx - PackageDef(tree.symbol) - } - - override def toString: String = "PackageClause" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/PackageDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/PackageDef.scala deleted file mode 100644 index 239682bb07d5..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/PackageDef.scala +++ /dev/null @@ -1,36 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Symbols.Symbol - -import scala.tasty -import scala.tasty.trees - -object PackageDef { - - // TODO make sure all extractors are tested - - def apply(sym: Symbol): trees.PackageDef = new Impl(sym) - - def unapplyPackageDef(arg: Impl)(implicit ctx: Context): Option[trees.PackageDef.Data] = { - Some(Name(arg.sym.name), Nil) // FIXME - } - - private[tasty] class Impl(val sym: Symbol) extends trees.PackageDef { - - override def pos(implicit ctx: tasty.Context): tasty.Position = ??? // FIXME: A packageDef should not have a position, maybe Definition should not have positions - - def owner(implicit tctx: tasty.Context): trees.Definition = { - implicit val ctx = tctx.asInstanceOf[TastyContext].ctx - Definition(sym.owner) - } - - def localContext(implicit tctx: tasty.Context): tasty.Context = { - implicit val ctx = tctx.asInstanceOf[TastyContext].ctx - new TastyContext(ctx.withOwner(sym)) - } - - override def toString: String = "PackageDef" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Pattern.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Pattern.scala deleted file mode 100644 index fd32b75d9e0c..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Pattern.scala +++ /dev/null @@ -1,49 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.{Trees, tpd} -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Names - -import scala.tasty.trees -import scala.tasty.types - -object Pattern { - - def apply(tree: tpd.Tree): trees.Pattern = new Impl(tree) - - def unapplyValue(arg: Impl)(implicit ctx: Context): Option[trees.Value.Data] = arg.tree match { - case lit: tpd.Literal => Some(Term(lit)) - case ident: tpd.Ident => Some(Term(ident)) - case _ => None - } - - def unapplyBind(arg: Impl)(implicit ctx: Context): Option[trees.Bind.Data] = arg.tree match { - case Trees.Bind(name: Names.TermName, body) => Some(TermName(name), Pattern(body)) - case _ => None - } - - def unapplyUnapply(arg: Impl)(implicit ctx: Context): Option[trees.Unapply.Data] = arg.tree match { - case Trees.UnApply(fun, implicits, patterns) => - Some((Term(fun), implicits.map(Term(_)), patterns.map(Pattern(_)))) - case _ => None - } - - def unapplyAlternative(arg: Impl)(implicit ctx: Context): Option[trees.Alternative.Data] = arg.tree match { - case Trees.Alternative(patterns) => Some(patterns.map(Pattern(_))) - case _ => None - } - - def unapplyTypeTest(arg: Impl)(implicit ctx: Context): Option[trees.TypeTest.Data] = arg.tree match { - case Trees.Typed(_, tpt) => Some(TypeTree(tpt)) - case _ => None - } - - private[tasty] class Impl(val tree: tpd.Tree) extends trees.Pattern with Positioned { - - def tpe: types.Type = Type(tree.tpe) - - override def toString: String = "Pattern" - } -} - diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/PolyType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/PolyType.scala deleted file mode 100644 index 1e3cb791e548..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/PolyType.scala +++ /dev/null @@ -1,23 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types - -import scala.tasty.types - -object PolyType { - - // TODO make sure all extractors are tested - - def apply(tpe: Types.PolyType): types.PolyType = new Impl(tpe) - - def unapplyPolyType(arg: Impl)(implicit ctx: Context): Option[types.PolyType.Data] = { - val meth = arg.meth - Some((meth.paramNames.map(TypeName(_)), meth.paramInfos.map(TypeBounds(_)), Type(meth.resType))) - } - - private[tasty] class Impl(val meth: Types.PolyType) extends types.PolyType { - override def toString: String = "PolyType" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Position.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Position.scala deleted file mode 100644 index 939cd5f3177d..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Position.scala +++ /dev/null @@ -1,18 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.util.SourcePosition - -private[tasty] class Position(val pos: SourcePosition) extends scala.tasty.Position { - override def start = pos.start - override def end = pos.end - - override def sourceFile = pos.source.file.jpath - - override def startLine = pos.startLine - override def endLine = pos.endLine - - override def startColumn = pos.startColumn - override def endColumn = pos.endColumn - - override def toString: String = s"Position(${pos.line}, ${pos.column})" -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Positioned.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Positioned.scala deleted file mode 100644 index a0508424f21f..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Positioned.scala +++ /dev/null @@ -1,9 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.core.Decorators.sourcePos - -private[tasty] trait Positioned extends scala.tasty.Positioned with TreeWithContext { - def pos(implicit ctx: scala.tasty.Context): scala.tasty.Position = { - new Position(sourcePos(tree.pos)(ctx.asInstanceOf[TastyContext].ctx)) - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/PossiblySignedName.scala b/compiler/src/dotty/tools/dotc/tasty/internal/PossiblySignedName.scala deleted file mode 100644 index 90208ace205d..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/PossiblySignedName.scala +++ /dev/null @@ -1,13 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.core.{NameKinds, Names} - -import scala.tasty.names - -object PossiblySignedName { - - def apply(name: Names.TermName): names.PossiblySignedName = - if (name.is(NameKinds.SignedName)) SignedName(name) - else TermName(name) - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/QualifiedModifier.scala b/compiler/src/dotty/tools/dotc/tasty/internal/QualifiedModifier.scala deleted file mode 100644 index 83cc934b2f13..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/QualifiedModifier.scala +++ /dev/null @@ -1,28 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Flags - -import scala.tasty.modifiers - -object QualifiedModifier { - - def apply(tree: tpd.DefTree)(implicit ctx: Context): Option[modifiers.Qualified] = - if (tree.symbol.privateWithin.exists) Some(new Impl(tree)) else None - - def unapplyQualifiedPrivate(arg: Impl)(implicit ctx: Context): Option[modifiers.QualifiedPrivate.Data] = { - if (arg.tree.symbol.is(Flags.Protected)) None - else Some(Type(arg.tree.symbol.privateWithin.typeRef)) - } - - def unapplyQualifiedProtected(arg: Impl)(implicit ctx: Context): Option[modifiers.QualifiedProtected.Data] = { - if (arg.tree.symbol.is(Flags.Protected)) Some(Type(arg.tree.symbol.privateWithin.typeRef)) - else None - } - - private[tasty] class Impl(val tree: tpd.DefTree) extends modifiers.Qualified { - override def toString: String = "Qualified" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/RecursiveType.scala b/compiler/src/dotty/tools/dotc/tasty/internal/RecursiveType.scala deleted file mode 100644 index 917dc5e06d23..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/RecursiveType.scala +++ /dev/null @@ -1,21 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types - -import scala.tasty.types - -object RecursiveType { - - // TODO make sure all extractors are tested - - def apply(binder: Types.RecType): types.RecursiveType = new Impl(binder) - - def unapplyRecursiveType(arg: Impl)(implicit ctx: Context): Option[types.RecursiveType.Data] = - Some(Type(arg.binder.underlying)) - - private[tasty] class Impl(val binder: Types.RecType) extends types.RecursiveType { - override def toString: String = "RecursiveType" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/SignedName.scala b/compiler/src/dotty/tools/dotc/tasty/internal/SignedName.scala deleted file mode 100644 index 96fd9fb94b4b..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/SignedName.scala +++ /dev/null @@ -1,25 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.NameKinds -import dotty.tools.dotc.core.Names - -import scala.tasty.names - -object SignedName { - - // TODO make sure all extractors are tested - - def apply(name: Names.TermName): names.SignedName = new Impl(name) - - def unapplySignedName(arg: Impl): Option[names.SignedName.Data] = { - val name = arg.name - val NameKinds.SignedName.SignedInfo(sig) = name.info - Some(TermName(name.underlying), TypeName(sig.resSig), sig.paramsSig.map(TypeName(_))) - } - - private[tasty] class Impl(val name: Names.TermName) extends names.SignedName { - override def toString: String = s"SignedName<$name>" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Statement.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Statement.scala deleted file mode 100644 index 1d0cfb3284b3..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Statement.scala +++ /dev/null @@ -1,15 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context - -import scala.tasty.trees - -object Statement { - def apply(tree: tpd.Tree)(implicit ctx: Context): trees.Statement = tree match { - case tree: tpd.Import => Import(tree) - case tree: tpd.DefTree => Definition(tree)(ctx) - case _ => Term(tree) - } -} - diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TastyContext.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TastyContext.scala deleted file mode 100644 index 7114c2b49859..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TastyContext.scala +++ /dev/null @@ -1,19 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.quoted.PickledQuotes - -import scala.tasty.trees - -private[dotc] class TastyContext(val ctx: Context) extends scala.tasty.Context { - def owner: trees.Definition = Definition(ctx.owner)(ctx) - - def toTasty[T](expr: quoted.Expr[T]): trees.Term = - internal.Term(PickledQuotes.quotedExprToTree(expr)(ctx)) - - def toTasty[T](tpe: quoted.Type[T]): trees.TypeTree = - internal.TypeTree(PickledQuotes.quotedTypeToTree(tpe)(ctx)) - - def toolbox: scala.runtime.tasty.Toolbox = Toolbox -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Term.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Term.scala deleted file mode 100644 index db786f7cdcbd..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Term.scala +++ /dev/null @@ -1,129 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.{Trees, tpd} -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.NameKinds._ -import dotty.tools.dotc.core.Names - -import scala.tasty.trees -import scala.tasty.types - -object Term { - - // TODO make sure all extractors are tested - - def apply(arg: tpd.Tree): trees.Term = new Impl(arg) - - def unapplyIdent(arg: Impl)(implicit ctx: Context): Option[trees.Ident.Data] = arg.tree match { - case Trees.Ident(name: Names.TermName) if arg.tree.isTerm => Some(TermName(name)) - case _ => None - } - - def unapplySelect(arg: Impl)(implicit ctx: Context): Option[trees.Select.Data] = arg.tree match { - case id@Trees.Select(qual, name: Names.TermName) if id.isTerm => Some(Term(qual), PossiblySignedName(name)) - case _ => None - } - - def unapplyLiteral(arg: Impl)(implicit ctx: Context): Option[trees.Literal.Data] = arg.tree match { - case Trees.Literal(const) => Some(Constant(const)) - case _ => None - } - - def unapplyThis(arg: Impl)(implicit ctx: Context): Option[trees.This.Data] = arg.tree match { - case Trees.This(qual) => Some(if (qual.isEmpty) None else Some(Id(qual))) - case _ => None - } - - def unapplyNew(arg: Impl)(implicit ctx: Context): Option[trees.New.Data] = arg.tree match { - case Trees.New(tpt) => Some(TypeTree(tpt)) - case _ => None - } - - def unapplyNamedArg(arg: Impl)(implicit ctx: Context): Option[trees.NamedArg.Data] = arg.tree match { - case Trees.NamedArg(name: Names.TermName, argument) => Some(TermName(name), Term(argument)) - case _ => None - } - - def unapplyApply(arg: Impl)(implicit ctx: Context): Option[trees.Apply.Data] = arg.tree match { - case Trees.Apply(fn, args) => Some((Term(fn), args.map(arg => Term(arg)))) - case _ => None - } - - def unapplyTypeApply(arg: Impl)(implicit ctx: Context): Option[trees.TypeApply.Data] = arg.tree match { - case Trees.TypeApply(fn, args) => Some((Term(fn), args.map(arg => TypeTree(arg)))) - case _ => None - } - - def unapplySuper(arg: Impl)(implicit ctx: Context): Option[trees.Super.Data] = arg.tree match { - case Trees.Super(qual, mixin) => Some((Term(qual), if (mixin.isEmpty) None else Some(Id(mixin)))) - case _ => None - } - - def unapplyTyped(arg: Impl)(implicit ctx: Context): Option[trees.Typed.Data] = arg.tree match { - case Trees.Typed(expr, tpt) => Some((Term(expr), TypeTree(tpt))) - case _ => None - } - - def unapplyAssign(arg: Impl)(implicit ctx: Context): Option[trees.Assign.Data] = arg.tree match { - case Trees.Assign(lhs, rhs) => Some((Term(lhs), Term(rhs))) - case _ => None - } - - def unapplyBlock(arg: Impl)(implicit ctx: Context): Option[trees.Block.Data] = arg.tree match { - case Trees.Block(stats, expr) => Some((stats.map(stat => Statement(stat)), Term(expr))) - case _ => None - } - - def unapplyInlined(arg: Impl)(implicit ctx: Context): Option[trees.Inlined.Data] = arg.tree match { - case Trees.Inlined(call, bindings, expansion) => - Some((Term(call), bindings.map(Definition(_)), Term(expansion))) - case _ => None - } - - def unapplyLambda(arg: Impl)(implicit ctx: Context): Option[trees.Lambda.Data] = arg.tree match { - case Trees.Closure(_, meth, tpt) => Some((Term(meth), if (tpt.isEmpty) None else Some(TypeTree(tpt)))) - case _ => None - } - - def unapplyIf(arg: Impl)(implicit ctx: Context): Option[trees.If.Data] = arg.tree match { - case Trees.If(cond, thenp, elsep) => Some((Term(cond), Term(thenp), Term(elsep))) - case _ => None - } - - def unapplyMatch(arg: Impl)(implicit ctx: Context): Option[trees.Match.Data] = arg.tree match { - case Trees.Match(selector, cases) => Some((Term(selector), cases.map(c => CaseDef(c)))) - case _ => None - } - - def unapplyTry(arg: Impl)(implicit ctx: Context): Option[trees.Try.Data] = arg.tree match { - case Trees.Try(body, catches, finalizer) => Some((Term(body), catches.map(c => CaseDef(c)), if (finalizer.isEmpty) None else Some(Term(finalizer)))) - case _ => None - } - - def unapplyReturn(arg: Impl)(implicit ctx: Context): Option[trees.Return.Data] = arg.tree match { - case Trees.Return(expr, from) => Some(Term(expr)) // TODO use `from` or remove it - case _ => None - } - - def unapplyRepeated(arg: Impl)(implicit ctx: Context): Option[trees.Repeated.Data] = arg.tree match { - case Trees.SeqLiteral(args, elemtpt) => Some(args.map(arg => Term(arg))) // TODO use `elemtpt`? - case _ => None - } - - def unapplySelectOuter(arg: Impl)(implicit ctx: Context): Option[trees.SelectOuter.Data] = arg.tree match { - case sel@Trees.Select(qual, OuterSelectName(_, levels)) => Some((Term(qual), levels, Type(sel.tpe))) - case _ => None - } - - def tree(term: trees.Term): tpd.Tree = term.asInstanceOf[Impl].tree - - private[tasty] class Impl(val tree: tpd.Tree) extends trees.Term with Positioned { - - assert(tree.isTerm || tree.isInstanceOf[Trees.NamedArg[_]] || tree.isInstanceOf[Trees.SeqLiteral[_]]) - - def tpe: types.Type = Type(tree.tpe) - - override def toString: String = "Term" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TermName.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TermName.scala deleted file mode 100644 index 18e3cd1f04c5..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TermName.scala +++ /dev/null @@ -1,63 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Names -import dotty.tools.dotc.core.NameKinds._ -import dotty.tools.dotc.core.NameKinds - -import scala.tasty.names - -object TermName { - - // TODO make sure all extractors are tested - - def apply(name: Names.TermName): names.TermName = new Impl(name) - - def unapplySimple(arg: Impl): Option[names.Simple.Data] = arg.name match { - case name: Names.SimpleName => Some(name.toString) - case _ => None - } - - def unapplyQualified(arg: Impl): Option[names.Qualified.Data] = arg.name match { - case name: Names.DerivedName if name.is(QualifiedName) => - Some(TermName(name.underlying), name.lastPart.toString) - case _ => None - } - - def unapplyDefaultGetter(arg: Impl): Option[names.DefaultGetter.Data] = arg.name match { - case name: Names.DerivedName if name.is(DefaultGetterName) => - Some(TermName(name.underlying), name.lastPart.toString) - case _ => None - } - - def unapplyVariant(arg: Impl): Option[names.Variant.Data] = arg.name match { - case name: Names.DerivedName if name.is(VariantName) => - Some(TermName(name.underlying), name.info.asInstanceOf[NumberedInfo].num == 1) - case _ => None - } - - def unapplySuperAccessor(arg: Impl): Option[names.SuperAccessor.Data] = arg.name match { - case name: Names.DerivedName if name.is(SuperAccessorName) => Some(TermName(name.underlying)) - case _ => None - } - - def unapplyProtectedAccessor(arg: Impl): Option[names.ProtectedAccessor.Data] = arg.name match { - case name: Names.DerivedName if name.is(ProtectedAccessorName) => Some(TermName(name.underlying)) - case _ => None - } - - def unapplyProtectedSetter(arg: Impl): Option[names.ProtectedSetter.Data] = arg.name match { - case name: Names.DerivedName if name.is(ProtectedSetterName) => Some(TermName(name.underlying)) - case _ => None - } - - def unapplyObjectClass(arg: Impl): Option[names.ObjectClass.Data] = arg.name match { - case name: Names.DerivedName if name.is(NameKinds.ModuleClassName) => Some(TermName(name.underlying)) - case _ => None - } - - private[tasty] class Impl(val name: Names.TermName) extends names.TermName { - override def toString: String = s"TermName<$name>" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Toolbox.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Toolbox.scala deleted file mode 100644 index 11e31a444d27..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Toolbox.scala +++ /dev/null @@ -1,217 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.core.Contexts.Context - -import scala.reflect.ClassTag - -import scala.tasty.{constants, names, modifiers, trees, types} - -object Toolbox extends scala.runtime.tasty.Toolbox { - - // Statements - - override def unapplyPackageClause(arg: trees.PackageClause)(implicit ctx: scala.tasty.Context) = PackageClause.unapplyPackageClause(impl(arg))(ictx) - - override def unapplyImport(arg: trees.Import)(implicit ctx: scala.tasty.Context) = Import.unapplyImport(impl(arg))(ictx) - - override def unapplyValDef(arg: trees.ValDef)(implicit ctx: scala.tasty.Context) = ValDef.unapplyValDef(impl(arg))(ictx) - - override def unapplyDefDef(arg: trees.DefDef)(implicit ctx: scala.tasty.Context) = DefDef.unapplyDefDef(impl(arg))(ictx) - - override def unapplyTypeDef(arg: trees.TypeDef)(implicit ctx: scala.tasty.Context) = TypeDef.unapplyTypeDef(impl(arg))(ictx) - - override def unapplyClassDef(arg: trees.ClassDef)(implicit ctx: scala.tasty.Context) = ClassDef.unapplyClassDef(impl(arg))(ictx) - - override def unapplyPackageDef(arg: trees.PackageDef)(implicit ctx: scala.tasty.Context) = PackageDef.unapplyPackageDef(impl(arg))(ictx) - - // Terms - - override def unapplyIdent(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyIdent(impl(arg))(ictx) - - override def unapplySelect(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplySelect(impl(arg))(ictx) - - override def unapplyLiteral(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyLiteral(impl(arg))(ictx) - - override def unapplyThis(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyThis(impl(arg))(ictx) - - override def unapplyNew(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyNew(impl(arg))(ictx) - - override def unapplyNamedArg(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyNamedArg(impl(arg))(ictx) - - override def unapplyApply(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyApply(impl(arg))(ictx) - - override def unapplyTypeApply(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyTypeApply(impl(arg))(ictx) - - override def unapplySuper(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplySuper(impl(arg))(ictx) - - override def unapplyTyped(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyTyped(impl(arg))(ictx) - - override def unapplyAssign(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyAssign(impl(arg))(ictx) - - override def unapplyBlock(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyBlock(impl(arg))(ictx) - - override def unapplyInlined(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyInlined(impl(arg))(ictx) - - override def unapplyLambda(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyLambda(impl(arg))(ictx) - - override def unapplyIf(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyIf(impl(arg))(ictx) - - override def unapplyMatch(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyMatch(impl(arg))(ictx) - - override def unapplyTry(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyTry(impl(arg))(ictx) - - override def unapplyReturn(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyReturn(impl(arg))(ictx) - - override def unapplyRepeated(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplyRepeated(impl(arg))(ictx) - - override def unapplySelectOuter(arg: trees.Term)(implicit ctx: scala.tasty.Context) = Term.unapplySelectOuter(impl(arg))(ictx) - - - // Pattern - - override def unapplyCaseDef(arg: trees.CaseDef)(implicit ctx: scala.tasty.Context) = CaseDef.unapplyCaseDef(impl(arg))(ictx) - - override def unapplyValue(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyValue(impl(arg))(ictx) - - override def unapplyBind(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyBind(impl(arg))(ictx) - - override def unapplyUnapply(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyUnapply(impl(arg))(ictx) - - override def unapplyAlternative(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyAlternative(impl(arg))(ictx) - - override def unapplyTypeTest(arg: trees.Pattern)(implicit ctx: scala.tasty.Context) = Pattern.unapplyTypeTest(impl(arg))(ictx) - - // Type trees - - override def unapplySynthetic(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplySynthetic(impl(arg))(ictx) - - override def unapplyTypeIdent(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyTypeIdent(impl(arg))(ictx) - - override def unapplyTypeSelect(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyTypeSelect(impl(arg))(ictx) - - override def unapplySingleton(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplySingleton(impl(arg))(ictx) - - override def unapplyRefined(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyRefined(impl(arg))(ictx) - - override def unapplyApplied(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyApplied(impl(arg))(ictx) - - override def unapplyAnnotated(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyAnnotated(impl(arg))(ictx) - - override def unapplyAnd(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyAnd(impl(arg))(ictx) - - override def unapplyOr(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyOr(impl(arg))(ictx) - - override def unapplyByName(arg: trees.TypeTree)(implicit ctx: scala.tasty.Context) = TypeTree.unapplyByName(impl(arg))(ictx) - - override def unapplyTypeBoundsTree(arg: trees.TypeBoundsTree)(implicit ctx: scala.tasty.Context) = TypeBoundsTree.unapplyTypeBounds(impl(arg))(ictx) - - // Names - - override def unapplySimple(arg: names.TermName) = TermName.unapplySimple(impl(arg)) - - override def unapplyQualified(arg: names.TermName) = TermName.unapplyQualified(impl(arg)) - - override def unapplyDefaultGetter(arg: names.TermName) = TermName.unapplyDefaultGetter(impl(arg)) - - override def unapplyVariant(arg: names.TermName) = TermName.unapplyVariant(impl(arg)) - - override def unapplySuperAccessor(arg: names.TermName) = TermName.unapplySuperAccessor(impl(arg)) - - override def unapplyProtectedAccessor(arg: names.TermName) = TermName.unapplyProtectedAccessor(impl(arg)) - - override def unapplyProtectedSetter(arg: names.TermName) = TermName.unapplyProtectedSetter(impl(arg)) - - override def unapplyObjectClass(arg: names.TermName) = TermName.unapplyObjectClass(impl(arg)) - - override def unapplySignedName(arg: names.SignedName) = SignedName.unapplySignedName(impl(arg)) - - override def unapplyTypeName(arg: names.TypeName) = TypeName.unapplyTypeName(impl(arg)) - - // Constants - - override def unapplyUnit(arg: constants.Constant) = Constant.unapplyUnit(impl(arg)) - - override def unapplyNull(arg: constants.Constant) = Constant.unapplyNull(impl(arg)) - - override def unapplyBoolean(arg: constants.Constant) = Constant.unapplyBoolean(impl(arg)) - - override def unapplyByte(arg: constants.Constant) = Constant.unapplyByte(impl(arg)) - - override def unapplyChar(arg: constants.Constant) = Constant.unapplyChar(impl(arg)) - - override def unapplyShort(arg: constants.Constant) = Constant.unapplyShort(impl(arg)) - - override def unapplyInt(arg: constants.Constant) = Constant.unapplyInt(impl(arg)) - - override def unapplyLong(arg: constants.Constant) = Constant.unapplyLong(impl(arg)) - - override def unapplyFloat(arg: constants.Constant) = Constant.unapplyFloat(impl(arg)) - - override def unapplyDouble(arg: constants.Constant) = Constant.unapplyDouble(impl(arg)) - - override def unapplyString(arg: constants.Constant) = Constant.unapplyString(impl(arg)) - - // Types - - override def unapplyConstantType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyConstantType(impl(arg))(ictx) - - override def unapplySymRef(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplySymRef(impl(arg))(ictx) - - override def unapplyNameRef(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyNameRef(impl(arg))(ictx) - - override def unapplySuperType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplySuperType(impl(arg))(ictx) - - override def unapplyRefinement(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyRefinement(impl(arg))(ictx) - - override def unapplyAppliedType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyAppliedType(impl(arg))(ictx) - - override def unapplyAnnotatedType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyAnnotatedType(impl(arg))(ictx) - - override def unapplyAndType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyAndType(impl(arg))(ictx) - - override def unapplyOrType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyOrType(impl(arg))(ictx) - - override def unapplyByNameType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyByNameType(impl(arg))(ictx) - - override def unapplyParamRef(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyParamRef(impl(arg))(ictx) - - override def unapplyThisType(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyThisType(impl(arg))(ictx) - - override def unapplyRecursiveThis(arg: types.Type)(implicit ctx: scala.tasty.Context) = Type.unapplyRecursiveThis(impl(arg))(ictx) - - override def unapplyRecursiveType(arg: types.RecursiveType)(implicit ctx: scala.tasty.Context) = RecursiveType.unapplyRecursiveType(impl(arg))(ictx) - - override def unapplyMethodType(arg: types.MethodType)(implicit ctx: scala.tasty.Context) = MethodType.unapplyMethodType(impl(arg))(ictx) - - override def unapplyPolyType(arg: types.PolyType)(implicit ctx: scala.tasty.Context) = PolyType.unapplyPolyType(impl(arg))(ictx) - - override def unapplyTypeLambda(arg: types.TypeLambda)(implicit ctx: scala.tasty.Context) = TypeLambda.unapplyTypeLambda(impl(arg))(ictx) - - override def unapplyTypeBounds(arg: types.TypeBounds)(implicit ctx: scala.tasty.Context) = TypeBounds.unapplyTypeBounds(impl(arg))(ictx) - - // Modifiers - - override def unapplyFlags(arg: modifiers.Flags)(implicit ctx: scala.tasty.Context) = FlagsModifier.unapplyFlags(impl(arg))(ictx) - - override def unapplyQualifiedPrivate(arg: modifiers.Qualified)(implicit ctx: scala.tasty.Context) = QualifiedModifier.unapplyQualifiedPrivate(impl(arg))(ictx) - - override def unapplyQualifiedProtected(arg: modifiers.Qualified)(implicit ctx: scala.tasty.Context) = QualifiedModifier.unapplyQualifiedProtected(impl(arg))(ictx) - - override def unapplyAnnotation(arg: modifiers.Annotation)(implicit ctx: scala.tasty.Context) = AnnotationModifier.unapplyAnnotation(impl(arg))(ictx) - - // Import Selectors - - override def unapplySimpleSelector(arg: trees.ImportSelector)(implicit ctx: scala.tasty.Context) = ImportSelector.unapplySimpleSelector(impl(arg))(ictx) - - override def unapplyRenameSelector(arg: trees.ImportSelector)(implicit ctx: scala.tasty.Context) = ImportSelector.unapplyRenameSelector(impl(arg))(ictx) - - override def unapplyOmitSelector(arg: trees.ImportSelector)(implicit ctx: scala.tasty.Context) = ImportSelector.unapplyOmitSelector(impl(arg))(ictx) - - private def ictx(implicit ctx: scala.tasty.Context): Context = { - val tcxt: TastyContext = impl(ctx) - tcxt.ctx - } - - // TODO emit better error message when tasty trait was not implemented by the compiler - private def impl[T, U <: T](arg: T): U = arg.asInstanceOf[U] -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TopLevelStatement.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TopLevelStatement.scala deleted file mode 100644 index 6f2bc72a7824..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TopLevelStatement.scala +++ /dev/null @@ -1,13 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context - -import scala.tasty.trees - -object TopLevelStatement { - def apply(tree: tpd.Tree)(implicit ctx: Context): trees.TopLevelStatement = tree match { - case tree: tpd.PackageDef => PackageClause(tree) - case _ => Statement(tree) - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TreeWithContext.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TreeWithContext.scala deleted file mode 100644 index 66bcaa37d487..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TreeWithContext.scala +++ /dev/null @@ -1,10 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.ast.Trees -import dotty.tools.dotc.core.Contexts.Context - -// TODO delete this trait -private[tasty] trait TreeWithContext { - def tree: Trees.Tree[_] -// def ctx: Context -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/Type.scala b/compiler/src/dotty/tools/dotc/tasty/internal/Type.scala deleted file mode 100644 index 4791524233fb..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/Type.scala +++ /dev/null @@ -1,100 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Symbols.Symbol -import dotty.tools.dotc.core.Types -import dotty.tools.dotc.core.Names - -import scala.tasty.types - -object Type { - - def apply(arg: Types.Type): types.Type = arg match { - case arg: Types.LambdaType => LambdaType(arg) - case _ => new Impl(arg) - } - - def unapplyConstantType(arg: Impl)(implicit ctx: Context): Option[types.ConstantType.Data] = arg.tpe match { - case Types.ConstantType(value) => Some(Constant(value)) - case _ => None - } - - def unapplySymRef(arg: Impl)(implicit ctx: Context): Option[types.SymRef.Data] = arg.tpe match { - case tp: Types.NamedType => - tp.designator match { - case sym: Symbol => Some(Definition(sym), TypeOrNoPrefix(tp.prefix)) - case _ => None - } - case _ => None - } - - def unapplyNameRef(arg: Impl)(implicit ctx: Context): Option[types.NameRef.Data] = arg.tpe match { - case tp: Types.NamedType => - tp.designator match { - case name: Names.Name => Some(Name(name), TypeOrNoPrefix(tp.prefix)) - case _ => None - } - case _ => None - } - - def unapplySuperType(arg: Impl)(implicit ctx: Context): Option[types.SuperType.Data] = arg.tpe match { - case Types.SuperType(thistpe, supertpe) => Some(Type(thistpe), Type(supertpe)) - case _ => None - } - - def unapplyRefinement(arg: Impl)(implicit ctx: Context): Option[types.Refinement.Data] = arg.tpe match { - case Types.RefinedType(parent, name, info) => - Some((Type(parent), if (name.isTermName) TermName(name.asTermName) else TypeName(name.asTypeName), MaybeType(info))) - case _ => None - } - - def unapplyAppliedType(arg: Impl)(implicit ctx: Context): Option[types.AppliedType.Data] = arg.tpe match { - case Types.AppliedType(tycon, args) => - Some((Type(tycon), args.map { case arg: Types.TypeBounds => TypeBounds(arg); case arg => Type(arg) })) - case _ => None - } - - def unapplyAnnotatedType(arg: Impl)(implicit ctx: Context): Option[types.AnnotatedType.Data] = arg.tpe match { - case Types.AnnotatedType(underlying, annot) => Some((Type(underlying), Term(annot.tree))) - case _ => None - } - - def unapplyAndType(arg: Impl)(implicit ctx: Context): Option[types.AndType.Data] = arg.tpe match { - case Types.AndType(left, right) => Some(Type(left), Type(right)) - case _ => None - } - - def unapplyOrType(arg: Impl)(implicit ctx: Context): Option[types.OrType.Data] = arg.tpe match { - case Types.OrType(left, right) => Some(Type(left), Type(right)) - case _ => None - } - - def unapplyByNameType(arg: Impl)(implicit ctx: Context): Option[types.ByNameType.Data] = arg.tpe match { - case Types.ExprType(resType) => Some(Type(resType)) - case _ => None - } - - def unapplyParamRef(arg: Impl)(implicit ctx: Context): Option[types.ParamRef.Data] = arg.tpe match { - case Types.TypeParamRef(binder, idx) => Some(TypeLambda(binder), idx) - case _ => None - } - - def unapplyThisType(arg: Impl)(implicit ctx: Context): Option[types.ThisType.Data] = arg.tpe match { - case Types.ThisType(tp) => Some(Type(tp)) - case _ => None - } - - def unapplyRecursiveThis(arg: Impl)(implicit ctx: Context): Option[types.RecursiveThis.Data] = arg.tpe match { - case Types.RecThis(binder) => Some(RecursiveType(binder)) - case _ => None - } - - private[tasty] class Impl(val tpe: Types.Type) extends types.Type { - - assert(!tpe.isInstanceOf[Types.TypeBounds]) - - override def toString: String = "Type" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeBounds.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeBounds.scala deleted file mode 100644 index 077c69eadba2..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TypeBounds.scala +++ /dev/null @@ -1,20 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types - -import scala.tasty.types - -object TypeBounds { - - def apply(bounds: Types.TypeBounds): types.TypeBounds = new Impl(bounds) - - def unapplyTypeBounds(arg: Impl)(implicit ctx: Context): Option[types.TypeBounds.Data] = { - Some(Type(arg.bounds.lo), Type(arg.bounds.hi)) - } - - private[tasty] class Impl(val bounds: Types.TypeBounds) extends types.TypeBounds { - override def toString: String = "TypeBounds" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeBoundsTree.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeBoundsTree.scala deleted file mode 100644 index 3357ff384eff..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TypeBoundsTree.scala +++ /dev/null @@ -1,26 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.ast.Trees -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types - -import scala.tasty.trees -import scala.tasty.types - -object TypeBoundsTree { - - def apply(bounds: tpd.TypeBoundsTree): trees.TypeBoundsTree = new Impl(bounds) - - def unapplyTypeBounds(arg: Impl)(implicit ctx: Context): Option[trees.TypeBoundsTree.Data] = { - Some(TypeTree(arg.tree.lo), TypeTree(arg.tree.hi)) - } - - private[tasty] class Impl(val tree: tpd.TypeBoundsTree) extends trees.TypeBoundsTree with Positioned { - - override def tpe: types.TypeBounds = TypeBounds(tree.tpe.asInstanceOf[Types.TypeBounds]) - - override def toString: String = "TypeBoundsTree" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeDef.scala deleted file mode 100644 index f95069b184b2..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TypeDef.scala +++ /dev/null @@ -1,31 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Symbols.TypeSymbol - -import scala.tasty.{modifiers, trees, types} - -object TypeDef { - - def apply(tree: tpd.TypeDef): trees.TypeDef = new Impl(tree) - - def apply(sym: TypeSymbol)(implicit ctx: Context): trees.TypeDef = new Impl(tpd.TypeDef(sym)) - - def unapplyTypeDef(arg: Impl)(implicit ctx: Context): Option[trees.TypeDef.Data] = { - val tdef = arg.tree - val rhs = tdef.rhs match { - case rhs: tpd.TypeBoundsTree => TypeBoundsTree(rhs) - case rhs => TypeTree(rhs) - } - Some((TypeName(tdef.name), rhs)) - } - - private[tasty] class Impl(val tree: tpd.TypeDef) extends trees.TypeDef with Definition with Positioned { - def tpe: types.Type = Type(tree.tpe) - def mods(implicit ctx: scala.tasty.Context): List[modifiers.Modifier] = Modifiers(tree) - override def toString: String = "TypeDef" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeLambda.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeLambda.scala deleted file mode 100644 index 8066bd8aa294..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TypeLambda.scala +++ /dev/null @@ -1,23 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types - -import scala.tasty.types - -object TypeLambda { - - // TODO make sure all extractors are tested - - def apply(tpe: Types.TypeLambda): types.TypeLambda = new Impl(tpe) - - def unapplyTypeLambda(arg: Impl)(implicit ctx: Context): Option[types.TypeLambda.Data] = { - val meth = arg.meth - Some((meth.paramNames.map(TypeName(_)), meth.paramInfos.map(TypeBounds(_)), Type(meth.resType))) - } - - private[tasty] class Impl(val meth: Types.TypeLambda) extends types.TypeLambda { - override def toString: String = "TypeLambda" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeName.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeName.scala deleted file mode 100644 index dca189e8cf9c..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TypeName.scala +++ /dev/null @@ -1,20 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.core.Names - -import scala.tasty.names - -object TypeName { - - def apply(name: Names.TypeName): names.TypeName = new Impl(name) - - def unapplyTypeName(arg: Impl): Option[names.TypeName.Data] = { - Some(TermName(arg.name.toTermName)) - } - - private[tasty] class Impl(val name: Names.TypeName) extends names.TypeName { - override def toString: String = s"TypeName<$name>" - } - -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeOrNoPrefix.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeOrNoPrefix.scala deleted file mode 100644 index 8701edd4bd9d..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TypeOrNoPrefix.scala +++ /dev/null @@ -1,12 +0,0 @@ -package dotty.tools.dotc.tasty.internal - -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Types - -import scala.tasty.types - -object TypeOrNoPrefix { - def apply(tpe: Types.Type)(implicit ctx: Context): types.MaybeType = - if (tpe == Types.NoPrefix) types.NoPrefix - else Type(tpe) -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/TypeTree.scala b/compiler/src/dotty/tools/dotc/tasty/internal/TypeTree.scala deleted file mode 100644 index f8557a30e855..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/TypeTree.scala +++ /dev/null @@ -1,76 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.Trees -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Names - -import scala.tasty.trees -import scala.tasty.types - -object TypeTree { - - def apply(tree: tpd.Tree): trees.TypeTree = new Impl(tree) - - def unapplySynthetic(arg: Impl)(implicit ctx: Context): Boolean = arg.tree match { - case Trees.TypeTree() => true - case _ => false - } - - def unapplyTypeIdent(arg: Impl)(implicit ctx: Context): Option[trees.TypeIdent.Data] = arg.tree match { - case id@Trees.Ident(name: Names.TypeName) if id.isType => Some(TypeName(name)) - case _ => None - } - - def unapplyTypeSelect(arg: Impl)(implicit ctx: Context): Option[trees.TypeSelect.Data] = arg.tree match { - case id@Trees.Select(qual, name: Names.TypeName) if id.isType => Some(Term(qual), TypeName(name)) - case _ => None - } - - def unapplySingleton(arg: Impl)(implicit ctx: Context): Option[trees.Singleton.Data] = arg.tree match { - case Trees.SingletonTypeTree(ref) => Some(Term(ref)) - case _ => None - } - - def unapplyRefined(arg: Impl)(implicit ctx: Context): Option[trees.Refined.Data] = arg.tree match { - case Trees.RefinedTypeTree(tpt, refinements) => Some(TypeTree(tpt), refinements.map(Definition(_))) - case _ => None - } - - def unapplyApplied(arg: Impl)(implicit ctx: Context): Option[trees.Applied.Data] = arg.tree match { - case Trees.AppliedTypeTree(tycon, args) => Some(TypeTree(tycon), args.map(TypeTree(_))) - case _ => None - } - - def unapplyAnnotated(arg: Impl)(implicit ctx: Context): Option[trees.Annotated.Data] = arg.tree match { - case Trees.Annotated(argument, annot) => Some(TypeTree(argument), Term(annot)) - case _ => None - } - - def unapplyAnd(arg: Impl)(implicit ctx: Context): Option[trees.And.Data] = arg.tree match { - case Trees.AndTypeTree(left, right) => Some(TypeTree(left), TypeTree(right)) - case _ => None - } - - def unapplyOr(arg: Impl)(implicit ctx: Context): Option[trees.Or.Data] = arg.tree match { - case Trees.OrTypeTree(left, right) => Some(TypeTree(left), TypeTree(right)) - case _ => None - } - - def unapplyByName(arg: Impl)(implicit ctx: Context): Option[trees.ByName.Data] = arg.tree match { - case Trees.ByNameTypeTree(tpt) => Some(TypeTree(tpt)) - case _ => None - } - - def tree(tpe: trees.TypeTree)(implicit ctx: Context): tpd.Tree = tpe.asInstanceOf[Impl].tree - - private[tasty] class Impl(val tree: tpd.Tree) extends trees.TypeTree with Positioned { - - assert(!tree.isInstanceOf[Trees.TypeBoundsTree[_]]) - - def tpe: types.Type = Type(tree.tpe) - - override def toString: String = "TypeTree" - } -} diff --git a/compiler/src/dotty/tools/dotc/tasty/internal/ValDef.scala b/compiler/src/dotty/tools/dotc/tasty/internal/ValDef.scala deleted file mode 100644 index 9635e62d5bc2..000000000000 --- a/compiler/src/dotty/tools/dotc/tasty/internal/ValDef.scala +++ /dev/null @@ -1,31 +0,0 @@ -package dotty.tools.dotc.tasty -package internal - -import dotty.tools.dotc.ast.tpd -import dotty.tools.dotc.core.Contexts.Context -import dotty.tools.dotc.core.Symbols.TermSymbol - -import scala.tasty.{modifiers, trees, types} - -object ValDef { - - def apply(tree: tpd.ValDef): trees.ValDef = new Impl(tree) - - def apply(sym: TermSymbol)(implicit ctx: Context): trees.ValDef = new Impl(tpd.ValDef(sym)) - - def unapplyValDef(arg: Impl)(implicit ctx: Context): Option[trees.ValDef.Data] = { - val vdef = arg.tree - val rhs = if (vdef.rhs.isEmpty) None else Some(Term(vdef.rhs)) - Some((TermName(vdef.name), TypeTree(vdef.tpt), rhs)) - } - - private def localContext(tree: tpd.Tree)(implicit ctx: Context): Context = - if (tree.hasType && tree.symbol.exists) ctx.withOwner(tree.symbol) else ctx - - private[tasty] class Impl(val tree: tpd.ValDef) extends trees.ValDef with Definition with Positioned { - def tpe: types.Type = Type(tree.tpe) - def mods(implicit ctx: scala.tasty.Context): List[modifiers.Modifier] = Modifiers(tree) - override def toString: String = "ValDef" - } - -} diff --git a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala index f701e5c65c92..c4a96e531189 100644 --- a/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala +++ b/compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala @@ -516,9 +516,9 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { outer.enteredSyms.foreach(registerCapturer) if (ctx.owner.owner.is(Macro)) { - registerCapturer(defn.TastyContext_compilationContext) + registerCapturer(defn.TastyUniverse_compilationUniverse) // Force a macro to have the context in first position - forceCapture(defn.TastyContext_compilationContext) + forceCapture(defn.TastyUniverse_compilationUniverse) // Force all parameters of the macro to be created in the definition order outer.enteredSyms.reverse.foreach(forceCapture) } @@ -649,7 +649,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer { private def isStage0Value(sym: Symbol)(implicit ctx: Context): Boolean = (sym.is(Inline) && sym.owner.is(Macro) && !defn.isFunctionType(sym.info)) || - sym == defn.TastyContext_compilationContext // intrinsic value at stage 0 + sym == defn.TastyUniverse_compilationUniverse // intrinsic value at stage 0 private def liftList(list: List[Tree], tpe: Type)(implicit ctx: Context): Tree = { list.foldRight[Tree](ref(defn.NilModule)) { (x, acc) => diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index e11b4613ca3b..9435843dd7de 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -14,6 +14,7 @@ import dotty.tools.dotc.core.quoted._ import dotty.tools.dotc.core.Types._ import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.TypeErasure +import dotty.tools.dotc.tasty.CompilationUniverse import scala.util.control.NonFatal import dotty.tools.dotc.util.Positions.Position @@ -36,7 +37,7 @@ object Splicer { val liftedArgs = getLiftedArgs(call, bindings) val interpreter = new Interpreter(pos, classLoader) val interpreted = interpreter.interpretCallToSymbol[Seq[Any] => Object](call.symbol) - val tctx = new tasty.internal.TastyContext(ctx) + val tctx = new tasty.CompilationUniverse(ctx) evaluateMacro(pos) { // Some parts of the macro are evaluated during the unpickling performed in quotedExprToTree val evaluated = interpreted.map(lambda => lambda(tctx :: liftedArgs).asInstanceOf[scala.quoted.Expr[Nothing]]) diff --git a/library/src/scala/quoted/Constant.scala b/library/src/scala/quoted/Constant.scala deleted file mode 100644 index 8b068c07201e..000000000000 --- a/library/src/scala/quoted/Constant.scala +++ /dev/null @@ -1,16 +0,0 @@ -package scala.quoted - -import scala.tasty.trees._ -import scala.tasty.Context - -object Constant { - def unapply[T](expr: Expr[T])(implicit ctx: Context): Option[T] = { - def const(tree: Tree): Option[T] = tree match { - case Literal(c) => Some(c.value.asInstanceOf[T]) - case Block(Nil, e) => const(e) - case Inlined(_, Nil, e) => const(e) - case _ => None - } - const(expr.toTasty) - } -} diff --git a/library/src/scala/quoted/Expr.scala b/library/src/scala/quoted/Expr.scala index 06b45b00aaa3..7e9fd0e9d9f1 100644 --- a/library/src/scala/quoted/Expr.scala +++ b/library/src/scala/quoted/Expr.scala @@ -2,8 +2,6 @@ package scala.quoted import scala.runtime.quoted.Toolbox import scala.runtime.quoted.Unpickler.Pickled -import scala.tasty.trees.Term -import scala.tasty.Context sealed abstract class Expr[T] { final def unary_~ : T = throw new Error("~ should have been compiled away") @@ -16,7 +14,6 @@ sealed abstract class Expr[T] { /** Show a source code like representation of this expression */ final def show(implicit toolbox: Toolbox[T]): String = toolbox.show(this) - final def toTasty(implicit ctx: Context): Term = ctx.toTasty(this) } object Expr { diff --git a/library/src/scala/quoted/Type.scala b/library/src/scala/quoted/Type.scala index 19cbbf90c765..c340b3207e03 100644 --- a/library/src/scala/quoted/Type.scala +++ b/library/src/scala/quoted/Type.scala @@ -3,12 +3,9 @@ package scala.quoted import scala.quoted.Types.TaggedType import scala.reflect.ClassTag import scala.runtime.quoted.Unpickler.Pickled -import scala.tasty.trees.TypeTree -import scala.tasty.Context sealed abstract class Type[T] { type unary_~ = T - final def toTasty(implicit ctx: Context): TypeTree = ctx.toTasty(this) } /** Some basic type tags, currently incomplete */ diff --git a/library/src/scala/runtime/quoted/Toolbox.scala b/library/src/scala/runtime/quoted/Toolbox.scala index 1f8c43c61c1d..d7982d09da13 100644 --- a/library/src/scala/runtime/quoted/Toolbox.scala +++ b/library/src/scala/runtime/quoted/Toolbox.scala @@ -1,8 +1,7 @@ package scala.runtime.quoted import scala.annotation.implicitNotFound -import scala.quoted.{Expr, Type} -import scala.tasty +import scala.quoted.Expr @implicitNotFound("Could not find implicit quoted.Toolbox. Default toolbox can be imported with `import dotty.tools.dotc.quoted.Toolbox._`") trait Toolbox[T] { diff --git a/library/src/scala/runtime/tasty/Toolbox.scala b/library/src/scala/runtime/tasty/Toolbox.scala deleted file mode 100644 index 60995029d355..000000000000 --- a/library/src/scala/runtime/tasty/Toolbox.scala +++ /dev/null @@ -1,140 +0,0 @@ -package scala.runtime.tasty - -import scala.tasty.constants.Constant -import scala.tasty.modifiers._ -import scala.tasty.names._ -import scala.tasty.trees._ -import scala.tasty.types._ -import scala.tasty.Context - -trait Toolbox { - - // Statements - - def unapplyPackageClause(arg: PackageClause)(implicit ctx: Context): Option[PackageClause.Data] - def unapplyImport(arg: Import)(implicit ctx: Context): Option[Import.Data] - - // Definitions - - def unapplyValDef(arg: ValDef)(implicit ctx: Context): Option[ValDef.Data] - def unapplyDefDef(arg: DefDef)(implicit ctx: Context): Option[DefDef.Data] - def unapplyTypeDef(arg: TypeDef)(implicit ctx: Context): Option[TypeDef.Data] - def unapplyClassDef(arg: ClassDef)(implicit ctx: Context): Option[ClassDef.Data] - def unapplyPackageDef(arg: PackageDef)(implicit ctx: Context): Option[PackageDef.Data] - - // Terms - - def unapplyIdent(arg: Term)(implicit ctx: Context): Option[Ident.Data] - def unapplySelect(arg: Term)(implicit ctx: Context): Option[Select.Data] - def unapplyLiteral(arg: Term)(implicit ctx: Context): Option[Literal.Data] - def unapplyThis(arg: Term)(implicit ctx: Context): Option[This.Data] - def unapplyNew(arg: Term)(implicit ctx: Context): Option[New.Data] - def unapplyNamedArg(arg: Term)(implicit ctx: Context): Option[NamedArg.Data] - def unapplyApply(arg: Term)(implicit ctx: Context): Option[Apply.Data] - def unapplyTypeApply(arg: Term)(implicit ctx: Context): Option[TypeApply.Data] - def unapplySuper(arg: Term)(implicit ctx: Context): Option[Super.Data] - def unapplyTyped(arg: Term)(implicit ctx: Context): Option[Typed.Data] - def unapplyAssign(arg: Term)(implicit ctx: Context): Option[Assign.Data] - def unapplyBlock(arg: Term)(implicit ctx: Context): Option[Block.Data] - def unapplyInlined(arg: Term)(implicit ctx: Context): Option[Inlined.Data] - def unapplyLambda(arg: Term)(implicit ctx: Context): Option[Lambda.Data] - def unapplyIf(arg: Term)(implicit ctx: Context): Option[If.Data] - def unapplyMatch(arg: Term)(implicit ctx: Context): Option[Match.Data] - def unapplyTry(arg: Term)(implicit ctx: Context): Option[Try.Data] - def unapplyReturn(arg: Term)(implicit ctx: Context): Option[Return.Data] - def unapplyRepeated(arg: Term)(implicit ctx: Context): Option[Repeated.Data] - def unapplySelectOuter(arg: Term)(implicit ctx: Context): Option[SelectOuter.Data] - - // Patterns - - def unapplyCaseDef(arg: CaseDef)(implicit ctx: Context): Option[CaseDef.Data] - - def unapplyValue(arg: Pattern)(implicit ctx: Context): Option[Value.Data] - def unapplyBind(arg: Pattern)(implicit ctx: Context): Option[Bind.Data] - def unapplyUnapply(arg: Pattern)(implicit ctx: Context): Option[Unapply.Data] - def unapplyAlternative(arg: Pattern)(implicit ctx: Context): Option[Alternative.Data] - def unapplyTypeTest(arg: Pattern)(implicit ctx: Context): Option[TypeTest.Data] - - // Type trees - - def unapplySynthetic(arg: TypeTree)(implicit ctx: Context): Boolean - def unapplyTypeIdent(arg: TypeTree)(implicit ctx: Context): Option[TypeIdent.Data] - def unapplyTypeSelect(arg: TypeTree)(implicit ctx: Context): Option[TypeSelect.Data] - def unapplySingleton(arg: TypeTree)(implicit ctx: Context): Option[Singleton.Data] - def unapplyRefined(arg: TypeTree)(implicit ctx: Context): Option[Refined.Data] - def unapplyApplied(arg: TypeTree)(implicit ctx: Context): Option[Applied.Data] - def unapplyAnnotated(arg: TypeTree)(implicit ctx: Context): Option[Annotated.Data] - def unapplyAnd(arg: TypeTree)(implicit ctx: Context): Option[And.Data] - def unapplyOr(arg: TypeTree)(implicit ctx: Context): Option[Or.Data] - def unapplyByName(arg: TypeTree)(implicit ctx: Context): Option[ByName.Data] - - def unapplyTypeBoundsTree(arg: TypeBoundsTree)(implicit ctx: Context): Option[TypeBoundsTree.Data] - - // Names - - def unapplySimple(arg: TermName): Option[Simple.Data] - def unapplyQualified(arg: TermName): Option[Qualified.Data] - - def unapplyDefaultGetter(arg: TermName): Option[DefaultGetter.Data] - def unapplyVariant(arg: TermName): Option[Variant.Data] - def unapplySuperAccessor(arg: TermName): Option[SuperAccessor.Data] - def unapplyProtectedAccessor(arg: TermName): Option[ProtectedAccessor.Data] - def unapplyProtectedSetter(arg: TermName): Option[ProtectedSetter.Data] - def unapplyObjectClass(arg: TermName): Option[ObjectClass.Data] - - def unapplySignedName(arg: SignedName): Option[SignedName.Data] - - def unapplyTypeName(arg: TypeName): Option[TypeName.Data] - - // Constants - - def unapplyUnit(arg: Constant): Boolean - def unapplyNull(arg: Constant): Boolean - def unapplyBoolean(arg: Constant): Option[Boolean] - def unapplyByte(arg: Constant): Option[Byte] - def unapplyChar(arg: Constant): Option[Char] - def unapplyShort(arg: Constant): Option[Short] - def unapplyInt(arg: Constant): Option[Int] - def unapplyLong(arg: Constant): Option[Long] - def unapplyFloat(arg: Constant): Option[Float] - def unapplyDouble(arg: Constant): Option[Double] - def unapplyString(arg: Constant): Option[String] - - // Types - - def unapplyConstantType(arg: Type)(implicit ctx: Context): Option[ConstantType.Data] - def unapplySymRef(arg: Type)(implicit ctx: Context): Option[SymRef.Data] - def unapplyNameRef(arg: Type)(implicit ctx: Context): Option[NameRef.Data] - def unapplySuperType(arg: Type)(implicit ctx: Context): Option[SuperType.Data] - def unapplyRefinement(arg: Type)(implicit ctx: Context): Option[Refinement.Data] - def unapplyAppliedType(arg: Type)(implicit ctx: Context): Option[AppliedType.Data] - def unapplyAnnotatedType(arg: Type)(implicit ctx: Context): Option[AnnotatedType.Data] - def unapplyAndType(arg: Type)(implicit ctx: Context): Option[AndType.Data] - def unapplyOrType(arg: Type)(implicit ctx: Context): Option[OrType.Data] - def unapplyByNameType(arg: Type)(implicit ctx: Context): Option[ByNameType.Data] - def unapplyParamRef(arg: Type)(implicit ctx: Context): Option[ParamRef.Data] - def unapplyThisType(arg: Type)(implicit ctx: Context): Option[ThisType.Data] - def unapplyRecursiveThis(arg: Type)(implicit ctx: Context): Option[RecursiveThis.Data] - - def unapplyRecursiveType(arg: RecursiveType)(implicit ctx: scala.tasty.Context): Option[RecursiveType.Data] - - def unapplyMethodType(arg: MethodType)(implicit ctx: scala.tasty.Context): Option[MethodType.Data] - def unapplyPolyType(arg: PolyType)(implicit ctx: scala.tasty.Context): Option[PolyType.Data] - def unapplyTypeLambda(arg: TypeLambda)(implicit ctx: scala.tasty.Context): Option[TypeLambda.Data] - - def unapplyTypeBounds(arg: TypeBounds)(implicit ctx: scala.tasty.Context): Option[TypeBounds.Data] - - // Modifiers - - def unapplyFlags(arg: Flags)(implicit ctx: Context): Option[Flags.Data] - def unapplyQualifiedPrivate(arg: Qualified)(implicit ctx: Context): Option[QualifiedPrivate.Data] - def unapplyQualifiedProtected(arg: Qualified)(implicit ctx: Context): Option[QualifiedProtected.Data] - def unapplyAnnotation(arg: Annotation)(implicit ctx: Context): Option[Annotation.Data] - - // Import selectors - - def unapplySimpleSelector(arg: ImportSelector)(implicit ctx: Context): Option[SimpleSelector.Data] - def unapplyRenameSelector(arg: ImportSelector)(implicit ctx: Context): Option[RenameSelector.Data] - def unapplyOmitSelector(arg: ImportSelector)(implicit ctx: Context): Option[OmitSelector.Data] - -} diff --git a/library/src/scala/tasty/Context.scala b/library/src/scala/tasty/Context.scala deleted file mode 100644 index afb71b8b10ec..000000000000 --- a/library/src/scala/tasty/Context.scala +++ /dev/null @@ -1,19 +0,0 @@ -package scala.tasty - -import scala.runtime.tasty.Toolbox -import scala.tasty.trees._ - -trait Context { - def owner: Definition - - def toTasty[T](expr: quoted.Expr[T]): Term - def toTasty[T](expr: quoted.Type[T]): TypeTree - - protected[tasty] def toolbox: Toolbox -} - -object Context { - // TODO move to some other place - /** Compiler context available in a ~ at inline site */ - def compilationContext: Context = throw new Exception("Not in inline macro") -} diff --git a/library/src/scala/tasty/ContextProvider.scala b/library/src/scala/tasty/ContextProvider.scala deleted file mode 100644 index 0b5bf1aaf302..000000000000 --- a/library/src/scala/tasty/ContextProvider.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.tasty - -import scala.annotation.implicitNotFound - -@implicitNotFound("Could not find implicit tasty.ContextProvider. Default ContextProvider can be imported with `import dotty.tools.dotc.tasty.ContextProvider._`") -trait ContextProvider { - - /** Provides a Contexts that is valid during the execution of `code`. - * DO NOT use this context of tasty trees that where generated from a different context. - */ - def provide[T](code: Context => T): T - -} diff --git a/library/src/scala/tasty/modifiers/FlagSet.scala b/library/src/scala/tasty/FlagSet.scala similarity index 98% rename from library/src/scala/tasty/modifiers/FlagSet.scala rename to library/src/scala/tasty/FlagSet.scala index d7d7b87f10cc..22cc2d245937 100644 --- a/library/src/scala/tasty/modifiers/FlagSet.scala +++ b/library/src/scala/tasty/FlagSet.scala @@ -1,4 +1,4 @@ -package scala.tasty.modifiers +package scala.tasty trait FlagSet { def isProtected: Boolean diff --git a/library/src/scala/tasty/Id.scala b/library/src/scala/tasty/Id.scala deleted file mode 100644 index 6aae233364c1..000000000000 --- a/library/src/scala/tasty/Id.scala +++ /dev/null @@ -1,5 +0,0 @@ -package scala.tasty - -trait Id extends Positioned { // untyped ident - def name: String -} diff --git a/library/src/scala/tasty/Position.scala b/library/src/scala/tasty/Position.scala deleted file mode 100644 index f5071a0a5567..000000000000 --- a/library/src/scala/tasty/Position.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.tasty - -trait Position { - def start: Int - def end: Int - - def sourceFile: java.nio.file.Path - - def startLine: Int - def startColumn: Int - def endLine: Int - def endColumn: Int -} diff --git a/library/src/scala/tasty/Positioned.scala b/library/src/scala/tasty/Positioned.scala deleted file mode 100644 index 18ebc462472f..000000000000 --- a/library/src/scala/tasty/Positioned.scala +++ /dev/null @@ -1,5 +0,0 @@ -package scala.tasty - -trait Positioned { - def pos(implicit ctx: Context): Position -} diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala new file mode 100644 index 000000000000..2c5bf830b722 --- /dev/null +++ b/library/src/scala/tasty/Tasty.scala @@ -0,0 +1,685 @@ +package scala.tasty + +import scala.reflect.ClassTag + +abstract class Tasty { + + // ===== Quotes =================================================== + + trait AbstractQuotedExpr { + def toTasty(implicit ctx: Context): Term + } + implicit def QuotedExprDeco[T](x: quoted.Expr[T]): AbstractQuotedExpr + + trait AbstractQuotedType { + def toTasty(implicit ctx: Context): TypeTree + } + implicit def QuotedTypeDeco[T](x: quoted.Type[T]): AbstractQuotedType + + // ===== Contexts ================================================= + + type Context + + trait AbstractContext { + def owner: Definition + } + implicit def ContextDeco(x: Context): AbstractContext + + // ===== Id ======================================================= + + type Id + + trait AbstractId extends Positioned + implicit def IdDeco(x: Id): AbstractId + + implicit def idClassTag: ClassTag[Id] + + val Id: IdExtractor + abstract class IdExtractor { + def unapply(x: Id): Option[String] + } + + // ===== Trees ==================================================== + + // ----- Top Level Statements ----------------------------------------------- + + type TopLevelStatement + + trait AbstractTopLevelStatement extends Positioned + implicit def TopLevelStatementDeco(t: TopLevelStatement): AbstractTopLevelStatement + + type PackageClause <: TopLevelStatement + + implicit def packageClauseClassTag: ClassTag[PackageClause] + + val PackageClause: PackageClauseExtractor + abstract class PackageClauseExtractor { + def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[TopLevelStatement])] + } + + trait AbstractPackageClause { + def definition: Definition + } + implicit def PackageClauseDeco(x: PackageClause): AbstractPackageClause + + // ----- Statements ----------------------------------------------- + + type Statement <: TopLevelStatement + + 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])] + } + + type ImportSelector + + implicit def importSelectorClassTag: ClassTag[ImportSelector] + + val SimpleSelector: SimpleSelectorExtractor + abstract class SimpleSelectorExtractor { + def unapply(x: ImportSelector)(implicit ctx: Context): Option[Id] + } + + val RenameSelector: RenameSelectorExtractor + abstract class RenameSelectorExtractor { + def unapply(x: ImportSelector)(implicit ctx: Context): Option[(Id, Id)] + } + + val OmitSelector: OmitSelectorExtractor + abstract class OmitSelectorExtractor { + def unapply(x: ImportSelector)(implicit ctx: Context): Option[Id] + } + + // ----- Definitions ---------------------------------------------- + + type Definition <: Statement + + implicit def definitionClassTag: ClassTag[Definition] + + trait AbstractDefinition { + def mods(implicit ctx: Context): List[Modifier] + def owner(implicit ctx: Context): Definition + def localContext(implicit ctx: Context): Context + } + implicit def DefinitionDeco(x: Definition): AbstractDefinition + + // ClassDef + + type ClassDef <: Definition + + implicit def classDefClassTag: ClassTag[ClassDef] + + val ClassDef: ClassDefExtractor + abstract class ClassDefExtractor { + def unapply(x: ClassDef)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] + } + + // DefDef + + type DefDef <: Definition + + implicit def defDefClassTag: ClassTag[DefDef] + + val DefDef: DefDefExtractor + abstract class DefDefExtractor { + def unapply(x: DefDef)(implicit ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] + } + + // ValDef + + type ValDef <: Definition + + implicit def valDefClassTag: ClassTag[ValDef] + + val ValDef: ValDefExtractor + abstract class ValDefExtractor { + def unapply(x: ValDef)(implicit ctx: Context): Option[(String, TypeTree, Option[Term])] + } + + // TypeDef + + type TypeDef <: Definition + + implicit def typeDefClassTag: ClassTag[TypeDef] + + val TypeDef: TypeDefExtractor + abstract class TypeDefExtractor { + def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, MaybeTypeTree /* TypeTree | TypeBoundsTree */)] + } + + // PackageDef + + type PackageDef <: Definition + + implicit def packageDefClassTag: ClassTag[PackageDef] + + val PackageDef: PackageDefExtractor + abstract class PackageDefExtractor { + def unapply(x: PackageDef)(implicit ctx: Context): Option[(String, List[Statement])] + } + + // ----- Parents -------------------------------------------------- + + type Parent + + implicit def parentClassTag: ClassTag[Parent] + + val TermParent: TermParentExtractor + abstract class TermParentExtractor { + def unapply(x: Parent)(implicit ctx: Context): Option[Term] + } + + val TypeParent: TypeParentExtractor + abstract class TypeParentExtractor { + def unapply(x: Parent)(implicit ctx: Context): Option[TypeTree] + } + + // ----- Terms ---------------------------------------------------- + + type Term <: Statement + + trait AbstractTerm extends Typed with Positioned + implicit def TermDeco(t: Term): AbstractTerm + + implicit def termClassTag: ClassTag[Term] + + val Ident: IdentExtractor + abstract class IdentExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[String] + } + + val Select: SelectExtractor + abstract class SelectExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, String, Option[Signature])] + } + + val Literal: LiteralExtractor + abstract class LiteralExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Constant] + } + + val This: ThisExtractor + abstract class ThisExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Option[Id]] + } + + val New: NewExtractor + abstract class NewExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[TypeTree] + } + + val NamedArg: NamedArgExtractor + abstract class NamedArgExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(String, Term)] + } + + val Apply: ApplyExtractor + abstract class ApplyExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Term])] + } + + val TypeApply: TypeApplyExtractor + abstract class TypeApplyExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[TypeTree])] + } + + val Super: SuperExtractor + abstract class SuperExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[Id])] + } + + val Typed: TypedExtractor + abstract class TypedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, TypeTree)] + } + + val Assign: AssignExtractor + abstract class AssignExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] + } + + val Block: BlockExtractor + abstract class BlockExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(List[Statement], Term)] + } + + val Inlined: InlinedExtractor + abstract class InlinedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Definition], Term)] + } + + val Lambda: LambdaExtractor + abstract class LambdaExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[TypeTree])] + } + + val If: IfExtractor + abstract class IfExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term, Term)] + } + + val Match: MatchExtractor + abstract class MatchExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef])] + } + + val Try: TryExtractor + abstract class TryExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef], Option[Term])] + } + + val Return: ReturnExtractor + abstract class ReturnExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Term] + } + + val Repeated: RepeatedExtractor + abstract class RepeatedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[List[Term]] + } + + val SelectOuter: SelectOuterExtractor + abstract class SelectOuterExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] + } + + // ----- CaseDef -------------------------------------------------- + + type CaseDef + + implicit def caseDefClassTag: ClassTag[CaseDef] + + val CaseDef: CaseDefExtractor + abstract class CaseDefExtractor { + def unapply(x: CaseDef): Option[(Pattern, Option[Term], Term)] + } + + // ----- Patterns ------------------------------------------------- + + type Pattern + + trait AbstractPattern extends Typed with Positioned + implicit def PatternDeco(x: Pattern): AbstractPattern + + implicit def patternClassTag: ClassTag[Pattern] + + val Value: ValueExtractor + abstract class ValueExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[Term] + } + + val Bind: BindExtractor + abstract class BindExtractor { + def unapply(x: 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])] + } + + val Alternative: AlternativeExtractor + abstract class AlternativeExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[List[Pattern]] + } + + val TypeTest: TypeTestExtractor + abstract class TypeTestExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[TypeTree] + } + + // ----- TypeTrees ------------------------------------------------ + + type MaybeTypeTree + + trait AbstractMaybeTypeTree { + def tpe: MaybeType + } + implicit def MaybeTypeTreeDeco(x: MaybeTypeTree): AbstractMaybeTypeTree + + + // ----- TypeTrees ------------------------------------------------ + + type TypeTree <: MaybeTypeTree + + trait AbstractTypeTree extends Typed with Positioned + implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree + + implicit def typeTreeClassTag: ClassTag[TypeTree] + + val Synthetic: SyntheticExtractor + abstract class SyntheticExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Boolean + } + + val TypeIdent: TypeIdentExtractor + abstract class TypeIdentExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[String] + } + + val TypeSelect: TypeSelectExtractor + abstract class TypeSelectExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] + } + + val Singleton: SingletonExtractor + abstract class SingletonExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[Term] + } + + val Refined: RefinedExtractor + abstract class RefinedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[Definition])] + } + + val Applied: AppliedExtractor + abstract class AppliedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[TypeTree])] + } + + val Annotated: AnnotatedExtractor + abstract class AnnotatedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, Term)] + } + + val And: AndExtractor + abstract class AndExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] + } + + val Or: OrExtractor + abstract class OrExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] + } + + val ByName: ByNameExtractor + abstract class ByNameExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree] + } + + // ----- TypeBoundsTrees ------------------------------------------------ + + type TypeBoundsTree <: MaybeTypeTree + + trait AbstractTypeBoundsTree { + def tpe: TypeBounds + } + implicit def TypeBoundsTreeDeco(x: TypeBoundsTree): AbstractTypeBoundsTree + + implicit def typeBoundsTreeClassTag: ClassTag[TypeBoundsTree] + + val TypeBoundsTree: TypeBoundsTreeExtractor + abstract class TypeBoundsTreeExtractor { + def unapply(x: TypeBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] + } + + // ===== Types ==================================================== + + type MaybeType + + trait Typed { + def tpe: Type + } + + // ----- Types ---------------------------------------------------- + + type Type <: MaybeType + + implicit def typeClassTag: ClassTag[Type] + + val ConstantType: ConstantTypeExtractor + abstract class ConstantTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Constant] + } + + val SymRef: SymRefExtractor + abstract class SymRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Definition, MaybeType /* Type | NoPrefix */)] + } + + val NameRef: NameRefExtractor + abstract class NameRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(String, MaybeType /* Type | NoPrefix */)] + } + + val SuperType: SuperTypeExtractor + abstract class SuperTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + } + + val Refinement: RefinementExtractor + abstract class RefinementExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, MaybeType /* Type | TypeBounds */)] + } + + val AppliedType: AppliedTypeExtractor + abstract class AppliedTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[MaybeType /* Type | TypeBounds */])] + } + + val AnnotatedType: AnnotatedTypeExtractor + abstract class AnnotatedTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] + } + + val AndType: AndTypeExtractor + abstract class AndTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + } + + val OrType: OrTypeExtractor + abstract class OrTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + } + + val ByNameType: ByNameTypeExtractor + abstract class ByNameTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Type] + } + + val ParamRef: ParamRefExtractor + abstract class ParamRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[MaybeType], Int)] + } + + val ThisType: ThisTypeExtractor + abstract class ThisTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Type] + } + + val RecursiveThis: RecursiveThisExtractor + abstract class RecursiveThisExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[RecursiveType] + } + + type RecursiveType <: Type + implicit def recursiveTypeClassTag: ClassTag[RecursiveType] + val RecursiveType: RecursiveTypeExtractor + abstract class RecursiveTypeExtractor { + def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] + } + + // ----- Methodic Types ------------------------------------------- + + type LambdaType[ParamInfo <: MaybeType] <: Type + + type MethodType <: LambdaType[Type] + + trait AbstractMethodType { + def isImplicit: Boolean + def isErased: Boolean + } + implicit def MethodTypeDeco(x: MethodType): AbstractMethodType + + implicit def methodTypeClassTag: ClassTag[MethodType] + + val MethodType: MethodTypeExtractor + abstract class MethodTypeExtractor { + def unapply(x: MethodType)(implicit ctx: Context): Option[(List[String], List[Type], Type)] + } + + type PolyType <: LambdaType[TypeBounds] + + implicit def polyTypeClassTag: ClassTag[PolyType] + + val PolyType: PolyTypeExtractor + abstract class PolyTypeExtractor { + def unapply(x: PolyType)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] + } + + type TypeLambda <: LambdaType[TypeBounds] + + implicit def typeLambdaClassTag: ClassTag[TypeLambda] + + val TypeLambda: TypeLambdaExtractor + abstract class TypeLambdaExtractor { + def unapply(x: TypeLambda)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] + } + + // ----- TypeBounds ----------------------------------------------- + + type TypeBounds <: MaybeType + + implicit def typeBoundsClassTag: ClassTag[TypeBounds] + + val TypeBounds: TypeBoundsExtractor + abstract class TypeBoundsExtractor { + def unapply(x: TypeBounds)(implicit ctx: Context): Option[(Type, Type)] + } + + // ----- NoPrefix ------------------------------------------------- + + type NoPrefix <: MaybeType + + implicit def noPrefixClassTag: ClassTag[NoPrefix] + + val NoPrefix: NoPrefixExtractor + abstract class NoPrefixExtractor { + def unapply(x: NoPrefix)(implicit ctx: Context): Boolean + } + + // ===== Constants ================================================ + + type Constant + trait AbstractConstant { + def value: Any + } + implicit def ConstantDeco(x: Constant): AbstractConstant + + implicit def constantClassTag: ClassTag[Constant] + + val UnitConstant: UnitExtractor + abstract class UnitExtractor { + def unapply(x: Constant): Boolean + } + + val NullConstant: NullExtractor + abstract class NullExtractor { + def unapply(x: Constant): Boolean + } + + val BooleanConstant: BooleanExtractor + abstract class BooleanExtractor { + def unapply(x: Constant): Option[Boolean] + } + + val ByteConstant: ByteExtractor + abstract class ByteExtractor { + def unapply(x: Constant): Option[Byte] + } + + val ShortConstant: ShortExtractor + abstract class ShortExtractor { + def unapply(x: Constant): Option[Short] + } + + val CharConstant: CharExtractor + abstract class CharExtractor { + def unapply(x: Constant): Option[Char] + } + + val IntConstant: IntExtractor + abstract class IntExtractor { + def unapply(x: Constant): Option[Int] + } + + val LongConstant: LongExtractor + abstract class LongExtractor { + def unapply(x: Constant): Option[Long] + } + + val FloatConstant: FloatExtractor + abstract class FloatExtractor { + def unapply(x: Constant): Option[Float] + } + + val DoubleConstant: DoubleExtractor + abstract class DoubleExtractor { + def unapply(x: Constant): Option[Double] + } + + val StringConstant: StringExtractor + abstract class StringExtractor { + def unapply(x: Constant): Option[String] + } + + // ===== Modifiers ================================================ + + type Modifier + + implicit def modifierClassTag: ClassTag[Modifier] + + val Annotation: AnnotationExtractor + abstract class AnnotationExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Term] + } + + val Flags: FlagsExtractor + abstract class FlagsExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[FlagSet] + } + + val QualifiedPrivate: QualifiedPrivateExtractor + abstract class QualifiedPrivateExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Type] + } + + val QualifiedProtected: QualifiedProtectedExtractor + abstract class QualifiedProtectedExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Type] + } + + // ===== Signature ================================================ + + type Signature + + implicit def signatureClassTag: ClassTag[Signature] + + val Signature: SignatureExtractor + abstract class SignatureExtractor { + def unapply(x: Signature)(implicit ctx: Context): Option[(List[String], String)] + } + + // ===== Positions ================================================ + + trait Position { + def start: Int + def end: Int + + def sourceFile: java.nio.file.Path + + def startLine: Int + def startColumn: Int + def endLine: Int + def endColumn: Int + } + + trait Positioned { + def pos(implicit ctx: Context): Position + } + +} diff --git a/library/src/scala/tasty/Universe.scala b/library/src/scala/tasty/Universe.scala new file mode 100644 index 000000000000..3f2f4fa678f4 --- /dev/null +++ b/library/src/scala/tasty/Universe.scala @@ -0,0 +1,11 @@ +package scala.tasty + +trait Universe { + implicit val tasty: Tasty + implicit val context: tasty.Context +} + +object Universe { + /** Compiler context available in a ~ at inline site */ + implicit def compilationUniverse: Universe = throw new Exception("Not in inline macro.") +} diff --git a/library/src/scala/tasty/constants/Constant.scala b/library/src/scala/tasty/constants/Constant.scala deleted file mode 100644 index 9e55c48d402e..000000000000 --- a/library/src/scala/tasty/constants/Constant.scala +++ /dev/null @@ -1,5 +0,0 @@ -package scala.tasty.constants - -trait Constant { - def value: Any -} diff --git a/library/src/scala/tasty/constants/package.scala b/library/src/scala/tasty/constants/package.scala deleted file mode 100644 index d54c2fb3e017..000000000000 --- a/library/src/scala/tasty/constants/package.scala +++ /dev/null @@ -1,48 +0,0 @@ -package scala.tasty - -package object constants { - - object Unit { - def unapply(arg: Constant)(implicit ctx: Context): Boolean = ctx.toolbox.unapplyUnit(arg) - } - - object Null { - def unapply(arg: Constant)(implicit ctx: Context): Boolean = ctx.toolbox.unapplyNull(arg) - } - - object Boolean { - def unapply(arg: Constant)(implicit ctx: Context): Option[Boolean] = ctx.toolbox.unapplyBoolean(arg) - } - - object Byte { - def unapply(arg: Constant)(implicit ctx: Context): Option[Byte] = ctx.toolbox.unapplyByte(arg) - } - - object Char { - def unapply(arg: Constant)(implicit ctx: Context): Option[Char] = ctx.toolbox.unapplyChar(arg) - } - - object Short { - def unapply(arg: Constant)(implicit ctx: Context): Option[Short] = ctx.toolbox.unapplyShort(arg) - } - - object Int { - def unapply(arg: Constant)(implicit ctx: Context): Option[Int] = ctx.toolbox.unapplyInt(arg) - } - - object Long { - def unapply(arg: Constant)(implicit ctx: Context): Option[Long] = ctx.toolbox.unapplyLong(arg) - } - - object Float { - def unapply(arg: Constant)(implicit ctx: Context): Option[Float] = ctx.toolbox.unapplyFloat(arg) - } - - object Double { - def unapply(arg: Constant)(implicit ctx: Context): Option[Double] = ctx.toolbox.unapplyDouble(arg) - } - - object String { - def unapply(arg: Constant)(implicit ctx: Context): Option[String] = ctx.toolbox.unapplyString(arg) - } -} diff --git a/library/src/scala/tasty/modifiers/Annotation.scala b/library/src/scala/tasty/modifiers/Annotation.scala deleted file mode 100644 index f107567f2051..000000000000 --- a/library/src/scala/tasty/modifiers/Annotation.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package modifiers - -trait Annotation extends Modifier - -object Annotation { - type Data = trees.Term - def unapply(arg: Annotation)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAnnotation(arg) -} diff --git a/library/src/scala/tasty/modifiers/Flags.scala b/library/src/scala/tasty/modifiers/Flags.scala deleted file mode 100644 index 71fc99efb304..000000000000 --- a/library/src/scala/tasty/modifiers/Flags.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package modifiers - -trait Flags extends Modifier - -object Flags { - type Data = FlagSet - def unapply(arg: Flags)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyFlags(arg) -} diff --git a/library/src/scala/tasty/modifiers/Modifier.scala b/library/src/scala/tasty/modifiers/Modifier.scala deleted file mode 100644 index 8f8bdb99d2cb..000000000000 --- a/library/src/scala/tasty/modifiers/Modifier.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.tasty.modifiers - -trait Modifier diff --git a/library/src/scala/tasty/modifiers/Qualified.scala b/library/src/scala/tasty/modifiers/Qualified.scala deleted file mode 100644 index daf1decce5fb..000000000000 --- a/library/src/scala/tasty/modifiers/Qualified.scala +++ /dev/null @@ -1,14 +0,0 @@ -package scala.tasty -package modifiers - -trait Qualified extends Modifier - -object QualifiedPrivate { - type Data = types.Type - def unapply(arg: Qualified)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyQualifiedPrivate(arg) -} - -object QualifiedProtected { - type Data = types.Type - def unapply(arg: Qualified)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyQualifiedProtected(arg) -} diff --git a/library/src/scala/tasty/names/Name.scala b/library/src/scala/tasty/names/Name.scala deleted file mode 100644 index 5666b9fde07b..000000000000 --- a/library/src/scala/tasty/names/Name.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.tasty.names - -trait Name diff --git a/library/src/scala/tasty/names/PossiblySignedName.scala b/library/src/scala/tasty/names/PossiblySignedName.scala deleted file mode 100644 index d32347808731..000000000000 --- a/library/src/scala/tasty/names/PossiblySignedName.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.tasty.names - -trait PossiblySignedName diff --git a/library/src/scala/tasty/names/SignedName.scala b/library/src/scala/tasty/names/SignedName.scala deleted file mode 100644 index d2691f73ba0e..000000000000 --- a/library/src/scala/tasty/names/SignedName.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package names - -trait SignedName extends PossiblySignedName - -object SignedName { - type Data = (TermName, TypeName, List[TypeName]) - def unapply(arg: SignedName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySignedName(arg) -} diff --git a/library/src/scala/tasty/names/TermName.scala b/library/src/scala/tasty/names/TermName.scala deleted file mode 100644 index 9274b39538dc..000000000000 --- a/library/src/scala/tasty/names/TermName.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.tasty.names - -trait TermName extends Name with PossiblySignedName diff --git a/library/src/scala/tasty/names/TypeName.scala b/library/src/scala/tasty/names/TypeName.scala deleted file mode 100644 index 0a7908f2867f..000000000000 --- a/library/src/scala/tasty/names/TypeName.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package names - -trait TypeName extends Name - -object TypeName { - type Data = TermName - def unapply(arg: TypeName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeName(arg) -} diff --git a/library/src/scala/tasty/names/package.scala b/library/src/scala/tasty/names/package.scala deleted file mode 100644 index 225de9da4346..000000000000 --- a/library/src/scala/tasty/names/package.scala +++ /dev/null @@ -1,52 +0,0 @@ -package scala.tasty - -package object names { - - object Simple { - type Data = String - def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySimple(arg) - } - - // s"$prefix.$name" - object Qualified { - type Data = (TermName, String) - def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyQualified(arg) - } - - // s"$methodName${"$default$"}${idx+1}" - object DefaultGetter { - type Data = (TermName, String) - def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyDefaultGetter(arg) - } - - // s"${if (covariant) "+" else "-"}$underlying" - object Variant { - type Data = (TermName, Boolean) - def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyVariant(arg) - } - - // s"${"super$"}$underlying" - object SuperAccessor { - type Data = TermName - def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySuperAccessor(arg) - } - - // s"${"protected$"}$underlying" - object ProtectedAccessor { - type Data = TermName - def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyProtectedAccessor(arg) - } - - // s"${"protected$set"}$underlying" - object ProtectedSetter { - type Data = TermName - def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyProtectedSetter(arg) - } - - // s"$underlying${"$"}" - object ObjectClass { - type Data = TermName - def unapply(arg: TermName)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyObjectClass(arg) - } - -} diff --git a/library/src/scala/tasty/trees/CaseDef.scala b/library/src/scala/tasty/trees/CaseDef.scala deleted file mode 100644 index d269e00b7958..000000000000 --- a/library/src/scala/tasty/trees/CaseDef.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package trees - -trait CaseDef extends Tree - -object CaseDef { - type Data = (Pattern, Option[Term], Term) - def unapply(arg: CaseDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyCaseDef(arg) -} diff --git a/library/src/scala/tasty/trees/ClassDef.scala b/library/src/scala/tasty/trees/ClassDef.scala deleted file mode 100644 index 92dcba8d0f04..000000000000 --- a/library/src/scala/tasty/trees/ClassDef.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.tasty -package trees - -import scala.tasty.modifiers.Modifier - -trait ClassDef extends Definition { - def mods(implicit ctx: Context): List[Modifier] -} - -object ClassDef { - type Data = (names.TypeName, DefDef, List[Tree] /* List[Term | TypeTree] */, Option[ValDef], List[Statement]) - def unapply(arg: ClassDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyClassDef(arg) -} diff --git a/library/src/scala/tasty/trees/DefDef.scala b/library/src/scala/tasty/trees/DefDef.scala deleted file mode 100644 index 72afe2a032f4..000000000000 --- a/library/src/scala/tasty/trees/DefDef.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.tasty -package trees - -import scala.tasty.modifiers.Modifier - -trait DefDef extends Definition { - def mods(implicit ctx: Context): List[Modifier] -} - -object DefDef { - type Data = (names.TermName, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term]) - def unapply(arg: DefDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyDefDef(arg) -} diff --git a/library/src/scala/tasty/trees/Definition.scala b/library/src/scala/tasty/trees/Definition.scala deleted file mode 100644 index 9fc800a2cedd..000000000000 --- a/library/src/scala/tasty/trees/Definition.scala +++ /dev/null @@ -1,7 +0,0 @@ -package scala.tasty -package trees - -trait Definition extends Statement { - def owner(implicit ctx: Context): Definition - def localContext(implicit ctx: Context): Context -} diff --git a/library/src/scala/tasty/trees/Import.scala b/library/src/scala/tasty/trees/Import.scala deleted file mode 100644 index 9d7ceef03173..000000000000 --- a/library/src/scala/tasty/trees/Import.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package trees - -trait Import extends Statement - -object Import { - type Data = (Term, List[ImportSelector]) - def unapply(arg: Import)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyImport(arg) -} diff --git a/library/src/scala/tasty/trees/ImportSelector.scala b/library/src/scala/tasty/trees/ImportSelector.scala deleted file mode 100644 index 4a24ba5cc996..000000000000 --- a/library/src/scala/tasty/trees/ImportSelector.scala +++ /dev/null @@ -1,19 +0,0 @@ -package scala.tasty -package trees - -trait ImportSelector - -object SimpleSelector { - type Data = Id - def unapply(arg: ImportSelector)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySimpleSelector(arg) -} - -object RenameSelector { - type Data = (Id, Id) - def unapply(arg: ImportSelector)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRenameSelector(arg) -} - -object OmitSelector { - type Data = Id - def unapply(arg: ImportSelector)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyOmitSelector(arg) -} diff --git a/library/src/scala/tasty/trees/PackageClause.scala b/library/src/scala/tasty/trees/PackageClause.scala deleted file mode 100644 index 6b5a15011d72..000000000000 --- a/library/src/scala/tasty/trees/PackageClause.scala +++ /dev/null @@ -1,11 +0,0 @@ -package scala.tasty -package trees - -trait PackageClause extends TopLevelStatement { - def definition(implicit ctx: Context): Definition -} - -object PackageClause { - type Data = (Term, List[TopLevelStatement]) - def unapply(arg: PackageClause)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyPackageClause(arg) -} diff --git a/library/src/scala/tasty/trees/PackageDef.scala b/library/src/scala/tasty/trees/PackageDef.scala deleted file mode 100644 index 36b4b2466b15..000000000000 --- a/library/src/scala/tasty/trees/PackageDef.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package trees - -trait PackageDef extends Definition - -object PackageDef { - type Data = (names.Name, List[Statement]) - def unapply(arg: PackageDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyPackageDef(arg) -} diff --git a/library/src/scala/tasty/trees/Pattern.scala b/library/src/scala/tasty/trees/Pattern.scala deleted file mode 100644 index eeba5b4c5ce2..000000000000 --- a/library/src/scala/tasty/trees/Pattern.scala +++ /dev/null @@ -1,33 +0,0 @@ -package scala.tasty -package trees - -import scala.tasty.types.Type - -trait Pattern extends Tree { - def tpe: Type -} - -object Value { - type Data = Term - def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyValue(arg) -} - -object Bind { - type Data = (names.TermName, Pattern) - def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyBind(arg) -} - -object Unapply { - type Data = (Term, List[Term], List[Pattern]) - def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyUnapply(arg) -} - -object Alternative { - type Data = List[Pattern] - def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAlternative(arg) -} - -object TypeTest { - type Data = TypeTree - def unapply(arg: Pattern)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeTest(arg) -} diff --git a/library/src/scala/tasty/trees/Statement.scala b/library/src/scala/tasty/trees/Statement.scala deleted file mode 100644 index 918e8226104c..000000000000 --- a/library/src/scala/tasty/trees/Statement.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.tasty.trees - -trait Statement extends TopLevelStatement diff --git a/library/src/scala/tasty/trees/Term.scala b/library/src/scala/tasty/trees/Term.scala deleted file mode 100644 index 75cc6347b059..000000000000 --- a/library/src/scala/tasty/trees/Term.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty.trees - -import scala.tasty.types.Type - -trait Term extends Statement { - def tpe: Type -} - - diff --git a/library/src/scala/tasty/trees/TopLevelStatement.scala b/library/src/scala/tasty/trees/TopLevelStatement.scala deleted file mode 100644 index 96ffdac8b3f8..000000000000 --- a/library/src/scala/tasty/trees/TopLevelStatement.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.tasty.trees - -trait TopLevelStatement extends Tree diff --git a/library/src/scala/tasty/trees/Tree.scala b/library/src/scala/tasty/trees/Tree.scala deleted file mode 100644 index 3aae962cc8da..000000000000 --- a/library/src/scala/tasty/trees/Tree.scala +++ /dev/null @@ -1,5 +0,0 @@ -package scala.tasty.trees - -import scala.tasty.Positioned - -trait Tree extends Positioned diff --git a/library/src/scala/tasty/trees/TypeBoundsTree.scala b/library/src/scala/tasty/trees/TypeBoundsTree.scala deleted file mode 100644 index ea4023049e8f..000000000000 --- a/library/src/scala/tasty/trees/TypeBoundsTree.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.tasty -package trees - -import scala.tasty.types.TypeBounds - -trait TypeBoundsTree extends Tree { - def tpe: TypeBounds -} - -object TypeBoundsTree { - type Data = (TypeTree, TypeTree) - def unapply(arg: TypeBoundsTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeBoundsTree(arg) -} diff --git a/library/src/scala/tasty/trees/TypeDef.scala b/library/src/scala/tasty/trees/TypeDef.scala deleted file mode 100644 index 6d05bcb0d21d..000000000000 --- a/library/src/scala/tasty/trees/TypeDef.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.tasty -package trees - -import scala.tasty.modifiers.Modifier - -trait TypeDef extends Definition { - def mods(implicit ctx: Context): List[Modifier] -} - -object TypeDef { - type Data = (names.TypeName, Tree /* Type | TypeBounds */) - def unapply(arg: TypeDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeDef(arg) -} diff --git a/library/src/scala/tasty/trees/TypeTree.scala b/library/src/scala/tasty/trees/TypeTree.scala deleted file mode 100644 index 623b989fc08c..000000000000 --- a/library/src/scala/tasty/trees/TypeTree.scala +++ /dev/null @@ -1,8 +0,0 @@ -package scala.tasty.trees - -import scala.tasty.types - -/** Trees denoting types */ -trait TypeTree extends Tree { - def tpe: types.Type -} diff --git a/library/src/scala/tasty/trees/ValDef.scala b/library/src/scala/tasty/trees/ValDef.scala deleted file mode 100644 index 6be0a4c416fa..000000000000 --- a/library/src/scala/tasty/trees/ValDef.scala +++ /dev/null @@ -1,13 +0,0 @@ -package scala.tasty -package trees - -import scala.tasty.modifiers.Modifier - -trait ValDef extends Definition { - def mods(implicit ctx: Context): List[Modifier] -} - -object ValDef { - type Data = (names.TermName, TypeTree, Option[Term]) - def unapply(arg: ValDef)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyValDef(arg) -} diff --git a/library/src/scala/tasty/trees/package.scala b/library/src/scala/tasty/trees/package.scala deleted file mode 100644 index df8220071956..000000000000 --- a/library/src/scala/tasty/trees/package.scala +++ /dev/null @@ -1,160 +0,0 @@ -package scala.tasty - -import scala.runtime.tasty.Toolbox - -package object trees { - - // Term trees - - object Ident { - type Data = (names.TermName) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyIdent(arg) - } - - object Select { - type Data = (Term, names.PossiblySignedName) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySelect(arg) - } - - object Literal { - type Data = constants.Constant - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyLiteral(arg) - } - - object This { - type Data = Option[Id] - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyThis(arg) - } - - object New { - type Data = TypeTree - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyNew(arg) - } - - object NamedArg { - type Data = (names.TermName, Term) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyNamedArg(arg) - } - - object Apply { - type Data = (Term, List[Term]) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyApply(arg) - } - - object TypeApply { - type Data = (Term, List[TypeTree]) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeApply(arg) - } - - object Super { - type Data = (Term, Option[Id]) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySuper(arg) - } - - object Typed { - type Data = (Term, TypeTree) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTyped(arg) - } - - object Assign { - type Data = (Term, Term) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAssign(arg) - } - - object Block { - type Data = (List[Statement], Term) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyBlock(arg) - } - - object Inlined { - type Data = (Term, List[Definition], Term) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyInlined(arg) - } - - object Lambda { - type Data = (Term, Option[TypeTree]) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyLambda(arg) - } - - object If { - type Data = (Term, Term, Term) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyIf(arg) - } - - object Match { - type Data = (Term, List[CaseDef]) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyMatch(arg) - } - - object Try { - type Data = (Term, List[CaseDef], Option[Term]) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTry(arg) - } - - object Return { - type Data = Term - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyReturn(arg) - } - - object Repeated { - type Data = List[Term] - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRepeated(arg) - } - - object SelectOuter { - type Data = (Term, Int, types.Type) - def unapply(arg: Term)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySelectOuter(arg) - } - - // Type trees - - object Synthetic { - def unapply(arg: TypeTree)(implicit ctx: Context): Boolean = ctx.toolbox.unapplySynthetic(arg) - } - - object TypeIdent { - type Data = names.TypeName - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeIdent(arg) - } - - object TypeSelect { - type Data = (Term, names.TypeName) - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeSelect(arg) - } - - object Singleton { - type Data = Term - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySingleton(arg) - } - - object Refined { - type Data = (TypeTree, List[Definition]) - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRefined(arg) - } - - object Applied { - type Data = (TypeTree, List[TypeTree]) - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyApplied(arg) - } - - object Annotated { - type Data = (TypeTree, Term) - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAnnotated(arg) - } - - object And { - type Data = (TypeTree, TypeTree) - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAnd(arg) - } - - object Or { - type Data = (TypeTree, TypeTree) - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyOr(arg) - } - - object ByName { - type Data = TypeTree - def unapply(arg: TypeTree)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyByName(arg) - } - -} diff --git a/library/src/scala/tasty/types/LambdaType.scala b/library/src/scala/tasty/types/LambdaType.scala deleted file mode 100644 index f4f2b61ef938..000000000000 --- a/library/src/scala/tasty/types/LambdaType.scala +++ /dev/null @@ -1,25 +0,0 @@ -package scala.tasty -package types - -trait LambdaType[ParamName <: names.Name, ParamInfo <: MaybeType] extends Type - -trait MethodType extends LambdaType[names.TermName, Type] { - def isImplicit: Boolean - def isErased: Boolean -} -object MethodType { - type Data = (List[names.TermName], List[Type], Type) - def unapply(arg: MethodType)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyMethodType(arg) -} - -trait PolyType extends LambdaType[names.TypeName, TypeBounds] -object PolyType { - type Data = (List[names.TypeName], List[TypeBounds], Type) - def unapply(arg: PolyType)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyPolyType(arg) -} - -trait TypeLambda extends LambdaType[names.TypeName, TypeBounds] -object TypeLambda { - type Data = (List[names.TypeName], List[TypeBounds], Type) - def unapply(arg: TypeLambda)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeLambda(arg) -} diff --git a/library/src/scala/tasty/types/MaybeType.scala b/library/src/scala/tasty/types/MaybeType.scala deleted file mode 100644 index 992c66fec277..000000000000 --- a/library/src/scala/tasty/types/MaybeType.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.tasty.types - -trait MaybeType diff --git a/library/src/scala/tasty/types/NoPrefix.scala b/library/src/scala/tasty/types/NoPrefix.scala deleted file mode 100644 index 3b1b56dc7514..000000000000 --- a/library/src/scala/tasty/types/NoPrefix.scala +++ /dev/null @@ -1,5 +0,0 @@ -package scala.tasty.types - -sealed trait NoPrefix extends MaybeType - -case object NoPrefix extends NoPrefix diff --git a/library/src/scala/tasty/types/RecursiveType.scala b/library/src/scala/tasty/types/RecursiveType.scala deleted file mode 100644 index 085f8bf9ec58..000000000000 --- a/library/src/scala/tasty/types/RecursiveType.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package types - -trait RecursiveType extends Type - -object RecursiveType { - type Data = Type - def unapply(arg: RecursiveType)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRecursiveType(arg) -} diff --git a/library/src/scala/tasty/types/Type.scala b/library/src/scala/tasty/types/Type.scala deleted file mode 100644 index 4d9d2f1f6e1e..000000000000 --- a/library/src/scala/tasty/types/Type.scala +++ /dev/null @@ -1,3 +0,0 @@ -package scala.tasty.types - -trait Type extends MaybeType diff --git a/library/src/scala/tasty/types/TypeBounds.scala b/library/src/scala/tasty/types/TypeBounds.scala deleted file mode 100644 index 0e1f69abdc0a..000000000000 --- a/library/src/scala/tasty/types/TypeBounds.scala +++ /dev/null @@ -1,9 +0,0 @@ -package scala.tasty -package types - -trait TypeBounds extends MaybeType - -object TypeBounds { - type Data = (Type, Type) - def unapply(arg: TypeBounds)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyTypeBounds(arg) -} diff --git a/library/src/scala/tasty/types/package.scala b/library/src/scala/tasty/types/package.scala deleted file mode 100644 index 811f08b998d9..000000000000 --- a/library/src/scala/tasty/types/package.scala +++ /dev/null @@ -1,72 +0,0 @@ -package scala.tasty - -import scala.tasty.trees.Term - -package object types { - - object ConstantType { - type Data = constants.Constant - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyConstantType(arg) - } - - object SymRef { - type Data = (trees.Definition, MaybeType /* Type | NoPrefix */) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySymRef(arg) - } - - object NameRef { - type Data = (names.Name, MaybeType /* Type | NoPrefix */) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyNameRef(arg) - } - - object SuperType { - type Data = (Type, Type) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplySuperType(arg) - } - - object Refinement { - type Data = (Type, names.Name, MaybeType /* Type | TypeBounds */) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRefinement(arg) - } - - object AppliedType { - type Data = (Type, List[types.MaybeType /* Type | TypeBounds */]) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAppliedType(arg) - } - - object AnnotatedType { - type Data = (Type, Term) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAnnotatedType(arg) - } - - object AndType { - type Data = (Type, Type) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyAndType(arg) - } - - object OrType { - type Data = (Type, Type) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyOrType(arg) - } - - object ByNameType { - type Data = Type - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyByNameType(arg) - } - - object ParamRef { - type Data = (LambdaType[_, _], Int) - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyParamRef(arg) - } - - object ThisType { - type Data = Type - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyThisType(arg) - } - - object RecursiveThis { - type Data = RecursiveType - def unapply(arg: Type)(implicit ctx: Context): Option[Data] = ctx.toolbox.unapplyRecursiveThis(arg) - } - -} diff --git a/library/src/scala/tasty/util/ConstantExtractor.scala b/library/src/scala/tasty/util/ConstantExtractor.scala new file mode 100644 index 000000000000..13e7adeecaf7 --- /dev/null +++ b/library/src/scala/tasty/util/ConstantExtractor.scala @@ -0,0 +1,30 @@ +package scala.tasty.util + +import scala.quoted.Expr +import scala.tasty.Tasty + +/** + * Usage: + * + * ``` + * val Constant = new ConstantExtractor(tasty) + * + * (x: Expr[B]) match { + * case Constant(value) => ... + * case x => ... + * } + * ``` + */ +class ConstantExtractor[T <: Tasty with Singleton](val tasty: T) { + import tasty._ + + def unapply[T](expr: Expr[T])(implicit ctx: Context): Option[T] = { + def const(tree: Term): Option[T] = tree match { + case Literal(c) => Some(c.value.asInstanceOf[T]) + case Block(Nil, e) => const(e) + case Inlined(_, Nil, e) => const(e) + case _ => None + } + const(expr.toTasty) + } +} diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index 57b6c103749c..33a8639af3ae 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -1,533 +1,660 @@ -package scala.tasty -package util +package scala.tasty.util -import scala.tasty.constants._ -import scala.tasty.names._ -import scala.tasty.modifiers._ -import scala.tasty.trees._ -import scala.tasty.types._ +import scala.tasty.Tasty object TastyPrinter { - def stringOf(tree: Tree)(implicit ctx: Context): String = { + def stringOfTree(tasty: Tasty)(tree: tasty.TopLevelStatement)(implicit ctx: tasty.Context): String = { implicit val buff: StringBuilder = new StringBuilder - visit(tree) + visitTree(tasty)(tree) buff.toString() } - def stringOf(tpe: MaybeType)(implicit ctx: Context): String = { + def stringOfTypeTree(tasty: Tasty)(tree: tasty.MaybeTypeTree)(implicit ctx: tasty.Context): String = { implicit val buff: StringBuilder = new StringBuilder - visit(tpe) + visitTypeTree(tasty)(tree) buff.toString() } - def stringOf(name: Name)(implicit ctx: Context): String = { + def stringOfType(tasty: Tasty)(tpe: tasty.MaybeType)(implicit ctx: tasty.Context): String = { implicit val buff: StringBuilder = new StringBuilder - visit(name) + visitType(tasty)(tpe) buff.toString() } - def stringOf(name: PossiblySignedName)(implicit ctx: Context): String = { + def stringOfModifier(tasty: Tasty)(mod: tasty.Modifier)(implicit ctx: tasty.Context): String = { implicit val buff: StringBuilder = new StringBuilder - visit(name) + visitModifier(tasty)(mod) buff.toString() } - def stringOf(mod: Modifier)(implicit ctx: Context): String = { + def stringOfConstant(tasty: Tasty)(mod: tasty.Constant)(implicit ctx: tasty.Context): String = { implicit val buff: StringBuilder = new StringBuilder - visit(mod) + visitConstant(tasty)(mod) buff.toString() } - def stringOf(mod: Constant)(implicit ctx: Context): String = { - implicit val buff: StringBuilder = new StringBuilder - visit(mod) - buff.toString() + private def visitTree(tasty: Tasty)(x: tasty.TopLevelStatement)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case Ident(name) => + buff append "Ident(" append name append ")" + case Select(qualifier, name, signature) => + buff append "Select(" + visitTree(tasty)(qualifier) + buff append ", " append name append ", " + signature match { + case Some(sig) => + val Signature(params, res) = sig + buff append "Some(Signature(" + if (params.isEmpty) buff append "Nil" + else buff append params + buff append ", " append res append "))" + case None => buff append "None" + } + buff append ")" + case This(qual) => + buff append "This(" + qual match { + case Some(id) => + buff append "Some(" + visitId(tasty)(id) + buff append ")" + case None => buff append "None" + } + buff append ")" + case Super(qual, mix) => + buff append "TypeApply(" + visitTree(tasty)(qual) + buff append ", " + mix match { + case Some(id) => + buff append "Some(" + visitId(tasty)(id) + buff append ")" + case None => buff append "None" + } + buff append ")" + case Apply(fun, args) => + buff append "Apply(" + visitTree(tasty)(fun) + buff append ", " + visitTrees(tasty)(args) + buff append ")" + case TypeApply(fun, args) => + buff append "TypeApply(" + visitTree(tasty)(fun) + buff append ", " + visitTypeTrees(tasty)(args) + buff append ")" + case Literal(const) => + buff append "Literal(" + visitConstant(tasty)(const) + buff append ")" + case New(tpt) => + buff append "New(" + visitTypeTree(tasty)(tpt) + buff append ")" + case Typed(expr, tpt) => + buff append "Typed(" + visitTree(tasty)(expr) + buff append ", " + visitTypeTree(tasty)(tpt) + buff append ")" + case NamedArg(name, arg) => + buff append "NamedArg(" append name append ", " + visitTree(tasty)(arg) + buff append ")" + case Assign(lhs, rhs) => + buff append "Assign(" + visitTree(tasty)(lhs) + buff append ", " + visitTree(tasty)(rhs) + buff append ")" + case Block(stats, expr) => + buff append "Block(" + visitTrees(tasty)(stats) + buff append ", " + visitTree(tasty)(expr) + buff append ")" + case If(cond, thenp, elsep) => + buff append "If(" + visitTree(tasty)(cond) + buff append ", " + visitTree(tasty)(thenp) + buff append ", " + visitTree(tasty)(elsep) + buff append ")" + case Lambda(meth, tpt) => + buff append "Lambda(" + visitTree(tasty)(meth) + buff append ", " + tpt match { + case Some(tree) => + buff append "Some(" + visitTypeTree(tasty)(tree) + buff append ")" + case _ => buff append "None" + } + buff append ")" + case Match(selector, cases) => + buff append "Match(" + visitTree(tasty)(selector) + buff append ", " + visitCaseDefs(tasty)(cases) + buff append ")" + case Return(expr) => + buff append "Return(" + visitTree(tasty)(expr) + buff append ")" + case Try(block, handlers, finalizer) => + buff append "Try(" + visitTree(tasty)(block) + buff append ", " + visitCaseDefs(tasty)(handlers) + buff append ", " + finalizer match { + case Some(tree) => + buff append "Some(" + visitTree(tasty)(tree) + buff append ")" + case _ => buff append "None" + } + buff append ")" + case Repeated(elems) => + buff append "Repeated(" + visitTrees(tasty)(elems) + buff append ")" + case Inlined(call, bindings, expansion) => + buff append "Inlined(" + visitTree(tasty)(call) + buff append ", " + visitTrees(tasty)(bindings) + buff append ", " + visitTree(tasty)(expansion) + buff append ")" + case ValDef(name, tpt, rhs) => + buff append "ValDef(" append name append ", " + visitTypeTree(tasty)(tpt) + buff append ", " + rhs match { + case Some(tree) => + buff append "Some(" + visitTree(tasty)(tree) + buff append ")" + case _ => buff append "None" + } + buff append ")" + case DefDef(name, typeParams, paramss, returnTpt, rhs) => + buff append "DefDef(" append name append ", " + visitTrees(tasty)(typeParams) + buff append ", " + paramss match { + case x0 :: xs => + buff append "List(" + visitTrees(tasty)(x0) + def visitNext(xs: List[List[tasty.ValDef]]): Unit = xs match { + case y :: ys => + buff append ", " + visitTrees(tasty)(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + } + buff append ", " + visitTypeTree(tasty)(returnTpt) + buff append ", " + rhs match { + case Some(tree) => + buff append "Some(" + visitTree(tasty)(tree) + buff append ")" + case None => buff append "None" + } + buff append ")" + case TypeDef(name, rhs) => + buff append "TypeDef(" append name append ", " + visitTypeTree(tasty)(rhs) + buff append ")" + case ClassDef(name, constr, parents, self, body) => + buff append "ClassDef(" append name append ", " + visitTree(tasty)(constr) + buff append ", " + visitParents(tasty)(parents) + buff append ", " + self match { + case Some(tree) => + buff append "Some(" + visitTree(tasty)(tree) + buff append ")" + case _ => buff append "None" + } + buff append ", " + visitTrees(tasty)(body) + buff append ")" + case PackageDef(name, members) => + buff append "PackageDef(" + buff append name + buff append ", " + visitTrees(tasty)(members) + buff append ")" + case Import(expr, selectors) => + buff append "Import(" + visitTree(tasty)(expr) + buff append ", " + + buff append "List(" + selectors.foreach { + case SimpleSelector(id) => + buff append "SimpleSelector(" + visitId(tasty)(id) + buff append ")" + case RenameSelector(id1, id2) => + buff append "RenameSelector(" + visitId(tasty)(id1) + buff append ", " + visitId(tasty)(id2) + buff append ")" + case OmitSelector(id) => + buff append "OmitSelector(" + visitId(tasty)(id) + buff append ")" + } + buff append ")" + buff append ")" + case PackageClause(pid, stats) => + buff append "PackageClause(" + visitTree(tasty)(pid) + buff append ", " + visitTrees(tasty)(stats) + buff append ")" + } + } + + private def visitTrees(tasty: Tasty)(list: List[tasty.TopLevelStatement])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + list match { + case x0 :: xs => + buff append "List(" + visitTree(tasty)(x0) + def visitNext(xs: List[tasty.TopLevelStatement]): Unit = xs match { + case y :: ys => + buff append ", " + visitTree(tasty)(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + } } - private def visit(tree: Tree)(implicit buff: StringBuilder, ctx: Context): Unit = tree match { - case Ident(name) => - buff append "Ident(" - visit(name: Name) - buff append ")" - case Select(qualifier, name) => - buff append "Select(" - visit(qualifier) - buff append ", " - visit(name) - buff append ")" - case This(qual) => - buff append "This(" append qual append ")" - case Super(qual, mix) => - buff append "TypeApply(" - visit(qual) - buff append ", " - buff append mix - buff append ")" - case Apply(fun, args) => - buff append "Apply(" - visit(fun) - buff append ", " - visitAny(args) - buff append ")" - case TypeApply(fun, args) => - buff append "TypeApply(" - visit(fun) - buff append ", " - visitAny(args) - buff append ")" - case Literal(const) => - buff append "Literal(" - visit(const) - buff append ")" - case New(tpt) => - buff append "New(" - visit(tpt) - buff append ")" - case Typed(expr, tpt) => - buff append "Typed(" - visit(expr) - buff append ", " - visit(tpt) - buff append ")" - case NamedArg(name, arg) => - buff append "NamedArg(" - visit(name: Name) - buff append ", " - visit(arg) - buff append ")" - case Assign(lhs, rhs) => - buff append "Assign(" - visit(lhs) - buff append ", " - visit(rhs) - buff append ")" - case Block(stats, expr) => - buff append "Block(" - visitAny(stats) - buff append ", " - visit(expr) - buff append ")" - case If(cond, thenp, elsep) => - buff append "If(" - visit(cond) - buff append ", " - visit(thenp) - buff append ", " - visit(elsep) - buff append ")" - case Lambda(meth, tpt) => - buff append "Lambda(" - visit(meth) - buff append ", " - visitAny(tpt) - buff append ")" - case Match(selector, cases) => - buff append "Match(" - visit(selector) - buff append ", " - visitAny(cases) - buff append ")" - case CaseDef(pat, guard, body) => - buff append "CaseDef(" - visit(pat) - buff append ", " - visitAny(guard) - buff append ", " - visit(body) - buff append ")" - case Return(expr) => - buff append "Return(" - visit(expr) - buff append ")" - case Try(block, handlers, finalizer) => - buff append "Try(" - visit(block) - buff append ", " - visitAny(handlers) - buff append ", " - visitAny(finalizer) - buff append ")" - case Repeated(elems) => - buff append "Repeated(" - visitAny(elems) - buff append ")" - case Inlined(call, bindings, expansion) => - buff append "Inlined(" - visit(call) - buff append ", " - visitAny(bindings) - buff append ", " - visit(expansion) - buff append ")" - case Synthetic() => - buff append "Synthetic()" - case TypeIdent(name) => - buff append "Ident(" // FIXME print as TypeIdent - visit(name) - buff append ")" - case TypeSelect(qualifier, name) => - buff append "TypeSelect(" - visit(qualifier) - buff append ", " - visit(name) - buff append ")" - case Singleton(ref) => - buff append "Singleton(" - visit(ref) - buff append ")" - case And(left, right) => - buff append "And(" - visit(left) - buff append ", " - visit(right) - buff append ")" - case Or(left, right) => - buff append "Or(" - visit(left) - buff append ", " - visit(right) - buff append ")" - case Refined(tpt, refinements) => - buff append "Refined(" - visit(tpt) - buff append ", " - visitAny(refinements) - buff append ")" - case Applied(tpt, args) => - buff append "Applied(" - visit(tpt) - buff append ", " - visitAny(args) - buff append ")" - case ByName(result) => - buff append "ByName(" - visit(result) - buff append ")" - case TypeBoundsTree(lo, hi) => - buff append "TypeBoundsTree(" - visit(lo) - buff append ", " - visit(hi) - buff append ")" - case Annotated(arg, annot) => - buff append "Annotated(" - visit(arg) - buff append ", " - visit(annot) - buff append ")" - case Value(v) => - buff append "Value(" - visit(v) - buff append ")" - case Bind(name, body) => - buff append "Bind(" - visit(name: Name) - buff append ", " - visit(body) - buff append ")" - case Unapply(fun, implicits, patterns) => - buff append "Unapply(" - visit(fun) - buff append ", " - visitAny(implicits) - buff append ", " - visitAny(patterns) - buff append ")" - case Alternative(patterns) => - buff append "Alternative(" - visitAny(patterns) - buff append ")" - case TypeTest(tpt) => - buff append "TypeTest(" - visit(tpt) - buff append ")" - case ValDef(name, tpt, rhs) => - buff append "ValDef(" - visit(name: Name) - buff append ", " - visit(tpt) - buff append ", " - visitAny(rhs) - buff append ")" - case DefDef(name, typeParams, paramss, returnTpt, rhs) => - buff append "DefDef(" - visit(name: Name) - buff append ", " - visitAny(typeParams) - buff append ", " - visitAny(paramss) - buff append ", " - visit(returnTpt) - buff append ", " - visitAny(rhs) - buff append ")" - case TypeDef(name, rhs) => - buff append "TypeDef(" - visit(name: Name) - buff append ", " - visit(rhs) - buff append ")" - case ClassDef(name, constr, parents, self, body) => - buff append "ClassDef(" - visit(name: Name) - buff append ", " - visit(constr) - buff append ", " - visitAny(parents) - buff append ", " - visitAny(self) - buff append ", " - visitAny(body) - buff append ")" - case PackageDef(name, members) => - buff append "PackageDef(" - visit(name: Name) - buff append ", " - visitAny(members) - buff append ")" - case Import(expr, selectors) => - buff append "Import(" - visit(expr) - buff append ", " - visitAny(selectors) - buff append ")" - case PackageClause(pid, stats) => - buff append "PackageClause(" - visit(pid) - buff append ", " - visitAny(stats) - buff append ")" + private def visitTypeTree(tasty: Tasty)(x: tasty.MaybeTypeTree)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case Synthetic() => + buff append "Synthetic()" + case TypeIdent(name) => + buff append "TypeIdent(" append name append ")" + case TypeSelect(qualifier, name) => + buff append "TypeSelect(" + visitTree(tasty)(qualifier) + buff append ", " append name append ")" + case Singleton(ref) => + buff append "Singleton(" + visitTree(tasty)(ref) + buff append ")" + case And(left, right) => + buff append "And(" + visitTypeTree(tasty)(left) + buff append ", " + visitTypeTree(tasty)(right) + buff append ")" + case Or(left, right) => + buff append "Or(" + visitTypeTree(tasty)(left) + buff append ", " + visitTypeTree(tasty)(right) + buff append ")" + case Refined(tpt, refinements) => + buff append "Refined(" + visitTypeTree(tasty)(tpt) + buff append ", " + visitTrees(tasty)(refinements) + buff append ")" + case Applied(tpt, args) => + buff append "Applied(" + visitTypeTree(tasty)(tpt) + buff append ", " + visitTypeTrees(tasty)(args) + buff append ")" + case ByName(result) => + buff append "ByName(" + visitTypeTree(tasty)(result) + buff append ")" + case Annotated(arg, annot) => + buff append "Annotated(" + visitTypeTree(tasty)(arg) + buff append ", " + visitTree(tasty)(annot) + buff append ")" + case TypeBoundsTree(lo, hi) => + buff append "TypeBoundsTree(" + visitTypeTree(tasty)(lo) + buff append ", " + visitTypeTree(tasty)(hi) + buff append ")" + } } - private def visitAny(x: Any)(implicit buff: StringBuilder, ctx: Context): Unit = x match { - case x: Tree => visit(x) - case x: MaybeType => visit(x) - case x: Name => visit(x) - case x: PossiblySignedName => visit(x) - case x: Constant => visit(x) - case x: Modifier => visit(x) - case x: ImportSelector => visit(x) - case x0 :: xs => - buff append "List(" - visitAny(x0) - def visitNext(xs: List[_]): Unit = xs match { - case y :: ys => - buff append ", " - visitAny(y) - visitNext(ys) - case Nil => - } - visitNext(xs) - buff append ")" - case Nil => buff append "Nil" - case Some(y) => - buff append "Some(" - visitAny(y) - buff append ")" - case None => buff append "None" + private def visitTypeTrees(tasty: Tasty)(list: List[tasty.TypeTree])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + list match { + case x0 :: xs => + buff append "List(" + visitTypeTree(tasty)(x0) + def visitNext(xs: List[tasty.TypeTree]): Unit = xs match { + case y :: ys => + buff append ", " + visitTypeTree(tasty)(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + } } - private def visit(const: Constant)(implicit buff: StringBuilder, ctx: Context): Unit = const match { - case constants.Unit() => buff append "Unit()" - case constants.Null() => buff append "Null()" - case constants.Boolean(value) => buff append "Boolean(" append value append ")" - case constants.Byte(value) => buff append "Byte(" append value append ")" - case constants.Short(value) => buff append "Short(" append value append ")" - case constants.Char(value) => buff append "Char('" append value append "')" - case constants.Int(value) => buff append "Int(" append value append ")" - case constants.Long(value) => buff append "Long(" append value append ")" - case constants.Float(value) => buff append "Float(" append value append ")" - case constants.Double(value) => buff append "Double(" append value append ")" - case constants.String(value) => buff append "String(\"" append value append "\")" // TODO escape string characters? + private def visitCaseDef(tasty: Tasty)(x: tasty.CaseDef)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case CaseDef(pat, guard, body) => + buff append "CaseDef(" + visitPattern(tasty)(pat) + buff append ", " + guard match { + case Some(tree) => + buff append "Some(" + visitTree(tasty)(guard.get) + buff append ")" + case None => + buff append "None" + } + buff append ", " + visitTree(tasty)(body) + buff append ")" + } } - private def visit(name: PossiblySignedName)(implicit buff: StringBuilder, ctx: Context): Unit = name match { - case SignedName(underlying, resSig, paramsSigs) => - buff append "SignedName(" - visit(underlying: Name) - buff append ", " - visit(resSig) - buff append ", " - visitAny(paramsSigs) - buff append ")" - case name: TermName => visit(name: Name) + private def visitCaseDefs(tasty: Tasty)(list: List[tasty.CaseDef])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + list match { + case x0 :: xs => + buff append "List(" + visitCaseDef(tasty)(x0) + def visitNext(xs: List[tasty.CaseDef]): Unit = xs match { + case y :: ys => + buff append ", " + visitCaseDef(tasty)(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + } } - private def visit(name: Name)(implicit buff: StringBuilder, ctx: Context): Unit = name match { - case TypeName(underlying) => - buff append "TypeName(" - visit(underlying: Name) - buff append ")" - case Simple(strName) => - buff append "Simple(" append strName append ")" - case Qualified(qual, strName) => - buff append "Qualified(" - visit(qual: Name) - buff append "," - buff append strName - buff append ")" - case DefaultGetter(underlying, strName) => - buff append "DefaultGetter(" - visit(underlying: Name) - buff append "," - buff append strName - buff append ")" - case Variant(underlying, variance) => - buff append "Variant(" - visit(underlying: Name) - buff append "," - buff append variance - buff append ")" - case SuperAccessor(underlying) => - buff append "SuperAccessor(" - visit(underlying: Name) - buff append ")" - case ProtectedAccessor(underlying) => - buff append "ProtectedAccessor(" - visit(underlying: Name) - buff append ")" - case ProtectedSetter(underlying) => - buff append "ProtectedSetter(" - visit(underlying: Name) - buff append ")" - case ObjectClass(underlying) => - buff append "ObjectClass(" - visit(underlying: Name) - buff append ")" + private def visitPattern(tasty: Tasty)(x: tasty.Pattern)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case Value(v) => + buff append "Value(" + visitTree(tasty)(v) + buff append ")" + case Bind(name, body) => + buff append "Bind(" append name append ", " + visitPattern(tasty)(body) + buff append ")" + case Unapply(fun, implicits, patterns) => + buff append "Unapply(" + visitTree(tasty)(fun) + buff append ", " + visitTrees(tasty)(implicits) + buff append ", " + visitPatterns(tasty)(patterns) + buff append ")" + case Alternative(patterns) => + buff append "Alternative(" + visitPatterns(tasty)(patterns) + buff append ")" + case TypeTest(tpt) => + buff append "TypeTest(" + visitTypeTree(tasty)(tpt) + buff append ")" + } } - private def visit(selector: ImportSelector)(implicit buff: StringBuilder, ctx: Context): Unit = selector match { - case SimpleSelector(id) => buff append "SimpleSelector(" append id append ")" - case OmitSelector(id) => buff append "OmitSelector(" append id append ")" - case RenameSelector(id1, id2) => - buff append "RenameSelector(" append id1 append ", " append id2 append ")" + private def visitPatterns(tasty: Tasty)(list: List[tasty.Pattern])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + list match { + case x0 :: xs => + buff append "List(" + visitPattern(tasty)(x0) + def visitNext(xs: List[tasty.Pattern]): Unit = xs match { + case y :: ys => + buff append ", " + visitPattern(tasty)(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + } } - private def visit(tpe: MaybeType)(implicit buff: StringBuilder, ctx: Context): Unit = { - def visitName(sym: Definition): Unit = sym match { - case ValDef(name, _, _) => visit(name: Name) - case DefDef(name, _, _, _, _) => visit(name: Name) - case TypeDef(name, _) => visit(name: Name) - case ClassDef(name, _, _, _, _) => visit(name: Name) - case PackageDef(name, _) => visit(name: Name) - case _ => buff append "NoDefinition" + private def visitConstant(tasty: Tasty)(x: tasty.Constant)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case UnitConstant() => buff append "Unit()" + case NullConstant() => buff append "Null()" + case BooleanConstant(value) => buff append "Boolean(" append value append ")" + case ByteConstant(value) => buff append "Byte(" append value append ")" + case ShortConstant(value) => buff append "Short(" append value append ")" + case CharConstant(value) => buff append "Char(" append value append ")" + case IntConstant(value) => buff append "Int(" append value append ")" + case LongConstant(value) => buff append "Long(" append value append ")" + case FloatConstant(value) => buff append "Float(" append value append ")" + case DoubleConstant(value) => buff append "Double(" append value append ")" + case StringConstant(value) => buff append "String(" append value append ")" } + } - tpe match { - case types.ConstantType(value) => + private def visitType(tasty: Tasty)(x: tasty.MaybeType)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case ConstantType(value) => buff append "ConstantType(" - visit(value) + visitConstant(tasty)(value) buff append ")" - case types.SymRef(sym, qual) => - buff append "SymRef(<" + case SymRef(sym, qual) => + def visitName(sym: Definition): Unit = sym match { + case ValDef(name, _, _) => buff append name + case DefDef(name, _, _, _, _) => buff append name + case TypeDef(name, _) => buff append name + case ClassDef(name, _, _, _, _) => buff append name + case PackageDef(name, _) => buff append name + case _ => buff append "#" + } + buff append "SymRef(" visitName(sym) - buff append ">, " - visit(qual) - buff append ")" - case types.NameRef(name, qual) => - buff append "NameRef(" - visit(name) buff append ", " - visit(qual) + visitType(tasty)(qual) buff append ")" - case types.Refinement(parent, name, info) => + case NameRef(name, qual) => + buff append "NameRef(" append name append ", " + visitType(tasty)(qual) + buff append ")" + case Refinement(parent, name, info) => buff append "Refinement(" - visit(parent) - buff append ", " - visit(name) - buff append ", " - visit(info) + visitType(tasty)(parent) + buff append ", " append name append ", " + visitType(tasty)(info) buff append ")" - case types.AppliedType(tycon, args) => + case AppliedType(tycon, args) => buff append "AppliedType(" - visit(tycon) + visitType(tasty)(tycon) buff append ", " - visitAny(args) + visitTypes(tasty)(args) buff append ")" - case types.AnnotatedType(underlying, annot) => + case AnnotatedType(underlying, annot) => buff append "AnnotatedType(" - visit(underlying) + visitType(tasty)(underlying) buff append ", " - visit(annot) + visitTree(tasty)(annot) buff append ")" - case types.AndType(left, right) => + case AndType(left, right) => buff append "AndType(" - visit(left) + visitType(tasty)(left) buff append ", " - visit(right) + visitType(tasty)(right) buff append ")" - case types.OrType(left, right) => + case OrType(left, right) => buff append "OrType(" - visit(left) + visitType(tasty)(left) buff append ", " - visit(right) + visitType(tasty)(right) buff append ")" - case types.ByNameType(underlying) => + case ByNameType(underlying) => buff append "ByNameType(" - visit(underlying) + visitType(tasty)(underlying) buff append ")" - case types.ParamRef(binder, idx) => + case ParamRef(binder, idx) => buff append "ParamRef(" - visit(binder) + visitType(tasty)(binder) buff append ", " append idx append ")" - case types.ThisType(tp) => + case ThisType(tp) => buff append "ThisType(" - visit(tp) + visitType(tasty)(tp) buff append ")" - case types.RecursiveThis(binder) => + case RecursiveThis(binder) => buff append "RecursiveThis(" - visit(binder) + visitType(tasty)(binder) buff append ")" - case types.MethodType(argNames, argTypes, resType) => + case MethodType(argNames, argTypes, resType) => buff append "MethodType(" - visitAny(argNames) + if (argNames.isEmpty) buff append "Nil" + else buff append argNames buff append ", " - visitAny(argTypes) + visitTypes(tasty)(argTypes) buff append ", " - visitAny(resType) + visitType(tasty)(resType) buff append ")" - case types.PolyType(argNames, argBounds, resType) => + case PolyType(argNames, argBounds, resType) => buff append "PolyType(" - visitAny(argNames) + if (argNames.isEmpty) buff append "Nil" + else buff append argNames buff append ", " - visitAny(argBounds) + visitTypes(tasty)(argBounds) buff append ", " - visitAny(resType) + visitType(tasty)(resType) buff append ")" - case types.TypeLambda(argNames, argBounds, resType) => + case TypeLambda(argNames, argBounds, resType) => buff append "TypeLambda(" - visitAny(argNames) + if (argNames.isEmpty) buff append "Nil" + else buff append argNames buff append ", " - visitAny(argBounds) + visitTypes(tasty)(argBounds) buff append ", " - visitAny(resType) + visitType(tasty)(resType) buff append ")" case TypeBounds(lo, hi) => buff append "TypeBounds(" - visit(lo) + visitType(tasty)(lo) buff append ", " - visit(hi) + visitType(tasty)(hi) buff append ")" - case tp: NoPrefix => + case NoPrefix() => buff append "NoPrefix" } } - private def visit(mod: Modifier)(implicit buff: StringBuilder, ctx: Context): Unit = mod match { - case Flags(flags) => - buff append "Flags(" append flags append ")" - case QualifiedPrivate(tp) => - buff append "QualifiedPrivate(" - visit(tp) - buff append ")" - case QualifiedProtected(tp) => - buff append "QualifiedProtected(" - visit(tp) - buff append ")" - case Annotation(tree) => - buff append "Annotation(" - visit(tree) - buff append ")" + private def visitTypes(tasty: Tasty)(list: List[tasty.MaybeType])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + list match { + case x0 :: xs => + buff append "List(" + visitType(tasty)(x0) + def visitNext(xs: List[tasty.MaybeType]): Unit = xs match { + case y :: ys => + buff append ", " + visitType(tasty)(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + } + } + + private def visitModifier(tasty: Tasty)(x: tasty.Modifier)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case Flags(flags) => + buff append "Flags(" append flags append ")" + case QualifiedPrivate(tp) => + buff append "QualifiedPrivate(" + visitType(tasty)(tp) + buff append ")" + case QualifiedProtected(tp) => + buff append "QualifiedProtected(" + visitType(tasty)(tp) + buff append ")" + case Annotation(tree) => + buff append "Annotation(" + visitTree(tasty)(tree) + buff append ")" + } + } + + private def visitParent(tasty: Tasty)(x: tasty.Parent)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case TermParent(term) => + buff append "TermParent(" + visitTree(tasty)(term) + buff append ")" + case TypeParent(typeTree) => + buff append "TypeParent(" + visitTypeTree(tasty)(typeTree) + buff append ")" + } + } + + private def visitParents(tasty: Tasty)(list: List[tasty.Parent])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + list match { + case x0 :: xs => + buff append "List(" + visitParent(tasty)(x0) + def visitNext(xs: List[tasty.Parent]): Unit = xs match { + case y :: ys => + buff append ", " + visitParent(tasty)(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + } + } + + private def visitId(tasty: Tasty)(x: tasty.Id)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + import tasty._ + x match { + case Id(name) => buff append "Id(" append name append ")" + } } } diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index c510860a4e96..9ffbc75ed9bb 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -1,108 +1,114 @@ package scala.tasty.util -import scala.tasty.trees._ -import scala.tasty.Context +import scala.tasty.Tasty -abstract class TreeAccumulator[X] { +abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { + import tasty._ // Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node. - def apply(x: X, tree: Tree)(implicit ctx: Context): X + def foldTree(x: X, tree: TopLevelStatement)(implicit ctx: Context): X + def foldTypeTree(x: X, tree: MaybeTypeTree)(implicit ctx: Context): X + def foldCaseDef(x: X, tree: CaseDef)(implicit ctx: Context): X + def foldPattern(x: X, tree: Pattern)(implicit ctx: Context): X + def foldParent(x: X, tree: Parent)(implicit ctx: Context): X - def apply(x: X, trees: Traversable[Tree])(implicit ctx: Context): X = (x /: trees)(apply) + def foldTree(x: X, trees: Traversable[TopLevelStatement])(implicit ctx: Context): X = (x /: trees)(foldTree) + def foldTypeTree(x: X, trees: Traversable[MaybeTypeTree])(implicit ctx: Context): X = (x /: trees)(foldTypeTree) + def foldCaseDef(x: X, trees: Traversable[CaseDef])(implicit ctx: Context): X = (x /: trees)(foldCaseDef) + def foldPattern(x: X, trees: Traversable[Pattern])(implicit ctx: Context): X = (x /: trees)(foldPattern) + def foldParent(x: X, trees: Traversable[Parent])(implicit ctx: Context): X = (x /: trees)(foldParent) - def foldOver(x: X, tree: Tree)(implicit ctx: Context): X = { + def foldOverTree(x: X, tree: TopLevelStatement)(implicit ctx: Context): X = { def localCtx(definition: Definition): Context = definition.localContext tree match { - case Ident(name) => + case Ident(_) => x - case Select(qualifier, name) => - this(x, qualifier) + case Select(qualifier, _, _) => + foldTree(x, qualifier) case This(qual) => x - case Super(qual, mix) => - this(x, qual) + case Super(qual, _) => + foldTree(x, qual) case Apply(fun, args) => - this(this(x, fun), args) + foldTree(foldTree(x, fun), args) case TypeApply(fun, args) => - this(this(x, fun), args) + foldTypeTree(foldTree(x, fun), args) case Literal(const) => x case New(tpt) => - this(x, tpt) + foldTypeTree(x, tpt) case Typed(expr, tpt) => - this(this(x, expr), tpt) - case NamedArg(name, arg) => - this(x, arg) + foldTypeTree(foldTree(x, expr), tpt) + case NamedArg(_, arg) => + foldTree(x, arg) case Assign(lhs, rhs) => - this(this(x, lhs), rhs) + foldTree(foldTree(x, lhs), rhs) case Block(stats, expr) => - this(this(x, stats), expr) + foldTree(foldTree(x, stats), expr) case If(cond, thenp, elsep) => - this(this(this(x, cond), thenp), elsep) + foldTree(foldTree(foldTree(x, cond), thenp), elsep) case Lambda(meth, tpt) => - val a = this(x, meth) - tpt.fold(a)(b => this(a, b)) + val a = foldTree(x, meth) + tpt.fold(a)(b => foldTypeTree(a, b)) case Match(selector, cases) => - this(this(x, selector), cases) - case CaseDef(pat, guard, body) => - this(this(this(x, pat), guard), body) + foldCaseDef(foldTree(x, selector), cases) case Return(expr) => - this(x, expr) + foldTree(x, expr) case Try(block, handler, finalizer) => - this(this(this(x, block), handler), finalizer) + foldTree(foldCaseDef(foldTree(x, block), handler), finalizer) case Repeated(elems) => - this(x, elems) + foldTree(x, elems) case Inlined(call, bindings, expansion) => - this(this(x, bindings), expansion) - case TypeIdent(name) => - x - case TypeSelect(qualifier, name) => - this(x, qualifier) - case Singleton(ref) => - this(x, ref) - case And(left, right) => - this(this(x, left), right) - case Or(left, right) => - this(this(x, left), right) - case Refined(tpt, refinements) => - this(this(x, tpt), refinements) - case Applied(tpt, args) => - this(this(x, tpt), args) - case ByName(result) => - this(x, result) - case TypeBoundsTree(lo, hi) => - this(this(x, lo), hi) - case Annotated(arg, annot) => - this(this(x, arg), annot) - case Value(v) => - this(x, v) - case Bind(_, body) => - this(x, body) - case Unapply(fun, implicits, patterns) => - this(this(this(x, fun), implicits), patterns) - case Alternative(patterns) => - this(x, patterns) - case TypeTest(tpt) => - this(x, tpt) + foldTree(foldTree(x, bindings), expansion) + case vdef @ ValDef(_, tpt, rhs) => implicit val ctx = localCtx(vdef) - this(this(x, tpt), rhs) + foldTree(foldTypeTree(x, tpt), rhs) case ddef @ DefDef(_, tparams, vparamss, tpt, rhs) => implicit val ctx = localCtx(ddef) - this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs) - case tdef @ TypeDef(name, rhs) => + foldTree(foldTypeTree((foldTree(x, tparams) /: vparamss)(foldTree), tpt), rhs) + case tdef @ TypeDef(_, rhs) => implicit val ctx = localCtx(tdef) - this(x, rhs) + foldTypeTree(x, rhs) case cdef @ ClassDef(_, constr, parents, self, body) => implicit val ctx = localCtx(cdef) - this(this(this(this(x, constr), parents), self), body) + foldTree(foldTree(foldParent(foldTree(x, constr), parents), self), body) case Import(expr, selectors) => - this(x, expr) + foldTree(x, expr) case clause @ PackageClause(pid, stats) => - this(this(x, pid), stats)(localCtx(clause.definition)) - case _ => - x + foldTree(foldTree(x, pid), stats)(localCtx(clause.definition)) } } + def foldOverTypeTree(x: X, tree: MaybeTypeTree)(implicit ctx: Context): X = tree match { + case Synthetic() => x + case TypeIdent(_) => x + case TypeSelect(qualifier, _) => foldTree(x, qualifier) + case Singleton(ref) => foldTree(x, ref) + case And(left, right) => foldTypeTree(foldTypeTree(x, left), right) + case Or(left, right) => foldTypeTree(foldTypeTree(x, left), right) + case Refined(tpt, refinements) => foldTree(foldTypeTree(x, tpt), refinements) + case Applied(tpt, args) => foldTypeTree(foldTypeTree(x, tpt), args) + case ByName(result) => foldTypeTree(x, result) + case TypeBoundsTree(lo, hi) => foldTypeTree(foldTypeTree(x, lo), hi) + case Annotated(arg, annot) => foldTree(foldTypeTree(x, arg), annot) + } + + def foldOverCaseDef(x: X, tree: CaseDef)(implicit ctx: Context): X = tree match { + case CaseDef(pat, guard, body) => foldTree(foldTree(foldPattern(x, pat), guard), body) + } + + def foldOverPattern(x: X, tree: Pattern)(implicit ctx: Context): X = tree match { + case Value(v) => foldTree(x, v) + case Bind(_, body) => foldPattern(x, body) + case Unapply(fun, implicits, patterns) => foldPattern(foldTree(foldTree(x, fun), implicits), patterns) + case Alternative(patterns) => foldPattern(x, patterns) + case TypeTest(tpt) => foldTypeTree(x, tpt) + } + + def foldOverParent(x: X, tree: Parent)(implicit ctx: Context): X = tree match { + case TermParent(term) => foldOverTree(x, term) + case TypeParent(typeTree) => foldOverTypeTree(x, typeTree) + } + } diff --git a/library/src/scala/tasty/util/TreeTraverser.scala b/library/src/scala/tasty/util/TreeTraverser.scala index d305aa868a20..62ce209a982b 100644 --- a/library/src/scala/tasty/util/TreeTraverser.scala +++ b/library/src/scala/tasty/util/TreeTraverser.scala @@ -1,14 +1,26 @@ package scala.tasty.util -import scala.tasty.Context -import scala.tasty.trees.Tree +import scala.tasty.Tasty -abstract class TreeTraverser extends TreeAccumulator[Unit] { +abstract class TreeTraverser[T <: Tasty with Singleton](tasty0: T) extends TreeAccumulator[Unit, T](tasty0) { + import tasty._ - def traverse(tree: Tree)(implicit ctx: Context): Unit + def traverseTree(tree: TopLevelStatement)(implicit ctx: Context): Unit = traverseTreeChildren(tree) + def traverseTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): Unit = traverseTypeTreeChildren(tree) + def traverseCaseDef(tree: CaseDef)(implicit ctx: Context): Unit = traverseCaseDef(tree) + def traversePattern(tree: Pattern)(implicit ctx: Context): Unit = traversePatternChildren(tree) + def traverseParent(tree: Parent)(implicit ctx: Context): Unit = traverseParentChildren(tree) - def apply(x: Unit, tree: Tree)(implicit ctx: Context): Unit = traverse(tree) + def foldTree(x: Unit, tree: TopLevelStatement)(implicit ctx: Context): Unit = traverseTree(tree) + def foldTypeTree(x: Unit, tree: MaybeTypeTree)(implicit ctx: Context) = traverseTypeTree(tree) + def foldCaseDef(x: Unit, tree: CaseDef)(implicit ctx: Context) = traverseCaseDef(tree) + def foldPattern(x: Unit, tree: Pattern)(implicit ctx: Context) = traversePattern(tree) + def foldParent(x: Unit, tree: Parent)(implicit ctx: Context) = traverseParent(tree) - protected def traverseChildren(tree: Tree)(implicit ctx: Context): Unit = foldOver((), tree) + protected def traverseTreeChildren(tree: TopLevelStatement)(implicit ctx: Context): Unit = foldOverTree((), tree) + protected def traverseTypeTreeChildren(tree: MaybeTypeTree)(implicit ctx: Context): Unit = foldOverTypeTree((), tree) + protected def traverseCaseDefChildren(tree: CaseDef)(implicit ctx: Context): Unit = foldOverCaseDef((), tree) + protected def traversePatternChildren(tree: Pattern)(implicit ctx: Context): Unit = foldOverPattern((), tree) + protected def traverseParentChildren(tree: Parent)(implicit ctx: Context): Unit = foldOverParent((), tree) } diff --git a/tests/pos/tasty/definitions.scala b/tests/pos/tasty/definitions.scala index 04294712eb8f..dd98ffadcd33 100644 --- a/tests/pos/tasty/definitions.scala +++ b/tests/pos/tasty/definitions.scala @@ -40,12 +40,19 @@ object definitions { case class TypeDef(name: String, rhs: TypeTree | TypeBoundsTree) extends Definition { def mods: List[Modifier] = ??? } - case class ClassDef(name: String, constructor: DefDef, parents: List[Term | TypeTree], + case class ClassDef(name: String, constructor: DefDef, parents: List[Parent], self: Option[ValDef], body: List[Statement]) extends Definition { def mods: List[Modifier] = ??? } case class PackageDef(name: String, members: List[Statement]) extends Definition +// ------ Parents-------------------------------- + + enum Parent { + case TermParent(parent: Term) + case TypeParent(parent: TypeTree) + } + // ------ Terms --------------------------------- /** Trees denoting terms */ diff --git a/tests/run/tasty-extractors-1.check b/tests/run/tasty-extractors-1.check index 725e762be608..1b8005b7c0a4 100644 --- a/tests/run/tasty-extractors-1.check +++ b/tests/run/tasty-extractors-1.check @@ -13,108 +13,108 @@ ConstantType(Float(2.1)) Literal(Double(2.2)) ConstantType(Double(2.2)) -Literal(String("abc")) -ConstantType(String("abc")) +Literal(String(abc)) +ConstantType(String(abc)) -Apply(Ident(Simple(println)), List(Literal(String("abc")))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Apply(Ident(println), List(Literal(String(abc)))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Typed(Literal(Int(8)), Ident(TypeName(Simple(Int)))) -SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) +Typed(Literal(Int(8)), TypeIdent(Int)) +SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))) -Typed(Literal(Byte(8)), Ident(TypeName(Simple(Byte)))) -SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) +Typed(Literal(Byte(8)), TypeIdent(Byte)) +SymRef(Byte, SymRef(scala, ThisType(SymRef(, NoPrefix)))) -Typed(Literal(Short(8)), Ident(TypeName(Simple(Short)))) -SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) +Typed(Literal(Short(8)), TypeIdent(Short)) +SymRef(Short, SymRef(scala, ThisType(SymRef(, NoPrefix)))) -Literal(Char('a')) -ConstantType(Char('a')) +Literal(Char(a)) +ConstantType(Char(a)) Block(List(Literal(Int(1)), Literal(Int(2))), Literal(Int(3))) ConstantType(Int(3)) -If(Typed(Literal(Boolean(true)), Ident(TypeName(Simple(Boolean)))), Literal(Int(1)), Literal(Int(2))) -SymRef(, ThisType(SymRef(, NoPrefix))) +If(Typed(Literal(Boolean(true)), TypeIdent(Boolean)), Literal(Int(1)), Literal(Int(2))) +SymRef(Int, ThisType(SymRef(scala, NoPrefix))) -Match(Literal(String("a")), List(CaseDef(Value(Literal(String("a"))), None, Block(Nil, Literal(Unit()))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Match(Literal(String(a)), List(CaseDef(Value(Literal(String(a))), None, Block(Nil, Literal(Unit()))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Match(Literal(String("b")), List(CaseDef(Bind(Simple(n), Value(Ident(Simple(_)))), None, Block(Nil, Literal(Unit()))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Match(Literal(String(b)), List(CaseDef(Bind(n, Value(Ident(_))), None, Block(Nil, Literal(Unit()))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Match(Literal(String("c")), List(CaseDef(Bind(Simple(n), TypeTest(Ident(TypeName(Simple(String))))), None, Block(Nil, Literal(Unit()))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Match(Literal(String(c)), List(CaseDef(Bind(n, TypeTest(TypeIdent(String))), None, Block(Nil, Literal(Unit()))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Match(Literal(String("e")), List(CaseDef(Value(Ident(Simple(_))), None, Block(Nil, Literal(Unit()))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Match(Literal(String(e)), List(CaseDef(Value(Ident(_)), None, Block(Nil, Literal(Unit()))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Match(Literal(String("f")), List(CaseDef(TypeTest(Ident(TypeName(Simple(String)))), None, Block(Nil, Literal(Unit()))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Match(Literal(String(f)), List(CaseDef(TypeTest(TypeIdent(String)), None, Block(Nil, Literal(Unit()))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Match(Typed(Literal(String("g")), Ident(TypeName(Simple(Any)))), List(CaseDef(Alternative(List(TypeTest(Ident(TypeName(Simple(String)))), TypeTest(Ident(TypeName(Simple(Int)))))), None, Block(Nil, Literal(Unit()))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Match(Typed(Literal(String(g)), TypeIdent(Any)), List(CaseDef(Alternative(List(TypeTest(TypeIdent(String)), TypeTest(TypeIdent(Int)))), None, Block(Nil, Literal(Unit()))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Match(Literal(String("h")), List(CaseDef(Value(Ident(Simple(_))), Some(Literal(Boolean(false))), Block(Nil, Literal(Unit()))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Match(Literal(String(h)), List(CaseDef(Value(Ident(_)), Some(Literal(Boolean(false))), Block(Nil, Literal(Unit()))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ValDef(Simple(a), Synthetic(), Some(Literal(String("o"))))), Match(Literal(String("i")), List(CaseDef(Bind(Simple(a), Value(Ident(Simple(_)))), None, Block(Nil, Literal(Unit())))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ValDef(a, Synthetic(), Some(Literal(String(o))))), Match(Literal(String(i)), List(CaseDef(Bind(a, Value(Ident(_))), None, Block(Nil, Literal(Unit())))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Match(Ident(Simple(Nil)), List(CaseDef(Unapply(TypeApply(Select(Ident(Simple(List)), Simple(unapplySeq)), List(Synthetic())), Nil, List(Bind(Simple(a), Value(Ident(Simple(_)))), Bind(Simple(b), Value(Ident(Simple(_)))), Bind(Simple(c), Value(Ident(Simple(_)))))), None, Block(Nil, Literal(Unit()))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Match(Ident(Nil), List(CaseDef(Unapply(TypeApply(Select(Ident(List), unapplySeq, Some(Signature(List(scala.collection.Seq), scala.Some))), List(Synthetic())), Nil, List(Bind(a, Value(Ident(_))), Bind(b, Value(Ident(_))), Bind(c, Value(Ident(_))))), None, Block(Nil, Literal(Unit()))))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Try(Literal(Int(1)), List(CaseDef(Value(Ident(Simple(_))), None, Block(Nil, Literal(Unit())))), None) -OrType(SymRef(, ThisType(SymRef(, NoPrefix))), SymRef(, ThisType(SymRef(, NoPrefix)))) +Try(Literal(Int(1)), List(CaseDef(Value(Ident(_)), None, Block(Nil, Literal(Unit())))), None) +OrType(SymRef(Int, ThisType(SymRef(scala, NoPrefix))), SymRef(Unit, ThisType(SymRef(scala, NoPrefix)))) Try(Literal(Int(2)), Nil, Some(Literal(Unit()))) ConstantType(Int(2)) -Try(Literal(Int(3)), List(CaseDef(Value(Ident(Simple(_))), None, Block(Nil, Literal(Unit())))), Some(Literal(Unit()))) -OrType(SymRef(, ThisType(SymRef(, NoPrefix))), SymRef(, ThisType(SymRef(, NoPrefix)))) +Try(Literal(Int(3)), List(CaseDef(Value(Ident(_)), None, Block(Nil, Literal(Unit())))), Some(Literal(Unit()))) +OrType(SymRef(Int, ThisType(SymRef(scala, NoPrefix))), SymRef(Unit, ThisType(SymRef(scala, NoPrefix)))) -Apply(Select(Literal(String("a")), Simple(==)), List(Literal(String("b")))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Apply(Select(Literal(String(a)), ==, Some(Signature(List(java.lang.Object), scala.Boolean))), List(Literal(String(b)))) +SymRef(Boolean, ThisType(SymRef(scala, NoPrefix))) -Apply(Select(New(Ident(TypeName(Simple(Object)))), Simple()), Nil) -SymRef(, ThisType(SymRef(, NoPrefix))) +Apply(Select(New(TypeIdent(Object)), , Some(Signature(Nil, java.lang.Object))), Nil) +SymRef(Object, ThisType(SymRef(lang, NoPrefix))) -Apply(Select(Ident(Simple(Int)), Simple(box)), List(NamedArg(Simple(x), Literal(Int(9))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Apply(Select(Ident(Int), box, Some(Signature(List(scala.Int), java.lang.Integer))), List(NamedArg(x, Literal(Int(9))))) +SymRef(Integer, ThisType(SymRef(lang, NoPrefix))) -Apply(TypeApply(Select(Ident(Simple(Ordering)), Simple(apply)), List(Ident(TypeName(Simple(Int))))), List(Ident(Simple(Int)))) -AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))))) +Apply(TypeApply(Select(Ident(Ordering), apply, Some(Signature(List(scala.math.Ordering), scala.math.Ordering))), List(TypeIdent(Int))), List(Ident(Int))) +AppliedType(SymRef(Ordering, ThisType(SymRef(math, NoPrefix))), List(SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))))) -Block(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), Some(Literal(Int(3))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ValDef(a, TypeIdent(Int), Some(Literal(Int(3))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ValDef(Simple(b), Ident(TypeName(Simple(Int))), Some(Literal(Int(3))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ValDef(b, TypeIdent(Int), Some(Literal(Int(3))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple(f1), Nil, Nil, Ident(TypeName(Simple(Int))), Some(Literal(Int(3))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(DefDef(f1, Nil, Nil, TypeIdent(Int), Some(Literal(Int(3))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple(f2), Nil, Nil, Ident(TypeName(Simple(Int))), Some(Return(Literal(Int(4)))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(DefDef(f2, Nil, Nil, TypeIdent(Int), Some(Return(Literal(Int(4)))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple(f3), Nil, List(List(ValDef(Simple(i), Ident(TypeName(Simple(Int))), None))), Ident(TypeName(Simple(Int))), Some(Ident(Simple(i))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(DefDef(f3, Nil, List(List(ValDef(i, TypeIdent(Int), None))), TypeIdent(Int), Some(Ident(i)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple(f4), Nil, List(List(ValDef(Simple(i), Ident(TypeName(Simple(Int))), None)), List(ValDef(Simple(j), Ident(TypeName(Simple(Int))), None))), Ident(TypeName(Simple(Int))), Some(Apply(Select(Ident(Simple(i)), Simple(+)), List(Ident(Simple(j))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(DefDef(f4, Nil, List(List(ValDef(i, TypeIdent(Int), None)), List(ValDef(j, TypeIdent(Int), None))), TypeIdent(Int), Some(Apply(Select(Ident(i), +, Some(Signature(List(scala.Int), scala.Int))), List(Ident(j)))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple(f5), Nil, List(List(ValDef(Simple(i), Ident(TypeName(Simple(Int))), None))), Ident(TypeName(Simple(Int))), Some(Ident(Simple(i)))), DefDef(DefaultGetter(Simple(f5),f5), Nil, Nil, Synthetic(), Some(Literal(Int(9))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(DefDef(f5, Nil, List(List(ValDef(i, TypeIdent(Int), None))), TypeIdent(Int), Some(Ident(i))), DefDef(f5$default$1, Nil, Nil, Synthetic(), Some(Literal(Int(9))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple(f6), List(TypeDef(TypeName(Simple(T)), TypeBoundsTree(Synthetic(), Synthetic()))), List(List(ValDef(Simple(x), Ident(TypeName(Simple(T))), None))), Ident(TypeName(Simple(T))), Some(Ident(Simple(x))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(DefDef(f6, List(TypeDef(T, TypeBoundsTree(Synthetic(), Synthetic()))), List(List(ValDef(x, TypeIdent(T), None))), TypeIdent(T), Some(Ident(x)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple(f7), List(TypeDef(TypeName(Simple(T)), TypeBoundsTree(Synthetic(), Synthetic()))), List(List(ValDef(Simple(x), Ident(TypeName(Simple(T))), None))), Singleton(Ident(Simple(x))), Some(Ident(Simple(x))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(DefDef(f7, List(TypeDef(T, TypeBoundsTree(Synthetic(), Synthetic()))), List(List(ValDef(x, TypeIdent(T), None))), Singleton(Ident(x)), Some(Ident(x)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple(f8), Nil, List(List(ValDef(Simple(i), Annotated(Applied(Synthetic(), List(Ident(TypeName(Simple(Int))))), Apply(Select(New(Synthetic()), Simple()), Nil)), None))), Ident(TypeName(Simple(Int))), Some(Literal(Int(9))))), Apply(Ident(Simple(f8)), List(Typed(Repeated(List(Literal(Int(1)), Literal(Int(2)), Literal(Int(3)))), Synthetic())))) -SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) +Block(List(DefDef(f8, Nil, List(List(ValDef(i, Annotated(Applied(Synthetic(), List(TypeIdent(Int))), Apply(Select(New(Synthetic()), , Some(Signature(Nil, scala.annotation.internal.Repeated))), Nil)), None))), TypeIdent(Int), Some(Literal(Int(9))))), Apply(Ident(f8), List(Typed(Repeated(List(Literal(Int(1)), Literal(Int(2)), Literal(Int(3)))), Synthetic())))) +SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))) -Block(List(DefDef(Simple(f9), Nil, List(List(ValDef(Simple(i), ByName(Ident(TypeName(Simple(Int)))), None))), Ident(TypeName(Simple(Int))), Some(Ident(Simple(i))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(DefDef(f9, Nil, List(List(ValDef(i, ByName(TypeIdent(Int)), None))), TypeIdent(Int), Some(Ident(i)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) diff --git a/tests/run/tasty-extractors-1/quoted_1.scala b/tests/run/tasty-extractors-1/quoted_1.scala index 996e397f94f3..da81b4040641 100644 --- a/tests/run/tasty-extractors-1/quoted_1.scala +++ b/tests/run/tasty-extractors-1/quoted_1.scala @@ -1,18 +1,20 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context +import scala.tasty.Universe import scala.tasty.util.TastyPrinter object Macros { implicit inline def printTree[T](x: => T): Unit = - ~impl('(x))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl('(x))(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ - def impl[T](x: Expr[T])(implicit ctx: Context): Expr[Unit] = { + def impl[T](x: Expr[T])(implicit u: Universe): Expr[Unit] = { + import u._ + import tasty._ val tree = x.toTasty - val treeStr = TastyPrinter.stringOf(tree) - val treeTpeStr = TastyPrinter.stringOf(tree.tpe) + val treeStr = TastyPrinter.stringOfTree(tasty)(tree) + val treeTpeStr = TastyPrinter.stringOfType(tasty)(tree.tpe) '{ println(~treeStr.toExpr) diff --git a/tests/run/tasty-extractors-2.check b/tests/run/tasty-extractors-2.check index 9a7c9f9b78f0..aeddca46e854 100644 --- a/tests/run/tasty-extractors-2.check +++ b/tests/run/tasty-extractors-2.check @@ -1,111 +1,111 @@ -Block(List(ValDef(Simple(x), Synthetic(), Some(Literal(Int(1))))), Assign(Ident(Simple(x)), Literal(Int(2)))) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ValDef(x, Synthetic(), Some(Literal(Int(1))))), Assign(Ident(x), Literal(Int(2)))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(DefDef(Simple($anonfun), Nil, List(List(ValDef(Simple(x), Ident(TypeName(Simple(Int))), None))), Synthetic(), Some(Ident(Simple(x))))), Lambda(Ident(Simple($anonfun)), None)) -AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))))) +Block(List(DefDef($anonfun, Nil, List(List(ValDef(x, TypeIdent(Int), None))), Synthetic(), Some(Ident(x)))), Lambda(Ident($anonfun), None)) +AppliedType(SymRef(Function1, ThisType(SymRef(scala, NoPrefix))), List(SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))), SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))))) -Ident(Simple(???)) -SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))) +Ident(???) +SymRef(???, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))) Typed(Literal(Int(1)), Singleton(Literal(Int(1)))) ConstantType(Int(1)) -Typed(Literal(Int(1)), Ident(TypeName(Simple(Int)))) -SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) +Typed(Literal(Int(1)), TypeIdent(Int)) +SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))) -Typed(Ident(Simple(Nil)), Applied(Ident(TypeName(Simple(List))), List(Ident(TypeName(Simple(Int)))))) -AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))))) +Typed(Ident(Nil), Applied(TypeIdent(List), List(TypeIdent(Int)))) +AppliedType(SymRef(List, ThisType(SymRef(immutable, NoPrefix))), List(SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))))) -Typed(Apply(Select(New(Ident(TypeName(Simple(Baz)))), Simple()), Nil), And(Ident(TypeName(Simple(Foo))), Ident(TypeName(Simple(Bar))))) -AndType(SymRef(, ThisType(SymRef())>, NoPrefix))), SymRef(, ThisType(SymRef())>, NoPrefix)))) +Typed(Apply(Select(New(TypeIdent(Baz)), , Some(Signature(Nil, Baz))), Nil), And(TypeIdent(Foo), TypeIdent(Bar))) +AndType(SymRef(Foo, ThisType(SymRef(, NoPrefix))), SymRef(Bar, ThisType(SymRef(, NoPrefix)))) -Typed(Literal(Int(1)), Or(Ident(TypeName(Simple(Int))), Ident(TypeName(Simple(String))))) -OrType(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef(, NoPrefix))))) +Typed(Literal(Int(1)), Or(TypeIdent(Int), TypeIdent(String))) +OrType(SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))), SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix))))) -Block(List(Import(Select(Ident(Simple(scala)), Simple(collection)), List(SimpleSelector(Id(mutable))))), Literal(Int(1))) +Block(List(Import(Select(Ident(scala), collection, None), List(SimpleSelector(Id(mutable))))), Literal(Int(1))) ConstantType(Int(1)) -Block(List(Import(Select(Ident(Simple(scala)), Simple(collection)), List(SimpleSelector(Id(mutable)), SimpleSelector(Id(immutable))))), Literal(Int(2))) +Block(List(Import(Select(Ident(scala), collection, None), List(SimpleSelector(Id(mutable))SimpleSelector(Id(immutable))))), Literal(Int(2))) ConstantType(Int(2)) -Block(List(Import(Select(Ident(Simple(scala)), Simple(collection)), List(RenameSelector(Id(mutable), Id(mut))))), Literal(Int(3))) +Block(List(Import(Select(Ident(scala), collection, None), List(RenameSelector(Id(mutable), Id(mut))))), Literal(Int(3))) ConstantType(Int(3)) -Block(List(Import(Select(Ident(Simple(scala)), Simple(collection)), List(OmitSelector(Id(mutable))))), Literal(Int(4))) +Block(List(Import(Select(Ident(scala), collection, None), List(OmitSelector(Id(mutable))))), Literal(Int(4))) ConstantType(Int(4)) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, Nil)), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, Nil)), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ValDef(Simple(Foo), Ident(TypeName(ObjectClass(Simple(Foo)))), Some(Apply(Select(New(Ident(TypeName(ObjectClass(Simple(Foo))))), Simple()), Nil))), ClassDef(TypeName(ObjectClass(Simple(Foo))), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), Some(ValDef(Simple(_), Singleton(Ident(Simple(Foo))), None)), Nil)), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ValDef(Foo, TypeIdent(Foo$), Some(Apply(Select(New(TypeIdent(Foo$)), , Some(Signature(Nil, Test$._$Foo$))), Nil))), ClassDef(Foo$, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), Some(ValDef(_, Singleton(Ident(Foo)), None)), Nil)), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(TypeDef(TypeName(Simple(Foo)), TypeBoundsTree(Synthetic(), Synthetic()))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(TypeDef(Foo, TypeBoundsTree(Synthetic(), Synthetic()))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(TypeDef(TypeName(Simple(Foo)), Ident(TypeName(Simple(Int))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(TypeDef(Foo, TypeIdent(Int))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(TypeDef(TypeName(Simple(Foo)), TypeBoundsTree(Ident(TypeName(Simple(Null))), Ident(TypeName(Simple(Object)))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(TypeDef(Foo, TypeBoundsTree(TypeIdent(Null), TypeIdent(Object)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), Some(Literal(Int(0)))), DefDef(Simple(a_=), Nil, List(List(ValDef(Simple(x$1), Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), Some(Literal(Int(0)))), DefDef(a_=, Nil, List(List(ValDef(x$1, Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(DefDef(Simple(a), Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(DefDef(Simple(a), Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(DefDef(Simple(a), Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo1)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None)))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo1, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo2)), DefDef(Simple(), Nil, List(List(ValDef(Simple(b), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(b), Synthetic(), None)))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo2, DefDef(, Nil, List(List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(b, Synthetic(), None)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo3)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None))), ValDef(Simple(Foo3), Ident(TypeName(ObjectClass(Simple(Foo3)))), Some(Apply(Select(New(Ident(TypeName(ObjectClass(Simple(Foo3))))), Simple()), Nil))), ClassDef(TypeName(ObjectClass(Simple(Foo3))), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), Some(ValDef(Simple(_), Singleton(Ident(Simple(Foo3))), None)), List(DefDef(DefaultGetter(Simple(),), Nil, Nil, Synthetic(), Some(Literal(Int(5))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo3, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None))), ValDef(Foo3, TypeIdent(Foo3$), Some(Apply(Select(New(TypeIdent(Foo3$)), , Some(Signature(Nil, Test$._$Foo3$))), Nil))), ClassDef(Foo3$, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), Some(ValDef(_, Singleton(Ident(Foo3)), None)), List(DefDef($lessinit$greater$default$1, Nil, Nil, Synthetic(), Some(Literal(Int(5))))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo4)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None)), List(ValDef(Simple(b), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None), ValDef(Simple(b), Synthetic(), None)))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo4, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo5)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None)), List(ValDef(Simple(b), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None), ValDef(Simple(b), Synthetic(), None))), ValDef(Simple(Foo5), Ident(TypeName(ObjectClass(Simple(Foo5)))), Some(Apply(Select(New(Ident(TypeName(ObjectClass(Simple(Foo5))))), Simple()), Nil))), ClassDef(TypeName(ObjectClass(Simple(Foo5))), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), Some(ValDef(Simple(_), Singleton(Ident(Simple(Foo5))), None)), List(DefDef(DefaultGetter(Simple(),), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None))), Synthetic(), Some(Ident(Simple(a))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo5, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None))), ValDef(Foo5, TypeIdent(Foo5$), Some(Apply(Select(New(TypeIdent(Foo5$)), , Some(Signature(Nil, Test$._$Foo5$))), Nil))), ClassDef(Foo5$, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), Some(ValDef(_, Singleton(Ident(Foo5)), None)), List(DefDef($lessinit$greater$default$2, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), Some(Ident(a)))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo6)), DefDef(Simple(), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Int))), None)), List(ValDef(Simple(b), Singleton(Ident(Simple(a))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), None), ValDef(Simple(b), Synthetic(), None)))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo6, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, Singleton(Ident(a)), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo8)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(Apply(Ident(Simple(println)), List(Literal(Int(0))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo8, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(Apply(Ident(println), List(Literal(Int(0))))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo10)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), Some(Literal(Int(9))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo10, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), Some(Literal(Int(9))))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo11)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), Some(Literal(Int(10)))), DefDef(Simple(a_=), Nil, List(List(ValDef(Simple(x$1), Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo11, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), Some(Literal(Int(10)))), DefDef(a_=, Nil, List(List(ValDef(x$1, Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo12)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(a), Synthetic(), Some(Literal(Int(11))))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo12, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), Some(Literal(Int(11))))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, Nil), ClassDef(TypeName(Simple(Bar)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, Nil)), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, Nil), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, Test$._$Foo))), Nil))), None, Nil)), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo2)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Synthetic()), None, Nil), ClassDef(TypeName(Simple(Bar)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil), Ident(TypeName(Simple(Foo2)))), None, Nil)), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo2, DefDef(, Nil, List(Nil), Synthetic(), None), List(TypeParent(Synthetic())), None, Nil), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), TypeParent(TypeIdent(Foo2))), None, Nil)), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(List(ValDef(Simple(i), Ident(TypeName(Simple(Int))), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(ValDef(Simple(i), Synthetic(), None))), ClassDef(TypeName(Simple(Bar)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Ident(TypeName(Simple(Foo)))), Simple()), List(Literal(Int(1))))), None, Nil)), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(List(ValDef(i, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(i, Synthetic(), None))), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(TypeIdent(Foo)), , Some(Signature(List(scala.Int), Test$._$Foo))), List(Literal(Int(1)))))), None, Nil)), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(X)), Ident(TypeName(Simple(Int)))))), DefDef(Simple(f), Nil, List(List(ValDef(Simple(a), Ident(TypeName(Simple(Foo))), None))), TypeSelect(Ident(Simple(a)), TypeName(Simple(X))), Some(Ident(Simple(???))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(X, TypeIdent(Int)))), DefDef(f, Nil, List(List(ValDef(a, TypeIdent(Foo), None))), TypeSelect(Ident(a), X), Some(Ident(???)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(TypeName(Simple(Foo)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(X)), TypeBoundsTree(Synthetic(), Synthetic())))), DefDef(Simple(f), Nil, List(List(ValDef(Simple(a), Refined(Ident(TypeName(Simple(Foo))), List(TypeDef(TypeName(Simple(X)), Ident(TypeName(Simple(Int)))))), None))), TypeSelect(Ident(Simple(a)), TypeName(Simple(X))), Some(Ident(Simple(???))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(X, TypeBoundsTree(Synthetic(), Synthetic())))), DefDef(f, Nil, List(List(ValDef(a, Refined(TypeIdent(Foo), List(TypeDef(X, TypeIdent(Int)))), None))), TypeSelect(Ident(a), X), Some(Ident(???)))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ValDef(Simple(lambda), Applied(Synthetic(), List(Ident(TypeName(Simple(Int))), Ident(TypeName(Simple(Int))))), Some(Block(List(DefDef(Simple($anonfun), Nil, List(List(ValDef(Simple(x), Synthetic(), None))), Synthetic(), Some(Ident(Simple(x))))), Lambda(Ident(Simple($anonfun)), None))))), Literal(Unit())) -SymRef(, ThisType(SymRef(, NoPrefix))) +Block(List(ValDef(lambda, Applied(Synthetic(), List(TypeIdent(Int), TypeIdent(Int))), Some(Block(List(DefDef($anonfun, Nil, List(List(ValDef(x, Synthetic(), None))), Synthetic(), Some(Ident(x)))), Lambda(Ident($anonfun), None))))), Literal(Unit())) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) diff --git a/tests/run/tasty-extractors-2/quoted_1.scala b/tests/run/tasty-extractors-2/quoted_1.scala index 996e397f94f3..da81b4040641 100644 --- a/tests/run/tasty-extractors-2/quoted_1.scala +++ b/tests/run/tasty-extractors-2/quoted_1.scala @@ -1,18 +1,20 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context +import scala.tasty.Universe import scala.tasty.util.TastyPrinter object Macros { implicit inline def printTree[T](x: => T): Unit = - ~impl('(x))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl('(x))(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ - def impl[T](x: Expr[T])(implicit ctx: Context): Expr[Unit] = { + def impl[T](x: Expr[T])(implicit u: Universe): Expr[Unit] = { + import u._ + import tasty._ val tree = x.toTasty - val treeStr = TastyPrinter.stringOf(tree) - val treeTpeStr = TastyPrinter.stringOf(tree.tpe) + val treeStr = TastyPrinter.stringOfTree(tasty)(tree) + val treeTpeStr = TastyPrinter.stringOfType(tasty)(tree.tpe) '{ println(~treeStr.toExpr) diff --git a/tests/run/tasty-extractors-3.check b/tests/run/tasty-extractors-3.check index ae10423620ec..5b8f72f7c560 100644 --- a/tests/run/tasty-extractors-3.check +++ b/tests/run/tasty-extractors-3.check @@ -1,42 +1,42 @@ -SymRef(, ThisType(SymRef(, NoPrefix))) +SymRef(Int, ThisType(SymRef(scala, NoPrefix))) -SymRef(, NoPrefix) +SymRef(x, NoPrefix) -TypeBounds(SymRef(, ThisType(SymRef(, NoPrefix))), SymRef(, ThisType(SymRef(, NoPrefix)))) +TypeBounds(SymRef(#, ThisType(SymRef(scala, NoPrefix))), SymRef(#, ThisType(SymRef(scala, NoPrefix)))) -SymRef(, ThisType(SymRef(, NoPrefix))) +SymRef(#, ThisType(SymRef(scala, NoPrefix))) -SymRef(, ThisType(SymRef(, NoPrefix))) +SymRef(#, ThisType(SymRef(scala, NoPrefix))) -SymRef(, NoPrefix) +SymRef(T, NoPrefix) -TypeBounds(SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix))))) +TypeBounds(SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))), SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix))))) -SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) +SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))) -SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) +SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))) -SymRef(, NoPrefix) +SymRef(T, NoPrefix) -SymRef(, ThisType(SymRef(, NoPrefix))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -SymRef(, ThisType(SymRef(, NoPrefix))) +SymRef(Object, ThisType(SymRef(lang, NoPrefix))) -TypeBounds(SymRef(, ThisType(SymRef(, NoPrefix))), SymRef(, ThisType(SymRef(, NoPrefix)))) +TypeBounds(SymRef(#, ThisType(SymRef(scala, NoPrefix))), SymRef(#, ThisType(SymRef(scala, NoPrefix)))) -SymRef(, ThisType(SymRef(, NoPrefix))) +SymRef(#, ThisType(SymRef(scala, NoPrefix))) -SymRef(, ThisType(SymRef(, NoPrefix))) +SymRef(#, ThisType(SymRef(scala, NoPrefix))) -Refinement(SymRef(, NoPrefix), TypeName(Simple(X)), TypeBounds(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))))) +Refinement(SymRef(Foo, NoPrefix), X, TypeBounds(SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))), SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))))) -SymRef(, ThisType(SymRef(, NoPrefix))) +SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -SymRef(, NoPrefix) +SymRef(Foo, NoPrefix) -SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))) +SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))) -SymRef(, NoPrefix) +SymRef($anon, NoPrefix) -Refinement(SymRef(, NoPrefix), TypeName(Simple(X)), TypeBounds(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))))) +Refinement(SymRef(Foo, NoPrefix), X, TypeBounds(SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))), SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))))) diff --git a/tests/run/tasty-extractors-3/quoted_1.scala b/tests/run/tasty-extractors-3/quoted_1.scala index 5ae4b1930679..935e02374b64 100644 --- a/tests/run/tasty-extractors-3/quoted_1.scala +++ b/tests/run/tasty-extractors-3/quoted_1.scala @@ -1,34 +1,29 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context -import scala.tasty.trees.{Tree, TypeBoundsTree, TypeTree} +import scala.tasty.Universe import scala.tasty.util.{TastyPrinter, TreeTraverser} object Macros { implicit inline def printTypes[T](x: => T): Unit = - ~impl('(x))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl('(x))(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ + + def impl[T](x: Expr[T])(implicit u: Universe): Expr[Unit] = { + import u._ + import u.tasty._ - def impl[T](x: Expr[T])(implicit ctx: Context): Expr[Unit] = { val buff = new StringBuilder - val traverser = new TreeTraverser { - override def traverse(tree: Tree)(implicit ctx: Context): Unit = { - tree match { - case tree: TypeTree => - buff.append(TastyPrinter.stringOf(tree.tpe)) - buff.append("\n\n") - case tree: TypeBoundsTree => - buff.append(TastyPrinter.stringOf(tree.tpe)) - buff.append("\n\n") - case _ => - } - traverseChildren(tree) + val traverser = new TreeTraverser(u.tasty) { + override def traverseTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): Unit = { + buff.append(TastyPrinter.stringOfType(u.tasty)(tree.tpe)) + buff.append("\n\n") + traverseTypeTreeChildren(tree) } } val tree = x.toTasty - traverser.traverse(tree)(ctx) + traverser.traverseTree(tree) '(print(~buff.result().toExpr)) } } diff --git a/tests/run/tasty-extractors-constants-1/quoted_1.scala b/tests/run/tasty-extractors-constants-1/quoted_1.scala index 807d23c8b755..96c38edc9204 100644 --- a/tests/run/tasty-extractors-constants-1/quoted_1.scala +++ b/tests/run/tasty-extractors-constants-1/quoted_1.scala @@ -1,20 +1,23 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context -import scala.tasty.names.Name -import scala.tasty.trees._ -import scala.tasty.util.{TastyPrinter, TreeTraverser} +import scala.tasty.Universe +import scala.tasty.util._ object Macros { implicit inline def testMacro: Unit = - ~impl(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ + + def impl(implicit u: Universe): Expr[Unit] = { + import u._ + import u.tasty._ - def impl(implicit ctx: Context): Expr[Unit] = { val buff = new StringBuilder def stagedPrintln(x: Any): Unit = buff append java.util.Objects.toString(x) append "\n" + val Constant = new ConstantExtractor(tasty) + 3.toExpr match { case Constant(n) => stagedPrintln(n) } '(4) match { case Constant(n) => stagedPrintln(n) } '("abc") match { case Constant(n) => stagedPrintln(n) } diff --git a/tests/run/tasty-extractors-constants-2/quoted_1.scala b/tests/run/tasty-extractors-constants-2/quoted_1.scala index 4747e67911b5..5ffc8278f494 100644 --- a/tests/run/tasty-extractors-constants-2/quoted_1.scala +++ b/tests/run/tasty-extractors-constants-2/quoted_1.scala @@ -1,29 +1,27 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context -import scala.tasty.names.Name -import scala.tasty.trees._ -import scala.tasty.util.{TastyPrinter, TreeTraverser} +import scala.tasty.Universe +import scala.tasty.util._ object Macros { inline def testMacro: Unit = - ~impl(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ - def impl(implicit ctx: Context): Expr[Unit] = { + def impl(implicit u: Universe): Expr[Unit] = { // 2 is a lifted constant - val show1 = power(2.toExpr, 3.0.toExpr).show - val run1 = power(2.toExpr, 3.0.toExpr).run + val show1 = power(2.toExpr, 3.0.toExpr)(u).show + val run1 = power(2.toExpr, 3.0.toExpr)(u).run // n is a lifted constant val n = 2 - val show2 = power(n.toExpr, 4.0.toExpr).show - val run2 = power(n.toExpr, 4.0.toExpr).run + val show2 = power(n.toExpr, 4.0.toExpr)(u).show + val run2 = power(n.toExpr, 4.0.toExpr)(u).run // n is a constant in a quote - val show3 = power('(2), 5.0.toExpr).show - val run3 = power('(2), 5.0.toExpr).run + val show3 = power('(2), 5.0.toExpr)(u).show + val run3 = power('(2), 5.0.toExpr)(u).run // n2 is clearly not a constant // FIXME @@ -46,7 +44,10 @@ object Macros { } } - def power(n: Expr[Int], x: Expr[Double])(implicit ctx: Context): Expr[Double] = { + def power(n: Expr[Int], x: Expr[Double])(implicit u: Universe): Expr[Double] = { + import u._ + import u.tasty._ + val Constant = new ConstantExtractor(u.tasty) n match { case Constant(n1) => powerCode(n1, x) case _ => '{ dynamicPower(~n, ~x) } diff --git a/tests/run/tasty-extractors-owners.check b/tests/run/tasty-extractors-owners.check index a6e05b47e0cf..b32a13ceafcc 100644 --- a/tests/run/tasty-extractors-owners.check +++ b/tests/run/tasty-extractors-owners.check @@ -1,27 +1,27 @@ -Simple(foo) -DefDef(Simple(main), Nil, List(List(ValDef(Simple(args), Synthetic(), None))), Synthetic(), None) +foo +DefDef(main, Nil, List(List(ValDef(args, Synthetic(), None))), Synthetic(), None) -Simple(bar) -DefDef(Simple(foo), Nil, Nil, Synthetic(), None) +bar +DefDef(foo, Nil, Nil, Synthetic(), None) -Simple(bar2) -DefDef(Simple(foo), Nil, Nil, Synthetic(), None) +bar2 +DefDef(foo, Nil, Nil, Synthetic(), None) -Simple(foo2) -DefDef(Simple(main), Nil, List(List(ValDef(Simple(args), Synthetic(), None))), Synthetic(), None) +foo2 +DefDef(main, Nil, List(List(ValDef(args, Synthetic(), None))), Synthetic(), None) -Simple(baz) -ValDef(Simple(foo2), Synthetic(), None) +baz +ValDef(foo2, Synthetic(), None) -Simple(baz2) -ValDef(Simple(foo2), Synthetic(), None) +baz2 +ValDef(foo2, Synthetic(), None) -Simple() -ClassDef(TypeName(Simple(A)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(B)), Synthetic()), DefDef(Simple(b), Nil, Nil, Synthetic(), None), ValDef(Simple(b2), Synthetic(), None))) + +ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) -Simple(b) -ClassDef(TypeName(Simple(A)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(B)), Synthetic()), DefDef(Simple(b), Nil, Nil, Synthetic(), None), ValDef(Simple(b2), Synthetic(), None))) +b +ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) -Simple(b2) -ClassDef(TypeName(Simple(A)), DefDef(Simple(), Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), Simple()), Nil)), None, List(TypeDef(TypeName(Simple(B)), Synthetic()), DefDef(Simple(b), Nil, Nil, Synthetic(), None), ValDef(Simple(b2), Synthetic(), None))) +b2 +ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) diff --git a/tests/run/tasty-extractors-owners/quoted_1.scala b/tests/run/tasty-extractors-owners/quoted_1.scala index c225bfaef664..93baa403a06c 100644 --- a/tests/run/tasty-extractors-owners/quoted_1.scala +++ b/tests/run/tasty-extractors-owners/quoted_1.scala @@ -1,39 +1,44 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context -import scala.tasty.names.Name -import scala.tasty.trees._ +import scala.tasty.Universe +import scala.tasty.Tasty import scala.tasty.util.{TastyPrinter, TreeTraverser} object Macros { implicit inline def printOwners[T](x: => T): Unit = - ~impl('(x))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl('(x))(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ + + def impl[T](x: Expr[T])(implicit u: Universe): Expr[Unit] = { + import u._ + import u.tasty._ - def impl[T](x: Expr[T])(implicit ctx: Context): Expr[Unit] = { val buff = new StringBuilder - val traverser = new TreeTraverser { - override def traverse(tree: Tree)(implicit ctx: Context): Unit = { + + val printer = new TreeTraverser(u.tasty) { + import tasty._ + override def traverseTree(tree: TopLevelStatement)(implicit ctx: Context): Unit = { tree match { - case tree @ DefDef(name: Name, _, _, _, _) => - buff.append(TastyPrinter.stringOf(name)) + case tree @ DefDef(name, _, _, _, _) => + buff.append(name) buff.append("\n") - buff.append(TastyPrinter.stringOf(tree.owner)) + buff.append(TastyPrinter.stringOfTree(tasty)(tree.owner)) buff.append("\n\n") - case tree @ ValDef(name: Name, _, _) => - buff.append(TastyPrinter.stringOf(name)) + case tree @ ValDef(name, _, _) => + buff.append(name) buff.append("\n") - buff.append(TastyPrinter.stringOf(tree.owner)) + buff.append(TastyPrinter.stringOfTree(tasty)(tree.owner)) buff.append("\n\n") case _ => } - traverseChildren(tree) + traverseTreeChildren(tree) } } val tree = x.toTasty - traverser.traverse(tree)(ctx) + printer.traverseTree(tree) '(print(~buff.result().toExpr)) } + } diff --git a/tests/run/tasty-extractors-types.check b/tests/run/tasty-extractors-types.check index b9cb6a572e4e..0cb6690578ab 100644 --- a/tests/run/tasty-extractors-types.check +++ b/tests/run/tasty-extractors-types.check @@ -1,12 +1,12 @@ -Ident(TypeName(Simple(Int))) -SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))) +TypeIdent(Int) +SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))) -Applied(Ident(TypeName(Simple(List))), List(Ident(TypeName(Simple(String))))) -AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))))) +Applied(TypeIdent(List), List(TypeIdent(String))) +AppliedType(SymRef(List, ThisType(SymRef(immutable, NoPrefix))), List(SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))))) -Applied(Ident(TypeName(Simple(Map))), List(Ident(TypeName(Simple(String))), Ident(TypeName(Simple(Int))))) -AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))), SymRef(, SymRef(, ThisType(SymRef())>, NoPrefix)))))) +Applied(TypeIdent(Map), List(TypeIdent(String), TypeIdent(Int))) +AppliedType(SymRef(Map, ThisType(SymRef(immutable, NoPrefix))), List(SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))), SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))))) -Applied(Ident(TypeName(Simple(Map))), List(Ident(TypeName(Simple(String))), Ident(TypeName(Simple(I))))) -AppliedType(SymRef(, ThisType(SymRef(, NoPrefix))), List(SymRef(, SymRef(, ThisType(SymRef(, NoPrefix)))), SymRef(, NoPrefix))) +Applied(TypeIdent(Map), List(TypeIdent(String), TypeIdent(I))) +AppliedType(SymRef(Map, ThisType(SymRef(immutable, NoPrefix))), List(SymRef(String, SymRef(Predef, ThisType(SymRef(scala, NoPrefix)))), SymRef(I, NoPrefix))) diff --git a/tests/run/tasty-extractors-types/quoted_1.scala b/tests/run/tasty-extractors-types/quoted_1.scala index 3f722c5618fa..953a425741e7 100644 --- a/tests/run/tasty-extractors-types/quoted_1.scala +++ b/tests/run/tasty-extractors-types/quoted_1.scala @@ -1,21 +1,21 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context -import scala.tasty.names.Name -import scala.tasty.trees._ +import scala.tasty.Universe import scala.tasty.util.{TastyPrinter, TreeTraverser} object Macros { implicit inline def printType[T]: Unit = - ~impl('[T])(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl('[T])(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ - def impl[T](x: Type[T])(implicit ctx: Context): Expr[Unit] = { + def impl[T](x: Type[T])(implicit u: Universe): Expr[Unit] = { + import u._ + import u.tasty._ val tree = x.toTasty '{ - println(~TastyPrinter.stringOf(tree).toExpr) - println(~TastyPrinter.stringOf(tree.tpe).toExpr) + println(~TastyPrinter.stringOfTypeTree(u.tasty)(tree).toExpr) + println(~TastyPrinter.stringOfType(u.tasty)(tree.tpe).toExpr) println() } } diff --git a/tests/run/tasty-linenumber/quoted_1.scala b/tests/run/tasty-linenumber/quoted_1.scala index 3dcfdf327947..5d4e6ab51837 100644 --- a/tests/run/tasty-linenumber/quoted_1.scala +++ b/tests/run/tasty-linenumber/quoted_1.scala @@ -2,7 +2,7 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context +import scala.tasty.Universe class LineNumber(val value: Int) { override def toString: String = value.toString @@ -11,9 +11,12 @@ class LineNumber(val value: Int) { object LineNumber { implicit inline def line[T >: Unit <: Unit]: LineNumber = - ~lineImpl('[T])(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~lineImpl('[T])(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ - def lineImpl(x: Type[Unit])(implicit ctx: Context): Expr[LineNumber] = + def lineImpl(x: Type[Unit])(implicit u: Universe): Expr[LineNumber] = { + import u._ + import u.tasty._ '(new LineNumber(~x.toTasty.pos.startLine.toExpr)) + } } diff --git a/tests/run/tasty-location.check b/tests/run/tasty-location.check index be2c79195a2d..adaee27a91a3 100644 --- a/tests/run/tasty-location.check +++ b/tests/run/tasty-location.check @@ -1,6 +1,6 @@ -foo Location(List(Test, loc1)) -foo Location(List(Test, main)) -foo Location(List(Test, main)) -foo Location(List(Test, main, bar)) -foo Location(List(Test, main, bar, baz)) -foo Location(List(Test, main, f, $anonfun)) +foo Location(List(Test$, loc1)) +foo Location(List(Test$, main)) +foo Location(List(Test$, main)) +foo Location(List(Test$, main, bar)) +foo Location(List(Test$, main, bar, baz)) +foo Location(List(Test$, main, f, $anonfun)) diff --git a/tests/run/tasty-location/quoted_1.scala b/tests/run/tasty-location/quoted_1.scala index b322a425a738..2ed101d91bd3 100644 --- a/tests/run/tasty-location/quoted_1.scala +++ b/tests/run/tasty-location/quoted_1.scala @@ -2,33 +2,28 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context -import scala.tasty.names._ -import scala.tasty.trees._ +import scala.tasty.Universe case class Location(owners: List[String]) object Location { implicit inline def location: Location = - ~impl(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ - def impl(implicit ctx: Context): Expr[Location] = { - val list = listOwnerNames(ctx.owner, Nil)(ctx) - '(new Location(~list.toExpr)) - } + def impl(implicit u: Universe): Expr[Location] = { + import u._ + import u.tasty._ - private def listOwnerNames(definition: Definition, acc: List[String])(implicit ctx: Context): List[String] = definition match { - case ValDef(name, _, _) => listOwnerNames(definition.owner, nameString(name) :: acc) - case DefDef(name, _, _, _, _) => listOwnerNames(definition.owner, nameString(name) :: acc) - case ClassDef(name, _, _, _, _) => listOwnerNames(definition.owner, nameString(name) :: acc) - case _ => acc - } + def listOwnerNames(definition: Definition, acc: List[String]): List[String] = definition match { + case ValDef(name, _, _) => listOwnerNames(definition.owner, name :: acc) + case DefDef(name, _, _, _, _) => listOwnerNames(definition.owner, name :: acc) + case ClassDef(name, _, _, _, _) => listOwnerNames(definition.owner, name :: acc) + case _ => acc + } - private def nameString(name: Name)(implicit ctx: Context): String = name match { - case Simple(nme) => nme - case ObjectClass(underlying) => nameString(underlying) - case TypeName(underlying) => nameString(underlying) + val list = listOwnerNames(u.context.owner, Nil) + '(new Location(~list.toExpr)) } private implicit def ListIsLiftable[T : Liftable : Type]: Liftable[List[T]] = { diff --git a/tests/run/tasty-macro-assert.check b/tests/run/tasty-macro-assert.check index 9cb0fa36e224..d8efe99f6d02 100644 --- a/tests/run/tasty-macro-assert.check +++ b/tests/run/tasty-macro-assert.check @@ -1,7 +1,7 @@ Condition was false Error left did not equal right: - left = Literal(String("acb")) - right = Literal(String("cde")) + left = Literal(String(acb)) + right = Literal(String(cde)) Error left was equal to right: - left = Literal(String("acb")) - right = Literal(String("acb")) + left = Literal(String(acb)) + right = Literal(String(acb)) diff --git a/tests/run/tasty-macro-assert/quoted_1.scala b/tests/run/tasty-macro-assert/quoted_1.scala index 46e9469762a3..dcfa4ee7e2c8 100644 --- a/tests/run/tasty-macro-assert/quoted_1.scala +++ b/tests/run/tasty-macro-assert/quoted_1.scala @@ -1,10 +1,7 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.trees._ -import scala.tasty.types._ -import scala.tasty.names._ -import scala.tasty.Context +import scala.tasty.Universe import scala.tasty.util.TastyPrinter object Asserts { @@ -17,13 +14,16 @@ object Asserts { object Ops inline def macroAssert(cond: Boolean): Unit = - ~impl('(cond))(Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl('(cond))(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ + + def impl(cond: Expr[Boolean])(implicit u: Universe): Expr[Unit] = { + import u._ + import u.tasty._ - def impl(cond: Expr[Boolean])(implicit ctx: Context): Expr[Unit] = { val tree = cond.toTasty def isOps(tpe: MaybeType): Boolean = tpe match { - case SymRef(DefDef(Simple("Ops"), _, _, _, _), _) => true // TODO check that the parent is Asserts + case SymRef(DefDef("Ops", _, _, _, _), _) => true // TODO check that the parent is Asserts case _ => false } @@ -36,10 +36,10 @@ object Asserts { } tree match { - case Apply(Select(OpsTree(left), Simple(op)), right :: Nil) => + case Apply(Select(OpsTree(left), op, _), right :: Nil) => // FIXME splice the threes directly - val lExpr = TastyPrinter.stringOf(left).toExpr - val rExpr = TastyPrinter.stringOf(right).toExpr + val lExpr = TastyPrinter.stringOfTree(tasty)(left).toExpr + val rExpr = TastyPrinter.stringOfTree(tasty)(right).toExpr op match { case "===" => '(assertEquals(~lExpr, ~rExpr)) case "!==" => '(assertNotEquals(~lExpr, ~rExpr)) diff --git a/tests/run/tasty-positioned/quoted_1.scala b/tests/run/tasty-positioned/quoted_1.scala index 63ccf76f9f21..f0945503f6d8 100644 --- a/tests/run/tasty-positioned/quoted_1.scala +++ b/tests/run/tasty-positioned/quoted_1.scala @@ -2,7 +2,7 @@ import scala.quoted._ import dotty.tools.dotc.quoted.Toolbox._ -import scala.tasty.Context +import scala.tasty.Universe case class Position(path: String, start: Int, end: Int, startLine: Int, startColumn: Int, endLine: Int, endColumn: Int) @@ -12,9 +12,12 @@ case class Positioned[T](value: T, position: Position) object Positioned { implicit inline def apply[T](x: T): Positioned[T] = - ~impl('(x))('[T], Context.compilationContext) // FIXME infer Context.compilationContext within top level ~ + ~impl('(x))('[T], Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ + + def impl[T](x: Expr[T])(implicit ev: Type[T], u: Universe): Expr[Positioned[T]] = { + import u._ + import u.tasty.{Position => _, _} - def impl[T](x: Expr[T])(implicit ev: Type[T], ctx: Context): Expr[Positioned[T]] = { val pos = x.toTasty.pos val path = pos.sourceFile.toString.toExpr From 5b6bb0b7d033b47c54c7a95139e0bfe848a992e4 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 3 May 2018 13:17:39 +0200 Subject: [PATCH 03/21] Workaround issue #4449 --- library/src/scala/tasty/util/TreeAccumulator.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index 9ffbc75ed9bb..d1b7a36a40b1 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -90,8 +90,8 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { case Refined(tpt, refinements) => foldTree(foldTypeTree(x, tpt), refinements) case Applied(tpt, args) => foldTypeTree(foldTypeTree(x, tpt), args) case ByName(result) => foldTypeTree(x, result) - case TypeBoundsTree(lo, hi) => foldTypeTree(foldTypeTree(x, lo), hi) case Annotated(arg, annot) => foldTree(foldTypeTree(x, arg), annot) + case TypeBoundsTree(lo, hi) => foldTypeTree(foldTypeTree(x, lo), hi) } def foldOverCaseDef(x: X, tree: CaseDef)(implicit ctx: Context): X = tree match { From d230e7d3ac5363194fd0ba6270de5373b0f005c1 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Thu, 3 May 2018 16:33:53 +0200 Subject: [PATCH 04/21] Rename TopLevelStatement to Tree --- .../src/dotty/tools/dotc/tasty/TastyImpl.scala | 9 +++------ library/src/scala/tasty/Tasty.scala | 14 ++++++-------- library/src/scala/tasty/util/TastyPrinter.scala | 8 ++++---- library/src/scala/tasty/util/TreeAccumulator.scala | 6 +++--- library/src/scala/tasty/util/TreeTraverser.scala | 6 +++--- tests/pos/tasty/definitions.scala | 11 +++++------ tests/run/tasty-extractors-owners/quoted_1.scala | 2 +- 7 files changed, 25 insertions(+), 31 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index 9afff553a488..b9488b1968c9 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -51,12 +51,9 @@ object TastyImpl extends scala.tasty.Tasty { // ===== Trees ==================================================== + type Tree = tpd.Tree - // ----- Top Level Statements ----------------------------------------------- - - type TopLevelStatement = tpd.Tree - - implicit def TopLevelStatementDeco(t: TopLevelStatement): AbstractTopLevelStatement = new AbstractTopLevelStatement { + implicit def TreeDeco(t: Tree): AbstractTree = new AbstractTree { def pos(implicit ctx: Context): Position = new TastyPosition(t.pos) } @@ -65,7 +62,7 @@ object TastyImpl extends scala.tasty.Tasty { def packageClauseClassTag: ClassTag[PackageClause] = implicitly[ClassTag[PackageClause]] val PackageClause: PackageClauseExtractor = new PackageClauseExtractor { - def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[TopLevelStatement])] = x match { + def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[Tree])] = x match { case x: tpd.PackageDef @unchecked => Some((x.pid, x.stats)) case _ => None } diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index 2c5bf830b722..9a3237c76b13 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -41,20 +41,18 @@ abstract class Tasty { // ===== Trees ==================================================== - // ----- Top Level Statements ----------------------------------------------- + type Tree - type TopLevelStatement + trait AbstractTree extends Positioned + implicit def TreeDeco(t: Tree): AbstractTree - trait AbstractTopLevelStatement extends Positioned - implicit def TopLevelStatementDeco(t: TopLevelStatement): AbstractTopLevelStatement - - type PackageClause <: TopLevelStatement + type PackageClause <: Tree implicit def packageClauseClassTag: ClassTag[PackageClause] val PackageClause: PackageClauseExtractor abstract class PackageClauseExtractor { - def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[TopLevelStatement])] + def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[Tree])] } trait AbstractPackageClause { @@ -64,7 +62,7 @@ abstract class Tasty { // ----- Statements ----------------------------------------------- - type Statement <: TopLevelStatement + type Statement <: Tree type Import <: Statement diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index 33a8639af3ae..bfe7b5986a29 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -4,7 +4,7 @@ import scala.tasty.Tasty object TastyPrinter { - def stringOfTree(tasty: Tasty)(tree: tasty.TopLevelStatement)(implicit ctx: tasty.Context): String = { + def stringOfTree(tasty: Tasty)(tree: tasty.Tree)(implicit ctx: tasty.Context): String = { implicit val buff: StringBuilder = new StringBuilder visitTree(tasty)(tree) buff.toString() @@ -34,7 +34,7 @@ object TastyPrinter { buff.toString() } - private def visitTree(tasty: Tasty)(x: tasty.TopLevelStatement)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitTree(tasty: Tasty)(x: tasty.Tree)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { import tasty._ x match { case Ident(name) => @@ -274,12 +274,12 @@ object TastyPrinter { } } - private def visitTrees(tasty: Tasty)(list: List[tasty.TopLevelStatement])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitTrees(tasty: Tasty)(list: List[tasty.Tree])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { list match { case x0 :: xs => buff append "List(" visitTree(tasty)(x0) - def visitNext(xs: List[tasty.TopLevelStatement]): Unit = xs match { + def visitNext(xs: List[tasty.Tree]): Unit = xs match { case y :: ys => buff append ", " visitTree(tasty)(y) diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index d1b7a36a40b1..524eedea0b15 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -6,19 +6,19 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { import tasty._ // Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node. - def foldTree(x: X, tree: TopLevelStatement)(implicit ctx: Context): X + def foldTree(x: X, tree: Tree)(implicit ctx: Context): X def foldTypeTree(x: X, tree: MaybeTypeTree)(implicit ctx: Context): X def foldCaseDef(x: X, tree: CaseDef)(implicit ctx: Context): X def foldPattern(x: X, tree: Pattern)(implicit ctx: Context): X def foldParent(x: X, tree: Parent)(implicit ctx: Context): X - def foldTree(x: X, trees: Traversable[TopLevelStatement])(implicit ctx: Context): X = (x /: trees)(foldTree) + def foldTree(x: X, trees: Traversable[Tree])(implicit ctx: Context): X = (x /: trees)(foldTree) def foldTypeTree(x: X, trees: Traversable[MaybeTypeTree])(implicit ctx: Context): X = (x /: trees)(foldTypeTree) def foldCaseDef(x: X, trees: Traversable[CaseDef])(implicit ctx: Context): X = (x /: trees)(foldCaseDef) def foldPattern(x: X, trees: Traversable[Pattern])(implicit ctx: Context): X = (x /: trees)(foldPattern) def foldParent(x: X, trees: Traversable[Parent])(implicit ctx: Context): X = (x /: trees)(foldParent) - def foldOverTree(x: X, tree: TopLevelStatement)(implicit ctx: Context): X = { + def foldOverTree(x: X, tree: Tree)(implicit ctx: Context): X = { def localCtx(definition: Definition): Context = definition.localContext tree match { case Ident(_) => diff --git a/library/src/scala/tasty/util/TreeTraverser.scala b/library/src/scala/tasty/util/TreeTraverser.scala index 62ce209a982b..bdad4e9991f7 100644 --- a/library/src/scala/tasty/util/TreeTraverser.scala +++ b/library/src/scala/tasty/util/TreeTraverser.scala @@ -5,19 +5,19 @@ import scala.tasty.Tasty abstract class TreeTraverser[T <: Tasty with Singleton](tasty0: T) extends TreeAccumulator[Unit, T](tasty0) { import tasty._ - def traverseTree(tree: TopLevelStatement)(implicit ctx: Context): Unit = traverseTreeChildren(tree) + def traverseTree(tree: Tree)(implicit ctx: Context): Unit = traverseTreeChildren(tree) def traverseTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): Unit = traverseTypeTreeChildren(tree) def traverseCaseDef(tree: CaseDef)(implicit ctx: Context): Unit = traverseCaseDef(tree) def traversePattern(tree: Pattern)(implicit ctx: Context): Unit = traversePatternChildren(tree) def traverseParent(tree: Parent)(implicit ctx: Context): Unit = traverseParentChildren(tree) - def foldTree(x: Unit, tree: TopLevelStatement)(implicit ctx: Context): Unit = traverseTree(tree) + def foldTree(x: Unit, tree: Tree)(implicit ctx: Context): Unit = traverseTree(tree) def foldTypeTree(x: Unit, tree: MaybeTypeTree)(implicit ctx: Context) = traverseTypeTree(tree) def foldCaseDef(x: Unit, tree: CaseDef)(implicit ctx: Context) = traverseCaseDef(tree) def foldPattern(x: Unit, tree: Pattern)(implicit ctx: Context) = traversePattern(tree) def foldParent(x: Unit, tree: Parent)(implicit ctx: Context) = traverseParent(tree) - protected def traverseTreeChildren(tree: TopLevelStatement)(implicit ctx: Context): Unit = foldOverTree((), tree) + protected def traverseTreeChildren(tree: Tree)(implicit ctx: Context): Unit = foldOverTree((), tree) protected def traverseTypeTreeChildren(tree: MaybeTypeTree)(implicit ctx: Context): Unit = foldOverTypeTree((), tree) protected def traverseCaseDefChildren(tree: CaseDef)(implicit ctx: Context): Unit = foldOverCaseDef((), tree) protected def traversePatternChildren(tree: Pattern)(implicit ctx: Context): Unit = foldOverPattern((), tree) diff --git a/tests/pos/tasty/definitions.scala b/tests/pos/tasty/definitions.scala index dd98ffadcd33..f51ed91f3182 100644 --- a/tests/pos/tasty/definitions.scala +++ b/tests/pos/tasty/definitions.scala @@ -4,14 +4,13 @@ object definitions { // ====== Trees ====================================== - trait Tree extends Positioned + sealed trait Tree // Top level statement // ------ Statements --------------------------------- - sealed trait TopLevelStatement extends Tree - sealed trait Statement extends TopLevelStatement + sealed trait Statement extends Tree - case class PackageClause(pkg: Term, body: List[TopLevelStatement]) extends TopLevelStatement + case class PackageClause(pkg: Term, body: List[Tree]) extends Tree case class Import(expr: Term, selector: List[ImportSelector]) extends Statement @@ -82,7 +81,7 @@ object definitions { } /** Trees denoting types */ - enum TypeTree extends Tree { + enum TypeTree extends Positioned { def tpe: Type = ??? case Synthetic() case Ident(name: String, override val tpe: Type) @@ -102,7 +101,7 @@ object definitions { } /** Trees denoting patterns */ - enum Pattern extends Tree { + enum Pattern extends Positioned { def tpe: Type = ??? case Value(v: Term) case Bind(name: String, pat: Pattern) diff --git a/tests/run/tasty-extractors-owners/quoted_1.scala b/tests/run/tasty-extractors-owners/quoted_1.scala index 93baa403a06c..1808af14a31b 100644 --- a/tests/run/tasty-extractors-owners/quoted_1.scala +++ b/tests/run/tasty-extractors-owners/quoted_1.scala @@ -18,7 +18,7 @@ object Macros { val printer = new TreeTraverser(u.tasty) { import tasty._ - override def traverseTree(tree: TopLevelStatement)(implicit ctx: Context): Unit = { + override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = { tree match { case tree @ DefDef(name, _, _, _, _) => buff.append(name) From 5b51f3ffd63132fbd5f3ac5802e3b98bb97d86ae Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 8 May 2018 16:10:11 +0200 Subject: [PATCH 05/21] Add Valuable test case --- tests/run/tasty-eval.check | 5 ++++ tests/run/tasty-eval/quoted_1.scala | 36 +++++++++++++++++++++++++++++ tests/run/tasty-eval/quoted_2.scala | 14 +++++++++++ 3 files changed, 55 insertions(+) create mode 100644 tests/run/tasty-eval.check create mode 100644 tests/run/tasty-eval/quoted_1.scala create mode 100644 tests/run/tasty-eval/quoted_2.scala diff --git a/tests/run/tasty-eval.check b/tests/run/tasty-eval.check new file mode 100644 index 000000000000..4866bcf63c1b --- /dev/null +++ b/tests/run/tasty-eval.check @@ -0,0 +1,5 @@ +Some(1) +Some(8) +Some(5) +Some(6) +None diff --git a/tests/run/tasty-eval/quoted_1.scala b/tests/run/tasty-eval/quoted_1.scala new file mode 100644 index 000000000000..c00a13445145 --- /dev/null +++ b/tests/run/tasty-eval/quoted_1.scala @@ -0,0 +1,36 @@ +import scala.quoted._ + +import scala.tasty.Universe +import scala.tasty.util.{TastyPrinter, TreeTraverser} + +object Macros { + + implicit inline def foo(i: Int): String = + ~impl('(i))(Universe.compilationUniverse) // FIXME infer Universe.compilationUniverse within top level ~ + + def impl(i: Expr[Int])(implicit u: Universe): Expr[String] = { + value(i).toString.toExpr + } + + inline implicit def value[X](e: Expr[X])(implicit u: Universe, ev: Valuable[X]): Option[X] = ev.value(e) + + trait Valuable[X] { + def value(e: Expr[X])(implicit u: Universe): Option[X] + } + + implicit def intIsEvalable: Valuable[Int] = new Valuable[Int] { + override def value(e: Expr[Int])(implicit u: Universe): Option[Int] = { + import u._ + import u.tasty._ + e.toTasty.tpe match { + case SymRef(ValDef(_, tpt, _), pre) => + tpt.tpe match { + case ConstantType(IntConstant(i)) => Some(i) + case _ => None + } + case ConstantType(IntConstant(i)) => Some(i) + case _ => None + } + } + } +} diff --git a/tests/run/tasty-eval/quoted_2.scala b/tests/run/tasty-eval/quoted_2.scala new file mode 100644 index 000000000000..208bcca87708 --- /dev/null +++ b/tests/run/tasty-eval/quoted_2.scala @@ -0,0 +1,14 @@ + +import Macros._ + +object Test { + def main(args: Array[String]): Unit = { + println(foo(1)) // "Some(1)" + println(foo(1 + 7)) // "Some(8)" + final val y = 5 + println(foo(y)) // "Some(5)" + println(foo(y + 1)) + val x = 4 + println(foo(x)) // "None" + } +} From 7a9ae29cfa51c9855eeba9a18930a1f7cf176c57 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 8 May 2018 17:17:20 +0200 Subject: [PATCH 06/21] Cleanup Tasty instance passed to Tastyprinter --- .../src/scala/tasty/util/TastyPrinter.scala | 931 +++++++++--------- tests/run/tasty-extractors-1/quoted_1.scala | 5 +- tests/run/tasty-extractors-2/quoted_1.scala | 5 +- tests/run/tasty-extractors-3/quoted_1.scala | 4 +- .../tasty-extractors-owners/quoted_1.scala | 9 +- .../run/tasty-extractors-types/quoted_1.scala | 5 +- 6 files changed, 473 insertions(+), 486 deletions(-) diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index bfe7b5986a29..24134d6fbf8f 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -2,287 +2,285 @@ package scala.tasty.util import scala.tasty.Tasty -object TastyPrinter { +class TastyPrinter[T <: Tasty with Singleton](tasty: T) { + import tasty._ - def stringOfTree(tasty: Tasty)(tree: tasty.Tree)(implicit ctx: tasty.Context): String = { + def stringOfTree(tree: Tree)(implicit ctx: Context): String = { implicit val buff: StringBuilder = new StringBuilder - visitTree(tasty)(tree) + visitTree(tree) buff.toString() } - def stringOfTypeTree(tasty: Tasty)(tree: tasty.MaybeTypeTree)(implicit ctx: tasty.Context): String = { + def stringOfTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): String = { implicit val buff: StringBuilder = new StringBuilder - visitTypeTree(tasty)(tree) + visitTypeTree(tree) buff.toString() } - def stringOfType(tasty: Tasty)(tpe: tasty.MaybeType)(implicit ctx: tasty.Context): String = { + def stringOfType(tpe: MaybeType)(implicit ctx: Context): String = { implicit val buff: StringBuilder = new StringBuilder - visitType(tasty)(tpe) + visitType(tpe) buff.toString() } - def stringOfModifier(tasty: Tasty)(mod: tasty.Modifier)(implicit ctx: tasty.Context): String = { + def stringOfModifier(mod: Modifier)(implicit ctx: Context): String = { implicit val buff: StringBuilder = new StringBuilder - visitModifier(tasty)(mod) + visitModifier(mod) buff.toString() } - def stringOfConstant(tasty: Tasty)(mod: tasty.Constant)(implicit ctx: tasty.Context): String = { + def stringOfConstant(mod: Constant)(implicit ctx: Context): String = { implicit val buff: StringBuilder = new StringBuilder - visitConstant(tasty)(mod) + visitConstant(mod) buff.toString() } - private def visitTree(tasty: Tasty)(x: tasty.Tree)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { - import tasty._ - x match { - case Ident(name) => - buff append "Ident(" append name append ")" - case Select(qualifier, name, signature) => - buff append "Select(" - visitTree(tasty)(qualifier) - buff append ", " append name append ", " - signature match { - case Some(sig) => - val Signature(params, res) = sig - buff append "Some(Signature(" - if (params.isEmpty) buff append "Nil" - else buff append params - buff append ", " append res append "))" - case None => buff append "None" - } - buff append ")" - case This(qual) => - buff append "This(" - qual match { - case Some(id) => - buff append "Some(" - visitId(tasty)(id) - buff append ")" - case None => buff append "None" - } - buff append ")" - case Super(qual, mix) => - buff append "TypeApply(" - visitTree(tasty)(qual) - buff append ", " - mix match { - case Some(id) => - buff append "Some(" - visitId(tasty)(id) - buff append ")" - case None => buff append "None" - } - buff append ")" - case Apply(fun, args) => - buff append "Apply(" - visitTree(tasty)(fun) - buff append ", " - visitTrees(tasty)(args) - buff append ")" - case TypeApply(fun, args) => - buff append "TypeApply(" - visitTree(tasty)(fun) - buff append ", " - visitTypeTrees(tasty)(args) - buff append ")" - case Literal(const) => - buff append "Literal(" - visitConstant(tasty)(const) - buff append ")" - case New(tpt) => - buff append "New(" - visitTypeTree(tasty)(tpt) - buff append ")" - case Typed(expr, tpt) => - buff append "Typed(" - visitTree(tasty)(expr) - buff append ", " - visitTypeTree(tasty)(tpt) - buff append ")" - case NamedArg(name, arg) => - buff append "NamedArg(" append name append ", " - visitTree(tasty)(arg) - buff append ")" - case Assign(lhs, rhs) => - buff append "Assign(" - visitTree(tasty)(lhs) - buff append ", " - visitTree(tasty)(rhs) - buff append ")" - case Block(stats, expr) => - buff append "Block(" - visitTrees(tasty)(stats) - buff append ", " - visitTree(tasty)(expr) - buff append ")" - case If(cond, thenp, elsep) => - buff append "If(" - visitTree(tasty)(cond) - buff append ", " - visitTree(tasty)(thenp) - buff append ", " - visitTree(tasty)(elsep) - buff append ")" - case Lambda(meth, tpt) => - buff append "Lambda(" - visitTree(tasty)(meth) - buff append ", " - tpt match { - case Some(tree) => - buff append "Some(" - visitTypeTree(tasty)(tree) - buff append ")" - case _ => buff append "None" - } - buff append ")" - case Match(selector, cases) => - buff append "Match(" - visitTree(tasty)(selector) - buff append ", " - visitCaseDefs(tasty)(cases) - buff append ")" - case Return(expr) => - buff append "Return(" - visitTree(tasty)(expr) - buff append ")" - case Try(block, handlers, finalizer) => - buff append "Try(" - visitTree(tasty)(block) - buff append ", " - visitCaseDefs(tasty)(handlers) - buff append ", " - finalizer match { - case Some(tree) => - buff append "Some(" - visitTree(tasty)(tree) - buff append ")" - case _ => buff append "None" - } - buff append ")" - case Repeated(elems) => - buff append "Repeated(" - visitTrees(tasty)(elems) - buff append ")" - case Inlined(call, bindings, expansion) => - buff append "Inlined(" - visitTree(tasty)(call) - buff append ", " - visitTrees(tasty)(bindings) - buff append ", " - visitTree(tasty)(expansion) - buff append ")" - case ValDef(name, tpt, rhs) => - buff append "ValDef(" append name append ", " - visitTypeTree(tasty)(tpt) - buff append ", " - rhs match { - case Some(tree) => - buff append "Some(" - visitTree(tasty)(tree) - buff append ")" - case _ => buff append "None" - } - buff append ")" - case DefDef(name, typeParams, paramss, returnTpt, rhs) => - buff append "DefDef(" append name append ", " - visitTrees(tasty)(typeParams) - buff append ", " - paramss match { - case x0 :: xs => - buff append "List(" - visitTrees(tasty)(x0) - def visitNext(xs: List[List[tasty.ValDef]]): Unit = xs match { - case y :: ys => - buff append ", " - visitTrees(tasty)(y) - visitNext(ys) - case Nil => - } - visitNext(xs) - buff append ")" - case Nil => buff append "Nil" - } - buff append ", " - visitTypeTree(tasty)(returnTpt) - buff append ", " - rhs match { - case Some(tree) => - buff append "Some(" - visitTree(tasty)(tree) - buff append ")" - case None => buff append "None" - } - buff append ")" - case TypeDef(name, rhs) => - buff append "TypeDef(" append name append ", " - visitTypeTree(tasty)(rhs) - buff append ")" - case ClassDef(name, constr, parents, self, body) => - buff append "ClassDef(" append name append ", " - visitTree(tasty)(constr) - buff append ", " - visitParents(tasty)(parents) - buff append ", " - self match { - case Some(tree) => - buff append "Some(" - visitTree(tasty)(tree) - buff append ")" - case _ => buff append "None" - } - buff append ", " - visitTrees(tasty)(body) - buff append ")" - case PackageDef(name, members) => - buff append "PackageDef(" - buff append name - buff append ", " - visitTrees(tasty)(members) - buff append ")" - case Import(expr, selectors) => - buff append "Import(" - visitTree(tasty)(expr) - buff append ", " + private def visitTree(x: Tree)(implicit buff: StringBuilder, ctx: Context): Unit = x match { + case Ident(name) => + buff append "Ident(" append name append ")" + case Select(qualifier, name, signature) => + buff append "Select(" + visitTree(qualifier) + buff append ", " append name append ", " + signature match { + case Some(sig) => + val Signature(params, res) = sig + buff append "Some(Signature(" + if (params.isEmpty) buff append "Nil" + else buff append params + buff append ", " append res append "))" + case None => buff append "None" + } + buff append ")" + case This(qual) => + buff append "This(" + qual match { + case Some(id) => + buff append "Some(" + visitId(id) + buff append ")" + case None => buff append "None" + } + buff append ")" + case Super(qual, mix) => + buff append "TypeApply(" + visitTree(qual) + buff append ", " + mix match { + case Some(id) => + buff append "Some(" + visitId(id) + buff append ")" + case None => buff append "None" + } + buff append ")" + case Apply(fun, args) => + buff append "Apply(" + visitTree(fun) + buff append ", " + visitTrees(args) + buff append ")" + case TypeApply(fun, args) => + buff append "TypeApply(" + visitTree(fun) + buff append ", " + visitTypeTrees(args) + buff append ")" + case Literal(const) => + buff append "Literal(" + visitConstant(const) + buff append ")" + case New(tpt) => + buff append "New(" + visitTypeTree(tpt) + buff append ")" + case Typed(expr, tpt) => + buff append "Typed(" + visitTree(expr) + buff append ", " + visitTypeTree(tpt) + buff append ")" + case NamedArg(name, arg) => + buff append "NamedArg(" append name append ", " + visitTree(arg) + buff append ")" + case Assign(lhs, rhs) => + buff append "Assign(" + visitTree(lhs) + buff append ", " + visitTree(rhs) + buff append ")" + case Block(stats, expr) => + buff append "Block(" + visitTrees(stats) + buff append ", " + visitTree(expr) + buff append ")" + case If(cond, thenp, elsep) => + buff append "If(" + visitTree(cond) + buff append ", " + visitTree(thenp) + buff append ", " + visitTree(elsep) + buff append ")" + case Lambda(meth, tpt) => + buff append "Lambda(" + visitTree(meth) + buff append ", " + tpt match { + case Some(tree) => + buff append "Some(" + visitTypeTree(tree) + buff append ")" + case _ => buff append "None" + } + buff append ")" + case Match(selector, cases) => + buff append "Match(" + visitTree(selector) + buff append ", " + visitCaseDefs(cases) + buff append ")" + case Return(expr) => + buff append "Return(" + visitTree(expr) + buff append ")" + case Try(block, handlers, finalizer) => + buff append "Try(" + visitTree(block) + buff append ", " + visitCaseDefs(handlers) + buff append ", " + finalizer match { + case Some(tree) => + buff append "Some(" + visitTree(tree) + buff append ")" + case _ => buff append "None" + } + buff append ")" + case Repeated(elems) => + buff append "Repeated(" + visitTrees(elems) + buff append ")" + case Inlined(call, bindings, expansion) => + buff append "Inlined(" + visitTree(call) + buff append ", " + visitTrees(bindings) + buff append ", " + visitTree(expansion) + buff append ")" + case ValDef(name, tpt, rhs) => + buff append "ValDef(" append name append ", " + visitTypeTree(tpt) + buff append ", " + rhs match { + case Some(tree) => + buff append "Some(" + visitTree(tree) + buff append ")" + case _ => buff append "None" + } + buff append ")" + case DefDef(name, typeParams, paramss, returnTpt, rhs) => + buff append "DefDef(" append name append ", " + visitTrees(typeParams) + buff append ", " + paramss match { + case x0 :: xs => + buff append "List(" + visitTrees(x0) + def visitNext(xs: List[List[ValDef]]): Unit = xs match { + case y :: ys => + buff append ", " + visitTrees(y) + visitNext(ys) + case Nil => + } + visitNext(xs) + buff append ")" + case Nil => buff append "Nil" + } + buff append ", " + visitTypeTree(returnTpt) + buff append ", " + rhs match { + case Some(tree) => + buff append "Some(" + visitTree(tree) + buff append ")" + case None => buff append "None" + } + buff append ")" + case TypeDef(name, rhs) => + buff append "TypeDef(" append name append ", " + visitTypeTree(rhs) + buff append ")" + case ClassDef(name, constr, parents, self, body) => + buff append "ClassDef(" append name append ", " + visitTree(constr) + buff append ", " + visitParents(parents) + buff append ", " + self match { + case Some(tree) => + buff append "Some(" + visitTree(tree) + buff append ")" + case _ => buff append "None" + } + buff append ", " + visitTrees(body) + buff append ")" + case PackageDef(name, members) => + buff append "PackageDef(" + buff append name + buff append ", " + visitTrees(members) + buff append ")" + case Import(expr, selectors) => + buff append "Import(" + visitTree(expr) + buff append ", " - buff append "List(" - selectors.foreach { - case SimpleSelector(id) => - buff append "SimpleSelector(" - visitId(tasty)(id) - buff append ")" - case RenameSelector(id1, id2) => - buff append "RenameSelector(" - visitId(tasty)(id1) - buff append ", " - visitId(tasty)(id2) - buff append ")" - case OmitSelector(id) => - buff append "OmitSelector(" - visitId(tasty)(id) - buff append ")" - } - buff append ")" - buff append ")" - case PackageClause(pid, stats) => - buff append "PackageClause(" - visitTree(tasty)(pid) - buff append ", " - visitTrees(tasty)(stats) - buff append ")" - } + buff append "List(" + selectors.foreach { + case SimpleSelector(id) => + buff append "SimpleSelector(" + visitId(id) + buff append ")" + case RenameSelector(id1, id2) => + buff append "RenameSelector(" + visitId(id1) + buff append ", " + visitId(id2) + buff append ")" + case OmitSelector(id) => + buff append "OmitSelector(" + visitId(id) + buff append ")" + } + buff append ")" + buff append ")" + case PackageClause(pid, stats) => + buff append "PackageClause(" + visitTree(pid) + buff append ", " + visitTrees(stats) + buff append ")" } - private def visitTrees(tasty: Tasty)(list: List[tasty.Tree])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitTrees(list: List[Tree])(implicit buff: StringBuilder, ctx: Context): Unit = { list match { case x0 :: xs => buff append "List(" - visitTree(tasty)(x0) - def visitNext(xs: List[tasty.Tree]): Unit = xs match { + visitTree(x0) + def visitNext(xs: List[Tree]): Unit = xs match { case y :: ys => buff append ", " - visitTree(tasty)(y) + visitTree(y) visitNext(ys) case Nil => } @@ -292,8 +290,7 @@ object TastyPrinter { } } - private def visitTypeTree(tasty: Tasty)(x: tasty.MaybeTypeTree)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { - import tasty._ + private def visitTypeTree(x: MaybeTypeTree)(implicit buff: StringBuilder, ctx: Context): Unit = { x match { case Synthetic() => buff append "Synthetic()" @@ -301,64 +298,64 @@ object TastyPrinter { buff append "TypeIdent(" append name append ")" case TypeSelect(qualifier, name) => buff append "TypeSelect(" - visitTree(tasty)(qualifier) + visitTree(qualifier) buff append ", " append name append ")" case Singleton(ref) => buff append "Singleton(" - visitTree(tasty)(ref) + visitTree(ref) buff append ")" case And(left, right) => buff append "And(" - visitTypeTree(tasty)(left) + visitTypeTree(left) buff append ", " - visitTypeTree(tasty)(right) + visitTypeTree(right) buff append ")" case Or(left, right) => buff append "Or(" - visitTypeTree(tasty)(left) + visitTypeTree(left) buff append ", " - visitTypeTree(tasty)(right) + visitTypeTree(right) buff append ")" case Refined(tpt, refinements) => buff append "Refined(" - visitTypeTree(tasty)(tpt) + visitTypeTree(tpt) buff append ", " - visitTrees(tasty)(refinements) + visitTrees(refinements) buff append ")" case Applied(tpt, args) => buff append "Applied(" - visitTypeTree(tasty)(tpt) + visitTypeTree(tpt) buff append ", " - visitTypeTrees(tasty)(args) + visitTypeTrees(args) buff append ")" case ByName(result) => buff append "ByName(" - visitTypeTree(tasty)(result) + visitTypeTree(result) buff append ")" case Annotated(arg, annot) => buff append "Annotated(" - visitTypeTree(tasty)(arg) + visitTypeTree(arg) buff append ", " - visitTree(tasty)(annot) + visitTree(annot) buff append ")" case TypeBoundsTree(lo, hi) => buff append "TypeBoundsTree(" - visitTypeTree(tasty)(lo) + visitTypeTree(lo) buff append ", " - visitTypeTree(tasty)(hi) + visitTypeTree(hi) buff append ")" } } - private def visitTypeTrees(tasty: Tasty)(list: List[tasty.TypeTree])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitTypeTrees(list: List[TypeTree])(implicit buff: StringBuilder, ctx: Context): Unit = { list match { case x0 :: xs => buff append "List(" - visitTypeTree(tasty)(x0) - def visitNext(xs: List[tasty.TypeTree]): Unit = xs match { + visitTypeTree(x0) + def visitNext(xs: List[TypeTree]): Unit = xs match { case y :: ys => buff append ", " - visitTypeTree(tasty)(y) + visitTypeTree(y) visitNext(ys) case Nil => } @@ -368,36 +365,35 @@ object TastyPrinter { } } - private def visitCaseDef(tasty: Tasty)(x: tasty.CaseDef)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { - import tasty._ + private def visitCaseDef(x: CaseDef)(implicit buff: StringBuilder, ctx: Context): Unit = { x match { case CaseDef(pat, guard, body) => buff append "CaseDef(" - visitPattern(tasty)(pat) + visitPattern(pat) buff append ", " guard match { case Some(tree) => buff append "Some(" - visitTree(tasty)(guard.get) + visitTree(guard.get) buff append ")" case None => buff append "None" } buff append ", " - visitTree(tasty)(body) + visitTree(body) buff append ")" } } - private def visitCaseDefs(tasty: Tasty)(list: List[tasty.CaseDef])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitCaseDefs(list: List[CaseDef])(implicit buff: StringBuilder, ctx: Context): Unit = { list match { case x0 :: xs => buff append "List(" - visitCaseDef(tasty)(x0) - def visitNext(xs: List[tasty.CaseDef]): Unit = xs match { + visitCaseDef(x0) + def visitNext(xs: List[CaseDef]): Unit = xs match { case y :: ys => buff append ", " - visitCaseDef(tasty)(y) + visitCaseDef(y) visitNext(ys) case Nil => } @@ -407,45 +403,42 @@ object TastyPrinter { } } - private def visitPattern(tasty: Tasty)(x: tasty.Pattern)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { - import tasty._ - x match { - case Value(v) => - buff append "Value(" - visitTree(tasty)(v) - buff append ")" - case Bind(name, body) => - buff append "Bind(" append name append ", " - visitPattern(tasty)(body) - buff append ")" - case Unapply(fun, implicits, patterns) => - buff append "Unapply(" - visitTree(tasty)(fun) - buff append ", " - visitTrees(tasty)(implicits) - buff append ", " - visitPatterns(tasty)(patterns) - buff append ")" - case Alternative(patterns) => - buff append "Alternative(" - visitPatterns(tasty)(patterns) - buff append ")" - case TypeTest(tpt) => - buff append "TypeTest(" - visitTypeTree(tasty)(tpt) - buff append ")" - } + private def visitPattern(x: Pattern)(implicit buff: StringBuilder, ctx: Context): Unit = x match { + case Value(v) => + buff append "Value(" + visitTree(v) + buff append ")" + case Bind(name, body) => + buff append "Bind(" append name append ", " + visitPattern(body) + buff append ")" + case Unapply(fun, implicits, patterns) => + buff append "Unapply(" + visitTree(fun) + buff append ", " + visitTrees(implicits) + buff append ", " + visitPatterns(patterns) + buff append ")" + case Alternative(patterns) => + buff append "Alternative(" + visitPatterns(patterns) + buff append ")" + case TypeTest(tpt) => + buff append "TypeTest(" + visitTypeTree(tpt) + buff append ")" } - private def visitPatterns(tasty: Tasty)(list: List[tasty.Pattern])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitPatterns(list: List[Pattern])(implicit buff: StringBuilder, ctx: Context): Unit = { list match { case x0 :: xs => buff append "List(" - visitPattern(tasty)(x0) - def visitNext(xs: List[tasty.Pattern]): Unit = xs match { + visitPattern(x0) + def visitNext(xs: List[Pattern]): Unit = xs match { case y :: ys => buff append ", " - visitPattern(tasty)(y) + visitPattern(y) visitNext(ys) case Nil => } @@ -455,141 +448,135 @@ object TastyPrinter { } } - private def visitConstant(tasty: Tasty)(x: tasty.Constant)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { - import tasty._ - x match { - case UnitConstant() => buff append "Unit()" - case NullConstant() => buff append "Null()" - case BooleanConstant(value) => buff append "Boolean(" append value append ")" - case ByteConstant(value) => buff append "Byte(" append value append ")" - case ShortConstant(value) => buff append "Short(" append value append ")" - case CharConstant(value) => buff append "Char(" append value append ")" - case IntConstant(value) => buff append "Int(" append value append ")" - case LongConstant(value) => buff append "Long(" append value append ")" - case FloatConstant(value) => buff append "Float(" append value append ")" - case DoubleConstant(value) => buff append "Double(" append value append ")" - case StringConstant(value) => buff append "String(" append value append ")" - } + private def visitConstant(x: Constant)(implicit buff: StringBuilder, ctx: Context): Unit = x match { + case UnitConstant() => buff append "Unit()" + case NullConstant() => buff append "Null()" + case BooleanConstant(value) => buff append "Boolean(" append value append ")" + case ByteConstant(value) => buff append "Byte(" append value append ")" + case ShortConstant(value) => buff append "Short(" append value append ")" + case CharConstant(value) => buff append "Char(" append value append ")" + case IntConstant(value) => buff append "Int(" append value append ")" + case LongConstant(value) => buff append "Long(" append value append ")" + case FloatConstant(value) => buff append "Float(" append value append ")" + case DoubleConstant(value) => buff append "Double(" append value append ")" + case StringConstant(value) => buff append "String(" append value append ")" } - private def visitType(tasty: Tasty)(x: tasty.MaybeType)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { - import tasty._ - x match { - case ConstantType(value) => - buff append "ConstantType(" - visitConstant(tasty)(value) - buff append ")" - case SymRef(sym, qual) => - def visitName(sym: Definition): Unit = sym match { - case ValDef(name, _, _) => buff append name - case DefDef(name, _, _, _, _) => buff append name - case TypeDef(name, _) => buff append name - case ClassDef(name, _, _, _, _) => buff append name - case PackageDef(name, _) => buff append name - case _ => buff append "#" - } - buff append "SymRef(" - visitName(sym) - buff append ", " - visitType(tasty)(qual) - buff append ")" - case NameRef(name, qual) => - buff append "NameRef(" append name append ", " - visitType(tasty)(qual) - buff append ")" - case Refinement(parent, name, info) => - buff append "Refinement(" - visitType(tasty)(parent) - buff append ", " append name append ", " - visitType(tasty)(info) - buff append ")" - case AppliedType(tycon, args) => - buff append "AppliedType(" - visitType(tasty)(tycon) - buff append ", " - visitTypes(tasty)(args) - buff append ")" - case AnnotatedType(underlying, annot) => - buff append "AnnotatedType(" - visitType(tasty)(underlying) - buff append ", " - visitTree(tasty)(annot) - buff append ")" - case AndType(left, right) => - buff append "AndType(" - visitType(tasty)(left) - buff append ", " - visitType(tasty)(right) - buff append ")" - case OrType(left, right) => - buff append "OrType(" - visitType(tasty)(left) - buff append ", " - visitType(tasty)(right) - buff append ")" - case ByNameType(underlying) => - buff append "ByNameType(" - visitType(tasty)(underlying) - buff append ")" - case ParamRef(binder, idx) => - buff append "ParamRef(" - visitType(tasty)(binder) - buff append ", " append idx append ")" - case ThisType(tp) => - buff append "ThisType(" - visitType(tasty)(tp) - buff append ")" - case RecursiveThis(binder) => - buff append "RecursiveThis(" - visitType(tasty)(binder) - buff append ")" - case MethodType(argNames, argTypes, resType) => - buff append "MethodType(" - if (argNames.isEmpty) buff append "Nil" - else buff append argNames - buff append ", " - visitTypes(tasty)(argTypes) - buff append ", " - visitType(tasty)(resType) - buff append ")" - case PolyType(argNames, argBounds, resType) => - buff append "PolyType(" - if (argNames.isEmpty) buff append "Nil" - else buff append argNames - buff append ", " - visitTypes(tasty)(argBounds) - buff append ", " - visitType(tasty)(resType) - buff append ")" - case TypeLambda(argNames, argBounds, resType) => - buff append "TypeLambda(" - if (argNames.isEmpty) buff append "Nil" - else buff append argNames - buff append ", " - visitTypes(tasty)(argBounds) - buff append ", " - visitType(tasty)(resType) - buff append ")" - case TypeBounds(lo, hi) => - buff append "TypeBounds(" - visitType(tasty)(lo) - buff append ", " - visitType(tasty)(hi) - buff append ")" - case NoPrefix() => - buff append "NoPrefix" - } + private def visitType(x: MaybeType)(implicit buff: StringBuilder, ctx: Context): Unit = x match { + case ConstantType(value) => + buff append "ConstantType(" + visitConstant(value) + buff append ")" + case SymRef(sym, qual) => + def visitName(sym: Definition): Unit = sym match { + case ValDef(name, _, _) => buff append name + case DefDef(name, _, _, _, _) => buff append name + case TypeDef(name, _) => buff append name + case ClassDef(name, _, _, _, _) => buff append name + case PackageDef(name, _) => buff append name + case _ => buff append "#" + } + buff append "SymRef(" + visitName(sym) + buff append ", " + visitType(qual) + buff append ")" + case NameRef(name, qual) => + buff append "NameRef(" append name append ", " + visitType(qual) + buff append ")" + case Refinement(parent, name, info) => + buff append "Refinement(" + visitType(parent) + buff append ", " append name append ", " + visitType(info) + buff append ")" + case AppliedType(tycon, args) => + buff append "AppliedType(" + visitType(tycon) + buff append ", " + visitTypes(args) + buff append ")" + case AnnotatedType(underlying, annot) => + buff append "AnnotatedType(" + visitType(underlying) + buff append ", " + visitTree(annot) + buff append ")" + case AndType(left, right) => + buff append "AndType(" + visitType(left) + buff append ", " + visitType(right) + buff append ")" + case OrType(left, right) => + buff append "OrType(" + visitType(left) + buff append ", " + visitType(right) + buff append ")" + case ByNameType(underlying) => + buff append "ByNameType(" + visitType(underlying) + buff append ")" + case ParamRef(binder, idx) => + buff append "ParamRef(" + visitType(binder) + buff append ", " append idx append ")" + case ThisType(tp) => + buff append "ThisType(" + visitType(tp) + buff append ")" + case RecursiveThis(binder) => + buff append "RecursiveThis(" + visitType(binder) + buff append ")" + case MethodType(argNames, argTypes, resType) => + buff append "MethodType(" + if (argNames.isEmpty) buff append "Nil" + else buff append argNames + buff append ", " + visitTypes(argTypes) + buff append ", " + visitType(resType) + buff append ")" + case PolyType(argNames, argBounds, resType) => + buff append "PolyType(" + if (argNames.isEmpty) buff append "Nil" + else buff append argNames + buff append ", " + visitTypes(argBounds) + buff append ", " + visitType(resType) + buff append ")" + case TypeLambda(argNames, argBounds, resType) => + buff append "TypeLambda(" + if (argNames.isEmpty) buff append "Nil" + else buff append argNames + buff append ", " + visitTypes(argBounds) + buff append ", " + visitType(resType) + buff append ")" + case TypeBounds(lo, hi) => + buff append "TypeBounds(" + visitType(lo) + buff append ", " + visitType(hi) + buff append ")" + case NoPrefix() => + buff append "NoPrefix" } - private def visitTypes(tasty: Tasty)(list: List[tasty.MaybeType])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitTypes(list: List[MaybeType])(implicit buff: StringBuilder, ctx: Context): Unit = { list match { case x0 :: xs => buff append "List(" - visitType(tasty)(x0) - def visitNext(xs: List[tasty.MaybeType]): Unit = xs match { + visitType(x0) + def visitNext(xs: List[MaybeType]): Unit = xs match { case y :: ys => buff append ", " - visitType(tasty)(y) + visitType(y) visitNext(ys) case Nil => } @@ -599,49 +586,43 @@ object TastyPrinter { } } - private def visitModifier(tasty: Tasty)(x: tasty.Modifier)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { - import tasty._ - x match { - case Flags(flags) => - buff append "Flags(" append flags append ")" - case QualifiedPrivate(tp) => - buff append "QualifiedPrivate(" - visitType(tasty)(tp) - buff append ")" - case QualifiedProtected(tp) => - buff append "QualifiedProtected(" - visitType(tasty)(tp) - buff append ")" - case Annotation(tree) => - buff append "Annotation(" - visitTree(tasty)(tree) - buff append ")" - } + private def visitModifier(x: Modifier)(implicit buff: StringBuilder, ctx: Context): Unit = x match { + case Flags(flags) => + buff append "Flags(" append flags append ")" + case QualifiedPrivate(tp) => + buff append "QualifiedPrivate(" + visitType(tp) + buff append ")" + case QualifiedProtected(tp) => + buff append "QualifiedProtected(" + visitType(tp) + buff append ")" + case Annotation(tree) => + buff append "Annotation(" + visitTree(tree) + buff append ")" } - private def visitParent(tasty: Tasty)(x: tasty.Parent)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { - import tasty._ - x match { - case TermParent(term) => - buff append "TermParent(" - visitTree(tasty)(term) - buff append ")" - case TypeParent(typeTree) => - buff append "TypeParent(" - visitTypeTree(tasty)(typeTree) - buff append ")" - } + private def visitParent(x: Parent)(implicit buff: StringBuilder, ctx: Context): Unit = x match { + case TermParent(term) => + buff append "TermParent(" + visitTree(term) + buff append ")" + case TypeParent(typeTree) => + buff append "TypeParent(" + visitTypeTree(typeTree) + buff append ")" } - private def visitParents(tasty: Tasty)(list: List[tasty.Parent])(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitParents(list: List[Parent])(implicit buff: StringBuilder, ctx: Context): Unit = { list match { case x0 :: xs => buff append "List(" - visitParent(tasty)(x0) - def visitNext(xs: List[tasty.Parent]): Unit = xs match { + visitParent(x0) + def visitNext(xs: List[Parent]): Unit = xs match { case y :: ys => buff append ", " - visitParent(tasty)(y) + visitParent(y) visitNext(ys) case Nil => } @@ -651,7 +632,7 @@ object TastyPrinter { } } - private def visitId(tasty: Tasty)(x: tasty.Id)(implicit buff: StringBuilder, ctx: tasty.Context): Unit = { + private def visitId(x: Id)(implicit buff: StringBuilder, ctx: Context): Unit = { import tasty._ x match { case Id(name) => buff append "Id(" append name append ")" diff --git a/tests/run/tasty-extractors-1/quoted_1.scala b/tests/run/tasty-extractors-1/quoted_1.scala index da81b4040641..c1055a1dcabe 100644 --- a/tests/run/tasty-extractors-1/quoted_1.scala +++ b/tests/run/tasty-extractors-1/quoted_1.scala @@ -13,8 +13,9 @@ object Macros { import u._ import tasty._ val tree = x.toTasty - val treeStr = TastyPrinter.stringOfTree(tasty)(tree) - val treeTpeStr = TastyPrinter.stringOfType(tasty)(tree.tpe) + val printer = new TastyPrinter(tasty) + val treeStr = printer.stringOfTree(tree) + val treeTpeStr = printer.stringOfType(tree.tpe) '{ println(~treeStr.toExpr) diff --git a/tests/run/tasty-extractors-2/quoted_1.scala b/tests/run/tasty-extractors-2/quoted_1.scala index da81b4040641..c1055a1dcabe 100644 --- a/tests/run/tasty-extractors-2/quoted_1.scala +++ b/tests/run/tasty-extractors-2/quoted_1.scala @@ -13,8 +13,9 @@ object Macros { import u._ import tasty._ val tree = x.toTasty - val treeStr = TastyPrinter.stringOfTree(tasty)(tree) - val treeTpeStr = TastyPrinter.stringOfType(tasty)(tree.tpe) + val printer = new TastyPrinter(tasty) + val treeStr = printer.stringOfTree(tree) + val treeTpeStr = printer.stringOfType(tree.tpe) '{ println(~treeStr.toExpr) diff --git a/tests/run/tasty-extractors-3/quoted_1.scala b/tests/run/tasty-extractors-3/quoted_1.scala index 935e02374b64..7dfc3c3ea0f7 100644 --- a/tests/run/tasty-extractors-3/quoted_1.scala +++ b/tests/run/tasty-extractors-3/quoted_1.scala @@ -13,10 +13,12 @@ object Macros { import u._ import u.tasty._ + val printer = new TastyPrinter(tasty) + val buff = new StringBuilder val traverser = new TreeTraverser(u.tasty) { override def traverseTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): Unit = { - buff.append(TastyPrinter.stringOfType(u.tasty)(tree.tpe)) + buff.append(printer.stringOfType(tree.tpe)) buff.append("\n\n") traverseTypeTreeChildren(tree) } diff --git a/tests/run/tasty-extractors-owners/quoted_1.scala b/tests/run/tasty-extractors-owners/quoted_1.scala index 1808af14a31b..10d2260401c8 100644 --- a/tests/run/tasty-extractors-owners/quoted_1.scala +++ b/tests/run/tasty-extractors-owners/quoted_1.scala @@ -13,22 +13,23 @@ object Macros { def impl[T](x: Expr[T])(implicit u: Universe): Expr[Unit] = { import u._ import u.tasty._ + val printer = new TastyPrinter(tasty) val buff = new StringBuilder - val printer = new TreeTraverser(u.tasty) { + val output = new TreeTraverser(u.tasty) { import tasty._ override def traverseTree(tree: Tree)(implicit ctx: Context): Unit = { tree match { case tree @ DefDef(name, _, _, _, _) => buff.append(name) buff.append("\n") - buff.append(TastyPrinter.stringOfTree(tasty)(tree.owner)) + buff.append(printer.stringOfTree(tree.owner)) buff.append("\n\n") case tree @ ValDef(name, _, _) => buff.append(name) buff.append("\n") - buff.append(TastyPrinter.stringOfTree(tasty)(tree.owner)) + buff.append(printer.stringOfTree(tree.owner)) buff.append("\n\n") case _ => } @@ -37,7 +38,7 @@ object Macros { } val tree = x.toTasty - printer.traverseTree(tree) + output.traverseTree(tree) '(print(~buff.result().toExpr)) } diff --git a/tests/run/tasty-extractors-types/quoted_1.scala b/tests/run/tasty-extractors-types/quoted_1.scala index 953a425741e7..198e6bc7f604 100644 --- a/tests/run/tasty-extractors-types/quoted_1.scala +++ b/tests/run/tasty-extractors-types/quoted_1.scala @@ -13,9 +13,10 @@ object Macros { import u._ import u.tasty._ val tree = x.toTasty + val printer = new TastyPrinter(tasty) '{ - println(~TastyPrinter.stringOfTypeTree(u.tasty)(tree).toExpr) - println(~TastyPrinter.stringOfType(u.tasty)(tree.tpe).toExpr) + println(~printer.stringOfTypeTree(tree).toExpr) + println(~printer.stringOfType(tree.tpe).toExpr) println() } } From 3faa1f4e90b86bab365d1586074ea0be56d03332 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 8 May 2018 19:16:54 +0200 Subject: [PATCH 07/21] Fix private path dependent type --- library/src/scala/tasty/util/TastyPrinter.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index 24134d6fbf8f..ecb02107ca70 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -2,7 +2,7 @@ package scala.tasty.util import scala.tasty.Tasty -class TastyPrinter[T <: Tasty with Singleton](tasty: T) { +class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { import tasty._ def stringOfTree(tree: Tree)(implicit ctx: Context): String = { From 92e7e59a48111f05b735eb0c1f2d78b91553ee62 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 8 May 2018 19:18:29 +0200 Subject: [PATCH 08/21] Fix tasty printer --- tests/run/tasty-macro-assert/quoted_1.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/run/tasty-macro-assert/quoted_1.scala b/tests/run/tasty-macro-assert/quoted_1.scala index dcfa4ee7e2c8..e4011cdccb26 100644 --- a/tests/run/tasty-macro-assert/quoted_1.scala +++ b/tests/run/tasty-macro-assert/quoted_1.scala @@ -38,8 +38,9 @@ object Asserts { tree match { case Apply(Select(OpsTree(left), op, _), right :: Nil) => // FIXME splice the threes directly - val lExpr = TastyPrinter.stringOfTree(tasty)(left).toExpr - val rExpr = TastyPrinter.stringOfTree(tasty)(right).toExpr + val printer = new TastyPrinter(tasty) + val lExpr = printer.stringOfTree(left).toExpr + val rExpr = printer.stringOfTree(right).toExpr op match { case "===" => '(assertEquals(~lExpr, ~rExpr)) case "!==" => '(assertNotEquals(~lExpr, ~rExpr)) From 85ed79644321dd54c72a4393b7f70a10cc1ec43e Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 9 May 2018 14:15:59 +0200 Subject: [PATCH 09/21] Add indexed map test and couple of fixes * Remove type vars from tasty types * Fix impure by name arguments to macros --- .../dotty/tools/dotc/tasty/TastyImpl.scala | 22 ++++---- library/src/scala/tasty/Tasty.scala | 4 +- tests/run/tasty-indexed-map/quoted_1.scala | 50 +++++++++++++++++++ tests/run/tasty-indexed-map/quoted_2.scala | 18 +++++++ 4 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 tests/run/tasty-indexed-map/quoted_1.scala create mode 100644 tests/run/tasty-indexed-map/quoted_2.scala diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index b9488b1968c9..b24fbe78e271 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -231,7 +231,7 @@ object TastyImpl extends scala.tasty.Tasty { implicit def TermDeco(t: Term): AbstractTerm = new AbstractTerm { def pos(implicit ctx: Context): Position = new TastyPosition(t.pos) - def tpe: Types.Type = t.tpe + def tpe(implicit ctx: Context): Types.Type = t.tpe } def termClassTag: ClassTag[Term] = implicitly[ClassTag[Term]] @@ -378,7 +378,7 @@ object TastyImpl extends scala.tasty.Tasty { def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] = x match { case x: tpd.Select @unchecked => x.name match { - case NameKinds.OuterSelectName(_, levels) => Some((x.qualifier, levels, x.tpe)) + case NameKinds.OuterSelectName(_, levels) => Some((x.qualifier, levels, x.tpe.stripTypeVar)) case _ => None } case _ => None @@ -405,7 +405,7 @@ object TastyImpl extends scala.tasty.Tasty { implicit def PatternDeco(x: Pattern): AbstractPattern = new AbstractPattern { def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) - def tpe: Types.Type = x.tpe + def tpe(implicit ctx: Context): Types.Type = x.tpe.stripTypeVar } def patternClassTag: ClassTag[Pattern] = implicitly[ClassTag[Pattern]] @@ -451,7 +451,7 @@ object TastyImpl extends scala.tasty.Tasty { type MaybeTypeTree = tpd.Tree implicit def MaybeTypeTreeDeco(x: MaybeTypeTree): AbstractMaybeTypeTree = new AbstractMaybeTypeTree { - def tpe: Type = x.tpe + def tpe(implicit ctx: Context): Type = x.tpe.stripTypeVar } // ----- TypeTrees ------------------------------------------------ @@ -462,7 +462,7 @@ object TastyImpl extends scala.tasty.Tasty { implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree = new AbstractTypeTree { def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) - def tpe: Types.Type = x.tpe + def tpe(implicit ctx: Context): Types.Type = x.tpe.stripTypeVar } val Synthetic: SyntheticExtractor = new SyntheticExtractor { @@ -605,35 +605,35 @@ object TastyImpl extends scala.tasty.Tasty { val AppliedType: AppliedTypeExtractor = new AppliedTypeExtractor { def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[MaybeType /* Type | TypeBounds */])] = x match { - case Types.AppliedType(tycon, args) => Some((tycon, args)) + case Types.AppliedType(tycon, args) => Some((tycon.stripTypeVar, args.map(_.stripTypeVar))) case _ => None } } val AnnotatedType: AnnotatedTypeExtractor = new AnnotatedTypeExtractor { def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] = x match { - case Types.AnnotatedType(underlying, annot) => Some((underlying, annot.tree)) + case Types.AnnotatedType(underlying, annot) => Some((underlying.stripTypeVar, annot.tree)) case _ => None } } val AndType: AndTypeExtractor = new AndTypeExtractor { def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { - case Types.AndType(left, right) => Some(left, right) + case Types.AndType(left, right) => Some(left.stripTypeVar, right.stripTypeVar) case _ => None } } val OrType: OrTypeExtractor = new OrTypeExtractor { def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { - case Types.OrType(left, right) => Some(left, right) + case Types.OrType(left, right) => Some(left.stripTypeVar, right.stripTypeVar) case _ => None } } val ByNameType: ByNameTypeExtractor = new ByNameTypeExtractor { def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { - case Types.ExprType(resType) => Some(resType) + case Types.ExprType(resType) => Some(resType.stripTypeVar) case _ => None } } @@ -668,7 +668,7 @@ object TastyImpl extends scala.tasty.Tasty { val RecursiveType: RecursiveTypeExtractor = new RecursiveTypeExtractor { def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] = x match { - case tp: Types.RecType => Some(tp.underlying) + case tp: Types.RecType => Some(tp.underlying.stripTypeVar) case _ => None } } diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index 9a3237c76b13..a072e7a3dcd5 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -335,7 +335,7 @@ abstract class Tasty { type MaybeTypeTree trait AbstractMaybeTypeTree { - def tpe: MaybeType + def tpe(implicit ctx: Context): MaybeType } implicit def MaybeTypeTreeDeco(x: MaybeTypeTree): AbstractMaybeTypeTree @@ -420,7 +420,7 @@ abstract class Tasty { type MaybeType trait Typed { - def tpe: Type + def tpe(implicit ctx: Context): Type } // ----- Types ---------------------------------------------------- diff --git a/tests/run/tasty-indexed-map/quoted_1.scala b/tests/run/tasty-indexed-map/quoted_1.scala new file mode 100644 index 000000000000..c5e4e1807790 --- /dev/null +++ b/tests/run/tasty-indexed-map/quoted_1.scala @@ -0,0 +1,50 @@ + +import scala.quoted._ + +import scala.tasty.Universe +import scala.tasty.util.TastyPrinter + +class MyMap[Keys](private val underlying: Array[Int]) extends AnyVal { + def get[K <: String](implicit i: Index[K, Keys]): Int = underlying(i.index) + def set[K <: String](value: Int)(implicit i: Index[K, Keys]): Unit = underlying(i.index) = value +} + +object MyMap { + def create[Keys](implicit s: Size[Keys]): MyMap[Keys] = new MyMap[Keys](new Array[Int](s.size)) +} + +trait Size[Keys] { def size: Int } +object Size { + def apply[Keys](v: Int): Size[Keys] = new Size { def size = v } + implicit val unit: Size[Unit] = Size(0) + implicit def cons[H, T](implicit s: Size[T]): Size[(H, T)] = Size(s.size + 1) +} + +class Index[K, Keys](val index: Int) extends AnyVal +object Index { + + implicit def zero[K, T]: Index[K, (K, T)] = new Index(0) + + implicit inline def succ[K, H, T](implicit prev: => Index[K, T]): Index[K, (H, T)] = ~succImpl(Universe.compilationUniverse)('[K], '[H], '[T]) + + def succImpl[K, H, T](u: Universe)(implicit k: Type[K], h: Type[H], t: Type[T]): Expr[Index[K, (H, T)]] = { + import u._ + import u.tasty._ + + def name(tp: MaybeType): String = tp match { + case ConstantType(StringConstant(str)) => str + } + + def names(tp: MaybeType): List[String] = tp match { + case AppliedType(_, x1 :: x2 :: Nil) => name(x1) :: names(x2) + case _ => Nil + } + + val key = name(k.toTasty.tpe) + val keys = name(h.toTasty.tpe) :: names(t.toTasty.tpe) + + val index = keys.indexOf(key) + + '(new Index(~index.toExpr)) + } +} diff --git a/tests/run/tasty-indexed-map/quoted_2.scala b/tests/run/tasty-indexed-map/quoted_2.scala new file mode 100644 index 000000000000..3392cef7a281 --- /dev/null +++ b/tests/run/tasty-indexed-map/quoted_2.scala @@ -0,0 +1,18 @@ +object Test { + + def main(args: Array[String]): Unit = { + val map = MyMap.create[("foo", ("bar", ("baz", Unit)))] + + map.set["foo"](9) + assert(map.get["foo"] == 9) + + map.set["bar"](42) + assert(map.get["bar"] == 42) + + map.set["baz"](42) + assert(map.get["baz"] == 42) + +// map.set["banana"](42) // error +// assert(map.get["banana"] == 42) // error + } +} \ No newline at end of file From 9f9b64a55c260b96143caf09a6f5505cd43f96d5 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 07:40:36 +0200 Subject: [PATCH 10/21] Use Iterable and rename folds on trees --- .../scala/tasty/util/TreeAccumulator.scala | 42 +++++++++---------- .../src/scala/tasty/util/TreeTraverser.scala | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index 524eedea0b15..8799f1075bec 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -12,11 +12,11 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { def foldPattern(x: X, tree: Pattern)(implicit ctx: Context): X def foldParent(x: X, tree: Parent)(implicit ctx: Context): X - def foldTree(x: X, trees: Traversable[Tree])(implicit ctx: Context): X = (x /: trees)(foldTree) - def foldTypeTree(x: X, trees: Traversable[MaybeTypeTree])(implicit ctx: Context): X = (x /: trees)(foldTypeTree) - def foldCaseDef(x: X, trees: Traversable[CaseDef])(implicit ctx: Context): X = (x /: trees)(foldCaseDef) - def foldPattern(x: X, trees: Traversable[Pattern])(implicit ctx: Context): X = (x /: trees)(foldPattern) - def foldParent(x: X, trees: Traversable[Parent])(implicit ctx: Context): X = (x /: trees)(foldParent) + def foldTrees(x: X, trees: Iterable[Tree])(implicit ctx: Context): X = (x /: trees)(foldTree) + def foldTypeTrees(x: X, trees: Iterable[MaybeTypeTree])(implicit ctx: Context): X = (x /: trees)(foldTypeTree) + def foldCaseDefs(x: X, trees: Iterable[CaseDef])(implicit ctx: Context): X = (x /: trees)(foldCaseDef) + def foldPatterns(x: X, trees: Iterable[Pattern])(implicit ctx: Context): X = (x /: trees)(foldPattern) + def foldParents(x: X, trees: Iterable[Parent])(implicit ctx: Context): X = (x /: trees)(foldParent) def foldOverTree(x: X, tree: Tree)(implicit ctx: Context): X = { def localCtx(definition: Definition): Context = definition.localContext @@ -30,9 +30,9 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { case Super(qual, _) => foldTree(x, qual) case Apply(fun, args) => - foldTree(foldTree(x, fun), args) + foldTrees(foldTree(x, fun), args) case TypeApply(fun, args) => - foldTypeTree(foldTree(x, fun), args) + foldTypeTrees(foldTree(x, fun), args) case Literal(const) => x case New(tpt) => @@ -44,39 +44,39 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { case Assign(lhs, rhs) => foldTree(foldTree(x, lhs), rhs) case Block(stats, expr) => - foldTree(foldTree(x, stats), expr) + foldTree(foldTrees(x, stats), expr) case If(cond, thenp, elsep) => foldTree(foldTree(foldTree(x, cond), thenp), elsep) case Lambda(meth, tpt) => val a = foldTree(x, meth) tpt.fold(a)(b => foldTypeTree(a, b)) case Match(selector, cases) => - foldCaseDef(foldTree(x, selector), cases) + foldCaseDefs(foldTree(x, selector), cases) case Return(expr) => foldTree(x, expr) case Try(block, handler, finalizer) => - foldTree(foldCaseDef(foldTree(x, block), handler), finalizer) + foldTrees(foldCaseDefs(foldTree(x, block), handler), finalizer) case Repeated(elems) => - foldTree(x, elems) + foldTrees(x, elems) case Inlined(call, bindings, expansion) => - foldTree(foldTree(x, bindings), expansion) + foldTree(foldTrees(x, bindings), expansion) case vdef @ ValDef(_, tpt, rhs) => implicit val ctx = localCtx(vdef) - foldTree(foldTypeTree(x, tpt), rhs) + foldTrees(foldTypeTree(x, tpt), rhs) case ddef @ DefDef(_, tparams, vparamss, tpt, rhs) => implicit val ctx = localCtx(ddef) - foldTree(foldTypeTree((foldTree(x, tparams) /: vparamss)(foldTree), tpt), rhs) + foldTrees(foldTypeTree((foldTrees(x, tparams) /: vparamss)(foldTrees), tpt), rhs) case tdef @ TypeDef(_, rhs) => implicit val ctx = localCtx(tdef) foldTypeTree(x, rhs) case cdef @ ClassDef(_, constr, parents, self, body) => implicit val ctx = localCtx(cdef) - foldTree(foldTree(foldParent(foldTree(x, constr), parents), self), body) + foldTrees(foldTrees(foldParents(foldTree(x, constr), parents), self), body) case Import(expr, selectors) => foldTree(x, expr) case clause @ PackageClause(pid, stats) => - foldTree(foldTree(x, pid), stats)(localCtx(clause.definition)) + foldTrees(foldTree(x, pid), stats)(localCtx(clause.definition)) } } @@ -87,22 +87,22 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { case Singleton(ref) => foldTree(x, ref) case And(left, right) => foldTypeTree(foldTypeTree(x, left), right) case Or(left, right) => foldTypeTree(foldTypeTree(x, left), right) - case Refined(tpt, refinements) => foldTree(foldTypeTree(x, tpt), refinements) - case Applied(tpt, args) => foldTypeTree(foldTypeTree(x, tpt), args) + case Refined(tpt, refinements) => foldTrees(foldTypeTree(x, tpt), refinements) + case Applied(tpt, args) => foldTypeTrees(foldTypeTree(x, tpt), args) case ByName(result) => foldTypeTree(x, result) case Annotated(arg, annot) => foldTree(foldTypeTree(x, arg), annot) case TypeBoundsTree(lo, hi) => foldTypeTree(foldTypeTree(x, lo), hi) } def foldOverCaseDef(x: X, tree: CaseDef)(implicit ctx: Context): X = tree match { - case CaseDef(pat, guard, body) => foldTree(foldTree(foldPattern(x, pat), guard), body) + case CaseDef(pat, guard, body) => foldTree(foldTrees(foldPattern(x, pat), guard), body) } def foldOverPattern(x: X, tree: Pattern)(implicit ctx: Context): X = tree match { case Value(v) => foldTree(x, v) case Bind(_, body) => foldPattern(x, body) - case Unapply(fun, implicits, patterns) => foldPattern(foldTree(foldTree(x, fun), implicits), patterns) - case Alternative(patterns) => foldPattern(x, patterns) + case Unapply(fun, implicits, patterns) => foldPatterns(foldTrees(foldTree(x, fun), implicits), patterns) + case Alternative(patterns) => foldPatterns(x, patterns) case TypeTest(tpt) => foldTypeTree(x, tpt) } diff --git a/library/src/scala/tasty/util/TreeTraverser.scala b/library/src/scala/tasty/util/TreeTraverser.scala index bdad4e9991f7..d6e11c52013c 100644 --- a/library/src/scala/tasty/util/TreeTraverser.scala +++ b/library/src/scala/tasty/util/TreeTraverser.scala @@ -7,7 +7,7 @@ abstract class TreeTraverser[T <: Tasty with Singleton](tasty0: T) extends TreeA def traverseTree(tree: Tree)(implicit ctx: Context): Unit = traverseTreeChildren(tree) def traverseTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): Unit = traverseTypeTreeChildren(tree) - def traverseCaseDef(tree: CaseDef)(implicit ctx: Context): Unit = traverseCaseDef(tree) + def traverseCaseDef(tree: CaseDef)(implicit ctx: Context): Unit = traverseCaseDefChildren(tree) def traversePattern(tree: Pattern)(implicit ctx: Context): Unit = traversePatternChildren(tree) def traverseParent(tree: Parent)(implicit ctx: Context): Unit = traverseParentChildren(tree) From aeba19d4008b65730635470753d97231f27245da Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 07:49:21 +0200 Subject: [PATCH 11/21] Rename MaybeType to TypeOrBounds --- .../dotty/tools/dotc/tasty/TastyImpl.scala | 24 ++++++------- library/src/scala/tasty/Tasty.scala | 34 +++++++++---------- .../src/scala/tasty/util/TastyPrinter.scala | 12 +++---- .../scala/tasty/util/TreeAccumulator.scala | 6 ++-- .../src/scala/tasty/util/TreeTraverser.scala | 6 ++-- tests/run/tasty-extractors-3/quoted_1.scala | 2 +- tests/run/tasty-indexed-map/quoted_1.scala | 4 +-- tests/run/tasty-macro-assert/quoted_1.scala | 2 +- 8 files changed, 45 insertions(+), 45 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index b24fbe78e271..f1aa5d30f2e1 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -186,7 +186,7 @@ object TastyImpl extends scala.tasty.Tasty { def typeDefClassTag: ClassTag[TypeDef] = implicitly[ClassTag[TypeDef]] val TypeDef: TypeDefExtractor = new TypeDefExtractor { - def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, MaybeTypeTree /* TypeTree | TypeBoundsTree */)] = x match { + def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, TypeOrBoundsTree /* TypeTree | TypeBoundsTree */)] = x match { case x: tpd.TypeDef @unchecked if !x.symbol.isClass => Some((x.name.toString, x.rhs)) case _ => None } @@ -446,11 +446,11 @@ object TastyImpl extends scala.tasty.Tasty { } } - // ----- MaybeTypeTree ------------------------------------------------ + // ----- TypeOrBoundsTree ------------------------------------------------ - type MaybeTypeTree = tpd.Tree + type TypeOrBoundsTree = tpd.Tree - implicit def MaybeTypeTreeDeco(x: MaybeTypeTree): AbstractMaybeTypeTree = new AbstractMaybeTypeTree { + implicit def TypeOrBoundsTreeDeco(x: TypeOrBoundsTree): AbstractTypeOrBoundsTree = new AbstractTypeOrBoundsTree { def tpe(implicit ctx: Context): Type = x.tpe.stripTypeVar } @@ -552,7 +552,7 @@ object TastyImpl extends scala.tasty.Tasty { // ===== Types ==================================================== - type MaybeType = Types.Type + type TypeOrBounds = Types.Type // ----- Types ---------------------------------------------------- @@ -568,7 +568,7 @@ object TastyImpl extends scala.tasty.Tasty { } val SymRef: SymRefExtractor = new SymRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Definition, MaybeType /* Type | NoPrefix */)] = x match { + def unapply(x: Type)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] = x match { case tp: Types.NamedType => tp.designator match { case sym: Symbol => Some((FromSymbol.definition(sym), tp.prefix)) @@ -579,7 +579,7 @@ object TastyImpl extends scala.tasty.Tasty { } val NameRef: NameRefExtractor = new NameRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(String, MaybeType /* Type | NoPrefix */)] = x match { + def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] = x match { case tp: Types.NamedType => tp.designator match { case name: Names.Name => Some(name.toString, tp.prefix) @@ -597,14 +597,14 @@ object TastyImpl extends scala.tasty.Tasty { } val Refinement: RefinementExtractor = new RefinementExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, MaybeType /* Type | TypeBounds */)] = x match { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, TypeOrBounds /* Type | TypeBounds */)] = x match { case Types.RefinedType(parent, name, info) => Some(parent, name.toString, info) case _ => None } } val AppliedType: AppliedTypeExtractor = new AppliedTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[MaybeType /* Type | TypeBounds */])] = x match { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] = x match { case Types.AppliedType(tycon, args) => Some((tycon.stripTypeVar, args.map(_.stripTypeVar))) case _ => None } @@ -639,10 +639,10 @@ object TastyImpl extends scala.tasty.Tasty { } val ParamRef: ParamRefExtractor = new ParamRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[MaybeType], Int)] = x match { + def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] = x match { case Types.TypeParamRef(binder, idx) => Some(( - binder.asInstanceOf[LambdaType[MaybeType]], // Cast to tpd + binder.asInstanceOf[LambdaType[TypeOrBounds]], // Cast to tpd idx)) case _ => None } @@ -675,7 +675,7 @@ object TastyImpl extends scala.tasty.Tasty { // ----- Methodic Types ------------------------------------------- - type LambdaType[ParamInfo <: MaybeType] = Types.LambdaType { type PInfo = ParamInfo } + type LambdaType[ParamInfo <: TypeOrBounds] = Types.LambdaType { type PInfo = ParamInfo } type MethodType = Types.MethodType diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index a072e7a3dcd5..ef400c697b9e 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -146,7 +146,7 @@ abstract class Tasty { val TypeDef: TypeDefExtractor abstract class TypeDefExtractor { - def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, MaybeTypeTree /* TypeTree | TypeBoundsTree */)] + def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, TypeOrBoundsTree /* TypeTree | TypeBoundsTree */)] } // PackageDef @@ -332,17 +332,17 @@ abstract class Tasty { // ----- TypeTrees ------------------------------------------------ - type MaybeTypeTree + type TypeOrBoundsTree - trait AbstractMaybeTypeTree { - def tpe(implicit ctx: Context): MaybeType + trait AbstractTypeOrBoundsTree { + def tpe(implicit ctx: Context): TypeOrBounds } - implicit def MaybeTypeTreeDeco(x: MaybeTypeTree): AbstractMaybeTypeTree + implicit def TypeOrBoundsTreeDeco(x: TypeOrBoundsTree): AbstractTypeOrBoundsTree // ----- TypeTrees ------------------------------------------------ - type TypeTree <: MaybeTypeTree + type TypeTree <: TypeOrBoundsTree trait AbstractTypeTree extends Typed with Positioned implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree @@ -401,7 +401,7 @@ abstract class Tasty { // ----- TypeBoundsTrees ------------------------------------------------ - type TypeBoundsTree <: MaybeTypeTree + type TypeBoundsTree <: TypeOrBoundsTree trait AbstractTypeBoundsTree { def tpe: TypeBounds @@ -417,7 +417,7 @@ abstract class Tasty { // ===== Types ==================================================== - type MaybeType + type TypeOrBounds trait Typed { def tpe(implicit ctx: Context): Type @@ -425,7 +425,7 @@ abstract class Tasty { // ----- Types ---------------------------------------------------- - type Type <: MaybeType + type Type <: TypeOrBounds implicit def typeClassTag: ClassTag[Type] @@ -436,12 +436,12 @@ abstract class Tasty { val SymRef: SymRefExtractor abstract class SymRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Definition, MaybeType /* Type | NoPrefix */)] + def unapply(x: Type)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] } val NameRef: NameRefExtractor abstract class NameRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(String, MaybeType /* Type | NoPrefix */)] + def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] } val SuperType: SuperTypeExtractor @@ -451,12 +451,12 @@ abstract class Tasty { val Refinement: RefinementExtractor abstract class RefinementExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, MaybeType /* Type | TypeBounds */)] + def unapply(x: Type)(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[MaybeType /* Type | TypeBounds */])] + def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] } val AnnotatedType: AnnotatedTypeExtractor @@ -481,7 +481,7 @@ abstract class Tasty { val ParamRef: ParamRefExtractor abstract class ParamRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[MaybeType], Int)] + def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] } val ThisType: ThisTypeExtractor @@ -503,7 +503,7 @@ abstract class Tasty { // ----- Methodic Types ------------------------------------------- - type LambdaType[ParamInfo <: MaybeType] <: Type + type LambdaType[ParamInfo <: TypeOrBounds] <: Type type MethodType <: LambdaType[Type] @@ -540,7 +540,7 @@ abstract class Tasty { // ----- TypeBounds ----------------------------------------------- - type TypeBounds <: MaybeType + type TypeBounds <: TypeOrBounds implicit def typeBoundsClassTag: ClassTag[TypeBounds] @@ -551,7 +551,7 @@ abstract class Tasty { // ----- NoPrefix ------------------------------------------------- - type NoPrefix <: MaybeType + type NoPrefix <: TypeOrBounds implicit def noPrefixClassTag: ClassTag[NoPrefix] diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index ecb02107ca70..c7251db83935 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -11,13 +11,13 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { buff.toString() } - def stringOfTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): String = { + def stringOfTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): String = { implicit val buff: StringBuilder = new StringBuilder visitTypeTree(tree) buff.toString() } - def stringOfType(tpe: MaybeType)(implicit ctx: Context): String = { + def stringOfType(tpe: TypeOrBounds)(implicit ctx: Context): String = { implicit val buff: StringBuilder = new StringBuilder visitType(tpe) buff.toString() @@ -290,7 +290,7 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { } } - private def visitTypeTree(x: MaybeTypeTree)(implicit buff: StringBuilder, ctx: Context): Unit = { + private def visitTypeTree(x: TypeOrBoundsTree)(implicit buff: StringBuilder, ctx: Context): Unit = { x match { case Synthetic() => buff append "Synthetic()" @@ -462,7 +462,7 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { case StringConstant(value) => buff append "String(" append value append ")" } - private def visitType(x: MaybeType)(implicit buff: StringBuilder, ctx: Context): Unit = x match { + private def visitType(x: TypeOrBounds)(implicit buff: StringBuilder, ctx: Context): Unit = x match { case ConstantType(value) => buff append "ConstantType(" visitConstant(value) @@ -568,12 +568,12 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { buff append "NoPrefix" } - private def visitTypes(list: List[MaybeType])(implicit buff: StringBuilder, ctx: Context): Unit = { + private def visitTypes(list: List[TypeOrBounds])(implicit buff: StringBuilder, ctx: Context): Unit = { list match { case x0 :: xs => buff append "List(" visitType(x0) - def visitNext(xs: List[MaybeType]): Unit = xs match { + def visitNext(xs: List[TypeOrBounds]): Unit = xs match { case y :: ys => buff append ", " visitType(y) diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index 8799f1075bec..1d25358276bc 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -7,13 +7,13 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { // Ties the knot of the traversal: call `foldOver(x, tree))` to dive in the `tree` node. def foldTree(x: X, tree: Tree)(implicit ctx: Context): X - def foldTypeTree(x: X, tree: MaybeTypeTree)(implicit ctx: Context): X + def foldTypeTree(x: X, tree: TypeOrBoundsTree)(implicit ctx: Context): X def foldCaseDef(x: X, tree: CaseDef)(implicit ctx: Context): X def foldPattern(x: X, tree: Pattern)(implicit ctx: Context): X def foldParent(x: X, tree: Parent)(implicit ctx: Context): X def foldTrees(x: X, trees: Iterable[Tree])(implicit ctx: Context): X = (x /: trees)(foldTree) - def foldTypeTrees(x: X, trees: Iterable[MaybeTypeTree])(implicit ctx: Context): X = (x /: trees)(foldTypeTree) + def foldTypeTrees(x: X, trees: Iterable[TypeOrBoundsTree])(implicit ctx: Context): X = (x /: trees)(foldTypeTree) def foldCaseDefs(x: X, trees: Iterable[CaseDef])(implicit ctx: Context): X = (x /: trees)(foldCaseDef) def foldPatterns(x: X, trees: Iterable[Pattern])(implicit ctx: Context): X = (x /: trees)(foldPattern) def foldParents(x: X, trees: Iterable[Parent])(implicit ctx: Context): X = (x /: trees)(foldParent) @@ -80,7 +80,7 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { } } - def foldOverTypeTree(x: X, tree: MaybeTypeTree)(implicit ctx: Context): X = tree match { + def foldOverTypeTree(x: X, tree: TypeOrBoundsTree)(implicit ctx: Context): X = tree match { case Synthetic() => x case TypeIdent(_) => x case TypeSelect(qualifier, _) => foldTree(x, qualifier) diff --git a/library/src/scala/tasty/util/TreeTraverser.scala b/library/src/scala/tasty/util/TreeTraverser.scala index d6e11c52013c..e51387bb2594 100644 --- a/library/src/scala/tasty/util/TreeTraverser.scala +++ b/library/src/scala/tasty/util/TreeTraverser.scala @@ -6,19 +6,19 @@ abstract class TreeTraverser[T <: Tasty with Singleton](tasty0: T) extends TreeA import tasty._ def traverseTree(tree: Tree)(implicit ctx: Context): Unit = traverseTreeChildren(tree) - def traverseTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): Unit = traverseTypeTreeChildren(tree) + def traverseTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): Unit = traverseTypeTreeChildren(tree) def traverseCaseDef(tree: CaseDef)(implicit ctx: Context): Unit = traverseCaseDefChildren(tree) def traversePattern(tree: Pattern)(implicit ctx: Context): Unit = traversePatternChildren(tree) def traverseParent(tree: Parent)(implicit ctx: Context): Unit = traverseParentChildren(tree) def foldTree(x: Unit, tree: Tree)(implicit ctx: Context): Unit = traverseTree(tree) - def foldTypeTree(x: Unit, tree: MaybeTypeTree)(implicit ctx: Context) = traverseTypeTree(tree) + def foldTypeTree(x: Unit, tree: TypeOrBoundsTree)(implicit ctx: Context) = traverseTypeTree(tree) def foldCaseDef(x: Unit, tree: CaseDef)(implicit ctx: Context) = traverseCaseDef(tree) def foldPattern(x: Unit, tree: Pattern)(implicit ctx: Context) = traversePattern(tree) def foldParent(x: Unit, tree: Parent)(implicit ctx: Context) = traverseParent(tree) protected def traverseTreeChildren(tree: Tree)(implicit ctx: Context): Unit = foldOverTree((), tree) - protected def traverseTypeTreeChildren(tree: MaybeTypeTree)(implicit ctx: Context): Unit = foldOverTypeTree((), tree) + protected def traverseTypeTreeChildren(tree: TypeOrBoundsTree)(implicit ctx: Context): Unit = foldOverTypeTree((), tree) protected def traverseCaseDefChildren(tree: CaseDef)(implicit ctx: Context): Unit = foldOverCaseDef((), tree) protected def traversePatternChildren(tree: Pattern)(implicit ctx: Context): Unit = foldOverPattern((), tree) protected def traverseParentChildren(tree: Parent)(implicit ctx: Context): Unit = foldOverParent((), tree) diff --git a/tests/run/tasty-extractors-3/quoted_1.scala b/tests/run/tasty-extractors-3/quoted_1.scala index 7dfc3c3ea0f7..7a3b00f08b71 100644 --- a/tests/run/tasty-extractors-3/quoted_1.scala +++ b/tests/run/tasty-extractors-3/quoted_1.scala @@ -17,7 +17,7 @@ object Macros { val buff = new StringBuilder val traverser = new TreeTraverser(u.tasty) { - override def traverseTypeTree(tree: MaybeTypeTree)(implicit ctx: Context): Unit = { + override def traverseTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): Unit = { buff.append(printer.stringOfType(tree.tpe)) buff.append("\n\n") traverseTypeTreeChildren(tree) diff --git a/tests/run/tasty-indexed-map/quoted_1.scala b/tests/run/tasty-indexed-map/quoted_1.scala index c5e4e1807790..e8c4fa1a056f 100644 --- a/tests/run/tasty-indexed-map/quoted_1.scala +++ b/tests/run/tasty-indexed-map/quoted_1.scala @@ -31,11 +31,11 @@ object Index { import u._ import u.tasty._ - def name(tp: MaybeType): String = tp match { + def name(tp: TypeOrBounds): String = tp match { case ConstantType(StringConstant(str)) => str } - def names(tp: MaybeType): List[String] = tp match { + def names(tp: TypeOrBounds): List[String] = tp match { case AppliedType(_, x1 :: x2 :: Nil) => name(x1) :: names(x2) case _ => Nil } diff --git a/tests/run/tasty-macro-assert/quoted_1.scala b/tests/run/tasty-macro-assert/quoted_1.scala index e4011cdccb26..61cf5f8bbb9f 100644 --- a/tests/run/tasty-macro-assert/quoted_1.scala +++ b/tests/run/tasty-macro-assert/quoted_1.scala @@ -22,7 +22,7 @@ object Asserts { val tree = cond.toTasty - def isOps(tpe: MaybeType): Boolean = tpe match { + def isOps(tpe: TypeOrBounds): Boolean = tpe match { case SymRef(DefDef("Ops", _, _, _, _), _) => true // TODO check that the parent is Asserts case _ => false } From 2166cc25de972db3f44d311da63fdd95a7587b02 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 08:02:37 +0200 Subject: [PATCH 12/21] Split NameRef into TermName and TypeName --- .../src/dotty/tools/dotc/tasty/TastyImpl.scala | 15 +++++++++++++-- library/src/scala/tasty/Tasty.scala | 9 +++++++-- library/src/scala/tasty/util/TastyPrinter.scala | 8 ++++++-- tests/pos/tasty/definitions.scala | 4 ++-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index f1aa5d30f2e1..54438d91607a 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -578,11 +578,22 @@ object TastyImpl extends scala.tasty.Tasty { } } - val NameRef: NameRefExtractor = new NameRefExtractor { + val TermRef: TermRefExtractor = new TermRefExtractor { def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] = x match { case tp: Types.NamedType => tp.designator match { - case name: Names.Name => Some(name.toString, tp.prefix) + case name: Names.TermName => Some(name.toString, tp.prefix) + case _ => None + } + case _ => None + } + } + + val TypeRef: TypeRefExtractor = new TypeRefExtractor { + def unapply(x: Type)(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) case _ => None } case _ => None diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index ef400c697b9e..1d96eeac33fb 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -439,8 +439,13 @@ abstract class Tasty { def unapply(x: Type)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] } - val NameRef: NameRefExtractor - abstract class NameRefExtractor { + val TermRef: TermRefExtractor + abstract class TermRefExtractor { + def unapply(x: Type)(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 */)] } diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index c7251db83935..260341fa6822 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -481,8 +481,12 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { buff append ", " visitType(qual) buff append ")" - case NameRef(name, qual) => - buff append "NameRef(" append name append ", " + case TermRef(name, qual) => + buff append "TermRef(" append name append ", " + visitType(qual) + buff append ")" + case TypeRef(name, qual) => + buff append "TypeRef(" append name append ", " visitType(qual) buff append ")" case Refinement(parent, name, info) => diff --git a/tests/pos/tasty/definitions.scala b/tests/pos/tasty/definitions.scala index f51ed91f3182..d9c42ed1225f 100644 --- a/tests/pos/tasty/definitions.scala +++ b/tests/pos/tasty/definitions.scala @@ -122,8 +122,8 @@ object definitions { case class ConstantType(value: Constant) extends Type case class SymRef(sym: Definition, qualifier: Type | NoPrefix = NoPrefix) extends Type - case class TypeNameRef(name: String, qualifier: Type | NoPrefix = NoPrefix) extends Type // NoPrefix means: select from _root_ - case class TermNameRef(name: String, qualifier: Type | NoPrefix = NoPrefix) extends Type // NoPrefix means: select from _root_ + case class TypeRef(name: String, qualifier: Type | NoPrefix = NoPrefix) extends Type // NoPrefix means: select from _root_ + case class TermRef(name: String, qualifier: Type | NoPrefix = NoPrefix) extends Type // NoPrefix means: select from _root_ case class SuperType(thistp: Type, underlying: Type) extends Type case class Refinement(underlying: Type, name: String, tpe: Type | TypeBounds) extends Type case class AppliedType(tycon: Type, args: List[Type | TypeBounds]) extends Type From f58a4f9727a12a508189c239523c0087b284322b Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 09:56:30 +0200 Subject: [PATCH 13/21] Refactor TastyPrinter --- .../src/scala/tasty/util/TastyPrinter.scala | 844 ++++++------------ tests/run/tasty-extractors-2.check | 2 +- 2 files changed, 254 insertions(+), 592 deletions(-) diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index 260341fa6822..55f13c259df6 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -5,641 +5,303 @@ import scala.tasty.Tasty class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { import tasty._ - def stringOfTree(tree: Tree)(implicit ctx: Context): String = { - implicit val buff: StringBuilder = new StringBuilder - visitTree(tree) - buff.toString() - } + def stringOfTree(tree: Tree)(implicit ctx: Context): String = + new Buffer().visitTree(tree).result() - def stringOfTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): String = { - implicit val buff: StringBuilder = new StringBuilder - visitTypeTree(tree) - buff.toString() - } + def stringOfTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): String = + new Buffer().visitTypeTree(tree).result() - def stringOfType(tpe: TypeOrBounds)(implicit ctx: Context): String = { - implicit val buff: StringBuilder = new StringBuilder - visitType(tpe) - buff.toString() - } + def stringOfType(tpe: TypeOrBounds)(implicit ctx: Context): String = + new Buffer().visitType(tpe).result() - def stringOfModifier(mod: Modifier)(implicit ctx: Context): String = { - implicit val buff: StringBuilder = new StringBuilder - visitModifier(mod) - buff.toString() - } + def stringOfModifier(mod: Modifier)(implicit ctx: Context): String = + new Buffer().visitModifier(mod).result() - def stringOfConstant(mod: Constant)(implicit ctx: Context): String = { - implicit val buff: StringBuilder = new StringBuilder - visitConstant(mod) - buff.toString() - } + def stringOfConstant(const: Constant)(implicit ctx: Context): String = + new Buffer().visitConstant(const).result() - private def visitTree(x: Tree)(implicit buff: StringBuilder, ctx: Context): Unit = x match { - case Ident(name) => - buff append "Ident(" append name append ")" - case Select(qualifier, name, signature) => - buff append "Select(" - visitTree(qualifier) - buff append ", " append name append ", " - signature match { - case Some(sig) => - val Signature(params, res) = sig - buff append "Some(Signature(" - if (params.isEmpty) buff append "Nil" - else buff append params - buff append ", " append res append "))" - case None => buff append "None" - } - buff append ")" - case This(qual) => - buff append "This(" - qual match { - case Some(id) => - buff append "Some(" - visitId(id) - buff append ")" - case None => buff append "None" - } - buff append ")" - case Super(qual, mix) => - buff append "TypeApply(" - visitTree(qual) - buff append ", " - mix match { - case Some(id) => - buff append "Some(" - visitId(id) - buff append ")" - case None => buff append "None" - } - buff append ")" - case Apply(fun, args) => - buff append "Apply(" - visitTree(fun) - buff append ", " - visitTrees(args) - buff append ")" - case TypeApply(fun, args) => - buff append "TypeApply(" - visitTree(fun) - buff append ", " - visitTypeTrees(args) - buff append ")" - case Literal(const) => - buff append "Literal(" - visitConstant(const) - buff append ")" - case New(tpt) => - buff append "New(" - visitTypeTree(tpt) - buff append ")" - case Typed(expr, tpt) => - buff append "Typed(" - visitTree(expr) - buff append ", " - visitTypeTree(tpt) - buff append ")" - case NamedArg(name, arg) => - buff append "NamedArg(" append name append ", " - visitTree(arg) - buff append ")" - case Assign(lhs, rhs) => - buff append "Assign(" - visitTree(lhs) - buff append ", " - visitTree(rhs) - buff append ")" - case Block(stats, expr) => - buff append "Block(" - visitTrees(stats) - buff append ", " - visitTree(expr) - buff append ")" - case If(cond, thenp, elsep) => - buff append "If(" - visitTree(cond) - buff append ", " - visitTree(thenp) - buff append ", " - visitTree(elsep) - buff append ")" - case Lambda(meth, tpt) => - buff append "Lambda(" - visitTree(meth) - buff append ", " - tpt match { - case Some(tree) => - buff append "Some(" - visitTypeTree(tree) - buff append ")" - case _ => buff append "None" - } - buff append ")" - case Match(selector, cases) => - buff append "Match(" - visitTree(selector) - buff append ", " - visitCaseDefs(cases) - buff append ")" - case Return(expr) => - buff append "Return(" - visitTree(expr) - buff append ")" - case Try(block, handlers, finalizer) => - buff append "Try(" - visitTree(block) - buff append ", " - visitCaseDefs(handlers) - buff append ", " - finalizer match { - case Some(tree) => - buff append "Some(" - visitTree(tree) - buff append ")" - case _ => buff append "None" - } - buff append ")" - case Repeated(elems) => - buff append "Repeated(" - visitTrees(elems) - buff append ")" - case Inlined(call, bindings, expansion) => - buff append "Inlined(" - visitTree(call) - buff append ", " - visitTrees(bindings) - buff append ", " - visitTree(expansion) - buff append ")" - case ValDef(name, tpt, rhs) => - buff append "ValDef(" append name append ", " - visitTypeTree(tpt) - buff append ", " - rhs match { - case Some(tree) => - buff append "Some(" - visitTree(tree) - buff append ")" - case _ => buff append "None" - } - buff append ")" - case DefDef(name, typeParams, paramss, returnTpt, rhs) => - buff append "DefDef(" append name append ", " - visitTrees(typeParams) - buff append ", " - paramss match { - case x0 :: xs => - buff append "List(" - visitTrees(x0) - def visitNext(xs: List[List[ValDef]]): Unit = xs match { - case y :: ys => - buff append ", " - visitTrees(y) - visitNext(ys) - case Nil => - } - visitNext(xs) - buff append ")" - case Nil => buff append "Nil" - } - buff append ", " - visitTypeTree(returnTpt) - buff append ", " - rhs match { - case Some(tree) => - buff append "Some(" - visitTree(tree) - buff append ")" - case None => buff append "None" - } - buff append ")" - case TypeDef(name, rhs) => - buff append "TypeDef(" append name append ", " - visitTypeTree(rhs) - buff append ")" - case ClassDef(name, constr, parents, self, body) => - buff append "ClassDef(" append name append ", " - visitTree(constr) - buff append ", " - visitParents(parents) - buff append ", " - self match { - case Some(tree) => - buff append "Some(" - visitTree(tree) - buff append ")" - case _ => buff append "None" - } - buff append ", " - visitTrees(body) - buff append ")" - case PackageDef(name, members) => - buff append "PackageDef(" - buff append name - buff append ", " - visitTrees(members) - buff append ")" - case Import(expr, selectors) => - buff append "Import(" - visitTree(expr) - buff append ", " - - buff append "List(" - selectors.foreach { - case SimpleSelector(id) => - buff append "SimpleSelector(" - visitId(id) - buff append ")" - case RenameSelector(id1, id2) => - buff append "RenameSelector(" - visitId(id1) - buff append ", " - visitId(id2) - buff append ")" - case OmitSelector(id) => - buff append "OmitSelector(" - visitId(id) - buff append ")" - } - buff append ")" - buff append ")" - case PackageClause(pid, stats) => - buff append "PackageClause(" - visitTree(pid) - buff append ", " - visitTrees(stats) - buff append ")" - } + private class Buffer(implicit ctx: Context) { self => - private def visitTrees(list: List[Tree])(implicit buff: StringBuilder, ctx: Context): Unit = { - list match { - case x0 :: xs => - buff append "List(" - visitTree(x0) - def visitNext(xs: List[Tree]): Unit = xs match { - case y :: ys => - buff append ", " - visitTree(y) - visitNext(ys) - case Nil => - } - visitNext(xs) - buff append ")" - case Nil => buff append "Nil" + private val sb: StringBuilder = new StringBuilder + + def result(): String = sb.result() + + def visitTree(x: Tree): Buffer = x match { + case Ident(name) => + this += "Ident(" += name += ")" + case Select(qualifier, name, signature) => + this += "Select(" += qualifier += ", " += name += ", " += signature += ")" + case This(qual) => + this += "This(" += qual += ")" + case Super(qual, mix) => + this += "TypeApply(" += qual += ", " += mix += ")" + case Apply(fun, args) => + this += "Apply(" += fun += ", " ++= args += ")" + case TypeApply(fun, args) => + this += "TypeApply(" += fun += ", " ++= args += ")" + case Literal(const) => + this += "Literal(" += const += ")" + case New(tpt) => + this += "New(" += tpt += ")" + case Typed(expr, tpt) => + this += "Typed(" += expr += ", " += tpt += ")" + case NamedArg(name, arg) => + this += "NamedArg(" += name += ", " += arg += ")" + case Assign(lhs, rhs) => + this += "Assign(" += lhs += ", " += rhs += ")" + case Block(stats, expr) => + this += "Block(" ++= stats += ", " += expr += ")" + case If(cond, thenp, elsep) => + this += "If(" += cond += ", " += thenp += ", " += elsep += ")" + case Lambda(meth, tpt) => + this += "Lambda(" += meth += ", " += tpt += ")" + case Match(selector, cases) => + this += "Match(" += selector += ", " ++= cases += ")" + case Return(expr) => + this += "Return(" += expr += ")" + case Try(block, handlers, finalizer) => + this += "Try(" += block += ", " ++= handlers += ", " += finalizer += ")" + case Repeated(elems) => + this += "Repeated(" ++= elems += ")" + case Inlined(call, bindings, expansion) => + this += "Inlined(" += call += ", " ++= bindings += ", " += expansion += ")" + case ValDef(name, tpt, rhs) => + this += "ValDef(" += name += ", " += tpt += ", " += rhs += ")" + case DefDef(name, typeParams, paramss, returnTpt, rhs) => + this += "DefDef(" += name += ", " ++= typeParams += ", " +++= paramss += ", " += returnTpt += ", " += rhs += ")" + case TypeDef(name, rhs) => + this += "TypeDef(" += name += ", " += rhs += ")" + case ClassDef(name, constr, parents, self, body) => + this += "ClassDef(" += name += ", " += constr += ", " ++= parents += ", " += self += ", " ++= body += ")" + case PackageDef(name, members) => + this += "PackageDef(" += name += ", " ++= members += ")" + case Import(expr, selectors) => + this += "Import(" += expr += ", " ++= selectors += ")" + case PackageClause(pid, stats) => + this += "PackageClause(" += pid += ", " ++= stats += ")" } - } - private def visitTypeTree(x: TypeOrBoundsTree)(implicit buff: StringBuilder, ctx: Context): Unit = { - x match { + def visitTypeTree(x: TypeOrBoundsTree): Buffer = x match { case Synthetic() => - buff append "Synthetic()" + this += "Synthetic()" case TypeIdent(name) => - buff append "TypeIdent(" append name append ")" + this += "TypeIdent(" += name += ")" case TypeSelect(qualifier, name) => - buff append "TypeSelect(" - visitTree(qualifier) - buff append ", " append name append ")" + this += "TypeSelect(" += qualifier += ", " += name += ")" case Singleton(ref) => - buff append "Singleton(" - visitTree(ref) - buff append ")" + this += "Singleton(" += ref += ")" case And(left, right) => - buff append "And(" - visitTypeTree(left) - buff append ", " - visitTypeTree(right) - buff append ")" + this += "And(" += left += ", " += right += ")" case Or(left, right) => - buff append "Or(" - visitTypeTree(left) - buff append ", " - visitTypeTree(right) - buff append ")" + this += "Or(" += left += ", " += right += ")" case Refined(tpt, refinements) => - buff append "Refined(" - visitTypeTree(tpt) - buff append ", " - visitTrees(refinements) - buff append ")" + this += "Refined(" += tpt += ", " ++= refinements += ")" case Applied(tpt, args) => - buff append "Applied(" - visitTypeTree(tpt) - buff append ", " - visitTypeTrees(args) - buff append ")" + this += "Applied(" += tpt += ", " ++= args += ")" case ByName(result) => - buff append "ByName(" - visitTypeTree(result) - buff append ")" + this += "ByName(" += result += ")" case Annotated(arg, annot) => - buff append "Annotated(" - visitTypeTree(arg) - buff append ", " - visitTree(annot) - buff append ")" + this += "Annotated(" += arg += ", " += annot += ")" case TypeBoundsTree(lo, hi) => - buff append "TypeBoundsTree(" - visitTypeTree(lo) - buff append ", " - visitTypeTree(hi) - buff append ")" + this += "TypeBoundsTree(" += lo += ", " += hi += ")" } - } - private def visitTypeTrees(list: List[TypeTree])(implicit buff: StringBuilder, ctx: Context): Unit = { - list match { - case x0 :: xs => - buff append "List(" - visitTypeTree(x0) - def visitNext(xs: List[TypeTree]): Unit = xs match { - case y :: ys => - buff append ", " - visitTypeTree(y) - visitNext(ys) - case Nil => - } - visitNext(xs) - buff append ")" - case Nil => buff append "Nil" + def visitCaseDef(x: CaseDef): Buffer = { + val CaseDef(pat, guard, body) = x + this += "CaseDef(" += pat += ", " += guard += ", " += body += ")" } - } - private def visitCaseDef(x: CaseDef)(implicit buff: StringBuilder, ctx: Context): Unit = { - x match { - case CaseDef(pat, guard, body) => - buff append "CaseDef(" - visitPattern(pat) - buff append ", " - guard match { - case Some(tree) => - buff append "Some(" - visitTree(guard.get) - buff append ")" - case None => - buff append "None" - } - buff append ", " - visitTree(body) - buff append ")" + def visitPattern(x: Pattern): Buffer = x match { + case Value(v) => + this += "Value(" += v += ")" + case Bind(name, body) => + this += "Bind(" += name += ", " += body += ")" + case Unapply(fun, implicits, patterns) => + this += "Unapply(" += fun += ", " ++= implicits += ", " ++= patterns += ")" + case Alternative(patterns) => + this += "Alternative(" ++= patterns += ")" + case TypeTest(tpt) => + this += "TypeTest(" += tpt += ")" } - } - private def visitCaseDefs(list: List[CaseDef])(implicit buff: StringBuilder, ctx: Context): Unit = { - list match { - case x0 :: xs => - buff append "List(" - visitCaseDef(x0) - def visitNext(xs: List[CaseDef]): Unit = xs match { - case y :: ys => - buff append ", " - visitCaseDef(y) - visitNext(ys) - case Nil => + def visitConstant(x: Constant): Buffer = x match { + case UnitConstant() => this += "Unit()" + case NullConstant() => this += "Null()" + case BooleanConstant(value) => this += "Boolean(" += value += ")" + case ByteConstant(value) => this += "Byte(" += value += ")" + case ShortConstant(value) => this += "Short(" += value += ")" + case CharConstant(value) => this += "Char(" += value += ")" + case IntConstant(value) => this += "Int(" += value.toString += ")" + case LongConstant(value) => this += "Long(" += value += ")" + case FloatConstant(value) => this += "Float(" += value += ")" + case DoubleConstant(value) => this += "Double(" += value += ")" + case StringConstant(value) => this += "String(" += value += ")" + } + + def visitType(x: TypeOrBounds): Buffer = x match { + case ConstantType(value) => + this += "ConstantType(" += value += ")" + case SymRef(sym, qual) => + def visitName(sym: Definition): Buffer = sym match { + case ValDef(name, _, _) => this += name + case DefDef(name, _, _, _, _) => this += name + case TypeDef(name, _) => this += name + case ClassDef(name, _, _, _, _) => this += name + case PackageDef(name, _) => this += name + case _ => this += "#" } - visitNext(xs) - buff append ")" - case Nil => buff append "Nil" + this += "SymRef(" + visitName(sym) + this += ", " += qual += ")" + case TermRef(name, qual) => + this += "TermRef(" += name += ", " += qual += ")" + case TypeRef(name, qual) => + this += "TypeRef(" += name += ", " += qual += ")" + case Refinement(parent, name, info) => + this += "Refinement(" += parent += ", " += name += ", " += info += ")" + case AppliedType(tycon, args) => + this += "AppliedType(" += tycon += ", " ++= args += ")" + case AnnotatedType(underlying, annot) => + this += "AnnotatedType(" += underlying += ", " += annot += ")" + case AndType(left, right) => + this += "AndType(" += left += ", " += right += ")" + case OrType(left, right) => + this += "OrType(" += left += ", " += right += ")" + case ByNameType(underlying) => + this += "ByNameType(" += underlying += ")" + case ParamRef(binder, idx) => + this += "ParamRef(" += binder+= ", " += idx += ")" + case ThisType(tp) => + this += "ThisType(" += tp += ")" + case RecursiveThis(binder) => + this += "RecursiveThis(" += binder += ")" + case MethodType(argNames, argTypes, resType) => + this += "MethodType(" ++= argNames += ", " ++= argTypes += ", " += resType += ")" + case PolyType(argNames, argBounds, resType) => + this += "PolyType(" ++= argNames += ", " ++= argBounds += ", " += resType += ")" + case TypeLambda(argNames, argBounds, resType) => + this += "TypeLambda(" ++= argNames += ", " ++= argBounds += ", " += resType += ")" + case TypeBounds(lo, hi) => + this += "TypeBounds(" += lo += ", " += hi += ")" + case NoPrefix() => + this += "NoPrefix" } - } - private def visitPattern(x: Pattern)(implicit buff: StringBuilder, ctx: Context): Unit = x match { - case Value(v) => - buff append "Value(" - visitTree(v) - buff append ")" - case Bind(name, body) => - buff append "Bind(" append name append ", " - visitPattern(body) - buff append ")" - case Unapply(fun, implicits, patterns) => - buff append "Unapply(" - visitTree(fun) - buff append ", " - visitTrees(implicits) - buff append ", " - visitPatterns(patterns) - buff append ")" - case Alternative(patterns) => - buff append "Alternative(" - visitPatterns(patterns) - buff append ")" - case TypeTest(tpt) => - buff append "TypeTest(" - visitTypeTree(tpt) - buff append ")" - } + def visitModifier(x: Modifier): Buffer = x match { + case Flags(flags) => this += "Flags(" += flags.toString += ")" + case QualifiedPrivate(tp) => this += "QualifiedPrivate(" += tp += ")" + case QualifiedProtected(tp) => this += "QualifiedProtected(" += tp += ")" + case Annotation(tree) => this += "Annotation(" += tree += ")" + } - private def visitPatterns(list: List[Pattern])(implicit buff: StringBuilder, ctx: Context): Unit = { - list match { - case x0 :: xs => - buff append "List(" - visitPattern(x0) - def visitNext(xs: List[Pattern]): Unit = xs match { - case y :: ys => - buff append ", " - visitPattern(y) - visitNext(ys) - case Nil => - } - visitNext(xs) - buff append ")" - case Nil => buff append "Nil" + def visitParent(x: Parent): Buffer = x match { + case TermParent(term) => this += "TermParent(" += term += ")" + case TypeParent(typeTree) => this += "TypeParent(" += typeTree += ")" } - } - private def visitConstant(x: Constant)(implicit buff: StringBuilder, ctx: Context): Unit = x match { - case UnitConstant() => buff append "Unit()" - case NullConstant() => buff append "Null()" - case BooleanConstant(value) => buff append "Boolean(" append value append ")" - case ByteConstant(value) => buff append "Byte(" append value append ")" - case ShortConstant(value) => buff append "Short(" append value append ")" - case CharConstant(value) => buff append "Char(" append value append ")" - case IntConstant(value) => buff append "Int(" append value append ")" - case LongConstant(value) => buff append "Long(" append value append ")" - case FloatConstant(value) => buff append "Float(" append value append ")" - case DoubleConstant(value) => buff append "Double(" append value append ")" - case StringConstant(value) => buff append "String(" append value append ")" - } + def visitId(x: Id): Buffer = { + val Id(name) = x + this += "Id(" += name += ")" + } - private def visitType(x: TypeOrBounds)(implicit buff: StringBuilder, ctx: Context): Unit = x match { - case ConstantType(value) => - buff append "ConstantType(" - visitConstant(value) - buff append ")" - case SymRef(sym, qual) => - def visitName(sym: Definition): Unit = sym match { - case ValDef(name, _, _) => buff append name - case DefDef(name, _, _, _, _) => buff append name - case TypeDef(name, _) => buff append name - case ClassDef(name, _, _, _, _) => buff append name - case PackageDef(name, _) => buff append name - case _ => buff append "#" - } - buff append "SymRef(" - visitName(sym) - buff append ", " - visitType(qual) - buff append ")" - case TermRef(name, qual) => - buff append "TermRef(" append name append ", " - visitType(qual) - buff append ")" - case TypeRef(name, qual) => - buff append "TypeRef(" append name append ", " - visitType(qual) - buff append ")" - case Refinement(parent, name, info) => - buff append "Refinement(" - visitType(parent) - buff append ", " append name append ", " - visitType(info) - buff append ")" - case AppliedType(tycon, args) => - buff append "AppliedType(" - visitType(tycon) - buff append ", " - visitTypes(args) - buff append ")" - case AnnotatedType(underlying, annot) => - buff append "AnnotatedType(" - visitType(underlying) - buff append ", " - visitTree(annot) - buff append ")" - case AndType(left, right) => - buff append "AndType(" - visitType(left) - buff append ", " - visitType(right) - buff append ")" - case OrType(left, right) => - buff append "OrType(" - visitType(left) - buff append ", " - visitType(right) - buff append ")" - case ByNameType(underlying) => - buff append "ByNameType(" - visitType(underlying) - buff append ")" - case ParamRef(binder, idx) => - buff append "ParamRef(" - visitType(binder) - buff append ", " append idx append ")" - case ThisType(tp) => - buff append "ThisType(" - visitType(tp) - buff append ")" - case RecursiveThis(binder) => - buff append "RecursiveThis(" - visitType(binder) - buff append ")" - case MethodType(argNames, argTypes, resType) => - buff append "MethodType(" - if (argNames.isEmpty) buff append "Nil" - else buff append argNames - buff append ", " - visitTypes(argTypes) - buff append ", " - visitType(resType) - buff append ")" - case PolyType(argNames, argBounds, resType) => - buff append "PolyType(" - if (argNames.isEmpty) buff append "Nil" - else buff append argNames - buff append ", " - visitTypes(argBounds) - buff append ", " - visitType(resType) - buff append ")" - case TypeLambda(argNames, argBounds, resType) => - buff append "TypeLambda(" - if (argNames.isEmpty) buff append "Nil" - else buff append argNames - buff append ", " - visitTypes(argBounds) - buff append ", " - visitType(resType) - buff append ")" - case TypeBounds(lo, hi) => - buff append "TypeBounds(" - visitType(lo) - buff append ", " - visitType(hi) - buff append ")" - case NoPrefix() => - buff append "NoPrefix" - } + def visitSignature(sig: Signature): Buffer = { + val Signature(params, res) = sig + this += "Signature(" ++= params += ", " += res += ")" + } - private def visitTypes(list: List[TypeOrBounds])(implicit buff: StringBuilder, ctx: Context): Unit = { - list match { - case x0 :: xs => - buff append "List(" - visitType(x0) - def visitNext(xs: List[TypeOrBounds]): Unit = xs match { - case y :: ys => - buff append ", " - visitType(y) - visitNext(ys) - case Nil => - } - visitNext(xs) - buff append ")" - case Nil => buff append "Nil" + def visitImportSelector(sel: ImportSelector): Buffer = sel match { + case SimpleSelector(id) => this += "SimpleSelector(" += id += ")" + case RenameSelector(id1, id2) => this += "RenameSelector(" += id1 += ", " += id2 += ")" + case OmitSelector(id) => this += "OmitSelector(" += id += ")" } - } - private def visitModifier(x: Modifier)(implicit buff: StringBuilder, ctx: Context): Unit = x match { - case Flags(flags) => - buff append "Flags(" append flags append ")" - case QualifiedPrivate(tp) => - buff append "QualifiedPrivate(" - visitType(tp) - buff append ")" - case QualifiedProtected(tp) => - buff append "QualifiedProtected(" - visitType(tp) - buff append ")" - case Annotation(tree) => - buff append "Annotation(" - visitTree(tree) - buff append ")" - } + def +=(x: Boolean): Buffer = { sb.append(x); this } + def +=(x: Byte): Buffer = { sb.append(x); this } + def +=(x: Short): Buffer = { sb.append(x); this } + def +=(x: Int): Buffer = { sb.append(x); this } + def +=(x: Long): Buffer = { sb.append(x); this } + def +=(x: Float): Buffer = { sb.append(x); this } + def +=(x: Double): Buffer = { sb.append(x); this } + def +=(x: Char): Buffer = { sb.append(x); this } + def +=(x: String): Buffer = { sb.append(x); this } - private def visitParent(x: Parent)(implicit buff: StringBuilder, ctx: Context): Unit = x match { - case TermParent(term) => - buff append "TermParent(" - visitTree(term) - buff append ")" - case TypeParent(typeTree) => - buff append "TypeParent(" - visitTypeTree(typeTree) - buff append ")" - } + def ++=(xs: List[String]): Buffer = visitList[String](xs, +=) - private def visitParents(list: List[Parent])(implicit buff: StringBuilder, ctx: Context): Unit = { - list match { + private implicit class TreeOps(buff: Buffer) { + def +=(x: Tree): Buffer = { visitTree(x); buff } + def +=(x: Option[Tree]): Buffer = { visitOption(x, visitTree); buff } + def ++=(x: List[Tree]): Buffer = { visitList(x, visitTree); buff } + def +++=(x: List[List[Tree]]): Buffer = { visitList(x, ++=); buff } + } + + private implicit class CaseDefOps(buff: Buffer) { + def +=(x: CaseDef): Buffer = { visitCaseDef(x); buff } + def ++=(x: List[CaseDef]): Buffer = { visitList(x, visitCaseDef); buff } + } + + private implicit class ParentOps(buff: Buffer) { + def +=(x: Parent): Buffer = { visitParent(x); buff } + def ++=(x: List[Parent]): Buffer = { visitList(x, visitParent); buff } + } + + private implicit class PatternOps(buff: Buffer) { + def +=(x: Pattern): Buffer = { visitPattern(x); buff } + def ++=(x: List[Pattern]): Buffer = { visitList(x, visitPattern); buff } + } + + private implicit class ConstantOps(buff: Buffer) { + def +=(x: Constant): Buffer = { visitConstant(x); buff } + } + + private implicit class TypeTreeOps(buff: Buffer) { + def +=(x: TypeOrBoundsTree): Buffer = { visitTypeTree(x); buff } + def +=(x: Option[TypeTree]): Buffer = { visitOption(x, visitTypeTree); buff } + def ++=(x: List[TypeTree]): Buffer = { visitList(x, visitTypeTree); buff } + } + + private implicit class TypeOps(buff: Buffer) { + def +=(x: TypeOrBounds): Buffer = { visitType(x); buff } + def ++=(x: List[TypeOrBounds]): Buffer = { visitList(x, visitType); buff } + } + + private implicit class IdOps(buff: Buffer) { + def +=(x: Id): Buffer = { visitId(x); buff } + def +=(x: Option[Id]): Buffer = { visitOption(x, visitId); buff } + } + + private implicit class SignatureOps(buff: Buffer) { + def +=(x: Option[Signature]): Buffer = { visitOption(x, visitSignature); buff } + } + + private implicit class ImportSelectorOps(buff: Buffer) { + def ++=(x: List[ImportSelector]): Buffer = { visitList(x, visitImportSelector); buff } + } + + private def visitOption[U](opt: Option[U], visit: U => Buffer): Buffer = opt match { + case Some(x) => + this += "Some(" + visit(x) + this += ")" + case _ => + this += "None" + } + + private def visitList[U](list: List[U], visit: U => Buffer): Buffer = list match { case x0 :: xs => - buff append "List(" - visitParent(x0) - def visitNext(xs: List[Parent]): Unit = xs match { + this += "List(" + visit(x0) + def visitNext(xs: List[U]): Unit = xs match { case y :: ys => - buff append ", " - visitParent(y) + this += ", " + visit(y) visitNext(ys) case Nil => } visitNext(xs) - buff append ")" - case Nil => buff append "Nil" + this += ")" + case Nil => + this += "Nil" } } - private def visitId(x: Id)(implicit buff: StringBuilder, ctx: Context): Unit = { - import tasty._ - x match { - case Id(name) => buff append "Id(" append name append ")" - } - } } diff --git a/tests/run/tasty-extractors-2.check b/tests/run/tasty-extractors-2.check index aeddca46e854..2971b38ec061 100644 --- a/tests/run/tasty-extractors-2.check +++ b/tests/run/tasty-extractors-2.check @@ -25,7 +25,7 @@ OrType(SymRef(Int, SymRef(scala, ThisType(SymRef(, NoPrefix)))), SymRef(St Block(List(Import(Select(Ident(scala), collection, None), List(SimpleSelector(Id(mutable))))), Literal(Int(1))) ConstantType(Int(1)) -Block(List(Import(Select(Ident(scala), collection, None), List(SimpleSelector(Id(mutable))SimpleSelector(Id(immutable))))), Literal(Int(2))) +Block(List(Import(Select(Ident(scala), collection, None), List(SimpleSelector(Id(mutable)), SimpleSelector(Id(immutable))))), Literal(Int(2))) ConstantType(Int(2)) Block(List(Import(Select(Ident(scala), collection, None), List(RenameSelector(Id(mutable), Id(mut))))), Literal(Int(3))) From 2015fa13561c76c1813ea0a21bfa6c3f03fb3d48 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 12:07:29 +0200 Subject: [PATCH 14/21] Redifine parent as Term | TypeTree --- .../dotty/tools/dotc/tasty/TastyImpl.scala | 20 ++++----- library/src/scala/tasty/Tasty.scala | 26 ++++++------ .../src/scala/tasty/util/TastyPrinter.scala | 17 +++----- .../scala/tasty/util/TreeAccumulator.scala | 9 ++-- .../src/scala/tasty/util/TreeTraverser.scala | 3 -- tests/run/tasty-extractors-2.check | 42 +++++++++---------- tests/run/tasty-extractors-owners.check | 6 +-- 7 files changed, 54 insertions(+), 69 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index 54438d91607a..370639659023 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -213,22 +213,14 @@ object TastyImpl extends scala.tasty.Tasty { type Parent = tpd.Tree - def parentClassTag: ClassTag[Parent] = implicitly[ClassTag[Parent]] - - val TermParent: TermParentExtractor = new TermParentExtractor { - def unapply(x: Parent)(implicit ctx: Context): Option[Term] = - if (x.isTerm) Some(x) else None - } - - val TypeParent: TypeParentExtractor = new TypeParentExtractor { - def unapply(x: Parent)(implicit ctx: Context): Option[TypeTree] = - if (x.isTerm) None else Some(x) - } - // ----- Terms ---------------------------------------------------- type Term = tpd.Tree + val Term: TermCaster = new TermCaster { + def unapply(x: Term)(implicit ctx: Context): Boolean = x.isTerm + } + implicit def TermDeco(t: Term): AbstractTerm = new AbstractTerm { def pos(implicit ctx: Context): Position = new TastyPosition(t.pos) def tpe(implicit ctx: Context): Types.Type = t.tpe @@ -458,6 +450,10 @@ object TastyImpl extends scala.tasty.Tasty { type TypeTree = tpd.Tree + val TypeTree: TypeTreeCaster = new TypeTreeCaster { + def unapply(x: TypeTree)(implicit ctx: Context): Boolean = x.isType + } + def typeTreeClassTag: ClassTag[TypeTree] = implicitly[ClassTag[TypeTree]] implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree = new AbstractTypeTree { diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index 1d96eeac33fb..a73564fd4c9d 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -162,24 +162,17 @@ abstract class Tasty { // ----- Parents -------------------------------------------------- - type Parent + type Parent /* Term | TypeTree */ - implicit def parentClassTag: ClassTag[Parent] + // ----- Terms ---------------------------------------------------- - val TermParent: TermParentExtractor - abstract class TermParentExtractor { - def unapply(x: Parent)(implicit ctx: Context): Option[Term] - } + type Term <: Statement with Parent - val TypeParent: TypeParentExtractor - abstract class TypeParentExtractor { - def unapply(x: Parent)(implicit ctx: Context): Option[TypeTree] + val Term: TermCaster + abstract class TermCaster { + def unapply(x: Term)(implicit ctx: Context): Boolean } - // ----- Terms ---------------------------------------------------- - - type Term <: Statement - trait AbstractTerm extends Typed with Positioned implicit def TermDeco(t: Term): AbstractTerm @@ -342,7 +335,12 @@ abstract class Tasty { // ----- TypeTrees ------------------------------------------------ - type TypeTree <: TypeOrBoundsTree + type TypeTree <: TypeOrBoundsTree with Parent + + val TypeTree: TypeTreeCaster + abstract class TypeTreeCaster { + def unapply(x: TypeTree)(implicit ctx: Context): Boolean + } trait AbstractTypeTree extends Typed with Positioned implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index 55f13c259df6..7d0c5373b51b 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -72,7 +72,12 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { case TypeDef(name, rhs) => this += "TypeDef(" += name += ", " += rhs += ")" case ClassDef(name, constr, parents, self, body) => - this += "ClassDef(" += name += ", " += constr += ", " ++= parents += ", " += self += ", " ++= body += ")" + this += "ClassDef(" += name += ", " += constr += ", " + visitList[Parent](parents, { + case parent @ Term() => this += parent + case parent @ TypeTree() => this += parent + }) + this += ", " += self += ", " ++= body += ")" case PackageDef(name, members) => this += "PackageDef(" += name += ", " ++= members += ")" case Import(expr, selectors) => @@ -194,11 +199,6 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { case Annotation(tree) => this += "Annotation(" += tree += ")" } - def visitParent(x: Parent): Buffer = x match { - case TermParent(term) => this += "TermParent(" += term += ")" - case TypeParent(typeTree) => this += "TypeParent(" += typeTree += ")" - } - def visitId(x: Id): Buffer = { val Id(name) = x this += "Id(" += name += ")" @@ -239,11 +239,6 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { def ++=(x: List[CaseDef]): Buffer = { visitList(x, visitCaseDef); buff } } - private implicit class ParentOps(buff: Buffer) { - def +=(x: Parent): Buffer = { visitParent(x); buff } - def ++=(x: List[Parent]): Buffer = { visitList(x, visitParent); buff } - } - private implicit class PatternOps(buff: Buffer) { def +=(x: Pattern): Buffer = { visitPattern(x); buff } def ++=(x: List[Pattern]): Buffer = { visitList(x, visitPattern); buff } diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index 1d25358276bc..da5403cc3a02 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -10,13 +10,12 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { def foldTypeTree(x: X, tree: TypeOrBoundsTree)(implicit ctx: Context): X def foldCaseDef(x: X, tree: CaseDef)(implicit ctx: Context): X def foldPattern(x: X, tree: Pattern)(implicit ctx: Context): X - def foldParent(x: X, tree: Parent)(implicit ctx: Context): X def foldTrees(x: X, trees: Iterable[Tree])(implicit ctx: Context): X = (x /: trees)(foldTree) def foldTypeTrees(x: X, trees: Iterable[TypeOrBoundsTree])(implicit ctx: Context): X = (x /: trees)(foldTypeTree) def foldCaseDefs(x: X, trees: Iterable[CaseDef])(implicit ctx: Context): X = (x /: trees)(foldCaseDef) def foldPatterns(x: X, trees: Iterable[Pattern])(implicit ctx: Context): X = (x /: trees)(foldPattern) - def foldParents(x: X, trees: Iterable[Parent])(implicit ctx: Context): X = (x /: trees)(foldParent) + private def foldParents(x: X, trees: Iterable[Parent])(implicit ctx: Context): X = (x /: trees)(foldOverParent) def foldOverTree(x: X, tree: Tree)(implicit ctx: Context): X = { def localCtx(definition: Definition): Context = definition.localContext @@ -106,9 +105,9 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { case TypeTest(tpt) => foldTypeTree(x, tpt) } - def foldOverParent(x: X, tree: Parent)(implicit ctx: Context): X = tree match { - case TermParent(term) => foldOverTree(x, term) - case TypeParent(typeTree) => foldOverTypeTree(x, typeTree) + 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) } } diff --git a/library/src/scala/tasty/util/TreeTraverser.scala b/library/src/scala/tasty/util/TreeTraverser.scala index e51387bb2594..c835b8fb2413 100644 --- a/library/src/scala/tasty/util/TreeTraverser.scala +++ b/library/src/scala/tasty/util/TreeTraverser.scala @@ -9,18 +9,15 @@ abstract class TreeTraverser[T <: Tasty with Singleton](tasty0: T) extends TreeA def traverseTypeTree(tree: TypeOrBoundsTree)(implicit ctx: Context): Unit = traverseTypeTreeChildren(tree) def traverseCaseDef(tree: CaseDef)(implicit ctx: Context): Unit = traverseCaseDefChildren(tree) def traversePattern(tree: Pattern)(implicit ctx: Context): Unit = traversePatternChildren(tree) - def traverseParent(tree: Parent)(implicit ctx: Context): Unit = traverseParentChildren(tree) def foldTree(x: Unit, tree: Tree)(implicit ctx: Context): Unit = traverseTree(tree) def foldTypeTree(x: Unit, tree: TypeOrBoundsTree)(implicit ctx: Context) = traverseTypeTree(tree) def foldCaseDef(x: Unit, tree: CaseDef)(implicit ctx: Context) = traverseCaseDef(tree) def foldPattern(x: Unit, tree: Pattern)(implicit ctx: Context) = traversePattern(tree) - def foldParent(x: Unit, tree: Parent)(implicit ctx: Context) = traverseParent(tree) protected def traverseTreeChildren(tree: Tree)(implicit ctx: Context): Unit = foldOverTree((), tree) protected def traverseTypeTreeChildren(tree: TypeOrBoundsTree)(implicit ctx: Context): Unit = foldOverTypeTree((), tree) protected def traverseCaseDefChildren(tree: CaseDef)(implicit ctx: Context): Unit = foldOverCaseDef((), tree) protected def traversePatternChildren(tree: Pattern)(implicit ctx: Context): Unit = foldOverPattern((), tree) - protected def traverseParentChildren(tree: Parent)(implicit ctx: Context): Unit = foldOverParent((), tree) } diff --git a/tests/run/tasty-extractors-2.check b/tests/run/tasty-extractors-2.check index 2971b38ec061..ef60d7330f8f 100644 --- a/tests/run/tasty-extractors-2.check +++ b/tests/run/tasty-extractors-2.check @@ -34,10 +34,10 @@ ConstantType(Int(3)) Block(List(Import(Select(Ident(scala), collection, None), List(OmitSelector(Id(mutable))))), Literal(Int(4))) ConstantType(Int(4)) -Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, Nil)), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, Nil)), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ValDef(Foo, TypeIdent(Foo$), Some(Apply(Select(New(TypeIdent(Foo$)), , Some(Signature(Nil, Test$._$Foo$))), Nil))), ClassDef(Foo$, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), Some(ValDef(_, Singleton(Ident(Foo)), None)), Nil)), Literal(Unit())) +Block(List(ValDef(Foo, TypeIdent(Foo$), Some(Apply(Select(New(TypeIdent(Foo$)), , Some(Signature(Nil, Test$._$Foo$))), Nil))), ClassDef(Foo$, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), Some(ValDef(_, Singleton(Ident(Foo)), None)), Nil)), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) Block(List(TypeDef(Foo, TypeBoundsTree(Synthetic(), Synthetic()))), Literal(Unit())) @@ -49,61 +49,61 @@ SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) Block(List(TypeDef(Foo, TypeBoundsTree(TypeIdent(Null), TypeIdent(Object)))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), Some(Literal(Int(0)))), DefDef(a_=, Nil, List(List(ValDef(x$1, Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), Some(Literal(Int(0)))), DefDef(a_=, Nil, List(List(ValDef(x$1, Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(DefDef(a, Nil, Nil, Synthetic(), Some(Literal(Int(0))))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo1, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None)))), Literal(Unit())) +Block(List(ClassDef(Foo1, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), None)))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo2, DefDef(, Nil, List(List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(b, Synthetic(), None)))), Literal(Unit())) +Block(List(ClassDef(Foo2, DefDef(, Nil, List(List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(b, Synthetic(), None)))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo3, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None))), ValDef(Foo3, TypeIdent(Foo3$), Some(Apply(Select(New(TypeIdent(Foo3$)), , Some(Signature(Nil, Test$._$Foo3$))), Nil))), ClassDef(Foo3$, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), Some(ValDef(_, Singleton(Ident(Foo3)), None)), List(DefDef($lessinit$greater$default$1, Nil, Nil, Synthetic(), Some(Literal(Int(5))))))), Literal(Unit())) +Block(List(ClassDef(Foo3, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), None))), ValDef(Foo3, TypeIdent(Foo3$), Some(Apply(Select(New(TypeIdent(Foo3$)), , Some(Signature(Nil, Test$._$Foo3$))), Nil))), ClassDef(Foo3$, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), Some(ValDef(_, Singleton(Ident(Foo3)), None)), List(DefDef($lessinit$greater$default$1, Nil, Nil, Synthetic(), Some(Literal(Int(5))))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo4, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None)))), Literal(Unit())) +Block(List(ClassDef(Foo4, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None)))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo5, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None))), ValDef(Foo5, TypeIdent(Foo5$), Some(Apply(Select(New(TypeIdent(Foo5$)), , Some(Signature(Nil, Test$._$Foo5$))), Nil))), ClassDef(Foo5$, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), Some(ValDef(_, Singleton(Ident(Foo5)), None)), List(DefDef($lessinit$greater$default$2, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), Some(Ident(a)))))), Literal(Unit())) +Block(List(ClassDef(Foo5, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, TypeIdent(Int), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None))), ValDef(Foo5, TypeIdent(Foo5$), Some(Apply(Select(New(TypeIdent(Foo5$)), , Some(Signature(Nil, Test$._$Foo5$))), Nil))), ClassDef(Foo5$, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), Some(ValDef(_, Singleton(Ident(Foo5)), None)), List(DefDef($lessinit$greater$default$2, Nil, List(List(ValDef(a, TypeIdent(Int), None))), Synthetic(), Some(Ident(a)))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo6, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, Singleton(Ident(a)), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None)))), Literal(Unit())) +Block(List(ClassDef(Foo6, DefDef(, Nil, List(List(ValDef(a, TypeIdent(Int), None)), List(ValDef(b, Singleton(Ident(a)), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), None), ValDef(b, Synthetic(), None)))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo8, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(Apply(Ident(println), List(Literal(Int(0))))))), Literal(Unit())) +Block(List(ClassDef(Foo8, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(Apply(Ident(println), List(Literal(Int(0))))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo10, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), Some(Literal(Int(9))))))), Literal(Unit())) +Block(List(ClassDef(Foo10, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), Some(Literal(Int(9))))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo11, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), Some(Literal(Int(10)))), DefDef(a_=, Nil, List(List(ValDef(x$1, Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) +Block(List(ClassDef(Foo11, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), Some(Literal(Int(10)))), DefDef(a_=, Nil, List(List(ValDef(x$1, Synthetic(), None))), Synthetic(), Some(Literal(Unit())))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo12, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(a, Synthetic(), Some(Literal(Int(11))))))), Literal(Unit())) +Block(List(ClassDef(Foo12, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(a, Synthetic(), Some(Literal(Int(11))))))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, Nil), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, Test$._$Foo))), Nil))), None, Nil)), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, Nil), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, Test$._$Foo))), Nil)), None, Nil)), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo2, DefDef(, Nil, List(Nil), Synthetic(), None), List(TypeParent(Synthetic())), None, Nil), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), TypeParent(TypeIdent(Foo2))), None, Nil)), Literal(Unit())) +Block(List(ClassDef(Foo2, DefDef(, Nil, List(Nil), Synthetic(), None), List(Synthetic()), None, Nil), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil), TypeIdent(Foo2)), None, Nil)), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo, DefDef(, Nil, List(List(ValDef(i, TypeIdent(Int), None))), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(ValDef(i, Synthetic(), None))), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(TypeIdent(Foo)), , Some(Signature(List(scala.Int), Test$._$Foo))), List(Literal(Int(1)))))), None, Nil)), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(List(ValDef(i, TypeIdent(Int), None))), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef(i, Synthetic(), None))), ClassDef(Bar, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(TypeIdent(Foo)), , Some(Signature(List(scala.Int), Test$._$Foo))), List(Literal(Int(1))))), None, Nil)), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(X, TypeIdent(Int)))), DefDef(f, Nil, List(List(ValDef(a, TypeIdent(Foo), None))), TypeSelect(Ident(a), X), Some(Ident(???)))), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef(X, TypeIdent(Int)))), DefDef(f, Nil, List(List(ValDef(a, TypeIdent(Foo), None))), TypeSelect(Ident(a), X), Some(Ident(???)))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) -Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(X, TypeBoundsTree(Synthetic(), Synthetic())))), DefDef(f, Nil, List(List(ValDef(a, Refined(TypeIdent(Foo), List(TypeDef(X, TypeIdent(Int)))), None))), TypeSelect(Ident(a), X), Some(Ident(???)))), Literal(Unit())) +Block(List(ClassDef(Foo, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef(X, TypeBoundsTree(Synthetic(), Synthetic())))), DefDef(f, Nil, List(List(ValDef(a, Refined(TypeIdent(Foo), List(TypeDef(X, TypeIdent(Int)))), None))), TypeSelect(Ident(a), X), Some(Ident(???)))), Literal(Unit())) SymRef(Unit, ThisType(SymRef(scala, NoPrefix))) Block(List(ValDef(lambda, Applied(Synthetic(), List(TypeIdent(Int), TypeIdent(Int))), Some(Block(List(DefDef($anonfun, Nil, List(List(ValDef(x, Synthetic(), None))), Synthetic(), Some(Ident(x)))), Lambda(Ident($anonfun), None))))), Literal(Unit())) diff --git a/tests/run/tasty-extractors-owners.check b/tests/run/tasty-extractors-owners.check index b32a13ceafcc..7712d05c567d 100644 --- a/tests/run/tasty-extractors-owners.check +++ b/tests/run/tasty-extractors-owners.check @@ -17,11 +17,11 @@ baz2 ValDef(foo2, Synthetic(), None) -ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) +ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) b -ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) +ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) b2 -ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(TermParent(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil))), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) +ClassDef(A, DefDef(, Nil, List(Nil), Synthetic(), None), List(Apply(Select(New(Synthetic()), , Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef(B, Synthetic()), DefDef(b, Nil, Nil, Synthetic(), None), ValDef(b2, Synthetic(), None))) From 0f7f5efa679342699ea9cea9970985e830b0bfd6 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 13:29:01 +0200 Subject: [PATCH 15/21] Put constants extractors in object --- .../dotty/tools/dotc/tasty/TastyImpl.scala | 113 +++++++++--------- library/src/scala/tasty/Tasty.scala | 109 +++++++++-------- .../src/scala/tasty/util/TastyPrinter.scala | 22 ++-- tests/run/tasty-eval/quoted_1.scala | 4 +- tests/run/tasty-indexed-map/quoted_1.scala | 2 +- 5 files changed, 130 insertions(+), 120 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index 370639659023..fc0867d124f6 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -755,83 +755,88 @@ object TastyImpl extends scala.tasty.Tasty { def constantClassTag: ClassTag[Constant] = implicitly[ClassTag[Constant]] - val UnitConstant: UnitExtractor = new UnitExtractor { - def unapply(x: Constant): Boolean = x match { - case x: Constants.Constant => x.tag == Constants.UnitTag - case _ => false + object Constant extends ConstantModule { + + object Unit extends UnitExtractor { + def unapply(x: Constant): Boolean = x match { + case x: Constants.Constant => x.tag == Constants.UnitTag + case _ => false + } } - } - val NullConstant: NullExtractor = new NullExtractor { - def unapply(x: Constant): Boolean = x match { - case x: Constants.Constant => x.tag == Constants.NullTag - case _ => false + object Null extends NullExtractor { + def unapply(x: Constant): Boolean = x match { + case x: Constants.Constant => x.tag == Constants.NullTag + case _ => false + } } - } - val BooleanConstant: BooleanExtractor = new BooleanExtractor { - def unapply(x: Constant): Option[Boolean] = x match { - case x: Constants.Constant if x.tag == Constants.BooleanTag => Some(x.booleanValue) - case _ => None + object Boolean extends BooleanExtractor { + def unapply(x: Constant): Option[Boolean] = x match { + case x: Constants.Constant if x.tag == Constants.BooleanTag => Some(x.booleanValue) + case _ => None + } } - } - val ByteConstant: ByteExtractor = new ByteExtractor { - def unapply(x: Constant): Option[Byte] = x match { - case x: Constants.Constant if x.tag == Constants.ByteTag => Some(x.byteValue) - case _ => None + object Byte extends ByteExtractor { + def unapply(x: Constant): Option[Byte] = x match { + case x: Constants.Constant if x.tag == Constants.ByteTag => Some(x.byteValue) + case _ => None + } } - } - val ShortConstant: ShortExtractor = new ShortExtractor { - def unapply(x: Constant): Option[Short] = x match { - case x: Constants.Constant if x.tag == Constants.ShortTag => Some(x.shortValue) - case _ => None + object Short extends ShortExtractor { + def unapply(x: Constant): Option[Short] = x match { + case x: Constants.Constant if x.tag == Constants.ShortTag => Some(x.shortValue) + case _ => None + } } - } - val CharConstant: CharExtractor = new CharExtractor { - def unapply(x: Constant): Option[Char] = x match { - case x: Constants.Constant if x.tag == Constants.CharTag => Some(x.charValue) - case _ => None + object Char extends CharExtractor { + def unapply(x: Constant): Option[Char] = x match { + case x: Constants.Constant if x.tag == Constants.CharTag => Some(x.charValue) + case _ => None + } } - } - val IntConstant: IntExtractor = new IntExtractor { - def unapply(x: Constant): Option[Int] = x match { - case x: Constants.Constant if x.tag == Constants.IntTag => Some(x.intValue) - case _ => None + object Int extends IntExtractor { + def unapply(x: Constant): Option[Int] = x match { + case x: Constants.Constant if x.tag == Constants.IntTag => Some(x.intValue) + case _ => None + } } - } - val LongConstant: LongExtractor = new LongExtractor { - def unapply(x: Constant): Option[Long] = x match { - case x: Constants.Constant if x.tag == Constants.LongTag => Some(x.longValue) - case _ => None + object Long extends LongExtractor { + def unapply(x: Constant): Option[Long] = x match { + case x: Constants.Constant if x.tag == Constants.LongTag => Some(x.longValue) + case _ => None + } } - } - val FloatConstant: FloatExtractor = new FloatExtractor { - def unapply(x: Constant): Option[Float] = x match { - case x: Constants.Constant if x.tag == Constants.FloatTag => Some(x.floatValue) - case _ => None + object Float extends FloatExtractor { + def unapply(x: Constant): Option[Float] = x match { + case x: Constants.Constant if x.tag == Constants.FloatTag => Some(x.floatValue) + case _ => None + } } - } - val DoubleConstant: DoubleExtractor = new DoubleExtractor { - def unapply(x: Constant): Option[Double] = x match { - case x: Constants.Constant if x.tag == Constants.DoubleTag => Some(x.doubleValue) - case _ => None + object Double extends DoubleExtractor { + def unapply(x: Constant): Option[Double] = x match { + case x: Constants.Constant if x.tag == Constants.DoubleTag => Some(x.doubleValue) + case _ => None + } } - } - val StringConstant: StringExtractor = new StringExtractor { - def unapply(x: Constant): Option[String] = x match { - case x: Constants.Constant if x.tag == Constants.StringTag => Some(x.stringValue) - case _ => None + object String extends StringExtractor { + def unapply(x: Constant): Option[String] = x match { + case x: Constants.Constant if x.tag == Constants.StringTag => Some(x.stringValue) + case _ => None + } } + } + // ===== Modifier ================================================= type Modifier = ModImpl diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index a73564fd4c9d..0e79100a5eb1 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -573,59 +573,64 @@ abstract class Tasty { implicit def constantClassTag: ClassTag[Constant] - val UnitConstant: UnitExtractor - abstract class UnitExtractor { - def unapply(x: Constant): Boolean - } - - val NullConstant: NullExtractor - abstract class NullExtractor { - def unapply(x: Constant): Boolean - } - - val BooleanConstant: BooleanExtractor - abstract class BooleanExtractor { - def unapply(x: Constant): Option[Boolean] - } - - val ByteConstant: ByteExtractor - abstract class ByteExtractor { - def unapply(x: Constant): Option[Byte] - } - - val ShortConstant: ShortExtractor - abstract class ShortExtractor { - def unapply(x: Constant): Option[Short] - } - - val CharConstant: CharExtractor - abstract class CharExtractor { - def unapply(x: Constant): Option[Char] - } - - val IntConstant: IntExtractor - abstract class IntExtractor { - def unapply(x: Constant): Option[Int] - } - - val LongConstant: LongExtractor - abstract class LongExtractor { - def unapply(x: Constant): Option[Long] - } - - val FloatConstant: FloatExtractor - abstract class FloatExtractor { - def unapply(x: Constant): Option[Float] - } - - val DoubleConstant: DoubleExtractor - abstract class DoubleExtractor { - def unapply(x: Constant): Option[Double] - } + val Constant: ConstantModule + abstract class ConstantModule { + + val Unit: UnitExtractor + abstract class UnitExtractor { + def unapply(x: Constant): Boolean + } + + val Null: NullExtractor + abstract class NullExtractor { + def unapply(x: Constant): Boolean + } + + val Boolean: BooleanExtractor + abstract class BooleanExtractor { + def unapply(x: Constant): Option[Boolean] + } + + val Byte: ByteExtractor + abstract class ByteExtractor { + def unapply(x: Constant): Option[Byte] + } + + val Short: ShortExtractor + abstract class ShortExtractor { + def unapply(x: Constant): Option[Short] + } + + val Char: CharExtractor + abstract class CharExtractor { + def unapply(x: Constant): Option[Char] + } + + val Int: IntExtractor + abstract class IntExtractor { + def unapply(x: Constant): Option[Int] + } + + val Long: LongExtractor + abstract class LongExtractor { + def unapply(x: Constant): Option[Long] + } + + val Float: FloatExtractor + abstract class FloatExtractor { + def unapply(x: Constant): Option[Float] + } + + val Double: DoubleExtractor + abstract class DoubleExtractor { + def unapply(x: Constant): Option[Double] + } + + val String: StringExtractor + abstract class StringExtractor { + def unapply(x: Constant): Option[String] + } - val StringConstant: StringExtractor - abstract class StringExtractor { - def unapply(x: Constant): Option[String] } // ===== Modifiers ================================================ diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index 7d0c5373b51b..5fe2ffa518bf 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -130,17 +130,17 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { } def visitConstant(x: Constant): Buffer = x match { - case UnitConstant() => this += "Unit()" - case NullConstant() => this += "Null()" - case BooleanConstant(value) => this += "Boolean(" += value += ")" - case ByteConstant(value) => this += "Byte(" += value += ")" - case ShortConstant(value) => this += "Short(" += value += ")" - case CharConstant(value) => this += "Char(" += value += ")" - case IntConstant(value) => this += "Int(" += value.toString += ")" - case LongConstant(value) => this += "Long(" += value += ")" - case FloatConstant(value) => this += "Float(" += value += ")" - case DoubleConstant(value) => this += "Double(" += value += ")" - case StringConstant(value) => this += "String(" += value += ")" + case Constant.Unit() => this += "Unit()" + case Constant.Null() => this += "Null()" + case Constant.Boolean(value) => this += "Boolean(" += value += ")" + case Constant.Byte(value) => this += "Byte(" += value += ")" + case Constant.Short(value) => this += "Short(" += value += ")" + case Constant.Char(value) => this += "Char(" += value += ")" + case Constant.Int(value) => this += "Int(" += value.toString += ")" + case Constant.Long(value) => this += "Long(" += value += ")" + case Constant.Float(value) => this += "Float(" += value += ")" + case Constant.Double(value) => this += "Double(" += value += ")" + case Constant.String(value) => this += "String(" += value += ")" } def visitType(x: TypeOrBounds): Buffer = x match { diff --git a/tests/run/tasty-eval/quoted_1.scala b/tests/run/tasty-eval/quoted_1.scala index c00a13445145..18d1857c79a4 100644 --- a/tests/run/tasty-eval/quoted_1.scala +++ b/tests/run/tasty-eval/quoted_1.scala @@ -25,10 +25,10 @@ object Macros { e.toTasty.tpe match { case SymRef(ValDef(_, tpt, _), pre) => tpt.tpe match { - case ConstantType(IntConstant(i)) => Some(i) + case ConstantType(Constant.Int(i)) => Some(i) case _ => None } - case ConstantType(IntConstant(i)) => Some(i) + case ConstantType(Constant.Int(i)) => Some(i) case _ => None } } diff --git a/tests/run/tasty-indexed-map/quoted_1.scala b/tests/run/tasty-indexed-map/quoted_1.scala index e8c4fa1a056f..fea6ab3113c5 100644 --- a/tests/run/tasty-indexed-map/quoted_1.scala +++ b/tests/run/tasty-indexed-map/quoted_1.scala @@ -32,7 +32,7 @@ object Index { import u.tasty._ def name(tp: TypeOrBounds): String = tp match { - case ConstantType(StringConstant(str)) => str + case ConstantType(Constant.String(str)) => str } def names(tp: TypeOrBounds): List[String] = tp match { From 756def7976c1aec7f7763aa9cfaeeee476ba9ee7 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 13:46:32 +0200 Subject: [PATCH 16/21] Move other extractors to objects --- .../dotty/tools/dotc/tasty/TastyImpl.scala | 688 +++++++++--------- library/src/scala/tasty/Tasty.scala | 515 ++++++------- .../scala/tasty/util/ConstantExtractor.scala | 6 +- .../src/scala/tasty/util/TastyPrinter.scala | 108 +-- .../scala/tasty/util/TreeAccumulator.scala | 69 +- tests/run/tasty-eval/quoted_1.scala | 6 +- tests/run/tasty-indexed-map/quoted_1.scala | 4 +- tests/run/tasty-macro-assert/quoted_1.scala | 6 +- 8 files changed, 714 insertions(+), 688 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index fc0867d124f6..1e71c2138a71 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -217,10 +217,6 @@ object TastyImpl extends scala.tasty.Tasty { type Term = tpd.Tree - val Term: TermCaster = new TermCaster { - def unapply(x: Term)(implicit ctx: Context): Boolean = x.isTerm - } - implicit def TermDeco(t: Term): AbstractTerm = new AbstractTerm { def pos(implicit ctx: Context): Position = new TastyPosition(t.pos) def tpe(implicit ctx: Context): Types.Type = t.tpe @@ -228,153 +224,159 @@ object TastyImpl extends scala.tasty.Tasty { def termClassTag: ClassTag[Term] = implicitly[ClassTag[Term]] - val Ident: IdentExtractor = new 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 _ => 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) + case _ => None + } } - } - val Select: SelectExtractor = new SelectExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, String, Option[Signature])] = x match { - case x: tpd.Select @unchecked if x.isTerm => - val sig = - if (x.symbol.signature == core.Signature.NotAMethod) None - else Some(x.symbol.signature) - Some((x.qualifier, x.name.toString, sig)) - 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 => + val sig = + if (x.symbol.signature == core.Signature.NotAMethod) None + else Some(x.symbol.signature) + Some((x.qualifier, x.name.toString, sig)) + case _ => None + } } - } - val Literal: LiteralExtractor = new LiteralExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[Constant] = x match { - case Trees.Literal(const) => Some(const) - case _ => None + object Literal extends LiteralExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Constant] = x match { + case Trees.Literal(const) => Some(const) + case _ => None + } } - } - val This: ThisExtractor = new ThisExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[Option[Id]] = x match { - case Trees.This(qual) => Some(if (qual.isEmpty) None else Some(qual)) - case _ => None + object This extends ThisExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Option[Id]] = x match { + case Trees.This(qual) => Some(if (qual.isEmpty) None else Some(qual)) + case _ => None + } } - } - val New: NewExtractor = new NewExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[TypeTree] = x match { - case x: tpd.New @unchecked => Some(x.tpt) - case _ => None + object New extends NewExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[TypeTree] = x match { + case x: tpd.New @unchecked => Some(x.tpt) + case _ => None + } } - } - val NamedArg: NamedArgExtractor = new 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 _ => 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 _ => None + } } - } - val Apply: ApplyExtractor = new 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 _ => 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 _ => None + } } - } - val TypeApply: TypeApplyExtractor = new 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 _ => 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 _ => None + } } - } - val Super: SuperExtractor = new 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 _ => 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 _ => None + } } - } - val Typed: TypedExtractor = new TypedExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, TypeTree)] = x match { - case x: tpd.Typed @unchecked => Some((x.expr, x.tpt)) - 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 _ => None + } } - } - val Assign: AssignExtractor = new AssignExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] = x match { - case x: tpd.Assign @unchecked => Some((x.lhs, x.rhs)) - 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 _ => None + } } - } - val Block: BlockExtractor = new BlockExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(List[Statement], Term)] = x match { - case x: tpd.Block @unchecked => Some((x.stats, x.expr)) - case _ => None + object Block extends BlockExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(List[Statement], Term)] = x match { + case x: tpd.Block @unchecked => Some((x.stats, x.expr)) + case _ => None + } } - } - val Inlined: InlinedExtractor = new InlinedExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Statement], Term)] = x match { - case x: tpd.Inlined @unchecked => - Some((x.call, x.bindings, x.expansion)) - case _ => None + object Inlined extends InlinedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Statement], Term)] = x match { + case x: tpd.Inlined @unchecked => + Some((x.call, x.bindings, x.expansion)) + case _ => None + } } - } - val Lambda: LambdaExtractor = new LambdaExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[TypeTree])] = x match { - case x: tpd.Closure @unchecked => Some((x.meth, if (x.tpt.isEmpty) None else Some(x.tpt))) - case _ => None + 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, if (x.tpt.isEmpty) None else Some(x.tpt))) + case _ => None + } } - } - val If: IfExtractor = new 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 _ => 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 _ => None + } } - } - val Match: MatchExtractor = new 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 _ => 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 _ => None + } } - } - val Try: TryExtractor = new 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, if (x.finalizer.isEmpty) None else Some(x.finalizer))) - 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, if (x.finalizer.isEmpty) None else Some(x.finalizer))) + case _ => None + } } - } - val Return: ReturnExtractor = new ReturnExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[Term] = x match { - case x: tpd.Return @unchecked => Some(x.expr) - 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 _ => None + } } - } - val Repeated: RepeatedExtractor = new RepeatedExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[List[Term]] = x match { - case x: tpd.SeqLiteral @unchecked => Some(x.elems) - 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 _ => None + } } - } - val SelectOuter: SelectOuterExtractor = new SelectOuterExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] = x match { - case x: tpd.Select @unchecked => - x.name match { - case NameKinds.OuterSelectName(_, levels) => Some((x.qualifier, levels, x.tpe.stripTypeVar)) - case _ => None - } - case _ => None + object SelectOuter extends SelectOuterExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] = x match { + case x: tpd.Select @unchecked => + x.name match { + case NameKinds.OuterSelectName(_, levels) => Some((x.qualifier, levels, x.tpe.stripTypeVar)) + case _ => None + } + case _ => None + } } + } // ----- CaseDef -------------------------------------------------- @@ -402,42 +404,47 @@ object TastyImpl extends scala.tasty.Tasty { def patternClassTag: ClassTag[Pattern] = implicitly[ClassTag[Pattern]] - val Value: ValueExtractor = new ValueExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[Term] = x match { - case lit: tpd.Literal @unchecked => Some(lit) - case ident: tpd.Ident @unchecked if ident.isTerm => Some(ident) - case _ => None + object Pattern extends PatternModule { + + object Value extends ValueExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[Term] = x match { + case lit: tpd.Literal @unchecked => Some(lit) + case ident: tpd.Ident @unchecked if ident.isTerm => Some(ident) + case _ => None + } } - } - val Bind: BindExtractor = new BindExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[(String, Pattern)] = x match { - case x: tpd.Bind @unchecked if x.name.isInstanceOf[Names.TermName] => Some(x.name.toString, x.body) - 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.isInstanceOf[Names.TermName] => Some(x.name.toString, x.body) + case _ => None + } } - } - val Unapply: UnapplyExtractor = new UnapplyExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[(Term, List[Term], List[Pattern])] = x match { - case x: tpd.UnApply @unchecked => Some(x.fun, x.implicits, x.patterns) - case _ => None + object Unapply extends UnapplyExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[(Term, List[Term], List[Pattern])] = x match { + case x: tpd.UnApply @unchecked => Some(x.fun, x.implicits, x.patterns) + case _ => None + } } - } - val Alternative: AlternativeExtractor = new AlternativeExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[List[Pattern]] = x match { - case x: tpd.Alternative @unchecked => Some(x.trees) - case _ => None + 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 _ => None + } } - } - val TypeTest: TypeTestExtractor = new TypeTestExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[TypeTree] = x match { - case x: tpd.Typed @unchecked => Some(x.tpt) - case _ => None + object TypeTest extends TypeTestExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[TypeTree] = x match { + case x: tpd.Typed @unchecked => Some(x.tpt) + case _ => None + } } + } + // ----- TypeOrBoundsTree ------------------------------------------------ type TypeOrBoundsTree = tpd.Tree @@ -450,85 +457,87 @@ object TastyImpl extends scala.tasty.Tasty { type TypeTree = tpd.Tree - val TypeTree: TypeTreeCaster = new TypeTreeCaster { - def unapply(x: TypeTree)(implicit ctx: Context): Boolean = x.isType - } - - def typeTreeClassTag: ClassTag[TypeTree] = implicitly[ClassTag[TypeTree]] - implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree = new AbstractTypeTree { def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) def tpe(implicit ctx: Context): Types.Type = x.tpe.stripTypeVar } - val Synthetic: SyntheticExtractor = new SyntheticExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Boolean = x match { - case Trees.TypeTree() => true - case _ => false + def typeTreeClassTag: ClassTag[TypeTree] = implicitly[ClassTag[TypeTree]] + + 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 Trees.TypeTree() => true + case _ => false + } } - } - val TypeIdent: TypeIdentExtractor = new 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 _ => None + 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 _ => None + } } - } - val TypeSelect: TypeSelectExtractor = new TypeSelectExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] = x match { - case x: tpd.Select @unchecked if x.isType => Some(x.qualifier, x.name.toString) - case _ => None + object TypeSelect extends TypeSelectExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] = x match { + case x: tpd.Select @unchecked if x.isType => Some(x.qualifier, x.name.toString) + case _ => None + } } - } - val Singleton: SingletonExtractor = new SingletonExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[Term] = x match { - case x: tpd.SingletonTypeTree @unchecked => Some(x.ref) - 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 _ => None + } } - } - val Refined: RefinedExtractor = new 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 _ => 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 _ => None + } } - } - val Applied: AppliedExtractor = new AppliedExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[TypeTree])] = x match { - case x: tpd.AppliedTypeTree @unchecked => Some(x.tpt, x.args) - case _ => None + object Applied extends AppliedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[TypeTree])] = x match { + case x: tpd.AppliedTypeTree @unchecked => Some(x.tpt, x.args) + case _ => None + } } - } - val Annotated: AnnotatedExtractor = new AnnotatedExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, Term)] = x match { - case x: tpd.Annotated @unchecked => Some(x.arg, x.annot) - 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 _ => None + } } - } - val And: AndExtractor = new AndExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { - case x: tpd.AndTypeTree @unchecked => Some(x.left, x.right) - 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 _ => None + } } - } - val Or: OrExtractor = new OrExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { - case x: tpd.OrTypeTree @unchecked => 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 _ => None + } } - } - val ByName: ByNameExtractor = new ByNameExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree] = x match { - case x: tpd.ByNameTypeTree @unchecked => Some(x.result) - 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 _ => None + } } + } // ----- TypeBoundsTrees ------------------------------------------------ @@ -553,173 +562,171 @@ object TastyImpl extends scala.tasty.Tasty { // ----- Types ---------------------------------------------------- type Type = Types.Type + type RecursiveType = Types.RecType + type LambdaType[ParamInfo <: TypeOrBounds] = Types.LambdaType { type PInfo = ParamInfo } + type MethodType = Types.MethodType + 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]] - val ConstantType: ConstantTypeExtractor = new ConstantTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Constant] = x match { - case Types.ConstantType(value) => Some(value) - case _ => None - } + implicit def MethodTypeDeco(x: MethodType): AbstractMethodType = new AbstractMethodType { + def isErased: Boolean = x.isErasedMethod + def isImplicit: Boolean = x.isImplicitMethod } - val SymRef: SymRefExtractor = new SymRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] = x match { - case tp: Types.NamedType => - tp.designator match { - case sym: Symbol => Some((FromSymbol.definition(sym), tp.prefix)) - case _ => None - } - case _ => None - } - } + object Type extends TypeModule { - val TermRef: TermRefExtractor = new TermRefExtractor { - def unapply(x: Type)(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) - case _ => None - } - case _ => None + def unapply(x: Type)(implicit ctx: Context): Boolean = x match { + case x: Types.TypeBounds => false + case x => x != Types.NoPrefix } - } - val TypeRef: TypeRefExtractor = new TypeRefExtractor { - def unapply(x: Type)(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) - case _ => None - } - case _ => None + object ConstantType extends ConstantTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Constant] = x match { + case Types.ConstantType(value) => Some(value) + case _ => None + } } - } - val SuperType: SuperTypeExtractor = new SuperTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { - case Types.SuperType(thistpe, supertpe) => Some(thistpe, supertpe) - case _ => None + object SymRef extends SymRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] = x match { + case tp: Types.NamedType => + tp.designator match { + case sym: Symbol => Some((FromSymbol.definition(sym), tp.prefix)) + case _ => None + } + case _ => None + } } - } - val Refinement: RefinementExtractor = new RefinementExtractor { - def unapply(x: Type)(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 TermRef extends TermRefExtractor { + def unapply(x: Type)(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) + case _ => None + } + case _ => None + } } - } - val AppliedType: AppliedTypeExtractor = new AppliedTypeExtractor { - def unapply(x: Type)(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 TypeRef extends TypeRefExtractor { + def unapply(x: Type)(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) + case _ => None + } + case _ => None + } } - } - val AnnotatedType: AnnotatedTypeExtractor = new AnnotatedTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] = x match { - case Types.AnnotatedType(underlying, annot) => Some((underlying.stripTypeVar, annot.tree)) - case _ => None + object SuperType extends SuperTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + case Types.SuperType(thistpe, supertpe) => Some(thistpe, supertpe) + case _ => None + } } - } - val AndType: AndTypeExtractor = new AndTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { - case Types.AndType(left, right) => Some(left.stripTypeVar, right.stripTypeVar) - case _ => None + object Refinement extends RefinementExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, TypeOrBounds /* Type | TypeBounds */)] = x match { + case Types.RefinedType(parent, name, info) => Some(parent, name.toString, info) + case _ => None + } } - } - val OrType: OrTypeExtractor = new OrTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { - case Types.OrType(left, right) => Some(left.stripTypeVar, right.stripTypeVar) - case _ => None + object AppliedType extends AppliedTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] = x match { + case Types.AppliedType(tycon, args) => Some((tycon.stripTypeVar, args.map(_.stripTypeVar))) + case _ => None + } } - } - val ByNameType: ByNameTypeExtractor = new ByNameTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { - case Types.ExprType(resType) => Some(resType.stripTypeVar) - case _ => None + object AnnotatedType extends AnnotatedTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] = x match { + case Types.AnnotatedType(underlying, annot) => Some((underlying.stripTypeVar, annot.tree)) + case _ => None + } } - } - val ParamRef: ParamRefExtractor = new ParamRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] = x match { - case Types.TypeParamRef(binder, idx) => - Some(( - binder.asInstanceOf[LambdaType[TypeOrBounds]], // Cast to tpd - idx)) - case _ => None + object AndType extends AndTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + case Types.AndType(left, right) => Some(left.stripTypeVar, right.stripTypeVar) + case _ => None + } } - } - val ThisType: ThisTypeExtractor = new ThisTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { - case Types.ThisType(tp) => Some(tp) - case _ => None + object OrType extends OrTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] = x match { + case Types.OrType(left, right) => Some(left.stripTypeVar, right.stripTypeVar) + case _ => None + } } - } - val RecursiveThis: RecursiveThisExtractor = new RecursiveThisExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[RecursiveType] = x match { - case Types.RecThis(binder) => Some(binder) - case _ => None + object ByNameType extends ByNameTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { + case Types.ExprType(resType) => Some(resType.stripTypeVar) + case _ => None + } } - } - - type RecursiveType = Types.RecType - def recursiveTypeClassTag: ClassTag[RecursiveType] = implicitly[ClassTag[RecursiveType]] - - val RecursiveType: RecursiveTypeExtractor = new RecursiveTypeExtractor { - def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] = x match { - case tp: Types.RecType => Some(tp.underlying.stripTypeVar) - case _ => None + object ParamRef extends ParamRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] = x match { + case Types.TypeParamRef(binder, idx) => + Some(( + binder.asInstanceOf[LambdaType[TypeOrBounds]], // Cast to tpd + idx)) + case _ => None + } } - } - - // ----- Methodic Types ------------------------------------------- - - type LambdaType[ParamInfo <: TypeOrBounds] = Types.LambdaType { type PInfo = ParamInfo } - type MethodType = Types.MethodType - - implicit def MethodTypeDeco(x: MethodType): AbstractMethodType = new AbstractMethodType { - def isErased: Boolean = x.isErasedMethod - def isImplicit: Boolean = x.isImplicitMethod - } - - def methodTypeClassTag: ClassTag[MethodType] = implicitly[ClassTag[MethodType]] - - val MethodType: MethodTypeExtractor = new MethodTypeExtractor { - def unapply(x: MethodType)(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 ThisType extends ThisTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Type] = x match { + case Types.ThisType(tp) => Some(tp) + case _ => None + } } - } - type PolyType = Types.PolyType - - def polyTypeClassTag: ClassTag[PolyType] = implicitly[ClassTag[PolyType]] + object RecursiveThis extends RecursiveThisExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[RecursiveType] = x match { + case Types.RecThis(binder) => Some(binder) + case _ => None + } + } - val PolyType: PolyTypeExtractor = new PolyTypeExtractor { - def unapply(x: PolyType)(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 RecursiveType extends RecursiveTypeExtractor { + def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] = x match { + case tp: Types.RecType => Some(tp.underlying.stripTypeVar) + case _ => None + } } - } - type TypeLambda = Types.TypeLambda + object MethodType extends MethodTypeExtractor { + def unapply(x: MethodType)(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 + } + } - def typeLambdaClassTag: ClassTag[TypeLambda] = implicitly[ClassTag[TypeLambda]] + object PolyType extends PolyTypeExtractor { + def unapply(x: PolyType)(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 + } + } - val TypeLambda: TypeLambdaExtractor = new TypeLambdaExtractor { - def unapply(x: TypeLambda)(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 + object TypeLambda extends TypeLambdaExtractor { + def unapply(x: TypeLambda)(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 + } } + } // ----- TypeBounds ------------------------------------------------ @@ -848,32 +855,37 @@ object TastyImpl extends scala.tasty.Tasty { def modifierClassTag: ClassTag[Modifier] = implicitly[ClassTag[Modifier]] - val Annotation: AnnotationExtractor = new AnnotationExtractor { - def unapply(x: Modifier)(implicit ctx: Context): Option[Term] = x match { - case ModAnnot(tree) => Some(tree) - case _ => None + + object Modifier extends ModifierModule { + + object Annotation extends AnnotationExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Term] = x match { + case ModAnnot(tree) => Some(tree) + case _ => None + } } - } - val Flags: FlagsExtractor = new FlagsExtractor { - def unapply(x: Modifier)(implicit ctx: Context): Option[FlagSet] = x match { - case ModFlags(flags) => Some(flags) - case _ => None + object Flags extends FlagsExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[FlagSet] = x match { + case ModFlags(flags) => Some(flags) + case _ => None + } } - } - val QualifiedPrivate: QualifiedPrivateExtractor = new QualifiedPrivateExtractor { - def unapply(x: Modifier)(implicit ctx: Context): Option[Type] = x match { - case ModQual(tp, false) => Some(tp) - case _ => None + object QualifiedPrivate extends QualifiedPrivateExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Type] = x match { + case ModQual(tp, false) => Some(tp) + case _ => None + } } - } - val QualifiedProtected: QualifiedProtectedExtractor = new QualifiedProtectedExtractor { - def unapply(x: Modifier)(implicit ctx: Context): Option[Type] = x match { - case ModQual(tp, true) => Some(tp) - case _ => None + object QualifiedProtected extends QualifiedProtectedExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Type] = x match { + case ModQual(tp, true) => Some(tp) + case _ => None + } } + } // ===== Signature ================================================ diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index 0e79100a5eb1..eac8e110aab8 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -168,114 +168,116 @@ abstract class Tasty { type Term <: Statement with Parent - val Term: TermCaster - abstract class TermCaster { - def unapply(x: Term)(implicit ctx: Context): Boolean - } - trait AbstractTerm extends Typed with Positioned implicit def TermDeco(t: Term): AbstractTerm implicit def termClassTag: ClassTag[Term] - val Ident: IdentExtractor - abstract class IdentExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[String] - } + val Term: TermModule + abstract class TermModule { - val Select: SelectExtractor - abstract class SelectExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, String, Option[Signature])] - } + def unapply(x: Term)(implicit ctx: Context): Boolean - val Literal: LiteralExtractor - abstract class LiteralExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[Constant] - } + val Ident: IdentExtractor + abstract class IdentExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[String] + } - val This: ThisExtractor - abstract class ThisExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[Option[Id]] - } + val Select: SelectExtractor + abstract class SelectExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, String, Option[Signature])] + } - val New: NewExtractor - abstract class NewExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[TypeTree] - } + val Literal: LiteralExtractor + abstract class LiteralExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Constant] + } - val NamedArg: NamedArgExtractor - abstract class NamedArgExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(String, Term)] - } + val This: ThisExtractor + abstract class ThisExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Option[Id]] + } - val Apply: ApplyExtractor - abstract class ApplyExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Term])] - } + val New: NewExtractor + abstract class NewExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[TypeTree] + } - val TypeApply: TypeApplyExtractor - abstract class TypeApplyExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[TypeTree])] - } + val NamedArg: NamedArgExtractor + abstract class NamedArgExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(String, Term)] + } - val Super: SuperExtractor - abstract class SuperExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[Id])] - } + val Apply: ApplyExtractor + abstract class ApplyExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Term])] + } - val Typed: TypedExtractor - abstract class TypedExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, TypeTree)] - } + val TypeApply: TypeApplyExtractor + abstract class TypeApplyExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[TypeTree])] + } - val Assign: AssignExtractor - abstract class AssignExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] - } + val Super: SuperExtractor + abstract class SuperExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[Id])] + } - val Block: BlockExtractor - abstract class BlockExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(List[Statement], Term)] - } + val Typed: TypedExtractor + abstract class TypedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, TypeTree)] + } - val Inlined: InlinedExtractor - abstract class InlinedExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Definition], Term)] - } + val Assign: AssignExtractor + abstract class AssignExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term)] + } - val Lambda: LambdaExtractor - abstract class LambdaExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[TypeTree])] - } + val Block: BlockExtractor + abstract class BlockExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(List[Statement], Term)] + } - val If: IfExtractor - abstract class IfExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term, Term)] - } + val Inlined: InlinedExtractor + abstract class InlinedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[Definition], Term)] + } - val Match: MatchExtractor - abstract class MatchExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef])] - } + val Lambda: LambdaExtractor + abstract class LambdaExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Option[TypeTree])] + } - val Try: TryExtractor - abstract class TryExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef], Option[Term])] - } + val If: IfExtractor + abstract class IfExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Term, Term)] + } - val Return: ReturnExtractor - abstract class ReturnExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[Term] - } + val Match: MatchExtractor + abstract class MatchExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef])] + } - val Repeated: RepeatedExtractor - abstract class RepeatedExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[List[Term]] - } + val Try: TryExtractor + abstract class TryExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, List[CaseDef], Option[Term])] + } + + val Return: ReturnExtractor + abstract class ReturnExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[Term] + } + + val Repeated: RepeatedExtractor + abstract class RepeatedExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[List[Term]] + } + + val SelectOuter: SelectOuterExtractor + abstract class SelectOuterExtractor { + def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] + } - val SelectOuter: SelectOuterExtractor - abstract class SelectOuterExtractor { - def unapply(x: Term)(implicit ctx: Context): Option[(Term, Int, Type)] } // ----- CaseDef -------------------------------------------------- @@ -298,29 +300,34 @@ abstract class Tasty { implicit def patternClassTag: ClassTag[Pattern] - val Value: ValueExtractor - abstract class ValueExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[Term] - } + val Pattern: PatternModule + abstract class PatternModule { - val Bind: BindExtractor - abstract class BindExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[(String, Pattern)] - } + val Value: ValueExtractor + abstract class ValueExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[Term] + } - val Unapply: UnapplyExtractor - abstract class UnapplyExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[(Term, List[Term], List[Pattern])] - } + val Bind: BindExtractor + abstract class BindExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[(String, Pattern)] + } - val Alternative: AlternativeExtractor - abstract class AlternativeExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[List[Pattern]] - } + val Unapply: UnapplyExtractor + abstract class UnapplyExtractor { + def unapply(x: 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]] + } + + val TypeTest: TypeTestExtractor + abstract class TypeTestExtractor { + def unapply(x: Pattern)(implicit ctx: Context): Option[TypeTree] + } - val TypeTest: TypeTestExtractor - abstract class TypeTestExtractor { - def unapply(x: Pattern)(implicit ctx: Context): Option[TypeTree] } // ----- TypeTrees ------------------------------------------------ @@ -337,64 +344,66 @@ abstract class Tasty { type TypeTree <: TypeOrBoundsTree with Parent - val TypeTree: TypeTreeCaster - abstract class TypeTreeCaster { - def unapply(x: TypeTree)(implicit ctx: Context): Boolean - } - trait AbstractTypeTree extends Typed with Positioned implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree implicit def typeTreeClassTag: ClassTag[TypeTree] - val Synthetic: SyntheticExtractor - abstract class SyntheticExtractor { + val TypeTree: TypeTreeModule + abstract class TypeTreeModule { + def unapply(x: TypeTree)(implicit ctx: Context): Boolean - } - val TypeIdent: TypeIdentExtractor - abstract class TypeIdentExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[String] - } + val Synthetic: SyntheticExtractor + abstract class SyntheticExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Boolean + } - val TypeSelect: TypeSelectExtractor - abstract class TypeSelectExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] - } + val TypeIdent: TypeIdentExtractor + abstract class TypeIdentExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[String] + } - val Singleton: SingletonExtractor - abstract class SingletonExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[Term] - } + val TypeSelect: TypeSelectExtractor + abstract class TypeSelectExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] + } - val Refined: RefinedExtractor - abstract class RefinedExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[Definition])] - } + val Singleton: SingletonExtractor + abstract class SingletonExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[Term] + } - val Applied: AppliedExtractor - abstract class AppliedExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[TypeTree])] - } + val Refined: RefinedExtractor + abstract class RefinedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[Definition])] + } - val Annotated: AnnotatedExtractor - abstract class AnnotatedExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, Term)] - } + val Applied: AppliedExtractor + abstract class AppliedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, List[TypeTree])] + } - val And: AndExtractor - abstract class AndExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] - } + val Annotated: AnnotatedExtractor + abstract class AnnotatedExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, Term)] + } - val Or: OrExtractor - abstract class OrExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] - } + val And: AndExtractor + abstract class AndExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] + } + + val Or: OrExtractor + abstract class OrExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] + } + + val ByName: ByNameExtractor + abstract class ByNameExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree] + } - val ByName: ByNameExtractor - abstract class ByNameExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[TypeTree] } // ----- TypeBoundsTrees ------------------------------------------------ @@ -425,120 +434,120 @@ abstract class Tasty { type Type <: TypeOrBounds - implicit def typeClassTag: ClassTag[Type] - - val ConstantType: ConstantTypeExtractor - abstract class ConstantTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Constant] - } - - val SymRef: SymRefExtractor - abstract class SymRefExtractor { - def unapply(x: Type)(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 */)] - } + type RecursiveType <: Type - val TypeRef: TypeRefExtractor - abstract class TypeRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] - } + type LambdaType[ParamInfo <: TypeOrBounds] <: Type + type MethodType <: LambdaType[Type] + type PolyType <: LambdaType[TypeBounds] + type TypeLambda <: LambdaType[TypeBounds] - val SuperType: SuperTypeExtractor - abstract class SuperTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] - } + 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] - val Refinement: RefinementExtractor - abstract class RefinementExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, TypeOrBounds /* Type | TypeBounds */)] + trait AbstractMethodType { + def isImplicit: Boolean + def isErased: Boolean } + implicit def MethodTypeDeco(x: MethodType): AbstractMethodType - val AppliedType: AppliedTypeExtractor - abstract class AppliedTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] - } + val Type: TypeModule + abstract class TypeModule { - val AnnotatedType: AnnotatedTypeExtractor - abstract class AnnotatedTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] - } + def unapply(x: Type)(implicit ctx: Context): Boolean - val AndType: AndTypeExtractor - abstract class AndTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] - } + val ConstantType: ConstantTypeExtractor + abstract class ConstantTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Constant] + } - val OrType: OrTypeExtractor - abstract class OrTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] - } + val SymRef: SymRefExtractor + abstract class SymRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Definition, TypeOrBounds /* Type | NoPrefix */)] + } - val ByNameType: ByNameTypeExtractor - abstract class ByNameTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Type] - } + val TermRef: TermRefExtractor + abstract class TermRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] + } - val ParamRef: ParamRefExtractor - abstract class ParamRefExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] - } + val TypeRef: TypeRefExtractor + abstract class TypeRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(String, TypeOrBounds /* Type | NoPrefix */)] + } - val ThisType: ThisTypeExtractor - abstract class ThisTypeExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[Type] - } + val SuperType: SuperTypeExtractor + abstract class SuperTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + } - val RecursiveThis: RecursiveThisExtractor - abstract class RecursiveThisExtractor { - def unapply(x: Type)(implicit ctx: Context): Option[RecursiveType] - } + val Refinement: RefinementExtractor + abstract class RefinementExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, String, TypeOrBounds /* Type | TypeBounds */)] + } - type RecursiveType <: Type - implicit def recursiveTypeClassTag: ClassTag[RecursiveType] - val RecursiveType: RecursiveTypeExtractor - abstract class RecursiveTypeExtractor { - def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] - } + val AppliedType: AppliedTypeExtractor + abstract class AppliedTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, List[TypeOrBounds /* Type | TypeBounds */])] + } - // ----- Methodic Types ------------------------------------------- + val AnnotatedType: AnnotatedTypeExtractor + abstract class AnnotatedTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Term)] + } - type LambdaType[ParamInfo <: TypeOrBounds] <: Type + val AndType: AndTypeExtractor + abstract class AndTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + } - type MethodType <: LambdaType[Type] + val OrType: OrTypeExtractor + abstract class OrTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(Type, Type)] + } - trait AbstractMethodType { - def isImplicit: Boolean - def isErased: Boolean - } - implicit def MethodTypeDeco(x: MethodType): AbstractMethodType + val ByNameType: ByNameTypeExtractor + abstract class ByNameTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Type] + } - implicit def methodTypeClassTag: ClassTag[MethodType] + val ParamRef: ParamRefExtractor + abstract class ParamRefExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[(LambdaType[TypeOrBounds], Int)] + } - val MethodType: MethodTypeExtractor - abstract class MethodTypeExtractor { - def unapply(x: MethodType)(implicit ctx: Context): Option[(List[String], List[Type], Type)] - } + val ThisType: ThisTypeExtractor + abstract class ThisTypeExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[Type] + } - type PolyType <: LambdaType[TypeBounds] + val RecursiveThis: RecursiveThisExtractor + abstract class RecursiveThisExtractor { + def unapply(x: Type)(implicit ctx: Context): Option[RecursiveType] + } - implicit def polyTypeClassTag: ClassTag[PolyType] + val RecursiveType: RecursiveTypeExtractor + abstract class RecursiveTypeExtractor { + def unapply(x: RecursiveType)(implicit ctx: Context): Option[Type] + } - val PolyType: PolyTypeExtractor - abstract class PolyTypeExtractor { - def unapply(x: PolyType)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] - } + val MethodType: MethodTypeExtractor + abstract class MethodTypeExtractor { + def unapply(x: MethodType)(implicit ctx: Context): Option[(List[String], List[Type], Type)] + } - type TypeLambda <: LambdaType[TypeBounds] + val PolyType: PolyTypeExtractor + abstract class PolyTypeExtractor { + def unapply(x: PolyType)(implicit ctx: Context): Option[(List[String], List[TypeBounds], Type)] + } - implicit def typeLambdaClassTag: ClassTag[TypeLambda] + val TypeLambda: TypeLambdaExtractor + abstract class TypeLambdaExtractor { + def unapply(x: TypeLambda)(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)] } // ----- TypeBounds ----------------------------------------------- @@ -639,26 +648,32 @@ abstract class Tasty { implicit def modifierClassTag: ClassTag[Modifier] - val Annotation: AnnotationExtractor - abstract class AnnotationExtractor { - def unapply(x: Modifier)(implicit ctx: Context): Option[Term] - } + val Modifier: ModifierModule + abstract class ModifierModule { - val Flags: FlagsExtractor - abstract class FlagsExtractor { - def unapply(x: Modifier)(implicit ctx: Context): Option[FlagSet] - } + val Annotation: AnnotationExtractor + abstract class AnnotationExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Term] + } - val QualifiedPrivate: QualifiedPrivateExtractor - abstract class QualifiedPrivateExtractor { - def unapply(x: Modifier)(implicit ctx: Context): Option[Type] - } + val Flags: FlagsExtractor + abstract class FlagsExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[FlagSet] + } + + val QualifiedPrivate: QualifiedPrivateExtractor + abstract class QualifiedPrivateExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Type] + } + + val QualifiedProtected: QualifiedProtectedExtractor + abstract class QualifiedProtectedExtractor { + def unapply(x: Modifier)(implicit ctx: Context): Option[Type] + } - val QualifiedProtected: QualifiedProtectedExtractor - abstract class QualifiedProtectedExtractor { - def unapply(x: Modifier)(implicit ctx: Context): Option[Type] } + // ===== Signature ================================================ type Signature diff --git a/library/src/scala/tasty/util/ConstantExtractor.scala b/library/src/scala/tasty/util/ConstantExtractor.scala index 13e7adeecaf7..a4c750721678 100644 --- a/library/src/scala/tasty/util/ConstantExtractor.scala +++ b/library/src/scala/tasty/util/ConstantExtractor.scala @@ -20,9 +20,9 @@ class ConstantExtractor[T <: Tasty with Singleton](val tasty: T) { def unapply[T](expr: Expr[T])(implicit ctx: Context): Option[T] = { def const(tree: Term): Option[T] = tree match { - case Literal(c) => Some(c.value.asInstanceOf[T]) - case Block(Nil, e) => const(e) - case Inlined(_, Nil, e) => const(e) + case Term.Literal(c) => Some(c.value.asInstanceOf[T]) + case Term.Block(Nil, e) => const(e) + case Term.Inlined(_, Nil, e) => const(e) case _ => None } const(expr.toTasty) diff --git a/library/src/scala/tasty/util/TastyPrinter.scala b/library/src/scala/tasty/util/TastyPrinter.scala index 5fe2ffa518bf..a8191369a9a3 100644 --- a/library/src/scala/tasty/util/TastyPrinter.scala +++ b/library/src/scala/tasty/util/TastyPrinter.scala @@ -27,43 +27,43 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { def result(): String = sb.result() def visitTree(x: Tree): Buffer = x match { - case Ident(name) => + case Term.Ident(name) => this += "Ident(" += name += ")" - case Select(qualifier, name, signature) => + case Term.Select(qualifier, name, signature) => this += "Select(" += qualifier += ", " += name += ", " += signature += ")" - case This(qual) => + case Term.This(qual) => this += "This(" += qual += ")" - case Super(qual, mix) => + case Term.Super(qual, mix) => this += "TypeApply(" += qual += ", " += mix += ")" - case Apply(fun, args) => + case Term.Apply(fun, args) => this += "Apply(" += fun += ", " ++= args += ")" - case TypeApply(fun, args) => + case Term.TypeApply(fun, args) => this += "TypeApply(" += fun += ", " ++= args += ")" - case Literal(const) => + case Term.Literal(const) => this += "Literal(" += const += ")" - case New(tpt) => + case Term.New(tpt) => this += "New(" += tpt += ")" - case Typed(expr, tpt) => + case Term.Typed(expr, tpt) => this += "Typed(" += expr += ", " += tpt += ")" - case NamedArg(name, arg) => + case Term.NamedArg(name, arg) => this += "NamedArg(" += name += ", " += arg += ")" - case Assign(lhs, rhs) => + case Term.Assign(lhs, rhs) => this += "Assign(" += lhs += ", " += rhs += ")" - case Block(stats, expr) => + case Term.Block(stats, expr) => this += "Block(" ++= stats += ", " += expr += ")" - case If(cond, thenp, elsep) => + case Term.If(cond, thenp, elsep) => this += "If(" += cond += ", " += thenp += ", " += elsep += ")" - case Lambda(meth, tpt) => + case Term.Lambda(meth, tpt) => this += "Lambda(" += meth += ", " += tpt += ")" - case Match(selector, cases) => + case Term.Match(selector, cases) => this += "Match(" += selector += ", " ++= cases += ")" - case Return(expr) => + case Term.Return(expr) => this += "Return(" += expr += ")" - case Try(block, handlers, finalizer) => + case Term.Try(block, handlers, finalizer) => this += "Try(" += block += ", " ++= handlers += ", " += finalizer += ")" - case Repeated(elems) => + case Term.Repeated(elems) => this += "Repeated(" ++= elems += ")" - case Inlined(call, bindings, expansion) => + case Term.Inlined(call, bindings, expansion) => this += "Inlined(" += call += ", " ++= bindings += ", " += expansion += ")" case ValDef(name, tpt, rhs) => this += "ValDef(" += name += ", " += tpt += ", " += rhs += ")" @@ -87,25 +87,25 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { } def visitTypeTree(x: TypeOrBoundsTree): Buffer = x match { - case Synthetic() => + case TypeTree.Synthetic() => this += "Synthetic()" - case TypeIdent(name) => + case TypeTree.TypeIdent(name) => this += "TypeIdent(" += name += ")" - case TypeSelect(qualifier, name) => + case TypeTree.TypeSelect(qualifier, name) => this += "TypeSelect(" += qualifier += ", " += name += ")" - case Singleton(ref) => + case TypeTree.Singleton(ref) => this += "Singleton(" += ref += ")" - case And(left, right) => + case TypeTree.And(left, right) => this += "And(" += left += ", " += right += ")" - case Or(left, right) => + case TypeTree.Or(left, right) => this += "Or(" += left += ", " += right += ")" - case Refined(tpt, refinements) => + case TypeTree.Refined(tpt, refinements) => this += "Refined(" += tpt += ", " ++= refinements += ")" - case Applied(tpt, args) => + case TypeTree.Applied(tpt, args) => this += "Applied(" += tpt += ", " ++= args += ")" - case ByName(result) => + case TypeTree.ByName(result) => this += "ByName(" += result += ")" - case Annotated(arg, annot) => + case TypeTree.Annotated(arg, annot) => this += "Annotated(" += arg += ", " += annot += ")" case TypeBoundsTree(lo, hi) => this += "TypeBoundsTree(" += lo += ", " += hi += ")" @@ -117,15 +117,15 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { } def visitPattern(x: Pattern): Buffer = x match { - case Value(v) => + case Pattern.Value(v) => this += "Value(" += v += ")" - case Bind(name, body) => + case Pattern.Bind(name, body) => this += "Bind(" += name += ", " += body += ")" - case Unapply(fun, implicits, patterns) => + case Pattern.Unapply(fun, implicits, patterns) => this += "Unapply(" += fun += ", " ++= implicits += ", " ++= patterns += ")" - case Alternative(patterns) => + case Pattern.Alternative(patterns) => this += "Alternative(" ++= patterns += ")" - case TypeTest(tpt) => + case Pattern.TypeTest(tpt) => this += "TypeTest(" += tpt += ")" } @@ -144,9 +144,9 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { } def visitType(x: TypeOrBounds): Buffer = x match { - case ConstantType(value) => + case Type.ConstantType(value) => this += "ConstantType(" += value += ")" - case SymRef(sym, qual) => + case Type.SymRef(sym, qual) => def visitName(sym: Definition): Buffer = sym match { case ValDef(name, _, _) => this += name case DefDef(name, _, _, _, _) => this += name @@ -158,33 +158,33 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { this += "SymRef(" visitName(sym) this += ", " += qual += ")" - case TermRef(name, qual) => + case Type.TermRef(name, qual) => this += "TermRef(" += name += ", " += qual += ")" - case TypeRef(name, qual) => + case Type.TypeRef(name, qual) => this += "TypeRef(" += name += ", " += qual += ")" - case Refinement(parent, name, info) => + case Type.Refinement(parent, name, info) => this += "Refinement(" += parent += ", " += name += ", " += info += ")" - case AppliedType(tycon, args) => + case Type.AppliedType(tycon, args) => this += "AppliedType(" += tycon += ", " ++= args += ")" - case AnnotatedType(underlying, annot) => + case Type.AnnotatedType(underlying, annot) => this += "AnnotatedType(" += underlying += ", " += annot += ")" - case AndType(left, right) => + case Type.AndType(left, right) => this += "AndType(" += left += ", " += right += ")" - case OrType(left, right) => + case Type.OrType(left, right) => this += "OrType(" += left += ", " += right += ")" - case ByNameType(underlying) => + case Type.ByNameType(underlying) => this += "ByNameType(" += underlying += ")" - case ParamRef(binder, idx) => + case Type.ParamRef(binder, idx) => this += "ParamRef(" += binder+= ", " += idx += ")" - case ThisType(tp) => + case Type.ThisType(tp) => this += "ThisType(" += tp += ")" - case RecursiveThis(binder) => + case Type.RecursiveThis(binder) => this += "RecursiveThis(" += binder += ")" - case MethodType(argNames, argTypes, resType) => + case Type.MethodType(argNames, argTypes, resType) => this += "MethodType(" ++= argNames += ", " ++= argTypes += ", " += resType += ")" - case PolyType(argNames, argBounds, resType) => + case Type.PolyType(argNames, argBounds, resType) => this += "PolyType(" ++= argNames += ", " ++= argBounds += ", " += resType += ")" - case TypeLambda(argNames, argBounds, resType) => + case Type.TypeLambda(argNames, argBounds, resType) => this += "TypeLambda(" ++= argNames += ", " ++= argBounds += ", " += resType += ")" case TypeBounds(lo, hi) => this += "TypeBounds(" += lo += ", " += hi += ")" @@ -193,10 +193,10 @@ class TastyPrinter[T <: Tasty with Singleton](val tasty: T) { } def visitModifier(x: Modifier): Buffer = x match { - case Flags(flags) => this += "Flags(" += flags.toString += ")" - case QualifiedPrivate(tp) => this += "QualifiedPrivate(" += tp += ")" - case QualifiedProtected(tp) => this += "QualifiedProtected(" += tp += ")" - case Annotation(tree) => this += "Annotation(" += tree += ")" + case Modifier.Flags(flags) => this += "Flags(" += flags.toString += ")" + case Modifier.QualifiedPrivate(tp) => this += "QualifiedPrivate(" += tp += ")" + case Modifier.QualifiedProtected(tp) => this += "QualifiedProtected(" += tp += ")" + case Modifier.Annotation(tree) => this += "Annotation(" += tree += ")" } def visitId(x: Id): Buffer = { diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index da5403cc3a02..e147340715c4 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -20,46 +20,45 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { def foldOverTree(x: X, tree: Tree)(implicit ctx: Context): X = { def localCtx(definition: Definition): Context = definition.localContext tree match { - case Ident(_) => + case Term.Ident(_) => x - case Select(qualifier, _, _) => + case Term.Select(qualifier, _, _) => foldTree(x, qualifier) - case This(qual) => + case Term.This(qual) => x - case Super(qual, _) => + case Term.Super(qual, _) => foldTree(x, qual) - case Apply(fun, args) => + case Term.Apply(fun, args) => foldTrees(foldTree(x, fun), args) - case TypeApply(fun, args) => + case Term.TypeApply(fun, args) => foldTypeTrees(foldTree(x, fun), args) - case Literal(const) => + case Term.Literal(const) => x - case New(tpt) => + case Term.New(tpt) => foldTypeTree(x, tpt) - case Typed(expr, tpt) => + case Term.Typed(expr, tpt) => foldTypeTree(foldTree(x, expr), tpt) - case NamedArg(_, arg) => + case Term.NamedArg(_, arg) => foldTree(x, arg) - case Assign(lhs, rhs) => + case Term.Assign(lhs, rhs) => foldTree(foldTree(x, lhs), rhs) - case Block(stats, expr) => + case Term.Block(stats, expr) => foldTree(foldTrees(x, stats), expr) - case If(cond, thenp, elsep) => + case Term.If(cond, thenp, elsep) => foldTree(foldTree(foldTree(x, cond), thenp), elsep) - case Lambda(meth, tpt) => + case Term.Lambda(meth, tpt) => val a = foldTree(x, meth) tpt.fold(a)(b => foldTypeTree(a, b)) - case Match(selector, cases) => + case Term.Match(selector, cases) => foldCaseDefs(foldTree(x, selector), cases) - case Return(expr) => + case Term.Return(expr) => foldTree(x, expr) - case Try(block, handler, finalizer) => + case Term.Try(block, handler, finalizer) => foldTrees(foldCaseDefs(foldTree(x, block), handler), finalizer) - case Repeated(elems) => + case Term.Repeated(elems) => foldTrees(x, elems) - case Inlined(call, bindings, expansion) => + case Term.Inlined(call, bindings, expansion) => foldTree(foldTrees(x, bindings), expansion) - case vdef @ ValDef(_, tpt, rhs) => implicit val ctx = localCtx(vdef) foldTrees(foldTypeTree(x, tpt), rhs) @@ -80,16 +79,16 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { } def foldOverTypeTree(x: X, tree: TypeOrBoundsTree)(implicit ctx: Context): X = tree match { - case Synthetic() => x - case TypeIdent(_) => x - case TypeSelect(qualifier, _) => foldTree(x, qualifier) - case Singleton(ref) => foldTree(x, ref) - case And(left, right) => foldTypeTree(foldTypeTree(x, left), right) - case Or(left, right) => foldTypeTree(foldTypeTree(x, left), right) - case Refined(tpt, refinements) => foldTrees(foldTypeTree(x, tpt), refinements) - case Applied(tpt, args) => foldTypeTrees(foldTypeTree(x, tpt), args) - case ByName(result) => foldTypeTree(x, result) - case Annotated(arg, annot) => foldTree(foldTypeTree(x, arg), annot) + case TypeTree.Synthetic() => x + case TypeTree.TypeIdent(_) => x + case TypeTree.TypeSelect(qualifier, _) => foldTree(x, qualifier) + case TypeTree.Singleton(ref) => foldTree(x, ref) + case TypeTree.And(left, right) => foldTypeTree(foldTypeTree(x, left), right) + case TypeTree.Or(left, right) => foldTypeTree(foldTypeTree(x, left), right) + case TypeTree.Refined(tpt, refinements) => foldTrees(foldTypeTree(x, tpt), refinements) + case TypeTree.Applied(tpt, args) => foldTypeTrees(foldTypeTree(x, tpt), args) + case TypeTree.ByName(result) => foldTypeTree(x, result) + case TypeTree.Annotated(arg, annot) => foldTree(foldTypeTree(x, arg), annot) case TypeBoundsTree(lo, hi) => foldTypeTree(foldTypeTree(x, lo), hi) } @@ -98,11 +97,11 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { } def foldOverPattern(x: X, tree: Pattern)(implicit ctx: Context): X = tree match { - case Value(v) => foldTree(x, v) - case Bind(_, body) => foldPattern(x, body) - case Unapply(fun, implicits, patterns) => foldPatterns(foldTrees(foldTree(x, fun), implicits), patterns) - case Alternative(patterns) => foldPatterns(x, patterns) - case TypeTest(tpt) => foldTypeTree(x, tpt) + case Pattern.Value(v) => foldTree(x, v) + case Pattern.Bind(_, body) => foldPattern(x, body) + case Pattern.Unapply(fun, implicits, patterns) => foldPatterns(foldTrees(foldTree(x, fun), implicits), patterns) + case Pattern.Alternative(patterns) => foldPatterns(x, patterns) + case Pattern.TypeTest(tpt) => foldTypeTree(x, tpt) } private def foldOverParent(x: X, tree: Parent)(implicit ctx: Context): X = tree match { diff --git a/tests/run/tasty-eval/quoted_1.scala b/tests/run/tasty-eval/quoted_1.scala index 18d1857c79a4..11617ff8761d 100644 --- a/tests/run/tasty-eval/quoted_1.scala +++ b/tests/run/tasty-eval/quoted_1.scala @@ -23,12 +23,12 @@ object Macros { import u._ import u.tasty._ e.toTasty.tpe match { - case SymRef(ValDef(_, tpt, _), pre) => + case Type.SymRef(ValDef(_, tpt, _), pre) => tpt.tpe match { - case ConstantType(Constant.Int(i)) => Some(i) + case Type.ConstantType(Constant.Int(i)) => Some(i) case _ => None } - case ConstantType(Constant.Int(i)) => Some(i) + case Type.ConstantType(Constant.Int(i)) => Some(i) case _ => None } } diff --git a/tests/run/tasty-indexed-map/quoted_1.scala b/tests/run/tasty-indexed-map/quoted_1.scala index fea6ab3113c5..f41cd00bcccf 100644 --- a/tests/run/tasty-indexed-map/quoted_1.scala +++ b/tests/run/tasty-indexed-map/quoted_1.scala @@ -32,11 +32,11 @@ object Index { import u.tasty._ def name(tp: TypeOrBounds): String = tp match { - case ConstantType(Constant.String(str)) => str + case Type.ConstantType(Constant.String(str)) => str } def names(tp: TypeOrBounds): List[String] = tp match { - case AppliedType(_, x1 :: x2 :: Nil) => name(x1) :: names(x2) + case Type.AppliedType(_, x1 :: x2 :: Nil) => name(x1) :: names(x2) case _ => Nil } diff --git a/tests/run/tasty-macro-assert/quoted_1.scala b/tests/run/tasty-macro-assert/quoted_1.scala index 61cf5f8bbb9f..c74f7bc675f7 100644 --- a/tests/run/tasty-macro-assert/quoted_1.scala +++ b/tests/run/tasty-macro-assert/quoted_1.scala @@ -23,20 +23,20 @@ object Asserts { val tree = cond.toTasty def isOps(tpe: TypeOrBounds): Boolean = tpe match { - case SymRef(DefDef("Ops", _, _, _, _), _) => true // TODO check that the parent is Asserts + case Type.SymRef(DefDef("Ops", _, _, _, _), _) => true // TODO check that the parent is Asserts case _ => false } object OpsTree { def unapply(arg: Term): Option[Term] = arg match { - case Apply(TypeApply(term, _), left :: Nil) if isOps(term.tpe) => + case Term.Apply(Term.TypeApply(term, _), left :: Nil) if isOps(term.tpe) => Some(left) case _ => None } } tree match { - case Apply(Select(OpsTree(left), op, _), right :: Nil) => + case Term.Apply(Term.Select(OpsTree(left), op, _), right :: Nil) => // FIXME splice the threes directly val printer = new TastyPrinter(tasty) val lExpr = printer.stringOfTree(left).toExpr From 1911fce8dbca7280669c71e108a64e2994f8db21 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 14:19:47 +0200 Subject: [PATCH 17/21] Update docs --- tests/pos/tasty/definitions.scala | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/pos/tasty/definitions.scala b/tests/pos/tasty/definitions.scala index d9c42ed1225f..1c0d85f7c291 100644 --- a/tests/pos/tasty/definitions.scala +++ b/tests/pos/tasty/definitions.scala @@ -39,19 +39,12 @@ object definitions { case class TypeDef(name: String, rhs: TypeTree | TypeBoundsTree) extends Definition { def mods: List[Modifier] = ??? } - case class ClassDef(name: String, constructor: DefDef, parents: List[Parent], + case class ClassDef(name: String, constructor: DefDef, parents: List[Term | TypeTree], self: Option[ValDef], body: List[Statement]) extends Definition { def mods: List[Modifier] = ??? } case class PackageDef(name: String, members: List[Statement]) extends Definition -// ------ Parents-------------------------------- - - enum Parent { - case TermParent(parent: Term) - case TypeParent(parent: TypeTree) - } - // ------ Terms --------------------------------- /** Trees denoting terms */ From f98450f256d1f022514d60cc03f65a308dcff456 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 16:31:25 +0200 Subject: [PATCH 18/21] Abstract tasty positions --- .../dotty/tools/dotc/tasty/TastyImpl.scala | 19 ++++++++++--------- library/src/scala/tasty/Tasty.scala | 5 ++++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index 1e71c2138a71..e9b9057d694a 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -37,7 +37,7 @@ object TastyImpl extends scala.tasty.Tasty { type Id = untpd.Ident implicit def IdDeco(x: Id): AbstractId = new AbstractId { - def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) + def pos(implicit ctx: Context): Position = x.pos } def idClassTag: ClassTag[Id] = implicitly[ClassTag[Id]] @@ -54,7 +54,7 @@ object TastyImpl extends scala.tasty.Tasty { type Tree = tpd.Tree implicit def TreeDeco(t: Tree): AbstractTree = new AbstractTree { - def pos(implicit ctx: Context): Position = new TastyPosition(t.pos) + def pos(implicit ctx: Context): Position = t.pos } type PackageClause = tpd.PackageDef @@ -218,7 +218,7 @@ object TastyImpl extends scala.tasty.Tasty { type Term = tpd.Tree implicit def TermDeco(t: Term): AbstractTerm = new AbstractTerm { - def pos(implicit ctx: Context): Position = new TastyPosition(t.pos) + def pos(implicit ctx: Context): Position = t.pos def tpe(implicit ctx: Context): Types.Type = t.tpe } @@ -398,7 +398,7 @@ object TastyImpl extends scala.tasty.Tasty { type Pattern = tpd.Tree implicit def PatternDeco(x: Pattern): AbstractPattern = new AbstractPattern { - def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) + def pos(implicit ctx: Context): Position = x.pos def tpe(implicit ctx: Context): Types.Type = x.tpe.stripTypeVar } @@ -458,7 +458,7 @@ object TastyImpl extends scala.tasty.Tasty { type TypeTree = tpd.Tree implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree = new AbstractTypeTree { - def pos(implicit ctx: Context): Position = new TastyPosition(x.pos) + def pos(implicit ctx: Context): Position = x.pos def tpe(implicit ctx: Context): Types.Type = x.tpe.stripTypeVar } @@ -901,9 +901,11 @@ object TastyImpl extends scala.tasty.Tasty { } - // ===== Private Methods ========================================== + // ===== Positions ================================================ - private class TastyPosition(val pos: SourcePosition) extends Position { + type Position = SourcePosition + + def PositionDeco(pos: Position): AbstractPosition = new AbstractPosition { def start = pos.start def end = pos.end @@ -914,7 +916,6 @@ object TastyImpl extends scala.tasty.Tasty { def startColumn = pos.startColumn def endColumn = pos.endColumn - - override def toString: String = s"Position(${pos.line}, ${pos.column})" } + } diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index eac8e110aab8..b08c275533c8 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -687,7 +687,9 @@ abstract class Tasty { // ===== Positions ================================================ - trait Position { + type Position + + trait AbstractPosition { def start: Int def end: Int @@ -698,6 +700,7 @@ abstract class Tasty { def endLine: Int def endColumn: Int } + implicit def PositionDeco(pos: Position): AbstractPosition trait Positioned { def pos(implicit ctx: Context): Position From b30672bb698a205efa2885214881a79ed674e734 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Fri, 11 May 2018 16:39:47 +0200 Subject: [PATCH 19/21] Cleanup TastyImpl: Remove implicits and make objects --- .../dotty/tools/dotc/tasty/TastyImpl.scala | 63 +++++++++---------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index e9b9057d694a..2f0e6e4b0afa 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -16,11 +16,11 @@ object TastyImpl extends scala.tasty.Tasty { // ===== Quotes =================================================== - implicit def QuotedExprDeco[T](x: quoted.Expr[T]): AbstractQuotedExpr = new AbstractQuotedExpr { + def QuotedExprDeco[T](x: quoted.Expr[T]): AbstractQuotedExpr = new AbstractQuotedExpr { def toTasty(implicit ctx: Context): Term = PickledQuotes.quotedExprToTree(x) } - implicit def QuotedTypeDeco[T](x: quoted.Type[T]): AbstractQuotedType = new AbstractQuotedType { + def QuotedTypeDeco[T](x: quoted.Type[T]): AbstractQuotedType = new AbstractQuotedType { def toTasty(implicit ctx: Context): TypeTree = PickledQuotes.quotedTypeToTree(x) } @@ -28,7 +28,7 @@ object TastyImpl extends scala.tasty.Tasty { type Context = Contexts.Context - implicit def ContextDeco(ctx: Context): AbstractContext = new AbstractContext { + def ContextDeco(ctx: Context): AbstractContext = new AbstractContext { def owner: Definition = FromSymbol.definition(ctx.owner)(ctx) } @@ -36,14 +36,14 @@ object TastyImpl extends scala.tasty.Tasty { type Id = untpd.Ident - implicit def IdDeco(x: Id): AbstractId = new AbstractId { + def IdDeco(x: Id): AbstractId = new AbstractId { def pos(implicit ctx: Context): Position = x.pos } def idClassTag: ClassTag[Id] = implicitly[ClassTag[Id]] - val Id: IdExtractor = new IdExtractor { - def unapply(x: Id) = x match { + 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 } @@ -53,7 +53,7 @@ object TastyImpl extends scala.tasty.Tasty { type Tree = tpd.Tree - implicit def TreeDeco(t: Tree): AbstractTree = new AbstractTree { + def TreeDeco(t: Tree): AbstractTree = new AbstractTree { def pos(implicit ctx: Context): Position = t.pos } @@ -61,14 +61,14 @@ object TastyImpl extends scala.tasty.Tasty { def packageClauseClassTag: ClassTag[PackageClause] = implicitly[ClassTag[PackageClause]] - val PackageClause: PackageClauseExtractor = new PackageClauseExtractor { + object PackageClause extends PackageClauseExtractor { def unapply(x: PackageClause)(implicit ctx: Context): Option[(Term, List[Tree])] = x match { case x: tpd.PackageDef @unchecked => Some((x.pid, x.stats)) case _ => None } } - implicit def PackageClauseDeco(x: PackageClause): AbstractPackageClause = new AbstractPackageClause { + def PackageClauseDeco(x: PackageClause): AbstractPackageClause = new AbstractPackageClause { override def definition: Definition = ??? } @@ -80,7 +80,7 @@ object TastyImpl extends scala.tasty.Tasty { def importClassTag: ClassTag[Import] = implicitly[ClassTag[Import]] - val Import: ImportExtractor = new ImportExtractor { + object Import extends ImportExtractor { def unapply(x: Import)(implicit ctx: Context): Option[(Term, List[ImportSelector])] = x match { case x: tpd.Import @unchecked => Some((x.expr, x.selectors)) case _ => None @@ -91,21 +91,21 @@ object TastyImpl extends scala.tasty.Tasty { def importSelectorClassTag: ClassTag[ImportSelector] = implicitly[ClassTag[ImportSelector]] - val SimpleSelector: SimpleSelectorExtractor = new SimpleSelectorExtractor { + 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 _ => None } } - val RenameSelector: RenameSelectorExtractor = new RenameSelectorExtractor { + object RenameSelector extends RenameSelectorExtractor { def unapply(x: ImportSelector)(implicit ctx: Context): Option[(Id, Id)] = x match { case Trees.Thicket((id1: untpd.Ident) :: (id2: untpd.Ident) :: Nil) if id2.name != nme.WILDCARD => Some(id1, id2) case _ => None } } - val OmitSelector: OmitSelectorExtractor = new OmitSelectorExtractor { + object OmitSelector extends OmitSelectorExtractor { def unapply(x: ImportSelector)(implicit ctx: Context): Option[Id] = x match { case Trees.Thicket((id: untpd.Ident) :: Trees.Ident(nme.WILDCARD) :: Nil) => Some(id) case _ => None @@ -116,7 +116,7 @@ object TastyImpl extends scala.tasty.Tasty { type Definition = tpd.Tree - implicit def DefinitionDeco(x: Definition): AbstractDefinition = new AbstractDefinition { + def DefinitionDeco(x: Definition): AbstractDefinition = new AbstractDefinition { def owner(implicit ctx: Context): Definition = FromSymbol.definition(x.symbol.owner) @@ -141,7 +141,7 @@ object TastyImpl extends scala.tasty.Tasty { def classDefClassTag: ClassTag[ClassDef] = implicitly[ClassTag[ClassDef]] - val ClassDef: ClassDefExtractor = new ClassDefExtractor { + object ClassDef extends ClassDefExtractor { def unapply(x: ClassDef)(implicit ctx: Context): Option[(String, DefDef, List[Parent], Option[ValDef], List[Statement])] = x match { case x: tpd.TypeDef @unchecked if x.isClassDef => val temp @ Trees.Template(constr, parents, self, _) = x.rhs @@ -157,7 +157,7 @@ object TastyImpl extends scala.tasty.Tasty { def defDefClassTag: ClassTag[DefDef] = implicitly[ClassTag[DefDef]] - val DefDef: DefDefExtractor = new DefDefExtractor { + object DefDef extends DefDefExtractor { def unapply(x: DefDef)(implicit ctx: Context): Option[(String, List[TypeDef], List[List[ValDef]], TypeTree, Option[Term])] = x match { case x: tpd.DefDef @unchecked => Some((x.name.toString, x.tparams, x.vparamss, x.tpt, if (x.rhs.isEmpty) None else Some(x.rhs))) @@ -171,7 +171,7 @@ object TastyImpl extends scala.tasty.Tasty { def valDefClassTag: ClassTag[ValDef] = implicitly[ClassTag[ValDef]] - val ValDef: ValDefExtractor = new ValDefExtractor { + object ValDef extends ValDefExtractor { def unapply(x: ValDef)(implicit ctx: Context): Option[(String, TypeTree, Option[Term])] = x match { case x: tpd.ValDef @unchecked => Some((x.name.toString, x.tpt, if (x.rhs.isEmpty) None else Some(x.rhs))) @@ -185,7 +185,7 @@ object TastyImpl extends scala.tasty.Tasty { def typeDefClassTag: ClassTag[TypeDef] = implicitly[ClassTag[TypeDef]] - val TypeDef: TypeDefExtractor = new TypeDefExtractor { + object TypeDef extends TypeDefExtractor { def unapply(x: TypeDef)(implicit ctx: Context): Option[(String, TypeOrBoundsTree /* TypeTree | TypeBoundsTree */)] = x match { case x: tpd.TypeDef @unchecked if !x.symbol.isClass => Some((x.name.toString, x.rhs)) case _ => None @@ -196,7 +196,7 @@ object TastyImpl extends scala.tasty.Tasty { def packageDefClassTag: ClassTag[PackageDef] = implicitly[ClassTag[PackageDef]] - val PackageDef: PackageDefExtractor = new PackageDefExtractor { + object PackageDef extends PackageDefExtractor { def unapply(x: PackageDef)(implicit ctx: Context): Option[(String, List[Statement])] = x match { case x: tpd.PackageDef => // FIXME Do not do this eagerly as it forces everithing in the package to be loaded. @@ -217,7 +217,7 @@ object TastyImpl extends scala.tasty.Tasty { type Term = tpd.Tree - implicit def TermDeco(t: Term): AbstractTerm = new AbstractTerm { + def TermDeco(t: Term): AbstractTerm = new AbstractTerm { def pos(implicit ctx: Context): Position = t.pos def tpe(implicit ctx: Context): Types.Type = t.tpe } @@ -385,7 +385,7 @@ object TastyImpl extends scala.tasty.Tasty { def caseDefClassTag: ClassTag[CaseDef] = implicitly[ClassTag[CaseDef]] - val CaseDef: CaseDefExtractor = new CaseDefExtractor { + object CaseDef extends CaseDefExtractor { def unapply(x: CaseDef): Option[(Pattern, Option[Term], Term)] = x match { case x: tpd.CaseDef @unchecked => Some(x.pat, if (x.guard.isEmpty) None else Some(x.guard), x.body) @@ -397,7 +397,7 @@ object TastyImpl extends scala.tasty.Tasty { type Pattern = tpd.Tree - implicit def PatternDeco(x: Pattern): AbstractPattern = new AbstractPattern { + def PatternDeco(x: Pattern): AbstractPattern = new AbstractPattern { def pos(implicit ctx: Context): Position = x.pos def tpe(implicit ctx: Context): Types.Type = x.tpe.stripTypeVar } @@ -449,7 +449,7 @@ object TastyImpl extends scala.tasty.Tasty { type TypeOrBoundsTree = tpd.Tree - implicit def TypeOrBoundsTreeDeco(x: TypeOrBoundsTree): AbstractTypeOrBoundsTree = new AbstractTypeOrBoundsTree { + def TypeOrBoundsTreeDeco(x: TypeOrBoundsTree): AbstractTypeOrBoundsTree = new AbstractTypeOrBoundsTree { def tpe(implicit ctx: Context): Type = x.tpe.stripTypeVar } @@ -457,7 +457,7 @@ object TastyImpl extends scala.tasty.Tasty { type TypeTree = tpd.Tree - implicit def TypeTreeDeco(x: TypeTree): AbstractTypeTree = new AbstractTypeTree { + def TypeTreeDeco(x: TypeTree): AbstractTypeTree = new AbstractTypeTree { def pos(implicit ctx: Context): Position = x.pos def tpe(implicit ctx: Context): Types.Type = x.tpe.stripTypeVar } @@ -544,11 +544,11 @@ object TastyImpl extends scala.tasty.Tasty { type TypeBoundsTree = tpd.TypeBoundsTree - implicit def TypeBoundsTreeDeco(x: TypeBoundsTree): AbstractTypeBoundsTree = ??? + def TypeBoundsTreeDeco(x: TypeBoundsTree): AbstractTypeBoundsTree = ??? def typeBoundsTreeClassTag: ClassTag[TypeBoundsTree] = implicitly[ClassTag[TypeBoundsTree]] - val TypeBoundsTree: TypeBoundsTreeExtractor = new TypeBoundsTreeExtractor { + object TypeBoundsTree extends TypeBoundsTreeExtractor { def unapply(x: TypeBoundsTree)(implicit ctx: Context): Option[(TypeTree, TypeTree)] = x match { case x: tpd.TypeBoundsTree @unchecked => Some(x.lo, x.hi) case _ => None @@ -574,7 +574,7 @@ object TastyImpl extends scala.tasty.Tasty { def polyTypeClassTag: ClassTag[PolyType] = implicitly[ClassTag[PolyType]] def typeLambdaClassTag: ClassTag[TypeLambda] = implicitly[ClassTag[TypeLambda]] - implicit def MethodTypeDeco(x: MethodType): AbstractMethodType = new AbstractMethodType { + def MethodTypeDeco(x: MethodType): AbstractMethodType = new AbstractMethodType { def isErased: Boolean = x.isErasedMethod def isImplicit: Boolean = x.isImplicitMethod } @@ -735,7 +735,7 @@ object TastyImpl extends scala.tasty.Tasty { def typeBoundsClassTag: ClassTag[TypeBounds] = implicitly[ClassTag[TypeBounds]] - val TypeBounds: TypeBoundsExtractor = new TypeBoundsExtractor { + object TypeBounds extends TypeBoundsExtractor { def unapply(x: TypeBounds)(implicit ctx: Context): Option[(Type, Type)] = x match { case x: Types.TypeBounds => Some(x.lo, x.hi) case _ => None @@ -748,7 +748,7 @@ object TastyImpl extends scala.tasty.Tasty { def noPrefixClassTag: ClassTag[NoPrefix] = implicitly[ClassTag[NoPrefix]] - val NoPrefix: NoPrefixExtractor = new NoPrefixExtractor { + object NoPrefix extends NoPrefixExtractor { def unapply(x: NoPrefix)(implicit ctx: Context): Boolean = x == Types.NoPrefix } @@ -756,7 +756,7 @@ object TastyImpl extends scala.tasty.Tasty { type Constant = Constants.Constant - implicit def ConstantDeco(x: Constant): AbstractConstant = new AbstractConstant { + def ConstantDeco(x: Constant): AbstractConstant = new AbstractConstant { def value: Any = x.value } @@ -894,13 +894,12 @@ object TastyImpl extends scala.tasty.Tasty { def signatureClassTag: ClassTag[Signature] = implicitly[ClassTag[Signature]] - val Signature: SignatureExtractor = new SignatureExtractor { + object Signature extends SignatureExtractor { def unapply(x: Signature)(implicit ctx: Context): Option[(List[String], String)] = { Some((x.paramsSig.map(_.toString), x.resSig.toString)) } } - // ===== Positions ================================================ type Position = SourcePosition From c460b52932a266bf91b027d1fe0e1233685e8816 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sat, 19 May 2018 11:25:45 +0200 Subject: [PATCH 20/21] Force read unpickled trees to avoid Ycheck failure --- .../src/dotty/tools/dotc/core/quoted/PickledQuotes.scala | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala index 1b87a7547000..629edec591d6 100644 --- a/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala +++ b/compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala @@ -16,7 +16,6 @@ import dotty.tools.dotc.core.tasty.{TastyPickler, TastyPrinter, TastyString} import scala.quoted.Types._ import scala.quoted.Exprs._ - import scala.reflect.ClassTag object PickledQuotes { @@ -53,7 +52,13 @@ object PickledQuotes { /** Transform the expression into its fully spliced Tree */ def quotedExprToTree[T](expr: quoted.Expr[T])(implicit ctx: Context): Tree = expr match { - case expr: TastyExpr[_] => unpickleExpr(expr) + case expr: TastyExpr[_] => + val unpickled = unpickleExpr(expr) + val force = new TreeTraverser { + def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = traverseChildren(tree) + } + force.traverse(unpickled) + unpickled case expr: LiftedExpr[T] => expr.value match { case value: Class[_] => ref(defn.Predef_classOf).appliedToType(classToType(value)) From 6f52db53a90c3de2e7dc79517dcc772523455474 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Sat, 19 May 2018 12:24:10 +0200 Subject: [PATCH 21/21] Make package definition tree to represent package symbols --- .../src/dotty/tools/dotc/tasty/FromSymbol.scala | 4 +--- .../src/dotty/tools/dotc/tasty/TastyImpl.scala | 4 ++-- .../src/dotty/tools/dotc/tasty/package.scala | 16 ++++++++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 compiler/src/dotty/tools/dotc/tasty/package.scala diff --git a/compiler/src/dotty/tools/dotc/tasty/FromSymbol.scala b/compiler/src/dotty/tools/dotc/tasty/FromSymbol.scala index 576808e4d391..deaf5cfd9b9a 100644 --- a/compiler/src/dotty/tools/dotc/tasty/FromSymbol.scala +++ b/compiler/src/dotty/tools/dotc/tasty/FromSymbol.scala @@ -5,7 +5,6 @@ import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Symbols._ import dotty.tools.dotc.core.Flags._ - object FromSymbol { def definition(sym: Symbol)(implicit ctx: Context): tpd.Tree = { @@ -18,8 +17,7 @@ object FromSymbol { else valDef(sym.asTerm) } - def packageDef(sym: Symbol)(implicit ctx: Context): tpd.PackageDef = - tpd.PackageDef(tpd.Ident(sym.typeRef), Nil) + def packageDef(sym: Symbol)(implicit ctx: Context): PackageDefinition = PackageDefinitionImpl(sym) def classDef(cls: ClassSymbol)(implicit ctx: Context): tpd.Tree = { val constr = tpd.DefDef(cls.unforcedDecls.find(_.isPrimaryConstructor).asTerm) diff --git a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala index 2f0e6e4b0afa..5b52b37ab2cd 100644 --- a/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tasty/TastyImpl.scala @@ -192,13 +192,13 @@ object TastyImpl extends scala.tasty.Tasty { } } - type PackageDef = tpd.Tree + type PackageDef = PackageDefinition def packageDefClassTag: ClassTag[PackageDef] = implicitly[ClassTag[PackageDef]] object PackageDef extends PackageDefExtractor { def unapply(x: PackageDef)(implicit ctx: Context): Option[(String, List[Statement])] = x match { - case x: tpd.PackageDef => + case x: PackageDefinition => // FIXME Do not do this eagerly as it forces everithing in the package to be loaded. // An alternative would be to add it as an extension method instead. val definitions = diff --git a/compiler/src/dotty/tools/dotc/tasty/package.scala b/compiler/src/dotty/tools/dotc/tasty/package.scala new file mode 100644 index 000000000000..106bae5f64a0 --- /dev/null +++ b/compiler/src/dotty/tools/dotc/tasty/package.scala @@ -0,0 +1,16 @@ +package dotty.tools.dotc + +import dotty.tools.dotc.ast.Trees.{Tree, Untyped} +import dotty.tools.dotc.core.Symbols.Symbol +import dotty.tools.dotc.core.Types.Type + +package object tasty { + + type PackageDefinition = PackageDefinitionImpl[Type] + + /** Represents the symbol of a definition in tree form */ + case class PackageDefinitionImpl[-T >: Untyped] private[tasty] (symbol: Symbol) extends Tree[T] { + type ThisTree[-T >: Untyped] = PackageDefinitionImpl[T] + } + +}