001//////////////////////////////////////////////////////////////////////////////// 002// checkstyle: Checks Java source code for adherence to a set of rules. 003// Copyright (C) 2001-2014 Oliver Burn 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.whitespace; 021 022import com.puppycrawl.tools.checkstyle.api.Check; 023import com.puppycrawl.tools.checkstyle.api.DetailAST; 024import com.puppycrawl.tools.checkstyle.api.TokenTypes; 025 026/** 027 * <p> 028 * Checks that there is no whitespace after a token. 029 * More specifically, it checks that it is not followed by whitespace, 030 * or (if linebreaks are allowed) all characters on the line after are 031 * whitespace. To forbid linebreaks afer a token, set property 032 * allowLineBreaks to false. 033 * </p> 034 * <p> By default the check will check the following operators: 035 * {@link TokenTypes#ARRAY_INIT ARRAY_INIT}, 036 * {@link TokenTypes#BNOT BNOT}, 037 * {@link TokenTypes#DEC DEC}, 038 * {@link TokenTypes#DOT DOT}, 039 * {@link TokenTypes#INC INC}, 040 * {@link TokenTypes#LNOT LNOT}, 041 * {@link TokenTypes#UNARY_MINUS UNARY_MINUS}, 042 * {@link TokenTypes#UNARY_PLUS UNARY_PLUS}. It also supports the operator 043 * {@link TokenTypes#TYPECAST TYPECAST}. 044 * </p> 045 * <p> 046 * An example of how to configure the check is: 047 * </p> 048 * <pre> 049 * <module name="NoWhitespaceAfter"/> 050 * </pre> 051 * <p> An example of how to configure the check to forbid linebreaks after 052 * a {@link TokenTypes#DOT DOT} token is: 053 * </p> 054 * <pre> 055 * <module name="NoWhitespaceAfter"> 056 * <property name="tokens" value="DOT"/> 057 * <property name="allowLineBreaks" value="false"/> 058 * </module> 059 * </pre> 060 * @author Rick Giles 061 * @author lkuehne 062 * @version 1.0 063 */ 064public class NoWhitespaceAfterCheck extends Check 065{ 066 /** Whether whitespace is allowed if the AST is at a linebreak */ 067 private boolean mAllowLineBreaks = true; 068 069 @Override 070 public int[] getDefaultTokens() 071 { 072 return new int[] { 073 TokenTypes.ARRAY_INIT, 074 TokenTypes.INC, 075 TokenTypes.DEC, 076 TokenTypes.UNARY_MINUS, 077 TokenTypes.UNARY_PLUS, 078 TokenTypes.BNOT, 079 TokenTypes.LNOT, 080 TokenTypes.DOT, 081 }; 082 } 083 084 @Override 085 public int[] getAcceptableTokens() 086 { 087 return new int[] { 088 TokenTypes.ARRAY_INIT, 089 TokenTypes.INC, 090 TokenTypes.DEC, 091 TokenTypes.UNARY_MINUS, 092 TokenTypes.UNARY_PLUS, 093 TokenTypes.BNOT, 094 TokenTypes.LNOT, 095 TokenTypes.DOT, 096 TokenTypes.TYPECAST, 097 }; 098 } 099 100 @Override 101 public void visitToken(DetailAST aAST) 102 { 103 DetailAST targetAST = aAST; 104 if (targetAST.getType() == TokenTypes.TYPECAST) { 105 targetAST = targetAST.findFirstToken(TokenTypes.RPAREN); 106 } 107 final String line = getLines()[aAST.getLineNo() - 1]; 108 final int after = 109 targetAST.getColumnNo() + targetAST.getText().length(); 110 111 if ((after >= line.length()) 112 || Character.isWhitespace(line.charAt(after))) 113 { 114 boolean flag = !mAllowLineBreaks; 115 for (int i = after + 1; !flag && (i < line.length()); i++) { 116 if (!Character.isWhitespace(line.charAt(i))) { 117 flag = true; 118 } 119 } 120 if (flag) { 121 log(targetAST.getLineNo(), after, 122 "ws.followed", targetAST.getText()); 123 } 124 } 125 } 126 127 /** 128 * Control whether whitespace is flagged at linebreaks. 129 * @param aAllowLineBreaks whether whitespace should be 130 * flagged at linebreaks. 131 */ 132 public void setAllowLineBreaks(boolean aAllowLineBreaks) 133 { 134 mAllowLineBreaks = aAllowLineBreaks; 135 } 136}