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 * <module name="NoEnumTrailingComma"/> 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}