Add Java9 Language Module, Update grammar

* Java8 mode now rejects private methods in interfaces
* Java9 mode now rejects "_" as identifier
This commit is contained in:
Andreas Dangel
2017-09-22 12:16:51 +02:00
parent df87db8d7a
commit cfa4b5b85c
8 changed files with 166 additions and 2 deletions

View File

@ -1,4 +1,9 @@
/**
* Add support for Java 9 changes
* private interface methods are only allowed with java9,
* a single underscore "_" is an invalid identifier in java9.
* Andreas Dangel 09/2017
*====================================================================
* Add support for new Java 8 annotation locations.
* Bugs #414, #415, #417
* @Snap252 06/2017
@ -319,6 +324,22 @@ public class JavaParser {
throwParseException("Cannot use explicit receiver parameters when running in JDK inferior to 1.8 mode!");
}
}
/**
* Keeps track whether we are dealing with an interface or not. Needed since the tree is
* is not fully constructed yet, when we check for private interface methods.
* The flag is updated, if entering ClassOrInterfaceDeclaration and reset when leaving.
*/
private boolean inInterface = false;
private void checkForBadPrivateInterfaceMethod(ASTMethodDeclaration node) {
if (jdkVersion < 9 && inInterface && node.isPrivate()) {
throwParseException("Cannot use private interface methods when running in JDK inferior to 9 mode!");
}
}
private void checkForBadIdentifier(String image) {
if (jdkVersion >= 9 && "_".equals(image)) {
throwParseException("With JDK 9, '_' is a keyword, and may not be used as an identifier!");
}
}
// This is a semantic LOOKAHEAD to determine if we're dealing with an assert
// Note that this can't be replaced with a syntactic lookahead
@ -1343,12 +1364,14 @@ jjtThis.setModifiers(modifiers);
}
{
( /* See note about this optional final modifier in BlockStatement */ ["final"|"abstract"] "class" | "interface" { jjtThis.setInterface(); } )
( /* See note about this optional final modifier in BlockStatement */
["final"|"abstract"] "class" | "interface" { jjtThis.setInterface(); inInterface = true; } )
t=<IDENTIFIER> { jjtThis.setImage(t.image); }
[ TypeParameters() ]
[ ExtendsList() ]
[ ImplementsList() ]
ClassOrInterfaceBody()
{ inInterface = false; } // always reset the flag after leaving the node
}
void ExtendsList():
@ -1446,6 +1469,7 @@ void ClassOrInterfaceBodyDeclaration():
";"
}
void FieldDeclaration(int modifiers) :
{jjtThis.setModifiers(modifiers);}
{
@ -1471,6 +1495,7 @@ void VariableDeclaratorId() :
{
checkForBadAssertUsage(image, "a variable name");
checkForBadEnumUsage(image, "a variable name");
checkForBadIdentifier(image);
jjtThis.setImage( image );
}
}
@ -1489,7 +1514,10 @@ void ArrayInitializer() :
}
void MethodDeclaration(int modifiers) :
{jjtThis.setModifiers(modifiers);}
{
jjtThis.setModifiers(modifiers);
{ checkForBadPrivateInterfaceMethod(jjtThis); }
}
{
[ TypeParameters() ]
(Annotation() {checkForBadTypeAnnotations();})* ResultType() MethodDeclarator() [ "throws" NameList() ]