diff --git a/.travis/build-site.sh b/.travis/build-site.sh index a4f30dc5bc..3d3fa5a43d 100644 --- a/.travis/build-site.sh +++ b/.travis/build-site.sh @@ -15,13 +15,13 @@ fi ( # Run the build, truncate output due to Travis log limits - echo -e "\n\nExecuting ./mvnw install...\n\n" + echo -e "\n\nExecuting ./mvnw install..." travis_wait ./mvnw install -DskipTests=true -B -V -q - echo -e "Finished executing ./mvnw install\n\n" + echo "Finished executing ./mvnw install" - echo -e "\n\nExecuting ./mvnw site site:stage...\n\n" - travis_wait ./mvnw site site:stage -DskipTests=true -Psite -B -V -q - echo -e "Finished executing ./mvnw site site:stage...\n\n" + echo -e "\n\nExecuting ./mvnw site site:stage... + travis_wait 40 ./mvnw site site:stage -DskipTests=true -Psite -B -V -q + echo "Finished executing ./mvnw site site:stage..." ) echo -e "\n\nCreating pmd-doc archive...\n\n" diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/ClassStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/ClassStats.java index 74d74693f9..7bc3c144e7 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/ClassStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/ClassStats.java @@ -173,6 +173,38 @@ import net.sourceforge.pmd.lang.java.oom.signature.OperationSignature; } + /** + * Finds the declaration nodes of all methods or constructors that are declared inside a class. + * + * @param node The class in which to look for. + * @param includeNested Include operations found in nested classes? + * + * @return The list of all operations declared inside the specified class. + * + * TODO:cf this one is computed every time + */ + private static List findOperations(ASTAnyTypeDeclaration node, + boolean includeNested) { + + if (includeNested) { + return node.findDescendantsOfType(ASTMethodOrConstructorDeclaration.class); + } + + List outerDecls + = node.jjtGetChild(0).findChildrenOfType(ASTClassOrInterfaceBodyDeclaration.class); + + + List operations = new ArrayList<>(); + + for (ASTClassOrInterfaceBodyDeclaration decl : outerDecls) { + if (decl.jjtGetChild(0) instanceof ASTMethodOrConstructorDeclaration) { + operations.add((ASTMethodOrConstructorDeclaration) decl.jjtGetChild(0)); + } + } + return operations; + } + + /** * Computes the value of a metric for an operation. * @@ -290,5 +322,4 @@ import net.sourceforge.pmd.lang.java.oom.signature.OperationSignature; private static double average(List values) { return sum(values) / values.size(); } - } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/Metrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/Metrics.java index 0088c8258b..5487383bb2 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/Metrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/Metrics.java @@ -68,6 +68,7 @@ public final class Metrics { * @return The value of the metric, or {@code Double.NaN} if the value couln't be computed */ public static double get(MetricKey key, ASTAnyTypeDeclaration node, MetricVersion version) { + if (!key.getCalculator().supports(node)) { return Double.NaN; } @@ -101,6 +102,7 @@ public final class Metrics { * @return The value of the metric, or {@code Double.NaN} if the value couln't be computed */ public static double get(MetricKey key, ASTMethodOrConstructorDeclaration node, MetricVersion version) { + if (!key.getCalculator().supports(node)) { return Double.NaN; } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/OperationMetricKey.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/OperationMetricKey.java index 3eae5891d0..12813d6241 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/OperationMetricKey.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/oom/api/OperationMetricKey.java @@ -15,17 +15,33 @@ import net.sourceforge.pmd.lang.java.oom.metrics.NcssMetric.NcssOperationMetric; */ public enum OperationMetricKey implements MetricKey { - /** Access to Foreign Data. */ - ATFD(new AtfdOperationMetric()), + /** + * Access to Foreign Data. + * + * @see net.sourceforge.pmd.lang.java.oom.metrics.AtfdMetric + */ + ATFD(new AtfdClassMetric()), - /** Cyclomatic complexity. */ - CYCLO(new CycloOperationMetric()), + /** + * Cyclomatic complexity. + * + * @see net.sourceforge.pmd.lang.java.oom.metrics.CycloMetric + */ + CYCLO(new CycloClassMetric()), - /** Non Commenting Source Statements. */ - NCSS(new NcssOperationMetric()), + /** + * Non Commenting Source Statements. + * + * @see net.sourceforge.pmd.lang.java.oom.metrics.NcssMetric + */ + NCSS(new NcssClassMetric()), - /** Lines of Code. */ - LOC(new LocOperationMetric()); + /** + * Lines of Code. + * + * @see net.sourceforge.pmd.lang.java.oom.metrics.LocMetric + */ + LOC(new LocClassMetric()); private final OperationMetric calculator; diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/DataStructureTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/DataStructureTest.java index bfe405480c..dfddc01a40 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/DataStructureTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/DataStructureTest.java @@ -118,6 +118,21 @@ public class DataStructureTest extends ParserTst { assertEquals(expected, real); } + + @Test + public void forceMemoizationTest() { + ASTCompilationUnit acu = parseAndVisitForClass15(MetricsVisitorTestData.class); + + List reference = visitWith(acu, true); + List real = visitWith(acu, true); + + assertEquals(reference.size(), real.size()); + + // we force recomputation so each result should be different + for (int i = 0; i < reference.size(); i++) { + assertNotEquals(reference.get(i), real.get(i)); + } + } private List visitWith(ASTCompilationUnit acu, final boolean force) { final PackageStats toplevel = Metrics.getTopLevelPackageStats(); @@ -143,22 +158,6 @@ public class DataStructureTest extends ParserTst { } - @Test - public void forceMemoizationTest() { - ASTCompilationUnit acu = parseAndVisitForClass15(MetricsVisitorTestData.class); - - List reference = visitWith(acu, true); - List real = visitWith(acu, true); - - assertEquals(reference.size(), real.size()); - - // we force recomputation so each result should be different - for (int i = 0; i < reference.size(); i++) { - assertNotEquals(reference.get(i), real.get(i)); - } - } - - private class RandomOperationMetric extends AbstractOperationMetric { private Random random = new Random(); @@ -179,9 +178,5 @@ public class DataStructureTest extends ParserTst { public double computeFor(ASTAnyTypeDeclaration node, MetricVersion version) { return random.nextInt(); } - - } - - } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/ParameterizedMetricKeyTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/ParameterizedMetricKeyTest.java index 4b5c405561..d2254d6d8e 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/ParameterizedMetricKeyTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/ParameterizedMetricKeyTest.java @@ -71,6 +71,7 @@ public class ParameterizedMetricKeyTest { @Test public void testAdHocMetricKey() { + MetricKey adHocKey = ClassMetricKey.of(null, "metric"); MetricVersion adHocVersion = new MetricVersion() { diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/metrics/AbstractMetricTestRule.java b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/metrics/AbstractMetricTestRule.java index cc1dc5ee25..a0b8ed1ea7 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/metrics/AbstractMetricTestRule.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/lang/java/oom/metrics/AbstractMetricTestRule.java @@ -72,7 +72,7 @@ public abstract class AbstractMetricTestRule extends AbstractJavaMetricsRule { */ protected abstract OperationMetricKey getOpKey(); - + @Override public Object visit(ASTCompilationUnit node, Object data) { reportClasses = getProperty(reportClassesDescriptor); @@ -155,5 +155,4 @@ public abstract class AbstractMetricTestRule extends AbstractJavaMetricsRule { } return data; } - } diff --git a/src/site/markdown/overview/changelog.md b/src/site/markdown/overview/changelog.md index cc8e601220..960c237aec 100644 --- a/src/site/markdown/overview/changelog.md +++ b/src/site/markdown/overview/changelog.md @@ -89,5 +89,6 @@ Based on those metrics, rules like "GodClass" detection can be implemented more * [#492](https://github.com/pmd/pmd/pull/492): \[java] Typeresolution for overloaded methods - [Bendegúz Nagy](https://github.com/WinterGrascph) * [#495](https://github.com/pmd/pmd/pull/495): \[core] Custom rule reinitialization code - [Clément Fournier](https://github.com/oowekyala) * [#479](https://github.com/pmd/pmd/pull/479): \[core] Typesafe and immutable properties - [Clément Fournier](https://github.com/oowekyala) +* [#499](https://github.com/pmd/pmd/pull/499): \[java] Metrics memoization tests - [Clément Fournier](https://github.com/oowekyala) * [#501](https://github.com/pmd/pmd/pull/501): \[java] Add support for most specific vararg method type resolution - [Bendegúz Nagy](https://github.com/WinterGrascph)