Indentation:

Fixes for several TODO comments.
Added AssignHandler.
This commit is contained in:
Oleg Sukhodolsky 2003-06-14 17:47:41 +00:00
parent 41758923b8
commit e464c231ec
15 changed files with 235 additions and 84 deletions

View File

@ -0,0 +1,82 @@
////////////////////////////////////////////////////////////////////////////////
// checkstyle: Checks Java source code for adherence to a set of rules.
// Copyright (C) 2001-2003 Oliver Burn
//
// 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 com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
/**
* Handler for assignements.
*
* @author o_sukhodolsky
*/
public class AssignHandler extends BlockParentHandler
{
/**
* Construct an instance of this handler with the given indentation check,
* abstract syntax tree, and parent handler.
*
* @param aIndentCheck the indentation check
* @param aAst the abstract syntax tree
* @param aParent the parent handler
*/
public AssignHandler(IndentationCheck aIndentCheck,
DetailAST aAst, ExpressionHandler aParent)
{
super(aIndentCheck, "assign", aAst, aParent);
}
/**
* Check the indentation of the expression we are handling.
*/
public void checkIndentation()
{
IndentLevel expectedLevel = getChildrenExpectedLevel();
// check indentation of assign if it starts line
DetailAST assign = getMainAst();
if (startsLine(assign)
&& !expectedLevel.accept(expandedTabsColumnNo(assign)))
{
logError(assign, "" , expandedTabsColumnNo(assign), expectedLevel);
}
// check indentation of rvalue
DetailAST child = (DetailAST) assign.getFirstChild();
// if this is assign in expression then skip first child,
// because it's lvalue.
if (assign.getParent() != null
&& assign.getParent().getType() == TokenTypes.EXPR)
{
child = (DetailAST) child.getNextSibling();
}
checkExpressionSubtree(child, expectedLevel, false, true);
}
/**
* @return true if indentation should be increased after
* fisrt line in checkLinesIndent()
* false otherwise
*/
protected boolean shouldIncreaseIndent()
{
return false;
}
}

View File

@ -203,7 +203,8 @@ public class BlockParentHandler extends ExpressionHandler
{
return;
}
logError(rcurly, "rcurly", expandedTabsColumnNo(rcurly), curlyLevel());
logError(rcurly, "rcurly", expandedTabsColumnNo(rcurly),
new IndentLevel(curlyLevel()));
}
/**

View File

@ -121,7 +121,8 @@ public abstract class ExpressionHandler
protected final void logError(DetailAST aAst, String aSubtypeName,
int aActualLevel)
{
logError(aAst, aSubtypeName, aActualLevel, getLevel());
logError(aAst, aSubtypeName, aActualLevel,
new IndentLevel(getLevel()));
}
/**
@ -133,13 +134,13 @@ public abstract class ExpressionHandler
* @param aExpectedLevel the expected indent level of the expression
*/
protected final void logError(DetailAST aAst, String aSubtypeName,
int aActualLevel, int aExpectedLevel)
int aActualLevel, IndentLevel aExpectedLevel)
{
String typeStr = (aSubtypeName == "" ? "" : (" " + aSubtypeName));
Object[] args = new Object[] {
mTypeName + typeStr,
new Integer(aActualLevel),
new Integer(aExpectedLevel),
aExpectedLevel,
};
mIndentCheck.indentationLog(aAst.getLineNo(),
"indentation.error",
@ -226,9 +227,7 @@ public abstract class ExpressionHandler
*/
protected final int getLineStart(DetailAST aAst)
{
// TODO: this breaks indentation -- add to tests
String line = mIndentCheck.getLines()[
aAst.getLineNo() - 1];
String line = mIndentCheck.getLines()[aAst.getLineNo() - 1];
return getLineStart(line);
}
@ -263,7 +262,7 @@ public abstract class ExpressionHandler
* fisrt line in checkLinesIndent()
* false otherwise
*/
protected boolean shouldIncraeseIndent()
protected boolean shouldIncreaseIndent()
{
return true;
}
@ -303,11 +302,11 @@ public abstract class ExpressionHandler
// doesn't start the line) then don't indent more, the first
// indentation is absorbed by the nesting
// TODO: shouldIncreseIndent() is a hack, should be removed
// TODO: shouldIncreaseIndent() is a hack, should be removed
// after complete rewriting of checkExpressionSubtree()
if (aFirstLineMatches
|| (aFirstLine > mMainAst.getLineNo() && shouldIncraeseIndent()))
|| (aFirstLine > mMainAst.getLineNo() && shouldIncreaseIndent()))
{
aIndentLevel = new IndentLevel(aIndentLevel,
mIndentCheck.getBasicOffset());

View File

@ -56,6 +56,7 @@ public class HandlerFactory
});
mTypeHandlers.put(new Integer(aType), ctor);
}
///CLOVER:OFF
catch (NoSuchMethodException e) {
throw new RuntimeException("couldn't find ctor for "
+ aHandlerClass);
@ -65,6 +66,7 @@ public class HandlerFactory
+ aHandlerClass,
e);
}
///CLOVER:ON
}
/** creates a HandlerFactory */
@ -92,8 +94,19 @@ public class HandlerFactory
register(TokenTypes.METHOD_CALL, MethodCallHandler.class);
register(TokenTypes.CTOR_CALL, MethodCallHandler.class);
register(TokenTypes.LABELED_STAT, LabelHandler.class);
register(TokenTypes.LABELED_STAT, LabelHandler.class);
register(TokenTypes.STATIC_INIT, StaticInitHandler.class);
register(TokenTypes.ASSIGN, AssignHandler.class);
register(TokenTypes.PLUS_ASSIGN, AssignHandler.class);
register(TokenTypes.MINUS_ASSIGN, AssignHandler.class);
register(TokenTypes.STAR_ASSIGN, AssignHandler.class);
register(TokenTypes.DIV_ASSIGN, AssignHandler.class);
register(TokenTypes.MOD_ASSIGN, AssignHandler.class);
register(TokenTypes.SR_ASSIGN, AssignHandler.class);
register(TokenTypes.BSR_ASSIGN, AssignHandler.class);
register(TokenTypes.SL_ASSIGN, AssignHandler.class);
register(TokenTypes.BAND_ASSIGN, AssignHandler.class);
register(TokenTypes.BXOR_ASSIGN, AssignHandler.class);
register(TokenTypes.BOR_ASSIGN, AssignHandler.class);
}
/**
@ -137,12 +150,15 @@ public class HandlerFactory
public ExpressionHandler getHandler(IndentationCheck aIndentCheck,
DetailAST aAst, ExpressionHandler aParent)
{
int type = aAst.getType();
if (aAst.getType() == TokenTypes.METHOD_CALL) {
return createMethodCallHandler(aIndentCheck, aAst, aParent);
}
Integer type = new Integer(aAst.getType());
ExpressionHandler expHandler = null;
try {
Constructor handlerCtor = (Constructor) mTypeHandlers.get(
new Integer(type));
Constructor handlerCtor = (Constructor) mTypeHandlers.get(type);
if (handlerCtor != null) {
expHandler = (ExpressionHandler) handlerCtor.newInstance(
new Object[] {
@ -153,6 +169,7 @@ public class HandlerFactory
);
}
}
///CLOVER:OFF
catch (InstantiationException e) {
throw new RuntimeException("couldn't instantiate constructor for "
+ aAst, e);
@ -169,6 +186,39 @@ public class HandlerFactory
if (expHandler == null) {
throw new RuntimeException("no handler for type " + type);
}
///CLOVER:ON
return expHandler;
}
/**
* Create new instance of handler for METHOD_CALL.
*
* @param aIndentCheck the indentation check
* @param aAst ast to handle
* @param aParent the handler parent of this AST
*
* @return new instance.
*/
ExpressionHandler createMethodCallHandler(IndentationCheck aIndentCheck,
DetailAST aAst, ExpressionHandler aParent)
{
ExpressionHandler handler =
(ExpressionHandler) mCreatedHandlers.get(aAst);
if (handler != null) {
return handler;
}
DetailAST ast = (DetailAST) aAst.getFirstChild();
while (ast != null && ast.getType() == TokenTypes.DOT) {
ast = (DetailAST) ast.getFirstChild();
}
if (ast != null && ast.getType() == TokenTypes.METHOD_CALL) {
aParent = createMethodCallHandler(aIndentCheck, ast, aParent);
mCreatedHandlers.put(ast, aParent);
}
return new MethodCallHandler(aIndentCheck, aAst, aParent);
}
/** cache for created method call handlers */
private Map mCreatedHandlers = new HashMap();
}

View File

@ -258,7 +258,7 @@ public class IndentationCheck
*
* @return the handler factory
*/
public HandlerFactory getHandlerFactory()
final HandlerFactory getHandlerFactory()
{
return mHandlerFactory;
}

View File

@ -94,10 +94,8 @@ public class MethodCallHandler extends ExpressionHandler
{
// if inside a method call's params, this could be part of
// an expression, so get the previous line's start
if (getParent() instanceof MethodCallHandler) {
MethodCallHandler container = ((MethodCallHandler) getParent())
.findContainingMethodCall(this);
MethodCallHandler container = ((MethodCallHandler) getParent());
if (container != null) {
if (areOnSameLine(container.getMainAst(), getMainAst())) {
return container.getLevel();
@ -110,7 +108,7 @@ public class MethodCallHandler extends ExpressionHandler
// if we get here, we are the child of the left hand side (name
// side) of a method call with no "containing" call, use
// the first non-method callparent
// the first non-method call parent
ExpressionHandler p = getParent();
while (p instanceof MethodCallHandler) {
@ -145,10 +143,6 @@ public class MethodCallHandler extends ExpressionHandler
// walk down the first child part of the dots that make up a method
// call name
// TODO: I'm not convinced this will work yet, what will happen
// when there is a method call in the dots? -- we would have to go
// down that call?
DetailAST ast = (DetailAST) aAst.getFirstChild();
while (ast != null && ast.getType() == TokenTypes.DOT) {
ast = (DetailAST) ast.getFirstChild();
@ -190,40 +184,6 @@ public class MethodCallHandler extends ExpressionHandler
return indentLevel;
}
/**
* Find the handler for the method call that contains the specified child
*
* @param aChild the child
*
* @return the handler that contains the specified child
*/
private MethodCallHandler findContainingMethodCall(
ExpressionHandler aChild)
{
DetailAST firstChild = (DetailAST) getMainAst().getFirstChild();
DetailAST secondChild = (DetailAST) firstChild.getNextSibling();
DetailAST climber = aChild.getMainAst().getParent();
while (climber != null) {
if (climber == firstChild) {
// part of method name
if (getParent() instanceof MethodCallHandler) {
return ((MethodCallHandler) getParent())
.findContainingMethodCall(this);
}
else {
return null;
}
}
else if (climber == secondChild) {
// part of method arguments, this the method the child
// is contained in
return this;
}
climber = climber.getParent();
}
return null;
}
/**
* Check the indentation of the expression we are handling.
*/
@ -262,7 +222,7 @@ public class MethodCallHandler extends ExpressionHandler
* fisrt line in checkLinesIndent()
* false otherwise
*/
protected boolean shouldIncraeseIndent()
protected boolean shouldIncreaseIndent()
{
return false;
}

View File

@ -78,11 +78,11 @@ public class MethodDefHandler extends BlockParentHandler
}
int columnNo = expandedTabsColumnNo(throwsAst);
int expectedColumnNo =
getLevel() + getIndentCheck().getBasicOffset();
IndentLevel expectedColumnNo =
new IndentLevel(getLevel() + getIndentCheck().getBasicOffset());
if (startsLine(throwsAst)
&& columnNo != expectedColumnNo)
&& !expectedColumnNo.accept(columnNo))
{
logError(throwsAst, "throws", columnNo, expectedColumnNo);
}

View File

@ -89,13 +89,7 @@ public class ObjectBlockHandler extends BlockParentHandler
*/
public int getLevelImpl()
{
DetailAST parentAST = getMainAst().getParent();
if (parentAST.getType() != TokenTypes.LITERAL_NEW) {
return getParent().getLevel();
}
else {
return getLineStart(parentAST);
}
return getParent().getLevel();
}
/**

View File

@ -0,0 +1,20 @@
public class InputInvalidAssignIndent
{
void foo(String[] args)
{
String line = mIndentCheck[
getLineNo()];
String line1 =
getLineNo();
line1 =
getLineNo();
int i
=
1;
// TODO: this should be illegal.
i =
3;
// TODO: add more testing
}
}

View File

@ -128,12 +128,12 @@ public class InputInvalidIfIndent {
}
// lcurly for if and else on same line
if (test) {
// TODO: broken
// System.
// getProperty("blah");
System.
getProperty("blah");
} else {
// System. // TODO: broken
// getProperty("blah");
System.
getProperty("blah");
}
// lcurly for if and else on same line

View File

@ -147,7 +147,7 @@ public class InputInvalidMethodIndent {
// getInteger("mytest").intValue(),
// 11);
// TODO: should complain about indentation
System.out.toString()
.equals("blah");

View File

@ -0,0 +1,25 @@
public class InputValidAssignIndent
{
void foo(String[] args)
{
i = 1 +
2 +
3;
String line = mIndentCheck[
getLineNo()];
String line1 =
getLineNo();
line1 =
getLineNo();
int i
=
1;
i = 3;
brace =
(candidate == SLIST)
? candidate : null;
// TODO: add more testing
}
}

View File

@ -46,9 +46,9 @@ public class InputValidDotIndent {
border = new javax.swing.border.
BevelBorder(BevelBorder.LOWERED);
// TODO: enable this when function parameter handling is turned on
// border = new javax.swing.border.BevelBorder(
// BevelBorder.LOWERED);
border = new javax.swing.border.BevelBorder(
BevelBorder.LOWERED);
border = new javax.
swing.
border.

View File

@ -176,7 +176,7 @@ public class InputValidMethodIndent extends java.awt.event.MouseAdapter implemen
+ method1());
System.out.toString()
.equals("blah");
.equals("blah");
if (!areOnSameLine((DetailAST)aChild.expr.getFirstChild(),

View File

@ -115,8 +115,7 @@ public class IndentationCheckTest extends BaseCheckTestCase {
"125: method call rparen at indentation level 6 not at correct indentation, 8",
"139: method call child at indentation level 10 not at correct indentation, 12",
"142: method call child at indentation level 10 not at correct indentation, 12",
// todo: 152 -- 8 should be 12
"152: method call child at indentation level 6 not at correct indentation, 8",
"152: method call child at indentation level 6 not at correct indentation, 12",
"158: method def throws at indentation level 6 not at correct indentation, 8",
};
verify(c, fname, expected);
@ -320,10 +319,6 @@ public class IndentationCheckTest extends BaseCheckTestCase {
"121: class def rcurly at indentation level 10 not at correct indentation, 8",
"124: class def child at indentation level 10 not at correct indentation, 12",
"129: method def child at indentation level 10 not at correct indentation, 8",
"130: object def lcurly at indentation level 8 not at correct indentation, 10",
"131: method def modifier at indentation level 12 not at correct indentation, 14",
"133: method def rcurly at indentation level 12 not at correct indentation, 14",
"134: object def rcurly at indentation level 8 not at correct indentation, 10",
"138: object def lcurly at indentation level 6 not at correct indentation, 8",
"142: object def rcurly at indentation level 6 not at correct indentation, 8",
"147: method def modifier at indentation level 10 not at correct indentation, 12",
@ -438,6 +433,13 @@ public class IndentationCheckTest extends BaseCheckTestCase {
"126: if lcurly at indentation level 10 not at correct indentation, 8",
"127: if child at indentation level 10 not at correct indentation, 12",
"127: method call child at indentation level 10 not at correct indentation, 12",
"132: if child at indentation level 14 not at correct indentation, 12",
// TODO: should be 16, not 12
"133: method call child at indentation level 10 not at correct indentation, 12",
"135: else child at indentation level 10 not at correct indentation, 12",
// TODO: why we get this message (it's duplicate of previous.
"135: method call child at indentation level 10 not at correct indentation, 12",
"136: method call child at indentation level 8 not at correct indentation, 12",
"143: if child at indentation level 16 not at correct indentation, 12",
"144: if rcurly at indentation level 9 not at correct indentation, 8",
"147: else child at indentation level 16 not at correct indentation, 12",
@ -670,5 +672,23 @@ public class IndentationCheckTest extends BaseCheckTestCase {
verify(checkConfig, getPath("indentation/InputBraceAdjustment.java"), expected);
}
public void testInvalidAssignWithChecker() throws Exception
{
final DefaultConfiguration checkConfig = createCheckConfig(IndentationCheck.class);
final String[] expected = {
"6: method call child at indentation level 10 not at correct indentation, 12",
"8: method call child at indentation level 10 not at correct indentation, 12",
"10: method call child at indentation level 10 not at correct indentation, 12",
"12: assign at indentation level 9 not at correct indentation, 12",
"13: assign child at indentation level 10 not at correct indentation, 12",
};
verify(checkConfig, getPath("indentation/InputInvalidAssignIndent.java"), expected);
}
public void testValidAssignWithChecker() throws Exception
{
final DefaultConfiguration checkConfig = createCheckConfig(IndentationCheck.class);
final String[] expected = {};
verify(checkConfig, getPath("indentation/InputValidAssignIndent.java"), expected);
}
}