From e4d5f8cce22cd6ed8815c3d4eb7b9ba381b0e4a0 Mon Sep 17 00:00:00 2001 From: Pavel Shirshov Date: Sat, 1 Aug 2020 22:15:34 +0100 Subject: [PATCH 1/3] fixes #8514, TypeApi#baseType exposed into Tasty --- .../tastyreflect/ReflectionCompilerInterface.scala | 3 +++ library/src/scala/tasty/Reflection.scala | 11 +++++++++++ .../src/scala/tasty/reflect/CompilerInterface.scala | 10 ++++++++++ 3 files changed, 24 insertions(+) diff --git a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala index 035cfd228302..2ae0ca5c9f21 100644 --- a/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala +++ b/compiler/src/dotty/tools/dotc/tastyreflect/ReflectionCompilerInterface.scala @@ -1205,6 +1205,9 @@ class ReflectionCompilerInterface(val rootContext: core.Contexts.Context) extend def Type_baseClasses(self: Type)(using Context): List[Symbol] = self.baseClasses + def Type_baseType(self: Type)(cls: Symbol)(using Context): Type = + self.baseType(cls) + def Type_derivesFrom(self: Type)(cls: Symbol)(using Context): Boolean = self.derivesFrom(cls) diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index edfee77e4aa2..c717b70283a2 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -1812,6 +1812,17 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => /** The base classes of this type with the class itself as first element. */ def baseClasses(using ctx: Context): List[Symbol] = internal.Type_baseClasses(self) + + /** The least type instance of given class which is a super-type + * of this type. Example: + * {{{ + * class D[T] + * class C extends p.D[Int] + * ThisType(C).baseType(D) = p.D[Int] + * }}} + */ + def baseType(using ctx: Context)(cls: Symbol): Type = internal.Type_baseType(self)(cls) + /** Is this type an instance of a non-bottom subclass of the given class `cls`? */ def derivesFrom(cls: Symbol)(using ctx: Context): Boolean = internal.Type_derivesFrom(self)(cls) diff --git a/library/src/scala/tasty/reflect/CompilerInterface.scala b/library/src/scala/tasty/reflect/CompilerInterface.scala index ad70193f8c17..ace40fcae909 100644 --- a/library/src/scala/tasty/reflect/CompilerInterface.scala +++ b/library/src/scala/tasty/reflect/CompilerInterface.scala @@ -876,6 +876,16 @@ trait CompilerInterface { /** The base classes of this type with the class itself as first element. */ def Type_baseClasses(self: Type)(using ctx: Context): List[Symbol] + /** The least type instance of given class which is a super-type + * of this type. Example: + * {{{ + * class D[T] + * class C extends p.D[Int] + * ThisType(C).baseType(D) = p.D[Int] + * }}} + */ + def Type_baseType(self: Type)(cls: Symbol)(using ctx: Context): Type + /** Is this type an instance of a non-bottom subclass of the given class `cls`? */ def Type_derivesFrom(self: Type)(cls: Symbol)(using ctx: Context): Boolean From edff4168eecf0c104e0d7d730fdd3b11205eee14 Mon Sep 17 00:00:00 2001 From: Pavel Shirshov Date: Sat, 1 Aug 2020 23:16:54 +0100 Subject: [PATCH 2/3] basic test --- library/src/scala/tasty/Reflection.scala | 2 +- tests/run-macros/i8514b.check | 1 + tests/run-macros/i8514b/Macro_1.scala | 16 ++++++++++++++++ tests/run-macros/i8514b/Test_2.scala | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 tests/run-macros/i8514b.check create mode 100644 tests/run-macros/i8514b/Macro_1.scala create mode 100644 tests/run-macros/i8514b/Test_2.scala diff --git a/library/src/scala/tasty/Reflection.scala b/library/src/scala/tasty/Reflection.scala index c717b70283a2..238a2f7b320b 100644 --- a/library/src/scala/tasty/Reflection.scala +++ b/library/src/scala/tasty/Reflection.scala @@ -1821,7 +1821,7 @@ class Reflection(private[scala] val internal: CompilerInterface) { self => * ThisType(C).baseType(D) = p.D[Int] * }}} */ - def baseType(using ctx: Context)(cls: Symbol): Type = internal.Type_baseType(self)(cls) + def baseType(cls: Symbol)(using ctx: Context): Type = internal.Type_baseType(self)(cls) /** Is this type an instance of a non-bottom subclass of the given class `cls`? */ def derivesFrom(cls: Symbol)(using ctx: Context): Boolean = diff --git a/tests/run-macros/i8514b.check b/tests/run-macros/i8514b.check new file mode 100644 index 000000000000..24b2051f3b9f --- /dev/null +++ b/tests/run-macros/i8514b.check @@ -0,0 +1 @@ +List(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class )),module class )),B), AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class )),class A),List(HKTypeLambda(List(T), List(TypeBounds(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scala),Nothing),TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scala),Any))), AppliedType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class )),module class )),P),List(TypeParamRef(T)))), TypeRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scala),Predef),String))), TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object), TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Any)) diff --git a/tests/run-macros/i8514b/Macro_1.scala b/tests/run-macros/i8514b/Macro_1.scala new file mode 100644 index 000000000000..92465e3bbd39 --- /dev/null +++ b/tests/run-macros/i8514b/Macro_1.scala @@ -0,0 +1,16 @@ +import scala.quoted._ + +class A[+X[_], -Y] +class P[T] +class B extends A[P, String] + +inline def test(): Unit = ${ testExpr } + +def testExpr(using QuoteContext): Expr[Unit] = { + import qctx.tasty._ + + val t = '[B].unseal.tpe + '{ + println(${Expr(t.baseClasses.map(b => t.baseType(b).toString))}) + } +} diff --git a/tests/run-macros/i8514b/Test_2.scala b/tests/run-macros/i8514b/Test_2.scala new file mode 100644 index 000000000000..c96956b4554d --- /dev/null +++ b/tests/run-macros/i8514b/Test_2.scala @@ -0,0 +1 @@ +@main def Test = test() From 24a7940f6358700236f5ecf2ecea8f8e328f596a Mon Sep 17 00:00:00 2001 From: Pavel Shirshov Date: Mon, 3 Aug 2020 14:14:28 +0100 Subject: [PATCH 3/3] #8514: cleanups --- tests/run-macros/i8514b.check | 5 ++++- tests/run-macros/i8514b/Macro_1.scala | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/run-macros/i8514b.check b/tests/run-macros/i8514b.check index 24b2051f3b9f..fcf27e623f06 100644 --- a/tests/run-macros/i8514b.check +++ b/tests/run-macros/i8514b.check @@ -1 +1,4 @@ -List(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class )),module class )),B), AppliedType(TypeRef(ThisType(TypeRef(NoPrefix,module class )),class A),List(HKTypeLambda(List(T), List(TypeBounds(TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scala),Nothing),TypeRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scala),Any))), AppliedType(TypeRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class )),module class )),P),List(TypeParamRef(T)))), TypeRef(TermRef(TermRef(ThisType(TypeRef(NoPrefix,module class )),module scala),Predef),String))), TypeRef(ThisType(TypeRef(NoPrefix,module class lang)),class Object), TypeRef(ThisType(TypeRef(NoPrefix,module class scala)),class Any)) +B +A[[T >: scala.Nothing <: scala.Any] => P[T], scala.Predef.String] +java.lang.Object +scala.Any diff --git a/tests/run-macros/i8514b/Macro_1.scala b/tests/run-macros/i8514b/Macro_1.scala index 92465e3bbd39..be6268f55bb3 100644 --- a/tests/run-macros/i8514b/Macro_1.scala +++ b/tests/run-macros/i8514b/Macro_1.scala @@ -10,7 +10,9 @@ def testExpr(using QuoteContext): Expr[Unit] = { import qctx.tasty._ val t = '[B].unseal.tpe + val baseTypes = t.baseClasses.map(b => t.baseType(b)) + '{ - println(${Expr(t.baseClasses.map(b => t.baseType(b).toString))}) + println(${Expr(baseTypes.map(_.show).mkString("\n"))}) } }