diff --git a/pmd-java/etc/grammar/Java.jjt b/pmd-java/etc/grammar/Java.jjt index 364d997e99..44def98dbb 100644 --- a/pmd-java/etc/grammar/Java.jjt +++ b/pmd-java/etc/grammar/Java.jjt @@ -1606,17 +1606,27 @@ ASTCompilationUnit CompilationUnit() : { [ LOOKAHEAD( ( Annotation() )* "package" ) PackageDeclaration() ( EmptyStatement() )* ] ( ImportDeclaration() ( EmptyStatement() )* )* - ( LOOKAHEAD(2) TypeDeclaration() ( EmptyStatement() )* )* - [ LOOKAHEAD({isKeyword("open") || isKeyword("module") || getToken(1).kind == AT}) ModuleDeclaration() ( EmptyStatement() )* ] + // the module decl lookahead needs to be before the type declaration branch, + // looking for annotations + "open" | "module" will fail faster if it's *not* + // a module (most common case) + [ LOOKAHEAD(ModuleDeclLahead()) ModuleDeclaration() ( EmptyStatement() )* ] + ( TypeDeclaration() ( EmptyStatement() )* )* ( < "\u001a" > )? - ( < "~[]" > )? + ( < "~[]" > )? // what's this for? Do you mean ( < ~[] > )*, i.e. "any character"? + { + jjtThis.setComments(token_source.comments); + return jjtThis; + } +} + +private void ModuleDeclLahead() #void: +{} { - jjtThis.setComments(token_source.comments); - return jjtThis; -} + (Annotation())* LOOKAHEAD({isKeyword("open") || isKeyword("module")}) } + void PackageDeclaration() : {} { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java index c93605ddb8..2f39c71b1e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/ast/JDKVersionTest.java @@ -263,6 +263,11 @@ public class JDKVersionTest { parseJava9(loadSource("jdk9_module_info.java")); } + @Test + public void testAnnotatedModule() { + parseJava9(loadSource("jdk9_module_info_with_annot.java")); + } + @Test(expected = ParseException.class) public final void jdk9TryWithResourcesInJava8() { parseJava18(loadSource("jdk9_try_with_resources.java")); diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/jdk9_module_info_with_annot.java b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/jdk9_module_info_with_annot.java new file mode 100644 index 0000000000..628f1c5cf2 --- /dev/null +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/ast/jdkversiontests/jdk9_module_info_with_annot.java @@ -0,0 +1,6 @@ +/* + * See ยง7.7 Module Declarations in JLS + */ +@Deprecated(since = "11", forRemoval = true) +module jdk.pack { +}