diff --git a/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala b/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala index 7c64df6e0e69..922c70cb31f6 100644 --- a/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala +++ b/compiler/src/dotty/tools/dotc/quoted/QuoteContextImpl.scala @@ -11,7 +11,6 @@ import dotty.tools.dotc.core.NameKinds import dotty.tools.dotc.core.StdNames._ import dotty.tools.dotc.quoted.reflect._ import dotty.tools.dotc.core.Decorators._ -import dotty.tools.dotc.quoted.reflect.FromSymbol.{definitionFromSym, packageDefFromSym} import dotty.tools.dotc.typer.Implicits import scala.quoted.QuoteContext @@ -154,13 +153,12 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext: case _ => None end StatementTypeTest - type Definition = tpd.Tree + type Definition = tpd.MemberDef object DefinitionTypeTest extends TypeTest[Tree, Definition]: def runtimeClass: Class[?] = classOf[Definition] override def unapply(x: Any): Option[Definition] = x match case x: tpd.MemberDef @unchecked => Some(x) - case x: PackageDefinition @unchecked => Some(x) case _ => None end DefinitionTypeTest @@ -170,7 +168,6 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext: extension (self: Definition): def name: String = self match case self: tpd.MemberDef => self.name.toString - case self: PackageDefinition => self.symbol.name.toString // TODO make PackageDefinition a MemberDef or NameTree end extension end DefinitionMethodsImpl @@ -284,29 +281,6 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext: end extension end TypeDefMethodsImpl - type PackageDef = PackageDefinition - - object PackageDefTypeTest extends TypeTest[Tree, PackageDef]: - def runtimeClass: Class[?] = classOf[PackageDef] - override def unapply(x: Any): Option[PackageDef] = x match - case x: PackageDefinition @unchecked => Some(x) - case _ => None - end PackageDefTypeTest - - object PackageDef extends PackageDefModule: - def unapply(tree: PackageDef): Option[(String, PackageDef)] = - Some((tree.name, tree.owner)) - end PackageDef - - object PackageDefMethodsImpl extends PackageDefMethods: - extension (self: PackageDef): - def owner: PackageDef = packageDefFromSym(self.symbol.owner) - def members: List[Statement] = - if (self.symbol.is(JavaDefined)) Nil // FIXME should also support java packages - else self.symbol.info.decls.iterator.map(definitionFromSym).toList - end extension - end PackageDefMethodsImpl - type Term = tpd.Tree object TermTypeTest extends TypeTest[Tree, Term]: @@ -1137,13 +1111,13 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext: def copy(original: Tree)(tpt: TypeTree, refinements: List[Definition]): Refined = tpd.cpy.RefinedTypeTree(original)(tpt, refinements) def unapply(x: Refined): Option[(TypeTree, List[Definition])] = - Some((x.tpt, x.refinements)) + Some((x.tpt, x.refinements.asInstanceOf[List[Definition]])) end Refined object RefinedMethodsImpl extends RefinedMethods: extension (self: Refined): def tpt: TypeTree = self.tpt - def refinements: List[Definition] = self.refinements + def refinements: List[Definition] = self.refinements.asInstanceOf[List[Definition]] end extension end RefinedMethodsImpl @@ -2288,6 +2262,9 @@ class QuoteContextImpl private (ctx: Context) extends QuoteContext: case sym if isMethod(sym) => sym.asTerm }.toList + def members: List[Symbol] = + self.typeRef.info.decls.toList + def typeMembers: List[Symbol] = self.unforcedDecls.filter(_.isType) diff --git a/compiler/src/dotty/tools/dotc/quoted/reflect/FromSymbol.scala b/compiler/src/dotty/tools/dotc/quoted/reflect/FromSymbol.scala index 7f90ecabfd09..97079e0d343b 100644 --- a/compiler/src/dotty/tools/dotc/quoted/reflect/FromSymbol.scala +++ b/compiler/src/dotty/tools/dotc/quoted/reflect/FromSymbol.scala @@ -12,9 +12,9 @@ import dotty.tools.dotc.core.Types._ object FromSymbol { def definitionFromSym(sym: Symbol)(using Context): tpd.Tree = { - assert(sym.exists) - if (sym.is(Package)) packageDefFromSym(sym) - else if (sym.isClass) classDef(sym.asClass) + assert(sym.exists, "Cannot get tree of no symbol") + assert(!sym.is(Package), "Cannot get tree of package symbol") + if (sym.isClass) classDef(sym.asClass) else if (sym.isType && sym.is(Case)) typeBindFromSym(sym.asType) else if (sym.isType) typeDefFromSym(sym.asType) else if (sym.is(Method)) defDefFromSym(sym.asTerm) @@ -22,8 +22,6 @@ object FromSymbol { else valDefFromSym(sym.asTerm) } - def packageDefFromSym(sym: Symbol)(using Context): PackageDefinition = PackageDefinitionImpl(sym) - def classDef(cls: ClassSymbol)(using Context): tpd.TypeDef = cls.defTree match { case tree: tpd.TypeDef => tree case tpd.EmptyTree => diff --git a/compiler/src/dotty/tools/dotc/quoted/reflect/package.scala b/compiler/src/dotty/tools/dotc/quoted/reflect/package.scala deleted file mode 100644 index 4f8475bfce6a..000000000000 --- a/compiler/src/dotty/tools/dotc/quoted/reflect/package.scala +++ /dev/null @@ -1,22 +0,0 @@ -package dotty.tools.dotc.quoted - -import dotty.tools.dotc.ast.Trees.{Tree, Untyped} -import dotty.tools.dotc.core.Contexts._ -import dotty.tools.dotc.core.Symbols.Symbol -import dotty.tools.dotc.core.Types.Type -import dotty.tools.dotc.util.SourceFile -import dotty.tools.dotc.core.SymDenotations.SymDenotation -import scala.annotation.constructorOnly - -package object reflect { - - type PackageDefinition = PackageDefinitionImpl[Type] - - /** Represents the symbol of a definition in tree form */ - case class PackageDefinitionImpl[-T >: Untyped] private[reflect] (sym: Symbol)(implicit @constructorOnly src: SourceFile) extends Tree[T] { - type ThisTree[-T >: Untyped] = PackageDefinitionImpl[T] - - override def denot(using Context): SymDenotation = sym.denot - } -} - diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index 8f721b7b7d19..de8df6033c03 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -20,8 +20,7 @@ import scala.tasty.reflect._ * * +- Tree -+- PackageClause * +- Import - * +- Statement -+- Definition --+- PackageDef - * | | +- ClassDef + * +- Statement -+- Definition --+- ClassDef * | | +- TypeDef * | | +- DefDef * | | +- ValDef @@ -225,7 +224,7 @@ trait Reflection { reflection => // ----- Definitions ---------------------------------------------- - /** Tree representing a definition in the source code. It can be `PackageDef`, `ClassDef`, `TypeDef`, `DefDef` or `ValDef` */ + /** Tree representing a definition in the source code. It can be `ClassDef`, `TypeDef`, `DefDef` or `ValDef` */ type Definition <: Statement given TypeTest[Tree, Definition] = DefinitionTypeTest @@ -352,29 +351,6 @@ trait Reflection { reflection => end extension end TypeDefMethods - // PackageDef - - /** Tree representing a package definition. This includes definitions in all source files */ - type PackageDef <: Definition - - given TypeTest[Tree, PackageDef] = PackageDefTypeTest - protected val PackageDefTypeTest: TypeTest[Tree, PackageDef] - - val PackageDef: PackageDefModule - - trait PackageDefModule { this: PackageDef.type => - def unapply(tree: PackageDef): Option[(String, PackageDef)] - } - - given PackageDefMethods as PackageDefMethods = PackageDefMethodsImpl - protected val PackageDefMethodsImpl: PackageDefMethods - - trait PackageDefMethods: - extension (self: PackageDef): - def owner: PackageDef - def members: List[Statement] - end extension - end PackageDefMethods // ----- Terms ---------------------------------------------------- @@ -2555,14 +2531,14 @@ trait Reflection { reflection => def comment: Option[Comment] /** Tree of this definition - * - * if this symbol `isPackageDef` it will return a `PackageDef`, - * if this symbol `isClassDef` it will return a `ClassDef`, - * if this symbol `isTypeDef` it will return a `TypeDef`, - * if this symbol `isValDef` it will return a `ValDef`, - * if this symbol `isDefDef` it will return a `DefDef` - * if this symbol `isBind` it will return a `Bind` - */ + * + * If this symbol `isClassDef` it will return `a `ClassDef`, + * if this symbol `isTypeDef` it will return `a `TypeDef`, + * if this symbol `isValDef` it will return `a `ValDef`, + * if this symbol `isDefDef` it will return `a `DefDef` + * if this symbol `isBind` it will return `a `Bind`, + * else will throw + */ def tree: Tree /** Annotations attached to this symbol */ @@ -2626,6 +2602,9 @@ trait Reflection { reflection => /** Type member with the given name directly declared in the class */ def typeMember(name: String): Symbol + /** All members directly declared in the class */ + def members: List[Symbol] + /** Get named non-private methods declared or inherited */ def method(name: String): List[Symbol] diff --git a/library/src/scala/tasty/reflect/ExtractorsPrinter.scala b/library/src/scala/tasty/reflect/ExtractorsPrinter.scala index 464e7a4f63be..216c161a37e1 100644 --- a/library/src/scala/tasty/reflect/ExtractorsPrinter.scala +++ b/library/src/scala/tasty/reflect/ExtractorsPrinter.scala @@ -118,8 +118,6 @@ class ExtractorsPrinter[R <: Reflection & Singleton](val tasty: R) extends Print this += ", " visitList[TypeTree](derived, visitTree) this += ", " += self += ", " ++= body += ")" - case PackageDef(name, owner) => - this += "PackageDef(\"" += name += "\", " += owner += ")" case Import(expr, selectors) => this += "Import(" += expr += ", " ++= selectors += ")" case PackageClause(pid, stats) => diff --git a/library/src/scala/tasty/reflect/SourceCodePrinter.scala b/library/src/scala/tasty/reflect/SourceCodePrinter.scala index 54d13d6dd0ed..d19293b80ec5 100644 --- a/library/src/scala/tasty/reflect/SourceCodePrinter.scala +++ b/library/src/scala/tasty/reflect/SourceCodePrinter.scala @@ -1228,12 +1228,11 @@ class SourceCodePrinter[R <: Reflection & Singleton](val tasty: R)(syntaxHighlig case RenameSelector(name, newName) => this += name += " => " += newName } - def printDefinitionName(sym: Definition): Buffer = sym match { + def printDefinitionName(tree: Definition): Buffer = tree match { case ValDef(name, _, _) => this += highlightValDef(name) case DefDef(name, _, _, _, _) => this += highlightValDef(name) case ClassDef(name, _, _, _, _, _) => this += highlightTypeDef(name.stripSuffix("$")) case TypeDef(name, _) => this += highlightTypeDef(name) - case PackageDef(name, _) => this += highlightTypeDef(name) } def printAnnotation(annot: Term)(using elideThis: Option[Symbol]): Buffer = { diff --git a/tests/pos-macros/i8521/Macro_1.scala b/tests/pos-macros/i8521/Macro_1.scala new file mode 100644 index 000000000000..7488ef448816 --- /dev/null +++ b/tests/pos-macros/i8521/Macro_1.scala @@ -0,0 +1,26 @@ +import scala.quoted._ + +object Foo { + inline def foo[T <: AnyKind]: String = ${ bar[T] } + + def bar[T <: AnyKind : Type](using qctx: QuoteContext): Expr[String] = { + import qctx.tasty.{Type => _, _} + + def packageToName(sym: Symbol): Unit = { + if sym.isPackageDef then + packageToName(sym.owner) + } + + val sym = implicitly[Type[T]].unseal.symbol + if (!sym.isNoSymbol) { + sym.tree match { + case c: ClassDef => + if (!sym.maybeOwner.isNoSymbol) { + if sym.maybeOwner.isPackageDef then + packageToName(sym.maybeOwner) + } + } + } + Expr("") + } +} diff --git a/tests/pos-macros/i8521/Tes_2.scala b/tests/pos-macros/i8521/Tes_2.scala new file mode 100644 index 000000000000..ac223dc68e0f --- /dev/null +++ b/tests/pos-macros/i8521/Tes_2.scala @@ -0,0 +1,5 @@ +class A + +object Test { + def test = Foo.foo[A] +}