diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 921f453709..0e3819b67e 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -55,6 +55,7 @@ Any feedback about it, especially about your use cases, is highly appreciated. ### Fixed Issues * 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 diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java index ed2a66c5e4..d8945901af 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/ApexHandler.java @@ -17,6 +17,7 @@ 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.ApexMetrics; 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; @@ -80,6 +81,10 @@ public class ApexHandler extends AbstractLanguageVersionHandler { super((Class>) (Object) ASTUserClassOrInterface.class, ASTMethod.class, ApexMetricsComputer.getInstance()); } + @Override + public void initialize() { + ApexMetrics.reset(); + } @Override public List getAvailableTypeMetrics() { diff --git a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java index 2e01e30668..a89912ed69 100644 --- a/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java +++ b/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/metrics/ApexMetrics.java @@ -37,8 +37,11 @@ public final class ApexMetrics { } - /** Resets the entire data structure. Used for tests. */ - static void reset() { + /** + * Resets the entire data structure. + * This needs to be done in case PMD is executed multiple times within one JVM run. + */ + public static void reset() { FACADE.reset(); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java index ec57cceff9..a1b84240ce 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/metrics/LanguageMetricsProvider.java @@ -31,6 +31,12 @@ import net.sourceforge.pmd.lang.ast.QualifiableNode; @Experimental public interface LanguageMetricsProvider { + /** + * 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. diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/processor/AbstractPMDProcessor.java b/pmd-core/src/main/java/net/sourceforge/pmd/processor/AbstractPMDProcessor.java index 9b1af9682c..ee0bb7f382 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/processor/AbstractPMDProcessor.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/processor/AbstractPMDProcessor.java @@ -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 renderers); diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java index 03ca3ba425..880cf87b5b 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/AbstractJavaHandler.java @@ -23,6 +23,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.JavaMetrics; 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; @@ -178,6 +179,10 @@ public abstract class AbstractJavaHandler extends AbstractLanguageVersionHandler super(ASTAnyTypeDeclaration.class, MethodLikeNode.class, JavaMetricsComputer.getInstance()); } + @Override + public void initialize() { + JavaMetrics.reset(); + } @Override public List> getAvailableTypeMetrics() { diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java index 5e889e0439..5bafa8c138 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/JavaMetrics.java @@ -38,8 +38,11 @@ public final class JavaMetrics { } - /** Resets the entire data structure. Used for tests. */ - static void reset() { + /** + * Resets the entire data structure. + * This needs to be done in case PMD is executed multiple times within one JVM run. + */ + public static void reset() { FACADE.reset(); }