-
Notifications
You must be signed in to change notification settings - Fork 72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Exploring inner modules for binary incompatibilities. Fix #127 #128
Conversation
186a52f
to
3fa7bdd
Compare
…abs#127 The former implementation of PackageInfo#accessibleClasses expects that for any module `Foo` compiled by scalac, both `Foo.class` and `Foo$.class` classfiles are produced. Because `Foo$.class` and `Foo.class` are essentially mirrors, and users never access directly `Foo$.class`, MiMa only traverses the `Foo.class`. This works well for top-level modules, but it breaks for inner modules, because no mirror class is created for inner modules (only the module class is created). The fix consist in treating inner modules differently, hence making sure inner modules are part of the set returned by PackageInfo#accessibleClasses.
3fa7bdd
to
2d67b04
Compare
Could you expand on this with an example? It seems incorrect to me. For example:
|
} | ||
// class, trait, and top-level module go through this condition | ||
(prefix exists (_.decodedName == clazz.decodedName.substring(0, idx))) || // prefix before dollar is an accessible class detected previously | ||
isInnerModule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be more robust to check the InnerClasses
attribute of the module class.
⚡ printf 'object N { class O }; class C { object O }' > /tmp/test.scala && scalac /tmp/test.scala && javap -classpath . -v 'C$O$' 'N$O' 2>&1 | grep --after=1 InnerClasses:
InnerClasses:
public #17= #2 of #16; //O$=class C$O$ of class C
--
InnerClasses:
public static #14= #2 of #13; //O=class N$O of class N
Hi Jason, thanks a lot for the feedback!
You are absolutely right. And, in fact, my statement "MiMa only traverses the Foo.class" is not false: MiMa does traverse both Unfortunately, I don't have more spare cycles to dedicate to this at the moment. I'm closing this PR. |
The former implementation of PackageInfo#accessibleClasses expects that for any
module
Foo
compiled by scalac, bothFoo.class
andFoo$.class
classfilesare produced. Because
Foo$.class
andFoo.class
are essentially mirrors, andusers never access directly
Foo$.class
, MiMa only traverses theFoo.class
. Thisworks well for top-level modules, but it breaks for inner modules, because no
mirror class is created for inner modules (only the module class is created).
The fix consist in treating inner modules differently, hence making sure inner
modules are part of the set returned by PackageInfo#accessibleClasses.