From 10289a9eb8160486fb032441559de1dcf67293cc Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 26 Apr 2022 11:30:27 +0200 Subject: [PATCH 1/2] Fix reflect typeMembers to return all members Fixes #14902 --- .../scala/quoted/runtime/impl/QuotesImpl.scala | 10 ++++++---- library/src/scala/quoted/Quotes.scala | 8 ++++---- .../tools/scaladoc/tasty/SyntheticSupport.scala | 2 +- tests/run-macros/i14902.check | 4 ++++ tests/run-macros/i14902/Macros_1.scala | 16 ++++++++++++++++ tests/run-macros/i14902/Test_2.scala | 12 ++++++++++++ 6 files changed, 43 insertions(+), 9 deletions(-) create mode 100644 tests/run-macros/i14902.check create mode 100644 tests/run-macros/i14902/Macros_1.scala create mode 100644 tests/run-macros/i14902/Test_2.scala diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 3cab93f247ae..160f42771c56 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -2619,13 +2619,15 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler case sym if sym.isType => sym.asType }.toList - def memberType(name: String): Symbol = typeMember(name) - def typeMember(name: String): Symbol = + def memberType(name: String): Symbol = self.unforcedDecls.find(sym => sym.name == name.toTypeName) + def typeMember(name: String): Symbol = + lookupPrefix.member(name.toTypeName).symbol - def memberTypes: List[Symbol] = typeMembers - def typeMembers: List[Symbol] = + def memberTypes: List[Symbol] = self.unforcedDecls.filter(_.isType) + def typeMembers: List[Symbol] = + lookupPrefix.typeMembers.map(_.symbol).toList def declarations: List[Symbol] = self.typeRef.info.decls.toList diff --git a/library/src/scala/quoted/Quotes.scala b/library/src/scala/quoted/Quotes.scala index 309e49be1370..2f4439d44a83 100644 --- a/library/src/scala/quoted/Quotes.scala +++ b/library/src/scala/quoted/Quotes.scala @@ -3879,17 +3879,17 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching => def declaredTypes: List[Symbol] /** Type member with the given name directly declared in the class */ - @deprecated("Use typeMember", "3.1.0") + @deprecated("Use declaredType or typeMember", "3.1.0") def memberType(name: String): Symbol - /** Type member with the given name directly declared in the class */ + /** Type member with the given name declared or inherited in the class */ def typeMember(name: String): Symbol /** Type member directly declared in the class */ - @deprecated("Use typeMembers", "3.1.0") + @deprecated("Use declaredTypes or typeMembers", "3.1.0") def memberTypes: List[Symbol] - /** Type member directly declared in the class */ + /** Type member directly declared or inherited in the class */ def typeMembers: List[Symbol] /** All members directly declared in the class */ diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala index dabc6468d4c9..b33d5f61faac 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala @@ -49,7 +49,7 @@ object SyntheticsSupport: c.symbol.typeRef.baseClasses.map(b => b -> c.symbol.typeRef.baseType(b)).tail def typeForClass(using Quotes)(c: reflect.ClassDef): reflect.TypeRepr = - c.symbol.typeRef.appliedTo(c.symbol.typeMembers.filter(_.isTypeParam).map(_.typeRef)) + c.symbol.typeRef.appliedTo(c.symbol.declaredTypes.filter(_.isTypeParam).map(_.typeRef)) /* We need there to filter out symbols with certain flagsets, because these symbols come from compiler and TASTY can't handle them well. They are valdefs that describe case companion objects and cases from enum. diff --git a/tests/run-macros/i14902.check b/tests/run-macros/i14902.check new file mode 100644 index 000000000000..9b27fcb7e5dc --- /dev/null +++ b/tests/run-macros/i14902.check @@ -0,0 +1,4 @@ +List(X) +List(X, Y, Z) +List(X) +List(Y, Z) diff --git a/tests/run-macros/i14902/Macros_1.scala b/tests/run-macros/i14902/Macros_1.scala new file mode 100644 index 000000000000..d2f2f3cf3a08 --- /dev/null +++ b/tests/run-macros/i14902/Macros_1.scala @@ -0,0 +1,16 @@ +import scala.quoted.* + +inline def typeMembers[A]: List[String] = ${ typeMembersExpr[A] } +inline def declaredTypes[A]: List[String] = ${ declaredTypesExpr[A] } + +private def typeMembersExpr[A: Type](using Quotes): Expr[List[String]] = { + import quotes.reflect.* + val members = TypeRepr.of[A].typeSymbol.typeMembers + Expr(members.map(_.name)) +} + +private def declaredTypesExpr[A: Type](using Quotes): Expr[List[String]] = { + import quotes.reflect.* + val decls = TypeRepr.of[A].typeSymbol.declaredTypes + Expr(decls.map(_.name)) +} diff --git a/tests/run-macros/i14902/Test_2.scala b/tests/run-macros/i14902/Test_2.scala new file mode 100644 index 000000000000..63b0fb610dc0 --- /dev/null +++ b/tests/run-macros/i14902/Test_2.scala @@ -0,0 +1,12 @@ +@main def Test: Unit = + println(typeMembers[A]) + println(typeMembers[B]) + println(declaredTypes[A]) + println(declaredTypes[B]) + +class A: + type X + +class B extends A: + type Y + type Z From 8df113456dc742c25c46fd60da6ebe0c660c3f6a Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Wed, 23 Nov 2022 09:26:37 +0100 Subject: [PATCH 2/2] Improve memberType/memberTypes implementation --- compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala index 160f42771c56..c27a470b3778 100644 --- a/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala +++ b/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala @@ -2620,12 +2620,12 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler }.toList def memberType(name: String): Symbol = - self.unforcedDecls.find(sym => sym.name == name.toTypeName) + self.typeRef.decls.find(sym => sym.name == name.toTypeName) def typeMember(name: String): Symbol = lookupPrefix.member(name.toTypeName).symbol def memberTypes: List[Symbol] = - self.unforcedDecls.filter(_.isType) + self.typeRef.decls.filter(_.isType) def typeMembers: List[Symbol] = lookupPrefix.typeMembers.map(_.symbol).toList