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