From bb1db4938ccae0f7149461ea372398fb8a53f2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20K=C3=BChne?= Date: Sun, 3 Aug 2003 13:22:44 +0000 Subject: [PATCH] fixed bug #772832, Confusion about class named 'Boolean' --- docs/releasenotes.html | 10 ++- .../coding/IllegalInstantiationCheck.java | 76 ++++++++++++++++++- 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/docs/releasenotes.html b/docs/releasenotes.html index 1ff6b522d..87163045b 100644 --- a/docs/releasenotes.html +++ b/docs/releasenotes.html @@ -174,10 +174,14 @@ handle all Unicode symbols (bug 755744)
  • Corrected misspelling of "precede" (bug 744342)
  • - -
  • EmptyForIteratorPadCheck errors when for statement - wraps at the iterator (bug 777471)
  • +
  • EmptyForIteratorPadCheck errors when for statement + wraps at the iterator (bug 777471)
  • + +
  • False alarms from IllegalInstantiation for + user defined classes with the same names as those in + java.lang (bug 772832)
  • + diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/IllegalInstantiationCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/IllegalInstantiationCheck.java index 4277f40c1..fbcc4389e 100644 --- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/IllegalInstantiationCheck.java +++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/coding/IllegalInstantiationCheck.java @@ -72,6 +72,12 @@ public class IllegalInstantiationCheck /** the imports for the file */ private final Set mImports = new HashSet(); + /** the class names defined in the file */ + private final Set mClassNames = new HashSet(); + + /** the instantiations in the file */ + private final Set mInstantiations = new HashSet(); + /** @see com.puppycrawl.tools.checkstyle.api.Check */ public int[] getDefaultTokens() { @@ -79,6 +85,7 @@ public class IllegalInstantiationCheck TokenTypes.IMPORT, TokenTypes.LITERAL_NEW, TokenTypes.PACKAGE_DEF, + TokenTypes.CLASS_DEF, }; } @@ -107,6 +114,8 @@ public class IllegalInstantiationCheck super.beginTree(aRootAST); mPkgName = null; mImports.clear(); + mInstantiations.clear(); + mClassNames.clear(); } /** @see com.puppycrawl.tools.checkstyle.api.Check */ @@ -122,11 +131,38 @@ public class IllegalInstantiationCheck case TokenTypes.IMPORT: processImport(aAST); break; + case TokenTypes.CLASS_DEF: + processClassDef(aAST); + break; default: throw new IllegalArgumentException("Unknown type " + aAST); } } + /** + * @see com.puppycrawl.tools.checkstyle.api.Check#finishTree + */ + public void finishTree(DetailAST aRootAST) + { + for (Iterator it = mInstantiations.iterator(); it.hasNext();) { + DetailAST literalNewAST = (DetailAST) it.next(); + postprocessLiteralNew(literalNewAST); + } + } + + /** + * Collects classes defined in the source file. Required + * to avoid false alarms for local vs. java.lang classes. + * + * @param aAST the classdef token. + */ + private void processClassDef(DetailAST aAST) + { + final DetailAST identToken = aAST.findFirstToken(TokenTypes.IDENT); + String className = identToken.getText(); + mClassNames.add(className); + } + /** * Perform processing for an import token * @param aAST the import token @@ -154,13 +190,22 @@ public class IllegalInstantiationCheck } /** - * Perform processing for an "new" token + * Collects a "new" token. * @param aAST the "new" token */ private void processLiteralNew(DetailAST aAST) { - final DetailAST typeNameAST = (DetailAST) aAST.getFirstChild(); + mInstantiations.add(aAST); + } + /** + * Processes one of the collected "new" tokens when treewalking + * has finished. + * @param aAST the "new" token. + */ + private void postprocessLiteralNew(DetailAST aAST) + { + final DetailAST typeNameAST = (DetailAST) aAST.getFirstChild(); final AST nameSibling = typeNameAST.getNextSibling(); if (nameSibling != null && nameSibling.getType() == TokenTypes.ARRAY_DECLARATOR) @@ -206,7 +251,32 @@ public class IllegalInstantiationCheck && illegal.endsWith(aClassName) && illegal.startsWith(javaLang)) { - return illegal; + // java.lang needs no import, but a class without import might + // also come from the same file or be in the same package. + // E.g. if a class defines an inner class "Boolean", + // the expression "new Boolean()" refers to that class, + // not to java.lang.Boolean + + boolean isSameFile = mClassNames.contains(aClassName); + + boolean isSamePackage = false; + try { + final ClassLoader classLoader = getClassLoader(); + if (classLoader != null) { + final String fqName = mPkgName + "." + aClassName; + classLoader.loadClass(fqName); + // no ClassNotFoundException, fqName is a known class + isSamePackage = true; + } + } + catch (ClassNotFoundException ex) { + // not a class from the same package + isSamePackage = false; + } + + if (!(isSameFile || isSamePackage)) { + return illegal; + } } // class from same package