Skip to content

Commit 67f3db6

Browse files
authored
Merge pull request scala#11302 from dotty-staging/scala3doc/improve-member-lookup
Scala3doc: improve member lookup
2 parents 8443c16 + a29d83d commit 67f3db6

File tree

5 files changed

+55
-9
lines changed

5 files changed

+55
-9
lines changed

scala3doc-testcases/src/tests/tests.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ package tests
6363
*/
6464
class A {
6565

66+
type X = tests.B
67+
type Y <: tests.B
68+
6669
/** This is my method.
6770
*
6871
* This is a link: [[AA]].

scala3doc/src/dotty/dokka/tasty/comments/Comments.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,15 @@ abstract class MarkupConversion[T](val repr: Repr)(using DocContext) {
9797
case Some((sym, targetText)) =>
9898
DocLink.ToDRI(sym.dri, targetText)
9999
case None =>
100-
val msg = s"Not found any dri for query"
101-
// TODO convert owner.pos to get to the comment, change to warning
102-
report.inform(s"$msg: $queryStr")
103-
DocLink.UnresolvedDRI(queryStr, msg)
100+
val txt = s"No DRI found for query"
101+
val msg = s"$txt: $queryStr"
102+
// TODO change to the commented-out version when we'll get rid of the warnings in stdlib
103+
// report.warning(
104+
// msg,
105+
// owner.pos.get.asInstanceOf[dotty.tools.dotc.util.SrcPos],
106+
// )
107+
report.inform(msg)
108+
DocLink.UnresolvedDRI(queryStr, txt)
104109

105110
private val SchemeUri = """[a-z]+:.*""".r
106111

scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,23 @@ trait MemberLookup {
2626
if sym.isClassDef || sym.flags.is(Flags.Package) then sym else nearestMembered(sym.owner)
2727

2828
val res =
29+
def toplevelLookup(querystrings: List[String]) =
30+
downwardLookup(querystrings, defn.PredefModule.moduleClass)
31+
.orElse(downwardLookup(querystrings, defn.ScalaPackage))
32+
.orElse(downwardLookup(querystrings, defn.RootPackage))
33+
2934
ownerOpt match {
3035
case Some(owner) =>
3136
val nearest = nearestMembered(owner)
3237
val nearestCls = nearestClass(owner)
3338
val nearestPkg = nearestPackage(owner)
39+
def relativeLookup(querystrings: List[String]) =
40+
// TODO walk the owner chain?
41+
downwardLookup(querystrings, nearestPkg).orElse(toplevelLookup(querystrings))
3442
query match {
3543
case Query.StrictMemberId(id) => localLookup(id, nearest).map(_ -> id)
3644
case Query.Id(id) =>
37-
(localLookup(id, nearest) orElse localLookup(id, nearestPkg)).map(_ -> id)
45+
(localLookup(id, nearest) orElse relativeLookup(List(id))).map(_ -> id)
3846
case Query.QualifiedId(Query.Qual.This, _, rest) =>
3947
downwardLookup(rest.asList, nearestCls).map(_ -> rest.join)
4048
case Query.QualifiedId(Query.Qual.Package, _, rest) =>
@@ -43,11 +51,12 @@ trait MemberLookup {
4351
downwardLookup(rest.asList, nearestCls).map(_ -> rest.join)
4452
case Query.QualifiedId(Query.Qual.Id(id), _, rest) if id == nearestPkg.name =>
4553
downwardLookup(rest.asList, nearestPkg).map(_ -> rest.join)
46-
case query: Query.QualifiedId => downwardLookup(query.asList, defn.RootPackage).map(_ -> query.join)
54+
case query: Query.QualifiedId =>
55+
relativeLookup(query.asList).map(_ -> query.join)
4756
}
4857

4958
case None =>
50-
downwardLookup(query.asList, defn.RootPackage).map(_ -> query.join)
59+
toplevelLookup(query.asList).map(_ -> query.join)
5160
}
5261

5362
// println(s"looked up `$query` in ${owner.show}[${owner.flags.show}] as ${res.map(_.show)}")
@@ -103,7 +112,12 @@ trait MemberLookup {
103112
def hackResolveModule(s: Symbol): Symbol =
104113
if s.flags.is(Flags.Module) then s.moduleClass else s
105114

106-
val matched = syms.find(matches)
115+
// val syms0 = syms.toList
116+
// val matched0 = syms0.find(matches)
117+
// if matched0.isEmpty then
118+
// println(s"Failed to look up $q in $owner; all members below:")
119+
// syms0.foreach { s => println(s"\t$s") }
120+
// val matched = matched0
107121

108122
// def showMatched() = matched.foreach { s =>
109123
// println(s">>> ${s.show}")
@@ -115,6 +129,7 @@ trait MemberLookup {
115129
// println(s"localLookup for class ${owner.show} of `$q`{forceTerm=$forceTerm}")
116130
// showMatched()
117131

132+
val matched = syms.find(matches)
118133
matched.map(hackResolveModule)
119134
}
120135

@@ -124,6 +139,16 @@ trait MemberLookup {
124139
owner.tree match {
125140
case tree: ClassDef =>
126141
findMatch(tree.body.iterator.collect { case t: Definition if hackIsNotAbsent(t.symbol) => t.symbol })
142+
case tree: TypeDef =>
143+
val tpe =
144+
tree.rhs match {
145+
case tb : TypeBoundsTree => tb.hi.tpe
146+
case tpt: TypeTree => tpt.tpe
147+
}
148+
149+
tpe.classSymbol.flatMap { s =>
150+
findMatch(hackMembersOf(s))
151+
}
127152
case _ =>
128153
findMatch(hackMembersOf(owner))
129154
}

scala3doc/test/dotty/dokka/tasty/comments/MemberLookupTests.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) {
1616

1717
def testOwnerlessLookup(): Unit = {
1818
val cases = List[(String, Sym)](
19+
"Array" -> cls("scala.Array"),
20+
"Option" -> cls("scala.Option"),
21+
"Predef$.identity" -> cls("scala.Predef$").fun("identity"),
22+
"Array$.from" -> cls("scala.Array$").fun("from"),
23+
"???" -> cls("scala.Predef$").fun("???"),
1924
"tests.A" -> cls("tests.A"),
2025
"tests.A$" -> cls("tests.A$"),
2126
"tests.Methods.simple" -> cls("tests.Methods").fun("simple"),
@@ -61,6 +66,14 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) {
6166

6267
cls("tests.A").fun("method") -> "B" -> cls("tests.B"),
6368
cls("tests.A").fun("method") -> "B$" -> cls("tests.B$"),
69+
70+
cls("tests.A") -> "B.method" -> cls("tests.B").fun("method"),
71+
cls("tests.A") -> "Option" -> cls("scala.Option"),
72+
73+
/*sanity*/ cls("tests.A") -> "this.X" -> cls("tests.A").tpe("X"),
74+
/*sanity*/ cls("tests.A") -> "this.Y" -> cls("tests.A").tpe("Y"),
75+
cls("tests.A") -> "this.X.method" -> cls("tests.B").fun("method"),
76+
cls("tests.A") -> "this.Y.method" -> cls("tests.B").fun("method"),
6477
)
6578

6679
cases.foreach { case ((Sym(owner), query), Sym(target)) =>

tasty/src/dotty/tools/tasty/TastyFormat.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ object TastyFormat {
270270
final val PositionsSection = "Positions"
271271
final val CommentsSection = "Comments"
272272

273-
/** Tags used to serialize names, should update [[nameTagToString]] if a new constant is added */
273+
/** Tags used to serialize names, should update [[TastyFormat$.nameTagToString]] if a new constant is added */
274274
class NameTags {
275275
final val UTF8 = 1 // A simple name in UTF8 encoding.
276276

0 commit comments

Comments
 (0)