@@ -111,10 +111,39 @@ class ClassfileParser(
111
111
}
112
112
113
113
/** 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())
118
147
119
148
var sawPrivateConstructor : Boolean = false
120
149
0 commit comments