Skip to content

Commit

Permalink
Fix #413: Handle inner classes based on content, not names.
Browse files Browse the repository at this point in the history
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 #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.
  • Loading branch information
sjrd committed Dec 7, 2023
1 parent 6ae6a1f commit c818a7f
Show file tree
Hide file tree
Showing 6 changed files with 272 additions and 248 deletions.
11 changes: 8 additions & 3 deletions tasty-query/shared/src/main/scala/tastyquery/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1832,6 +1832,9 @@ object Symbols {
/** Is this the root package? */
final def isRootPackage: Boolean = owner == null

/** Is this the empty package? */
private[tastyquery] def isEmptyPackage: Boolean = specialKind == SpecialKind.empty

/** Is this the scala package? */
private[tastyquery] def isScalaPackage: Boolean = specialKind == SpecialKind.scala

Expand Down Expand Up @@ -1961,9 +1964,10 @@ object Symbols {
private[Symbols] object SpecialKind:
inline val None = 0
inline val root = 1
inline val scala = 2
inline val java = 3
inline val javaLang = 4
inline val empty = 2
inline val scala = 3
inline val java = 4
inline val javaLang = 5
end SpecialKind

private def computeSpecialKind(name: SimpleName, owner: PackageSymbol | Null): SpecialKind =
Expand All @@ -1972,6 +1976,7 @@ object Symbols {
(owner.specialKind: @switch) match
case SpecialKind.root =>
name match
case nme.EmptyPackageName => SpecialKind.empty
case nme.scalaPackageName => SpecialKind.scala
case nme.javaPackageName => SpecialKind.java
case _ => SpecialKind.None
Expand Down
Loading

0 comments on commit c818a7f

Please sign in to comment.