|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This infrastructure is required for the inliner: when inlining code
from a classfile, the corresponding ClassBType is needed for various
things (eg access checks, InnerClass attribute).
The test creates two ClassBTypes for the same class: once using the
(unpickled) Symbol, once using the parsed ASM ClassNode, and verifies
that the two are the same.
There's a cleanup to the InnerClass attribute:
object T { class Member; def foo = { class Local } }
class T
For Java compatibility the InnerClass entry for Member says the class
is nested in T (not in the module class T$). We now make sure to add
that entry only to T, not to T$ (unless Member is actually referenced
in the classfile T$, in that case it will be added, as required).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit seems bigger than it is. Most of it is tests, and moving
some code around. The actual changes are small, but a bit subtle.
The InnerClass and EnclosingMethod attributes should now be close to
the JVM spec (which is summarized in BTypes.scala). New tests make
sure that changes to these attributes, and changes to the way Java
reflection sees Scala classfiles, don't go unnoticed.
A new file, BCodeAsmCommon, holds code that's shared between the two
backend (it could hold more, future work).
In general, the difficulty with emitting InnerClass / EnclosingMethod
is that we need to find out source-level properties. We need to make
sure to do enough phase-travelling, and work around destructive
changes to the ownerchain in lambdalift (we use originalOwner a lot).
The change to JavaMirrors is prompted by the change to the
EnclosingMethod attribute, which changes Java reflection's answer to
getEnclosingMethod and getEnclosingConstructor. Classes defined in
field initializers no longer have an enclosing method, just an
enclosing class, which broke an assumption in JavaMirrors.
There's one change in erasure. Before this change, when an object
declaration implements / overrides a method, and a bridge is required,
then the bridge method was actually a ModuleSymbol (it would get the
lateMETHOD flag and be emitted as a method anyway). This is confusing,
when iterating through the members of a class, you can find two
modules with the same name, and one of them doesn't have a module
class. Now, such bridge methods will be MethodSymbols.
Removed Symbol.originalEnclosingMethod, that is a backend thing and
doesn't need to live in the symbol API.
|