From efcb63fd741d3e07f37e986e2d8ab6fe6da8d43b Mon Sep 17 00:00:00 2001 From: Oliver Burn Date: Sat, 5 Jan 2002 13:18:22 +0000 Subject: [PATCH] Added support to check that casts are followed by whitespace, as recommended in the Sun coding standard. Can be turned off with all other whitespace checks. May want to specifically be able to turn off this feature. --- .../puppycrawl/tools/checkstyle/Checker.java | 2 +- .../tools/checkstyle/Configuration.java | 2 +- .../puppycrawl/tools/checkstyle/Verifier.java | 7 +++++++ .../tools/checkstyle/VerifierImpl.java | 17 ++++++++++++++- .../com/puppycrawl/tools/checkstyle/java.g | 21 +++++++++---------- .../tools/checkstyle/CheckerTest.java | 1 + .../tools/checkstyle/InputWhitespace.java | 15 ++++++++++--- 7 files changed, 48 insertions(+), 17 deletions(-) diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Checker.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Checker.java index cf8b1dfcd..7c3ac1fa0 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Checker.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Checker.java @@ -193,7 +193,7 @@ class Checker lines.add(l); } - return (String[]) lines.toArray(new String[] {}); + return (String[]) lines.toArray(new String[0]); } /** diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java index b0af26dc6..9035d013c 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Configuration.java @@ -524,7 +524,7 @@ class Configuration } lines.add(l); } - mHeaderLines = (String[]) lines.toArray(new String[] {}); + mHeaderLines = (String[]) lines.toArray(new String[0]); } /** diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java index 5b84054ed..a626fab6b 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java @@ -105,6 +105,13 @@ interface Verifier **/ void verifyNoWSBefore(MyCommonAST aAST); + /** + * Verify that whitespace IS after an typecast. + * @param aLineNo number of line to check + * @param aColNo column where the cast ends + */ + void verifyWSAfterCast(int aLineNo, int aColNo); + /** * Report the location of a C++ comment. * @param aLineNo the line number diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java index 34e341e10..8ed4d5968 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java @@ -121,7 +121,7 @@ class VerifierImpl { checkImports(); Collections.sort(mMessages); - return (LineText[]) mMessages.toArray(new LineText[] {}); + return (LineText[]) mMessages.toArray(new LineText[0]); } /** @see Verifier **/ @@ -420,6 +420,21 @@ class VerifierImpl } } + /** @see Verifier **/ + public void verifyWSAfterCast(int aLineNo, int aColNo) + { + if (mConfig.isIgnoreWhitespace()) { + return; + } + + final String line = mLines[aLineNo - 1]; + if ((aColNo < line.length()) && + !Character.isWhitespace(line.charAt(aColNo))) + { + log(aLineNo,"cast needs to be followed by whitespace."); + } + } + /** @see Verifier **/ public void reportCppComment(int aLineNo, int aColNo) { diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g index 178ee69a2..d30f0fa64 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g @@ -60,6 +60,7 @@ tokens { } { + final Verifier ver = VerifierSingleton.getInstance(); private static String sFirstIdent = ""; } @@ -165,7 +166,7 @@ builtInType // A (possibly-qualified) java identifier. We start with the first IDENT // and expand its name by adding dots and following IDENTS identifier - : i1:IDENT {VerifierSingleton.getInstance().reportReference(i1.getText());} + : i1:IDENT {ver.reportReference(i1.getText());} ( DOT^ IDENT )* ; @@ -176,9 +177,9 @@ identifierStar ( DOT^ i3:STAR {str += ".*"; star = true;} )? { if (star) { - VerifierSingleton.getInstance().reportStarImport(ln, str); + ver.reportStarImport(ln, str); } else { - VerifierSingleton.getInstance().reportImport(ln, str); + ver.reportImport(ln, str); } } ; @@ -760,14 +761,14 @@ unaryExpressionNotPlusMinus } : // If typecast is built in type, must be numeric operand // Also, no reason to backtrack if type keyword like int, float... - lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] RPAREN! + lpb:LPAREN^ {#lpb.setType(TYPECAST);} builtInTypeSpec[true] rpb:RPAREN! {ver.verifyWSAfterCast(rpb.getLine(), rpb.getColumn());} unaryExpression // Have to backtrack to see if operator follows. If no operator // follows, it's a typecast. No semantic checking needed to parse. // if it _looks_ like a cast, it _is_ a cast; else it's a "(expr)" | (LPAREN classTypeSpec[true] RPAREN unaryExpressionNotPlusMinus)=> - lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] RPAREN! + lp:LPAREN^ {#lp.setType(TYPECAST);} classTypeSpec[true] rpb2:RPAREN! {ver.verifyWSAfterCast(rpb2.getLine(), rpb2.getColumn());} unaryExpressionNotPlusMinus | postfixExpression @@ -779,7 +780,7 @@ postfixExpression : primaryExpression // start with a primary ( // qualified id (id.id.id.id...) -- build the name - DOT^ ( IDENT {VerifierSingleton.getInstance().reportReference(sFirstIdent);} + DOT^ ( IDENT {ver.reportReference(sFirstIdent);} | "this" | "class" | newExpression @@ -948,7 +949,9 @@ options { codeGenBitsetTestThreshold=20; } - +{ + final Verifier ver = VerifierSingleton.getInstance(); +} // OPERATORS QUESTION : '?' ; @@ -1016,9 +1019,6 @@ WS : ( ' ' // Single-line comments SL_COMMENT -{ - Verifier ver = VerifierSingleton.getInstance(); -} : "//" { ver.reportCppComment(getLine(),getColumn() - 3); } (~('\n'|'\r'))* ('\n'|'\r'('\n')?) { @@ -1032,7 +1032,6 @@ ML_COMMENT { int startLine; int startCol; - Verifier ver = VerifierSingleton.getInstance(); } : "/*" { startLine = getLine(); startCol = getColumn() - 3; } (/* '\r' '\n' can be matched in one alternative or by matching diff --git a/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java b/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java index c9e7e6660..c15dc38dc 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java @@ -103,6 +103,7 @@ public class CheckerTest filepath + ":35: 'synchronized' is not proceeded with whitespace.", filepath + ":39: 'catch' is not proceeded with whitespace.", filepath + ":74: 'return' is not proceeded with whitespace.", + filepath + ":86: cast needs to be followed by whitespace.", }; verify(c, filepath, expected); } diff --git a/src/tests/com/puppycrawl/tools/checkstyle/InputWhitespace.java b/src/tests/com/puppycrawl/tools/checkstyle/InputWhitespace.java index e05a2a74b..a7cb23e8a 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/InputWhitespace.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/InputWhitespace.java @@ -44,8 +44,8 @@ class InputWhitespace skip blank lines between comment and code, should be ok **/ - - + + private int mVar4 = 1; @@ -78,5 +78,14 @@ class InputWhitespace return 2; // this is ok } } - + + /** test casts **/ + private void testCasts() + { + Object o = (Object) new Object(); // ok + o = (Object)o; // error + o = (Object) o; // ok + o = (Object) + o; // ok + } }