@@ -132,24 +132,24 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
132132 }
133133
134134 /*
135- * Populates the InnerClasses JVM attribute with `refedInnerClasses`.
136- * In addition to inner classes mentioned somewhere in `jclass` (where `jclass` is a class file being emitted)
137- * `refedInnerClasses` should contain those inner classes defined as direct member classes of `jclass`
138- * but otherwise not mentioned in `jclass`.
135+ * Populates the InnerClasses JVM attribute with `refedInnerClasses`. See also the doc on inner
136+ * classes in BTypes.scala.
139137 *
140- * `refedInnerClasses` may contain duplicates,
141- * need not contain the enclosing inner classes of each inner class it lists (those are looked up for consistency ).
138+ * `refedInnerClasses` may contain duplicates, need not contain the enclosing inner classes of
139+ * each inner class it lists (those are looked up and included ).
142140 *
143- * This method serializes in the InnerClasses JVM attribute in an appropriate order,
141+ * This method serializes in the InnerClasses JVM attribute in an appropriate order,
144142 * not necessarily that given by `refedInnerClasses`.
145143 *
146144 * can-multi-thread
147145 */
148- final def addInnerClassesASM (jclass : asm.ClassVisitor , refedInnerClasses : List [ClassBType ]): Unit = {
149- val allNestedClasses = refedInnerClasses.flatMap(_.enclosingNestedClassesChain).distinct
150-
146+ final def addInnerClasses (jclass : asm.ClassVisitor , declaredInnerClasses : List [ClassBType ], refedInnerClasses : List [ClassBType ]): Unit = {
151147 // sorting ensures nested classes are listed after their enclosing class thus satisfying the Eclipse Java compiler
152- for (nestedClass <- allNestedClasses.sortBy(_.internalName.toString)) {
148+ val allNestedClasses = new mutable.TreeSet [ClassBType ]()(Ordering .by(_.internalName))
149+ allNestedClasses ++= declaredInnerClasses
150+ refedInnerClasses.foreach(allNestedClasses ++= _.enclosingNestedClassesChain)
151+ for nestedClass <- allNestedClasses
152+ do {
153153 // Extract the innerClassEntry - we know it exists, enclosingNestedClassesChain only returns nested classes.
154154 val Some (e) = nestedClass.innerClassAttributeEntry
155155 jclass.visitInnerClass(e.name, e.outerName, e.innerName, e.flags)
@@ -218,26 +218,16 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
218218 final val emitLines = debugLevel >= 2
219219 final val emitVars = debugLevel >= 3
220220
221- /*
222- * Contains class-symbols that:
223- * (a) are known to denote inner classes
224- * (b) are mentioned somewhere in the class being generated.
225- *
226- * In other words, the lifetime of `innerClassBufferASM` is associated to "the class being generated".
227- */
228- final val innerClassBufferASM = mutable.Set .empty[ClassBType ]
229-
230221 /**
231- * The class internal name for a given class symbol. If the symbol describes a nested class, the
232- * ClassBType is added to the innerClassBufferASM.
222+ * The class internal name for a given class symbol.
233223 */
234224 final def internalName (sym : Symbol ): String = {
235225 // For each java class, the scala compiler creates a class and a module (thus a module class).
236- // If the `sym` is a java module class, we use the java class instead. This ensures that we
237- // register the class (instead of the module class) in innerClassBufferASM .
226+ // If the `sym` is a java module class, we use the java class instead. This ensures that the
227+ // ClassBType is created from the main class (instead of the module class).
238228 // The two symbols have the same name, so the resulting internalName is the same.
239229 val classSym = if (sym.is(JavaDefined ) && sym.is(ModuleClass )) sym.linkedClass else sym
240- getClassBTypeAndRegisterInnerClass (classSym).internalName
230+ getClassBType (classSym).internalName
241231 }
242232
243233 private def assertClassNotArray (sym : Symbol ): Unit = {
@@ -251,8 +241,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
251241 }
252242
253243 /**
254- * The ClassBType for a class symbol. If the class is nested, the ClassBType is added to the
255- * innerClassBufferASM.
244+ * The ClassBType for a class symbol.
256245 *
257246 * The class symbol scala.Nothing is mapped to the class scala.runtime.Nothing$. Similarly,
258247 * scala.Null is mapped to scala.runtime.Null$. This is because there exist no class files
@@ -264,16 +253,12 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
264253 * the class descriptor of the receiver (the implementation class) is obtained by creating the
265254 * ClassBType.
266255 */
267- final def getClassBTypeAndRegisterInnerClass (sym : Symbol ): ClassBType = {
256+ final def getClassBType (sym : Symbol ): ClassBType = {
268257 assertClassNotArrayNotPrimitive(sym)
269258
270259 if (sym == defn.NothingClass ) srNothingRef
271260 else if (sym == defn.NullClass ) srNullRef
272- else {
273- val r = classBTypeFromSymbol(sym)
274- if (r.isNestedClass) innerClassBufferASM += r
275- r
276- }
261+ else classBTypeFromSymbol(sym)
277262 }
278263
279264 /*
@@ -288,16 +273,14 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
288273 }
289274
290275 /**
291- * The jvm descriptor of a type. If `t` references a nested class, its ClassBType is added to
292- * the innerClassBufferASM.
276+ * The jvm descriptor of a type.
293277 */
294278 final def typeDescriptor (t : Type ): String = { toTypeKind(t).descriptor }
295279
296280 /**
297- * The jvm descriptor for a symbol. If `sym` represents a nested class, its ClassBType is added
298- * to the innerClassBufferASM.
281+ * The jvm descriptor for a symbol.
299282 */
300- final def symDescriptor (sym : Symbol ): String = { getClassBTypeAndRegisterInnerClass (sym).descriptor }
283+ final def symDescriptor (sym : Symbol ): String = getClassBType (sym).descriptor
301284
302285 final def toTypeKind (tp : Type ): BType = typeToTypeKind(tp)(BCodeHelpers .this )(this )
303286
@@ -691,16 +674,15 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
691674 def genMirrorClass (moduleClass : Symbol , cunit : CompilationUnit ): asm.tree.ClassNode = {
692675 assert(moduleClass.is(ModuleClass ))
693676 assert(moduleClass.companionClass == NoSymbol , moduleClass)
694- innerClassBufferASM.clear()
695677 this .cunit = cunit
678+ val bType = mirrorClassBTypeFromSymbol(moduleClass)
696679 val moduleName = internalName(moduleClass) // + "$"
697- val mirrorName = moduleName.substring( 0 , moduleName.length() - 1 )
680+ val mirrorName = bType.internalName
698681
699- val flags = (asm.Opcodes .ACC_SUPER | asm.Opcodes .ACC_PUBLIC | asm.Opcodes .ACC_FINAL )
700682 val mirrorClass = new asm.tree.ClassNode
701683 mirrorClass.visit(
702684 classfileVersion,
703- flags,
685+ bType.info. flags,
704686 mirrorName,
705687 null /* no java-generic-signature */ ,
706688 ObjectRef .internalName,
@@ -717,10 +699,6 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
717699 emitAnnotations(mirrorClass, moduleClass.annotations ++ ssa)
718700
719701 addForwarders(mirrorClass, mirrorName, moduleClass)
720-
721- innerClassBufferASM ++= classBTypeFromSymbol(moduleClass).info.memberClasses
722- addInnerClassesASM(mirrorClass, innerClassBufferASM.toList)
723-
724702 mirrorClass.visitEnd()
725703
726704 moduleClass.name // this side-effect is necessary, really.
@@ -754,8 +732,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
754732 * must-single-thread
755733 */
756734 def legacyAddCreatorCode (clinit : asm.MethodVisitor , cnode : asm.tree.ClassNode , thisName : String ): Unit = {
757- // this tracks the inner class in innerClassBufferASM, if needed.
758- val androidCreatorType = getClassBTypeAndRegisterInnerClass(AndroidCreatorClass )
735+ val androidCreatorType = getClassBType(AndroidCreatorClass )
759736 val tdesc_creator = androidCreatorType.descriptor
760737
761738 cnode.visitField(
@@ -818,8 +795,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
818795 def primitiveOrClassToBType (sym : Symbol ): BType = {
819796 assert(sym.isClass, sym)
820797 assert(sym != defn.ArrayClass || compilingArray, sym)
821- primitiveTypeMap.getOrElse(sym,
822- storage.getClassBTypeAndRegisterInnerClass(sym)).asInstanceOf [BType ]
798+ primitiveTypeMap.getOrElse(sym, storage.getClassBType(sym)).asInstanceOf [BType ]
823799 }
824800
825801 /**
@@ -862,7 +838,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
862838
863839 tp match {
864840 case tp : ThisType if tp.cls == defn.ArrayClass => ObjectRef .asInstanceOf [ct.bTypes.ClassBType ] // was introduced in 9b17332f11 to fix SI-999, but this code is not reached in its test, or any other test
865- case tp : ThisType => storage.getClassBTypeAndRegisterInnerClass (tp.cls)
841+ case tp : ThisType => storage.getClassBType (tp.cls)
866842 // case t: SingletonType => primitiveOrClassToBType(t.classSymbol)
867843 case t : SingletonType => typeToTypeKind(t.underlying)(ct)(storage)
868844 case t : RefinedType => typeToTypeKind(t.parent)(ct)(storage) // parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b))
0 commit comments