diff --git a/scala3doc-testcases/src/tests/tests.scala b/scala3doc-testcases/src/tests/tests.scala index 4f5721cdbf6f..12c805384226 100644 --- a/scala3doc-testcases/src/tests/tests.scala +++ b/scala3doc-testcases/src/tests/tests.scala @@ -63,6 +63,9 @@ package tests */ class A { + type X = tests.B + type Y <: tests.B + /** This is my method. * * This is a link: [[AA]]. diff --git a/scala3doc/src/dotty/dokka/tasty/comments/Comments.scala b/scala3doc/src/dotty/dokka/tasty/comments/Comments.scala index 27faca5d19d9..75e589c7bece 100644 --- a/scala3doc/src/dotty/dokka/tasty/comments/Comments.scala +++ b/scala3doc/src/dotty/dokka/tasty/comments/Comments.scala @@ -97,10 +97,15 @@ abstract class MarkupConversion[T](val repr: Repr)(using DocContext) { case Some((sym, targetText)) => DocLink.ToDRI(sym.dri, targetText) case None => - val msg = s"Not found any dri for query" - // TODO convert owner.pos to get to the comment, change to warning - report.inform(s"$msg: $queryStr") - DocLink.UnresolvedDRI(queryStr, msg) + val txt = s"No DRI found for query" + val msg = s"$txt: $queryStr" + // TODO change to the commented-out version when we'll get rid of the warnings in stdlib + // report.warning( + // msg, + // owner.pos.get.asInstanceOf[dotty.tools.dotc.util.SrcPos], + // ) + report.inform(msg) + DocLink.UnresolvedDRI(queryStr, txt) private val SchemeUri = """[a-z]+:.*""".r diff --git a/scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala b/scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala index bd9af2b0e629..0fe41fe8da1d 100644 --- a/scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala +++ b/scala3doc/src/dotty/dokka/tasty/comments/MemberLookup.scala @@ -26,15 +26,23 @@ trait MemberLookup { if sym.isClassDef || sym.flags.is(Flags.Package) then sym else nearestMembered(sym.owner) val res = + def toplevelLookup(querystrings: List[String]) = + downwardLookup(querystrings, defn.PredefModule.moduleClass) + .orElse(downwardLookup(querystrings, defn.ScalaPackage)) + .orElse(downwardLookup(querystrings, defn.RootPackage)) + ownerOpt match { case Some(owner) => val nearest = nearestMembered(owner) val nearestCls = nearestClass(owner) val nearestPkg = nearestPackage(owner) + def relativeLookup(querystrings: List[String]) = + // TODO walk the owner chain? + downwardLookup(querystrings, nearestPkg).orElse(toplevelLookup(querystrings)) query match { case Query.StrictMemberId(id) => localLookup(id, nearest).map(_ -> id) case Query.Id(id) => - (localLookup(id, nearest) orElse localLookup(id, nearestPkg)).map(_ -> id) + (localLookup(id, nearest) orElse relativeLookup(List(id))).map(_ -> id) case Query.QualifiedId(Query.Qual.This, _, rest) => downwardLookup(rest.asList, nearestCls).map(_ -> rest.join) case Query.QualifiedId(Query.Qual.Package, _, rest) => @@ -43,11 +51,12 @@ trait MemberLookup { downwardLookup(rest.asList, nearestCls).map(_ -> rest.join) case Query.QualifiedId(Query.Qual.Id(id), _, rest) if id == nearestPkg.name => downwardLookup(rest.asList, nearestPkg).map(_ -> rest.join) - case query: Query.QualifiedId => downwardLookup(query.asList, defn.RootPackage).map(_ -> query.join) + case query: Query.QualifiedId => + relativeLookup(query.asList).map(_ -> query.join) } case None => - downwardLookup(query.asList, defn.RootPackage).map(_ -> query.join) + toplevelLookup(query.asList).map(_ -> query.join) } // println(s"looked up `$query` in ${owner.show}[${owner.flags.show}] as ${res.map(_.show)}") @@ -103,7 +112,12 @@ trait MemberLookup { def hackResolveModule(s: Symbol): Symbol = if s.flags.is(Flags.Module) then s.moduleClass else s - val matched = syms.find(matches) + // val syms0 = syms.toList + // val matched0 = syms0.find(matches) + // if matched0.isEmpty then + // println(s"Failed to look up $q in $owner; all members below:") + // syms0.foreach { s => println(s"\t$s") } + // val matched = matched0 // def showMatched() = matched.foreach { s => // println(s">>> ${s.show}") @@ -115,6 +129,7 @@ trait MemberLookup { // println(s"localLookup for class ${owner.show} of `$q`{forceTerm=$forceTerm}") // showMatched() + val matched = syms.find(matches) matched.map(hackResolveModule) } @@ -124,6 +139,16 @@ trait MemberLookup { owner.tree match { case tree: ClassDef => findMatch(tree.body.iterator.collect { case t: Definition if hackIsNotAbsent(t.symbol) => t.symbol }) + case tree: TypeDef => + val tpe = + tree.rhs match { + case tb : TypeBoundsTree => tb.hi.tpe + case tpt: TypeTree => tpt.tpe + } + + tpe.classSymbol.flatMap { s => + findMatch(hackMembersOf(s)) + } case _ => findMatch(hackMembersOf(owner)) } diff --git a/scala3doc/test/dotty/dokka/tasty/comments/MemberLookupTests.scala b/scala3doc/test/dotty/dokka/tasty/comments/MemberLookupTests.scala index 154e7456d120..52a94c6a4eff 100644 --- a/scala3doc/test/dotty/dokka/tasty/comments/MemberLookupTests.scala +++ b/scala3doc/test/dotty/dokka/tasty/comments/MemberLookupTests.scala @@ -16,6 +16,11 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) { def testOwnerlessLookup(): Unit = { val cases = List[(String, Sym)]( + "Array" -> cls("scala.Array"), + "Option" -> cls("scala.Option"), + "Predef$.identity" -> cls("scala.Predef$").fun("identity"), + "Array$.from" -> cls("scala.Array$").fun("from"), + "???" -> cls("scala.Predef$").fun("???"), "tests.A" -> cls("tests.A"), "tests.A$" -> cls("tests.A$"), "tests.Methods.simple" -> cls("tests.Methods").fun("simple"), @@ -61,6 +66,14 @@ class LookupTestCases[Q <: Quotes](val q: Quotes) { cls("tests.A").fun("method") -> "B" -> cls("tests.B"), cls("tests.A").fun("method") -> "B$" -> cls("tests.B$"), + + cls("tests.A") -> "B.method" -> cls("tests.B").fun("method"), + cls("tests.A") -> "Option" -> cls("scala.Option"), + + /*sanity*/ cls("tests.A") -> "this.X" -> cls("tests.A").tpe("X"), + /*sanity*/ cls("tests.A") -> "this.Y" -> cls("tests.A").tpe("Y"), + cls("tests.A") -> "this.X.method" -> cls("tests.B").fun("method"), + cls("tests.A") -> "this.Y.method" -> cls("tests.B").fun("method"), ) cases.foreach { case ((Sym(owner), query), Sym(target)) => diff --git a/tasty/src/dotty/tools/tasty/TastyFormat.scala b/tasty/src/dotty/tools/tasty/TastyFormat.scala index 88c44a21ea2c..4e22b7519d12 100644 --- a/tasty/src/dotty/tools/tasty/TastyFormat.scala +++ b/tasty/src/dotty/tools/tasty/TastyFormat.scala @@ -270,7 +270,7 @@ object TastyFormat { final val PositionsSection = "Positions" final val CommentsSection = "Comments" - /** Tags used to serialize names, should update [[nameTagToString]] if a new constant is added */ + /** Tags used to serialize names, should update [[TastyFormat$.nameTagToString]] if a new constant is added */ class NameTags { final val UTF8 = 1 // A simple name in UTF8 encoding.