Module compilation unit grammar

Alex Buckley alex.buckley at oracle.com
Tue Apr 5 15:47:30 PDT 2011


export needs to be processed after the types _in its module_ have been 
defined, but before the types _in other modules_ have been defined. Does 
this help break the chicken and egg?

I see no reason to allow top level type exports but disallow nested type 
exports. A compiler classifies 'p.q' in an export as a package or type 
name based on the packages and types declared in the module doing the 
export - how could the compiler not see them?

Alex

On 4/4/2011 1:43 PM, Jonathan Gibbons wrote:
> Export issues ...
> 
> It is easy enough to process ModuleExport in source code through to 
> ModuleExport_attribute in a class file.
> 
> But, I foresee problems implementing the semantics of export insofar as 
> it affects the visibility of types.  Chickens and Eggs.  export may 
> refer to types, so it needs to come after those types have been defined. 
> But since export affects visibility, it needs to be processed before 
> that, so we can determine how it affects visibility of types within the 
> compilation ...
> 
> How much does it make sense to be able to specify nested types in an 
> export statement?  E.g. the 'export p.q.*' below, and by implication, 
> 'export p.q.Foo' where p is a package and q is a top level class?
> 
> -- Jon
> 
> 
> On 04/01/2011 04:22 PM, Alex Buckley wrote:
>> 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