-
Bug
-
Resolution: Fixed
-
P4
-
7
-
None
-
generic
-
generic
-
Verified
The 'Primary' grammar production intentionally excludes ExpressionName (see 15.14, 15.8). This appears to have not been well-understood when the productions for 'MethodInvocation' and 'ClassInstanceCreationExpression' evolved.
The grammar for 'MethodInvocation' includes the following cases (plus cases for 'super'):
MethodName ( ArgumentList_opt )
Primary . NonWildTypeArguments_opt Identifier ( ArgumentList_opt )
TypeName . NonWildTypeArguments Identifier ( ArgumentList_opt )
This doesn't include a case for expressions like (where 'x' is a variable):
x.<Foo>m()
Treating the productions as strictly syntactic, this instance is arguably covered by the 'TypeName' case -- 'x' has the syntactic form of a TypeName. But the JLS grammar productions also carry semantic meaning; in this specific case, a 'TypeName' interpretation isn't supported by 6.5.5, and falls apart in 15.12.1, when no class to be searched is specified.
My preferred productions:
AmbiguousName . NonWildTypeArguments_opt Identifier ( ArgumentList_opt )
Primary . NonWildTypeArguments_opt Identifier ( ArgumentList_opt )
At that point, it's worth exploring whether the definition of 'MethodName' is worth having at all. It might make sense to remove it completely from the spec.
For 'ClassInstanceCreationExpression':
new TypeArguments_opt ClassOrInterfaceType ( ArgumentList_opt ) ClassBody_opt
Primary . new TypeArguments_opt Identifier TypeArguments_opt ( ArgumentList_opt ) ClassBody_opt
After the changes for diamond (JSR 334):
new TypeArguments_opt ClassOrInterfaceType TypeDeclSpecifier TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
Primary . new TypeArguments_opt Identifier TypeArguments_opt TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
Similarly, this doesn't allow:
x.new Foo()
A new production is needed:
new TypeArguments_opt ClassOrInterfaceType TypeDeclSpecifier TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
ExpressionName . new TypeArguments_opt Identifier TypeArguments_opt TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
Primary . new TypeArguments_opt Identifier TypeArguments_opt TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
An alternative to the above changes (for both methods and constructors) is to introduce a production that fits the intuition:
PrimaryThing:
ExpressionName
Primary
PostfixExpression:
PrimaryThing
PostIncrementExpression
PostDecrementExpression
Maybe this could be called "Primary", depending on how the thing we currently call "Primary" is used... (I think the goal of excluding 'ExpressionName' from 'Primary' currently is to avoid having to disambiguate x.y.z as nested primaries vs. a single name.)
Finally, the use of 'TypeArguments' vs. 'NonWildTypeArguments' is inconsistent. This difference is reconciled by a textual restriction in 15.9, although it is not very precise. It would be better to put the restriction in the grammar.
ClassInstanceCreationExpression:
new NonWildTypeArguments_opt ClassOrInterfaceType TypeDeclSpecifier NonWildTypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
ExpressionName . new NoWildTypeArguments_opt Identifier TypeArguments_opt NonWildTypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
Primary . new NonWildTypeArguments_opt Identifier TypeArguments_opt NonWildTypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
NonWildTypeArgumentsOrDiamond:
NonWildTypeArguments
< >
(I'm not fond of some of these names. Might I also recommend the following renamings:
NonWildTypeArguments -> GroundTypeArguments or ConcreteTypeArguments
NonWildTypeArgumentsOrDiamond -> ClassInstanceTypeArguments
)
The grammar for 'MethodInvocation' includes the following cases (plus cases for 'super'):
MethodName ( ArgumentList_opt )
Primary . NonWildTypeArguments_opt Identifier ( ArgumentList_opt )
TypeName . NonWildTypeArguments Identifier ( ArgumentList_opt )
This doesn't include a case for expressions like (where 'x' is a variable):
x.<Foo>m()
Treating the productions as strictly syntactic, this instance is arguably covered by the 'TypeName' case -- 'x' has the syntactic form of a TypeName. But the JLS grammar productions also carry semantic meaning; in this specific case, a 'TypeName' interpretation isn't supported by 6.5.5, and falls apart in 15.12.1, when no class to be searched is specified.
My preferred productions:
AmbiguousName . NonWildTypeArguments_opt Identifier ( ArgumentList_opt )
Primary . NonWildTypeArguments_opt Identifier ( ArgumentList_opt )
At that point, it's worth exploring whether the definition of 'MethodName' is worth having at all. It might make sense to remove it completely from the spec.
For 'ClassInstanceCreationExpression':
new TypeArguments_opt ClassOrInterfaceType ( ArgumentList_opt ) ClassBody_opt
Primary . new TypeArguments_opt Identifier TypeArguments_opt ( ArgumentList_opt ) ClassBody_opt
After the changes for diamond (JSR 334):
new TypeArguments_opt ClassOrInterfaceType TypeDeclSpecifier TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
Primary . new TypeArguments_opt Identifier TypeArguments_opt TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
Similarly, this doesn't allow:
x.new Foo()
A new production is needed:
new TypeArguments_opt ClassOrInterfaceType TypeDeclSpecifier TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
ExpressionName . new TypeArguments_opt Identifier TypeArguments_opt TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
Primary . new TypeArguments_opt Identifier TypeArguments_opt TypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
An alternative to the above changes (for both methods and constructors) is to introduce a production that fits the intuition:
PrimaryThing:
ExpressionName
Primary
PostfixExpression:
PrimaryThing
PostIncrementExpression
PostDecrementExpression
Maybe this could be called "Primary", depending on how the thing we currently call "Primary" is used... (I think the goal of excluding 'ExpressionName' from 'Primary' currently is to avoid having to disambiguate x.y.z as nested primaries vs. a single name.)
Finally, the use of 'TypeArguments' vs. 'NonWildTypeArguments' is inconsistent. This difference is reconciled by a textual restriction in 15.9, although it is not very precise. It would be better to put the restriction in the grammar.
ClassInstanceCreationExpression:
new NonWildTypeArguments_opt ClassOrInterfaceType TypeDeclSpecifier NonWildTypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
ExpressionName . new NoWildTypeArguments_opt Identifier TypeArguments_opt NonWildTypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
Primary . new NonWildTypeArguments_opt Identifier TypeArguments_opt NonWildTypeArgumentsOrDiamond_opt ( ArgumentList_opt ) ClassBody_opt
NonWildTypeArgumentsOrDiamond:
NonWildTypeArguments
< >
(I'm not fond of some of these names. Might I also recommend the following renamings:
NonWildTypeArguments -> GroundTypeArguments or ConcreteTypeArguments
NonWildTypeArgumentsOrDiamond -> ClassInstanceTypeArguments
)