@@ -109,10 +109,39 @@ class ClassfileParser(
109
109
}
110
110
111
111
/** 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())
116
145
117
146
var sawPrivateConstructor : Boolean = false
118
147
0 commit comments