Make the auxclasspath option optional. Falls back to the old behavior, which prevents many false positives. But it introduces the false negative case #1226, if no auxclasspath is set.
This commit is contained in:
@ -144,7 +144,8 @@ public class ClassScope extends AbstractJavaScope {
|
||||
|
||||
if (!mnd.isVarargs()
|
||||
&& occurrence.getArgumentCount() == mnd.getParameterCount()
|
||||
&& parameterTypes.equals(argumentTypes)) {
|
||||
&& (!getEnclosingScope(SourceFileScope.class).hasAuxclasspath()
|
||||
|| parameterTypes.equals(argumentTypes))) {
|
||||
return mnd;
|
||||
} else if (mnd.isVarargs()) {
|
||||
int varArgIndex = parameterTypes.size() - 1;
|
||||
@ -153,8 +154,14 @@ public class ClassScope extends AbstractJavaScope {
|
||||
// first parameter is varArg, calling method might have 0 or more arguments
|
||||
// or the calling method has enough arguments to fill in the parameters before the vararg
|
||||
if ((varArgIndex == 0 || argumentTypes.size() >= varArgIndex)
|
||||
&& parameterTypes.subList(0, varArgIndex).equals(argumentTypes.subList(0, varArgIndex))) {
|
||||
&& (!getEnclosingScope(SourceFileScope.class).hasAuxclasspath()
|
||||
|| parameterTypes.subList(0, varArgIndex).equals(argumentTypes.subList(0, varArgIndex)))) {
|
||||
boolean sameType = true;
|
||||
|
||||
if (!getEnclosingScope(SourceFileScope.class).hasAuxclasspath()) {
|
||||
return mnd;
|
||||
}
|
||||
|
||||
for (int i = varArgIndex; i < argumentTypes.size(); i++) {
|
||||
if (!varArgType.equals(argumentTypes.get(i))) {
|
||||
sameType = false;
|
||||
|
@ -45,6 +45,17 @@ public class SourceFileScope extends AbstractJavaScope {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether an auxclasspath has been configured or not.
|
||||
* This can be used to enable/disable more detailed symbol table analysis and type resolution
|
||||
* can be used - or to fall back to more simple implementation.
|
||||
* @return <code>true</code> if the auxclasspath is configured and types can be resolved reliably.
|
||||
* @see #resolveType(String)
|
||||
*/
|
||||
public boolean hasAuxclasspath() {
|
||||
return types.hasAuxclasspath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to resolve a class by name.
|
||||
* @param name the name of the class
|
||||
|
@ -11,6 +11,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sourceforge.pmd.lang.java.typeresolution.PMDASMClassLoader;
|
||||
import net.sourceforge.pmd.util.ClasspathClassLoader;
|
||||
|
||||
/**
|
||||
* Keeps track of the types encountered in a ASTCompilationUnit
|
||||
@ -18,6 +19,7 @@ import net.sourceforge.pmd.lang.java.typeresolution.PMDASMClassLoader;
|
||||
public class TypeSet {
|
||||
|
||||
private final PMDASMClassLoader pmdClassLoader;
|
||||
private boolean hasAuxclasspath;
|
||||
|
||||
/**
|
||||
* The {@link TypeSet} provides type resolution for the symbol facade.
|
||||
@ -35,9 +37,18 @@ public class TypeSet {
|
||||
if (cl == null) {
|
||||
cl = TypeSet.class.getClassLoader();
|
||||
}
|
||||
hasAuxclasspath = cl instanceof ClasspathClassLoader;
|
||||
pmdClassLoader = PMDASMClassLoader.getInstance(cl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the classloader is using the auxclasspath or not.
|
||||
* @return <code>true</code> if the classloader is using the auxclasspath feature
|
||||
*/
|
||||
public boolean hasAuxclasspath() {
|
||||
return hasAuxclasspath;
|
||||
}
|
||||
|
||||
/**
|
||||
* A resolver that can resolve a class by name. The name can be a simple name or a fully qualified name.
|
||||
*/
|
||||
|
@ -200,17 +200,22 @@ public abstract class RuleTst {
|
||||
/**
|
||||
* Run the rule on the given code and put the violations in the report.
|
||||
*/
|
||||
public void runTestFromString(String code, Rule rule, Report report, LanguageVersion languageVersion) throws PMDException {
|
||||
PMD p = new PMD();
|
||||
p.getConfiguration().setDefaultLanguageVersion(languageVersion);
|
||||
RuleContext ctx = new RuleContext();
|
||||
ctx.setReport(report);
|
||||
ctx.setSourceCodeFilename("n/a");
|
||||
ctx.setLanguageVersion(languageVersion);
|
||||
ctx.setIgnoreExceptions(false);
|
||||
RuleSet rules = new RuleSet();
|
||||
rules.addRule(rule);
|
||||
p.getSourceCodeProcessor().processSourceCode(new StringReader(code), new RuleSets(rules), ctx);
|
||||
public void runTestFromString(String code, Rule rule, Report report, LanguageVersion languageVersion) {
|
||||
try {
|
||||
PMD p = new PMD();
|
||||
p.getConfiguration().setDefaultLanguageVersion(languageVersion);
|
||||
p.getConfiguration().prependClasspath("."); // configure the "auxclasspath" option for unit testing
|
||||
RuleContext ctx = new RuleContext();
|
||||
ctx.setReport(report);
|
||||
ctx.setSourceCodeFilename("n/a");
|
||||
ctx.setLanguageVersion(languageVersion);
|
||||
ctx.setIgnoreExceptions(false);
|
||||
RuleSet rules = new RuleSet();
|
||||
rules.addRule(rule);
|
||||
p.getSourceCodeProcessor().processSourceCode(new StringReader(code), new RuleSets(rules), ctx);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user