diff --git a/docs/checkstyle_checks.xml b/docs/checkstyle_checks.xml
index 4f12c5c63..840315221 100644
--- a/docs/checkstyle_checks.xml
+++ b/docs/checkstyle_checks.xml
@@ -17,11 +17,11 @@
Limitations: this does not handle inner classes very well.
- * - * @author Oliver Burn - * @version 1.0 - */ -class ClassResolver -{ - /** name of the package to check if the class belongs to **/ - private final String mPkg; - /** set of imports to check against **/ - private final Set mImports; - /** use to load classes **/ - private final ClassLoader mLoader; - - /** - * Creates a newClassResolver instance.
- *
- * @param aLoader the ClassLoader to load classes with.
- * @param aPkg the name of the package the class may belong to
- * @param aImports set of imports to check if the class belongs to
- */
- ClassResolver(ClassLoader aLoader, String aPkg, Set aImports)
- {
- mLoader = aLoader;
- mPkg = aPkg;
- mImports = aImports;
- }
-
- /**
- * Attempts to resolve the Class for a specified name. The algorithm is
- * to check:
- * - fully qualified name
- * - explicit imports
- * - enclosing package
- * - star imports
- * @param aName name of the class to resolve
- * @return the resolved class
- * @throws ClassNotFoundException if unable to resolve the class
- */
- Class resolve(String aName) throws ClassNotFoundException
- {
- // See if the class is full qualified
- if (isLoadable(aName)) {
- return safeLoad(aName);
- }
-
- // try matching explicit imports
- Iterator it = mImports.iterator();
- while (it.hasNext()) {
- final String imp = ((LineText) it.next()).getText();
- if (imp.endsWith(aName) && isLoadable(imp)) {
- return safeLoad(imp);
- }
- }
-
- // See if in the package
- if (mPkg != null) {
- final String fqn = mPkg + "." + aName;
- if (isLoadable(fqn)) {
- return safeLoad(fqn);
- }
- }
-
- // try "java.lang."
- final String langClass = "java.lang." + aName;
- if (isLoadable(langClass)) {
- return safeLoad(langClass);
- }
-
- // try star imports
- it = mImports.iterator();
- while (it.hasNext()) {
- final String imp = ((LineText) it.next()).getText();
- if (imp.endsWith(".*")) {
- final String fqn = imp.substring(0, imp.lastIndexOf('.') + 1)
- + aName;
- if (isLoadable(fqn)) {
- return safeLoad(fqn);
- }
- }
- }
-
- // Giving up, the type is unknown, so load the class to generate an
- // exception
- return safeLoad(aName);
- }
-
- /**
- * @return whether a specified class is loadable with safeLoad().
- * @param aName name of the class to check
- */
- boolean isLoadable(String aName)
- {
- try {
- safeLoad(aName);
- return true;
- }
- catch (ClassNotFoundException e) {
- return false;
- }
- }
-
- /**
- * Will load a specified class is such a way that it will NOT be
- * initialised.
- * @param aName name of the class to load
- * @return the Class for the specified class
- * @throws ClassNotFoundException if an error occurs
- */
- Class safeLoad(String aName)
- throws ClassNotFoundException
- {
- // The next line will load the class using the specified class
- // loader. The magic is having the "false" parameter. This means the
- // class will not be initialised. Very, very important.
- return Class.forName(aName, false, mLoader);
- }
-}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java
index f2b391865..5e8710f21 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/TreeWalker.java
@@ -125,11 +125,12 @@ class TreeWalker
* Initiates the walk of an AST.
* @param aAST the root AST
* @param aContents the contents of the file the AST was generated from
+ * @param aLoader the class loader for resolving classes
*/
- void walk(DetailAST aAST, FileContents aContents)
+ void walk(DetailAST aAST, FileContents aContents, ClassLoader aLoader)
{
mMessages.reset();
- notifyBegin(aContents);
+ notifyBegin(aContents, aLoader);
// empty files are not flagged by javac, will yield aAST == null
if (aAST != null) {
@@ -143,8 +144,9 @@ class TreeWalker
/**
* Notify interested checks that about to begin walking a tree.
* @param aContents the contents of the file the AST was generated from
+ * @param aLoader the class loader for resolving classes
*/
- private void notifyBegin(FileContents aContents)
+ private void notifyBegin(FileContents aContents, ClassLoader aLoader)
{
// TODO: do not track Context properly for token
final Iterator it = mAllChecks.iterator();
@@ -153,6 +155,7 @@ class TreeWalker
final HashMap treeContext = new HashMap();
check.setTreeContext(treeContext);
check.setFileContents(aContents);
+ check.setClassLoader(aLoader);
check.beginTree();
}
}
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/api/Check.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/api/Check.java
index 1ca3e777d..ebd1e3b21 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/api/Check.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/api/Check.java
@@ -33,6 +33,8 @@ public abstract class Check
/** name to store file contents under */
private static final String FILE_CONTENTS_ATTRIBUTE = "fILEcONTENTS";
+ /** name to store class loader under */
+ private static final String CLASS_LOADER_ATTRIBUTE = "cLaSsLoAdEr";
/** the global context for the check */
private Map mGlobalContext;
@@ -224,6 +226,24 @@ public abstract class Check
return (FileContents) getTreeContext().get(FILE_CONTENTS_ATTRIBUTE);
}
+ /**
+ * Set the class loader associated with the tree.
+ * @param aLoader the class loader
+ */
+ public final void setClassLoader(ClassLoader aLoader)
+ {
+ getTreeContext().put(CLASS_LOADER_ATTRIBUTE, aLoader);
+ }
+
+ /**
+ * Returns the class loader associated with the tree.
+ * @return the class loader
+ */
+ public final ClassLoader getClassLoader()
+ {
+ return (ClassLoader) getTreeContext().get(CLASS_LOADER_ATTRIBUTE);
+ }
+
/** @return the tab width to report errors with */
protected final int getTabWidth()
{
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/ClassResolver.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/ClassResolver.java
index d5c7420a3..3ad213f6b 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/ClassResolver.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/ClassResolver.java
@@ -21,8 +21,6 @@ package com.puppycrawl.tools.checkstyle.checks;
import java.util.Set;
import java.util.Iterator;
-import com.puppycrawl.tools.checkstyle.api.DetailAST;
-
/**
* Utility class to resolve a class name to an actual class. Note that loaded
* classes are not initialized.
@@ -75,7 +73,7 @@ class ClassResolver
// try matching explicit imports
Iterator it = mImports.iterator();
while (it.hasNext()) {
- final String imp = ((DetailAST) it.next()).getText();
+ final String imp = (String) it.next();
if (imp.endsWith(aName) && isLoadable(imp)) {
return safeLoad(imp);
}
@@ -98,7 +96,7 @@ class ClassResolver
// try star imports
it = mImports.iterator();
while (it.hasNext()) {
- final String imp = ((DetailAST) it.next()).getText();
+ final String imp = (String) it.next();
if (imp.endsWith(".*")) {
final String fqn = imp.substring(0, imp.lastIndexOf('.') + 1)
+ aName;
diff --git a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/JavadocMethodCheck.java b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/JavadocMethodCheck.java
index a0d0108b5..fb54c195d 100644
--- a/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/JavadocMethodCheck.java
+++ b/src/checkstyle/com/puppycrawl/tools/checkstyle/checks/JavadocMethodCheck.java
@@ -179,7 +179,7 @@ public class JavadocMethodCheck
{
final FullIdent name = getImportText(aAST);
if (name != null) {
- mImports.add(name);
+ mImports.add(name.getText());
}
}
@@ -473,13 +473,16 @@ public class JavadocMethodCheck
if (!found) {
boolean reqd = true;
if (mCheckUnusedThrows) {
- final ClassResolver cr = new ClassResolver(
- Thread.currentThread().getContextClassLoader(),
- mPackageFullIdent.getText(), mImports);
+ final ClassResolver cr =
+ new ClassResolver(
+ getClassLoader(),
+ mPackageFullIdent.getText(),
+ mImports);
try {
final Class clazz = cr.resolve(tag.getArg1());
- reqd = !RuntimeException.class.isAssignableFrom(clazz)
- && !Error.class.isAssignableFrom(clazz);
+ reqd =
+ !RuntimeException.class.isAssignableFrom(clazz)
+ && !Error.class.isAssignableFrom(clazz);
}
catch (ClassNotFoundException e) {
log(tag.getLineNo(), "javadoc.classInfo",
diff --git a/src/tests/com/puppycrawl/tools/checkstyle/ClassResolverTest.java b/src/tests/com/puppycrawl/tools/checkstyle/checks/ClassResolverTest.java
similarity index 82%
rename from src/tests/com/puppycrawl/tools/checkstyle/ClassResolverTest.java
rename to src/tests/com/puppycrawl/tools/checkstyle/checks/ClassResolverTest.java
index be5339767..88eaaf834 100644
--- a/src/tests/com/puppycrawl/tools/checkstyle/ClassResolverTest.java
+++ b/src/tests/com/puppycrawl/tools/checkstyle/checks/ClassResolverTest.java
@@ -1,4 +1,4 @@
-package com.puppycrawl.tools.checkstyle;
+package com.puppycrawl.tools.checkstyle.checks;
import junit.framework.TestCase;
@@ -16,9 +16,9 @@ public class ClassResolverTest
public void testMisc() throws ClassNotFoundException
{
final Set imps = new HashSet();
- imps.add(new LineText(666, "java.io.File"));
- imps.add(new LineText(666, "nothing.will.match.*"));
- imps.add(new LineText(666, "java.applet.*"));
+ imps.add("java.io.File");
+ imps.add("nothing.will.match.*");
+ imps.add("java.applet.*");
ClassResolver cr =
new ClassResolver(Thread.currentThread().getContextClassLoader(),
null, imps);
@@ -40,7 +40,7 @@ public class ClassResolverTest
catch (ClassNotFoundException e) {
}
- imps.add(new LineText(324, "java.text.ChoiceFormat"));
+ imps.add("java.text.ChoiceFormat");
cr.resolve("ChoiceFormat");
cr = new ClassResolver(Thread.currentThread().getContextClassLoader(),