Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8301905

javac wrongly accepts semicolons in package and import decls

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P5 P5
    • 21
    • tools
    • None
    • source
    • low
    • Hide
      Existing code with extraneous semicolons before import statements will fail to compile. See https://github.com/openjdk/jdk/pull/12448#issuecomment-1420746427 which estimates 0.2% of projects will no longer build after this change.
      Show
      Existing code with extraneous semicolons before import statements will fail to compile. See https://github.com/openjdk/jdk/pull/12448#issuecomment-1420746427 which estimates 0.2% of projects will no longer build after this change.
    • Language construct
    • JDK

      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.

            acobbs Archie Cobbs
            abuckley Alex Buckley
            Vicente Arturo Romero Zaldivar
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: