Summary
Disallow extraneous semicolons prior to import statements.
Problem
The grammar in JLS §7.3 specifies that while a lone semicolon is a valid TopLevelClassOrInterfaceDeclaration, it is not a valid ImportDeclaration. Therefore, if we see a lone semicolon while looking for the next import
statement we have to advance and accept a class declaration, and we can therefore no longer accept any further import statements.
However, the compiler is not following the spec. It is allowing these extraneous semicolons.
Solution
Disallow extraneous semicolons prior to import
statements for source versions 21 and later by generating an error; for source versions below 21, generate a warning instead.
If extraneous semicolon(s) are encountered, generate an "extraneous semicolon" error or warning message and continue parsing import
statements (if any). This behavior is more gentle than the simple "greedy" approach, which would be to assume that an extra semicolon must represent an empty class declaration and then failing repeatedly on each of the subsequent import
statements with a "class, interface, enum, or record expected" error.
Here's an example of the changed behavior:
Previous:
$ cat Foo0.java
package p; ;;; import java.util.Map; class Foo {} ;;;;;;;;
$ javac -d ../../classes Foo0.java
$
New:
$ cat Foo0.java
package p; ;;; import java.util.Map; class Foo {} ;;;;;;;;
$ javac -d ../../classes Foo0.java
Foo0.java:1: error: extraneous semicolon
package p; ;;; import java.util.Map; class Foo {} ;;;;;;;;
^
1 error
$ javac -d ../../classes --release 19 Foo0.java
Foo0.java:1: warning: extraneous semicolon
package p; ;;; import java.util.Map; class Foo {} ;;;;;;;;
^
1 warning
$
Specification
Here's are some relevant grammar production rules from JLS §7.3:
CompilationUnit:
OrdinaryCompilationUnit
ModularCompilationUnit
OrdinaryCompilationUnit:
[PackageDeclaration] {ImportDeclaration} {TopLevelClassOrInterfaceDeclaration}
PackageDeclaration:
{PackageModifier} package Identifier {. Identifier} ;
ImportDeclaration:
SingleTypeImportDeclaration
TypeImportOnDemandDeclaration
SingleStaticImportDeclaration
StaticImportOnDemandDeclaration
SingleTypeImportDeclaration:
import TypeName ;
TypeImportOnDemandDeclaration:
import PackageOrTypeName . * ;
SingleStaticImportDeclaration:
import static TypeName . Identifier ;
StaticImportOnDemandDeclaration:
import static TypeName . * ;
TopLevelClassOrInterfaceDeclaration:
ClassDeclaration
InterfaceDeclaration
;
Only TopLevelClassOrInterfaceDeclaration allows a standalone semicolon; this has been the case since at least Java 6.
- csr of
-
JDK-8027682 javac wrongly accepts semicolons in package and import decls
-
- Resolved
-