All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck Maven / Gradle / Ivy

Go to download

Checkstyle is a development tool to help programmers write Java code that adheres to a coding standard

There is a newer version: 10.18.1
Show newest version
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2016 the original author or authors.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
////////////////////////////////////////////////////////////////////////////////

package com.puppycrawl.tools.checkstyle.checks.indentation;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashSet;
import java.util.Set;

import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.DetailAST;

/**
 * Checks correct indentation of Java Code.
 *
 * 

* The basic idea behind this is that while * pretty printers are sometimes convenient for reformats of * legacy code, they often either aren't configurable enough or * just can't anticipate how format should be done. Sometimes this is * personal preference, other times it is practical experience. In any * case, this check should just ensure that a minimal set of indentation * rules are followed. *

* *

* Implementation -- * Basically, this check requests visitation for all handled token * types (those tokens registered in the HandlerFactory). When visitToken * is called, a new ExpressionHandler is created for the AST and pushed * onto the handlers stack. The new handler then checks the indentation * for the currently visiting AST. When leaveToken is called, the * ExpressionHandler is popped from the stack. *

* *

* While on the stack the ExpressionHandler can be queried for the * indentation level it suggests for children as well as for other * values. *

* *

* While an ExpressionHandler checks the indentation level of its own * AST, it typically also checks surrounding ASTs. For instance, a * while loop handler checks the while loop as well as the braces * and immediate children. *

*
 *   - handler class -to-> ID mapping kept in Map
 *   - parent passed in during construction
 *   - suggest child indent level
 *   - allows for some tokens to be on same line (ie inner classes OBJBLOCK)
 *     and not increase indentation level
 *   - looked at using double dispatch for getSuggestedChildIndent(), but it
 *     doesn't seem worthwhile, at least now
 *   - both tabs and spaces are considered whitespace in front of the line...
 *     tabs are converted to spaces
 *   - block parents with parens -- for, while, if, etc... -- are checked that
 *     they match the level of the parent
 * 
* * @author jrichard * @author o_sukhodolsky * @author Maikel Steneker * @author maxvetrenko */ public class IndentationCheck extends AbstractCheck { /** * A key is pointing to the warning message text in "messages.properties" * file. */ public static final String MSG_ERROR = "indentation.error"; /** * A key is pointing to the warning message text in "messages.properties" * file. */ public static final String MSG_ERROR_MULTI = "indentation.error.multi"; /** * A key is pointing to the warning message text in "messages.properties" * file. */ public static final String MSG_CHILD_ERROR = "indentation.child.error"; /** * A key is pointing to the warning message text in "messages.properties" * file. */ public static final String MSG_CHILD_ERROR_MULTI = "indentation.child.error.multi"; /** Default indentation amount - based on Sun. */ private static final int DEFAULT_INDENTATION = 4; /** Handlers currently in use. */ private final Deque handlers = new ArrayDeque<>(); /** Instance of line wrapping handler to use. */ private final LineWrappingHandler lineWrappingHandler = new LineWrappingHandler(this); /** Factory from which handlers are distributed. */ private final HandlerFactory handlerFactory = new HandlerFactory(); /** Lines logged as having incorrect indentation. */ private Set incorrectIndentationLines; /** How many tabs or spaces to use. */ private int basicOffset = DEFAULT_INDENTATION; /** How much to indent a case label. */ private int caseIndent = DEFAULT_INDENTATION; /** How far brace should be indented when on next line. */ private int braceAdjustment; /** How far throws should be indented when on next line. */ private int throwsIndent = DEFAULT_INDENTATION; /** How much to indent an array initialization when on next line. */ private int arrayInitIndent = DEFAULT_INDENTATION; /** How far continuation line should be indented when line-wrapping is present. */ private int lineWrappingIndentation = DEFAULT_INDENTATION; /** * Force strict condition in line wrapping case. If value is true, line wrap indent * have to be same as lineWrappingIndentation parameter, if value is false, line wrap indent * have to be not less than lineWrappingIndentation parameter. */ private boolean forceStrictCondition; /** * Get forcing strict condition. * @return forceStrictCondition value. */ public boolean isForceStrictCondition() { return forceStrictCondition; } /** * Set forcing strict condition. * @param value user's value of forceStrictCondition. */ public void setForceStrictCondition(boolean value) { forceStrictCondition = value; } /** * Set the basic offset. * * @param basicOffset the number of tabs or spaces to indent */ public void setBasicOffset(int basicOffset) { this.basicOffset = basicOffset; } /** * Get the basic offset. * * @return the number of tabs or spaces to indent */ public int getBasicOffset() { return basicOffset; } /** * Adjusts brace indentation (positive offset). * * @param adjustmentAmount the brace offset */ public void setBraceAdjustment(int adjustmentAmount) { braceAdjustment = adjustmentAmount; } /** * Get the brace adjustment amount. * * @return the positive offset to adjust braces */ public int getBraceAdjustment() { return braceAdjustment; } /** * Set the case indentation level. * * @param amount the case indentation level */ public void setCaseIndent(int amount) { caseIndent = amount; } /** * Get the case indentation level. * * @return the case indentation level */ public int getCaseIndent() { return caseIndent; } /** * Set the throws indentation level. * * @param throwsIndent the throws indentation level */ public void setThrowsIndent(int throwsIndent) { this.throwsIndent = throwsIndent; } /** * Get the throws indentation level. * * @return the throws indentation level */ public int getThrowsIndent() { return throwsIndent; } /** * Set the array initialisation indentation level. * * @param arrayInitIndent the array initialisation indentation level */ public void setArrayInitIndent(int arrayInitIndent) { this.arrayInitIndent = arrayInitIndent; } /** * Get the line-wrapping indentation level. * * @return the initialisation indentation level */ public int getArrayInitIndent() { return arrayInitIndent; } /** * Get the array line-wrapping indentation level. * * @return the line-wrapping indentation level */ public int getLineWrappingIndentation() { return lineWrappingIndentation; } /** * Set the line-wrapping indentation level. * * @param lineWrappingIndentation the line-wrapping indentation level */ public void setLineWrappingIndentation(int lineWrappingIndentation) { this.lineWrappingIndentation = lineWrappingIndentation; } /** * Log an error message. * * @param line the line number where the error was found * @param key the message that describes the error * @param args the details of the message * * @see java.text.MessageFormat */ public void indentationLog(int line, String key, Object... args) { if (!incorrectIndentationLines.contains(line)) { incorrectIndentationLines.add(line); log(line, key, args); } } /** * Get the width of a tab. * * @return the width of a tab */ public int getIndentationTabWidth() { return getTabWidth(); } @Override public int[] getDefaultTokens() { return getAcceptableTokens(); } @Override public int[] getAcceptableTokens() { return handlerFactory.getHandledTypes(); } @Override public int[] getRequiredTokens() { return getAcceptableTokens(); } @Override public void beginTree(DetailAST ast) { handlerFactory.clearCreatedHandlers(); handlers.clear(); final PrimordialHandler primordialHandler = new PrimordialHandler(this); handlers.push(primordialHandler); primordialHandler.checkIndentation(); incorrectIndentationLines = new HashSet<>(); } @Override public void visitToken(DetailAST ast) { final AbstractExpressionHandler handler = handlerFactory.getHandler(this, ast, handlers.peek()); handlers.push(handler); handler.checkIndentation(); } @Override public void leaveToken(DetailAST ast) { handlers.pop(); } /** * Accessor for the line wrapping handler. * * @return the line wrapping handler */ public LineWrappingHandler getLineWrappingHandler() { return lineWrappingHandler; } /** * Accessor for the handler factory. * * @return the handler factory */ public final HandlerFactory getHandlerFactory() { return handlerFactory; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy