1 ///////////////////////////////////////////////////////////////////////////////////////////////
2 // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3 // Copyright (C) 2001-2026 the original author or authors.
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ///////////////////////////////////////////////////////////////////////////////////////////////
19
20 package com.puppycrawl.tools.checkstyle.checks.javadoc;
21
22 import javax.annotation.Nullable;
23
24 import com.puppycrawl.tools.checkstyle.FileStatefulCheck;
25 import com.puppycrawl.tools.checkstyle.api.DetailNode;
26 import com.puppycrawl.tools.checkstyle.api.JavadocCommentsTokenTypes;
27 import com.puppycrawl.tools.checkstyle.utils.JavadocUtil;
28
29 /**
30 * <div>
31 * Checks that multiple {@code @throws} and {@code @exception} Javadoc tags are listed
32 * alphabetically by exception name.
33 * </div>
34 *
35 * @since 14.1.0
36 */
37 @FileStatefulCheck
38 public class JavadocThrowsOrderCheck extends AbstractJavadocCheck {
39
40 /**
41 * A key is pointing to the warning message text in "messages.properties" file.
42 */
43 public static final String MSG_KEY = "javadoc.throws.order";
44
45 /** The greatest exception name found so far in the current Javadoc tree. */
46 @Nullable
47 private String previousExceptionName;
48
49 /**
50 * Creates a new {@code JavadocThrowsOrderCheck} instance.
51 */
52 public JavadocThrowsOrderCheck() {
53 // no code by default
54 }
55
56 @Override
57 public int[] getDefaultJavadocTokens() {
58 return getRequiredJavadocTokens();
59 }
60
61 @Override
62 public int[] getRequiredJavadocTokens() {
63 return new int[] {
64 JavadocCommentsTokenTypes.THROWS_BLOCK_TAG,
65 JavadocCommentsTokenTypes.EXCEPTION_BLOCK_TAG,
66 };
67 }
68
69 @Override
70 public void visitJavadocToken(DetailNode ast) {
71 final DetailNode identifier = JavadocUtil.findFirstToken(
72 ast, JavadocCommentsTokenTypes.IDENTIFIER);
73
74 if (identifier != null) {
75 final String exceptionName = identifier.getText();
76 final String previousName = previousExceptionName;
77 if (previousName != null && exceptionName.compareTo(previousName) < 0) {
78 final String tagName = getTagName(ast);
79 log(ast, MSG_KEY, tagName, exceptionName, previousName);
80 }
81 else {
82 previousExceptionName = exceptionName;
83 }
84 }
85 }
86
87 @Override
88 public void beginJavadocTree(DetailNode rootAst) {
89 previousExceptionName = null;
90 }
91
92 /**
93 * Gets the tag name from a throws or exception block tag.
94 *
95 * @param ast throws or exception block tag
96 * @return tag name
97 */
98 private static String getTagName(DetailNode ast) {
99 return JavadocUtil.findFirstToken(ast, JavadocCommentsTokenTypes.TAG_NAME).getText();
100 }
101
102 }