diff --git a/build.xml b/build.xml
index 895468b47..15e73a5c0 100644
--- a/build.xml
+++ b/build.xml
@@ -161,7 +161,8 @@
paramPattern="^a[A-Z][a-zA-Z0-9]*$"
lcurlyMethod="nl"
lcurlyOther="nlow"
- lcurlyType="nl">
+ lcurlyType="nl"
+ rcurly="alone">
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java
index d8a1eff6d..5e1f7a2ea 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java
@@ -306,24 +306,30 @@ public class CheckStyleTask
mConfig.setCacheFile(aCacheFile.getAbsolutePath());
}
- /** @param aTo the lefy curly placement option for methods **/
+ /** @param aTo the left curly placement option for methods **/
public void setLCurlyMethod(String aTo)
{
mConfig.setLCurlyMethod(extractLeftCurlyOption(aTo));
}
- /** @param aTo the lefy curly placement option for types **/
+ /** @param aTo the left curly placement option for types **/
public void setLCurlyType(String aTo)
{
mConfig.setLCurlyType(extractLeftCurlyOption(aTo));
}
- /** @param aTo the lefy curly placement option for others **/
+ /** @param aTo the left curly placement option for others **/
public void setLCurlyOther(String aTo)
{
mConfig.setLCurlyOther(extractLeftCurlyOption(aTo));
}
+ /** @param aTo the right curly placement option **/
+ public void setRCurly(String aTo)
+ {
+ mConfig.setRCurly(extractRightCurlyOption(aTo));
+ }
+
////////////////////////////////////////////////////////////////////////////
// The doers
////////////////////////////////////////////////////////////////////////////
@@ -545,4 +551,20 @@ public class CheckStyleTask
}
return opt;
}
+
+ /**
+ * @param aFrom String to decode the option from
+ * @return the RightCurlyOption represented by aFrom
+ * @throws BuildException if unable to decode aFrom
+ */
+ private RightCurlyOption extractRightCurlyOption(String aFrom)
+ throws BuildException
+ {
+ final RightCurlyOption opt = RightCurlyOption.decode(aFrom);
+ if (opt == null) {
+ throw new BuildException("Unable to parse '" + aFrom + "'.",
+ location);
+ }
+ return opt;
+ }
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java
index b98bd7c4c..1a2244f01 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java
@@ -156,6 +156,8 @@ public class Configuration
private LeftCurlyOption mLCurlyType = LeftCurlyOption.EOL;
/** where to place left curlies on others **/
private LeftCurlyOption mLCurlyOther = LeftCurlyOption.EOL;
+ /** where to place right curlies **/
+ private RightCurlyOption mRCurly = RightCurlyOption.SAME;
////////////////////////////////////////////////////////////////////////////
// Constructors
@@ -243,6 +245,8 @@ public class Configuration
setLCurlyOther(getLeftCurlyOptionProperty(
aProps, LCURLY_OTHER_PROP,
LeftCurlyOption.EOL, aLog));
+ setRCurly(getRightCurlyOptionProperty(
+ aProps, RCURLY_PROP, RightCurlyOption.SAME, aLog));
}
/**
@@ -817,6 +821,18 @@ public class Configuration
mLCurlyOther = aTo;
}
+ /** @return the right curly placement option **/
+ public RightCurlyOption getRCurly()
+ {
+ return mRCurly;
+ }
+
+ /** @param aTo set the right curly placement option **/
+ public void setRCurly(RightCurlyOption aTo)
+ {
+ mRCurly = aTo;
+ }
+
////////////////////////////////////////////////////////////////////////////
// Private methods
@@ -897,4 +913,32 @@ 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 RightCurlyOption property. If the property is not
+ * defined or cannot be decoded, then a default value is returned.
+ */
+ private static RightCurlyOption getRightCurlyOptionProperty(
+ Properties aProps,
+ String aName,
+ RightCurlyOption aDefault,
+ PrintStream aLog)
+ {
+ RightCurlyOption retVal = aDefault;
+ final String strRep = aProps.getProperty(aName);
+ if (strRep != null) {
+ retVal = RightCurlyOption.decode(strRep);
+ if (retVal == null) {
+ aLog.println("Unable to parse " + aName +
+ " property with value " + strRep +
+ ", defaulting to " + aDefault + ".");
+ }
+ }
+ return retVal;
+ }
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Defn.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Defn.java
index f76e3a983..fb0a3b998 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Defn.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Defn.java
@@ -85,4 +85,6 @@ public interface Defn
String LCURLY_TYPE_PROP = "checkstyle.lcurly.type";
/** property name for lcurly placement for others **/
String LCURLY_OTHER_PROP = "checkstyle.lcurly.other";
+ /** property name for rcurly placement **/
+ String RCURLY_PROP = "checkstyle.rcurly";
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/RightCurlyOption.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/RightCurlyOption.java
new file mode 100644
index 000000000..2280e0646
--- /dev/null
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/RightCurlyOption.java
@@ -0,0 +1,73 @@
+////////////////////////////////////////////////////////////////////////////////
+// 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.util.Map;
+import java.util.HashMap;
+
+/**
+ * Represents the options for placing the right curly brace '}'.
+ *
+ * @author Oliver Burn
+ * @version 1.0
+ */
+public final class RightCurlyOption
+{
+ /** maps from a string representation to an option **/
+ private static final Map STR_TO_OPT = new HashMap();
+
+ /** represents placing the brace alone on a line **/
+ public static final RightCurlyOption ALONE = new RightCurlyOption("alone");
+ /** represents placing the brace on the same line **/
+ public static final RightCurlyOption SAME = new RightCurlyOption("same");
+ /** represents ignoring the placement **/
+ public static final RightCurlyOption IGNORE =
+ new RightCurlyOption("ignore");
+
+ /** the string representation of the option **/
+ private final String mStrRep;
+
+ /**
+ * Creates a new RightCurlyOption instance.
+ * @param aStrRep the string representation
+ */
+ private RightCurlyOption(String aStrRep)
+ {
+ mStrRep = aStrRep.trim().toLowerCase();
+ STR_TO_OPT.put(mStrRep, this);
+ }
+
+ /** @see Object **/
+ public String toString()
+ {
+ return mStrRep;
+ }
+
+ /**
+ * Returns the RightCurlyOption specified by a string representation. If no
+ * option exists then null is returned.
+ * @param aStrRep the String representation to parse
+ * @return the RightCurlyOption value represented by aStrRep,
+ * or null if none exists.
+ */
+ public static RightCurlyOption decode(String aStrRep)
+ {
+ return (RightCurlyOption) STR_TO_OPT.get(aStrRep.trim().toLowerCase());
+ }
+}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java
index 85164bd31..b230b6680 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java
@@ -605,6 +605,27 @@ class Verifier
}
+ /**
+ * Verify the correct placement of the right curly brace.
+ * @param aBrace location of the brace
+ * @param aStartLine line the next statement starts on
+ */
+ void verifyRCurly(MyCommonAST aBrace, int aStartLine)
+ {
+ final RightCurlyOption option = mConfig.getRCurly();
+ if ((mConfig.getRCurly() == RightCurlyOption.SAME)
+ && (aBrace.getLineNo() != aStartLine))
+ {
+ log(aBrace.getLineNo(), "'}' should be on the same line.");
+ }
+ else if ((mConfig.getRCurly() == RightCurlyOption.ALONE)
+ && (aBrace.getLineNo() == aStartLine))
+ {
+ log(aBrace.getLineNo(), "'}' should be alone on a line.");
+ }
+ }
+
+
/**
* Verify that a constructor length is ok.
* @param aLineNo line the constructor block starts at
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g
index abd8e6754..712e055ba 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g
@@ -582,7 +582,14 @@ statement[int[] aType, MyCommonAST[] aCurlies]
warnWhenFollowAmbig = false;
}
:
- ee:"else"! {stmtType[0] = STMT_OTHER; } statement[stmtType, stmtBraces]
+ ee:"else"!
+ {
+ if (stmtType[0] == STMT_COMPOUND) {
+ ver.verifyRCurly(stmtBraces[1], ee.getLine());
+ }
+ stmtType[0] = STMT_OTHER;
+ }
+ statement[stmtType, stmtBraces]
{
ver.verifyWSAroundBegin(ee.getLine(), ee.getColumn(), ee.getText());
if (stmtType[0] == STMT_OTHER) {
@@ -723,33 +730,32 @@ forIter
tryBlock
{
final MyCommonAST[] stmtBraces = new MyCommonAST[2];
+ final MethodSignature ignoreMS = new MethodSignature();
}
: t:"try"^ compoundStatement[stmtBraces]
{
ver.verifyWSAroundBegin(t.getLine(), t.getColumn(), t.getText());
ver.verifyLCurlyOther(t.getLine(), stmtBraces[0]);
}
- (handler)*
- (
- f:"finally"^ compoundStatement[stmtBraces]
+
+ (
+ c:"catch"^ { ver.verifyRCurly(stmtBraces[1], c.getLine()); }
+ LPAREN! parameterDeclaration[ignoreMS] RPAREN! compoundStatement[stmtBraces]
+ {
+ ver.verifyWSAroundBegin(
+ c.getLine(), c.getColumn(), c.getText());
+ ver.verifyLCurlyOther(c.getLine(), stmtBraces[0]);
+ }
+ )*
+
+ (
+ f:"finally"^ { ver.verifyRCurly(stmtBraces[1], f.getLine()); }
+ compoundStatement[stmtBraces]
{ ver.verifyLCurlyOther(f.getLine(), stmtBraces[0]); }
)?
;
-// an exception handler
-handler
-{
- final MyCommonAST[] stmtBraces = new MyCommonAST[2];
-}
- : c:"catch"^ LPAREN! parameterDeclaration[new MethodSignature()] RPAREN! compoundStatement[stmtBraces]
- {
- ver.verifyWSAroundBegin(c.getLine(), c.getColumn(), c.getText());
- ver.verifyLCurlyOther(c.getLine(), stmtBraces[0]);
- }
- ;
-
-
// expressions
// Note that most of these expressions follow the pattern
// thisLevelExpression :
diff --git a/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java b/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java
index 5c9b1e68e..135d43a1b 100644
--- a/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java
+++ b/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java
@@ -45,6 +45,7 @@ public class CheckerTest
mConfig.setLCurlyMethod(LeftCurlyOption.NL);
mConfig.setLCurlyOther(LeftCurlyOption.NLOW);
mConfig.setLCurlyType(LeftCurlyOption.NL);
+ mConfig.setRCurly(RightCurlyOption.ALONE);
}
protected String getPath(String aFilename)
@@ -643,6 +644,7 @@ public class CheckerTest
throws Exception
{
mConfig.setJavadocScope(Scope.NOTHING);
+ mConfig.setRCurly(RightCurlyOption.SAME);
final Checker c = createChecker();
final String filepath = getPath("InputLeftCurlyOther.java");
assertNotNull(c);
@@ -650,9 +652,13 @@ public class CheckerTest
filepath + ":19: '{' should be on the previous line.",
filepath + ":21: '{' should be on the previous line.",
filepath + ":23: '{' should be on the previous line.",
+ filepath + ":25: '}' should be on the same line.",
+ filepath + ":28: '}' should be on the same line.",
filepath + ":30: '{' should be on the previous line.",
filepath + ":34: '{' should be on the previous line.",
+ filepath + ":40: '}' should be on the same line.",
filepath + ":42: '{' should be on the previous line.",
+ filepath + ":44: '}' should be on the same line.",
filepath + ":46: '{' should be on the previous line.",
filepath + ":52: '{' should be on the previous line.",
filepath + ":54: '{' should be on the previous line.",