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; 026import com.puppycrawl.tools.checkstyle.utils.CommonUtil; 027import com.puppycrawl.tools.checkstyle.utils.JavadocUtil; 028import com.puppycrawl.tools.checkstyle.utils.TokenUtil; 029 030/** 031 * <p> 032 * Checks for illegal tokens. By default labels are prohibited. 033 * </p> 034 * <p> 035 * Rationale: Certain language features can harm readability, lead to 036 * confusion or are not obvious to novice developers. Other features 037 * may be discouraged in certain frameworks, such as not having 038 * native methods in Enterprise JavaBeans components. 039 * </p> 040 * <ul> 041 * <li> 042 * Property {@code tokens} - tokens to check 043 * Type is {@code int[]}. 044 * Default value is: 045 * <a href="https://checkstyle.org/apidocs/com/puppycrawl/tools/checkstyle/api/TokenTypes.html#LABELED_STAT"> 046 * LABELED_STAT</a>. 047 * </li> 048 * </ul> 049 * <p> 050 * To configure the check: 051 * </p> 052 * <pre> 053 * <module name="IllegalToken"/> 054 * </pre> 055 * <p>Example:</p> 056 * <pre> 057 * public void myTest() { 058 * outer: // violation 059 * for (int i = 0; i < 5; i++) { 060 * if (i == 1) { 061 * break outer; 062 * } 063 * } 064 * } 065 * </pre> 066 * <p> 067 * To configure the check to report violation on token LITERAL_NATIVE: 068 * </p> 069 * <pre> 070 * <module name="IllegalToken"> 071 * <property name="tokens" value="LITERAL_NATIVE"/> 072 * </module> 073 * </pre> 074 * <p>Example:</p> 075 * <pre> 076 * public native void myTest(); // violation 077 * </pre> 078 * <p> 079 * Parent is {@code com.puppycrawl.tools.checkstyle.TreeWalker} 080 * </p> 081 * <p> 082 * Violation Message Keys: 083 * </p> 084 * <ul> 085 * <li> 086 * {@code illegal.token} 087 * </li> 088 * </ul> 089 * 090 * @since 3.2 091 */ 092@StatelessCheck 093public class IllegalTokenCheck 094 extends AbstractCheck { 095 096 /** 097 * A key is pointing to the warning message text in "messages.properties" 098 * file. 099 */ 100 public static final String MSG_KEY = "illegal.token"; 101 102 @Override 103 public int[] getDefaultTokens() { 104 return new int[] { 105 TokenTypes.LABELED_STAT, 106 }; 107 } 108 109 @Override 110 public int[] getAcceptableTokens() { 111 return TokenUtil.getAllTokenIds(); 112 } 113 114 @Override 115 public int[] getRequiredTokens() { 116 return CommonUtil.EMPTY_INT_ARRAY; 117 } 118 119 @Override 120 public boolean isCommentNodesRequired() { 121 return true; 122 } 123 124 @Override 125 public void visitToken(DetailAST ast) { 126 log( 127 ast, 128 MSG_KEY, 129 convertToString(ast) 130 ); 131 } 132 133 /** 134 * Converts given AST node to string representation. 135 * 136 * @param ast node to be represented as string 137 * @return string representation of AST node 138 */ 139 private static String convertToString(DetailAST ast) { 140 final String tokenText; 141 switch (ast.getType()) { 142 case TokenTypes.LABELED_STAT: 143 tokenText = ast.getFirstChild().getText() + ast.getText(); 144 break; 145 // multiline tokens need to become singlelined 146 case TokenTypes.COMMENT_CONTENT: 147 tokenText = JavadocUtil.escapeAllControlChars(ast.getText()); 148 break; 149 default: 150 tokenText = ast.getText(); 151 break; 152 } 153 return tokenText; 154 } 155 156}