Source code: com/puppycrawl/tools/checkstyle/checks/ModifierOrderCheck.java
1 ////////////////////////////////////////////////////////////////////////////////
2 // checkstyle: Checks Java source code for adherence to a set of rules.
3 // Copyright (C) 2001-2003 Oliver Burn
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;
21
22 import antlr.collections.AST;
23
24 import java.util.List;
25 import java.util.ArrayList;
26 import java.util.Iterator;
27
28 import com.puppycrawl.tools.checkstyle.api.Check;
29 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
30 import com.puppycrawl.tools.checkstyle.api.DetailAST;
31
32 /**
33 * <p>
34 * Checks that the order of modifiers conforms to the suggestions in the
35 * <a
36 * href="http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html">
37 * Java Language specification, sections 8.1.1, 8.3.1 and 8.4.3</a>.
38 * The correct order is:</p>
39
40 <ol>
41 <li><span class="code">public</span></li>
42 <li><span class="code">protected</span></li>
43
44 <li><span class="code">private</span></li>
45 <li><span class="code">abstract</span></li>
46 <li><span class="code">static</span></li>
47 <li><span class="code">final</span></li>
48 <li><span class="code">transient</span></li>
49 <li><span class="code">volatile</span></li>
50
51 <li><span class="code">synchronized</span></li>
52 <li><span class="code">native</span></li>
53 <li><span class="code">strictfp</span></li>
54 </ol>
55 * <p>
56 * Rationale: Code is easier to read if everybody follows
57 * a standard.
58 * </p>
59 * <p>
60 * An example of how to configure the check is:
61 * </p>
62 * <pre>
63 * <module name="ModifierOrder"/>
64 * </pre>
65 * @author Lars Kühne
66 */
67 public class ModifierOrderCheck
68 extends Check
69 {
70 /**
71 * The order of modifiers as suggested in sections 8.1.1,
72 * 8.3.1 and 8.4.3 of the JLS.
73 */
74 private static final String[] JLS_ORDER =
75 {
76 "public", "protected", "private", "abstract", "static", "final",
77 "transient", "volatile", "synchronized", "native", "strictfp",
78 };
79
80 /** @see com.puppycrawl.tools.checkstyle.api.Check */
81 public int[] getDefaultTokens()
82 {
83 return new int[] {TokenTypes.MODIFIERS};
84 }
85
86 /** @see com.puppycrawl.tools.checkstyle.api.Check */
87 public void visitToken(DetailAST aAST)
88 {
89 final List mods = new ArrayList();
90 AST modifier = aAST.getFirstChild();
91 while (modifier != null) {
92 mods.add(modifier);
93 modifier = modifier.getNextSibling();
94 }
95
96 if (!mods.isEmpty()) {
97 final DetailAST error = checkOrderSuggestedByJLS(mods);
98 if (error != null) {
99 log(error.getLineNo(), error.getColumnNo(),
100 "mod.order", error.getText());
101 }
102 }
103 }
104
105
106 /**
107 * Checks if the modifiers were added in the order suggested
108 * in the Java language specification.
109 *
110 * @param aModifiers list of modifier AST tokens
111 * @return null if the order is correct, otherwise returns the offending
112 * * modifier AST.
113 */
114 DetailAST checkOrderSuggestedByJLS(List aModifiers)
115 {
116 int i = 0;
117 DetailAST modifier;
118 final Iterator it = aModifiers.iterator();
119 do {
120 if (!it.hasNext()) {
121 return null;
122 }
123
124 modifier = (DetailAST) it.next();
125 while ((i < JLS_ORDER.length)
126 && !JLS_ORDER[i].equals(modifier.getText()))
127 {
128 i++;
129 }
130 } while (i < JLS_ORDER.length);
131
132 return modifier;
133 }
134 }