Module compilation unit grammar

Alex Buckley alex.buckley at oracle.com
Fri Apr 1 16:22:33 PDT 2011


There are two ways to define export:

1) Export a package as a unit. No need for '.*' and it is impossible to 
export individual types. (Allowing 'export p.q' to mean package p.q but 
'export p.q.r' to mean type r in package p.q is too confusing, I think.)

2) Export individual types, and use '.*' to export all public types in 
the package. Also '.**' to export all public types in subpackages.

I prefer (2) because:

- While it's appealing to think of a package as a unit, the reality is 
that a package is nothing more than a qualifier on a type name. A module 
system doesn't make a package visible per se; it makes certain public 
types in a package visible.

- 'import' already provides a type-centric view of the world. Even if 
you write 'import foo.*', you are aware of individual types within 
package foo. I think we should stick with it for 'export'. Good practice 
may end up being to export individual type names, as it is with import.

- It allows the .** "all subpackages" export, which (1) would enumerate 
individually.

(2) adds the burden of classifying names as package names or type names; 
see below. (2) also requires more of the module system, though in no way 
does it cause split packages at runtime any more than (1).

I propose:
- 'export p' is invalid because p is not a qualified name.
- 'export p.q' means export the single type p.q.
- 'export p.*' means export all public types in package p.
- 'export p.**' means export all public types in package p and its 
subpackages, and their subpackages, etc.
- 'export p.q.*' means export either all public types in package p.q or 
all public member types in type q in package p - depending on p.q's 
classification given the module's membership.

Alex

On 4/1/2011 3:33 PM, Mandy Chung wrote:
>  Adding to Jon's question:
> 
>     export p.*;
> 
> Does '*' match '.' in the package name?  If not, it'd be useful to 
> support '**' like syntax e.g. 'export java.**;'  exports all package 
> names with 'java.' prefix.
> 
> Mandy
> 
> On 4/1/11 3:05 PM, Jonathan Gibbons wrote:
>> Is the asterisk form of export constrained to packages and/or is it 
>> required for packages?
>>
>> For example, which of the following are valid
>>
>>     export p;
>>     export p.*;
>>     export p.Clazz;
>>     export p.Clazz.*;
>>
>> -- Jon
>>
>>
>> On 03/11/2011 03:51 PM, Alex Buckley wrote:
>>> Here is the current grammar used by javac to parse a module 
>>> compilation unit ("module-info.java").
>>>
>>>
>>> * Example
>>>
>>> module a.b @ 1.0 {
>>>   require c.d @ [2.0,3.0);
>>>   export  e.f.*;
>>>   provide g.h @ 4.0;
>>>   permit  i.j;
>>>   class   k.l;
>>> }
>>>
>>> - A compilation unit may contain a module declaration.
>>>
>>> - A module declaration may not be annotated.
>>>
>>> - A module name is a qualified identifier, in the spirit of a 
>>> package-or-type name and a type name (JLS3 6.5).
>>>
>>> - A module version is like a qualified identifier, except that the 
>>> characters of the identifier may be any Java letter or digit (to 
>>> allow a first numeric character) and the qualifier may be .+-:~ (as 
>>> per 
>>> http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version, 
>>> referred to by org/openjdk/jigsaw/JigsawVersion.java).
>>>
>>> - require takes a qualified identifier indicating a module name, 
>>> optionally followed by '@' and a version query. A version query is an 
>>> exact version or an interval.
>>>
>>> - require supports 'local' and 'optional' flags. There is no 'public' 
>>> flag because re-export is handled by the export statement.
>>>
>>> - export takes a qualified identifier indicating a package or type 
>>> name, possibly ending in '. *'.
>>>
>>> - permit takes a qualified identifier indicating a module name.
>>>
>>> - class takes a qualified identifier indicating a type name.
>>>
>>> - require/local/optional/export/provide/permit are restricted keywords.
>>>
>>>
>>> * Grammar
>>>
>>> [x] denotes zero or one occurrences of x.
>>> {x} denotes zero or more occurrences of x.
>>> (x|y) means one of either x or y.
>>>
>>>
>>> CompilationUnit:
>>>   [PackageDeclaration] [ImportDeclaration] [TypeDeclaration]
>>>   [ModuleDeclaration]
>>>
>>> ModuleDeclaration:
>>>   'module' ModuleName ['@' Version] '{' {ModuleStatement} '}'
>>>
>>> ModuleName:
>>>   Identifier
>>>   ModuleName '.' Identifier
>>>
>>> ModuleStatement:
>>>   ModuleRequire
>>>   ModuleProvide
>>>   ModuleExport
>>>   ModulePermit
>>>   ModuleClass
>>>
>>> ModuleRequire:
>>>   'require' [ModuleRequireModifier] ModuleName ['@' VersionQuery] ';'
>>>
>>> ModuleRequireModifier:
>>>   'local'
>>>   'optional'
>>>
>>> ModuleExport:
>>>   'export' PackageOrTypeName ['.' '*'] ';'
>>>
>>> ModuleProvide:
>>>   'provide' ModuleName ['@' Version] ';'
>>>
>>> ModulePermit:
>>>   'permit' ModuleName ';'
>>>
>>> ModuleClass:
>>>   'class' TypeName ';'
>>>
>>> VersionQuery:
>>>   Version
>>>   ('['|'(') Version ',' Version (')'|']')
>>>
>>> Version:
>>>   ModuleIdentifier {VersionTokenizer ModuleIdentifier}
>>>
>>> ModuleIdentifier:
>>>   JavaLetterOrDigit
>>>   ModuleIdentifier JavaLetterOrDigit
>>>
>>> VersionTokenizer:
>>>   . or + or - or : or ~
>>>
>>
> 



More information about the jigsaw-dev mailing list