001////////////////////////////////////////////////////////////////////////////////
002// checkstyle: Checks Java source code for adherence to a set of rules.
003// Copyright (C) 2001-2020 the original author or authors.
004//
005// This library is free software; you can redistribute it and/or
006// modify it under the terms of the GNU Lesser General Public
007// License as published by the Free Software Foundation; either
008// version 2.1 of the License, or (at your option) any later version.
009//
010// This library is distributed in the hope that it will be useful,
011// but WITHOUT ANY WARRANTY; without even the implied warranty of
012// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
013// Lesser General Public License for more details.
014//
015// You should have received a copy of the GNU Lesser General Public
016// License along with this library; if not, write to the Free Software
017// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
018////////////////////////////////////////////////////////////////////////////////
019
020package com.puppycrawl.tools.checkstyle.checks.coding;
021
022import com.puppycrawl.tools.checkstyle.StatelessCheck;
023import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
024import com.puppycrawl.tools.checkstyle.api.DetailAST;
025import com.puppycrawl.tools.checkstyle.api.TokenTypes;
026
027/**
028 * <p>
029 *  Checks that enum definition does not contain a trailing comma.
030 *  Rationale: JLS allows trailing commas in arrays and enumerations, but does not allow
031 *  them in other locations. To unify the coding style, the use of trailing commas should
032 *  be prohibited.
033 * </p>
034 * <pre>
035 * enum Foo1 {
036 *   FOO,
037 *   BAR;
038 * }
039 * </pre>
040 * <p>
041 *  The check demands that there should not be any comma after last constant in
042 *  enum definition.
043 * </p>
044 * <pre>
045 * enum Foo1 {
046 *   FOO,
047 *   BAR, //violation
048 * }
049 * </pre>
050 * <p>
051 * To configure the check:
052 * </p>
053 * <pre>
054 * &lt;module name=&quot;NoEnumTrailingComma&quot;/&gt;
055 * </pre>
056 * <p>
057 * Which results in the following violations:
058 * </p>
059 * <pre>
060 * enum Foo1 {
061 *   FOO,
062 *   BAR; //OK
063 * }
064 * enum Foo2 {
065 *   FOO,
066 *   BAR //OK
067 * }
068 * enum Foo3 {
069 *   FOO,
070 *   BAR, //violation
071 * }
072 * enum Foo4 {
073 *   FOO,
074 *   BAR, // violation
075 *   ;
076 * }
077 * enum Foo5 {
078 *   FOO,
079 *   BAR,; // violation
080 * }
081 * enum Foo6 { FOO, BAR,; } // violation
082 * enum Foo7 { FOO, BAR, } // violation
083 * enum Foo8 {
084 *   FOO,
085 *   BAR // OK
086 *   ;
087 * }
088 * enum Foo9 { FOO, BAR; } // OK
089 * enum Foo10 { FOO, BAR } // OK
090 * </pre>
091 * <p>
092 * Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker}
093 * </p>
094 * <p>
095 * Violation Message Keys:
096 * </p>
097 * <ul>
098 * <li>
099 * {@code no.enum.trailing.comma}
100 * </li>
101 * </ul>
102 *
103 * @since 8.29
104 */
105@StatelessCheck
106public class NoEnumTrailingCommaCheck extends AbstractCheck {
107
108    /**
109     * A key is pointing to the warning message text in "messages.properties"
110     * file.
111     */
112    public static final String MSG_KEY = "no.enum.trailing.comma";
113
114    @Override
115    public int[] getDefaultTokens() {
116        return getRequiredTokens();
117    }
118
119    @Override
120    public int[] getAcceptableTokens() {
121        return getRequiredTokens();
122    }
123
124    @Override
125    public int[] getRequiredTokens() {
126        return new int[] {TokenTypes.ENUM_CONSTANT_DEF};
127    }
128
129    @Override
130    public void visitToken(DetailAST detailAST) {
131        final DetailAST nextSibling = detailAST.getNextSibling();
132        if (nextSibling.getType() == TokenTypes.COMMA) {
133            final DetailAST nextToNextSibling = nextSibling.getNextSibling();
134            if (nextToNextSibling.getType() != TokenTypes.ENUM_CONSTANT_DEF) {
135                log(nextSibling, MSG_KEY);
136            }
137        }
138    }
139}