1 /////////////////////////////////////////////////////////////////////////////////////////////// 2 // checkstyle: Checks Java source code and other text files for adherence to a set of rules. 3 // Copyright (C) 2001-2024 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.naming; 21 22 import com.puppycrawl.tools.checkstyle.api.DetailAST; 23 import com.puppycrawl.tools.checkstyle.api.TokenTypes; 24 import com.puppycrawl.tools.checkstyle.utils.ScopeUtil; 25 26 /** 27 * <div> 28 * Checks that constant names conform to a specified pattern. 29 * A <em>constant</em> is a <strong>static</strong> and <strong>final</strong> 30 * field or an interface/annotation field, except 31 * <strong>serialVersionUID</strong> and <strong>serialPersistentFields 32 * </strong>. 33 * </div> 34 * 35 * <ul> 36 * <li> 37 * Property {@code applyToPackage} - Control if check should apply to package-private members. 38 * Type is {@code boolean}. 39 * Default value is {@code true}. 40 * </li> 41 * <li> 42 * Property {@code applyToPrivate} - Control if check should apply to private members. 43 * Type is {@code boolean}. 44 * Default value is {@code true}. 45 * </li> 46 * <li> 47 * Property {@code applyToProtected} - Control if check should apply to protected members. 48 * Type is {@code boolean}. 49 * Default value is {@code true}. 50 * </li> 51 * <li> 52 * Property {@code applyToPublic} - Control if check should apply to public members. 53 * Type is {@code boolean}. 54 * Default value is {@code true}. 55 * </li> 56 * <li> 57 * Property {@code format} - Sets the pattern to match valid identifiers. 58 * Type is {@code java.util.regex.Pattern}. 59 * Default value is {@code "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"}. 60 * </li> 61 * </ul> 62 * 63 * <p> 64 * Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker} 65 * </p> 66 * 67 * <p> 68 * Violation Message Keys: 69 * </p> 70 * <ul> 71 * <li> 72 * {@code name.invalidPattern} 73 * </li> 74 * </ul> 75 * 76 * @since 3.0 77 */ 78 public class ConstantNameCheck 79 extends AbstractAccessControlNameCheck { 80 81 /** Creates a new {@code ConstantNameCheck} instance. */ 82 public ConstantNameCheck() { 83 super("^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"); 84 } 85 86 @Override 87 public int[] getDefaultTokens() { 88 return getRequiredTokens(); 89 } 90 91 @Override 92 public int[] getAcceptableTokens() { 93 return getRequiredTokens(); 94 } 95 96 @Override 97 public int[] getRequiredTokens() { 98 return new int[] {TokenTypes.VARIABLE_DEF}; 99 } 100 101 @Override 102 protected final boolean mustCheckName(DetailAST ast) { 103 boolean returnValue = false; 104 105 final DetailAST modifiersAST = 106 ast.findFirstToken(TokenTypes.MODIFIERS); 107 final boolean isStaticFinal = 108 modifiersAST.findFirstToken(TokenTypes.LITERAL_STATIC) != null 109 && modifiersAST.findFirstToken(TokenTypes.FINAL) != null 110 || ScopeUtil.isInAnnotationBlock(ast) 111 || ScopeUtil.isInInterfaceBlock(ast); 112 if (isStaticFinal && shouldCheckInScope(modifiersAST) 113 && !ScopeUtil.isInCodeBlock(ast)) { 114 // Handle the serialVersionUID and serialPersistentFields constants 115 // which are used for Serialization. Cannot enforce rules on it. :-) 116 final DetailAST nameAST = ast.findFirstToken(TokenTypes.IDENT); 117 if (!"serialVersionUID".equals(nameAST.getText()) 118 && !"serialPersistentFields".equals(nameAST.getText())) { 119 returnValue = true; 120 } 121 } 122 123 return returnValue; 124 } 125 126 }