Details
-
Bug
-
Status: Open
-
P4
-
Resolution: Unresolved
-
None
-
None
Description
Top-level packages have the following scope:
"The scope of a top level class or interface (§7.6) is all class and interface declarations in the package in which the top level class or interface is declared."
Notably, this doesn't say "all compilation units", and in fact names used in import statements never resolve to classes in the current package, even though they are formally classified as TypeNames (qualified by PackageOrTypeNames).
package P; public class Foo {}
package x; public class P { public static class Foo {} }
package x;
import P.Foo; // compiles to P/Foo
class Test extends P.Foo {} // compiles to x/P$Foo
However, javac also treats the class as being in scope when interpreting package annotations.
package P; public @interface Bar {}
package x; public class P { public @interface Bar {} }
@P.Bar package x; // compiles to x/P$Foo
(I assume modules have similar behavior.)
Possible fixes:
- Add some cases to the scope rule to include essentially everything *except* imports
- Reconsider the exception for imports
- Implement the current rule when interpreting package annotations and modules
Note that the default package is a special case, because top-level classes in the default package can't be referenced with qualified names. Allowing imports from the current package could be a useful feature in the default package. Disallowing annotations or annotation arguments referencing the current package could be a breaking change without a good workaround in the default package.
"The scope of a top level class or interface (§7.6) is all class and interface declarations in the package in which the top level class or interface is declared."
Notably, this doesn't say "all compilation units", and in fact names used in import statements never resolve to classes in the current package, even though they are formally classified as TypeNames (qualified by PackageOrTypeNames).
package P; public class Foo {}
package x; public class P { public static class Foo {} }
package x;
import P.Foo; // compiles to P/Foo
class Test extends P.Foo {} // compiles to x/P$Foo
However, javac also treats the class as being in scope when interpreting package annotations.
package P; public @interface Bar {}
package x; public class P { public @interface Bar {} }
@P.Bar package x; // compiles to x/P$Foo
(I assume modules have similar behavior.)
Possible fixes:
- Add some cases to the scope rule to include essentially everything *except* imports
- Reconsider the exception for imports
- Implement the current rule when interpreting package annotations and modules
Note that the default package is a special case, because top-level classes in the default package can't be referenced with qualified names. Allowing imports from the current package could be a useful feature in the default package. Disallowing annotations or annotation arguments referencing the current package could be a breaking change without a good workaround in the default package.