@@ -109,10 +109,39 @@ class ClassfileParser(
109109 }
110110
111111 /** Return the class symbol of the given name. */
112- def classNameToSymbol (name : Name )(using Context ): Symbol = innerClasses.get(name.toString) match {
113- case Some (entry) => innerClasses.classSymbol(entry)
114- case None => requiredClass(name)
115- }
112+ def classNameToSymbol (name : Name )(using Context ): Symbol =
113+ val nameStr = name.toString
114+ innerClasses.get(nameStr) match
115+ case Some (entry) => innerClasses.classSymbol(entry)
116+ case None =>
117+ def lookupTopLevel (): Symbol = requiredClass(name)
118+ // For inner classes we usually don't get to this branch: `innerClasses.classSymbol` already returns the symbol
119+ // of the inner class based on the InnerClass table. However, if the classfile is missing the
120+ // InnerClass entry for `name`, it might still be that there exists an inner symbol (because
121+ // some other classfile _does_ have an InnerClass entry for `name`). In this case, we want to
122+ // return the actual inner symbol (C.D, with owner C), not the top-level symbol C$D. This is
123+ // what the logic below is for (see scala/bug#9937 / lampepfl/dotty#12086).
124+ val split = nameStr.lastIndexOf('$' )
125+ if split < 0 || split >= nameStr.length - 1 then
126+ lookupTopLevel()
127+ else
128+ val outerNameStr = nameStr.substring(0 , split)
129+ val innerNameStr = nameStr.substring(split + 1 , nameStr.length)
130+ val outerSym = classNameToSymbol(outerNameStr.toTypeName)
131+ outerSym.denot.infoOrCompleter match
132+ case _ : StubInfo =>
133+ // If the outer class C cannot be found, look for a top-level class C$D
134+ lookupTopLevel()
135+ case _ =>
136+ // We have a java-defined class name C$D and look for a member D of C. But we don't know if
137+ // D is declared static or not, so we have to search both in class C and its companion.
138+ val innerName = innerNameStr.toTypeName
139+ val r =
140+ if outerSym eq classRoot.symbol then
141+ instanceScope.lookup(innerName).orElse(staticScope.lookup(innerName))
142+ else
143+ outerSym.info.member(innerName).orElse(outerSym.asClass.companionModule.info.member(innerName)).symbol
144+ r.orElse(lookupTopLevel())
116145
117146 var sawPrivateConstructor : Boolean = false
118147
0 commit comments