Where do empty compilation units belong?
Jonathan Gibbons
jonathan.gibbons at oracle.com
Mon Nov 26 23:22:53 UTC 2018
On 11/26/2018 01:44 PM, Alex Buckley wrote:
> // 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 straightforward:
>
> OrdinaryCompilationUnit:
> 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?
>
> Alex
That seems good to me.
To summarize the javac behavior ...
* javac accepts/ignores an empty file
* javac treats import-only compilation units as in the unnamed
package, which is not allowed in a named module
* javac enforces file naming constraints when declaring a public class
* javac uses file naming constraints when looking on the (module)
source path for a file for a class
Attached is a toy class to generate combinations of package, import and
type declarations. You can use the source-launcher feature to run it.
-- Jon
More information about the jigsaw-dev
mailing list