diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/CatchBlockOption.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/CatchBlockOption.java
new file mode 100644
index 000000000..42c654fad
--- /dev/null
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/CatchBlockOption.java
@@ -0,0 +1,87 @@
+////////////////////////////////////////////////////////////////////////////////
+// checkstyle: Checks Java source code for adherence to a set of rules.
+// Copyright (C) 2001-2002 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;
+
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Represents the options for a catch block.
+ *
+ * @author Oliver Burn
+ */
+public final class CatchBlockOption implements Serializable
+{
+ /** maps from a string representation to an option **/
+ private static final Map STR_TO_OPT = new HashMap();
+
+ /** represents ignoring catch blocks **/
+ public static final CatchBlockOption IGNORE =
+ new CatchBlockOption("ignore");
+ /** represents requiring some text in the catch block **/
+ public static final CatchBlockOption TEXT = new CatchBlockOption("text");
+ /** represents requiring a statement in the catch block **/
+ public static final CatchBlockOption STMT = new CatchBlockOption("stmt");
+
+ /** the string representation of the option **/
+ private final String mStrRep;
+
+ /**
+ * Creates a new CatchBlockOption instance.
+ * @param aStrRep the string representation
+ */
+ private CatchBlockOption(String aStrRep)
+ {
+ mStrRep = aStrRep.trim().toLowerCase();
+ STR_TO_OPT.put(mStrRep, this);
+ }
+
+ /** @see Object **/
+ public String toString()
+ {
+ return mStrRep;
+ }
+
+ /**
+ * Returns the CatchBlockOption specified by a string representation. If no
+ * option exists then null is returned.
+ * @param aStrRep the String representation to parse
+ * @return the CatchBlockOption value represented by aStrRep,
+ * or null if none exists.
+ */
+ public static CatchBlockOption decode(String aStrRep)
+ {
+ return (CatchBlockOption) STR_TO_OPT.get(aStrRep.trim().toLowerCase());
+ }
+
+ /**
+ * Ensures that we don't get multiple instances of one CatchBlockOption
+ * during deserialization. See Section 3.6 of the Java Object
+ * Serialization Specification for details.
+ *
+ * @return the serialization replacement object
+ * @throws ObjectStreamException if a deserialization error occurs
+ */
+ private Object readResolve() throws ObjectStreamException
+ {
+ return decode(mStrRep);
+ }
+}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java
index 7345731d5..7a7123bde 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java
@@ -645,6 +645,18 @@ public class CheckStyleTask
});
}
+ /** @param aTo the catch block option **/
+ public void setCatchBlock(final String aTo)
+ {
+ mOptionMemory.add(new Runnable()
+ {
+ public void run()
+ {
+ mConfig.setCatchBlock(extractCatchBlockOption(aTo));
+ }
+ });
+ }
+
/** @param aTo the parenthesis padding option **/
public void setParenPad(final String aTo)
{
@@ -657,18 +669,6 @@ public class CheckStyleTask
});
}
- /** @param aAllowed whether empty catch blocks are allowed **/
- public void setAllowEmptyCatch(final boolean aAllowed)
- {
- mOptionMemory.add(new Runnable()
- {
- public void run()
- {
- mConfig.setAllowEmptyCatch(aAllowed);
- }
- });
- }
-
////////////////////////////////////////////////////////////////////////////
// The doers
////////////////////////////////////////////////////////////////////////////
@@ -914,6 +914,22 @@ public class CheckStyleTask
return opt;
}
+ /**
+ * @param aFrom String to decode the option from
+ * @return the CatchBlockOption represented by aFrom
+ * @throws BuildException if unable to decode aFrom
+ */
+ private CatchBlockOption extractCatchBlockOption(String aFrom)
+ throws BuildException
+ {
+ final CatchBlockOption opt = CatchBlockOption.decode(aFrom);
+ if (opt == null) {
+ throw new BuildException("Unable to parse '" + aFrom + "'.",
+ location);
+ }
+ return opt;
+ }
+
/**
* @param aFrom String to decode the option from
* @return the PadOption represented by aFrom
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java
index c8682f127..a2e6cbd3a 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java
@@ -186,13 +186,12 @@ public class Configuration
private LeftCurlyOption mLCurlyOther = LeftCurlyOption.EOL;
/** where to place right curlies **/
private RightCurlyOption mRCurly = RightCurlyOption.SAME;
+ /** how to process catch blocks **/
+ private CatchBlockOption mCatchBlock = CatchBlockOption.TEXT;
/** how to pad parenthesis **/
private PadOption mParenPadOption = PadOption.NOSPACE;
- /** whether to allow emtpy exception handlers **/
- private boolean mAllowEmptyCatch = false;
-
////////////////////////////////////////////////////////////////////////////
// Constructors
////////////////////////////////////////////////////////////////////////////
@@ -285,12 +284,13 @@ public class Configuration
LeftCurlyOption.EOL, aLog));
setRCurly(getRightCurlyOptionProperty(
aProps, RCURLY_PROP, RightCurlyOption.SAME, aLog));
+ setCatchBlock(
+ getCatchBlockOptionProperty(
+ aProps, CATCH_BLOCK_PROP, CatchBlockOption.TEXT, aLog));
setParenPadOption(getPadOptionProperty(aProps,
PAREN_PAD_PROP,
PadOption.NOSPACE,
aLog));
- setAllowEmptyCatch(getBooleanProperty(
- aProps, ALLOW_EMPTY_CATCH_PROP, mAllowEmptyCatch));
}
/**
@@ -1005,6 +1005,18 @@ public class Configuration
mRCurly = aTo;
}
+ /** @return the catch block option **/
+ public CatchBlockOption getCatchBlock()
+ {
+ return mCatchBlock;
+ }
+
+ /** @param aTo set the catch block option **/
+ public void setCatchBlock(CatchBlockOption aTo)
+ {
+ mCatchBlock = aTo;
+ }
+
/** @return the parenthesis padding option **/
public PadOption getParenPadOption()
{
@@ -1017,18 +1029,6 @@ public class Configuration
mParenPadOption = aTo;
}
- /** @return whether empty catch blocks are allowed */
- public boolean isAllowEmptyCatch()
- {
- return mAllowEmptyCatch;
- }
-
- /** @param aAllowEmptyCatch whether empty catch blocks are allowed */
- public void setAllowEmptyCatch(boolean aAllowEmptyCatch)
- {
- mAllowEmptyCatch = aAllowEmptyCatch;
- }
-
////////////////////////////////////////////////////////////////////////////
// Private methods
////////////////////////////////////////////////////////////////////////////
@@ -1137,6 +1137,34 @@ public class Configuration
return retVal;
}
+ /**
+ * @param aProps the properties set to use
+ * @param aLog where to log errors to
+ * @param aName the name of the property to parse
+ * @param aDefault the default value to use.
+ *
+ * @return the value of a CatchBlockOption property. If the property is not
+ * defined or cannot be decoded, then a default value is returned.
+ */
+ private static CatchBlockOption getCatchBlockOptionProperty(
+ Properties aProps,
+ String aName,
+ CatchBlockOption aDefault,
+ PrintStream aLog)
+ {
+ CatchBlockOption retVal = aDefault;
+ final String strRep = aProps.getProperty(aName);
+ if (strRep != null) {
+ retVal = CatchBlockOption.decode(strRep);
+ if (retVal == null) {
+ aLog.println("Unable to parse " + aName +
+ " property with value " + strRep +
+ ", defaulting to " + aDefault + ".");
+ }
+ }
+ return retVal;
+ }
+
/**
* @param aProps the properties set to use
* @param aLog where to log errors to
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Defn.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Defn.java
index 4104581dc..fec00e480 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Defn.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Defn.java
@@ -101,6 +101,6 @@ public interface Defn
/** property name for padding around parenthesis **/
String PAREN_PAD_PROP = "checkstyle.paren.pad";
- /** property name for allowing empty exception handlers **/
- String ALLOW_EMPTY_CATCH_PROP = "checkstyle.allow.empty.catch";
+ /** property name for catch block options **/
+ String CATCH_BLOCK_PROP = "checkstyle.catchblock";
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java
index 7ea29ab95..be5ba28bf 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java
@@ -227,7 +227,7 @@ class Verifier
{
log(aSig.getName().getLineNo(),
aSig.getName().getColumnNo(),
- "method name '" + aSig.getName() +
+ "method name '" + aSig.getName().getText() +
"' must match pattern '" + mConfig.getMethodPat() + "'.");
}
@@ -869,15 +869,59 @@ class Verifier
}
/**
- * Report that the parser has found a (potentially empty) catch block.
- * @param aLineNo the line number of the catch keyword
- * @param aColNo the column number of the catch keyword
- * @param aIsEmpty whether the block contains any statement
+ * Report that the parser has found a catch block.
+ * @param aBraces the start and end braces from the catch block
+ * @param aNoStmt whether there are any statements in the block
*/
- void reportCatchBlock(int aLineNo, int aColNo, boolean aIsEmpty)
+ void reportCatchBlock(MyCommonAST[] aBraces, boolean aNoStmt)
{
- if (aIsEmpty && !mConfig.isAllowEmptyCatch()) {
- log(aLineNo, aColNo - 1, "Empty catch block.");
+ if (aNoStmt && (mConfig.getCatchBlock() == CatchBlockOption.STMT)) {
+ log(aBraces[0].getLineNo(),
+ aBraces[0].getColumnNo(),
+ "Must have at least one statement.");
+ }
+ else if (mConfig.getCatchBlock() == CatchBlockOption.TEXT) {
+ if (aBraces[0].getLineNo() == aBraces[1].getLineNo()) {
+ // Handle braces on the same line
+ final String txt = mLines[aBraces[0].getLineNo() - 1]
+ .substring(aBraces[0].getColumnNo() + 1,
+ aBraces[1].getColumnNo());
+ if (txt.trim().length() == 0) {
+ log(aBraces[0].getLineNo(),
+ aBraces[0].getColumnNo(),
+ "Empty catch block.");
+ }
+ }
+ else {
+ // check only whitespace of first & last lines
+ if ((mLines[aBraces[0].getLineNo() - 1]
+ .substring(aBraces[0].getColumnNo() + 1).trim().length()
+ == 0)
+ &&
+ (mLines[aBraces[1].getLineNo() - 1]
+ .substring(0, aBraces[1].getColumnNo()).trim().length()
+ == 0))
+ {
+
+ // Need to check if all lines are also only whitespace
+ boolean isBlank = true;
+ for (int i = aBraces[0].getLineNo();
+ i < (aBraces[1].getLineNo() - 1);
+ i++)
+ {
+ if (mLines[i].trim().length() > 0) {
+ isBlank = false;
+ break;
+ }
+ }
+
+ if (isBlank) {
+ log(aBraces[0].getLineNo(),
+ aBraces[0].getColumnNo(),
+ "Empty catch block.");
+ }
+ }
+ }
}
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g
index 95ee7fb23..06905e731 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g
@@ -754,7 +754,7 @@ tryBlock
{
ver.verifyWSAroundBegin(
c.getLine(), c.getColumn(), c.getText());
- ver.reportCatchBlock(c.getLine(), c.getColumn(), isEmpty[0]);
+ ver.reportCatchBlock(stmtBraces, isEmpty[0]);
ver.verifyLCurlyOther(c.getLine(), stmtBraces[0]);
}
)*