Skip to content

Commit 19d7d39

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

File tree

5 files changed

+46
-8
lines changed

5 files changed

+46
-8
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 */

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)