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