Merge branch 'issue-1984'

This commit is contained in:
Clément Fournier
2020-01-17 18:32:16 +01:00
9 changed files with 108 additions and 58 deletions

View File

@ -76,6 +76,7 @@ Each `<file>` element in the XML format now has 3 new attributes:
* apex
* [#2208](https://github.com/pmd/pmd/issues/2208): \[apex] ASTFormalComment should implement ApexNode&lt;T&gt;
* core
* [#1984](https://github.com/pmd/pmd/issues/1984): \[java] Cyclomatic complexity is misreported (lack of clearing metrics cache)
* [#2006](https://github.com/pmd/pmd/issues/2006): \[core] PMD should warn about multiple instances of the same rule in a ruleset
* [#2161](https://github.com/pmd/pmd/issues/2161): \[core] ResourceLoader is deprecated and marked as internal but is exposed
* [#2170](https://github.com/pmd/pmd/issues/2170): \[core] DocumentFile doesn't preserve newlines

View File

@ -5,8 +5,6 @@
package net.sourceforge.pmd.lang.apex;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.Parser;
@ -17,14 +15,11 @@ import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
import net.sourceforge.pmd.lang.apex.ast.ApexNode;
import net.sourceforge.pmd.lang.apex.ast.DumpFacade;
import net.sourceforge.pmd.lang.apex.metrics.ApexMetricsComputer;
import net.sourceforge.pmd.lang.apex.metrics.api.ApexClassMetricKey;
import net.sourceforge.pmd.lang.apex.metrics.api.ApexOperationMetricKey;
import net.sourceforge.pmd.lang.apex.metrics.ApexMetricsProvider;
import net.sourceforge.pmd.lang.apex.multifile.ApexMultifileVisitorFacade;
import net.sourceforge.pmd.lang.apex.rule.ApexRuleViolationFactory;
import net.sourceforge.pmd.lang.ast.xpath.DefaultASTXPathHandler;
import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
@ -70,26 +65,4 @@ public class ApexHandler extends AbstractLanguageVersionHandler {
public LanguageMetricsProvider<ASTUserClassOrInterface<?>, ASTMethod> getLanguageMetricsProvider() {
return myMetricsProvider;
}
private static class ApexMetricsProvider extends AbstractLanguageMetricsProvider<ASTUserClassOrInterface<?>, ASTMethod> {
@SuppressWarnings("unchecked")
ApexMetricsProvider() {
// a wild double cast
super((Class<ASTUserClassOrInterface<?>>) (Object) ASTUserClassOrInterface.class, ASTMethod.class, ApexMetricsComputer.getInstance());
}
@Override
public List<ApexClassMetricKey> getAvailableTypeMetrics() {
return Arrays.asList(ApexClassMetricKey.values());
}
@Override
public List<ApexOperationMetricKey> getAvailableOperationMetrics() {
return Arrays.asList(ApexOperationMetricKey.values());
}
}
}

View File

@ -37,7 +37,10 @@ public final class ApexMetrics {
}
/** Resets the entire data structure. Used for tests. */
/**
* Resets the entire data structure.
* This needs to be done in case PMD is executed multiple times within one JVM run.
*/
static void reset() {
FACADE.reset();
}

View File

@ -0,0 +1,39 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.metrics;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClassOrInterface;
import net.sourceforge.pmd.lang.apex.metrics.api.ApexClassMetricKey;
import net.sourceforge.pmd.lang.apex.metrics.api.ApexOperationMetricKey;
import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider;
public class ApexMetricsProvider extends AbstractLanguageMetricsProvider<ASTUserClassOrInterface<?>, ASTMethod> {
@SuppressWarnings("unchecked")
public ApexMetricsProvider() {
// a wild double cast
super((Class<ASTUserClassOrInterface<?>>) (Object) ASTUserClassOrInterface.class, ASTMethod.class, ApexMetricsComputer.getInstance());
}
@Override
public void initialize() {
ApexMetrics.reset();
}
@Override
public List<ApexClassMetricKey> getAvailableTypeMetrics() {
return Arrays.asList(ApexClassMetricKey.values());
}
@Override
public List<ApexOperationMetricKey> getAvailableOperationMetrics() {
return Arrays.asList(ApexOperationMetricKey.values());
}
}

View File

@ -31,6 +31,12 @@ import net.sourceforge.pmd.lang.ast.QualifiableNode;
@Experimental
public interface LanguageMetricsProvider<T extends QualifiableNode, O extends QualifiableNode> {
/**
* Provides a hook to do any initializing before the first file is processed by PMD.
* This can be used by the metrics implementations to reset the cache.
*/
void initialize();
/**
* Returns a list of all supported type metric keys
* for the language.

View File

@ -24,6 +24,9 @@ import net.sourceforge.pmd.SourceCodeProcessor;
import net.sourceforge.pmd.benchmark.TimeTracker;
import net.sourceforge.pmd.benchmark.TimedOperation;
import net.sourceforge.pmd.benchmark.TimedOperationCategory;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageRegistry;
import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
import net.sourceforge.pmd.renderers.Renderer;
import net.sourceforge.pmd.util.datasource.DataSource;
@ -114,6 +117,8 @@ public abstract class AbstractPMDProcessor {
configuration.getAnalysisCache().checkValidity(rs, configuration.getClassLoader());
final SourceCodeProcessor processor = new SourceCodeProcessor(configuration);
resetMetrics();
for (final DataSource dataSource : files) {
// this is the real, canonical and absolute filename (not shortened)
String realFileName = dataSource.getNiceFileName(false, null);
@ -134,6 +139,15 @@ public abstract class AbstractPMDProcessor {
}
}
private void resetMetrics() {
for (Language language : LanguageRegistry.getLanguages()) {
LanguageMetricsProvider<?, ?> languageMetricsProvider = language.getDefaultVersion().getLanguageVersionHandler().getLanguageMetricsProvider();
if (languageMetricsProvider != null) {
languageMetricsProvider.initialize();
}
}
}
protected abstract void runAnalysis(PmdRunnable runnable);
protected abstract void collectReports(List<Renderer> renderers);

View File

@ -5,8 +5,6 @@
package net.sourceforge.pmd.lang.java;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.pmd.lang.AbstractLanguageVersionHandler;
import net.sourceforge.pmd.lang.DataFlowHandler;
@ -23,9 +21,7 @@ import net.sourceforge.pmd.lang.java.ast.JavaNode;
import net.sourceforge.pmd.lang.java.ast.MethodLikeNode;
import net.sourceforge.pmd.lang.java.dfa.DataFlowFacade;
import net.sourceforge.pmd.lang.java.dfa.JavaDFAGraphRule;
import net.sourceforge.pmd.lang.java.metrics.JavaMetricsComputer;
import net.sourceforge.pmd.lang.java.metrics.api.JavaClassMetricKey;
import net.sourceforge.pmd.lang.java.metrics.api.JavaOperationMetricKey;
import net.sourceforge.pmd.lang.java.metrics.JavaMetricsProvider;
import net.sourceforge.pmd.lang.java.multifile.MultifileVisitorFacade;
import net.sourceforge.pmd.lang.java.qname.QualifiedNameResolver;
import net.sourceforge.pmd.lang.java.rule.JavaRuleViolationFactory;
@ -38,8 +34,6 @@ import net.sourceforge.pmd.lang.java.xpath.TypeIsExactlyFunction;
import net.sourceforge.pmd.lang.java.xpath.TypeIsFunction;
import net.sourceforge.pmd.lang.java.xpath.TypeOfFunction;
import net.sourceforge.pmd.lang.metrics.LanguageMetricsProvider;
import net.sourceforge.pmd.lang.metrics.MetricKey;
import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider;
import net.sourceforge.pmd.lang.rule.RuleViolationFactory;
import net.sf.saxon.sxpath.IndependentContext;
@ -169,25 +163,4 @@ public abstract class AbstractJavaHandler extends AbstractLanguageVersionHandler
public LanguageMetricsProvider<ASTAnyTypeDeclaration, MethodLikeNode> getLanguageMetricsProvider() {
return myMetricsProvider;
}
private static class JavaMetricsProvider extends AbstractLanguageMetricsProvider<ASTAnyTypeDeclaration, MethodLikeNode> {
JavaMetricsProvider() {
super(ASTAnyTypeDeclaration.class, MethodLikeNode.class, JavaMetricsComputer.getInstance());
}
@Override
public List<? extends MetricKey<ASTAnyTypeDeclaration>> getAvailableTypeMetrics() {
return Arrays.asList(JavaClassMetricKey.values());
}
@Override
public List<? extends MetricKey<MethodLikeNode>> getAvailableOperationMetrics() {
return Arrays.asList(JavaOperationMetricKey.values());
}
}
}

View File

@ -38,7 +38,10 @@ public final class JavaMetrics {
}
/** Resets the entire data structure. Used for tests. */
/**
* Resets the entire data structure.
* This needs to be done in case PMD is executed multiple times within one JVM run.
*/
static void reset() {
FACADE.reset();
}

View File

@ -0,0 +1,38 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.metrics;
import java.util.Arrays;
import java.util.List;
import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;
import net.sourceforge.pmd.lang.java.ast.MethodLikeNode;
import net.sourceforge.pmd.lang.java.metrics.api.JavaClassMetricKey;
import net.sourceforge.pmd.lang.java.metrics.api.JavaOperationMetricKey;
import net.sourceforge.pmd.lang.metrics.MetricKey;
import net.sourceforge.pmd.lang.metrics.internal.AbstractLanguageMetricsProvider;
public class JavaMetricsProvider extends AbstractLanguageMetricsProvider<ASTAnyTypeDeclaration, MethodLikeNode> {
public JavaMetricsProvider() {
super(ASTAnyTypeDeclaration.class, MethodLikeNode.class, JavaMetricsComputer.getInstance());
}
@Override
public void initialize() {
JavaMetrics.reset();
}
@Override
public List<? extends MetricKey<ASTAnyTypeDeclaration>> getAvailableTypeMetrics() {
return Arrays.asList(JavaClassMetricKey.values());
}
@Override
public List<? extends MetricKey<MethodLikeNode>> getAvailableOperationMetrics() {
return Arrays.asList(JavaOperationMetricKey.values());
}
}