Skip to content

Commit c740a00

Browse files
committedOct 5, 2022
Add a check that requires since on @Deprecated
Closes gh-343
1 parent 9610342 commit c740a00

File tree

9 files changed

+192
-0
lines changed

9 files changed

+192
-0
lines changed
 

‎spring-javaformat/spring-javaformat-checkstyle/src/main/java/io/spring/javaformat/checkstyle/SpringConfigurationLoader.java

+1
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class SpringConfigurationLoader {
4949
}
5050

5151
public Collection<FileSetCheck> load(PropertyResolver propertyResolver) {
52+
System.out.println(getClass().getResource("spring-checkstyle.xml"));
5253
Configuration config = loadConfiguration(getClass().getResourceAsStream("spring-checkstyle.xml"),
5354
propertyResolver);
5455
return Arrays.stream(config.getChildren()).filter(this.moduleFactory::nonFiltered).map(this::load)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2017-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.spring.javaformat.checkstyle.check;
18+
19+
import com.puppycrawl.tools.checkstyle.api.DetailAST;
20+
import com.puppycrawl.tools.checkstyle.api.FullIdent;
21+
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
22+
23+
/**
24+
* Checks that {@link Deprecated @Deprecated} annotations follow Spring conventions.
25+
*
26+
* @author Andy Wilkinson
27+
* @since 0.0.35
28+
*/
29+
public class SpringDeprecatedCheck extends AbstractSpringCheck {
30+
31+
@Override
32+
public int[] getAcceptableTokens() {
33+
return new int[] { TokenTypes.ANNOTATION };
34+
}
35+
36+
@Override
37+
public void visitToken(DetailAST ast) {
38+
if (ast.getType() == TokenTypes.ANNOTATION) {
39+
visitAnnotation(ast);
40+
}
41+
}
42+
43+
private void visitAnnotation(DetailAST annotation) {
44+
String text = FullIdent.createFullIdent(annotation.findFirstToken(TokenTypes.AT).getNextSibling()).getText();
45+
if ("Deprecated".equals(text) || "java.lang.Deprecated".equals(text)) {
46+
visitDeprecated(annotation);
47+
}
48+
}
49+
50+
private void visitDeprecated(DetailAST deprecated) {
51+
DetailAST sinceAttribute = findSinceAttribute(deprecated);
52+
if (sinceAttribute == null) {
53+
log(deprecated.getLineNo(), deprecated.getColumnNo(), "deprecated.missingSince");
54+
}
55+
else {
56+
DetailAST expr = sinceAttribute.findFirstToken(TokenTypes.EXPR);
57+
DetailAST sinceLiteral = expr.findFirstToken(TokenTypes.STRING_LITERAL);
58+
if ("\"\"".equals(sinceLiteral.getText())) {
59+
log(deprecated.getLineNo(), deprecated.getColumnNo(), "deprecated.emptySince");
60+
}
61+
}
62+
}
63+
64+
private DetailAST findSinceAttribute(DetailAST deprecated) {
65+
DetailAST child = deprecated.getFirstChild();
66+
while (child != null) {
67+
if (child.getType() == TokenTypes.ANNOTATION_MEMBER_VALUE_PAIR) {
68+
DetailAST attributeIdent = child.findFirstToken(TokenTypes.IDENT);
69+
if (attributeIdent != null && ("since".equals(attributeIdent.getText()))) {
70+
return child;
71+
}
72+
}
73+
child = child.getNextSibling();
74+
}
75+
return null;
76+
}
77+
78+
}

‎spring-javaformat/spring-javaformat-checkstyle/src/main/resources/io/spring/javaformat/checkstyle/check/messages.properties

+2
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ nothis.unexpected=Reference to instance variable ''{0}'' should not use \"this.\
2727
ternary.equalOperator=Ternary operation should use != when testing.
2828
ternary.missingParen=Ternary operation missing parentheses. Use the form \"(a != b) ? y : n\"
2929
leadingwhitespace.incorrect=Indentation should be performed with {0} only.
30+
deprecated.missingSince=@Deprecated has no since attribute.
31+
deprecated.emptySince=@Deprecated has an empty since attribute.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
+DeprecatedBadCase.java:22:1: @Deprecated has no since attribute. [SpringDeprecated]
2+
+DeprecatedBadCase.java:25:9: @Deprecated has no since attribute. [SpringDeprecated]
3+
+DeprecatedBadCase.java:28:9: @Deprecated has an empty since attribute. [SpringDeprecated]
4+
+DeprecatedBadCase.java:33:9: @Deprecated has no since attribute. [SpringDeprecated]
5+
+DeprecatedBadCase.java:36:17: @Deprecated has an empty since attribute. [SpringDeprecated]
6+
+5 errors
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
+0 errors
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE module PUBLIC
3+
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
4+
"https://checkstyle.org/dtds/configuration_1_3.dtd">
5+
<module name="com.puppycrawl.tools.checkstyle.Checker">
6+
<module name="com.puppycrawl.tools.checkstyle.TreeWalker">
7+
<module name="io.spring.javaformat.checkstyle.check.SpringDeprecatedCheck"/>
8+
</module>
9+
</module>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0"?>
2+
<!DOCTYPE module PUBLIC
3+
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
4+
"https://checkstyle.org/dtds/configuration_1_3.dtd">
5+
<module name="com.puppycrawl.tools.checkstyle.Checker">
6+
<module name="com.puppycrawl.tools.checkstyle.TreeWalker">
7+
<module name="io.spring.javaformat.checkstyle.check.SpringDeprecatedCheck"/>
8+
</module>
9+
</module>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2017-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Bad cases for use of {@link Deprecated @Deprecated}.
19+
*
20+
* @author Andy Wilkinson
21+
*/
22+
@Deprecated
23+
public class DeprecatedBadCase {
24+
25+
@java.lang.Deprecated
26+
public static final String SOME_CONSTANT;
27+
28+
@Deprecated(since = "")
29+
public void someMethod() {
30+
31+
}
32+
33+
@Deprecated
34+
private class InnerClass {
35+
36+
@Deprecated(since = "")
37+
private void someInnerMethod() {
38+
39+
}
40+
41+
}
42+
43+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2017-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Valid cases for use of {@link Deprecated @Deprecated}.
19+
*
20+
* @author Andy Wilkinson
21+
*/
22+
@Deprecated(since = "2.0.0")
23+
public class DeprecatedValid {
24+
25+
@Deprecated(since = "1.2.0")
26+
public static final String SOME_CONSTANT;
27+
28+
@Deprecated(since = "1.3.0")
29+
public void someMethod() {
30+
31+
}
32+
33+
@Deprecated(since = "1.2.0")
34+
private class InnerClass {
35+
36+
@Deprecated(since = "1.1.0")
37+
private void someInnerMethod() {
38+
39+
}
40+
41+
}
42+
43+
}

0 commit comments

Comments
 (0)