@@ -132,24 +132,24 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
132
132
}
133
133
134
134
/*
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.
139
137
*
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 ).
142
140
*
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,
144
142
* not necessarily that given by `refedInnerClasses`.
145
143
*
146
144
* can-multi-thread
147
145
*/
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 = {
151
147
// 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 {
153
153
// Extract the innerClassEntry - we know it exists, enclosingNestedClassesChain only returns nested classes.
154
154
val Some (e) = nestedClass.innerClassAttributeEntry
155
155
jclass.visitInnerClass(e.name, e.outerName, e.innerName, e.flags)
@@ -218,26 +218,16 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
218
218
final val emitLines = debugLevel >= 2
219
219
final val emitVars = debugLevel >= 3
220
220
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
-
230
221
/**
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.
233
223
*/
234
224
final def internalName (sym : Symbol ): String = {
235
225
// 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).
238
228
// The two symbols have the same name, so the resulting internalName is the same.
239
229
val classSym = if (sym.is(JavaDefined ) && sym.is(ModuleClass )) sym.linkedClass else sym
240
- getClassBTypeAndRegisterInnerClass (classSym).internalName
230
+ getClassBType (classSym).internalName
241
231
}
242
232
243
233
private def assertClassNotArray (sym : Symbol ): Unit = {
@@ -251,8 +241,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
251
241
}
252
242
253
243
/**
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.
256
245
*
257
246
* The class symbol scala.Nothing is mapped to the class scala.runtime.Nothing$. Similarly,
258
247
* 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 {
264
253
* the class descriptor of the receiver (the implementation class) is obtained by creating the
265
254
* ClassBType.
266
255
*/
267
- final def getClassBTypeAndRegisterInnerClass (sym : Symbol ): ClassBType = {
256
+ final def getClassBType (sym : Symbol ): ClassBType = {
268
257
assertClassNotArrayNotPrimitive(sym)
269
258
270
259
if (sym == defn.NothingClass ) srNothingRef
271
260
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)
277
262
}
278
263
279
264
/*
@@ -288,16 +273,14 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
288
273
}
289
274
290
275
/**
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.
293
277
*/
294
278
final def typeDescriptor (t : Type ): String = { toTypeKind(t).descriptor }
295
279
296
280
/**
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.
299
282
*/
300
- final def symDescriptor (sym : Symbol ): String = { getClassBTypeAndRegisterInnerClass (sym).descriptor }
283
+ final def symDescriptor (sym : Symbol ): String = getClassBType (sym).descriptor
301
284
302
285
final def toTypeKind (tp : Type ): BType = typeToTypeKind(tp)(BCodeHelpers .this )(this )
303
286
@@ -691,16 +674,15 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
691
674
def genMirrorClass (moduleClass : Symbol , cunit : CompilationUnit ): asm.tree.ClassNode = {
692
675
assert(moduleClass.is(ModuleClass ))
693
676
assert(moduleClass.companionClass == NoSymbol , moduleClass)
694
- innerClassBufferASM.clear()
695
677
this .cunit = cunit
678
+ val bType = mirrorClassBTypeFromSymbol(moduleClass)
696
679
val moduleName = internalName(moduleClass) // + "$"
697
- val mirrorName = moduleName.substring( 0 , moduleName.length() - 1 )
680
+ val mirrorName = bType.internalName
698
681
699
- val flags = (asm.Opcodes .ACC_SUPER | asm.Opcodes .ACC_PUBLIC | asm.Opcodes .ACC_FINAL )
700
682
val mirrorClass = new asm.tree.ClassNode
701
683
mirrorClass.visit(
702
684
classfileVersion,
703
- flags,
685
+ bType.info. flags,
704
686
mirrorName,
705
687
null /* no java-generic-signature */ ,
706
688
ObjectRef .internalName,
@@ -717,10 +699,6 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
717
699
emitAnnotations(mirrorClass, moduleClass.annotations ++ ssa)
718
700
719
701
addForwarders(mirrorClass, mirrorName, moduleClass)
720
-
721
- innerClassBufferASM ++= classBTypeFromSymbol(moduleClass).info.memberClasses
722
- addInnerClassesASM(mirrorClass, innerClassBufferASM.toList)
723
-
724
702
mirrorClass.visitEnd()
725
703
726
704
moduleClass.name // this side-effect is necessary, really.
@@ -754,8 +732,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
754
732
* must-single-thread
755
733
*/
756
734
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 )
759
736
val tdesc_creator = androidCreatorType.descriptor
760
737
761
738
cnode.visitField(
@@ -818,8 +795,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
818
795
def primitiveOrClassToBType (sym : Symbol ): BType = {
819
796
assert(sym.isClass, sym)
820
797
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 ]
823
799
}
824
800
825
801
/**
@@ -862,7 +838,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
862
838
863
839
tp match {
864
840
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)
866
842
// case t: SingletonType => primitiveOrClassToBType(t.classSymbol)
867
843
case t : SingletonType => typeToTypeKind(t.underlying)(ct)(storage)
868
844
case t : RefinedType => typeToTypeKind(t.parent)(ct)(storage) // parents.map(_.toTypeKind(ct)(storage).asClassBType).reduceLeft((a, b) => a.jvmWiseLUB(b))
0 commit comments