From 49bcb59031c2cb2d0aa2e53124020e3033c1dd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20K=C3=BChne?= Date: Sun, 21 Jul 2002 10:27:32 +0000 Subject: [PATCH] fixed false alarm about unused imports for class array objects (e.g. Vector[].class), reported by Michael Rumpf --- .../puppycrawl/tools/checkstyle/Verifier.java | 34 +++++++++++++++++-- .../com/puppycrawl/tools/checkstyle/java.g | 16 ++++++--- .../tools/checkstyle/InputImport.java | 28 +++++++++++++++ 3 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java index 4769586b0..9f9243c1b 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/Verifier.java @@ -797,6 +797,18 @@ class Verifier void reportReference(String aType) { mReferenced.add(aType); + + // we might have multiple levels of inner classes, + // all of them have to be marked as referenced + + // as an unwanted side effect we also add package names like + // "com", "java", etc., but that probably doesn't hurt + // and could be fixed by getting more info using the classloader + int lastDot = aType.lastIndexOf('.'); + while (lastDot != -1) { + mReferenced.add(aType.substring(0, lastDot)); + lastDot = aType.lastIndexOf('.', lastDot - 1); + } } @@ -1434,9 +1446,7 @@ class Verifier else if (fromPackage(imp.getText(), mPkgName)) { log(imp.getLineNo(), "Redundant import from the same package."); } - else if (!imp.getText().endsWith(".*") - && !mReferenced.contains(basename(imp.getText()))) - { + else if (!isReferencedImport(imp)) { log(imp.getLineNo(), "Unused import - " + imp.getText()); } else if (isIllegalImport(imp.getText())) { @@ -1446,6 +1456,24 @@ class Verifier } } + /** + * Checks is an import statement is referenced. + * @param aImp the import parameter, e.g. "javax.swing.JButton". + * @return if aImp is used by one of the entries in mReferenced. + */ + private boolean isReferencedImport(LineText aImp) + { + if (aImp.getText().endsWith(".*")) { + // we should try to figure out the used classes via classloader + return true; + } + String impText = aImp.getText(); + + return + mReferenced.contains(basename(impText)) + || mReferenced.contains(impText); + } + /** * Checks if an import is from a package that must not be used. * @param aImportText the argument of the import keyword diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g index dc9b9cdc8..e850df630 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/java.g @@ -181,10 +181,12 @@ builtInType identifier : i1:IDENT { - ver.reportReference(i1.getText()); sLastIdentifier = new LineText(i1.getLine(), i1.getColumn(), i1.getText()); } ( DOT^ i2:IDENT {ver.verifyDot(#DOT); sLastIdentifier.appendText("." + i2.getText());} )* + { + ver.reportReference(sLastIdentifier.getText()); + } ; identifierStar @@ -956,9 +958,9 @@ postfixExpression : primaryExpression // start with a primary ( // qualified id (id.id.id.id...) -- build the name - DOT^ {ver.verifyDot(#DOT);} ( IDENT {ver.reportReference(sFirstIdent);} + DOT^ {ver.verifyDot(#DOT);} ( i1:IDENT {sLastIdentifier.appendText("." + i1.getText()); ver.reportReference(sLastIdentifier.getText());} | "this" - | "class" {ver.reportReference(sFirstIdent);} + | "class" {ver.reportReference(sLastIdentifier.getText());} | newExpression | "super" // ClassName.super.field ) @@ -966,7 +968,7 @@ postfixExpression // is the _last_ qualifier. // allow ClassName[].class - | ( lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR);} RBRACK! )+ + | ( lbc:LBRACK^ {#lbc.setType(ARRAY_DECLARATOR); ver.reportReference(sLastIdentifier.getText());} RBRACK! )+ DOT^ "class" {ver.verifyDot(#DOT);} // an array indexing operation @@ -995,7 +997,11 @@ postfixExpression // the basic element of an expression primaryExpression - : i1:IDENT {sFirstIdent = i1.getText();} + : i1:IDENT + { + sFirstIdent = i1.getText(); + sLastIdentifier = new LineText(i1.getLine(), i1.getColumn(), i1.getText()); + } | constant | "true" | "false" diff --git a/src/tests/com/puppycrawl/tools/checkstyle/InputImport.java b/src/tests/com/puppycrawl/tools/checkstyle/InputImport.java index b2fc70555..11806155b 100644 --- a/src/tests/com/puppycrawl/tools/checkstyle/InputImport.java +++ b/src/tests/com/puppycrawl/tools/checkstyle/InputImport.java @@ -13,10 +13,18 @@ import java.sql.Connection; import java.util.List; import java.util.List; import sun.net.ftpclient.FtpClient; +import java.util.Iterator; +import java.util.Enumeration; +import java.util.Arrays; +import javax.swing.JToolBar; +import javax.swing.JToggleButton; +import javax.swing.ScrollPaneLayout; +import javax.swing.BorderFactory; /** * Test case for imports * @author Oliver Burn + * @author lkuehne **/ class InputImport { @@ -25,5 +33,25 @@ class InputImport /** ignore **/ private Class mUse2 = java.io.File.class; /** ignore **/ + private Class mUse3 = Iterator[].class; + /** ignore **/ + private Class mUse4 = java.util.Enumeration[].class; + /** usage of illegal import **/ private FtpClient ftpClient = null; + + /** usage via static method, both normal and fully qualified */ + { + int[] x = {}; + Arrays.sort(x); + Object obj = javax.swing.BorderFactory.createEmptyBorder(); + } + + /** usage of inner class as type */ + private JToolBar.Separator mSep = null; + + /** usage of inner class in Constructor */ + private Object mUse5 = new ScrollPaneLayout.UIRessource(); + + /** usage of inner class in constructor, fully qualified */ + private Object mUse6 = new javax.swing.JToggleButton.ToggleButtonModel(); }