Skip to content

Commit efc8081

Browse files
committed
Fix reflect typeMembers to return all members
Fixes #14902
1 parent ba8dccb commit efc8081

File tree

6 files changed

+47
-9
lines changed

6 files changed

+47
-9
lines changed

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2619,13 +2619,19 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
26192619
case sym if sym.isType => sym.asType
26202620
}.toList
26212621

2622-
def memberType(name: String): Symbol = typeMember(name)
2623-
def typeMember(name: String): Symbol =
2622+
def memberType(name: String): Symbol =
26242623
self.unforcedDecls.find(sym => sym.name == name.toTypeName)
2624+
def typeMember(name: String): Symbol =
2625+
lookupPrefix.allMembers.iterator.map(_.symbol).collect {
2626+
case sym if sym.isType && sym.name.toString == name => sym.asType
2627+
}.toList.headOption.getOrElse(dotc.core.Symbols.NoSymbol)
26252628

2626-
def memberTypes: List[Symbol] = typeMembers
2627-
def typeMembers: List[Symbol] =
2629+
def memberTypes: List[Symbol] =
26282630
self.unforcedDecls.filter(_.isType)
2631+
def typeMembers: List[Symbol] =
2632+
lookupPrefix.allMembers.iterator.map(_.symbol).collect {
2633+
case sym if sym.isType => sym.asType
2634+
}.toList
26292635

26302636
def declarations: List[Symbol] =
26312637
self.typeRef.info.decls.toList

library/src/scala/quoted/Quotes.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3885,17 +3885,17 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
38853885
def declaredTypes: List[Symbol]
38863886

38873887
/** Type member with the given name directly declared in the class */
3888-
@deprecated("Use typeMember", "3.1.0")
3888+
@deprecated("Use declaredType or typeMember", "3.1.0")
38893889
def memberType(name: String): Symbol
38903890

3891-
/** Type member with the given name directly declared in the class */
3891+
/** Type member with the given name declared or inherited in the class */
38923892
def typeMember(name: String): Symbol
38933893

38943894
/** Type member directly declared in the class */
3895-
@deprecated("Use typeMembers", "3.1.0")
3895+
@deprecated("Use declaredTypes or typeMembers", "3.1.0")
38963896
def memberTypes: List[Symbol]
38973897

3898-
/** Type member directly declared in the class */
3898+
/** Type member directly declared or inherited in the class */
38993899
def typeMembers: List[Symbol]
39003900

39013901
/** All members directly declared in the class */

scaladoc/src/dotty/tools/scaladoc/tasty/SyntheticSupport.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ object SyntheticsSupport:
3838
c.symbol.typeRef.baseClasses.map(b => b -> c.symbol.typeRef.baseType(b)).tail
3939

4040
def typeForClass(using Quotes)(c: reflect.ClassDef): reflect.TypeRepr =
41-
c.symbol.typeRef.appliedTo(c.symbol.typeMembers.filter(_.isTypeParam).map(_.typeRef))
41+
c.symbol.typeRef.appliedTo(c.symbol.declaredTypes.filter(_.isTypeParam).map(_.typeRef))
4242

4343
/* We need there to filter out symbols with certain flagsets, because these symbols come from compiler and TASTY can't handle them well.
4444
They are valdefs that describe case companion objects and cases from enum.

tests/run-macros/i14902.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
List(X)
2+
List(X, Y, Z)
3+
List(X)
4+
List(Y, Z)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import scala.quoted.*
2+
3+
inline def typeMembers[A]: List[String] = ${ typeMembersExpr[A] }
4+
inline def declaredTypes[A]: List[String] = ${ declaredTypesExpr[A] }
5+
6+
private def typeMembersExpr[A: Type](using Quotes): Expr[List[String]] = {
7+
import quotes.reflect.*
8+
val members = TypeRepr.of[A].typeSymbol.typeMembers
9+
Expr(members.map(_.name).sorted) // TODO: make typeMembers return stable result
10+
}
11+
12+
private def declaredTypesExpr[A: Type](using Quotes): Expr[List[String]] = {
13+
import quotes.reflect.*
14+
val decls = TypeRepr.of[A].typeSymbol.declaredTypes
15+
Expr(decls.map(_.name).sorted) // TODO: make declaredTypes return stable result
16+
}

tests/run-macros/i14902/Test_2.scala

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@main def Test: Unit =
2+
println(typeMembers[A])
3+
println(typeMembers[B])
4+
println(declaredTypes[A])
5+
println(declaredTypes[B])
6+
7+
class A:
8+
type X
9+
10+
class B extends A:
11+
type Y
12+
type Z

0 commit comments

Comments
 (0)