@@ -21,8 +21,9 @@ abstract class BCodeTypes extends BCodeIdiomatic {
21
21
import global ._
22
22
import bTypes ._
23
23
24
- // when compiling the Scala library, some assertions don't hold (e.g., scala.Boolean has null superClass although it's not an interface)
25
- val isCompilingStdLib = ! (settings.sourcepath.isDefault)
24
+ // Used only for assertions. When compiling the Scala library, some assertions don't hold
25
+ // (e.g., scala.Boolean has null superClass although it's not an interface)
26
+ private val isCompilingStdLib = ! (settings.sourcepath.isDefault)
26
27
27
28
// special names
28
29
var StringReference : ClassBType = null
@@ -175,12 +176,21 @@ abstract class BCodeTypes extends BCodeIdiomatic {
175
176
// ------------------------------------------------
176
177
177
178
/**
178
- * TODO @lry should probably be a map form ClassBType to Tracked
179
+ * Type information for classBTypes.
180
+ *
181
+ * TODO rename Tracked
179
182
*/
180
- val exemplars = new java.util.concurrent.ConcurrentHashMap [BType , Tracked ]
183
+ val exemplars = new java.util.concurrent.ConcurrentHashMap [ClassBType , Tracked ]
181
184
182
185
/**
183
186
* Maps class symbols to their corresponding `Tracked` instance.
187
+ *
188
+ * This map is only used during the first backend phase (Worker1) where ClassDef trees are
189
+ * transformed into ClassNode asm trees. In this phase, ClassBTypes and their Tracked are created
190
+ * and added to the `exemplars` map. The `symExemplars` map is only used to know if a symbol has
191
+ * already been visited.
192
+ *
193
+ * TODO move this map to the builder class. it's only used during building. can be gc'd with the builder.
184
194
*/
185
195
val symExemplars = new java.util.concurrent.ConcurrentHashMap [Symbol , Tracked ]
186
196
@@ -313,7 +323,7 @@ abstract class BCodeTypes extends BCodeIdiomatic {
313
323
final def isDeprecated (sym : Symbol ): Boolean = { sym.annotations exists (_ matches definitions.DeprecatedAttr ) }
314
324
315
325
/* must-single-thread */
316
- final def hasInternalName (sym : Symbol ) = { sym.isClass || ( sym.isModule && ! sym.isMethod) }
326
+ final def hasInternalName (sym : Symbol ) = sym.isClass || sym.isModuleNotMethod
317
327
318
328
/* must-single-thread */
319
329
def getSuperInterfaces (csym : Symbol ): List [Symbol ] = {
@@ -702,6 +712,10 @@ abstract class BCodeTypes extends BCodeIdiomatic {
702
712
var x = ics
703
713
while (x ne NoSymbol ) {
704
714
assert(x.isClass, s " not a class symbol: ${x.fullName}" )
715
+ // Uses `rawowner` because `owner` reflects changes in the owner chain due to flattening.
716
+ // The owner chain of a class only contains classes. This is because the lambdalift phase
717
+ // changes the `rawowner` destructively to point to the enclosing class. Before, the owner
718
+ // might be for example a method.
705
719
val isInner = ! x.rawowner.isPackageClass
706
720
if (isInner) {
707
721
chain ::= x
@@ -794,14 +808,23 @@ abstract class BCodeTypes extends BCodeIdiomatic {
794
808
* must-single-thread
795
809
*/
796
810
def javaFlags (sym : Symbol ): Int = {
797
- // constructors of module classes should be private
798
- // PP: why are they only being marked private at this stage and not earlier?
811
+ // constructors of module classes should be private. introduced in b06edbc, probably to prevent
812
+ // creating module instances from java. for nested modules, the constructor needs to be public
813
+ // since they are created by the outer class and stored in a field. a java client can create
814
+ // new instances via outerClassInstance.new InnerModuleClass$().
815
+ // TODO: do this early, mark the symbol private.
799
816
val privateFlag =
800
817
sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModule(sym.owner))
801
818
802
- // Final: the only fields which can receive ACC_FINAL are eager vals.
803
- // Neither vars nor lazy vals can, because:
819
+ // Symbols marked in source as `final` have the FINAL flag. (In the past, the flag was also
820
+ // added to modules and module classes, not anymore since 296b706).
821
+ // Note that the presence of the `FINAL` flag on a symbol does not correspond 1:1 to emitting
822
+ // ACC_FINAL in bytecode.
823
+ //
824
+ // Top-level modules are marked ACC_FINAL in bytecode (even without the FINAL flag). Nested
825
+ // objects don't get the flag to allow overriding (under -Yoverride-objects, SI-5676).
804
826
//
827
+ // For fields, only eager val fields can receive ACC_FINAL. vars or lazy vals can't:
805
828
// Source: http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3
806
829
// "Another problem is that the specification allows aggressive
807
830
// optimization of final fields. Within a thread, it is permissible to
@@ -818,7 +841,6 @@ abstract class BCodeTypes extends BCodeIdiomatic {
818
841
// we can exclude lateFINAL. Such symbols are eligible for inlining, but to
819
842
// avoid breaking proxy software which depends on subclassing, we do not
820
843
// emit ACC_FINAL.
821
- // Nested objects won't receive ACC_FINAL in order to allow for their overriding.
822
844
823
845
val finalFlag = (
824
846
(((sym.rawflags & symtab.Flags .FINAL ) != 0 ) || isTopLevelModule(sym))
@@ -845,6 +867,10 @@ abstract class BCodeTypes extends BCodeIdiomatic {
845
867
if (sym.isVarargsMethod) ACC_VARARGS else 0 ,
846
868
if (sym.hasFlag(symtab.Flags .SYNCHRONIZED )) ACC_SYNCHRONIZED else 0
847
869
)
870
+ // TODO @lry should probably also check / add "deprectated"
871
+ // all call sites of "javaFlags" seem to check for deprecation rigth after.
872
+ // Exception: the call below in javaFieldFlags. However, the caller of javaFieldFlags then
873
+ // does the check.
848
874
}
849
875
850
876
/*
0 commit comments