diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala index 7d33317a9eef..c1981f6c6edd 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/TastyImpl.scala @@ -554,9 +554,16 @@ object TastyImpl extends scala.tasty.Tasty { } } - object TypeSelect extends TypeSelectExtractor { + object TermSelect extends TermSelectExtractor { 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 x: tpd.Select @unchecked if x.isType && x.qualifier.isTerm => Some(x.qualifier, x.name.toString) + case _ => None + } + } + + object TypeSelect extends TypeSelectExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, String)] = x match { + case x: tpd.Select @unchecked if x.isType && x.qualifier.isType => Some(x.qualifier, x.name.toString) case _ => None } } diff --git a/library/src/scala/tasty/Tasty.scala b/library/src/scala/tasty/Tasty.scala index e66f4fe76fc4..4c6f11350f8e 100644 --- a/library/src/scala/tasty/Tasty.scala +++ b/library/src/scala/tasty/Tasty.scala @@ -433,9 +433,14 @@ abstract class Tasty { tasty => def unapply(x: TypeTree)(implicit ctx: Context): Option[String] } + val TermSelect: TermSelectExtractor + abstract class TermSelectExtractor { + def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] + } + val TypeSelect: TypeSelectExtractor abstract class TypeSelectExtractor { - def unapply(x: TypeTree)(implicit ctx: Context): Option[(Term, String)] + def unapply(x: TypeTree)(implicit ctx: Context): Option[(TypeTree, String)] } val Singleton: SingletonExtractor diff --git a/library/src/scala/tasty/util/ShowExtractors.scala b/library/src/scala/tasty/util/ShowExtractors.scala index 6f2b0e83c313..72c143c41db6 100644 --- a/library/src/scala/tasty/util/ShowExtractors.scala +++ b/library/src/scala/tasty/util/ShowExtractors.scala @@ -94,6 +94,8 @@ class ShowExtractors[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty this += "TypeTree.Synthetic()" case TypeTree.TypeIdent(name) => this += "TypeTree.TypeIdent(\"" += name += "\")" + case TypeTree.TermSelect(qualifier, name) => + this += "TypeTree.TermSelect(" += qualifier += ", \"" += name += "\")" case TypeTree.TypeSelect(qualifier, name) => this += "TypeTree.TypeSelect(" += qualifier += ", \"" += name += "\")" case TypeTree.Singleton(ref) => diff --git a/library/src/scala/tasty/util/ShowSourceCode.scala b/library/src/scala/tasty/util/ShowSourceCode.scala index 86a1b629bc75..b128ebe8d4ec 100644 --- a/library/src/scala/tasty/util/ShowSourceCode.scala +++ b/library/src/scala/tasty/util/ShowSourceCode.scala @@ -85,7 +85,7 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty val parents1 = parents.filter { case Term.Apply(Term.Select(Term.New(tpt), _, _), _) => !Types.JavaLangObject.unapply(tpt.tpe) - case TypeTree.TypeSelect(Term.Select(Term.Ident("_root_"), "scala", _), "Product") => false + case TypeTree.TermSelect(Term.Select(Term.Ident("_root_"), "scala", _), "Product") => false case _ => true } if (parents1.nonEmpty) { @@ -701,12 +701,11 @@ class ShowSourceCode[T <: Tasty with Singleton](tasty0: T) extends Show[T](tasty case TypeTree.TypeIdent(name) => printType(tree.tpe) + case TypeTree.TermSelect(qual, name) => + printTree(qual) += "." += name + case TypeTree.TypeSelect(qual, name) => - (qual: Any) match { - case qual @ TypeTree.TypeIdent(_) => printTypeTree(qual) // FIXME: qual is of type Tree buy we are getting a TypeTree qualifier - case _ => printTree(qual) - } - this += "." += name + printTypeTree(qual) += "#" += name case TypeTree.Singleton(ref) => printTree(ref) diff --git a/library/src/scala/tasty/util/TreeAccumulator.scala b/library/src/scala/tasty/util/TreeAccumulator.scala index e147340715c4..c2da959397b9 100644 --- a/library/src/scala/tasty/util/TreeAccumulator.scala +++ b/library/src/scala/tasty/util/TreeAccumulator.scala @@ -81,7 +81,8 @@ abstract class TreeAccumulator[X, T <: Tasty with Singleton](val tasty: T) { def foldOverTypeTree(x: X, tree: TypeOrBoundsTree)(implicit ctx: Context): X = tree match { case TypeTree.Synthetic() => x case TypeTree.TypeIdent(_) => x - case TypeTree.TypeSelect(qualifier, _) => foldTree(x, qualifier) + case TypeTree.TermSelect(qualifier, _) => foldTree(x, qualifier) + case TypeTree.TypeSelect(qualifier, _) => foldTypeTree(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) diff --git a/tests/pos/simpleTypeSelect.decompiled b/tests/pos/simpleTypeSelect.decompiled new file mode 100644 index 000000000000..4619340bb43b --- /dev/null +++ b/tests/pos/simpleTypeSelect.decompiled @@ -0,0 +1,8 @@ +/** Decompiled from out/posTestFromTasty/pos/simpleTypeSelect/Foo.class */ +trait Foo() extends java.lang.Object { + type Bar +} +/** Decompiled from out/posTestFromTasty/pos/simpleTypeSelect/Test.class */ +object Test { + val x: Foo#Bar = scala.Predef.??? +} diff --git a/tests/pos/simpleTypeSelect.scala b/tests/pos/simpleTypeSelect.scala new file mode 100644 index 000000000000..2aa4d3e913e1 --- /dev/null +++ b/tests/pos/simpleTypeSelect.scala @@ -0,0 +1,5 @@ + +trait Foo { type Bar } +object Test { + val x: Foo#Bar = ??? +} diff --git a/tests/pos/tasty/definitions.scala b/tests/pos/tasty/definitions.scala index a90e6912e7c3..7d1568824afa 100644 --- a/tests/pos/tasty/definitions.scala +++ b/tests/pos/tasty/definitions.scala @@ -92,7 +92,8 @@ object definitions { def tpe: Type = ??? case Synthetic() case Ident(name: String, override val tpe: Type) - case Select(prefix: Term, name: String) + case TermSelect(prefix: Term, name: String) + case TypeSelect(prefix: TypeTree, name: String) case Singleton(ref: Term) case Refined(underlying: TypeTree, refinements: List[Definition]) case Applied(tycon: TypeTree, args: List[TypeTree | TypeBoundsTree]) diff --git a/tests/run/tasty-extractors-2.check b/tests/run/tasty-extractors-2.check index 3247ffb7a635..2baf5ba3e382 100644 --- a/tests/run/tasty-extractors-2.check +++ b/tests/run/tasty-extractors-2.check @@ -100,10 +100,10 @@ Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef(" Term.Block(List(ClassDef("Foo", DefDef("", Nil, List(List(ValDef("i", TypeTree.TypeIdent("Int"), None))), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(ValDef("i", TypeTree.Synthetic(), None))), ClassDef("Bar", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.TypeIdent("Foo")), "", Some(Signature(List(scala.Int), Test$._$Foo))), List(Term.Literal(Constant.Int(1))))), None, Nil)), Term.Literal(Constant.Unit())) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Block(List(ClassDef("Foo", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("X", TypeTree.TypeIdent("Int")))), DefDef("f", Nil, List(List(ValDef("a", TypeTree.TypeIdent("Foo"), None))), TypeTree.TypeSelect(Term.Ident("a"), "X"), Some(Term.Ident("???")))), Term.Literal(Constant.Unit())) +Term.Block(List(ClassDef("Foo", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("X", TypeTree.TypeIdent("Int")))), DefDef("f", Nil, List(List(ValDef("a", TypeTree.TypeIdent("Foo"), None))), TypeTree.TermSelect(Term.Ident("a"), "X"), Some(Term.Ident("???")))), Term.Literal(Constant.Unit())) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) -Term.Block(List(ClassDef("Foo", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("X", TypeBoundsTree(TypeTree.Synthetic(), TypeTree.Synthetic())))), DefDef("f", Nil, List(List(ValDef("a", TypeTree.Refined(TypeTree.TypeIdent("Foo"), List(TypeDef("X", TypeTree.TypeIdent("Int")))), None))), TypeTree.TypeSelect(Term.Ident("a"), "X"), Some(Term.Ident("???")))), Term.Literal(Constant.Unit())) +Term.Block(List(ClassDef("Foo", DefDef("", Nil, List(Nil), TypeTree.Synthetic(), None), List(Term.Apply(Term.Select(Term.New(TypeTree.Synthetic()), "", Some(Signature(Nil, java.lang.Object))), Nil)), None, List(TypeDef("X", TypeBoundsTree(TypeTree.Synthetic(), TypeTree.Synthetic())))), DefDef("f", Nil, List(List(ValDef("a", TypeTree.Refined(TypeTree.TypeIdent("Foo"), List(TypeDef("X", TypeTree.TypeIdent("Int")))), None))), TypeTree.TermSelect(Term.Ident("a"), "X"), Some(Term.Ident("???")))), Term.Literal(Constant.Unit())) Type.SymRef(ClassDef("Unit", _, _, _, _), Type.ThisType(Type.SymRef(PackageDef("scala", _), NoPrefix()))) Term.Block(List(ValDef("lambda", TypeTree.Applied(TypeTree.Synthetic(), List(TypeTree.TypeIdent("Int"), TypeTree.TypeIdent("Int"))), Some(Term.Block(List(DefDef("$anonfun", Nil, List(List(ValDef("x", TypeTree.Synthetic(), None))), TypeTree.Synthetic(), Some(Term.Ident("x")))), Term.Lambda(Term.Ident("$anonfun"), None))))), Term.Literal(Constant.Unit()))