From 89b4dcd4d51d0dcc0b1347bcc7f4f3c533fefaa4 Mon Sep 17 00:00:00 2001 From: Erik Silkensen <94125+esilkensen@users.noreply.github.com> Date: Fri, 24 Jan 2020 15:16:57 -0700 Subject: [PATCH] Issue #3238: Java 8 Grammar: annotations on arrays and varargs --- .../whitespace/NoWhitespaceAfterCheck.java | 24 +- .../tools/checkstyle/grammar/java.g | 23 +- .../checkstyle/grammar/AstRegressionTest.java | 6 + .../grammar/java8/AnnotationTest.java | 9 + ...utNoWhitespaceAfterArrayDeclarations3.java | 3 + .../grammar/InputRegressionJava8Class2.java | 38 ++ .../grammar/InputRegressionJava8Class2Ast.txt | 379 ++++++++++++++++++ .../grammar/java8/InputAnnotations12.java | 16 + .../java8/InputAnnotationsOnArray.java | 24 ++ 9 files changed, 514 insertions(+), 8 deletions(-) create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/grammar/InputRegressionJava8Class2.java create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/grammar/InputRegressionJava8Class2Ast.txt create mode 100644 src/test/resources/com/puppycrawl/tools/checkstyle/grammar/java8/InputAnnotations12.java diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheck.java b/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheck.java index d03c25e74c9..caf9a737572 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheck.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/checks/whitespace/NoWhitespaceAfterCheck.java @@ -170,8 +170,7 @@ public void setAllowLineBreaks(boolean allowLineBreaks) { public void visitToken(DetailAST ast) { final DetailAST whitespaceFollowedAst = getWhitespaceFollowedNode(ast); - if (whitespaceFollowedAst.getNextSibling() == null - || whitespaceFollowedAst.getNextSibling().getType() != TokenTypes.ANNOTATIONS) { + if (shouldCheckWhitespaceAfter(whitespaceFollowedAst)) { final int whitespaceColumnNo = getPositionAfter(whitespaceFollowedAst); final int whitespaceLineNo = whitespaceFollowedAst.getLineNo(); @@ -206,6 +205,27 @@ private static DetailAST getWhitespaceFollowedNode(DetailAST ast) { return whitespaceFollowedAst; } + /** + * Returns whether whitespace after a visited node should be checked. For example, whitespace + * is not allowed between a type and an array declarator (returns true), except when there is + * an annotation in between the type and array declarator (returns false). + * @param ast the visited node + * @return true if whitespace after ast should be checked + */ + private static boolean shouldCheckWhitespaceAfter(DetailAST ast) { + boolean checkWhitespace = true; + final DetailAST sibling = ast.getNextSibling(); + if (sibling != null) { + if (sibling.getType() == TokenTypes.ANNOTATIONS) { + checkWhitespace = false; + } + else if (sibling.getType() == TokenTypes.ARRAY_DECLARATOR) { + checkWhitespace = sibling.getFirstChild().getType() != TokenTypes.ANNOTATIONS; + } + } + return checkWhitespace; + } + /** * Gets position after token (place of possible redundant whitespace). * @param ast Node representing token. diff --git a/src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java.g b/src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java.g index 7a569209981..48f0aea9a0f 100644 --- a/src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java.g +++ b/src/main/resources/com/puppycrawl/tools/checkstyle/grammar/java.g @@ -257,6 +257,14 @@ typeSpec[boolean addImagNode] | builtInTypeSpec[addImagNode] ; +// A type specification for a variable length parameter is a type name with +// possible brackets afterwards that can end with annotations. +variableLengthParameterTypeSpec + : (classOrInterfaceType[false] | builtInType) + ({LA(1) == AT}? annotations | ) + (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK ({LA(1) == AT}? annotations | ))* + ; + // A class type specification is a class type with either: // - possible brackets afterwards // (which would make it an array type). @@ -387,8 +395,8 @@ builtInTypeSpec[boolean addImagNode] // A type name. which is either a (possibly qualified and parameterized) // class name or a primitive (builtin) type type - : classOrInterfaceType[false] - | builtInType + : ({LA(1) == AT}? annotations | ) + (classOrInterfaceType[false] | builtInType) ; /** A declaration is the creation of a reference or primitive-type variable @@ -893,9 +901,11 @@ variableDeclarator![AST mods, AST t] {#variableDeclarator = #(#[VARIABLE_DEF,"VARIABLE_DEF"], mods, #(#[TYPE,"TYPE"],d), id, v);} ; -declaratorBrackets[AST typ] - : {#declaratorBrackets=typ;} - (lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} RBRACK)* +declaratorBrackets![AST typ] + : ({LA(1) == AT}? an:annotations | ) lb:LBRACK {#lb.setType(ARRAY_DECLARATOR);} rb:RBRACK + db:declaratorBrackets[#(lb, typ, an, rb)] + {#declaratorBrackets = #db;} + | {#declaratorBrackets = typ;} ; varInitializer @@ -969,7 +979,7 @@ parameterDeclarationList ; variableLengthParameterDeclaration! - : pm:parameterModifier t:typeSpec[false] td:ELLIPSIS IDENT + : pm:parameterModifier t:variableLengthParameterTypeSpec td:ELLIPSIS IDENT pd:declaratorBrackets[#t] {#variableLengthParameterDeclaration = #(#[PARAMETER_DEF,"PARAMETER_DEF"], pm, #([TYPE,"TYPE"],pd), td, IDENT);} @@ -1592,6 +1602,7 @@ newArrayDeclarator warnWhenFollowAmbig = false; } : + ({LA(1) == AT}? annotations | ) lb:LBRACK^ {#lb.setType(ARRAY_DECLARATOR);} (expression)? RBRACK diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/grammar/AstRegressionTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/grammar/AstRegressionTest.java index d1354ba4b73..7eef9b1ae63 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/grammar/AstRegressionTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/grammar/AstRegressionTest.java @@ -68,6 +68,12 @@ public void testJava8ClassAstTree1() throws Exception { getPath("InputRegressionJava8Class1.java")); } + @Test + public void testJava8ClassAstTree2() throws Exception { + verifyAst(getPath("InputRegressionJava8Class2Ast.txt"), + getPath("InputRegressionJava8Class2.java")); + } + @Test public void testInputSemicolonBetweenImports() throws Exception { verifyAst(getPath("InputSemicolonBetweenImportsAst.txt"), diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/grammar/java8/AnnotationTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/grammar/java8/AnnotationTest.java index 1a9952f2d5b..4b98d27f686 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/grammar/java8/AnnotationTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/grammar/java8/AnnotationTest.java @@ -132,4 +132,13 @@ public void testAnnotationInTypeParameters() verify(checkConfig, getPath("InputAnnotations11.java"), expected); } + @Test + public void testAnnotationOnVarargs() + throws Exception { + final DefaultConfiguration checkConfig = + createModuleConfig(MemberNameCheck.class); + final String[] expected = CommonUtil.EMPTY_STRING_ARRAY; + verify(checkConfig, getPath("InputAnnotations12.java"), expected); + } + } diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/nowhitespaceafter/InputNoWhitespaceAfterArrayDeclarations3.java b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/nowhitespaceafter/InputNoWhitespaceAfterArrayDeclarations3.java index 51b841061b2..ec377c1e581 100644 --- a/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/nowhitespaceafter/InputNoWhitespaceAfterArrayDeclarations3.java +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/checks/whitespace/nowhitespaceafter/InputNoWhitespaceAfterArrayDeclarations3.java @@ -9,6 +9,9 @@ public void testWithAnnotationInMiddle1(final char @AnnotationAfterTest [] a) {} public void testWithAnnotationInMiddle2(final char@AnnotationAfterTest [] a) {}//Correct public void testWithAnnotationInMiddle3(final char @AnnotationAfterTest[] a) {}//Correct public void testWithAnnotationInMiddle4(final char@AnnotationAfterTest[]a) {}//Correct + public @AnnotationAfterTest String @AnnotationAfterTest [] testWithAnnotationInMiddle5() { + return new @AnnotationAfterTest String @AnnotationAfterTest [3];//Correct + } @Target(ElementType.TYPE_USE) @interface AnnotationAfterTest { diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/InputRegressionJava8Class2.java b/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/InputRegressionJava8Class2.java new file mode 100644 index 00000000000..d8b0097c4e4 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/InputRegressionJava8Class2.java @@ -0,0 +1,38 @@ +//start line index in expected file is 2 +package com.puppycrawl.tools.checkstyle.grammar; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Map; +import java.util.List; +import java.util.function.IntBinaryOperator; +import java.util.function.Predicate; +import java.util.function.Supplier; + +public class InputRegressionJava8Class2 { + static class Inner1 { static class Inner2 { public void m() {} } } + static class Inner3 { public void m() {} } + + public void m1(@MyAnnotation String @MyAnnotation ... vararg) {} + public String m2() @MyAnnotation [] @MyAnnotation [] { return null; } + + public void instructions() { + // annotations + Map.@MyAnnotation Entry e; + String str = (@MyAnnotation String) ""; + (new Inner3()).<@MyAnnotation String>m(); + Object arr = new @MyAnnotation String @MyAnnotation [3]; + for (String a @MyAnnotation [] : m2()) {} + Object arr2 = new @MyAnnotation int[3]; + } +} + +@Retention(RetentionPolicy.CLASS) +@Target({ ElementType.TYPE_USE }) +@interface MyAnnotation { +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/InputRegressionJava8Class2Ast.txt b/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/InputRegressionJava8Class2Ast.txt new file mode 100644 index 00000000000..34587704b51 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/InputRegressionJava8Class2Ast.txt @@ -0,0 +1,379 @@ +PACKAGE_DEF -> package [2:0] +|--ANNOTATIONS -> ANNOTATIONS [2:39] +|--DOT -> . [2:39] +| |--DOT -> . [2:28] +| | |--DOT -> . [2:22] +| | | |--DOT -> . [2:11] +| | | | |--IDENT -> com [2:8] +| | | | `--IDENT -> puppycrawl [2:12] +| | | `--IDENT -> tools [2:23] +| | `--IDENT -> checkstyle [2:29] +| `--IDENT -> grammar [2:40] +`--SEMI -> ; [2:47] +IMPORT -> import [4:0] +|--DOT -> . [4:27] +| |--DOT -> . [4:16] +| | |--DOT -> . [4:11] +| | | |--IDENT -> java [4:7] +| | | `--IDENT -> lang [4:12] +| | `--IDENT -> annotation [4:17] +| `--IDENT -> ElementType [4:28] +`--SEMI -> ; [4:39] +IMPORT -> import [5:0] +|--DOT -> . [5:27] +| |--DOT -> . [5:16] +| | |--DOT -> . [5:11] +| | | |--IDENT -> java [5:7] +| | | `--IDENT -> lang [5:12] +| | `--IDENT -> annotation [5:17] +| `--IDENT -> Retention [5:28] +`--SEMI -> ; [5:37] +IMPORT -> import [6:0] +|--DOT -> . [6:27] +| |--DOT -> . [6:16] +| | |--DOT -> . [6:11] +| | | |--IDENT -> java [6:7] +| | | `--IDENT -> lang [6:12] +| | `--IDENT -> annotation [6:17] +| `--IDENT -> RetentionPolicy [6:28] +`--SEMI -> ; [6:43] +IMPORT -> import [7:0] +|--DOT -> . [7:27] +| |--DOT -> . [7:16] +| | |--DOT -> . [7:11] +| | | |--IDENT -> java [7:7] +| | | `--IDENT -> lang [7:12] +| | `--IDENT -> annotation [7:17] +| `--IDENT -> Target [7:28] +`--SEMI -> ; [7:34] +IMPORT -> import [8:0] +|--DOT -> . [8:16] +| |--DOT -> . [8:11] +| | |--IDENT -> java [8:7] +| | `--IDENT -> util [8:12] +| `--IDENT -> ArrayList [8:17] +`--SEMI -> ; [8:26] +IMPORT -> import [9:0] +|--DOT -> . [9:16] +| |--DOT -> . [9:11] +| | |--IDENT -> java [9:7] +| | `--IDENT -> util [9:12] +| `--IDENT -> Collections [9:17] +`--SEMI -> ; [9:28] +IMPORT -> import [10:0] +|--DOT -> . [10:16] +| |--DOT -> . [10:11] +| | |--IDENT -> java [10:7] +| | `--IDENT -> util [10:12] +| `--IDENT -> Comparator [10:17] +`--SEMI -> ; [10:27] +IMPORT -> import [11:0] +|--DOT -> . [11:16] +| |--DOT -> . [11:11] +| | |--IDENT -> java [11:7] +| | `--IDENT -> util [11:12] +| `--IDENT -> Map [11:17] +`--SEMI -> ; [11:20] +IMPORT -> import [12:0] +|--DOT -> . [12:16] +| |--DOT -> . [12:11] +| | |--IDENT -> java [12:7] +| | `--IDENT -> util [12:12] +| `--IDENT -> List [12:17] +`--SEMI -> ; [12:21] +IMPORT -> import [13:0] +|--DOT -> . [13:25] +| |--DOT -> . [13:16] +| | |--DOT -> . [13:11] +| | | |--IDENT -> java [13:7] +| | | `--IDENT -> util [13:12] +| | `--IDENT -> function [13:17] +| `--IDENT -> IntBinaryOperator [13:26] +`--SEMI -> ; [13:43] +IMPORT -> import [14:0] +|--DOT -> . [14:25] +| |--DOT -> . [14:16] +| | |--DOT -> . [14:11] +| | | |--IDENT -> java [14:7] +| | | `--IDENT -> util [14:12] +| | `--IDENT -> function [14:17] +| `--IDENT -> Predicate [14:26] +`--SEMI -> ; [14:35] +IMPORT -> import [15:0] +|--DOT -> . [15:25] +| |--DOT -> . [15:16] +| | |--DOT -> . [15:11] +| | | |--IDENT -> java [15:7] +| | | `--IDENT -> util [15:12] +| | `--IDENT -> function [15:17] +| `--IDENT -> Supplier [15:26] +`--SEMI -> ; [15:34] +CLASS_DEF -> CLASS_DEF [17:0] +|--MODIFIERS -> MODIFIERS [17:0] +| `--LITERAL_PUBLIC -> public [17:0] +|--LITERAL_CLASS -> class [17:7] +|--IDENT -> InputRegressionJava8Class2 [17:13] +`--OBJBLOCK -> OBJBLOCK [17:40] + |--LCURLY -> { [17:40] + |--CLASS_DEF -> CLASS_DEF [18:4] + | |--MODIFIERS -> MODIFIERS [18:4] + | | `--LITERAL_STATIC -> static [18:4] + | |--LITERAL_CLASS -> class [18:11] + | |--IDENT -> Inner1 [18:17] + | `--OBJBLOCK -> OBJBLOCK [18:24] + | |--LCURLY -> { [18:24] + | |--CLASS_DEF -> CLASS_DEF [18:26] + | | |--MODIFIERS -> MODIFIERS [18:26] + | | | `--LITERAL_STATIC -> static [18:26] + | | |--LITERAL_CLASS -> class [18:33] + | | |--IDENT -> Inner2 [18:39] + | | |--TYPE_PARAMETERS -> TYPE_PARAMETERS [18:45] + | | | |--GENERIC_START -> < [18:45] + | | | |--TYPE_PARAMETER -> TYPE_PARAMETER [18:46] + | | | | `--IDENT -> V [18:46] + | | | `--GENERIC_END -> > [18:47] + | | `--OBJBLOCK -> OBJBLOCK [18:49] + | | |--LCURLY -> { [18:49] + | | |--METHOD_DEF -> METHOD_DEF [18:51] + | | | |--MODIFIERS -> MODIFIERS [18:51] + | | | | `--LITERAL_PUBLIC -> public [18:51] + | | | |--TYPE -> TYPE [18:58] + | | | | `--LITERAL_VOID -> void [18:58] + | | | |--IDENT -> m [18:63] + | | | |--LPAREN -> ( [18:64] + | | | |--PARAMETERS -> PARAMETERS [18:65] + | | | |--RPAREN -> ) [18:65] + | | | `--SLIST -> { [18:67] + | | | `--RCURLY -> } [18:68] + | | `--RCURLY -> } [18:70] + | `--RCURLY -> } [18:72] + |--CLASS_DEF -> CLASS_DEF [19:4] + | |--MODIFIERS -> MODIFIERS [19:4] + | | `--LITERAL_STATIC -> static [19:4] + | |--LITERAL_CLASS -> class [19:11] + | |--IDENT -> Inner3 [19:17] + | |--TYPE_PARAMETERS -> TYPE_PARAMETERS [19:23] + | | |--GENERIC_START -> < [19:23] + | | |--TYPE_PARAMETER -> TYPE_PARAMETER [19:24] + | | | `--IDENT -> T [19:24] + | | `--GENERIC_END -> > [19:25] + | `--OBJBLOCK -> OBJBLOCK [19:27] + | |--LCURLY -> { [19:27] + | |--METHOD_DEF -> METHOD_DEF [19:29] + | | |--MODIFIERS -> MODIFIERS [19:29] + | | | `--LITERAL_PUBLIC -> public [19:29] + | | |--TYPE -> TYPE [19:36] + | | | `--LITERAL_VOID -> void [19:36] + | | |--IDENT -> m [19:41] + | | |--LPAREN -> ( [19:42] + | | |--PARAMETERS -> PARAMETERS [19:43] + | | |--RPAREN -> ) [19:43] + | | `--SLIST -> { [19:45] + | | `--RCURLY -> } [19:46] + | `--RCURLY -> } [19:48] + |--METHOD_DEF -> METHOD_DEF [21:4] + | |--MODIFIERS -> MODIFIERS [21:4] + | | `--LITERAL_PUBLIC -> public [21:4] + | |--TYPE -> TYPE [21:11] + | | `--LITERAL_VOID -> void [21:11] + | |--IDENT -> m1 [21:16] + | |--LPAREN -> ( [21:18] + | |--PARAMETERS -> PARAMETERS [21:19] + | | `--PARAMETER_DEF -> PARAMETER_DEF [21:19] + | | |--MODIFIERS -> MODIFIERS [21:19] + | | | `--ANNOTATION -> ANNOTATION [21:19] + | | | |--AT -> @ [21:19] + | | | `--IDENT -> MyAnnotation [21:20] + | | |--TYPE -> TYPE [21:33] + | | | |--IDENT -> String [21:33] + | | | `--ANNOTATIONS -> ANNOTATIONS [21:40] + | | | `--ANNOTATION -> ANNOTATION [21:40] + | | | |--AT -> @ [21:40] + | | | `--IDENT -> MyAnnotation [21:41] + | | |--ELLIPSIS -> ... [21:54] + | | `--IDENT -> vararg [21:58] + | |--RPAREN -> ) [21:64] + | `--SLIST -> { [21:66] + | `--RCURLY -> } [21:67] + |--METHOD_DEF -> METHOD_DEF [22:4] + | |--MODIFIERS -> MODIFIERS [22:4] + | | `--LITERAL_PUBLIC -> public [22:4] + | |--TYPE -> TYPE [22:54] + | | `--ARRAY_DECLARATOR -> [ [22:54] + | | |--ARRAY_DECLARATOR -> [ [22:37] + | | | |--IDENT -> String [22:11] + | | | |--ANNOTATIONS -> ANNOTATIONS [22:23] + | | | | `--ANNOTATION -> ANNOTATION [22:23] + | | | | |--AT -> @ [22:23] + | | | | `--IDENT -> MyAnnotation [22:24] + | | | `--RBRACK -> ] [22:38] + | | |--ANNOTATIONS -> ANNOTATIONS [22:40] + | | | `--ANNOTATION -> ANNOTATION [22:40] + | | | |--AT -> @ [22:40] + | | | `--IDENT -> MyAnnotation [22:41] + | | `--RBRACK -> ] [22:55] + | |--IDENT -> m2 [22:18] + | |--LPAREN -> ( [22:20] + | |--PARAMETERS -> PARAMETERS [22:21] + | |--RPAREN -> ) [22:21] + | `--SLIST -> { [22:57] + | |--LITERAL_RETURN -> return [22:59] + | | |--EXPR -> EXPR [22:66] + | | | `--LITERAL_NULL -> null [22:66] + | | `--SEMI -> ; [22:70] + | `--RCURLY -> } [22:72] + |--METHOD_DEF -> METHOD_DEF [24:4] + | |--MODIFIERS -> MODIFIERS [24:4] + | | `--LITERAL_PUBLIC -> public [24:4] + | |--TYPE -> TYPE [24:11] + | | `--LITERAL_VOID -> void [24:11] + | |--IDENT -> instructions [24:16] + | |--LPAREN -> ( [24:28] + | |--PARAMETERS -> PARAMETERS [24:29] + | |--RPAREN -> ) [24:29] + | `--SLIST -> { [24:31] + | |--VARIABLE_DEF -> VARIABLE_DEF [26:11] + | | |--MODIFIERS -> MODIFIERS [26:11] + | | |--TYPE -> TYPE [26:11] + | | | `--DOT -> . [26:11] + | | | |--IDENT -> Map [26:8] + | | | |--ANNOTATIONS -> ANNOTATIONS [26:12] + | | | | `--ANNOTATION -> ANNOTATION [26:12] + | | | | |--AT -> @ [26:12] + | | | | `--IDENT -> MyAnnotation [26:13] + | | | `--IDENT -> Entry [26:26] + | | `--IDENT -> e [26:32] + | |--SEMI -> ; [26:33] + | |--VARIABLE_DEF -> VARIABLE_DEF [27:8] + | | |--MODIFIERS -> MODIFIERS [27:8] + | | |--TYPE -> TYPE [27:8] + | | | `--IDENT -> String [27:8] + | | |--IDENT -> str [27:15] + | | `--ASSIGN -> = [27:19] + | | `--EXPR -> EXPR [27:21] + | | `--TYPECAST -> ( [27:21] + | | |--TYPE -> TYPE [27:22] + | | | |--ANNOTATIONS -> ANNOTATIONS [27:22] + | | | | `--ANNOTATION -> ANNOTATION [27:22] + | | | | |--AT -> @ [27:22] + | | | | `--IDENT -> MyAnnotation [27:23] + | | | `--IDENT -> String [27:36] + | | |--RPAREN -> ) [27:42] + | | `--STRING_LITERAL -> "" [27:44] + | |--SEMI -> ; [27:46] + | |--EXPR -> EXPR [28:46] + | | `--METHOD_CALL -> ( [28:46] + | | |--DOT -> . [28:22] + | | | |--LPAREN -> ( [28:8] + | | | |--LITERAL_NEW -> new [28:9] + | | | | |--IDENT -> Inner3 [28:13] + | | | | |--LPAREN -> ( [28:19] + | | | | |--ELIST -> ELIST [28:20] + | | | | `--RPAREN -> ) [28:20] + | | | |--RPAREN -> ) [28:21] + | | | |--TYPE_ARGUMENTS -> TYPE_ARGUMENTS [28:23] + | | | | |--GENERIC_START -> < [28:23] + | | | | |--TYPE_ARGUMENT -> TYPE_ARGUMENT [28:24] + | | | | | |--ANNOTATIONS -> ANNOTATIONS [28:24] + | | | | | | `--ANNOTATION -> ANNOTATION [28:24] + | | | | | | |--AT -> @ [28:24] + | | | | | | `--IDENT -> MyAnnotation [28:25] + | | | | | `--IDENT -> String [28:38] + | | | | `--GENERIC_END -> > [28:44] + | | | `--IDENT -> m [28:45] + | | |--ELIST -> ELIST [28:47] + | | `--RPAREN -> ) [28:47] + | |--SEMI -> ; [28:48] + | |--VARIABLE_DEF -> VARIABLE_DEF [29:8] + | | |--MODIFIERS -> MODIFIERS [29:8] + | | |--TYPE -> TYPE [29:8] + | | | `--IDENT -> Object [29:8] + | | |--IDENT -> arr [29:15] + | | `--ASSIGN -> = [29:19] + | | `--EXPR -> EXPR [29:21] + | | `--LITERAL_NEW -> new [29:21] + | | |--ANNOTATIONS -> ANNOTATIONS [29:25] + | | | `--ANNOTATION -> ANNOTATION [29:25] + | | | |--AT -> @ [29:25] + | | | `--IDENT -> MyAnnotation [29:26] + | | |--IDENT -> String [29:39] + | | `--ARRAY_DECLARATOR -> [ [29:60] + | | |--ANNOTATIONS -> ANNOTATIONS [29:46] + | | | `--ANNOTATION -> ANNOTATION [29:46] + | | | |--AT -> @ [29:46] + | | | `--IDENT -> MyAnnotation [29:47] + | | |--EXPR -> EXPR [29:61] + | | | `--NUM_INT -> 3 [29:61] + | | `--RBRACK -> ] [29:62] + | |--SEMI -> ; [29:63] + | |--LITERAL_FOR -> for [30:8] + | | |--LPAREN -> ( [30:12] + | | |--FOR_EACH_CLAUSE -> FOR_EACH_CLAUSE [30:36] + | | | |--VARIABLE_DEF -> VARIABLE_DEF [30:36] + | | | | |--MODIFIERS -> MODIFIERS [30:36] + | | | | |--TYPE -> TYPE [30:36] + | | | | | `--ARRAY_DECLARATOR -> [ [30:36] + | | | | | |--IDENT -> String [30:13] + | | | | | |--ANNOTATIONS -> ANNOTATIONS [30:22] + | | | | | | `--ANNOTATION -> ANNOTATION [30:22] + | | | | | | |--AT -> @ [30:22] + | | | | | | `--IDENT -> MyAnnotation [30:23] + | | | | | `--RBRACK -> ] [30:37] + | | | | `--IDENT -> a [30:20] + | | | |--COLON -> : [30:39] + | | | `--EXPR -> EXPR [30:43] + | | | `--METHOD_CALL -> ( [30:43] + | | | |--IDENT -> m2 [30:41] + | | | |--ELIST -> ELIST [30:44] + | | | `--RPAREN -> ) [30:44] + | | |--RPAREN -> ) [30:45] + | | `--SLIST -> { [30:47] + | | `--RCURLY -> } [30:48] + | |--VARIABLE_DEF -> VARIABLE_DEF [31:8] + | | |--MODIFIERS -> MODIFIERS [31:8] + | | |--TYPE -> TYPE [31:8] + | | | `--IDENT -> Object [31:8] + | | |--IDENT -> arr2 [31:15] + | | `--ASSIGN -> = [31:20] + | | `--EXPR -> EXPR [31:22] + | | `--LITERAL_NEW -> new [31:22] + | | |--ANNOTATIONS -> ANNOTATIONS [31:26] + | | | `--ANNOTATION -> ANNOTATION [31:26] + | | | |--AT -> @ [31:26] + | | | `--IDENT -> MyAnnotation [31:27] + | | |--LITERAL_INT -> int [31:40] + | | `--ARRAY_DECLARATOR -> [ [31:43] + | | |--EXPR -> EXPR [31:44] + | | | `--NUM_INT -> 3 [31:44] + | | `--RBRACK -> ] [31:45] + | |--SEMI -> ; [31:46] + | `--RCURLY -> } [32:4] + `--RCURLY -> } [33:0] +ANNOTATION_DEF -> ANNOTATION_DEF [35:0] +|--MODIFIERS -> MODIFIERS [35:0] +| |--ANNOTATION -> ANNOTATION [35:0] +| | |--AT -> @ [35:0] +| | |--IDENT -> Retention [35:1] +| | |--LPAREN -> ( [35:10] +| | |--EXPR -> EXPR [35:26] +| | | `--DOT -> . [35:26] +| | | |--IDENT -> RetentionPolicy [35:11] +| | | `--IDENT -> CLASS [35:27] +| | `--RPAREN -> ) [35:32] +| `--ANNOTATION -> ANNOTATION [36:0] +| |--AT -> @ [36:0] +| |--IDENT -> Target [36:1] +| |--LPAREN -> ( [36:7] +| |--ANNOTATION_ARRAY_INIT -> { [36:8] +| | |--EXPR -> EXPR [36:21] +| | | `--DOT -> . [36:21] +| | | |--IDENT -> ElementType [36:10] +| | | `--IDENT -> TYPE_USE [36:22] +| | `--RCURLY -> } [36:31] +| `--RPAREN -> ) [36:32] +|--AT -> @ [37:0] +|--LITERAL_INTERFACE -> interface [37:1] +|--IDENT -> MyAnnotation [37:11] +`--OBJBLOCK -> OBJBLOCK [37:24] + |--LCURLY -> { [37:24] + `--RCURLY -> } [38:0] diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/java8/InputAnnotations12.java b/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/java8/InputAnnotations12.java new file mode 100644 index 00000000000..fe4e8395611 --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/java8/InputAnnotations12.java @@ -0,0 +1,16 @@ +package com.puppycrawl.tools.checkstyle.grammar.java8; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + + +public class InputAnnotations12 { + public void m1(@MyAnnotation1 String @MyAnnotation1 ... vararg) {} + public void m2(@MyAnnotation1 int @MyAnnotation1 ... vararg) {} + public void m3(@MyAnnotation1 String @MyAnnotation1 [] @MyAnnotation1 [] ... vararg) {} + public void m4(@MyAnnotation1 int[] @MyAnnotation1 ... vararg) {} + public void m5(@MyAnnotation1 String[][] @MyAnnotation1 [] @MyAnnotation1 [] ... vararg) {} + + @Target(ElementType.TYPE_USE) + @interface MyAnnotation1 {} +} diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/java8/InputAnnotationsOnArray.java b/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/java8/InputAnnotationsOnArray.java index 49c2590a377..ff6e8bad4f8 100644 --- a/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/java8/InputAnnotationsOnArray.java +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/grammar/java8/InputAnnotationsOnArray.java @@ -9,6 +9,9 @@ public final class InputAnnotationsOnArray { + private String array1 @Nullable []; + private @Nullable int array2 @Nullable [] @Nullable []; + private InputAnnotationsOnArray() { } @@ -27,6 +30,27 @@ public static T[][] checkNotNullContents2(T @Nullable [] @Nullable [] array) return array; } + + public static T @Nullable [] checkNotNullContents3(T array @Nullable []) { + if (array == null) { + throw new NullPointerException(); + } + + return array; + } + + public T checkNotNullContents4(T @Nullable [] array) @Nullable [] { + if (array == null) { + throw new NullPointerException(); + } + String tmp1 @Nullable []; + @Nullable Object[] tmp2 = new @Nullable Integer[3]; + @Nullable int[] tmp3 = new @Nullable int[3]; + @Nullable Object tmp4 = new @Nullable String @Nullable [3] @Nullable [2]; + @Nullable Object tmp5 = new @Nullable int @Nullable [3] @Nullable [2]; + + return array; + } } @Retention(RetentionPolicy.CLASS)