diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 000000000..220773bd8 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,2 @@ +TEST-com.puppycrawl.tools.checkstyle.*.txt +classes diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..b90bd3b1c --- /dev/null +++ b/ChangeLog @@ -0,0 +1,24 @@ +2001-06-28 Oliver Burn + + * src/checkstyle/com/puppycrawl/tools/checkstyle/java.tree.g: Now report + references associated with ".class" declarations. Bug reported by + Brendan Humphreys. + + * src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java: + Changed package checking to handle "java.lang." imports. + + * build.xml: Updated version to 1.2 + + * src/tests/com/puppycrawl/tools/checkstyle/InputImport.java: Created. + + * src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java: Added test + for imports. + + * src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java: + Now checks for imports from java.lang package. + + * ChangeLog: Introduced its use. + + * Main.java, VerifierImpl.java, CheckStyleTask.java: Now output + messages to standard out, instead of standard error. Makes piping the + output of checkstyle a lot easier. diff --git a/build.xml b/build.xml index d7b9fc62e..580967dd0 100644 --- a/build.xml +++ b/build.xml @@ -4,7 +4,7 @@ - + diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/.cvsignore b/src/checkstyle/com/puppycrawl/tools/checkstyle/.cvsignore new file mode 100644 index 000000000..b891726e5 --- /dev/null +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/.cvsignore @@ -0,0 +1 @@ +GeneratedJava*.java diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java index c74b974bd..be193a759 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/CheckStyleTask.java @@ -135,20 +135,20 @@ public class CheckStyleTask { mProps.setProperty(RELAX_JAVADOC_PROP, "" + aRelax); } - + /** @param aIgnore whether to ignore import statements **/ public void setIgnoreImports(boolean aIgnore) { mProps.setProperty(IGNORE_IMPORTS_PROP, "" + aIgnore); } - + //////////////////////////////////////////////////////////////////////////// // The doers //////////////////////////////////////////////////////////////////////////// /** * Actually checks the files specified. All errors are reported to - * System.err. Will fail if any errors occurred. + * System.out. Will fail if any errors occurred. * @throws BuildException an error occurred **/ public void execute() @@ -163,7 +163,7 @@ public class CheckStyleTask // Create the checker Checker c; try { - c = new Checker(mProps, System.err); + c = new Checker(mProps, System.out); } catch (RESyntaxException e){ e.printStackTrace(); diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java index 7339c75eb..81775a97e 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Main.java @@ -39,12 +39,12 @@ public final class Main Checker c = null; try { - c = new Checker(System.getProperties(), System.err); + c = new Checker(System.getProperties(), System.out); } catch (RESyntaxException rese) { - System.err.println("Unable to create an regexp object: " + + System.out.println("Unable to create an regexp object: " + rese.getMessage()); - rese.printStackTrace(System.err); + rese.printStackTrace(System.out); System.exit(1); } @@ -59,7 +59,7 @@ public final class Main /** Prints the usage information. **/ private static void usage() { - System.err.println( + System.out.println( "Usage: java " + com.puppycrawl.tools.checkstyle.Main.class.getName() + " file..."); System.exit(1); diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java index c96677d8b..339c46f58 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/VerifierImpl.java @@ -68,7 +68,7 @@ class VerifierImpl /** tracks the level of block definitions for methods **/ private int mMethodBlockLevel = 0; - + /** the messages being logged **/ private final List mMessages = new ArrayList(); @@ -123,7 +123,7 @@ class VerifierImpl private final boolean mRelaxJavadoc; /** whether to process imports **/ private final boolean mCheckImports; - + /** the header lines to check for **/ private final String[] mHeaderLines; /** line number to ignore in header **/ @@ -459,7 +459,7 @@ class VerifierImpl { mReferenced.add(aType); } - + /** @see Verifier **/ public void reportImport(int aLineNo, String aType) { @@ -473,11 +473,18 @@ class VerifierImpl "Duplicate import to line " + lt.getLineNo() + "."); } } - } - mImports.add(new LineText(aLineNo, aType)); + // Check for import from java.lang package. + if (aType.startsWith("java.lang.")) { + log(aLineNo, "Redundant import from the java.lang package."); + } + else { + // Add to list to check for duplicates and usage + mImports.add(new LineText(aLineNo, aType)); + } + } } - + /** @see Verifier **/ public void reportStarImport(int aLineNo, String aPkg) { @@ -485,31 +492,31 @@ class VerifierImpl log(aLineNo, "Avoid using the '.*' form of import."); } } - + /** @see Verifier **/ public void reportStartTypeBlock(boolean aIsInterface) { mInInterface.push(new Boolean(aIsInterface)); } - + /** @see Verifier **/ public void reportEndTypeBlock() { mInInterface.pop(); } - + /** @see Verifier **/ public void reportStartMethodBlock() { mMethodBlockLevel++; } - + /** @see Verifier **/ public void reportEndMethodBlock() { mMethodBlockLevel--; } - + //////////////////////////////////////////////////////////////////////////// // Private methods @@ -528,9 +535,9 @@ class VerifierImpl retVal = new RE(aPattern); } catch (RESyntaxException e) { - System.err.println("Failed to initialise regexp expression " + + System.out.println("Failed to initialise regexp expression " + aPattern); - e.printStackTrace(System.err); + e.printStackTrace(System.out); System.exit(1); } return retVal; @@ -783,13 +790,14 @@ class VerifierImpl return (i == -1) ? aType : aType.substring(i + 1); } - /** Check for imports that are unused. **/ + /** Check the imports that are unused or unrequired. **/ private void checkImports() { if (!mCheckImports) { return; } + // Loop checking for unused imports final Iterator it = mImports.iterator(); while (it.hasNext()) { final LineText imp = (LineText) it.next(); diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.tree.g b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.tree.g index 8880f4d74..7ba473ecd 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.tree.g +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.tree.g @@ -37,6 +37,8 @@ options { { Verifier ver = VerifierSingleton.getInstance(); + // Used in primaryExpression + MyCommonAST firstExprIdent = null; } compilationUnit @@ -414,35 +416,35 @@ expr | #("instanceof" expr expr) // Java ensures surrounded by WS! | #(UNARY_MINUS expr) { ver.verifyNoWSAfter(#UNARY_MINUS); } | #(UNARY_PLUS expr) { ver.verifyNoWSAfter(#UNARY_PLUS); } - | primaryExpression + | primaryExpression ; primaryExpression - : IDENT - | #( DOT - ( expr - ( IDENT - | arrayIndex - | "this" - | "class" - | #( "new" IDENT elist ) - ) - | #(ARRAY_DECLARATOR type) - | builtInType ("class")? - ) - ) - | arrayIndex - | #(METHOD_CALL primaryExpression elist) - | #(TYPECAST typeSpec expr) - | newExpression - | constant - | "super" - | "true" - | "false" - | "this" - | "null" - | typeSpec // type name used with instanceof - ; + : i1:IDENT { firstExprIdent = i1;} + | #( DOT + (expr + (i2:IDENT { firstExprIdent = null;} + | arrayIndex + | "this" + | "class" { if (firstExprIdent != null) { ver.reportReference(firstExprIdent.getText()); } } + | #( "new" IDENT elist ) + ) + | #(ARRAY_DECLARATOR type) + | builtInType ("class")? + ) + ) + | arrayIndex + | #(METHOD_CALL primaryExpression elist) + | #(TYPECAST typeSpec expr) + | newExpression + | constant + | "super" + | "true" + | "false" + | "this" + | "null" + | typeSpec // type name used with instanceof + ; arrayIndex : #(INDEX_OP primaryExpression expression) diff --git a/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java b/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java index e9a92d2da..1f9c89155 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/CheckerTest.java @@ -14,13 +14,13 @@ public class CheckerTest private final ByteArrayOutputStream mBAOS = new ByteArrayOutputStream(); private final PrintStream mStream = new PrintStream(mBAOS); private final Properties mProps = new Properties(); - + public CheckerTest(String name) { super(name); } - protected void setUp() + protected void setUp() { mProps.setProperty(Checker.HEADER_FILE_PROP, "java.header"); } @@ -42,7 +42,7 @@ public class CheckerTest assertEquals(aExpected.length, errs); } - + public void testWhitespace() throws Exception { @@ -68,34 +68,30 @@ public class CheckerTest { final Checker c = new Checker(mProps, mStream); final String[] expected = { - "InputBraces.java:7: Unused import - java.lang.Class", - "InputBraces.java:8: Duplicate import to line 7.", - "InputBraces.java:8: Unused import - java.lang.Class", - "InputBraces.java:9: Avoid using the '.*' form of import.", - "InputBraces.java:33: 'do' construct must use '{}'s.", - "InputBraces.java:45: 'while' construct must use '{}'s.", - "InputBraces.java:45: ';' is not preceeded with whitespace.", - "InputBraces.java:46: 'while' construct must use '{}'s.", - "InputBraces.java:48: 'while' construct must use '{}'s.", - "InputBraces.java:49: 'if' construct must use '{}'s.", - "InputBraces.java:62: 'for' construct must use '{}'s.", - "InputBraces.java:62: ';' is not preceeded with whitespace.", - "InputBraces.java:63: 'for' construct must use '{}'s.", - "InputBraces.java:65: 'for' construct must use '{}'s.", - "InputBraces.java:66: 'if' construct must use '{}'s.", - "InputBraces.java:85: 'if' construct must use '{}'s.", - "InputBraces.java:85: ';' is not preceeded with whitespace.", - "InputBraces.java:86: 'if' construct must use '{}'s.", + "InputBraces.java:29: 'do' construct must use '{}'s.", + "InputBraces.java:41: 'while' construct must use '{}'s.", + "InputBraces.java:41: ';' is not preceeded with whitespace.", + "InputBraces.java:42: 'while' construct must use '{}'s.", + "InputBraces.java:44: 'while' construct must use '{}'s.", + "InputBraces.java:45: 'if' construct must use '{}'s.", + "InputBraces.java:58: 'for' construct must use '{}'s.", + "InputBraces.java:58: ';' is not preceeded with whitespace.", + "InputBraces.java:59: 'for' construct must use '{}'s.", + "InputBraces.java:61: 'for' construct must use '{}'s.", + "InputBraces.java:62: 'if' construct must use '{}'s.", + "InputBraces.java:81: 'if' construct must use '{}'s.", + "InputBraces.java:81: ';' is not preceeded with whitespace.", + "InputBraces.java:82: 'if' construct must use '{}'s.", + "InputBraces.java:84: 'if' construct must use '{}'s.", + "InputBraces.java:84: 'else' construct must use '{}'s.", "InputBraces.java:88: 'if' construct must use '{}'s.", - "InputBraces.java:88: 'else' construct must use '{}'s.", - "InputBraces.java:92: 'if' construct must use '{}'s.", - "InputBraces.java:97: 'else' construct must use '{}'s.", - "InputBraces.java:102: 'if' construct must use '{}'s.", - "InputBraces.java:103: 'if' construct must use '{}'s." + "InputBraces.java:93: 'else' construct must use '{}'s.", + "InputBraces.java:98: 'if' construct must use '{}'s.", + "InputBraces.java:99: 'if' construct must use '{}'s." }; verify(c, "InputBraces.java", expected); } - + public void testTags() throws Exception { @@ -125,7 +121,7 @@ public class CheckerTest verify(c, "InputTags.java", expected); } - + public void testInner() throws Exception { @@ -205,7 +201,7 @@ public class CheckerTest }; verify(c, "InputPublicOnly.java", expected); } - + public void testRelaxedJavadoc() throws Exception { @@ -230,7 +226,7 @@ public class CheckerTest "InputPublicOnly.java:84: method is missing a Javadoc comment." }; verify(c, "InputPublicOnly.java", expected); - } + } public void testHeader() throws Exception @@ -244,4 +240,19 @@ public class CheckerTest }; verify(c, "inputHeader.java", expected); } + + public void testImport() + throws Exception + { + final Checker c = new Checker(mProps, mStream); + assertNotNull(c); + final String[] expected = { + "InputImport.java:7: Unused import - java.util.List", + "InputImport.java:8: Duplicate import to line 7.", + "InputImport.java:8: Unused import - java.util.List", + "InputImport.java:9: Avoid using the '.*' form of import.", + "InputImport.java:10: Redundant import from the java.lang package.", + }; + verify(c, "InputImport.java", expected); + } } diff --git a/src/tests/com/puppycrawl/tools/checkstyle/InputBraces.java b/src/tests/com/puppycrawl/tools/checkstyle/InputBraces.java index b40d460f4..7fc17bff2 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/InputBraces.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/InputBraces.java @@ -4,10 +4,6 @@ //////////////////////////////////////////////////////////////////////////////// package com.puppycrawl.tools.checkstyle; -import java.lang.Class; // ignore -import java.lang.Class; // ignore -import java.io.*; // ignore - /** * Test case for correct use of braces. * @author Oliver Burn diff --git a/src/tests/com/puppycrawl/tools/checkstyle/InputImport.java b/src/tests/com/puppycrawl/tools/checkstyle/InputImport.java new file mode 100644 index 000000000..fe15bcdd6 --- /dev/null +++ b/src/tests/com/puppycrawl/tools/checkstyle/InputImport.java @@ -0,0 +1,23 @@ +//////////////////////////////////////////////////////////////////////////////// +// Test case file for checkstyle. +// Created: 2001 +//////////////////////////////////////////////////////////////////////////////// +package com.puppycrawl.tools.checkstyle; + +import java.util.List; +import java.util.List; +import java.io.*; +import java.lang.String; +import java.sql.Connection; + +/** + * Test case for imports + * @author Oliver Burn + **/ +class InputImport +{ + /** ignore **/ + private Class mUse1 = Connection.class; + /** ignore **/ + private Class mUse2 = java.io.File.class; +}