-
Notifications
You must be signed in to change notification settings - Fork 11
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
Fix #413: Handle inner classes based on content, not names. #419
Conversation
a4f9628
to
c818a7f
Compare
true | ||
else if doLoadClassFile(classData, loadedFiles) then true | ||
else | ||
// Oops, maybe we will need this one later; removing it from loadedFiles |
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.
Maybe you should explain in which situation we would need it again
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.
Done.
|
||
if result == ClassKind.Java && innerClassesStream != null then | ||
if containsSelfInnerClassDecl(structure.binaryName, innerClassesStream.nn) then ClassKind.JavaInnerOrArtifact | ||
else ClassKind.Java |
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.
Should we expect this else
to happen?
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.
That is definitely expected. Top-level classes have InnerClasses
data for their inner classes, and even for any other inner class of other classes that they happen to refer to.
Previously, we assumed that if there is a file `Foo` and a file `Foo$Bar`, that the latter must be an inner class (or companion) of `Foo`, and that it must therefore be ignored. As scalacenter#413 shows, and as the new `JavaDefined$Evil` test shows, this is not always valid. The only true test of a class being top-level can only be found in its content, either through the `Scala` attribute or the `InnerClasses` attribute. We completely rewrite `Loaders`. We now systematically try to load every file that is requested, except when we *already* know that it is a Java inner class. This means that we will read the contents of more files than before, but still each file at most once in the common case. A file *may* be read multiple times if it is a Java non-top-level class that gets requested by its name as if it were a top-level class. The loading will fail but we have to keep the file in case it is loaded later on as an inner class. When reading *all* the declarations of a package, we always try outer classes before potential inner classes so that no double reading happens.
c818a7f
to
648de54
Compare
Previously, we assumed that if there is a file
Foo
and a fileFoo$Bar
, that the latter must be an inner class (or companion) ofFoo
, and that it must therefore be ignored.As #413 shows, and as the new
JavaDefined$Evil
test shows, this is not always valid.The only true test of a class being top-level can only be found in its content, either through the
Scala
attribute or theInnerClasses
attribute.We completely rewrite
Loaders
. We now systematically try to load every file that is requested, except when we already know that it is a Java inner class. This means that we will read the contents of more files than before, but still each file at most once in the common case.A file may be read multiple times if it is a Java non-top-level class that gets requested by its name as if it were a top-level class. The loading will fail but we have to keep the file in case it is loaded later on as an inner class.
When reading all the declarations of a package, we always try outer classes before potential inner classes so that no double reading happens.
The following
TypeSuite
test passes with this PR with the"org.scalaz" %% "scalaz-core" % "7.3.8"
dependency:Moreover, I re-tested locally the local test from PR #416.