Where do empty compilation units belong?

Alex Buckley alex.buckley at oracle.com
Mon Nov 26 21:44:01 UTC 2018

// Adding compiler-dev since the parsing of files into compilation units 
is not a Jigsaw issue.

On 11/20/2018 9:14 PM, Jayaprakash Artanareeswaran wrote:
> "jigsaw-dev" <jigsaw-dev-bounces at openjdk.java.net> wrote on 21/11/2018
> 01:56:42 AM:
>  > Jon points out that `OrdinaryCompilationUnit` will match an empty stream
>  > of tokens (I dislike the syntax-driven optionality here, but it's
>  > longstanding) so the file D.java could be regarded as a compilation unit
>  > with no package declaration, no import declarations, and no type
>  > declarations.
>  >
>  > Per JLS 7.4.2, such a compilation unit is in an unnamed package, and
>  > must be associated with an unnamed module.
>  >
>  > I would prefer 7.4.2 to say only that a compilation unit with no package
>  > declarations _and at least one type declaration_ is in an unnamed
>  > package (and must be associated with an unnamed module; 7.3 should
>  > enumerate that possibility). A compilation unit with no package
>  > declarations _and no type declarations_ would be deemed unobservable by
>  > 7.3, and all these questions about what to do with empty files would
>  > disappear.
> That would be perfect and make things unambiguous. But for now, the
> paragraph above is good enough for me.

Unfortunately, import declarations can have side effects (compile-time 
errors) so to be sure that the "no package or type decl === 
unobservable" rule is suitable for a file containing just an import 
decl, we would have to do a case analysis of how javac and ecj handle 
the eight combinations of the three parts allowed in an ordinary 
compilation unit. That's overkill for the situation involving empty 
files that keeps coming up and that I really want to clarify. I don't 
think anyone loves that an ordinary compilation unit matches the empty 
stream, so let's define away that scenario. As Jon said, an empty file 
doesn't present anything to be checked; there is no compilation unit 
there, so let's be unambiguous about that.

We can rule out the empty stream in 7.3 with grammar or with semantics. 
Usually a semantic description is clearest (gives everyone the proper 
terminology and concepts) but in this case we don't want the description 
to wrestle with "consists of one, two, or three parts" when the grammar 
allows zero. So, a new grammatical description is appropriate, and 

     PackageDeclaration {ImportDeclaration} {TypeDeclaration}
     ImportDeclaration {ImportDeclaration} {TypeDeclaration}
     TypeDeclaration {TypeDeclaration}

The "three parts, each of which is optional" description is still 
accurate. The package decl part is optional (as long as you have the 
import decls part and/or the type decls part); the import decls part is 
optional (as long as you have either the package decl part or ...) ... 
you get the picture.

I would leave 7.4.2 alone; an ordinary compilation unit with no package 
or type decls but with import decls is part of the unnamed package (and 
thus unnamed module) as before, and compilers can handle that, I think.

Any comments?


More information about the compiler-dev mailing list