diff --git a/config/suppressions-xpath.xml b/config/suppressions-xpath.xml index dcf048d38fec..01a72f9ac3e2 100644 --- a/config/suppressions-xpath.xml +++ b/config/suppressions-xpath.xml @@ -7,16 +7,16 @@ + query="/CLASS_DEF[./IDENT[@text='XdocsPagesTest']] + //METHOD_DEF[./IDENT[@text='validateCheckSection' + or @text='getModulePropertyExpectedValue']]"/> + query="/CLASS_DEF[./IDENT[@text='XdocsPagesTest']]//METHOD_DEF"/> + query="/CLASS_DEF[./IDENT[@text='JavadocMethodCheck' + or @text='JavadocStyleCheck' or @text='CustomImportOrderCheck']]//METHOD_DEF"/> diff --git a/pom.xml b/pom.xml index 75622fcc835e..eb8c96b5d6a8 100644 --- a/pom.xml +++ b/pom.xml @@ -3086,6 +3086,7 @@ ${pitest.plugin.version} + REMOVE_CONDITIONALS CONDITIONALS_BOUNDARY CONSTRUCTOR_CALLS FALSE_RETURNS diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionClassMemberImpliedModifierTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionClassMemberImpliedModifierTest.java index 5991bf549348..1e772f66b1ee 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionClassMemberImpliedModifierTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionClassMemberImpliedModifierTest.java @@ -51,12 +51,15 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionClassMemberImpliedModifierOne']" - + "/OBJBLOCK/INTERFACE_DEF[@text='Foo']", - "/CLASS_DEF[@text='SuppressionXpathRegressionClassMemberImpliedModifierOne']" - + "/OBJBLOCK/INTERFACE_DEF[@text='Foo']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionClassMemberImpliedModifierOne']" - + "/OBJBLOCK/INTERFACE_DEF[@text='Foo']/MODIFIERS/LITERAL_PUBLIC" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionClassMemberImpliedModifierOne']]" + + "/OBJBLOCK/INTERFACE_DEF[./IDENT[@text='Foo']]", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionClassMemberImpliedModifierOne']]" + + "/OBJBLOCK/INTERFACE_DEF[./IDENT[@text='Foo']]/MODIFIERS", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionClassMemberImpliedModifierOne']]" + + "/OBJBLOCK/INTERFACE_DEF[./IDENT[@text='Foo']]/MODIFIERS/LITERAL_PUBLIC" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -77,12 +80,12 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionClassMemberImpliedModifierTwo']" - + "/OBJBLOCK/ENUM_DEF[@text='Count']", - "/CLASS_DEF[@text='SuppressionXpathRegressionClassMemberImpliedModifierTwo']" - + "/OBJBLOCK/ENUM_DEF[@text='Count']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionClassMemberImpliedModifierTwo']" - + "/OBJBLOCK/ENUM_DEF[@text='Count']/MODIFIERS/LITERAL_PUBLIC" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionClassMemberImpliedModifierTwo']]" + + "/OBJBLOCK/ENUM_DEF[./IDENT[@text='Count']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionClassMemberImpliedModifierTwo']]" + + "/OBJBLOCK/ENUM_DEF[./IDENT[@text='Count']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionClassMemberImpliedModifierTwo']]" + + "/OBJBLOCK/ENUM_DEF[./IDENT[@text='Count']]/MODIFIERS/LITERAL_PUBLIC" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionCyclomaticComplexityTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionCyclomaticComplexityTest.java index ecae0131f70e..d7ef0e40e431 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionCyclomaticComplexityTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionCyclomaticComplexityTest.java @@ -53,12 +53,12 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionCyclomaticOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']", - "/CLASS_DEF[@text='SuppressionXpathRegressionCyclomaticOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionCyclomaticOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/MODIFIERS/LITERAL_PUBLIC" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionCyclomaticOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionCyclomaticOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionCyclomaticOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/MODIFIERS/LITERAL_PUBLIC" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -80,12 +80,12 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionCyclomaticTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='foo2']", - "/CLASS_DEF[@text='SuppressionXpathRegressionCyclomaticTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='foo2']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionCyclomaticTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='foo2']/MODIFIERS/LITERAL_PUBLIC" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionCyclomaticTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='foo2']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionCyclomaticTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='foo2']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionCyclomaticTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='foo2']]/MODIFIERS/LITERAL_PUBLIC" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionDeclarationOrderTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionDeclarationOrderTest.java index df57d661fdcf..e4aa6ec31a02 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionDeclarationOrderTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionDeclarationOrderTest.java @@ -51,12 +51,12 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionDeclarationOne']" - + "/OBJBLOCK/VARIABLE_DEF[@text='name']", - "/CLASS_DEF[@text='SuppressionXpathRegressionDeclarationOne']" - + "/OBJBLOCK/VARIABLE_DEF[@text='name']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionDeclarationOne']" - + "/OBJBLOCK/VARIABLE_DEF[@text='name']/MODIFIERS/LITERAL_PUBLIC" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDeclarationOne']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='name']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDeclarationOne']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='name']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDeclarationOne']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='name']]/MODIFIERS/LITERAL_PUBLIC" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -77,12 +77,12 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionDeclarationTwo']" - + "/OBJBLOCK/VARIABLE_DEF[@text='MAX']", - "/CLASS_DEF[@text='SuppressionXpathRegressionDeclarationTwo']" - + "/OBJBLOCK/VARIABLE_DEF[@text='MAX']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionDeclarationTwo']" - + "/OBJBLOCK/VARIABLE_DEF[@text='MAX']/MODIFIERS/LITERAL_PUBLIC" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDeclarationTwo']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='MAX']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDeclarationTwo']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='MAX']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDeclarationTwo']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='MAX']]/MODIFIERS/LITERAL_PUBLIC" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionDefaultComesLastTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionDefaultComesLastTest.java index 94a4baadcb2a..943df2e85dd9 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionDefaultComesLastTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionDefaultComesLastTest.java @@ -52,10 +52,10 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionDefaultComesLastOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_SWITCH/CASE_GROUP", - "/CLASS_DEF[@text='SuppressionXpathRegressionDefaultComesLastOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_SWITCH/CASE_GROUP" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDefaultComesLastOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_SWITCH/CASE_GROUP[1]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDefaultComesLastOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_SWITCH/CASE_GROUP" + "/LITERAL_DEFAULT" ); @@ -78,8 +78,9 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionDefaultComesLastTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_SWITCH/CASE_GROUP/LITERAL_DEFAULT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionDefaultComesLastTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_SWITCH/CASE_GROUP" + + "/LITERAL_DEFAULT" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionEmptyForInitializerPadTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionEmptyForInitializerPadTest.java index 9f934259fbbb..4456f302a07a 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionEmptyForInitializerPadTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionEmptyForInitializerPadTest.java @@ -52,10 +52,10 @@ public void testPreceded() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionEmptyForInitializerPadPreceded']" - + "/OBJBLOCK/METHOD_DEF[@text='method']/SLIST/LITERAL_FOR/FOR_INIT", - "/CLASS_DEF[@text='SuppressionXpathRegressionEmptyForInitializerPadPreceded']" - + "/OBJBLOCK/METHOD_DEF[@text='method']/SLIST/LITERAL_FOR/SEMI" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionEmptyForInitializerPadPreceded']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_FOR/FOR_INIT", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionEmptyForInitializerPadPreceded']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_FOR/SEMI[1]" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -77,10 +77,12 @@ public void testNotPreceded() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionEmptyForInitializerPadNotPreceded']" - + "/OBJBLOCK/METHOD_DEF[@text='method']/SLIST/LITERAL_FOR/FOR_INIT", - "/CLASS_DEF[@text='SuppressionXpathRegressionEmptyForInitializerPadNotPreceded']" - + "/OBJBLOCK/METHOD_DEF[@text='method']/SLIST/LITERAL_FOR/SEMI" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionEmptyForInitializerPadNotPreceded']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_FOR/FOR_INIT", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionEmptyForInitializerPadNotPreceded']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_FOR/SEMI[1]" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionEmptyForIteratorPadTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionEmptyForIteratorPadTest.java index 4469095f5840..77e90d2f4f7a 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionEmptyForIteratorPadTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionEmptyForIteratorPadTest.java @@ -52,10 +52,12 @@ public void testFollowed() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionEmptyForIteratorPadFollowed']/OBJBLOCK" - + "/METHOD_DEF[@text='method']/SLIST/LITERAL_FOR/FOR_ITERATOR", - "/CLASS_DEF[@text='SuppressionXpathRegressionEmptyForIteratorPadFollowed']/OBJBLOCK" - + "/METHOD_DEF[@text='method']/SLIST/LITERAL_FOR/RPAREN" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionEmptyForIteratorPadFollowed']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_FOR/FOR_ITERATOR", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionEmptyForIteratorPadFollowed']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_FOR/RPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -77,10 +79,12 @@ public void testNotFollowed() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionEmptyForIteratorPadNotFollowed']/OBJBLOCK" - + "/METHOD_DEF[@text='method']/SLIST/LITERAL_FOR/FOR_ITERATOR", - "/CLASS_DEF[@text='SuppressionXpathRegressionEmptyForIteratorPadNotFollowed']/OBJBLOCK" - + "/METHOD_DEF[@text='method']/SLIST/LITERAL_FOR/RPAREN" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionEmptyForIteratorPadNotFollowed']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_FOR/FOR_ITERATOR", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionEmptyForIteratorPadNotFollowed']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_FOR/RPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionExplicitInitializationTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionExplicitInitializationTest.java index bb2f4c23ffd6..139aec9c9da6 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionExplicitInitializationTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionExplicitInitializationTest.java @@ -51,8 +51,8 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionExplicitOne']" - + "/OBJBLOCK/VARIABLE_DEF[@text='a']/IDENT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionExplicitOne']]" + + "/OBJBLOCK/VARIABLE_DEF/IDENT[@text='a']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -73,8 +73,8 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionExplicitTwo']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bar']/IDENT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionExplicitTwo']]/OBJBLOCK" + + "/VARIABLE_DEF/IDENT[@text='bar']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionFallThroughTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionFallThroughTest.java index 06ec99557ca7..3763e80d3600 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionFallThroughTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionFallThroughTest.java @@ -51,10 +51,10 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionExplicitOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_SWITCH/CASE_GROUP", - "/CLASS_DEF[@text='SuppressionXpathRegressionExplicitOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_SWITCH/CASE_GROUP/LITERAL_CASE" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionExplicitOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_SWITCH/CASE_GROUP[3]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionExplicitOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_SWITCH/CASE_GROUP/LITERAL_CASE" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -76,11 +76,13 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionExplicitTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='methodFallThruCustomWords']/SLIST/LITERAL_WHILE/SLIST" - + "/LITERAL_SWITCH/CASE_GROUP", - "/CLASS_DEF[@text='SuppressionXpathRegressionExplicitTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='methodFallThruCustomWords']/SLIST/LITERAL_WHILE/SLIST" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionExplicitTwo']]/OBJBLOCK" + + "/METHOD_DEF[" + + "./IDENT[@text='methodFallThruCustomWords']]/SLIST/LITERAL_WHILE/SLIST" + + "/LITERAL_SWITCH/CASE_GROUP[2]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionExplicitTwo']]/OBJBLOCK" + + "/METHOD_DEF[" + + "./IDENT[@text='methodFallThruCustomWords']]/SLIST/LITERAL_WHILE/SLIST" + "/LITERAL_SWITCH/CASE_GROUP/LITERAL_DEFAULT" ); diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionGenericWhitespaceTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionGenericWhitespaceTest.java index 5bf3d56c0cf0..6588138aa66d 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionGenericWhitespaceTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionGenericWhitespaceTest.java @@ -51,9 +51,9 @@ public void testProcessEnd() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessEnd']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/PARAMETERS/PARAMETER_DEF[@text='cls']" - + "/TYPE[@text='Class']/TYPE_ARGUMENTS/GENERIC_END" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessEnd']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/PARAMETERS/PARAMETER_DEF[./IDENT[@text='cls']]" + + "/TYPE[./IDENT[@text='Class']]/TYPE_ARGUMENTS/GENERIC_END" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -74,9 +74,11 @@ public void testProcessNestedGenericsOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessNestedGenericsOne']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/TYPE_PARAMETERS/TYPE_PARAMETER[@text='E']" - + "/TYPE_UPPER_BOUNDS[@text='Enum']/TYPE_ARGUMENTS/GENERIC_END" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionProcessNestedGenericsOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/TYPE_PARAMETERS" + + "/TYPE_PARAMETER[./IDENT[@text='E']]" + + "/TYPE_UPPER_BOUNDS[./IDENT[@text='Enum']]/TYPE_ARGUMENTS/GENERIC_END" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -97,9 +99,11 @@ public void testProcessNestedGenericsTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessNestedGenericsTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/TYPE_PARAMETERS/TYPE_PARAMETER[@text='E']" - + "/TYPE_UPPER_BOUNDS[@text='Enum']/TYPE_ARGUMENTS/GENERIC_END" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionProcessNestedGenericsTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/TYPE_PARAMETERS" + + "/TYPE_PARAMETER[./IDENT[@text='E']]" + + "/TYPE_UPPER_BOUNDS[./IDENT[@text='Enum']]/TYPE_ARGUMENTS/GENERIC_END" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -120,9 +124,11 @@ public void testProcessNestedGenericsThree() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessNestedGenericsThree']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/TYPE_PARAMETERS/TYPE_PARAMETER[@text='E']" - + "/TYPE_UPPER_BOUNDS[@text='Enum']/TYPE_ARGUMENTS/GENERIC_END" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionProcessNestedGenericsThree']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/TYPE_PARAMETERS" + + "/TYPE_PARAMETER[./IDENT[@text='E']]" + + "/TYPE_UPPER_BOUNDS[./IDENT[@text='Enum']]/TYPE_ARGUMENTS/GENERIC_END" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -143,8 +149,10 @@ public void testProcessSingleGenericOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessSingleGenericOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR/METHOD_CALL/DOT[@text='Collections']" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionProcessSingleGenericOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR/METHOD_CALL" + + "/DOT[./IDENT[@text='Collections']]" + "/TYPE_ARGUMENTS/GENERIC_END" ); @@ -166,8 +174,9 @@ public void testProcessSingleGenericTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessSingleGenericTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/TYPE_PARAMETERS/GENERIC_END" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionProcessSingleGenericTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/TYPE_PARAMETERS/GENERIC_END" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -188,10 +197,10 @@ public void testProcessStartOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessStartOne']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/TYPE_PARAMETERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessStartOne']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/TYPE_PARAMETERS/GENERIC_START" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessStartOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/TYPE_PARAMETERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessStartOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/TYPE_PARAMETERS/GENERIC_START" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -212,12 +221,14 @@ public void testProcessStartTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessStartTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/PARAMETERS/PARAMETER_DEF[@text='consumer']" - + "/TYPE[@text='Consumer']/TYPE_ARGUMENTS", - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessStartTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']/PARAMETERS/PARAMETER_DEF[@text='consumer']" - + "/TYPE[@text='Consumer']/TYPE_ARGUMENTS/GENERIC_START" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessStartTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/PARAMETERS" + + "/PARAMETER_DEF[./IDENT[@text='consumer']]" + + "/TYPE[./IDENT[@text='Consumer']]/TYPE_ARGUMENTS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessStartTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='bad']]/PARAMETERS" + + "/PARAMETER_DEF[./IDENT[@text='consumer']]" + + "/TYPE[./IDENT[@text='Consumer']]/TYPE_ARGUMENTS/GENERIC_START" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -238,14 +249,14 @@ public void testProcessStartThree() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessStartThree']/OBJBLOCK" - + "/METHOD_DEF[@text='bad']", - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessStartThree']/OBJBLOCK/" - + "METHOD_DEF[@text='bad']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessStartThree']/OBJBLOCK/" - + "METHOD_DEF[@text='bad']/TYPE_PARAMETERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionProcessStartThree']/OBJBLOCK/" - + "METHOD_DEF[@text='bad']/TYPE_PARAMETERS/GENERIC_START" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessStartThree']]/OBJBLOCK/" + + "METHOD_DEF[./IDENT[@text='bad']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessStartThree']]/OBJBLOCK/" + + "METHOD_DEF[./IDENT[@text='bad']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessStartThree']]/OBJBLOCK/" + + "METHOD_DEF[./IDENT[@text='bad']]/TYPE_PARAMETERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionProcessStartThree']]/OBJBLOCK/" + + "METHOD_DEF[./IDENT[@text='bad']]/TYPE_PARAMETERS/GENERIC_START" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionHiddenFieldTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionHiddenFieldTest.java index f8e511fb12f7..493a3cbbbc7d 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionHiddenFieldTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionHiddenFieldTest.java @@ -51,9 +51,9 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionExplicitOne']/OBJBLOCK" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionExplicitOne']]/OBJBLOCK" + "/INSTANCE_INIT/SLIST/EXPR/METHOD_CALL/ELIST/LAMBDA/PARAMETERS" - + "/PARAMETER_DEF[@text='value']/IDENT" + + "/PARAMETER_DEF/IDENT[@text='value']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -74,8 +74,9 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionExplicitTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='method']/PARAMETERS/PARAMETER_DEF[@text='other']/IDENT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionExplicitTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='method']]/PARAMETERS/PARAMETER_DEF" + + "/IDENT[@text='other']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionIllegalThrowsTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionIllegalThrowsTest.java index 4919013ecdff..469e0a4378b2 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionIllegalThrowsTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionIllegalThrowsTest.java @@ -51,8 +51,9 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionIllegalThrowsOne']/OBJBLOCK" - + "/METHOD_DEF[@text='sayHello']/LITERAL_THROWS[@text='RuntimeException']/IDENT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionIllegalThrowsOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='sayHello']]/LITERAL_THROWS" + + "/IDENT[@text='RuntimeException']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -73,8 +74,9 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionIllegalThrowsTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='methodTwo']/LITERAL_THROWS/DOT[@text='Error']" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionIllegalThrowsTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='methodTwo']]/LITERAL_THROWS" + + "/DOT[./IDENT[@text='Error']]" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionImportControlTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionImportControlTest.java index bb360071c8f0..0de64157a586 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionImportControlTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionImportControlTest.java @@ -120,7 +120,7 @@ public void testFour() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/IMPORT[./DOT[@text='Scanner']]" + "/IMPORT[2]" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionJavadocVariableTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionJavadocVariableTest.java index 5b1d6e4281bf..9f57f44a8e96 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionJavadocVariableTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionJavadocVariableTest.java @@ -51,12 +51,12 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionJavadocVariableOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='age']", - "/CLASS_DEF[@text='SuppressionXpathRegressionJavadocVariableOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='age']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionJavadocVariableOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='age']/MODIFIERS/LITERAL_PRIVATE" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionJavadocVariableOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='age']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionJavadocVariableOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='age']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionJavadocVariableOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='age']]/MODIFIERS/LITERAL_PRIVATE" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -77,12 +77,15 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionJavadocVariableTwo']/OBJBLOCK" - + "/CLASS_DEF[@text='InnerInner2']/OBJBLOCK/VARIABLE_DEF[@text='fData']", - "/CLASS_DEF[@text='SuppressionXpathRegressionJavadocVariableTwo']/OBJBLOCK" - + "/CLASS_DEF[@text='InnerInner2']/OBJBLOCK/VARIABLE_DEF[@text='fData']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionJavadocVariableTwo']/OBJBLOCK" - + "/CLASS_DEF[@text='InnerInner2']/OBJBLOCK/VARIABLE_DEF[@text='fData']/MODIFIERS" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionJavadocVariableTwo']]/OBJBLOCK" + + "/CLASS_DEF[./IDENT[@text='InnerInner2']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='fData']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionJavadocVariableTwo']]/OBJBLOCK" + + "/CLASS_DEF[./IDENT[@text='InnerInner2']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='fData']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionJavadocVariableTwo']]/OBJBLOCK" + + "/CLASS_DEF[./IDENT[@text='InnerInner2']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='fData']]/MODIFIERS" + "/LITERAL_PUBLIC" ); diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionLeftCurlyTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionLeftCurlyTest.java index 9da6ba5a3c14..ea8260a8ad21 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionLeftCurlyTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionLeftCurlyTest.java @@ -53,8 +53,8 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionLeftCurlyOne']/OBJBLOCK", - "/CLASS_DEF[@text='SuppressionXpathRegressionLeftCurlyOne']/OBJBLOCK/LCURLY" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionLeftCurlyOne']]/OBJBLOCK", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionLeftCurlyOne']]/OBJBLOCK/LCURLY" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -76,8 +76,8 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionLeftCurlyTwo']/OBJBLOCK", - "/CLASS_DEF[@text='SuppressionXpathRegressionLeftCurlyTwo']/OBJBLOCK/LCURLY" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionLeftCurlyTwo']]/OBJBLOCK", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionLeftCurlyTwo']]/OBJBLOCK/LCURLY" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -98,8 +98,8 @@ public void testThree() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionLeftCurlyThree']/OBJBLOCK" - + "/METHOD_DEF[@text='sample']/SLIST/LITERAL_IF/SLIST" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionLeftCurlyThree']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='sample']]/SLIST/LITERAL_IF/SLIST" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionMethodParamPadTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionMethodParamPadTest.java index 6c582a4da898..f44b2a472340 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionMethodParamPadTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionMethodParamPadTest.java @@ -51,8 +51,8 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionMethodParamPadOne']/OBJBLOCK" - + "/METHOD_DEF[@text='InputMethodParamPad']/LPAREN" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionMethodParamPadOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='InputMethodParamPad']]/LPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -73,8 +73,8 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionMethodParamPadTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='sayHello']/LPAREN" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionMethodParamPadTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='sayHello']]/LPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -96,8 +96,8 @@ public void testThree() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionMethodParamPadThree']/OBJBLOCK" - + "/METHOD_DEF[@text='sayHello']/LPAREN" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionMethodParamPadThree']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='sayHello']]/LPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionMultipleVariableDeclarationsTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionMultipleVariableDeclarationsTest.java index abcf943afe93..bbedd8e18eb4 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionMultipleVariableDeclarationsTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionMultipleVariableDeclarationsTest.java @@ -51,22 +51,30 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='i']", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='i']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='i']/TYPE", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='i']/TYPE/LITERAL_INT", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='j']", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='j']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='j']/TYPE", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='j']/TYPE/LITERAL_INT" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='i']]", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='i']]/MODIFIERS", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='i']]/TYPE", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='i']]/TYPE/LITERAL_INT", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='j']]", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='j']]/MODIFIERS", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='j']]/TYPE", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='j']]/TYPE/LITERAL_INT" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -87,14 +95,18 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationTwo']/OBJBLOCK" - + "/VARIABLE_DEF[@text='i1']", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationTwo']/OBJBLOCK" - + "/VARIABLE_DEF[@text='i1']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationTwo']/OBJBLOCK" - + "/VARIABLE_DEF[@text='i1']/TYPE", - "/CLASS_DEF[@text='SuppressionXpathRegressionMultipleVariableDeclarationTwo']/OBJBLOCK" - + "/VARIABLE_DEF[@text='i1']/TYPE/LITERAL_INT" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationTwo']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='i1']]", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationTwo']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='i1']]/MODIFIERS", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationTwo']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='i1']]/TYPE", + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionMultipleVariableDeclarationTwo']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='i1']]/TYPE/LITERAL_INT" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNPathComplexityTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNPathComplexityTest.java index 490589607311..41a839fec79f 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNPathComplexityTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNPathComplexityTest.java @@ -54,12 +54,12 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionNPathComplexityOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']", - "/CLASS_DEF[@text='SuppressionXpathRegressionNPathComplexityOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/MODIFIERS", - "/CLASS_DEF[@text='SuppressionXpathRegressionNPathComplexityOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/MODIFIERS/LITERAL_PUBLIC" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNPathComplexityOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNPathComplexityOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNPathComplexityOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/MODIFIERS/LITERAL_PUBLIC" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -81,7 +81,8 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionNPathComplexityTwo']/OBJBLOCK/STATIC_INIT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNPathComplexityTwo']]" + + "/OBJBLOCK/STATIC_INIT" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedForDepthTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedForDepthTest.java index 69234b26dadb..a6ceca110bd1 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedForDepthTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedForDepthTest.java @@ -51,8 +51,9 @@ public void testCorrect() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionNestedForDepth']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_FOR/SLIST/LITERAL_FOR/SLIST/LITERAL_FOR" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNestedForDepth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_FOR" + + "/SLIST/LITERAL_FOR/SLIST/LITERAL_FOR" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedIfDepthTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedIfDepthTest.java index 88af3face11f..57c729a6ffd3 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedIfDepthTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedIfDepthTest.java @@ -51,8 +51,9 @@ public void testCorrect() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionNestedIfDepth']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_IF/SLIST/LITERAL_IF/SLIST/LITERAL_IF" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNestedIfDepth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_IF" + + "/SLIST/LITERAL_IF/SLIST/LITERAL_IF" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedTryDepthTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedTryDepthTest.java index 2e8c5816a1ca..c50f570d8699 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedTryDepthTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNestedTryDepthTest.java @@ -51,8 +51,9 @@ public void testCorrect() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionNestedTryDepth']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_TRY/SLIST/LITERAL_TRY/SLIST/LITERAL_TRY" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNestedTryDepth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_TRY/SLIST" + + "/LITERAL_TRY/SLIST/LITERAL_TRY" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNoWhitespaceAfterTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNoWhitespaceAfterTest.java index baf537bec741..b28cb30b2679 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNoWhitespaceAfterTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNoWhitespaceAfterTest.java @@ -51,10 +51,11 @@ public void testNoWhitespaceAfter() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionNoWhitespaceAfter']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR", - "/CLASS_DEF[@text='SuppressionXpathRegressionNoWhitespaceAfter']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR/UNARY_MINUS" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNoWhitespaceAfter']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNoWhitespaceAfter']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR/UNARY_MINUS[" + + "./NUM_INT[@text='1']]" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNoWhitespaceBeforeTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNoWhitespaceBeforeTest.java index 56228c64149b..82236fe8f16a 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNoWhitespaceBeforeTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionNoWhitespaceBeforeTest.java @@ -51,8 +51,8 @@ public void testNoWhitespaceBefore() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionNoWhitespaceBefore']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/SEMI" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionNoWhitespaceBefore']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/SEMI" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionOneStatementPerLineTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionOneStatementPerLineTest.java index 491082894d5c..3910f3978bb9 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionOneStatementPerLineTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionOneStatementPerLineTest.java @@ -51,8 +51,8 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionOneStatementPerLineOne']/OBJBLOCK" - + "/VARIABLE_DEF[@text='j']/SEMI" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionOneStatementPerLineOne']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='j']]/SEMI" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -73,8 +73,8 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionOneStatementPerLineTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='foo5']/SLIST/LITERAL_FOR/SLIST/SEMI" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionOneStatementPerLineTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='foo5']]/SLIST/LITERAL_FOR/SLIST/SEMI[2]" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionParenPadTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionParenPadTest.java index d8394cbdd7cf..9d9d1c9e41bf 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionParenPadTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionParenPadTest.java @@ -53,8 +53,8 @@ public void testLeftFollowed() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionParenPadLeftFollowed']" - + "/OBJBLOCK/METHOD_DEF[@text='method']/SLIST/LITERAL_IF/LPAREN" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionParenPadLeftFollowed']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_IF/LPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -76,8 +76,8 @@ public void testLeftNotFollowed() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionParenPadLeftNotFollowed']" - + "/OBJBLOCK/METHOD_DEF[@text='method']/SLIST/LITERAL_IF/LPAREN" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionParenPadLeftNotFollowed']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_IF/LPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -98,8 +98,8 @@ public void testRightPreceded() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionParenPadRightPreceded']" - + "/OBJBLOCK/METHOD_DEF[@text='method']/SLIST/LITERAL_IF/RPAREN" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionParenPadRightPreceded']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_IF/RPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -121,8 +121,8 @@ public void testRightNotPreceded() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionParenPadRightNotPreceded']" - + "/OBJBLOCK/METHOD_DEF[@text='method']/SLIST/LITERAL_IF/RPAREN" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionParenPadRightNotPreceded']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='method']]/SLIST/LITERAL_IF/RPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionRequireThisTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionRequireThisTest.java index 2f5dfe0b3cb3..df606249e49b 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionRequireThisTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionRequireThisTest.java @@ -52,8 +52,9 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionRequireThisOne']/OBJBLOCK" - + "/METHOD_DEF[@text='changeAge']/SLIST/EXPR/ASSIGN[@text='age']/IDENT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionRequireThisOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='changeAge']]/SLIST/EXPR/ASSIGN" + + "/IDENT[@text='age']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -75,8 +76,9 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionRequireThisTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='method2']/SLIST/EXPR/METHOD_CALL[@text='method1']/IDENT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionRequireThisTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='method2']]/SLIST/EXPR" + + "/METHOD_CALL/IDENT[@text='method1']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionRightCurlyTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionRightCurlyTest.java index 45612098fa4e..43a0f83cdb99 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionRightCurlyTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionRightCurlyTest.java @@ -52,8 +52,8 @@ public void testOne() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionRightCurlyOne']/OBJBLOCK" - + "/METHOD_DEF[@text='test']/SLIST/LITERAL_IF/SLIST/RCURLY" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionRightCurlyOne']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='test']]/SLIST/LITERAL_IF/SLIST/RCURLY" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -75,8 +75,8 @@ public void testTwo() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionRightCurlyTwo']/OBJBLOCK" - + "/METHOD_DEF[@text='fooMethod']/SLIST/LITERAL_TRY/SLIST/RCURLY" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionRightCurlyTwo']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='fooMethod']]/SLIST/LITERAL_TRY/SLIST/RCURLY" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -98,8 +98,8 @@ public void testThree() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionRightCurlyThree']/OBJBLOCK" - + "/METHOD_DEF[@text='sample']/SLIST/LITERAL_IF/SLIST/RCURLY" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionRightCurlyThree']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='sample']]/SLIST/LITERAL_IF/SLIST/RCURLY" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -121,8 +121,8 @@ public void testFour() throws Exception { }; final List expectedXpathQueries = Collections.singletonList( - "/CLASS_DEF[@text='SuppressionXpathRegressionRightCurlyFour']/OBJBLOCK" - + "/METHOD_DEF[@text='sample']/SLIST/LITERAL_IF/SLIST/RCURLY" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionRightCurlyFour']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='sample']]/SLIST/LITERAL_IF/SLIST/RCURLY" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionSingleSpaceSeparatorTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionSingleSpaceSeparatorTest.java index d25786d83111..d978d9a8aa75 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionSingleSpaceSeparatorTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionSingleSpaceSeparatorTest.java @@ -51,8 +51,8 @@ public void testSingleSpaceSeparator() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionSingleSpaceSeparator']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/IDENT" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionSingleSpaceSeparator']]/OBJBLOCK" + + "/VARIABLE_DEF/IDENT[@text='bad']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionTypecastParenPadTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionTypecastParenPadTest.java index 39ed89e89700..23b2ec85f0cd 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionTypecastParenPadTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionTypecastParenPadTest.java @@ -53,10 +53,10 @@ public void testLeftFollowed() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionTypecastParenPadLeftFollowed']" - + "/OBJBLOCK/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR", - "/CLASS_DEF[@text='SuppressionXpathRegressionTypecastParenPadLeftFollowed']" - + "/OBJBLOCK/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR/TYPECAST" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionTypecastParenPadLeftFollowed']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionTypecastParenPadLeftFollowed']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR/TYPECAST" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -78,10 +78,10 @@ public void testLeftNotFollowed() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionTypecastParenPadLeftNotFollowed']" - + "/OBJBLOCK/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR", - "/CLASS_DEF[@text='SuppressionXpathRegressionTypecastParenPadLeftNotFollowed']" - + "/OBJBLOCK/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR/TYPECAST" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionTypecastParenPadLeftNotFollowed']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionTypecastParenPadLeftNotFollowed']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR/TYPECAST" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -102,8 +102,8 @@ public void testRightPreceded() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionTypecastParenPadRightPreceded']" - + "/OBJBLOCK/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR/TYPECAST/RPAREN" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionTypecastParenPadRightPreceded']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR/TYPECAST/RPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -125,8 +125,9 @@ public void testRightNotPreceded() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionTypecastParenPadRightNotPreceded']" - + "/OBJBLOCK/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR/TYPECAST/RPAREN" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionTypecastParenPadRightNotPreceded']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR/TYPECAST/RPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionUpperEllTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionUpperEllTest.java index 91a3d1f4f0d4..6a858bfed3cc 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionUpperEllTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionUpperEllTest.java @@ -51,10 +51,11 @@ public void testUpperEll() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionUpperEll']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR", - "/CLASS_DEF[@text='SuppressionXpathRegressionUpperEll']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR/NUM_LONG" + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionUpperEll']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR[./NUM_LONG[@text='0l']]", + "/CLASS_DEF[./IDENT[@text='SuppressionXpathRegressionUpperEll']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR" + + "/NUM_LONG[@text='0l']" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionWhitespaceAfterTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionWhitespaceAfterTest.java index 484ba23a2864..6d9fe70949cd 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionWhitespaceAfterTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionWhitespaceAfterTest.java @@ -51,8 +51,9 @@ public void testWhitespaceAfterTypecast() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionWhitespaceAfterTypecast']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN/EXPR/TYPECAST/RPAREN" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionWhitespaceAfterTypecast']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/EXPR/TYPECAST/RPAREN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -73,8 +74,9 @@ public void testWhitespaceAfterNotFollowed() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionWhitespaceAfterNotFollowed']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN/ARRAY_INIT/COMMA" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionWhitespaceAfterNotFollowed']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN/ARRAY_INIT/COMMA" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionWhitespaceAroundTest.java b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionWhitespaceAroundTest.java index 96b5720e472f..cfae44aed4d9 100644 --- a/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionWhitespaceAroundTest.java +++ b/src/it/java/org/checkstyle/suppressionxpathfilter/XpathRegressionWhitespaceAroundTest.java @@ -51,8 +51,9 @@ public void testWhitespaceAroundNotPreceded() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionWhitespaceAroundNotPreceded']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionWhitespaceAroundNotPreceded']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, @@ -73,8 +74,9 @@ public void testWhitespaceAroundNotFollowed() throws Exception { }; final List expectedXpathQueries = Arrays.asList( - "/CLASS_DEF[@text='SuppressionXpathRegressionWhitespaceAroundNotFollowed']/OBJBLOCK" - + "/VARIABLE_DEF[@text='bad']/ASSIGN" + "/CLASS_DEF[./IDENT[" + + "@text='SuppressionXpathRegressionWhitespaceAroundNotFollowed']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='bad']]/ASSIGN" ); runVerifications(moduleConfig, fileToProcess, expectedViolation, diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/utils/XpathUtil.java b/src/main/java/com/puppycrawl/tools/checkstyle/utils/XpathUtil.java new file mode 100644 index 000000000000..617a4f630bdd --- /dev/null +++ b/src/main/java/com/puppycrawl/tools/checkstyle/utils/XpathUtil.java @@ -0,0 +1,117 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 the original author or authors. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//////////////////////////////////////////////////////////////////////////////// + +package com.puppycrawl.tools.checkstyle.utils; + +import java.util.Arrays; +import java.util.List; + +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; + +/** + * Contains utility methods for xpath. + * + */ +public final class XpathUtil { + + /** + * List of token types which support value attribute. + * These token types were selected based on analysis that all others do not match required + * criteria - value of the token must be useful and help to retrieve more precise results. + * There are three types of AST tokens: + * 1. Tokens for which the values are equal to the name of the token. Or in other words, + * nodes for which the following expression is always true: + *
+     *     detailAst.getText().equals(TokenUtil.getTokenName(detailAst.getType()))
+     * 
+ * For example: + *
+     *     //MODIFIERS[@text='MODIFIERS']
+     *     //OBJBLOCK[@text='OBJBLOCK']
+     * 
+ * These tokens do not match required criteria because their values do not carry any + * information, they do not affect the xpath requests and do not help to get more accurate + * results. The values of these nodes are useless. No matter which class you analyze, these + * values are always the same. + * In addition, they make xpath queries more complex, less readable and less obvious. + * 2. Tokens for which the values differ from token names, but values are always constant. + * For example: + *
+     *     //LITERAL_VOID[@text='void']
+     *     //RCURLY[@text='}']
+     * 
+ * These tokens are not used for the same reasons as were described in the previous part. + * 3. Tokens for which values are not constant. The values of these nodes are closely related + * to a concrete class, method, variable and so on. + * For example: + *
+     *     String greeting = "HelloWorld";
+     *     //STRING_LITERAL[@text='HelloWorld']
+     * 
+ *
+     *     int year = 2017;
+     *     //NUM_INT[@text=2017]
+     * 
+ *
+     *     int age = 23;
+     *     //NUM_INT[@text=23]
+     * 
+ * As you can see same {@code NUM_INT} token type can have different values, depending on + * context. + *
+     *     public class MyClass {}
+     *     //IDENT[@text='MyClass']
+     * 
+ * Only these tokens support value attribute because they make our xpath queries more accurate. + * These token types are listed below. + * */ + private static final List TOKEN_TYPES_WITH_VALUE_ATTRIBUTE = Arrays.asList( + TokenTypes.IDENT, TokenTypes.STRING_LITERAL, TokenTypes.CHAR_LITERAL, + TokenTypes.NUM_LONG, TokenTypes.NUM_INT, TokenTypes.NUM_DOUBLE, TokenTypes.NUM_FLOAT); + + /** Stop instances being created. **/ + private XpathUtil() { + } + + /** + * Checks, if specified node can have {@code @text} attribute. + * + * @param ast {@code DetailAst} element + * @return true if element supports {@code @text} attribute, false otherwise + */ + public static boolean supportsValueAttribute(DetailAST ast) { + return TOKEN_TYPES_WITH_VALUE_ATTRIBUTE.contains(ast.getType()); + } + + /** + * Returns value of the ast element. + * + * @param ast {@code DetailAst} element + * @return value of the ast element + */ + public static String getValue(DetailAST ast) { + String value = ast.getText(); + if (ast.getType() == TokenTypes.STRING_LITERAL) { + value = value.substring(1, value.length() - 1); + } + return value; + } + +} diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/ElementNode.java b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/ElementNode.java index 8ce44682bcb3..169ae5d8b1c3 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/ElementNode.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/ElementNode.java @@ -20,8 +20,8 @@ package com.puppycrawl.tools.checkstyle.xpath; import com.puppycrawl.tools.checkstyle.api.DetailAST; -import com.puppycrawl.tools.checkstyle.api.TokenTypes; import com.puppycrawl.tools.checkstyle.utils.TokenUtil; +import com.puppycrawl.tools.checkstyle.utils.XpathUtil; import net.sf.saxon.om.AxisInfo; import net.sf.saxon.om.NodeInfo; import net.sf.saxon.tree.iter.ArrayIterator; @@ -55,11 +55,8 @@ public class ElementNode extends AbstractNode { /** Represents text of the DetailAST. */ private final String text; - /** The attributes. */ - private AbstractNode[] attributes; - - /** Represents value of TokenTypes#IDENT. */ - private String ident; + /** The text attribute node. */ + private AttributeNode attributeNode; /** * Creates a new {@code ElementNode} instance. @@ -73,9 +70,9 @@ public ElementNode(AbstractNode root, AbstractNode parent, DetailAST detailAst) this.parent = parent; this.root = root; this.detailAst = detailAst; - setIdent(); - createChildren(); text = TokenUtil.getTokenName(detailAst.getType()); + createTextAttribute(); + createChildren(); } /** @@ -100,12 +97,19 @@ private void createChildren() { */ @Override public String getAttributeValue(String namespace, String localPart) { + final String result; if (TEXT_ATTRIBUTE_NAME.equals(localPart)) { - return ident; + if (attributeNode == null) { + result = null; + } + else { + result = attributeNode.getStringValue(); + } } else { - throw throwUnsupportedOperationException(); + result = null; } + return result; } /** @@ -179,13 +183,8 @@ public AxisIterator iterateAxis(byte axisNumber) { } break; case AxisInfo.ATTRIBUTE: - if (attributes == null) { - result = EmptyIterator.OfNodes.THE_INSTANCE; - } - else { - try (AxisIterator iterator = new ArrayIterator.OfNodes(attributes)) { - result = iterator; - } + try (AxisIterator iterator = SingleNodeIterator.makeIterator(attributeNode)) { + result = iterator; } break; case AxisInfo.CHILD: @@ -271,17 +270,16 @@ public DetailAST getUnderlyingNode() { } /** - * Finds child element with {@link TokenTypes#IDENT}, extracts its value and stores it. - * Value can be accessed using {@code @text} attribute. Now {@code @text} attribute is only - * supported attribute. + * Checks if token type supports {@code @text} attribute, + * extracts its value, creates {@code AttributeNode} object and returns it. + * Value can be accessed using {@code @text} attribute. */ - private void setIdent() { - final DetailAST identAst = detailAst.findFirstToken(TokenTypes.IDENT); - if (identAst != null) { - ident = identAst.getText(); - attributes = new AbstractNode[1]; - attributes[0] = new AttributeNode(TEXT_ATTRIBUTE_NAME, ident); + private void createTextAttribute() { + AttributeNode attribute = null; + if (XpathUtil.supportsValueAttribute(detailAst)) { + attribute = new AttributeNode(TEXT_ATTRIBUTE_NAME, XpathUtil.getValue(detailAst)); } + attributeNode = attribute; } /** diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/RootNode.java b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/RootNode.java index 0a097f684469..b57c6851b688 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/RootNode.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/RootNode.java @@ -56,9 +56,7 @@ public RootNode(DetailAST detailAst) { super(new GenericTreeInfo(Configuration.newConfiguration())); this.detailAst = detailAst; - if (detailAst != null) { - createChildren(); - } + createChildren(); } /** diff --git a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGenerator.java b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGenerator.java index 5354bb191e70..a6af50a6cf47 100644 --- a/src/main/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGenerator.java +++ b/src/main/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGenerator.java @@ -26,9 +26,9 @@ import com.puppycrawl.tools.checkstyle.TreeWalkerAuditEvent; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.FileText; -import com.puppycrawl.tools.checkstyle.api.TokenTypes; import com.puppycrawl.tools.checkstyle.utils.CommonUtil; import com.puppycrawl.tools.checkstyle.utils.TokenUtil; +import com.puppycrawl.tools.checkstyle.utils.XpathUtil; /** * Generates xpath queries. Xpath queries are generated based on received @@ -60,13 +60,15 @@ *

*
    *
  • - * /CLASS_DEF[@text='Main']/OBJBLOCK/METHOD_DEF[@text='sayHello'] + * /CLASS_DEF[./IDENT[@text='Main']]/OBJBLOCK/METHOD_DEF[./IDENT[@text='sayHello']] *
  • *
  • - * /CLASS_DEF[@text='Main']/OBJBLOCK/METHOD_DEF[@text='sayHello']/MODIFIERS + * /CLASS_DEF[./IDENT[@text='Main']]/OBJBLOCK/METHOD_DEF[./IDENT[@text='sayHello']] + * /MODIFIERS *
  • *
  • - * /CLASS_DEF[@text='Main']/OBJBLOCK/METHOD_DEF[@text='sayHello']/MODIFIERS/LITERAL_PUBLIC + * /CLASS_DEF[./IDENT[@text='Main']]/OBJBLOCK/METHOD_DEF[./IDENT[@text='sayHello']] + * /MODIFIERS/LITERAL_PUBLIC *
  • *
* @@ -144,16 +146,13 @@ public List generate() { } /** - * Returns child {@code DetailAst} element of the given root, - * which has child element with token type equals to {@link TokenTypes#IDENT}. + * Returns child {@code DetailAst} element of the given root, which has value attribute. * @param root {@code DetailAST} root ast * @return child {@code DetailAst} element of the given root */ - private static DetailAST findChildWithIdent(DetailAST root) { + private static DetailAST findChildWithValueAttribute(DetailAST root) { return TokenUtil.findFirstTokenByPredicate(root, - cur -> { - return cur.findFirstToken(TokenTypes.IDENT) != null; - }).orElse(null); + XpathUtil::supportsValueAttribute).orElse(null); } /** @@ -162,14 +161,65 @@ private static DetailAST findChildWithIdent(DetailAST root) { * @return full xpath query for given ast element */ private static String generateXpathQuery(DetailAST ast) { - String xpathQuery = getXpathQuery(null, ast); - if (!isUniqueAst(ast)) { - final DetailAST child = findChildWithIdent(ast); - if (child != null) { - xpathQuery += "[." + getXpathQuery(ast, child) + ']'; + final StringBuilder xpathQueryBuilder = new StringBuilder(getXpathQuery(null, ast)); + if (!isXpathQueryForNodeIsAccurateEnough(ast)) { + xpathQueryBuilder.append('[').append(findPositionAmongSiblings(ast)).append(']'); + } + return xpathQueryBuilder.toString(); + } + + /** + * Finds position of the ast element among siblings. + * @param ast {@code DetailAST} ast element + * @return position of the ast element + */ + private static int findPositionAmongSiblings(DetailAST ast) { + DetailAST cur = ast; + int pos = 0; + while (cur != null) { + if (cur.getType() == ast.getType()) { + pos++; + } + cur = cur.getPreviousSibling(); + } + return pos; + } + + /** + * Checks if ast element has all requirements to have unique xpath query. + * @param ast {@code DetailAST} ast element + * @return true if ast element will have unique xpath query, false otherwise + */ + private static boolean isXpathQueryForNodeIsAccurateEnough(DetailAST ast) { + return !hasAtLeastOneSiblingWithSameTokenType(ast) + || XpathUtil.supportsValueAttribute(ast) + || findChildWithValueAttribute(ast) != null; + } + + /** + * Checks if the given ast element has unique {@code TokenTypes} among siblings. + * @param ast {@code DetailAST} ast element + * @return if the given ast element has unique {@code TokenTypes} among siblings + */ + private static boolean hasAtLeastOneSiblingWithSameTokenType(DetailAST ast) { + boolean result = false; + DetailAST prev = ast.getPreviousSibling(); + while (prev != null) { + if (prev.getType() == ast.getType()) { + result = true; + break; } + prev = prev.getPreviousSibling(); } - return xpathQuery; + DetailAST next = ast.getNextSibling(); + while (next != null) { + if (next.getType() == ast.getType()) { + result = true; + break; + } + next = next.getNextSibling(); + } + return result; } /** @@ -179,16 +229,14 @@ private static String generateXpathQuery(DetailAST ast) { private List getMatchingAstElements() { final List result = new ArrayList<>(); DetailAST curNode = rootAst; - while (curNode != null && curNode.getLineNo() <= lineNumber) { + while (curNode != null) { if (isMatchingByLineAndColumnAndTokenType(curNode)) { result.add(curNode); } DetailAST toVisit = curNode.getFirstChild(); while (curNode != null && toVisit == null) { toVisit = curNode.getNextSibling(); - if (toVisit == null) { - curNode = curNode.getParent(); - } + curNode = curNode.getParent(); } curNode = toVisit; @@ -209,51 +257,26 @@ private static String getXpathQuery(DetailAST root, DetailAST ast) { final StringBuilder curNodeQueryBuilder = new StringBuilder(256); curNodeQueryBuilder.append('/') .append(TokenUtil.getTokenName(cur.getType())); - final DetailAST identAst = cur.findFirstToken(TokenTypes.IDENT); - if (identAst != null) { + if (XpathUtil.supportsValueAttribute(cur)) { curNodeQueryBuilder.append("[@text='") - .append(identAst.getText()) + .append(XpathUtil.getValue(cur)) .append("']"); } + else { + final DetailAST child = findChildWithValueAttribute(cur); + if (child != null && child != ast) { + curNodeQueryBuilder.append("[.") + .append(getXpathQuery(cur, child)) + .append(']'); + } + } + resultBuilder.insert(0, curNodeQueryBuilder); cur = cur.getParent(); } return resultBuilder.toString(); } - /** - * Checks if the given ast element has unique {@code TokenTypes} among siblings. - * @param ast {@code DetailAST} ast element - * @return if the given ast element has unique {@code TokenTypes} among siblings - */ - private static boolean hasAtLeastOneSiblingWithSameTokenType(DetailAST ast) { - boolean result = false; - if (ast.getParent() == null) { - DetailAST prev = ast.getPreviousSibling(); - while (prev != null) { - if (prev.getType() == ast.getType()) { - result = true; - break; - } - prev = prev.getPreviousSibling(); - } - if (!result) { - DetailAST next = ast.getNextSibling(); - while (next != null) { - if (next.getType() == ast.getType()) { - result = true; - break; - } - next = next.getNextSibling(); - } - } - } - else { - result = ast.getParent().getChildCount(ast.getType()) > 1; - } - return result; - } - /** * Returns the column number with tabs expanded. * @param ast {@code DetailAST} root ast @@ -275,18 +298,4 @@ private boolean isMatchingByLineAndColumnAndTokenType(DetailAST ast) { && expandedTabColumn(ast) == columnNumber && (tokenType == 0 || tokenType == ast.getType()); } - - /** - * To be sure that generated xpath query will return exactly required ast element, the element - * should be checked for uniqueness. If ast element has {@link TokenTypes#IDENT} as the child - * or there is no sibling with the same {@code TokenTypes} then element is supposed to be - * unique. This method finds if {@code DetailAst} element is unique. - * @param ast {@code DetailAST} ast element - * @return if {@code DetailAst} element is unique - */ - private static boolean isUniqueAst(DetailAST ast) { - return ast.findFirstToken(TokenTypes.IDENT) != null - || !hasAtLeastOneSiblingWithSameTokenType(ast); - } - } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java index 273251973bb3..6fd4112a5492 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/MainTest.java @@ -808,9 +808,11 @@ public void testPrintTreeJavadocOption() throws Exception { @Test public void testPrintSuppressionOption() throws Exception { - final String expected = "/CLASS_DEF[@text='InputMainSuppressionsStringPrinter']" + EOL - + "/CLASS_DEF[@text='InputMainSuppressionsStringPrinter']/MODIFIERS" + EOL - + "/CLASS_DEF[@text='InputMainSuppressionsStringPrinter']/LITERAL_CLASS" + EOL; + final String expected = "/CLASS_DEF[./IDENT[@text='InputMainSuppressionsStringPrinter']]" + + EOL + + "/CLASS_DEF[./IDENT[@text='InputMainSuppressionsStringPrinter']]/MODIFIERS" + EOL + + "/CLASS_DEF[./IDENT[@text='InputMainSuppressionsStringPrinter']]/LITERAL_CLASS" + + EOL; exit.checkAssertionAfterwards(() -> { assertEquals("Unexpected output log", @@ -824,14 +826,19 @@ public void testPrintSuppressionOption() throws Exception { @Test public void testPrintSuppressionAndTabWidthOption() throws Exception { - final String expected = "/CLASS_DEF[@text='InputMainSuppressionsStringPrinter']/OBJBLOCK" - + "/METHOD_DEF[@text='getName']/SLIST/VARIABLE_DEF[@text='var']" + EOL - + "/CLASS_DEF[@text='InputMainSuppressionsStringPrinter']/OBJBLOCK" - + "/METHOD_DEF[@text='getName']/SLIST/VARIABLE_DEF[@text='var']/MODIFIERS" + EOL - + "/CLASS_DEF[@text='InputMainSuppressionsStringPrinter']/OBJBLOCK" - + "/METHOD_DEF[@text='getName']/SLIST/VARIABLE_DEF[@text='var']/TYPE" + EOL - + "/CLASS_DEF[@text='InputMainSuppressionsStringPrinter']/OBJBLOCK" - + "/METHOD_DEF[@text='getName']/SLIST/VARIABLE_DEF[@text='var']/TYPE/LITERAL_INT" + final String expected = "/CLASS_DEF[./IDENT[@text='InputMainSuppressionsStringPrinter']]" + + "/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='getName']]/SLIST/VARIABLE_DEF[./IDENT[@text='var']]" + + EOL + + "/CLASS_DEF[./IDENT[@text='InputMainSuppressionsStringPrinter']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='getName']]/SLIST/VARIABLE_DEF[./IDENT[@text='var']]" + + "/MODIFIERS" + EOL + + "/CLASS_DEF[./IDENT[@text='InputMainSuppressionsStringPrinter']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='getName']]/SLIST/VARIABLE_DEF[./IDENT[@text='var']]" + + "/TYPE" + EOL + + "/CLASS_DEF[./IDENT[@text='InputMainSuppressionsStringPrinter']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='getName']]/SLIST/VARIABLE_DEF[./IDENT[@text='var']]" + + "/TYPE/LITERAL_INT" + EOL; exit.checkAssertionAfterwards(() -> { @@ -920,81 +927,81 @@ public void testGenerateXpathSuppressionOptionOne() throws Exception { + "" + EOL + + " query=\"/CLASS_DEF[./IDENT[@text='InputMainComplexityOverflow']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='provokeNpathIntegerOverflow']]\"/>" + EOL + "" + EOL + + " query=\"/CLASS_DEF[./IDENT[@text='InputMainComplexityOverflow']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='provokeNpathIntegerOverflow']]/SLIST\"/>" + EOL + "" + EOL + "" + EOL + "" + EOL + "" + EOL + "" + EOL + "" + EOL + "" + EOL + "" + EOL + "" + EOL + "" + EOL + "" + EOL; @@ -1020,18 +1027,20 @@ public void testGenerateXpathSuppressionOptionTwo() throws Exception { + "" + EOL + + " query=\"/CLASS_DEF[./IDENT[@text='InputMainGenerateXpathSuppressions']]" + + "/OBJBLOCK/VARIABLE_DEF/IDENT[@text='low']\"/>" + EOL + "" + EOL + + " query=\"/CLASS_DEF[./IDENT[@text='InputMainGenerateXpathSuppressions']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/LITERAL_THROWS" + + "/IDENT[@text='RuntimeException']\"/>" + EOL + "" + EOL + "" + EOL; @@ -1072,8 +1081,9 @@ public void testGenerateXpathSuppressionOptionDefaultTabWidth() throws Exception + "" + EOL + + " query=\"/CLASS_DEF[./IDENT[" + + "@text='InputMainGenerateXpathSuppressionsTabWidth']]" + + "/OBJBLOCK/VARIABLE_DEF/IDENT[@text='low']\"/>" + EOL + "" + EOL; exit.checkAssertionAfterwards(() -> { diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/SuppressionsStringPrinterTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/SuppressionsStringPrinterTest.java index 939406373a14..f4e1dbc219be 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/SuppressionsStringPrinterTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/SuppressionsStringPrinterTest.java @@ -47,10 +47,10 @@ public void testIsProperUtilsClass() throws ReflectiveOperationException { @Test public void testCorrect() throws Exception { - final String expected = "/CLASS_DEF[@text='InputSuppressionsStringPrinter']" + EOL - + "/CLASS_DEF[@text='InputSuppressionsStringPrinter']/MODIFIERS" + EOL - + "/CLASS_DEF[@text='InputSuppressionsStringPrinter']/MODIFIERS/LITERAL_PUBLIC" - + EOL; + final String expected = "/CLASS_DEF[./IDENT[@text='InputSuppressionsStringPrinter']]" + EOL + + "/CLASS_DEF[./IDENT[@text='InputSuppressionsStringPrinter']]/MODIFIERS" + EOL + + "/CLASS_DEF[./IDENT[@text='InputSuppressionsStringPrinter']]/MODIFIERS" + + "/LITERAL_PUBLIC" + EOL; final File input = new File(getPath("InputSuppressionsStringPrinter.java")); final String lineAndColumnNumber = "3:1"; @@ -64,12 +64,12 @@ public void testCorrect() throws Exception { @Test public void testCustomTabWidth() throws Exception { - final String expected = "/CLASS_DEF[@text='InputSuppressionsStringPrinter']/OBJBLOCK" - + "/METHOD_DEF[@text='toString']" + EOL - + "/CLASS_DEF[@text='InputSuppressionsStringPrinter']/OBJBLOCK" - + "/METHOD_DEF[@text='toString']/MODIFIERS" + EOL - + "/CLASS_DEF[@text='InputSuppressionsStringPrinter']/OBJBLOCK" - + "/METHOD_DEF[@text='toString']/MODIFIERS/LITERAL_PUBLIC" + EOL; + final String expected = "/CLASS_DEF[./IDENT[@text='InputSuppressionsStringPrinter']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='toString']]" + EOL + + "/CLASS_DEF[./IDENT[@text='InputSuppressionsStringPrinter']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='toString']]/MODIFIERS" + EOL + + "/CLASS_DEF[./IDENT[@text='InputSuppressionsStringPrinter']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='toString']]/MODIFIERS/LITERAL_PUBLIC" + EOL; final File input = new File(getPath("InputSuppressionsStringPrinter.java")); final String lineAndColumnNumber = "5:13"; diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAstFilterTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAstFilterTest.java index 3675eefae3ba..1c2b3edf942f 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAstFilterTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAstFilterTest.java @@ -68,7 +68,25 @@ public void test() throws Exception { getPath("InputXpathFileGeneratorAstFilter.java"), message); Assert.assertEquals("expected xpath", - "/CLASS_DEF[@text='InputXpathFileGeneratorAstFilter']/OBJBLOCK/LCURLY", + "/CLASS_DEF[./IDENT[@text='InputXpathFileGeneratorAstFilter']]/OBJBLOCK/LCURLY", + XpathFileGeneratorAstFilter.findCorrespondingXpathQuery(auditEvent)); + } + + @Test + public void testNoXpathQuery() throws Exception { + final LocalizedMessage message = new LocalizedMessage(10, 10, TokenTypes.LCURLY, + "messages.properties", null, null, SeverityLevel.ERROR, null, LeftCurlyCheck.class, + null); + final TreeWalkerAuditEvent event = createTreeWalkerAuditEvent( + "InputXpathFileGeneratorAstFilter.java", message); + final XpathFileGeneratorAstFilter filter = new XpathFileGeneratorAstFilter(); + + Assert.assertTrue("filter accepted", filter.accept(event)); + + final AuditEvent auditEvent = new AuditEvent(this, + getPath("InputXpathFileGeneratorAstFilter.java"), message); + + Assert.assertNull("expected null", XpathFileGeneratorAstFilter.findCorrespondingXpathQuery(auditEvent)); } @@ -88,8 +106,8 @@ public void testTabWidth() throws Exception { getPath("InputXpathFileGeneratorAstFilter.java"), message); Assert.assertEquals("expected xpath", - "/CLASS_DEF[@text='InputXpathFileGeneratorAstFilter']/OBJBLOCK" - + "/METHOD_DEF[@text='tabMethod']/SLIST/LITERAL_RETURN", + "/CLASS_DEF[./IDENT[@text='InputXpathFileGeneratorAstFilter']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='tabMethod']]/SLIST/LITERAL_RETURN", XpathFileGeneratorAstFilter.findCorrespondingXpathQuery(auditEvent)); } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAuditListenerTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAuditListenerTest.java index 0d2b4f472073..29af89e5555f 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAuditListenerTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/XpathFileGeneratorAuditListenerTest.java @@ -43,6 +43,7 @@ import com.puppycrawl.tools.checkstyle.checks.coding.NestedForDepthCheck; import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheck; import com.puppycrawl.tools.checkstyle.checks.whitespace.MethodParamPadCheck; +import com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream; public class XpathFileGeneratorAuditListenerTest { @@ -61,6 +62,14 @@ public class XpathFileGeneratorAuditListenerTest { private static final LocalizedMessage FOURTH_MESSAGE = createLocalizedMessage(5, 5, TokenTypes.VARIABLE_DEF, "JavadocModuleId", JavadocVariableCheck.class); + /** + * Output stream to hold the test results. The IntelliJ IDEA issues the AutoCloseableResource + * warning here, so it need to be suppressed. The {@code ByteArrayOutputStream} does not hold + * any resources that need to be released. + */ + private final CloseAndFlushTestByteArrayOutputStream outStream = + new CloseAndFlushTestByteArrayOutputStream(); + @BeforeClass public static void constructEvents() throws Exception { final TreeWalkerAuditEvent event1 = createTreeWalkerAuditEvent( @@ -157,8 +166,8 @@ public void testCorrectOne() { + " files=\"InputXpathFileGeneratorAuditListener.java\"" + EOL + " checks=\"LeftCurlyCheck\"" + EOL - + " query=\"/CLASS_DEF[@text='InputXpathFileGeneratorAuditListener']/OBJBLOCK" - + "/LCURLY\"/>" + EOL + + " query=\"/CLASS_DEF[./IDENT[@text='InputXpathFileGeneratorAuditListener']]" + + "/OBJBLOCK/LCURLY\"/>" + EOL + "" + EOL; verifyOutput(expected, event); @@ -182,13 +191,14 @@ public void testCorrectTwo() { + "" + EOL + + " query=\"/CLASS_DEF[./IDENT[@text='InputXpathFileGeneratorAuditListener']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='sort']]\"/>" + EOL + "" + EOL + + " query=\"/CLASS_DEF[./IDENT[@text='InputXpathFileGeneratorAuditListener']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='sort']]/SLIST/LITERAL_FOR/SLIST" + + "/LITERAL_FOR\"/>" + EOL + "" + EOL; verifyOutput(expected, event1, event2); @@ -215,13 +225,37 @@ public void testOnlyOneMatching() { + "" + EOL + + " query=\"/CLASS_DEF[./IDENT[@text='InputXpathFileGeneratorAuditListener']]" + + "/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='isValid']]\"/>" + EOL + "" + EOL; verifyOutput(expected, event1, event2, event3); } + @Test + public void testCloseStream() { + final XpathFileGeneratorAuditListener listener = + new XpathFileGeneratorAuditListener(outStream, + AutomaticBean.OutputStreamOptions.CLOSE); + listener.finishLocalSetup(); + listener.auditStarted(null); + listener.auditFinished(null); + + assertEquals("Invalid close count", 1, outStream.getCloseCount()); + } + + @Test + public void testNoCloseStream() { + final XpathFileGeneratorAuditListener listener = + new XpathFileGeneratorAuditListener(outStream, + AutomaticBean.OutputStreamOptions.NONE); + listener.finishLocalSetup(); + listener.auditStarted(null); + listener.auditFinished(null); + + assertEquals("Invalid close count", 0, outStream.getCloseCount()); + } + private AuditEvent createAuditEvent(String fileName, int lineNumber, int columnNumber, Class sourceClass) { final LocalizedMessage message = diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionXpathSingleFilterTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionXpathSingleFilterTest.java index b97e83d421fa..052feaf239cb 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionXpathSingleFilterTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/filters/SuppressionXpathSingleFilterTest.java @@ -57,7 +57,7 @@ protected String getPackageLocation() { @Test public void testMatching() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputSuppressionXpathSingleFilter']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputSuppressionXpathSingleFilter']]"; final SuppressionXpathSingleFilter filter = createSuppressionXpathSingleFilter("InputSuppressionXpathSingleFilter", "Test", null, null, xpath); @@ -101,9 +101,9 @@ public void testNonMatchingColumnNumber() throws Exception { @Test public void testComplexQuery() throws Exception { - final String xpath = "//VARIABLE_DEF[@text='pi' and " - + "../..[@text='countTokens']] " - + "| //VARIABLE_DEF[@text='someVariable' and ../..[@text='sum']]"; + final String xpath = "//VARIABLE_DEF[./IDENT[@text='pi'] and " + + "../../IDENT[@text='countTokens']] " + + "| //VARIABLE_DEF[./IDENT[@text='someVariable'] and ../../IDENT[@text='sum']]"; final SuppressionXpathSingleFilter filter = createSuppressionXpathSingleFilter("InputSuppressionXpathSingleFilter", "Test", null, null, xpath); @@ -193,7 +193,7 @@ public void testNonMatchingModuleId() throws Exception { @Test public void testMatchingModuleId() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputSuppressionXpathSingleFilter']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputSuppressionXpathSingleFilter']]"; final SuppressionXpathSingleFilter filter = createSuppressionXpathSingleFilter("InputSuppressionXpathSingleFilter", "Test", null, "id19", xpath); diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/filters/XpathFilterElementTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/filters/XpathFilterElementTest.java index c259f5b96c8c..4a5290a28ad6 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/filters/XpathFilterElementTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/filters/XpathFilterElementTest.java @@ -61,7 +61,7 @@ protected String getPackageLocation() { @Test public void testMatching() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathFilterElementSuppressByXpath']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathFilterElementSuppressByXpath']]"; final XpathFilterElement filter = new XpathFilterElement( "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath); final TreeWalkerAuditEvent ev = getEvent(3, 0, @@ -71,7 +71,7 @@ public void testMatching() throws Exception { @Test public void testNonMatchingTokenType() throws Exception { - final String xpath = "//METHOD_DEF[@text='countTokens']"; + final String xpath = "//METHOD_DEF[./IDENT[@text='countTokens']]"; final XpathFilterElement filter = new XpathFilterElement( "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath); final TreeWalkerAuditEvent ev = getEvent(3, 0, @@ -81,7 +81,7 @@ public void testNonMatchingTokenType() throws Exception { @Test public void testNonMatchingLineNumber() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathFilterElementSuppressByXpath']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathFilterElementSuppressByXpath']]"; final XpathFilterElement filter = new XpathFilterElement( "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath); final TreeWalkerAuditEvent ev = getEvent(100, 0, @@ -91,7 +91,7 @@ public void testNonMatchingLineNumber() throws Exception { @Test public void testNonMatchingColumnNumber() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathFilterElementSuppressByXpath']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathFilterElementSuppressByXpath']]"; final XpathFilterElement filter = new XpathFilterElement( "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath); final TreeWalkerAuditEvent ev = getEvent(3, 100, @@ -101,9 +101,9 @@ public void testNonMatchingColumnNumber() throws Exception { @Test public void testComplexQuery() throws Exception { - final String xpath = "//VARIABLE_DEF[@text='pi' and " - + "../..[@text='countTokens']] " - + "| //VARIABLE_DEF[@text='someVariable' and ../..[@text='sum']]"; + final String xpath = "//VARIABLE_DEF[./IDENT[@text='pi'] and " + + "../../IDENT[@text='countTokens']] " + + "| //VARIABLE_DEF[./IDENT[@text='someVariable'] and ../../IDENT[@text='sum']]"; final XpathFilterElement filter = new XpathFilterElement( "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath); final TreeWalkerAuditEvent eventOne = getEvent(5, 8, @@ -185,7 +185,7 @@ public void testNonMatchingModuleId() throws Exception { @Test public void testMatchingModuleId() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathFilterElementSuppressByXpath']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathFilterElementSuppressByXpath']]"; final XpathFilterElement filter = new XpathFilterElement( "InputXpathFilterElementSuppressByXpath", "Test", null, "id19", xpath); final LocalizedMessage message = diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/utils/XpathUtilTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/utils/XpathUtilTest.java new file mode 100644 index 000000000000..28e7193ad928 --- /dev/null +++ b/src/test/java/com/puppycrawl/tools/checkstyle/utils/XpathUtilTest.java @@ -0,0 +1,85 @@ +//////////////////////////////////////////////////////////////////////////////// +// checkstyle: Checks Java source code for adherence to a set of rules. +// Copyright (C) 2001-2019 the original author or authors. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//////////////////////////////////////////////////////////////////////////////// + +package com.puppycrawl.tools.checkstyle.utils; + +import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.isUtilsClassHasPrivateConstructor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.puppycrawl.tools.checkstyle.api.DetailAST; +import com.puppycrawl.tools.checkstyle.api.TokenTypes; + +public class XpathUtilTest { + + @Test + public void testIsProperUtilsClass() throws ReflectiveOperationException { + assertTrue("Constructor is not private", + isUtilsClassHasPrivateConstructor(XpathUtil.class, true)); + } + + @Test + public void testSupportsValueAttribute() { + assertTrue("Should return true for supported token typs", + XpathUtil.supportsValueAttribute(createDetailAST(TokenTypes.IDENT))); + assertTrue("Should return true for supported token typs", + XpathUtil.supportsValueAttribute(createDetailAST(TokenTypes.NUM_INT))); + assertTrue("Should return true for supported token typs", + XpathUtil.supportsValueAttribute(createDetailAST(TokenTypes.STRING_LITERAL))); + assertTrue("Should return true for supported token typs", + XpathUtil.supportsValueAttribute(createDetailAST(TokenTypes.CHAR_LITERAL))); + assertTrue("Should return true for supported token typs", + XpathUtil.supportsValueAttribute(createDetailAST(TokenTypes.NUM_DOUBLE))); + assertFalse("Should return false for unsupported token typs", + XpathUtil.supportsValueAttribute(createDetailAST(TokenTypes.VARIABLE_DEF))); + assertFalse("Should return false for unsupported token typs", + XpathUtil.supportsValueAttribute(createDetailAST(TokenTypes.OBJBLOCK))); + assertFalse("Should return true for supported token typs", + XpathUtil.supportsValueAttribute(createDetailAST(TokenTypes.LITERAL_CHAR))); + } + + @Test + public void testGetValue() { + assertEquals("Returned value differs from expected", "HELLO WORLD", + XpathUtil.getValue(createDetailAST(TokenTypes.STRING_LITERAL, "\"HELLO WORLD\""))); + assertEquals("Returned value differs from expected", "123", + XpathUtil.getValue(createDetailAST(TokenTypes.NUM_INT, "123"))); + assertEquals("Returned value differs from expected", "HELLO WORLD", + XpathUtil.getValue(createDetailAST(TokenTypes.IDENT, "HELLO WORLD"))); + assertNotEquals("Returned value differs from expected", "HELLO WORLD", + XpathUtil.getValue(createDetailAST(TokenTypes.STRING_LITERAL, "HELLO WORLD"))); + } + + private static DetailAST createDetailAST(int type) { + final DetailAST detailAST = new DetailAST(); + detailAST.setType(type); + return detailAST; + } + + private static DetailAST createDetailAST(int type, String text) { + final DetailAST detailAST = new DetailAST(); + detailAST.setType(type); + detailAST.setText(text); + return detailAST; + } +} diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/xpath/ElementNodeTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/xpath/ElementNodeTest.java index c9d57a333001..ce956ee84309 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/xpath/ElementNodeTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/xpath/ElementNodeTest.java @@ -21,6 +21,7 @@ import static com.puppycrawl.tools.checkstyle.internal.utils.XpathUtil.getXpathItems; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.File; @@ -33,7 +34,12 @@ import com.puppycrawl.tools.checkstyle.JavaParser; import com.puppycrawl.tools.checkstyle.api.DetailAST; import com.puppycrawl.tools.checkstyle.api.TokenTypes; +import net.sf.saxon.om.AxisInfo; import net.sf.saxon.om.NodeInfo; +import net.sf.saxon.tree.iter.ArrayIterator; +import net.sf.saxon.tree.iter.AxisIterator; +import net.sf.saxon.tree.iter.EmptyIterator; +import net.sf.saxon.tree.util.Navigator; public class ElementNodeTest extends AbstractPathTestSupport { @@ -71,4 +77,91 @@ public void testRootOfElementNode() throws Exception { root instanceof RootNode); } + @Test + public void testGetNodeByValueNumInt() throws Exception { + final String xPath = "//NUM_INT[@text = 123]"; + final List nodes = getXpathItems(xPath, rootNode); + assertEquals("Invalid number of nodes", 1, nodes.size()); + assertEquals("Invalid token type", TokenTypes.NUM_INT, + ((AbstractNode) nodes.get(0)).getTokenType()); + } + + @Test + public void testGetNodeByValueStringLiteral() throws Exception { + final String xPath = "//STRING_LITERAL[@text = 'HelloWorld']"; + final List nodes = getXpathItems(xPath, rootNode); + assertEquals("Invalid number of nodes", 2, nodes.size()); + assertEquals("Invalid token type", TokenTypes.STRING_LITERAL, + ((AbstractNode) nodes.get(0)).getTokenType()); + } + + @Test + public void testGetNodeByValueWithSameTokenText() throws Exception { + final String xPath = "//MODIFIERS[@text = 'MODIFIERS']"; + final List nodes = getXpathItems(xPath, rootNode); + assertEquals("Invalid number of nodes", 0, nodes.size()); + } + + @Test + public void testGetAttributeValue() { + final DetailAST detailAST = new DetailAST(); + detailAST.setType(TokenTypes.IDENT); + detailAST.setText("HelloWorld"); + + final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST); + + assertEquals("Invalid text attribute", "HelloWorld", + elementNode.getAttributeValue(null, "text")); + } + + @Test + public void testGetAttributeValueNoAttribute() { + final DetailAST detailAST = new DetailAST(); + detailAST.setType(TokenTypes.CLASS_DEF); + detailAST.setText("HelloWorld"); + + final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST); + + assertNull("Must be null", elementNode.getAttributeValue(null, "text")); + } + + @Test + public void testGetAttributeValueWrongAttribute() { + final DetailAST detailAST = new DetailAST(); + detailAST.setType(TokenTypes.IDENT); + detailAST.setText("HelloWorld"); + + final ElementNode elementNode = new ElementNode(rootNode, rootNode, detailAST); + + assertNull("Must be null", elementNode.getAttributeValue(null, "wroooong")); + } + + @Test + public void testIterateAxisEmptyChildren() { + final DetailAST detailAST = new DetailAST(); + detailAST.setType(TokenTypes.METHOD_DEF); + final ElementNode elementNode = new ElementNode(rootNode, null, detailAST); + try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.CHILD)) { + assertTrue("Invalid iterator", iterator instanceof EmptyIterator); + } + try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.DESCENDANT)) { + assertTrue("Invalid iterator", iterator instanceof EmptyIterator); + } + } + + @Test + public void testIterateAxisWithChildren() { + final DetailAST detailAST = new DetailAST(); + detailAST.setType(TokenTypes.METHOD_DEF); + final DetailAST childAst = new DetailAST(); + childAst.setType(TokenTypes.VARIABLE_DEF); + detailAST.addChild(childAst); + final ElementNode elementNode = new ElementNode(rootNode, null, detailAST); + try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.CHILD)) { + assertTrue("Invalid iterator", iterator instanceof ArrayIterator); + } + try (AxisIterator iterator = elementNode.iterateAxis(AxisInfo.DESCENDANT)) { + assertTrue("Invalid iterator", iterator instanceof Navigator.DescendantEnumeration); + } + } } diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathMapperTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathMapperTest.java index a2a5cd2aa581..002ba63a6314 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathMapperTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathMapperTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -155,7 +156,8 @@ public void testComplexQueryThree() throws Exception { @Test public void testAttributeOr() throws Exception { - final String xpath = "//METHOD_DEF[@text='getSomeMethod' or @text='nonExistentMethod']"; + final String xpath = "//METHOD_DEF[./IDENT[@text='getSomeMethod'] " + + "or ./IDENT[@text='nonExistentMethod']]"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); final DetailAST expectedClassDefNode = getSiblingByType(rootNode.getUnderlyingNode(), @@ -170,8 +172,8 @@ public void testAttributeOr() throws Exception { @Test public void testAttributeAnd() throws Exception { - final String xpath = "//METHOD_DEF[@text='callSomeMethod' and " - + "../..[@text='InputXpathMapperAst']]"; + final String xpath = "//METHOD_DEF[./IDENT[@text='callSomeMethod'] and " + + "../..[./IDENT[@text='InputXpathMapperAst']]]"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); final DetailAST expectedClassDefNode = getSiblingByType(rootNode.getUnderlyingNode(), @@ -185,7 +187,7 @@ public void testAttributeAnd() throws Exception { @Test public void testQueryAllElementsWithAttribute() throws Exception { - final String xpath = "//*[@text]"; + final String xpath = "//*[./IDENT[@text]]"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final List nodes = getXpathItems(xpath, rootNode); assertEquals("Invalid number of nodes", 18, nodes.size()); @@ -209,7 +211,7 @@ public void testQueryElementByIndex() throws Exception { @Test public void testQueryAllVariableDefinitionsWithAttribute() throws Exception { - final String xpath = "//VARIABLE_DEF[@*]"; + final String xpath = "//VARIABLE_DEF[./IDENT[@*]]"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final List nodes = getXpathItems(xpath, rootNode); assertEquals("Invalid number of nodes", 4, nodes.size()); @@ -225,7 +227,7 @@ public void testQueryAllVariableDefWrongAttribute() throws Exception { @Test public void testQueryAllMethodDefinitionsInContext() throws Exception { - final String objectXpath = "/CLASS_DEF[@text='InputXpathMapperAst']//OBJBLOCK"; + final String objectXpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperAst']]//OBJBLOCK"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final List objectNodes = getXpathItems(objectXpath, rootNode); assertEquals("Invalid number of nodes", 1, objectNodes.size()); @@ -261,7 +263,7 @@ public void testQueryAllClassDefinitions() throws Exception { @Test public void testQueryByMethodName() throws Exception { - final String xpath = "//METHOD_DEF[@text='getSomeMethod']"; + final String xpath = "//METHOD_DEF[./IDENT[@text='getSomeMethod']]"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); final DetailAST expectedMethodDefNode = getSiblingByType(rootNode.getUnderlyingNode(), @@ -275,7 +277,8 @@ public void testQueryByMethodName() throws Exception { @Test public void testQueryMethodDefinitionsByClassName() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathMapperAst']//OBJBLOCK//METHOD_DEF"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperAst']]" + + "//OBJBLOCK//METHOD_DEF"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); final DetailAST expectedMethodDefNode = getSiblingByType(rootNode.getUnderlyingNode(), @@ -289,8 +292,8 @@ public void testQueryMethodDefinitionsByClassName() throws Exception { @Test public void testQueryByClassNameAndMethodName() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathMapperAst']//OBJBLOCK" - + "//METHOD_DEF[@text='getSomeMethod']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperAst']]//OBJBLOCK" + + "//METHOD_DEF[./IDENT[@text='getSomeMethod']]"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); final DetailAST expectedMethodDefNode = getSiblingByType(rootNode.getUnderlyingNode(), @@ -304,7 +307,7 @@ public void testQueryByClassNameAndMethodName() throws Exception { @Test public void testQueryClassDefinitionByClassName() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathMapperAst']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperAst']]"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final List nodes = getXpathItems(xpath, rootNode); final DetailAST[] actual = convertToArray(nodes); @@ -313,8 +316,6 @@ public void testQueryClassDefinitionByClassName() throws Exception { final DetailAST[] expected = {expectedClassDefNode}; final ElementNode classDefNode = (ElementNode) nodes.get(0); assertEquals("Invalid number of nodes", "CLASS_DEF", classDefNode.getStringValue()); - assertEquals("Invalid number of nodes", "InputXpathMapperAst", - classDefNode.getAttributeValue("", "text")); assertArrayEquals("Result nodes differ from expected", expected, actual); } @@ -336,7 +337,7 @@ public void testQueryWrongXpath() throws Exception { @Test public void testQueryAncestor() throws Exception { - final String xpath = "//VARIABLE_DEF[@text='another']/ancestor::METHOD_DEF"; + final String xpath = "//VARIABLE_DEF[./IDENT[@text='another']]/ancestor::METHOD_DEF"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); final DetailAST expectedMethodDefNode = getSiblingByType(rootNode.getUnderlyingNode(), @@ -349,7 +350,8 @@ public void testQueryAncestor() throws Exception { @Test public void testQueryAncestorOrSelf() throws Exception { - final String xpath = "//VARIABLE_DEF[@text='another']/ancestor-or-self::VARIABLE_DEF"; + final String xpath = "//VARIABLE_DEF[./IDENT[@text='another']]" + + "/ancestor-or-self::VARIABLE_DEF"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), @@ -430,7 +432,7 @@ public void testQueryElementNotImplementedAxis() throws Exception { @Test public void testQuerySelf() throws Exception { - final String objectXpath = "/CLASS_DEF[@text='InputXpathMapperAst']//OBJBLOCK"; + final String objectXpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperAst']]//OBJBLOCK"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final List objectNodes = getXpathItems(objectXpath, rootNode); assertEquals("Invalid number of nodes", 1, objectNodes.size()); @@ -457,17 +459,12 @@ public void testRootWithNullDetailAst() { @Test public void testQueryNonExistentAttribute() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathMapperAst']"; + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperAst']]"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final List nodes = getXpathItems(xpath, rootNode); final ElementNode classDefNode = (ElementNode) nodes.get(0); - try { - classDefNode.getAttributeValue("", "noneExistingAttribute"); - fail("Exception is excepted"); - } - catch (UnsupportedOperationException ex) { - assertEquals("Invalid number of nodes", "Operation is not supported", ex.getMessage()); - } + assertNull("Not existing attribute should have null value", + classDefNode.getAttributeValue("", "noneExistingAttribute")); } @Test @@ -480,7 +477,7 @@ public void testQueryRootSelf() throws Exception { @Test public void testQueryAnnotation() throws Exception { - final String xpath = "//ANNOTATION[@text='SuppressWarnings']"; + final String xpath = "//ANNOTATION[./IDENT[@text='Deprecated']]"; final RootNode rootNode = getRootNode("InputXpathMapperAnnotation.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); final DetailAST expectedAnnotationNode = getSiblingByType(rootNode.getUnderlyingNode(), @@ -520,7 +517,7 @@ public void testQueryEnumElementsNumber() throws Exception { @Test public void testQueryEnumElementByName() throws Exception { - final String xpath = "//*[@text='TWO']"; + final String xpath = "//*[./IDENT[@text='TWO']]"; final RootNode enumRootNode = getRootNode("InputXpathMapperEnum.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, enumRootNode)); final DetailAST expectedEnumConstantDefNode = getSiblingByType( @@ -556,7 +553,7 @@ public void testQueryInterfaceMethodDefNumber() throws Exception { @Test public void testQueryInterfaceParameterDef() throws Exception { - final String xpath = "//PARAMETER_DEF[@text='someVariable']/../.."; + final String xpath = "//PARAMETER_DEF[./IDENT[@text='someVariable']]/../.."; final RootNode interfaceRootNode = getRootNode("InputXpathMapperInterface.java"); final DetailAST[] actual = convertToArray(getXpathItems(xpath, interfaceRootNode)); final DetailAST expectedMethodDefNode = getSiblingByType( @@ -571,7 +568,7 @@ public void testQueryInterfaceParameterDef() throws Exception { @Test public void testIdent() throws Exception { - final String xpath = "/CLASS_DEF[@text='InputXpathMapperAst']/IDENT"; + final String xpath = "/CLASS_DEF/IDENT[@text='InputXpathMapperAst']"; final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); final List nodes = getXpathItems(xpath, rootNode); final DetailAST[] actual = convertToArray(nodes); @@ -583,6 +580,212 @@ public void testIdent() throws Exception { assertArrayEquals("Result nodes differ from expected", expected, actual); } + @Test + public void testIdentByValue() throws Exception { + final String xpath = "//IDENT[@text='puppycrawl']"; + final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedMethodDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.PACKAGE_DEF) + .findFirstToken(TokenTypes.DOT) + .findFirstToken(TokenTypes.DOT) + .findFirstToken(TokenTypes.DOT) + .findFirstToken(TokenTypes.DOT) + .findFirstToken(TokenTypes.DOT) + .findFirstToken(TokenTypes.IDENT) + .getNextSibling(); + final DetailAST[] expected = {expectedMethodDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testNumVariableByItsValue() throws Exception { + final String xpath = "//VARIABLE_DEF[.//NUM_INT[@text=123]]"; + final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.CLASS_DEF) + .findFirstToken(TokenTypes.OBJBLOCK) + .findFirstToken(TokenTypes.METHOD_DEF) + .findFirstToken(TokenTypes.SLIST) + .findFirstToken(TokenTypes.VARIABLE_DEF); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testStringVariableByItsValue() throws Exception { + final String xpath = "//VARIABLE_DEF[./ASSIGN/EXPR" + + "/STRING_LITERAL[@text='HelloWorld']]"; + final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.CLASS_DEF) + .findFirstToken(TokenTypes.OBJBLOCK) + .findFirstToken(TokenTypes.METHOD_DEF) + .findFirstToken(TokenTypes.SLIST) + .findFirstToken(TokenTypes.VARIABLE_DEF) + .getNextSibling() + .getNextSibling(); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testSameNodesByNameAndByValue() throws Exception { + final String xpath1 = "//VARIABLE_DEF[./IDENT[@text='another']]/ASSIGN/EXPR/STRING_LITERAL"; + final String xpath2 = "//VARIABLE_DEF/ASSIGN/EXPR/STRING_LITERAL[@text='HelloWorld']"; + final RootNode rootNode = getRootNode("InputXpathMapperAst.java"); + final DetailAST[] actual1 = convertToArray(getXpathItems(xpath1, rootNode)); + final DetailAST[] actual2 = convertToArray(getXpathItems(xpath2, rootNode)); + assertArrayEquals("Result nodes differ from expected", actual1, actual2); + } + + @Test + public void testMethodDefByAnnotationValue() throws Exception { + final String xpath = "//METHOD_DEF[.//ANNOTATION[./IDENT[@text='SuppressWarnings']" + + " and .//*[@text='good']]]"; + final RootNode rootNode = getRootNode("InputXpathMapperAnnotation.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedAnnotationNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.CLASS_DEF) + .findFirstToken(TokenTypes.OBJBLOCK) + .findFirstToken(TokenTypes.METHOD_DEF) + .getNextSibling(); + final DetailAST[] expected = {expectedAnnotationNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testFirstImport() throws Exception { + final String xpath = "/IMPORT[1]"; + final RootNode rootNode = getRootNode("InputXpathMapperPositions.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.IMPORT); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testSecondImport() throws Exception { + final String xpath = "/IMPORT[2]"; + final RootNode rootNode = getRootNode("InputXpathMapperPositions.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.IMPORT).getNextSibling(); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testThirdImport() throws Exception { + final String xpath = "/IMPORT[3]"; + final RootNode rootNode = getRootNode("InputXpathMapperPositions.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.IMPORT).getNextSibling().getNextSibling(); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testLastImport() throws Exception { + final String xpath = "/IMPORT[9]"; + final RootNode rootNode = getRootNode("InputXpathMapperPositions.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.IMPORT) + .getNextSibling() + .getNextSibling() + .getNextSibling() + .getNextSibling() + .getNextSibling() + .getNextSibling() + .getNextSibling() + .getNextSibling(); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testFirstCaseGroup() throws Exception { + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperPositions']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='switchMethod']]" + + "/SLIST/LITERAL_SWITCH/CASE_GROUP[1]"; + final RootNode rootNode = getRootNode("InputXpathMapperPositions.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.CLASS_DEF) + .findFirstToken(TokenTypes.OBJBLOCK) + .findFirstToken(TokenTypes.METHOD_DEF) + .findFirstToken(TokenTypes.SLIST) + .findFirstToken(TokenTypes.LITERAL_SWITCH) + .findFirstToken(TokenTypes.CASE_GROUP); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testSecondCaseGroup() throws Exception { + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperPositions']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='switchMethod']]" + + "/SLIST/LITERAL_SWITCH/CASE_GROUP[2]"; + final RootNode rootNode = getRootNode("InputXpathMapperPositions.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.CLASS_DEF) + .findFirstToken(TokenTypes.OBJBLOCK) + .findFirstToken(TokenTypes.METHOD_DEF) + .findFirstToken(TokenTypes.SLIST) + .findFirstToken(TokenTypes.LITERAL_SWITCH) + .findFirstToken(TokenTypes.CASE_GROUP) + .getNextSibling(); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testThirdCaseGroup() throws Exception { + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperPositions']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='switchMethod']]" + + "/SLIST/LITERAL_SWITCH/CASE_GROUP[3]"; + final RootNode rootNode = getRootNode("InputXpathMapperPositions.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.CLASS_DEF) + .findFirstToken(TokenTypes.OBJBLOCK) + .findFirstToken(TokenTypes.METHOD_DEF) + .findFirstToken(TokenTypes.SLIST) + .findFirstToken(TokenTypes.LITERAL_SWITCH) + .findFirstToken(TokenTypes.CASE_GROUP) + .getNextSibling() + .getNextSibling(); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + + @Test + public void testFourthCaseGroup() throws Exception { + final String xpath = "/CLASS_DEF[./IDENT[@text='InputXpathMapperPositions']]" + + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='switchMethod']]" + + "/SLIST/LITERAL_SWITCH/CASE_GROUP[4]"; + final RootNode rootNode = getRootNode("InputXpathMapperPositions.java"); + final DetailAST[] actual = convertToArray(getXpathItems(xpath, rootNode)); + final DetailAST expectedVariableDefNode = getSiblingByType(rootNode.getUnderlyingNode(), + TokenTypes.CLASS_DEF) + .findFirstToken(TokenTypes.OBJBLOCK) + .findFirstToken(TokenTypes.METHOD_DEF) + .findFirstToken(TokenTypes.SLIST) + .findFirstToken(TokenTypes.LITERAL_SWITCH) + .findFirstToken(TokenTypes.CASE_GROUP) + .getNextSibling() + .getNextSibling() + .getNextSibling(); + final DetailAST[] expected = {expectedVariableDefNode}; + assertArrayEquals("Result nodes differ from expected", expected, actual); + } + private RootNode getRootNode(String fileName) throws Exception { final File file = new File(getPath(fileName)); final DetailAST rootAst = JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS); diff --git a/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGeneratorTest.java b/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGeneratorTest.java index f01f2fd4019b..c42c1f1451c9 100644 --- a/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGeneratorTest.java +++ b/src/test/java/com/puppycrawl/tools/checkstyle/xpath/XpathQueryGeneratorTest.java @@ -69,9 +69,9 @@ public void testClassDef() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/MODIFIERS", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/MODIFIERS/LITERAL_PUBLIC"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/MODIFIERS/LITERAL_PUBLIC"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -83,12 +83,12 @@ public void testMethodDef() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']" - + "/OBJBLOCK/METHOD_DEF[@text='callSomeMethod']", - "/CLASS_DEF[@text='InputXpathQueryGenerator']" - + "/OBJBLOCK/METHOD_DEF[@text='callSomeMethod']/MODIFIERS", - "/CLASS_DEF[@text='InputXpathQueryGenerator']" - + "/OBJBLOCK/METHOD_DEF[@text='callSomeMethod']/MODIFIERS/LITERAL_PUBLIC"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='callSomeMethod']]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='callSomeMethod']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='callSomeMethod']]/MODIFIERS/LITERAL_PUBLIC"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -100,18 +100,18 @@ public void testVariableDef() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='callSomeMethod']/SLIST/LITERAL_FOR" - + "/SLIST/VARIABLE_DEF[@text='d']", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='callSomeMethod']/SLIST/LITERAL_FOR" - + "/SLIST/VARIABLE_DEF[@text='d']/MODIFIERS", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='callSomeMethod']/SLIST/LITERAL_FOR" - + "/SLIST/VARIABLE_DEF[@text='d']/TYPE", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='callSomeMethod']/SLIST/LITERAL_FOR" - + "/SLIST/VARIABLE_DEF[@text='d']/TYPE/LITERAL_SHORT"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='callSomeMethod']]/SLIST/LITERAL_FOR/SLIST" + + "/VARIABLE_DEF[./IDENT[@text='d']]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='callSomeMethod']]/SLIST/LITERAL_FOR/SLIST" + + "/VARIABLE_DEF[./IDENT[@text='d']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='callSomeMethod']]/SLIST/LITERAL_FOR/SLIST" + + "/VARIABLE_DEF[./IDENT[@text='d']]/TYPE", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='callSomeMethod']]/SLIST/LITERAL_FOR/SLIST" + + "/VARIABLE_DEF[./IDENT[@text='d']]/TYPE/LITERAL_SHORT"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -123,8 +123,8 @@ public void testLcurly() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/METHOD_DEF[@text='Label']" - + "/SLIST/LITERAL_SWITCH/LCURLY"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='Label']]/SLIST/LITERAL_SWITCH/LCURLY"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -136,8 +136,8 @@ public void testRcurly() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/INSTANCE_INIT" - + "/SLIST/RCURLY"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK" + + "/INSTANCE_INIT/SLIST/RCURLY"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -149,10 +149,10 @@ public void testExpr() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/VARIABLE_DEF[@text='mUse4']/ASSIGN/EXPR", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/VARIABLE_DEF[@text='mUse4']/ASSIGN/EXPR/DOT"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/VARIABLE_DEF[" + + "./IDENT[@text='mUse4']]/ASSIGN/EXPR", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/VARIABLE_DEF[" + + "./IDENT[@text='mUse4']]/ASSIGN/EXPR/DOT"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -164,8 +164,8 @@ public void testLparen() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='callSomeMethod']/LPAREN"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='callSomeMethod']]/LPAREN"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -199,7 +199,7 @@ public void testImport() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/IMPORT[./DOT[@text='File']]"); + "/IMPORT[2]"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -211,19 +211,19 @@ public void testMethodParams() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='saveUser']/PARAMETERS", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='saveUser']/PARAMETERS/PARAMETER_DEF[@text='name']", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='saveUser']/PARAMETERS/PARAMETER_DEF[@text='name']" - + "/MODIFIERS", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='saveUser']/PARAMETERS/PARAMETER_DEF[@text='name']" - + "/TYPE[@text='String']", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='saveUser']/PARAMETERS/PARAMETER_DEF[@text='name']" - + "/TYPE[@text='String']/IDENT"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='saveUser']]/PARAMETERS", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='saveUser']]/PARAMETERS/PARAMETER_DEF[./IDENT[@text='name']]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='saveUser']]/PARAMETERS/PARAMETER_DEF[./IDENT[@text='name']]" + + "/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='saveUser']]/PARAMETERS/PARAMETER_DEF[./IDENT[@text='name']]" + + "/TYPE[./IDENT[@text='String']]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='saveUser']]/PARAMETERS/PARAMETER_DEF[./IDENT[@text='name']]" + + "/TYPE/IDENT[@text='String']"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -235,8 +235,8 @@ public void testSwitch() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='Label']/SLIST/LITERAL_SWITCH"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='Label']]/SLIST/LITERAL_SWITCH"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -248,10 +248,10 @@ public void testSwitchCase() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/METHOD_DEF[@text='Label']" - + "/SLIST/LITERAL_SWITCH/CASE_GROUP", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/METHOD_DEF[@text='Label']" - + "/SLIST/LITERAL_SWITCH/CASE_GROUP/LITERAL_DEFAULT"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='Label']]/SLIST/LITERAL_SWITCH/CASE_GROUP[1]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='Label']]/SLIST/LITERAL_SWITCH/CASE_GROUP/LITERAL_DEFAULT"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -263,12 +263,12 @@ public void testVariableStringLiteral() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='callSomeMethod']/SLIST/VARIABLE_DEF[@text='another']" - + "/ASSIGN/EXPR", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='callSomeMethod']/SLIST/VARIABLE_DEF[@text='another']" - + "/ASSIGN/EXPR/STRING_LITERAL"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='callSomeMethod']]/SLIST/VARIABLE_DEF[./IDENT[@text='another']]" + + "/ASSIGN/EXPR[./STRING_LITERAL[@text='HelloWorld']]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='callSomeMethod']]/SLIST/VARIABLE_DEF[./IDENT[@text='another']]" + + "/ASSIGN/EXPR/STRING_LITERAL[@text='HelloWorld']"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -280,8 +280,8 @@ public void testComma() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK/METHOD_DEF[@text='foo']" - + "/SLIST/LITERAL_FOR/FOR_ITERATOR/ELIST/COMMA"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='foo']]/SLIST/LITERAL_FOR/FOR_ITERATOR/ELIST/COMMA"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -293,10 +293,10 @@ public void testLiteralVoid() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='foo']/TYPE", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/OBJBLOCK" - + "/METHOD_DEF[@text='foo']/TYPE/LITERAL_VOID"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='foo']]/TYPE", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/OBJBLOCK/METHOD_DEF[" + + "./IDENT[@text='foo']]/TYPE/LITERAL_VOID"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -308,7 +308,7 @@ public void testFirstImport() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/IMPORT[./DOT[@text='JToolBar']]"); + "/IMPORT[1]"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -320,7 +320,19 @@ public void testLastImport() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/IMPORT[./DOT[@text='Iterator']]"); + "/IMPORT[5]"); + assertEquals("Generated queries do not match expected ones", expected, actual); + } + + @Test + public void testImportByValue() { + final int lineNumber = 4; + final int columnNumber = 8; + final XpathQueryGenerator queryGenerator = new XpathQueryGenerator(rootAst, lineNumber, + columnNumber, fileText, DEFAULT_TAB_WIDTH); + final List actual = queryGenerator.generate(); + final List expected = Collections.singletonList( + "/IMPORT/DOT[./IDENT[@text='JToolBar']]/DOT/IDENT[@text='javax']"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -332,7 +344,7 @@ public void testIdent() { columnNumber, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']/IDENT"); + "/CLASS_DEF/IDENT[@text='InputXpathQueryGenerator']"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -350,12 +362,12 @@ public void testTabWidthBeforeMethodDef() throws Exception { columnNumber, testFileText, tabWidth); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGeneratorTabWidth']/OBJBLOCK" - + "/METHOD_DEF[@text='toString']", - "/CLASS_DEF[@text='InputXpathQueryGeneratorTabWidth']/OBJBLOCK" - + "/METHOD_DEF[@text='toString']/MODIFIERS", - "/CLASS_DEF[@text='InputXpathQueryGeneratorTabWidth']/OBJBLOCK" - + "/METHOD_DEF[@text='toString']/MODIFIERS/LITERAL_PUBLIC"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGeneratorTabWidth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='toString']]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGeneratorTabWidth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='toString']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGeneratorTabWidth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='toString']]/MODIFIERS/LITERAL_PUBLIC"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -373,10 +385,10 @@ public void testTabWidthAfterVoidLiteral() throws Exception { columnNumber, testFileText, tabWidth); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGeneratorTabWidth']/OBJBLOCK" - + "/METHOD_DEF[@text='getName']/TYPE", - "/CLASS_DEF[@text='InputXpathQueryGeneratorTabWidth']/OBJBLOCK" - + "/METHOD_DEF[@text='getName']/TYPE/LITERAL_VOID"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGeneratorTabWidth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='getName']]/TYPE", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGeneratorTabWidth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='getName']]/TYPE/LITERAL_VOID"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -394,8 +406,8 @@ public void testTabWidthBeforeSlist() throws Exception { columnNumber, testFileText, tabWidth); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGeneratorTabWidth']/OBJBLOCK" - + "/METHOD_DEF[@text='tabAfterMe']/SLIST"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGeneratorTabWidth']]/OBJBLOCK" + + "/METHOD_DEF[./IDENT[@text='tabAfterMe']]/SLIST"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -413,8 +425,8 @@ public void testTabWidthEndOfLine() throws Exception { columnNumber, testFileText, tabWidth); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGeneratorTabWidth']/OBJBLOCK" - + "/VARIABLE_DEF[@text='endLineTab']/SEMI"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGeneratorTabWidth']]/OBJBLOCK" + + "/VARIABLE_DEF[./IDENT[@text='endLineTab']]/SEMI"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -426,7 +438,7 @@ public void testClassDefWithTokenType() { columnNumber, TokenTypes.CLASS_DEF, fileText, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Collections.singletonList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]"); assertEquals("Generated queries do not match expected ones", expected, actual); } @@ -440,9 +452,9 @@ public void testConstructorWithTreeWalkerAuditEvent() { new XpathQueryGenerator(event, DEFAULT_TAB_WIDTH); final List actual = queryGenerator.generate(); final List expected = Arrays.asList( - "/CLASS_DEF[@text='InputXpathQueryGenerator']", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/MODIFIERS", - "/CLASS_DEF[@text='InputXpathQueryGenerator']/MODIFIERS/LITERAL_PUBLIC"); + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/MODIFIERS", + "/CLASS_DEF[./IDENT[@text='InputXpathQueryGenerator']]/MODIFIERS/LITERAL_PUBLIC"); assertEquals("Generated queries do not match expected ones", expected, actual); } diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/treewalker/InputTreeWalkerSuppressionXpathFilterAbsolute.xml b/src/test/resources/com/puppycrawl/tools/checkstyle/treewalker/InputTreeWalkerSuppressionXpathFilterAbsolute.xml index cdb6bc5cf286..41ee95208853 100644 --- a/src/test/resources/com/puppycrawl/tools/checkstyle/treewalker/InputTreeWalkerSuppressionXpathFilterAbsolute.xml +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/treewalker/InputTreeWalkerSuppressionXpathFilterAbsolute.xml @@ -4,6 +4,6 @@ "https://checkstyle.org/dtds/suppressions_1_2_xpath_experimental.dtd"> + query="/CLASS_DEF[./IDENT[@text='InputTreeWalkerSuppressionXpathFilterAbsolute']]/ + OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/SLIST" /> diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/xpathmapper/InputXpathMapperAnnotation.java b/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/xpathmapper/InputXpathMapperAnnotation.java index e2d86c6d383b..e88216b0c367 100644 --- a/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/xpathmapper/InputXpathMapperAnnotation.java +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/xpathmapper/InputXpathMapperAnnotation.java @@ -1,6 +1,15 @@ package com.puppycrawl.tools.checkstyle.xpath.xpathmapper; -@SuppressWarnings("test") +@Deprecated public class InputXpathMapperAnnotation { + @SuppressWarnings("bad") + public void test1() { + + } + + @SuppressWarnings("good") + public void test2() { + + } } diff --git a/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/xpathmapper/InputXpathMapperPositions.java b/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/xpathmapper/InputXpathMapperPositions.java new file mode 100644 index 000000000000..20a887cf86ca --- /dev/null +++ b/src/test/resources/com/puppycrawl/tools/checkstyle/xpath/xpathmapper/InputXpathMapperPositions.java @@ -0,0 +1,27 @@ +package com.puppycrawl.tools.checkstyle.xpath.xpathmapper; + +import java.util.Date; +import java.util.Scanner; +import java.lang.StringBuilder; +import javax.crypto.Cipher; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.stream.Collectors; + +public class InputXpathMapperPositions { + public void switchMethod() { + int i = 23; + switch (i) { + case 3: + break; + default: + break; + case 1: + break; + case 2: + break; + } + } +} diff --git a/src/xdocs/config_filters.xml b/src/xdocs/config_filters.xml index c20f0acf9d7d..6946b7058ffb 100644 --- a/src/xdocs/config_filters.xml +++ b/src/xdocs/config_filters.xml @@ -889,6 +889,19 @@ public class UserService { all methods with name sayHelloWorld inside FileOne and FileTwo files:

+

+ Currently, xpath queries support one type of attribute @text. + @text - addresses to the value of the node. For example: variable value, + annotation value, text content and etc. + Only the following token types support @text attribute: + TokenTypes.IDENT, TokenTypes.STRING_LITERAL, + TokenTypes.CHAR_LITERAL, TokenTypes.NUM_LONG, + TokenTypes.NUM_INT, TokenTypes.NUM_DOUBLE, + TokenTypes.NUM_FLOAT. + These token types were selected because only their values are useful and can be used + in xpath queries for more accurate results. + Other token types always have constant values. +

<?xml version="1.0"?> @@ -899,7 +912,7 @@ public class UserService { <suppressions> <suppress-xpath checks="CyclomaticComplexity" files="FileOne.java,FileTwo.java" - query="//METHOD_DEF[@text='sayHelloWorld']"/> + query="//METHOD_DEF[./IDENT[@text='sayHelloWorld']]"/> </suppressions>

@@ -925,8 +938,8 @@ public class UserService { Suppress checks for certain methods:

-<suppress-xpath checks=".*" query="//METHOD_DEF[@text='getSomeVar' - or @text='setSomeVar']"/> +<suppress-xpath checks=".*" query="//METHOD_DEF[./IDENT[@text='getSomeVar' + or @text='setSomeVar']]"/>

Suppress checks for variable testVariable inside testMethod method @@ -934,23 +947,24 @@ public class UserService {

<suppress-xpath checks=".*" query="/CLASS_DEF[@text='TestClass'] - //METHOD_DEF[@text='testMethod']//VARIABLE_DEF[@text='testVariable']"/> + //METHOD_DEF[./IDENT[@text='testMethod']] + //VARIABLE_DEF[./IDENT[@text='testVariable']]"/>

In the following sample, violations for LeftCurly check will be suppressed for classes with name Main or for methods with name calculate.

-<suppress-xpath checks="LeftCurly" query="/CLASS_DEF[@text='Main']//* - | //METHOD_DEF[@text='calculate']/*"/> +<suppress-xpath checks="LeftCurly" query="/CLASS_DEF[./IDENT[@text='Main']]//* + | //METHOD_DEF[./IDENT[@text='calculate']]/*"/>

The following example demonstrates how to suppress RequireThis violations for variable age inside changeAge method.

-<suppress-xpath checks="RequireThis" query="/CLASS_DEF[@text='InputTest'] - //METHOD_DEF[@text='changeAge']//ASSIGN[@text='age']/IDENT"/> +<suppress-xpath checks="RequireThis" query="/CLASS_DEF[./IDENT[@text='InputTest']] + //METHOD_DEF[./IDENT[@text='changeAge']]//ASSIGN/IDENT[@text='age']"/> public class InputTest { @@ -970,8 +984,9 @@ public class InputTest { W3Schools Xpath Axes.

-<suppress-xpath checks="IllegalThrows" query="//LITERAL_THROWS/IDENT[ - ..[@text='RuntimeException'] and ./ancestor::METHOD_DEF[@text='throwsMethod']]"/> +<suppress-xpath checks="IllegalThrows" query="//LITERAL_THROWS + /IDENT[@text='RuntimeException' and + ./ancestor::METHOD_DEF[./IDENT[@text='throwsMethod']]]"/> public class InputTest { @@ -990,9 +1005,133 @@ public class InputTest { W3Schools Xpath Syntax.

-<suppress-xpath checks=".*" query="//METHOD_DEF[@text='legacyMethod'] +<suppress-xpath checks=".*" query="//METHOD_DEF[./IDENT[@text='legacyMethod']] /descendant-or-self::node()"/> + +

Some elements can be suppressed by different ways. + For example, to suppress violation on variable wordCount in following code: +

+ +public class InputTest { + private int wordCount = 11; +} + +

You need to look at AST of such code by our CLI tool:

+ +$ java -jar checkstyle-X.XX-all.jar -t InputTest.java +CLASS_DEF -> CLASS_DEF [1:0] +|--MODIFIERS -> MODIFIERS [1:0] +| `--LITERAL_PUBLIC -> public [1:0] +|--LITERAL_CLASS -> class [1:7] +|--IDENT -> InputTest [1:13] +`--OBJBLOCK -> OBJBLOCK [1:23] +|--LCURLY -> { [1:23] +|--VARIABLE_DEF -> VARIABLE_DEF [2:4] +| |--MODIFIERS -> MODIFIERS [2:4] +| | `--LITERAL_PRIVATE -> private [2:4] +| |--TYPE -> TYPE [2:12] +| | `--LITERAL_INT -> int [2:12] +| |--IDENT -> wordCount [2:16] +| |--ASSIGN -> = [2:26] +| | `--EXPR -> EXPR [2:28] +| | `--NUM_INT -> 11 [2:28] +| `--SEMI -> ; [2:30] +`--RCURLY -> } [3:0] + +

The easiest way is to suppress by variable name. As you can see VARIABLE_DEF + node refers to variable declaration statement and has child node with token type + IDENT which is used for storing class, method, variable names.

+

The following example demonstrates how variable can be queried by its name:

+ +<suppress-xpath checks="." query="//VARIABLE_DEF[ + ./IDENT[@text='wordCount']]"/> + +

Another way is to suppress by variable value. Again, if you look at the printed AST tree + above, you will notice that one of the grandchildren of VARIABLE_DEF node is + responsible for storing variable value - NUM_INT with value 11.

+

The following example demonstrates how variable can be queried by its value, same + approach applies to String, char, float, double, int, long data types:

+ +<suppress-xpath checks="." query="//VARIABLE_DEF[.//NUM_INT[@value=11]]"/> + +

Next example is about suppressing method with certain annotation by its value.

+ + public class InputTest { + @Generated("first") // should not be suppressed + public void test1() { + } + + @Generated("second") // should be suppressed + public void test2() { + } + } + +

First of all we need to look at AST tree printed by our CLI tool:

+ +$ java -jar checkstyle-X.XX-all.jar -t InputTest.java +CLASS_DEF -> CLASS_DEF [1:0] +|--MODIFIERS -> MODIFIERS [1:0] +| `--LITERAL_PUBLIC -> public [1:0] +|--LITERAL_CLASS -> class [1:7] +|--IDENT -> InputTest [1:13] +`--OBJBLOCK -> OBJBLOCK [1:23] +|--LCURLY -> { [1:23] +|--METHOD_DEF -> METHOD_DEF [2:4] +| |--MODIFIERS -> MODIFIERS [2:4] +| | |--ANNOTATION -> ANNOTATION [2:4] +| | | |--AT -> @ [2:4] +| | | |--IDENT -> Generated [2:5] +| | | |--LPAREN -> ( [2:14] +| | | |--EXPR -> EXPR [2:15] +| | | | `--STRING_LITERAL -> "first" [2:15] +| | | `--RPAREN -> ) [2:22] +| | `--LITERAL_PUBLIC -> public [3:4] +| |--TYPE -> TYPE [3:11] +| | `--LITERAL_VOID -> void [3:11] +| |--IDENT -> test1 [3:16] +| |--LPAREN -> ( [3:21] +| |--PARAMETERS -> PARAMETERS [3:22] +| |--RPAREN -> ) [3:22] +| `--SLIST -> { [3:24] +| `--RCURLY -> } [4:4] +|--METHOD_DEF -> METHOD_DEF [6:4] +| |--MODIFIERS -> MODIFIERS [6:4] +| | |--ANNOTATION -> ANNOTATION [6:4] +| | | |--AT -> @ [6:4] +| | | |--IDENT -> Generated [6:5] +| | | |--LPAREN -> ( [6:14] +| | | |--EXPR -> EXPR [6:15] +| | | | `--STRING_LITERAL -> "second" [6:15] +| | | `--RPAREN -> ) [6:23] +| | `--LITERAL_PUBLIC -> public [7:4] +| |--TYPE -> TYPE [7:11] +| | `--LITERAL_VOID -> void [7:11] +| |--IDENT -> test2 [7:16] +| |--LPAREN -> ( [7:21] +| |--PARAMETERS -> PARAMETERS [7:22] +| |--RPAREN -> ) [7:22] +| `--SLIST -> { [7:24] +| `--RCURLY -> } [8:4] +`--RCURLY -> } [9:0] + +

AST node ANNOTATION -> ANNOTATION [6:4] has direct child + IDENT -> Generated [6:5], therefore can be queried by IDENT value: +

+ +<suppress-xpath checks="." query="//METHOD_DEF[ + .//ANNOTATION/IDENT[@text='Generated']]"/> + +

The problem with query above that it will suppress violations for all methods with + annotation @Generated. In order to suppress methods with + @Generated("second") annotations only, you need to look at AST tree again. + Value of the ANNOTATION node is stored inside sub-node with token type + STRING_LITERAL. Use the following query to suppress methods with + @Generated("second") annotation:

+ +<suppress-xpath checks="." query="//METHOD_DEF[.//ANNOTATION[ + ./IDENT[@text='Generated'] and .//*[@text='second']]]"/> +