diff --git a/fixtures/VariableDeclaration/OneRecord.java b/fixtures/VariableDeclaration/OneRecord.java new file mode 100644 index 00000000..1f9d5610 --- /dev/null +++ b/fixtures/VariableDeclaration/OneRecord.java @@ -0,0 +1,8 @@ +package VariableDeclaration; + +public record OneRecord(String aString, Integer anInteger, Long aLong) { + + void y() { + + } +} \ No newline at end of file diff --git a/fixtures/assignments/RecordAssignments.java b/fixtures/assignments/RecordAssignments.java new file mode 100644 index 00000000..d21303dc --- /dev/null +++ b/fixtures/assignments/RecordAssignments.java @@ -0,0 +1,27 @@ +package assignments; + +record RecordAssignments() { + + public void m1() { + int a = 10; + int b = 20; + + b = b + 10; + a = a + 10; + + int c; + c = 60; + } + + public void m2() { + int a = 20; + int b = a; + + int c; + c = a + b; + } + + public void m3() { + + } +} \ No newline at end of file diff --git a/fixtures/cbo/RecordCoupling.java b/fixtures/cbo/RecordCoupling.java new file mode 100644 index 00000000..a7ce3394 --- /dev/null +++ b/fixtures/cbo/RecordCoupling.java @@ -0,0 +1,16 @@ +package cbo; + +record RecordCoupling(){ + + private B b; + + public D m1() { + A a = new A(); + C[] x = new C[10]; + + CouplingHelper h = new CouplingHelper(); + C2 c2 = h.m1(); + + return d; + } +} \ No newline at end of file diff --git a/fixtures/class-types/ARecord.java b/fixtures/class-types/ARecord.java new file mode 100644 index 00000000..48148e39 --- /dev/null +++ b/fixtures/class-types/ARecord.java @@ -0,0 +1,4 @@ +package classtypes; + +record ARecord(String aString, Integer anInteger, Long aLong) { +} \ No newline at end of file diff --git a/fixtures/comparison/RecordComparison.java b/fixtures/comparison/RecordComparison.java new file mode 100644 index 00000000..a058507d --- /dev/null +++ b/fixtures/comparison/RecordComparison.java @@ -0,0 +1,32 @@ +package comparison; + +record RecordComparison() { + + public void m1() { + int a = 1, b = 2; + + if(a == 1 || b == 2) { + System.out.println("Yay!"); + } + } + + public void m2() { + int a = 1, b = 2; + + if(a == 1) { + System.out.println("Yay!"); + } + } + + public void m3() { + int a = 1; + } + + public void m4() { + int a = 1; + + if(a != 1) { + System.out.println("Yay!"); + } + } +} \ No newline at end of file diff --git a/fixtures/dit/RecordR.java b/fixtures/dit/RecordR.java new file mode 100644 index 00000000..7dfad8ad --- /dev/null +++ b/fixtures/dit/RecordR.java @@ -0,0 +1,22 @@ +package dit; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +record RecordR() implements ActionListener, UmaInterface { + + @Override + public void actionPerformed(ActionEvent e) { + String x = e.getActionCommand(); + if(x.isEmpty()){ + x = "teste"; + } + else{ + x = x; + } + } + + public int a(){ + return 0; + } +} \ No newline at end of file diff --git a/fixtures/dit/UmaInterface.java b/fixtures/dit/UmaInterface.java new file mode 100644 index 00000000..b709e585 --- /dev/null +++ b/fixtures/dit/UmaInterface.java @@ -0,0 +1,6 @@ +package dit; + +public interface UmaInterface { + + public int a(); +} diff --git a/fixtures/fields/RecordFields.java b/fixtures/fields/RecordFields.java new file mode 100644 index 00000000..8638a968 --- /dev/null +++ b/fixtures/fields/RecordFields.java @@ -0,0 +1,6 @@ +package fields; + +public record RecordFields(int a, String b, char c) { + + private final static int x = 0; +} \ No newline at end of file diff --git a/fixtures/innerclasses/MessyRecord.java b/fixtures/innerclasses/MessyRecord.java new file mode 100644 index 00000000..9a2b16f4 --- /dev/null +++ b/fixtures/innerclasses/MessyRecord.java @@ -0,0 +1,87 @@ +package innerclasses; + +record MessyRecord { + + private int a; + private int b; + + class InnerClass1 { + public void m1() { + int x = 0; + int y = 0; + if(x > 10) { + if(y < 20) { + // ... + } else { + // ... + } + } + } + + public void m2() {} + } + + static class InnerClass2 { + public void m1() { + int a = a + 10; + } + + public void m2() {} + + public void m3() {} + } + + public void m1() { + this.a = 10; + + for(int i = 0; i < 10; i++) { + // ... + } + System.out.println(a); + } + + public void m2() { + this.b = 10; + System.out.println(b); + + } + + public void m3() { + Thread t = new Thread() + { + public void run() + { + System.out.println("Child Thread 1"); + } + }; + } + + public void m4() { + Arrays.asList("a1", "a2", "a3") + .stream() + .findFirst() + .ifPresent(x -> System.out.println(x)); + } + + + public void m5() { + Thread t = new Thread() + { + public void run() + { + System.out.println("Child Thread 2"); + } + + public void x() { } + }; + } + + public void m6() { + class InnerClass3 { + public void m1(); + }; + + int a = 1; + } + +} diff --git a/fixtures/innerclasses/RecordSC2.java b/fixtures/innerclasses/RecordSC2.java new file mode 100644 index 00000000..b95e188f --- /dev/null +++ b/fixtures/innerclasses/RecordSC2.java @@ -0,0 +1,17 @@ +package innerclasses; + +class RecordSC2 { + public void m1() { + System.out.println(new Object() { + @Override public String toString() { + + class X { + public void m1() { + int a = 1; + } + } + return "Hello world!"; + } + }); + } +} \ No newline at end of file diff --git a/fixtures/methods/OneRecord.java b/fixtures/methods/OneRecord.java new file mode 100644 index 00000000..eeed9da9 --- /dev/null +++ b/fixtures/methods/OneRecord.java @@ -0,0 +1,28 @@ +package methods; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public record OneRecord(String aString, Integer anInteger, Long aLong) implements ActionListener { + + public OneRecord(String aString, Long aLong) { + this(aString, 0, aLong); + } + + public int simpleSum(int parcela) { + return anInteger + parcela; + } + + @Override + public void actionPerformed(ActionEvent e) {} + + private static void privateStaticMethod(){} + + void defaultMethod() {} + + protected void protectedMethod() {} + + public synchronized void syncMethod(){} + + public final void finalMethod() {} +} \ No newline at end of file diff --git a/fixtures/parameters/OneRecord.java b/fixtures/parameters/OneRecord.java new file mode 100644 index 00000000..c2c43046 --- /dev/null +++ b/fixtures/parameters/OneRecord.java @@ -0,0 +1,14 @@ +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public record OneRecord(String aString, Integer anInteger, Long aLong) implements ActionListener { + + public int simpleSum(int parcela){ + return anInteger + parcela; + } + + @Override + public void actionPerformed(ActionEvent e) { + + } +} \ No newline at end of file diff --git a/fixtures/records/OneRecord.java b/fixtures/records/OneRecord.java new file mode 100644 index 00000000..c2c43046 --- /dev/null +++ b/fixtures/records/OneRecord.java @@ -0,0 +1,14 @@ +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public record OneRecord(String aString, Integer anInteger, Long aLong) implements ActionListener { + + public int simpleSum(int parcela){ + return anInteger + parcela; + } + + @Override + public void actionPerformed(ActionEvent e) { + + } +} \ No newline at end of file diff --git a/fixtures/returns/RecordReturns.java b/fixtures/returns/RecordReturns.java new file mode 100644 index 00000000..7fa148fc --- /dev/null +++ b/fixtures/returns/RecordReturns.java @@ -0,0 +1,28 @@ +package returns; + +record RecordReturns() { + + public void m1() { + boolean a = true; + boolean b = false; + + if(a) return; + if(b) return; + return; + } + + public int m2() { + boolean a = true; + + if(a) return 10; + return 20; + } + + public void m3() { + return; + } + + public void m4() { + + } +} \ No newline at end of file diff --git a/fixtures/variables/RecordVariables.java b/fixtures/variables/RecordVariables.java new file mode 100644 index 00000000..912b25e3 --- /dev/null +++ b/fixtures/variables/RecordVariables.java @@ -0,0 +1,24 @@ +package variables; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public record RecordVariables(String aString, Integer anInteger, Long aLong) implements ActionListener { + + public int simpleSum(int parcela) { + return anInteger + parcela; + } + + @Override + public void actionPerformed(ActionEvent e) { + int x = 4; + int y = 5; + } + + private static void privateStaticMethod(){ + int x = 5; + long z = 80; + } + + void defaultMethod() {} +} \ No newline at end of file diff --git a/fixtures/wmc/RecordWMC.java b/fixtures/wmc/RecordWMC.java new file mode 100644 index 00000000..d4e15517 --- /dev/null +++ b/fixtures/wmc/RecordWMC.java @@ -0,0 +1,18 @@ +package wmc; + +record RecordWMC(){ + + public void m1(boolean x) { + int a = 0; + + if(x) a++; + else a--; + } + + public void m2(boolean x) { + int a = 0; + + if(x == true) a++; + else a--; + } +} \ No newline at end of file diff --git a/fixtures/wordcounts/RecordCount.java b/fixtures/wordcounts/RecordCount.java new file mode 100644 index 00000000..626beb2e --- /dev/null +++ b/fixtures/wordcounts/RecordCount.java @@ -0,0 +1,22 @@ +package wordcounts; + +record RecordCount(){ + + public void m1() { + System.out.println("a"); + System.out.println("a"); + } + + public void m2() { + + int a = 10; + + int b = 20; + + if (((a>0)) && (b < 10)) { + // .... + } + + String superLongVariableName = "John"; + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index f12790b8..6a24eecf 100644 --- a/pom.xml +++ b/pom.xml @@ -1,287 +1,287 @@ - - 4.0.0 - com.github.mauricioaniche - ck - jar - 0.7.1-SNAPSHOT - CK calculator - http://www.mauricioaniche.com - Java code metrics calculator - - - - Apache License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - - mauricioaniche - Mauricio Aniche - mauricioaniche@gmail.com - Delft University of Technology - - developer - - -3 - - - - - http://github.com/mauricioaniche/ck - scm:git:git://github.com/mauricioaniche/ck.git - scm:git:git@github.com:mauricioaniche/ck.git - HEAD - - - - - - - org.assertj - assertj-core - 3.20.2 - test - - - - org.eclipse.jgit - org.eclipse.jgit - 5.12.0.202106070339-r - test - - - - org.junit.jupiter - junit-jupiter-engine - 5.8.0-M1 - test - - - - org.junit.jupiter - junit-jupiter-params - 5.8.0-M1 - test - - - - - org.reflections - reflections - 0.9.12 - - - - org.eclipse.jdt - org.eclipse.jdt.core - 3.26.0 - - - - com.google.guava - guava - 30.1.1-jre - - - - org.slf4j - slf4j-log4j12 - 1.7.30 - - - - commons-io - commons-io - 2.10.0 - - - - org.apache.commons - commons-lang3 - 3.12.0 - - - - org.apache.commons - commons-csv - 1.8 - - - - - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0 - - 11 - 11 - - - - - org.pitest - pitest-maven - 1.5.2 - - - com.github.mauricioaniche.ck.* - - - com.github.mauricioaniche.ck.* - - - - - - maven-assembly-plugin - - - - com.github.mauricioaniche.ck.Runner - - - - jar-with-dependencies - - - - - package - - single - - - - - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - - org.apache.maven.scm - maven-scm-provider-gitexe - 1.11.2 - - - org.apache.maven.scm - maven-scm-api - 1.11.2 - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.2.0 - - - attach-sources - - jar - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.2.0 - - none - 8 - - - - attach-javadocs - - jar - - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.7 - - - - prepare-agent - - - - report - test - - report - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - - - - - release-sign-artifacts - - - performRelease - true - - - - - - org.apache.maven.plugins - maven-gpg-plugin - - - sign-artifacts - verify - - sign - - - - - - - - - - - UTF-8 - UTF-8 - - + + 4.0.0 + com.github.mauricioaniche + ck + jar + 0.7.1-SNAPSHOT + CK calculator + http://www.mauricioaniche.com + Java code metrics calculator + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + + mauricioaniche + Mauricio Aniche + mauricioaniche@gmail.com + Delft University of Technology + + developer + + -3 + + + + + http://github.com/mauricioaniche/ck + scm:git:git://github.com/mauricioaniche/ck.git + scm:git:git@github.com:mauricioaniche/ck.git + HEAD + + + + + + + org.assertj + assertj-core + 3.20.2 + test + + + + org.eclipse.jgit + org.eclipse.jgit + 5.12.0.202106070339-r + test + + + + org.junit.jupiter + junit-jupiter-engine + 5.8.0-M1 + test + + + + org.junit.jupiter + junit-jupiter-params + 5.8.0-M1 + test + + + + + org.reflections + reflections + 0.9.12 + + + + org.eclipse.jdt + org.eclipse.jdt.core + 3.37.0 + + + + com.google.guava + guava + 30.1.1-jre + + + + org.slf4j + slf4j-log4j12 + 1.7.30 + + + + commons-io + commons-io + 2.10.0 + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + org.apache.commons + commons-csv + 1.8 + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 21 + 21 + + + + + org.pitest + pitest-maven + 1.5.2 + + + com.github.mauricioaniche.ck.* + + + com.github.mauricioaniche.ck.* + + + + + + maven-assembly-plugin + + + + com.github.mauricioaniche.ck.Runner + + + + jar-with-dependencies + + + + + package + + single + + + + + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + + org.apache.maven.scm + maven-scm-provider-gitexe + 1.11.2 + + + org.apache.maven.scm + maven-scm-api + 1.11.2 + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + + jar + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.2.0 + + none + 8 + + + + attach-javadocs + + jar + + + + + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + + prepare-agent + + + + report + test + + report + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.22.2 + + + + + + + release-sign-artifacts + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + + + + + UTF-8 + UTF-8 + + diff --git a/src/main/java/com/github/mauricioaniche/ck/CK.java b/src/main/java/com/github/mauricioaniche/ck/CK.java index 803e07cc..f27e0c2a 100644 --- a/src/main/java/com/github/mauricioaniche/ck/CK.java +++ b/src/main/java/com/github/mauricioaniche/ck/CK.java @@ -1,125 +1,127 @@ -package com.github.mauricioaniche.ck; - -import com.github.mauricioaniche.ck.metric.ClassLevelMetric; -import com.github.mauricioaniche.ck.metric.MethodLevelMetric; -import com.github.mauricioaniche.ck.util.FileUtils; -import com.github.mauricioaniche.ck.util.MetricsFinder; -import com.google.common.collect.Lists; -import org.apache.log4j.Logger; -import org.eclipse.jdt.core.JavaCore; -import org.eclipse.jdt.core.dom.AST; -import org.eclipse.jdt.core.dom.ASTParser; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Callable; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class CK { - - private final int maxAtOnce; - private final boolean useJars; - - private static Logger log = Logger.getLogger(CK.class); - - Callable> classLevelMetrics; - Callable> methodLevelMetrics; - - // mostly for testing purposes - public CK(Callable> classLevelMetrics, Callable> methodLevelMetrics) { - this.useJars = false; - this.classLevelMetrics = classLevelMetrics; - this.methodLevelMetrics = methodLevelMetrics; - this.maxAtOnce = 100; - } - - public CK(boolean useJars, int maxAtOnce, boolean variablesAndFields) { - MetricsFinder finder = new MetricsFinder(); - this.classLevelMetrics = () -> finder.allClassLevelMetrics(); - this.methodLevelMetrics = () -> finder.allMethodLevelMetrics(variablesAndFields); - - this.useJars = useJars; - if(maxAtOnce == 0) - this.maxAtOnce = getMaxPartitionBasedOnMemory(); - else - this.maxAtOnce = maxAtOnce; - } - - public CK() { - this(false, 0, true); - } - - public void calculate(String path, CKNotifier notifier) { - String[] javaFiles = FileUtils.getAllJavaFiles(path); - log.info("Found " + javaFiles.length + " java files"); - - calculate(Paths.get(path), notifier, - Stream.of(javaFiles) - .map(Paths::get) - .toArray(Path[]::new) - ); - } - - /** - * Convenience method to call ck with a path rather than a string - * @param path The path which contain the java class files to analyse - * @param notifier Handle to process the results and handle errors - */ - public void calculate(Path path, CKNotifier notifier) { - calculate(path.toString(), notifier); - } - - /** - * Calculate metrics for the passed javaFilePaths. Uses path to set the environment - * @param path The environment to where the source code is located - * @param notifier Handle to process the results and handle errors - * @param javaFilePaths The files to collect metrics of. - */ - public void calculate(Path path, CKNotifier notifier, Path... javaFilePaths) { - String[] srcDirs = FileUtils.getAllDirs(path.toString()); - log.info("Found " + srcDirs.length + " src dirs"); - - String[] allDependencies = useJars ? FileUtils.getAllJars(path.toString()) : null; - - if(useJars) - log.info("Found " + allDependencies.length + " jar dependencies"); - - MetricsExecutor storage = new MetricsExecutor(classLevelMetrics, methodLevelMetrics, notifier); - - // Converts the paths to strings and makes the method support relative paths as well. - List strJavaFilePaths = Stream.of(javaFilePaths).map(file -> file.isAbsolute() ? file.toString() : path.resolve(file).toString()).collect(Collectors.toList()); - - List> partitions = Lists.partition(strJavaFilePaths, maxAtOnce); - log.debug("Max partition size: " + maxAtOnce + ", total partitions=" + partitions.size()); - - for(List partition : partitions) { - log.debug("Next partition"); - ASTParser parser = ASTParser.newParser(AST.JLS11); - - parser.setResolveBindings(true); - parser.setBindingsRecovery(true); - - Map options = JavaCore.getOptions(); - JavaCore.setComplianceOptions(JavaCore.VERSION_11, options); - parser.setCompilerOptions(options); - parser.setEnvironment(allDependencies, srcDirs, null, true); - parser.createASTs(partition.toArray(new String[partition.size()]), null, new String[0], storage, null); - } - - log.info("Finished parsing"); - } - - private int getMaxPartitionBasedOnMemory() { - long maxMemory= Runtime.getRuntime().maxMemory() / (1 << 20); // in MiB - - if (maxMemory >= 2000) return 400; - else if (maxMemory >= 1500) return 300; - else if (maxMemory >= 1000) return 200; - else if (maxMemory >= 500) return 100; - else return 25; - } - -} +package com.github.mauricioaniche.ck; + +import com.github.mauricioaniche.ck.metric.ClassLevelMetric; +import com.github.mauricioaniche.ck.metric.MethodLevelMetric; +import com.github.mauricioaniche.ck.util.FileUtils; +import com.github.mauricioaniche.ck.util.MetricsFinder; +import com.google.common.collect.Lists; +import org.apache.log4j.Logger; +import org.eclipse.jdt.core.JavaCore; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class CK { + + private final int maxAtOnce; + private final boolean useJars; + + private static Logger log = Logger.getLogger(CK.class); + + Callable> classLevelMetrics; + Callable> methodLevelMetrics; + + // mostly for testing purposes + public CK(Callable> classLevelMetrics, Callable> methodLevelMetrics) { + this.useJars = false; + this.classLevelMetrics = classLevelMetrics; + this.methodLevelMetrics = methodLevelMetrics; + this.maxAtOnce = 100; + } + + public CK(boolean useJars, int maxAtOnce, boolean variablesAndFields) { + MetricsFinder finder = new MetricsFinder(); + this.classLevelMetrics = () -> finder.allClassLevelMetrics(); + this.methodLevelMetrics = () -> finder.allMethodLevelMetrics(variablesAndFields); + + this.useJars = useJars; + if(maxAtOnce == 0) + this.maxAtOnce = getMaxPartitionBasedOnMemory(); + else + this.maxAtOnce = maxAtOnce; + } + + public CK() { + this(false, 0, true); + } + + public void calculate(String path, CKNotifier notifier) { + String[] javaFiles = FileUtils.getAllJavaFiles(path); + log.info("Found " + javaFiles.length + " java files"); + + calculate(Paths.get(path), notifier, + Stream.of(javaFiles) + .map(Paths::get) + .toArray(Path[]::new) + ); + } + + /** + * Convenience method to call ck with a path rather than a string + * @param path The path which contain the java class files to analyse + * @param notifier Handle to process the results and handle errors + */ + public void calculate(Path path, CKNotifier notifier) { + calculate(path.toString(), notifier); + } + + /** + * Calculate metrics for the passed javaFilePaths. Uses path to set the environment + * @param path The environment to where the source code is located + * @param notifier Handle to process the results and handle errors + * @param javaFilePaths The files to collect metrics of. + */ + public void calculate(Path path, CKNotifier notifier, Path... javaFilePaths) { + String[] srcDirs = FileUtils.getAllDirs(path.toString()); + log.info("Found " + srcDirs.length + " src dirs"); + + String[] allDependencies = useJars ? FileUtils.getAllJars(path.toString()) : null; + + if(useJars) + log.info("Found " + allDependencies.length + " jar dependencies"); + + MetricsExecutor storage = new MetricsExecutor(classLevelMetrics, methodLevelMetrics, notifier); + + // Converts the paths to strings and makes the method support relative paths as well. + List strJavaFilePaths = Stream.of(javaFilePaths).map(file -> file.isAbsolute() ? file.toString() : path.resolve(file).toString()).collect(Collectors.toList()); + + List> partitions = Lists.partition(strJavaFilePaths, maxAtOnce); + log.debug("Max partition size: " + maxAtOnce + ", total partitions=" + partitions.size()); + + for(List partition : partitions) { + log.debug("Next partition"); + ASTParser parser = ASTParser.newParser(AST.JLS16); + + parser.setResolveBindings(true); + parser.setBindingsRecovery(true); + + Map options = JavaCore.getOptions(); + JavaCore.setComplianceOptions(JavaCore.VERSION_16, options); + parser.setCompilerOptions(options); + parser.setEnvironment(allDependencies, srcDirs, null, true); + parser.createASTs(partition.toArray(new String[partition.size()]), null, new String[0], storage, null); + } + + log.info("Finished parsing"); + } + + private int getMaxPartitionBasedOnMemory() { + long maxMemory= Runtime.getRuntime().maxMemory() / (1 << 20); // in MiB + + if (maxMemory >= 2000) return 400; + else if (maxMemory >= 1500) return 300; + else if (maxMemory >= 1000) return 200; + else if (maxMemory >= 500) return 100; + else return 25; + } + +} diff --git a/src/main/java/com/github/mauricioaniche/ck/CKVisitor.java b/src/main/java/com/github/mauricioaniche/ck/CKVisitor.java index 0e53b66c..0ea437e5 100644 --- a/src/main/java/com/github/mauricioaniche/ck/CKVisitor.java +++ b/src/main/java/com/github/mauricioaniche/ck/CKVisitor.java @@ -1,1298 +1,1361 @@ -package com.github.mauricioaniche.ck; - -import com.github.mauricioaniche.ck.metric.CKASTVisitor; -import com.github.mauricioaniche.ck.metric.ClassLevelMetric; -import com.github.mauricioaniche.ck.metric.MethodLevelMetric; -import com.github.mauricioaniche.ck.util.JDTUtils; -import org.eclipse.jdt.core.dom.*; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.Stack; -import java.util.concurrent.Callable; - -import static com.github.mauricioaniche.ck.util.LOCCalculator.calculate; - -public class CKVisitor extends ASTVisitor { - - private String sourceFilePath; - private int anonymousNumber; - private int initializerNumber; - - class MethodInTheStack { - CKMethodResult result; - List methodLevelMetrics; - } - - class ClassInTheStack { - CKClassResult result; - List classLevelMetrics; - Stack methods; - - - ClassInTheStack() { - methods = new Stack<>(); - } - } - private Stack classes; - - private Set collectedClasses; - - private CompilationUnit cu; - private Callable> classLevelMetrics; - private Callable> methodLevelMetrics; - - public CKVisitor(String sourceFilePath, CompilationUnit cu, Callable> classLevelMetrics, Callable> methodLevelMetrics) { - this.sourceFilePath = sourceFilePath; - this.cu = cu; - this.classLevelMetrics = classLevelMetrics; - this.methodLevelMetrics = methodLevelMetrics; - this.classes = new Stack<>(); - this.collectedClasses = new HashSet<>(); - } - - @Override - public boolean visit(TypeDeclaration node) { - ITypeBinding binding = node.resolveBinding(); - - // build a CKClassResult based on the current type - // declaration we are visiting - String className = binding != null ? binding.getBinaryName() : node.getName().getFullyQualifiedName(); - String type = getTypeOfTheUnit(node); - int modifiers = node.getModifiers(); - CKClassResult currentClass = new CKClassResult(sourceFilePath, className, type, modifiers); - currentClass.setLoc(calculate(node.toString())); - - // there might be metrics that use it - // (even before a class is declared) - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if (!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - - } - - // create a set of visitors, just for the current class - List classLevelMetrics = instantiateClassLevelMetricVisitors(className); - - // store everything in a 'class in the stack' data structure - ClassInTheStack classInTheStack = new ClassInTheStack(); - classInTheStack.result = currentClass; - classInTheStack.classLevelMetrics = classLevelMetrics; - - // push it to the stack, so we know the current class we are visiting - classes.push(classInTheStack); - - // there might be class level metrics that use the TypeDeclaration - // so, let's run them - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - - return true; - } - - - @Override - public void endVisit(TypeDeclaration node) { - - // let's first visit any metrics that might make use of this endVisit - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - - ClassInTheStack completedClass = classes.pop(); - - // persist the results of the class level metrics in the result - completedClass.classLevelMetrics.forEach(m -> m.setResult(completedClass.result)); - - // we are done processing this class, so now let's - // store it in the collected classes set - collectedClasses.add(completedClass.result); - } - - public boolean visit(MethodDeclaration node) { - - IMethodBinding binding = node.resolveBinding(); - String currentMethodName = JDTUtils.getMethodFullName(node); - String currentQualifiedMethodName = JDTUtils.getQualifiedMethodFullName(node); - boolean isConstructor = node.isConstructor(); - - String className = ((currentQualifiedMethodName.lastIndexOf(currentMethodName) - 1) > 0) ? currentQualifiedMethodName.substring(0, (currentQualifiedMethodName.lastIndexOf(currentMethodName) - 1)) : ""; - - CKMethodResult currentMethod = new CKMethodResult(currentMethodName, currentQualifiedMethodName, isConstructor, node.getModifiers()); - currentMethod.setLoc(calculate(node.toString())); - currentMethod.setStartLine(JDTUtils.getStartLine(cu, node)); - - // let's instantiate method level visitors for this current method - List methodLevelMetrics = instantiateMethodLevelMetricVisitors(currentQualifiedMethodName); - - // we add it to the current class we are visiting - MethodInTheStack methodInTheStack = new MethodInTheStack(); - methodInTheStack.result = currentMethod; - methodInTheStack.methodLevelMetrics = methodLevelMetrics; - classes.peek().methods.push(methodInTheStack); - - // and there might be metrics that also use the methoddeclaration node. - // so, let's call them - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - - return true; - } - - @Override - public void endVisit(MethodDeclaration node) { - - // let's first invoke the metrics, because they might use this node - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - - // remove the method from the stack - MethodInTheStack completedMethod = classes.peek().methods.pop(); - - // persist the data of the visitors in the CKMethodResult - completedMethod.methodLevelMetrics.forEach(m -> m.setResult(completedMethod.result)); - - // store its final version in the current class - classes.peek().result.addMethod(completedMethod.result); - } - - - public boolean visit(AnonymousClassDeclaration node) { - java.util.List stringList = new java.util.ArrayList<>(); - stringList = stringList.stream().map(string -> string.toString()).collect(java.util.stream.Collectors.toList()); - - // there might be metrics that use it - // (even before an anonymous class is created) - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - - // we give the anonymous class a 'class$AnonymousN' name - String anonClassName = classes.peek().result.getClassName() + "$Anonymous" + ++anonymousNumber; - CKClassResult currentClass = new CKClassResult(sourceFilePath, anonClassName, "anonymous", -1); - currentClass.setLoc(calculate(node.toString())); - - // create a set of visitors, just for the current class - List classLevelMetrics = instantiateClassLevelMetricVisitors(anonClassName); - - // store everything in a 'class in the stack' data structure - ClassInTheStack classInTheStack = new ClassInTheStack(); - classInTheStack.result = currentClass; - classInTheStack.classLevelMetrics = classLevelMetrics; - - // push it to the stack, so we know the current class we are visiting - classes.push(classInTheStack); - - // and there might be metrics that also use the methoddeclaration node. - // so, let's call them - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - - return true; - } - - public void endVisit(AnonymousClassDeclaration node) { - - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - - ClassInTheStack completedClass = classes.pop(); - - // persist the results of the class level metrics in the result - completedClass.classLevelMetrics.forEach(m -> m.setResult(completedClass.result)); - - // we are done processing this class, so now let's - // store it in the collected classes set - collectedClasses.add(completedClass.result); - } - - // static blocks - public boolean visit(Initializer node) { - - String currentMethodName = "(initializer " + (++initializerNumber) + ")"; - - CKMethodResult currentMethod = new CKMethodResult(currentMethodName, currentMethodName, false, node.getModifiers()); - currentMethod.setLoc(calculate(node.toString())); - currentMethod.setStartLine(JDTUtils.getStartLine(cu, node)); - - // let's instantiate method level visitors for this current method - List methodLevelMetrics = instantiateMethodLevelMetricVisitors(currentMethodName); - - // we add it to the current class we are visiting - MethodInTheStack methodInTheStack = new MethodInTheStack(); - methodInTheStack.result = currentMethod; - methodInTheStack.methodLevelMetrics = methodLevelMetrics; - classes.peek().methods.push(methodInTheStack); - - // and there might be metrics that also use the methoddeclaration node. - // so, let's call them - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - - return true; - } - - @Override - public void endVisit(Initializer node) { - - // let's first invoke the metrics, because they might use this node - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - - // remove the method from the stack - MethodInTheStack completedMethod = classes.peek().methods.pop(); - - // persist the data of the visitors in the CKMethodResult - completedMethod.methodLevelMetrics.forEach(m -> m.setResult(completedMethod.result)); - - // store its final version in the current class - classes.peek().result.addMethod(completedMethod.result); - } - - - public boolean visit(EnumDeclaration node) { - ITypeBinding binding = node.resolveBinding(); - - // there might be metrics that use it - // (even before a enum is declared) - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if (!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - - // build a CKClassResult based on the current type - // declaration we are visiting - String className = binding != null ? binding.getBinaryName() : node.getName().getFullyQualifiedName(); - String type = "enum"; - int modifiers = node.getModifiers(); - CKClassResult currentClass = new CKClassResult(sourceFilePath, className, type, modifiers); - currentClass.setLoc(calculate(node.toString())); - - // create a set of visitors, just for the current class - List classLevelMetrics = instantiateClassLevelMetricVisitors(className); - - // store everything in a 'class in the stack' data structure - ClassInTheStack classInTheStack = new ClassInTheStack(); - classInTheStack.result = currentClass; - classInTheStack.classLevelMetrics = classLevelMetrics; - - // push it to the stack, so we know the current class we are visiting - classes.push(classInTheStack); - - // there might be class level metrics that use the TypeDeclaration - // so, let's run them - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - - return true; - - } - - @Override - public void endVisit(EnumDeclaration node) { - // let's first visit any metrics that might make use of this endVisit - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - - ClassInTheStack completedClass = classes.pop(); - - // persist the results of the class level metrics in the result - completedClass.classLevelMetrics.forEach(m -> m.setResult(completedClass.result)); - - // we are done processing this class, so now let's - // store it in the collected classes set - collectedClasses.add(completedClass.result); - } - - private List instantiateClassLevelMetricVisitors(String className) { - try { - List classes = classLevelMetrics.call(); - classes.forEach(c -> { c.setClassName(className); }); - return classes; -// return classLevelMetrics.call(); - } catch(Exception e) { - throw new RuntimeException("Could not instantiate class level visitors", e); - } - } - - private List instantiateMethodLevelMetricVisitors(String methodName) { - try { - List methods = methodLevelMetrics.call(); - methods.forEach(m -> { m.setMethodName(methodName); }); - return methods; -// return methodLevelMetrics.call(); - } catch(Exception e) { - throw new RuntimeException("Could not instantiate method level visitors", e); - } - } - - public Set getCollectedClasses() { - return collectedClasses; - } - - private String getTypeOfTheUnit(TypeDeclaration node) { - return node.isInterface() ? "interface" : (classes.isEmpty() ? "class" : "innerclass"); - } - - // ------------------------------------------------------- - // From here, just delegating the calls to the metrics - public boolean visit(AnnotationTypeDeclaration node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(AnnotationTypeMemberDeclaration node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ArrayAccess node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ArrayCreation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ArrayInitializer node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ArrayType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(AssertStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(Assignment node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(Block node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(BlockComment node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(BooleanLiteral node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(BreakStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(CastExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(CatchClause node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(CharacterLiteral node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ClassInstanceCreation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(CompilationUnit node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - } - - public boolean visit(ConditionalExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ConstructorInvocation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ContinueStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(CreationReference node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(Dimension node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(DoStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(EmptyStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(EnhancedForStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(EnumConstantDeclaration node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ExpressionMethodReference node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ExpressionStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(FieldAccess node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(FieldDeclaration node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ForStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(IfStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ImportDeclaration node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(InfixExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(InstanceofExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(IntersectionType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(LabeledStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(LambdaExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(LineComment node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(MarkerAnnotation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(MemberRef node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(MemberValuePair node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(MethodRef node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(MethodRefParameter node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(MethodInvocation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(Modifier node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(NameQualifiedType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(NormalAnnotation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(NullLiteral node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(NumberLiteral node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(PackageDeclaration node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ParameterizedType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ParenthesizedExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(PostfixExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(PrefixExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(PrimitiveType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(QualifiedName node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(QualifiedType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ReturnStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SimpleName node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SimpleType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SingleMemberAnnotation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SingleVariableDeclaration node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(StringLiteral node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SuperConstructorInvocation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SuperFieldAccess node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SuperMethodInvocation node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SuperMethodReference node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SwitchCase node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SwitchStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(SynchronizedStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(TagElement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(TextElement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ThisExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(ThrowStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(TryStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(TypeDeclarationStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(TypeLiteral node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(TypeMethodReference node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(TypeParameter node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(UnionType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(VariableDeclarationExpression node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(VariableDeclarationStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(VariableDeclarationFragment node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(WhileStatement node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - public boolean visit(WildcardType node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - // we only visit if we found a type already. - // TODO: understand what happens with a javadoc in a class. Will the TypeDeclaration come first? - public boolean visit(Javadoc node) { - if(!classes.isEmpty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); - } - return true; - - } - - // --------------------------------------------- - // End visits - - @Override - public void endVisit(Block node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - @Override - public void endVisit(FieldAccess node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - @Override - public void endVisit(ConditionalExpression node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(ForStatement node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(EnhancedForStatement node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(DoStatement node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(WhileStatement node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(SwitchCase node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(IfStatement node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(SwitchStatement node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(CatchClause node) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if(!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - - public void endVisit(Javadoc node) { - if(!classes.empty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - if (!classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - } - - public void endVisit(QualifiedName node) { - if(!classes.empty()) { - classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - if(!classes.isEmpty() && !classes.peek().methods.isEmpty()) - classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); - } - // TODO: add all other endVisit blocks +package com.github.mauricioaniche.ck; + +import com.github.mauricioaniche.ck.metric.CKASTVisitor; +import com.github.mauricioaniche.ck.metric.ClassLevelMetric; +import com.github.mauricioaniche.ck.metric.MethodLevelMetric; +import com.github.mauricioaniche.ck.util.JDTUtils; +import org.eclipse.jdt.core.dom.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.Stack; +import java.util.concurrent.Callable; + +import static com.github.mauricioaniche.ck.util.LOCCalculator.calculate; + +public class CKVisitor extends ASTVisitor { + + private String sourceFilePath; + private int anonymousNumber; + private int initializerNumber; + + class MethodInTheStack { + CKMethodResult result; + List methodLevelMetrics; + } + + class ClassInTheStack { + CKClassResult result; + List classLevelMetrics; + Stack methods; + + + ClassInTheStack() { + methods = new Stack<>(); + } + } + private Stack classes; + + private Set collectedClasses; + + private CompilationUnit cu; + private Callable> classLevelMetrics; + private Callable> methodLevelMetrics; + + public CKVisitor(String sourceFilePath, CompilationUnit cu, Callable> classLevelMetrics, Callable> methodLevelMetrics) { + this.sourceFilePath = sourceFilePath; + this.cu = cu; + this.classLevelMetrics = classLevelMetrics; + this.methodLevelMetrics = methodLevelMetrics; + this.classes = new Stack<>(); + this.collectedClasses = new HashSet<>(); + } + + @Override + public boolean visit(RecordDeclaration node){ + ITypeBinding binding = node.resolveBinding(); + + // build a CKClassResult based on the current type + // declaration we are visiting + String className = binding != null ? binding.getBinaryName() : node.getName().getFullyQualifiedName(); + String type = getTypeOfTheUnit(node); + int modifiers = node.getModifiers(); + CKClassResult currentClass = new CKClassResult(sourceFilePath, className, type, modifiers); + currentClass.setLoc(calculate(node.toString())); + +// // there might be metrics that use it +// // (even before a class is declared) + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if (!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + } + + // create a set of visitors, just for the current class + List classLevelMetrics = instantiateClassLevelMetricVisitors(className); + + // store everything in a 'class in the stack' data structure + ClassInTheStack classInTheStack = new ClassInTheStack(); + classInTheStack.result = currentClass; + classInTheStack.classLevelMetrics = classLevelMetrics; + + // push it to the stack, so we know the current class we are visiting + classes.push(classInTheStack); + + // there might be class level metrics that use the TypeDeclaration + // so, let's run them + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + return true; + } + + @Override + public boolean visit(TypeDeclaration node) { + ITypeBinding binding = node.resolveBinding(); + + // build a CKClassResult based on the current type + // declaration we are visiting + String className = binding != null ? binding.getBinaryName() : node.getName().getFullyQualifiedName(); + String type = getTypeOfTheUnit(node); + int modifiers = node.getModifiers(); + CKClassResult currentClass = new CKClassResult(sourceFilePath, className, type, modifiers); + currentClass.setLoc(calculate(node.toString())); + + // there might be metrics that use it + // (even before a class is declared) + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if (!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + } + + // create a set of visitors, just for the current class + List classLevelMetrics = instantiateClassLevelMetricVisitors(className); + + // store everything in a 'class in the stack' data structure + ClassInTheStack classInTheStack = new ClassInTheStack(); + classInTheStack.result = currentClass; + classInTheStack.classLevelMetrics = classLevelMetrics; + + // push it to the stack, so we know the current class we are visiting + classes.push(classInTheStack); + + // there might be class level metrics that use the TypeDeclaration + // so, let's run them + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + return true; + } + + @Override + public void endVisit(RecordDeclaration node) { + + // let's first visit any metrics that might make use of this endVisit + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + + ClassInTheStack completedClass = classes.pop(); + + // persist the results of the class level metrics in the result + completedClass.classLevelMetrics.forEach(m -> m.setResult(completedClass.result)); + + // we are done processing this class, so now let's + // store it in the collected classes set + collectedClasses.add(completedClass.result); + } + + @Override + public void endVisit(TypeDeclaration node) { + + // let's first visit any metrics that might make use of this endVisit + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + + ClassInTheStack completedClass = classes.pop(); + + // persist the results of the class level metrics in the result + completedClass.classLevelMetrics.forEach(m -> m.setResult(completedClass.result)); + + // we are done processing this class, so now let's + // store it in the collected classes set + collectedClasses.add(completedClass.result); + } + + public boolean visit(MethodDeclaration node) { + + IMethodBinding binding = node.resolveBinding(); + String currentMethodName = JDTUtils.getMethodFullName(node); + String currentQualifiedMethodName = JDTUtils.getQualifiedMethodFullName(node); + boolean isConstructor = node.isConstructor(); + + String className = ((currentQualifiedMethodName.lastIndexOf(currentMethodName) - 1) > 0) ? currentQualifiedMethodName.substring(0, (currentQualifiedMethodName.lastIndexOf(currentMethodName) - 1)) : ""; + + CKMethodResult currentMethod = new CKMethodResult(currentMethodName, currentQualifiedMethodName, isConstructor, node.getModifiers()); + currentMethod.setLoc(calculate(node.toString())); + currentMethod.setStartLine(JDTUtils.getStartLine(cu, node)); + + // let's instantiate method level visitors for this current method + List methodLevelMetrics = instantiateMethodLevelMetricVisitors(currentQualifiedMethodName); + + // we add it to the current class we are visiting + MethodInTheStack methodInTheStack = new MethodInTheStack(); + methodInTheStack.result = currentMethod; + methodInTheStack.methodLevelMetrics = methodLevelMetrics; + classes.peek().methods.push(methodInTheStack); + + // and there might be metrics that also use the methoddeclaration node. + // so, let's call them + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + return true; + } + + @Override + public void endVisit(MethodDeclaration node) { + + // let's first invoke the metrics, because they might use this node + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + + // remove the method from the stack + MethodInTheStack completedMethod = classes.peek().methods.pop(); + + // persist the data of the visitors in the CKMethodResult + completedMethod.methodLevelMetrics.forEach(m -> m.setResult(completedMethod.result)); + + // store its final version in the current class + classes.peek().result.addMethod(completedMethod.result); + } + + + public boolean visit(AnonymousClassDeclaration node) { + java.util.List stringList = new java.util.ArrayList<>(); + stringList = stringList.stream().map(string -> string.toString()).collect(java.util.stream.Collectors.toList()); + + // there might be metrics that use it + // (even before an anonymous class is created) + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + // we give the anonymous class a 'class$AnonymousN' name + String anonClassName = classes.peek().result.getClassName() + "$Anonymous" + ++anonymousNumber; + CKClassResult currentClass = new CKClassResult(sourceFilePath, anonClassName, "anonymous", -1); + currentClass.setLoc(calculate(node.toString())); + + // create a set of visitors, just for the current class + List classLevelMetrics = instantiateClassLevelMetricVisitors(anonClassName); + + // store everything in a 'class in the stack' data structure + ClassInTheStack classInTheStack = new ClassInTheStack(); + classInTheStack.result = currentClass; + classInTheStack.classLevelMetrics = classLevelMetrics; + + // push it to the stack, so we know the current class we are visiting + classes.push(classInTheStack); + + // and there might be metrics that also use the methoddeclaration node. + // so, let's call them + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + return true; + } + + public void endVisit(AnonymousClassDeclaration node) { + + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + + ClassInTheStack completedClass = classes.pop(); + + // persist the results of the class level metrics in the result + completedClass.classLevelMetrics.forEach(m -> m.setResult(completedClass.result)); + + // we are done processing this class, so now let's + // store it in the collected classes set + collectedClasses.add(completedClass.result); + } + + // static blocks + public boolean visit(Initializer node) { + + String currentMethodName = "(initializer " + (++initializerNumber) + ")"; + + CKMethodResult currentMethod = new CKMethodResult(currentMethodName, currentMethodName, false, node.getModifiers()); + currentMethod.setLoc(calculate(node.toString())); + currentMethod.setStartLine(JDTUtils.getStartLine(cu, node)); + + // let's instantiate method level visitors for this current method + List methodLevelMetrics = instantiateMethodLevelMetricVisitors(currentMethodName); + + // we add it to the current class we are visiting + MethodInTheStack methodInTheStack = new MethodInTheStack(); + methodInTheStack.result = currentMethod; + methodInTheStack.methodLevelMetrics = methodLevelMetrics; + classes.peek().methods.push(methodInTheStack); + + // and there might be metrics that also use the methoddeclaration node. + // so, let's call them + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + return true; + } + + @Override + public void endVisit(Initializer node) { + + // let's first invoke the metrics, because they might use this node + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + + // remove the method from the stack + MethodInTheStack completedMethod = classes.peek().methods.pop(); + + // persist the data of the visitors in the CKMethodResult + completedMethod.methodLevelMetrics.forEach(m -> m.setResult(completedMethod.result)); + + // store its final version in the current class + classes.peek().result.addMethod(completedMethod.result); + } + + + public boolean visit(EnumDeclaration node) { + ITypeBinding binding = node.resolveBinding(); + + // there might be metrics that use it + // (even before a enum is declared) + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if (!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + + // build a CKClassResult based on the current type + // declaration we are visiting + String className = binding != null ? binding.getBinaryName() : node.getName().getFullyQualifiedName(); + String type = "enum"; + int modifiers = node.getModifiers(); + CKClassResult currentClass = new CKClassResult(sourceFilePath, className, type, modifiers); + currentClass.setLoc(calculate(node.toString())); + + // create a set of visitors, just for the current class + List classLevelMetrics = instantiateClassLevelMetricVisitors(className); + + // store everything in a 'class in the stack' data structure + ClassInTheStack classInTheStack = new ClassInTheStack(); + classInTheStack.result = currentClass; + classInTheStack.classLevelMetrics = classLevelMetrics; + + // push it to the stack, so we know the current class we are visiting + classes.push(classInTheStack); + + // there might be class level metrics that use the TypeDeclaration + // so, let's run them + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + + return true; + + } + + @Override + public void endVisit(EnumDeclaration node) { + // let's first visit any metrics that might make use of this endVisit + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + + ClassInTheStack completedClass = classes.pop(); + + // persist the results of the class level metrics in the result + completedClass.classLevelMetrics.forEach(m -> m.setResult(completedClass.result)); + + // we are done processing this class, so now let's + // store it in the collected classes set + collectedClasses.add(completedClass.result); + } + + private List instantiateClassLevelMetricVisitors(String className) { + try { + List classes = classLevelMetrics.call(); + classes.forEach(c -> { c.setClassName(className); }); + return classes; +// return classLevelMetrics.call(); + } catch(Exception e) { + throw new RuntimeException("Could not instantiate class level visitors", e); + } + } + + private List instantiateMethodLevelMetricVisitors(String methodName) { + try { + List methods = methodLevelMetrics.call(); + methods.forEach(m -> { m.setMethodName(methodName); }); + return methods; +// return methodLevelMetrics.call(); + } catch(Exception e) { + throw new RuntimeException("Could not instantiate method level visitors", e); + } + } + + public Set getCollectedClasses() { + return collectedClasses; + } + + private String getTypeOfTheUnit(TypeDeclaration node) { + return node.isInterface() ? "interface" : (classes.isEmpty() ? "class" : "innerclass"); + } + + private String getTypeOfTheUnit(RecordDeclaration node) { + return "record"; + } + + // ------------------------------------------------------- + // From here, just delegating the calls to the metrics + public boolean visit(AnnotationTypeDeclaration node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(AnnotationTypeMemberDeclaration node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ArrayAccess node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ArrayCreation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ArrayInitializer node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ArrayType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(AssertStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(Assignment node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(Block node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(BlockComment node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(BooleanLiteral node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(BreakStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(CastExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(CatchClause node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(CharacterLiteral node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ClassInstanceCreation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(CompilationUnit node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + } + + public boolean visit(ConditionalExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ConstructorInvocation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ContinueStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(CreationReference node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(Dimension node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(DoStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(EmptyStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(EnhancedForStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(EnumConstantDeclaration node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ExpressionMethodReference node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ExpressionStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(FieldAccess node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(FieldDeclaration node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ForStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(IfStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ImportDeclaration node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(InfixExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(InstanceofExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(IntersectionType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(LabeledStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(LambdaExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(LineComment node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(MarkerAnnotation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(MemberRef node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(MemberValuePair node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(MethodRef node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(MethodRefParameter node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(MethodInvocation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(Modifier node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(NameQualifiedType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(NormalAnnotation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(NullLiteral node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(NumberLiteral node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(PackageDeclaration node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ParameterizedType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ParenthesizedExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(PostfixExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(PrefixExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(PrimitiveType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(QualifiedName node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(QualifiedType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + @Override + public boolean visit(RecordPattern node) { + return super.visit(node); + } + + public boolean visit(ReturnStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SimpleName node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SimpleType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SingleMemberAnnotation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SingleVariableDeclaration node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(StringLiteral node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SuperConstructorInvocation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SuperFieldAccess node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SuperMethodInvocation node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SuperMethodReference node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SwitchCase node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SwitchStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(SynchronizedStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(TagElement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(TextElement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ThisExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(ThrowStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(TryStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(TypeDeclarationStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(TypeLiteral node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(TypeMethodReference node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(TypeParameter node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(UnionType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(VariableDeclarationExpression node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(VariableDeclarationStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(VariableDeclarationFragment node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(WhileStatement node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + public boolean visit(WildcardType node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + // we only visit if we found a type already. + // TODO: understand what happens with a javadoc in a class. Will the TypeDeclaration come first? + public boolean visit(Javadoc node) { + if(!classes.isEmpty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.visit(node)); + } + return true; + + } + + // --------------------------------------------- + // End visits + + @Override + public void endVisit(Block node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + @Override + public void endVisit(FieldAccess node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + @Override + public void endVisit(ConditionalExpression node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(ForStatement node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(EnhancedForStatement node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(DoStatement node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(WhileStatement node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(SwitchCase node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(IfStatement node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(SwitchStatement node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(CatchClause node) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if(!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + + public void endVisit(Javadoc node) { + if(!classes.empty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + if (!classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + } + + public void endVisit(QualifiedName node) { + if(!classes.empty()) { + classes.peek().classLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + if(!classes.isEmpty() && !classes.peek().methods.isEmpty()) + classes.peek().methods.peek().methodLevelMetrics.stream().map(metric -> (CKASTVisitor) metric).forEach(ast -> ast.endVisit(node)); + } + // TODO: add all other endVisit blocks } \ No newline at end of file diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/CKASTVisitor.java b/src/main/java/com/github/mauricioaniche/ck/metric/CKASTVisitor.java index 8d8d8902..03f2cfe2 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/CKASTVisitor.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/CKASTVisitor.java @@ -1,700 +1,707 @@ -package com.github.mauricioaniche.ck.metric; - -import org.eclipse.jdt.core.dom.*; - -public interface CKASTVisitor { - - - default void visit(AnnotationTypeDeclaration node) { - - } - - default void visit(AnnotationTypeMemberDeclaration node) { - - } - - default void visit(AnonymousClassDeclaration node) { - - } - - default void visit(ArrayAccess node) { - - } - - default void visit(ArrayCreation node) { - - } - - default void visit(ArrayInitializer node) { - - } - - default void visit(ArrayType node) { - - } - - default void visit(AssertStatement node) { - - } - - default void visit(Assignment node) { - - } - - default void visit(Block node) { - - } - - default void visit(BlockComment node) { - - } - - default void visit(BooleanLiteral node) { - - } - - default void visit(BreakStatement node) { - - } - - default void visit(CastExpression node) { - - } - - default void visit(CatchClause node) { - - } - - default void visit(CharacterLiteral node) { - - } - - default void visit(ClassInstanceCreation node) { - - } - - default void visit(CompilationUnit node) { - - } - - default void visit(ConditionalExpression node) { - - } - - default void visit(ConstructorInvocation node) { - - } - - default void visit(ContinueStatement node) { - - } - - default void visit(CreationReference node) { - - } - - default void visit(Dimension node) { - - } - - default void visit(DoStatement node) { - - } - - default void visit(EmptyStatement node) { - - } - - default void visit(EnhancedForStatement node) { - - } - - default void visit(EnumConstantDeclaration node) { - - } - - default void visit(EnumDeclaration node) { - - } - - default void visit(ExportsDirective node) { - - } - - default void visit(ExpressionMethodReference node) { - - } - - default void visit(ExpressionStatement node) { - - } - - default void visit(FieldAccess node) { - - } - - default void visit(FieldDeclaration node) { - - } - - default void visit(ForStatement node) { - - } - - default void visit(IfStatement node) { - - } - - default void visit(ImportDeclaration node) { - - } - - default void visit(InfixExpression node) { - - } - - default void visit(Initializer node) { - - } - - default void visit(InstanceofExpression node) { - - } - - default void visit(IntersectionType node) { - - } - - default void visit(Javadoc node) { - - } - - default void visit(LabeledStatement node) { - - } - - default void visit(LambdaExpression node) { - - } - - default void visit(LineComment node) { - - } - - default void visit(MarkerAnnotation node) { - - } - - default void visit(MemberRef node) { - - } - - default void visit(MemberValuePair node) { - - } - - default void visit(MethodRef node) { - - } - - default void visit(MethodRefParameter node) { - - } - - default void visit(MethodDeclaration node) { - - } - - default void visit(MethodInvocation node) { - - } - - default void visit(Modifier node) { - - } - - default void visit(ModuleDeclaration node) { - - } - - default void visit(ModuleModifier node) { - - } - - default void visit(NameQualifiedType node) { - - } - - default void visit(NormalAnnotation node) { - - } - - default void visit(NullLiteral node) { - - } - - default void visit(NumberLiteral node) { - - } - - default void visit(OpensDirective node) { - - } - - default void visit(PackageDeclaration node) { - - } - - default void visit(ParameterizedType node) { - - } - - default void visit(ParenthesizedExpression node) { - - } - - default void visit(PostfixExpression node) { - - } - - default void visit(PrefixExpression node) { - - } - - default void visit(ProvidesDirective node) { - - } - - default void visit(PrimitiveType node) { - - } - - default void visit(QualifiedName node) { - - } - - default void visit(QualifiedType node) { - - } - - default void visit(RequiresDirective node) { - - } - - default void visit(ReturnStatement node) { - - } - - default void visit(SimpleName node) { - - } - - default void visit(SimpleType node) { - - } - - default void visit(SingleMemberAnnotation node) { - - } - - default void visit(SingleVariableDeclaration node) { - - } - - default void visit(StringLiteral node) { - - } - - default void visit(SuperConstructorInvocation node) { - - } - - default void visit(SuperFieldAccess node) { - - } - - default void visit(SuperMethodInvocation node) { - - } - - default void visit(SuperMethodReference node) { - - } - - default void visit(SwitchCase node) { - - } - - default void visit(SwitchStatement node) { - - } - - default void visit(SynchronizedStatement node) { - - } - - default void visit(TagElement node) { - - } - - default void visit(TextElement node) { - - } - - default void visit(ThisExpression node) { - - } - - default void visit(ThrowStatement node) { - - } - - default void visit(TryStatement node) { - - } - - default void visit(TypeDeclaration node) { - - } - - default void visit(TypeDeclarationStatement node) { - - } - - default void visit(TypeLiteral node) { - - } - - default void visit(TypeMethodReference node) { - - } - - default void visit(TypeParameter node) { - - } - - default void visit(UnionType node) { - - } - - default void visit(UsesDirective node) { - - } - - default void visit(VariableDeclarationExpression node) { - - } - - default void visit(VariableDeclarationStatement node) { - - } - - default void visit(VariableDeclarationFragment node) { - - } - - default void visit(WhileStatement node) { - - } - - default void visit(WildcardType node) { - - } - - default void endVisit(AnnotationTypeDeclaration node) { - } - - default void endVisit(AnnotationTypeMemberDeclaration node) { - } - - default void endVisit(AnonymousClassDeclaration node) { - } - - default void endVisit(ArrayAccess node) { - } - - default void endVisit(ArrayCreation node) { - } - - default void endVisit(ArrayInitializer node) { - } - - default void endVisit(ArrayType node) { - } - - default void endVisit(AssertStatement node) { - } - - default void endVisit(Assignment node) { - } - - default void endVisit(Block node) { - } - - default void endVisit(BlockComment node) { - } - - default void endVisit(BooleanLiteral node) { - } - - default void endVisit(BreakStatement node) { - } - - default void endVisit(CastExpression node) { - } - - default void endVisit(CatchClause node) { - } - - default void endVisit(CharacterLiteral node) { - } - - default void endVisit(ClassInstanceCreation node) { - } - - default void endVisit(CompilationUnit node) { - } - - default void endVisit(ConditionalExpression node) { - } - - default void endVisit(ConstructorInvocation node) { - } - - default void endVisit(ContinueStatement node) { - } - - default void endVisit(CreationReference node) { - } - - default void endVisit(DoStatement node) { - } - - default void endVisit(EmptyStatement node) { - } - - default void endVisit(EnhancedForStatement node) { - } - - default void endVisit(EnumConstantDeclaration node) { - } - - default void endVisit(EnumDeclaration node) { - } - - default void endVisit(ExportsDirective node) { - } - - default void endVisit(ExpressionMethodReference node) { - } - - default void endVisit(ExpressionStatement node) { - } - - default void endVisit(Dimension node) { - } - - default void endVisit(FieldAccess node) { - } - - default void endVisit(FieldDeclaration node) { - } - - default void endVisit(ForStatement node) { - } - - default void endVisit(IfStatement node) { - } - - default void endVisit(ImportDeclaration node) { - } - - default void endVisit(InfixExpression node) { - } - - default void endVisit(InstanceofExpression node) { - } - - default void endVisit(Initializer node) { - } - - default void endVisit(Javadoc node) { - } - - default void endVisit(LabeledStatement node) { - } - - default void endVisit(LambdaExpression node) { - } - - default void endVisit(LineComment node) { - } - - default void endVisit(MarkerAnnotation node) { - } - - default void endVisit(MemberRef node) { - } - - default void endVisit(MemberValuePair node) { - } - - default void endVisit(MethodRef node) { - } - - default void endVisit(MethodRefParameter node) { - } - - default void endVisit(MethodDeclaration node) { - } - - default void endVisit(MethodInvocation node) { - } - - default void endVisit(Modifier node) { - } - - default void endVisit(ModuleDeclaration node) { - } - - default void endVisit(ModuleModifier node) { - } - - default void endVisit(NameQualifiedType node) { - } - - default void endVisit(NormalAnnotation node) { - } - - default void endVisit(NullLiteral node) { - } - - default void endVisit(NumberLiteral node) { - } - - default void endVisit(OpensDirective node) { - } - - default void endVisit(PackageDeclaration node) { - } - - default void endVisit(ParameterizedType node) { - } - - default void endVisit(ParenthesizedExpression node) { - } - - default void endVisit(PostfixExpression node) { - } - - default void endVisit(PrefixExpression node) { - } - - default void endVisit(PrimitiveType node) { - } - - default void endVisit(ProvidesDirective node) { - } - - default void endVisit(QualifiedName node) { - } - - default void endVisit(QualifiedType node) { - } - - default void endVisit(RequiresDirective node) { - } - - default void endVisit(ReturnStatement node) { - } - - default void endVisit(SimpleName node) { - } - - default void endVisit(SimpleType node) { - } - - default void endVisit(SingleMemberAnnotation node) { - } - - default void endVisit(SingleVariableDeclaration node) { - } - - default void endVisit(StringLiteral node) { - } - - default void endVisit(SuperConstructorInvocation node) { - } - - default void endVisit(SuperFieldAccess node) { - } - - default void endVisit(SuperMethodInvocation node) { - } - - default void endVisit(SuperMethodReference node) { - } - - default void endVisit(SwitchCase node) { - } - - default void endVisit(SwitchStatement node) { - } - - default void endVisit(SynchronizedStatement node) { - } - - default void endVisit(TagElement node) { - } - - default void endVisit(TextElement node) { - } - - default void endVisit(ThisExpression node) { - } - - default void endVisit(ThrowStatement node) { - } - - default void endVisit(TryStatement node) { - } - - default void endVisit(TypeDeclaration node) { - } - - default void endVisit(TypeDeclarationStatement node) { - } - - default void endVisit(TypeLiteral node) { - } - - default void endVisit(TypeMethodReference node) { - } - - default void endVisit(TypeParameter node) { - } - - default void endVisit(UnionType node) { - } - - default void endVisit(UsesDirective node) { - } - - default void endVisit(IntersectionType node) { - } - - default void endVisit(VariableDeclarationExpression node) { - } - - default void endVisit(VariableDeclarationStatement node) { - } - - default void endVisit(VariableDeclarationFragment node) { - } - - default void endVisit(WhileStatement node) { - } - - default void endVisit(WildcardType node) { - } -} +package com.github.mauricioaniche.ck.metric; + +import org.eclipse.jdt.core.dom.*; + +public interface CKASTVisitor { + + default void visit(AnnotationTypeDeclaration node) { + + } + + default void visit(AnnotationTypeMemberDeclaration node) { + + } + + default void visit(AnonymousClassDeclaration node) { + + } + + default void visit(ArrayAccess node) { + + } + + default void visit(ArrayCreation node) { + + } + + default void visit(ArrayInitializer node) { + + } + + default void visit(ArrayType node) { + + } + + default void visit(AssertStatement node) { + + } + + default void visit(Assignment node) { + + } + + default void visit(Block node) { + + } + + default void visit(BlockComment node) { + + } + + default void visit(BooleanLiteral node) { + + } + + default void visit(BreakStatement node) { + + } + + default void visit(CastExpression node) { + + } + + default void visit(CatchClause node) { + + } + + default void visit(CharacterLiteral node) { + + } + + default void visit(ClassInstanceCreation node) { + + } + + default void visit(CompilationUnit node) { + + } + + default void visit(ConditionalExpression node) { + + } + + default void visit(ConstructorInvocation node) { + + } + + default void visit(ContinueStatement node) { + + } + + default void visit(CreationReference node) { + + } + + default void visit(Dimension node) { + + } + + default void visit(DoStatement node) { + + } + + default void visit(EmptyStatement node) { + + } + + default void visit(EnhancedForStatement node) { + + } + + default void visit(EnumConstantDeclaration node) { + + } + + default void visit(EnumDeclaration node) { + + } + + default void visit(ExportsDirective node) { + + } + + default void visit(ExpressionMethodReference node) { + + } + + default void visit(ExpressionStatement node) { + + } + + default void visit(FieldAccess node) { + + } + + default void visit(FieldDeclaration node) { + + } + + default void visit(ForStatement node) { + + } + + default void visit(IfStatement node) { + + } + + default void visit(ImportDeclaration node) { + + } + + default void visit(InfixExpression node) { + + } + + default void visit(Initializer node) { + + } + + default void visit(InstanceofExpression node) { + + } + + default void visit(IntersectionType node) { + + } + + default void visit(Javadoc node) { + + } + + default void visit(LabeledStatement node) { + + } + + default void visit(LambdaExpression node) { + + } + + default void visit(LineComment node) { + + } + + default void visit(MarkerAnnotation node) { + + } + + default void visit(MemberRef node) { + + } + + default void visit(MemberValuePair node) { + + } + + default void visit(MethodRef node) { + + } + + default void visit(MethodRefParameter node) { + + } + + default void visit(MethodDeclaration node) { + + } + + default void visit(MethodInvocation node) { + + } + + default void visit(Modifier node) { + + } + + default void visit(ModuleDeclaration node) { + + } + + default void visit(ModuleModifier node) { + + } + + default void visit(NameQualifiedType node) { + + } + + default void visit(NormalAnnotation node) { + + } + + default void visit(NullLiteral node) { + + } + + default void visit(NumberLiteral node) { + + } + + default void visit(OpensDirective node) { + + } + + default void visit(PackageDeclaration node) { + + } + + default void visit(ParameterizedType node) { + + } + + default void visit(ParenthesizedExpression node) { + + } + + default void visit(PostfixExpression node) { + + } + + default void visit(PrefixExpression node) { + + } + + default void visit(ProvidesDirective node) { + + } + + default void visit(PrimitiveType node) { + + } + + default void visit(QualifiedName node) { + + } + + default void visit(QualifiedType node) { + + } + + default void visit(RequiresDirective node) { + + } + + default void visit(RecordDeclaration node) { + + } + + default void endVisit(RecordDeclaration node) { + + } + + default void visit(ReturnStatement node) { + + } + + default void visit(SimpleName node) { + + } + + default void visit(SimpleType node) { + + } + + default void visit(SingleMemberAnnotation node) { + + } + + default void visit(SingleVariableDeclaration node) { + + } + + default void visit(StringLiteral node) { + + } + + default void visit(SuperConstructorInvocation node) { + + } + + default void visit(SuperFieldAccess node) { + + } + + default void visit(SuperMethodInvocation node) { + + } + + default void visit(SuperMethodReference node) { + + } + + default void visit(SwitchCase node) { + + } + + default void visit(SwitchStatement node) { + + } + + default void visit(SynchronizedStatement node) { + + } + + default void visit(TagElement node) { + + } + + default void visit(TextElement node) { + + } + + default void visit(ThisExpression node) { + + } + + default void visit(ThrowStatement node) { + + } + + default void visit(TryStatement node) { + + } + + default void visit(TypeDeclaration node) { + + } + + default void visit(TypeDeclarationStatement node) { + + } + + default void visit(TypeLiteral node) { + + } + + default void visit(TypeMethodReference node) { + + } + + default void visit(TypeParameter node) { + + } + + default void visit(UnionType node) { + + } + + default void visit(UsesDirective node) { + + } + + default void visit(VariableDeclarationExpression node) { + + } + + default void visit(VariableDeclarationStatement node) { + + } + + default void visit(VariableDeclarationFragment node) { + + } + + default void visit(WhileStatement node) { + + } + + default void visit(WildcardType node) { + + } + + default void endVisit(AnnotationTypeDeclaration node) { + } + + default void endVisit(AnnotationTypeMemberDeclaration node) { + } + + default void endVisit(AnonymousClassDeclaration node) { + } + + default void endVisit(ArrayAccess node) { + } + + default void endVisit(ArrayCreation node) { + } + + default void endVisit(ArrayInitializer node) { + } + + default void endVisit(ArrayType node) { + } + + default void endVisit(AssertStatement node) { + } + + default void endVisit(Assignment node) { + } + + default void endVisit(Block node) { + } + + default void endVisit(BlockComment node) { + } + + default void endVisit(BooleanLiteral node) { + } + + default void endVisit(BreakStatement node) { + } + + default void endVisit(CastExpression node) { + } + + default void endVisit(CatchClause node) { + } + + default void endVisit(CharacterLiteral node) { + } + + default void endVisit(ClassInstanceCreation node) { + } + + default void endVisit(CompilationUnit node) { + } + + default void endVisit(ConditionalExpression node) { + } + + default void endVisit(ConstructorInvocation node) { + } + + default void endVisit(ContinueStatement node) { + } + + default void endVisit(CreationReference node) { + } + + default void endVisit(DoStatement node) { + } + + default void endVisit(EmptyStatement node) { + } + + default void endVisit(EnhancedForStatement node) { + } + + default void endVisit(EnumConstantDeclaration node) { + } + + default void endVisit(EnumDeclaration node) { + } + + default void endVisit(ExportsDirective node) { + } + + default void endVisit(ExpressionMethodReference node) { + } + + default void endVisit(ExpressionStatement node) { + } + + default void endVisit(Dimension node) { + } + + default void endVisit(FieldAccess node) { + } + + default void endVisit(FieldDeclaration node) { + } + + default void endVisit(ForStatement node) { + } + + default void endVisit(IfStatement node) { + } + + default void endVisit(ImportDeclaration node) { + } + + default void endVisit(InfixExpression node) { + } + + default void endVisit(InstanceofExpression node) { + } + + default void endVisit(Initializer node) { + } + + default void endVisit(Javadoc node) { + } + + default void endVisit(LabeledStatement node) { + } + + default void endVisit(LambdaExpression node) { + } + + default void endVisit(LineComment node) { + } + + default void endVisit(MarkerAnnotation node) { + } + + default void endVisit(MemberRef node) { + } + + default void endVisit(MemberValuePair node) { + } + + default void endVisit(MethodRef node) { + } + + default void endVisit(MethodRefParameter node) { + } + + default void endVisit(MethodDeclaration node) { + } + + default void endVisit(MethodInvocation node) { + } + + default void endVisit(Modifier node) { + } + + default void endVisit(ModuleDeclaration node) { + } + + default void endVisit(ModuleModifier node) { + } + + default void endVisit(NameQualifiedType node) { + } + + default void endVisit(NormalAnnotation node) { + } + + default void endVisit(NullLiteral node) { + } + + default void endVisit(NumberLiteral node) { + } + + default void endVisit(OpensDirective node) { + } + + default void endVisit(PackageDeclaration node) { + } + + default void endVisit(ParameterizedType node) { + } + + default void endVisit(ParenthesizedExpression node) { + } + + default void endVisit(PostfixExpression node) { + } + + default void endVisit(PrefixExpression node) { + } + + default void endVisit(PrimitiveType node) { + } + + default void endVisit(ProvidesDirective node) { + } + + default void endVisit(QualifiedName node) { + } + + default void endVisit(QualifiedType node) { + } + + default void endVisit(RequiresDirective node) { + } + + default void endVisit(ReturnStatement node) { + } + + default void endVisit(SimpleName node) { + } + + default void endVisit(SimpleType node) { + } + + default void endVisit(SingleMemberAnnotation node) { + } + + default void endVisit(SingleVariableDeclaration node) { + } + + default void endVisit(StringLiteral node) { + } + + default void endVisit(SuperConstructorInvocation node) { + } + + default void endVisit(SuperFieldAccess node) { + } + + default void endVisit(SuperMethodInvocation node) { + } + + default void endVisit(SuperMethodReference node) { + } + + default void endVisit(SwitchCase node) { + } + + default void endVisit(SwitchStatement node) { + } + + default void endVisit(SynchronizedStatement node) { + } + + default void endVisit(TagElement node) { + } + + default void endVisit(TextElement node) { + } + + default void endVisit(ThisExpression node) { + } + + default void endVisit(ThrowStatement node) { + } + + default void endVisit(TryStatement node) { + } + + default void endVisit(TypeDeclaration node) { + } + + default void endVisit(TypeDeclarationStatement node) { + } + + default void endVisit(TypeLiteral node) { + } + + default void endVisit(TypeMethodReference node) { + } + + default void endVisit(TypeParameter node) { + } + + default void endVisit(UnionType node) { + } + + default void endVisit(UsesDirective node) { + } + + default void endVisit(IntersectionType node) { + } + + default void endVisit(VariableDeclarationExpression node) { + } + + default void endVisit(VariableDeclarationStatement node) { + } + + default void endVisit(VariableDeclarationFragment node) { + } + + default void endVisit(WhileStatement node) { + } + + default void endVisit(WildcardType node) { + } +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/ClassLevelMetric.java b/src/main/java/com/github/mauricioaniche/ck/metric/ClassLevelMetric.java index 66d15a2e..7021688f 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/ClassLevelMetric.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/ClassLevelMetric.java @@ -1,12 +1,11 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import org.eclipse.jdt.core.dom.CompilationUnit; - -public interface ClassLevelMetric { - void setResult(CKClassResult result); - - default void setClassName(String className) { - - } -} +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; + +public interface ClassLevelMetric { + void setResult(CKClassResult result); + + default void setClassName(String className) { + + } +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/ClassLevelWordCounter.java b/src/main/java/com/github/mauricioaniche/ck/metric/ClassLevelWordCounter.java index 32b2e5f3..12c3f73d 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/ClassLevelWordCounter.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/ClassLevelWordCounter.java @@ -1,47 +1,54 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import com.github.mauricioaniche.ck.util.WordCounter; -import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; -import org.eclipse.jdt.core.dom.EnumDeclaration; -import org.eclipse.jdt.core.dom.TypeDeclaration; - -import static com.github.mauricioaniche.ck.util.WordCounter.removeSpacesAndIdentation; - -public class ClassLevelWordCounter implements CKASTVisitor, ClassLevelMetric { - - private String classSourceCode; - - public void visit(TypeDeclaration node) { - - String typeSourceCode = node.toString(); - setOrRemoveSourceCode(typeSourceCode); - - } - - public void visit(AnonymousClassDeclaration node) { - setOrRemoveSourceCode(node.toString()); - - } - - public void visit(EnumDeclaration node) { - setOrRemoveSourceCode(node.toString()); - - } - - private void setOrRemoveSourceCode(String typeSourceCode) { - if (classSourceCode == null) { - classSourceCode = removeSpacesAndIdentation(typeSourceCode); - } else { - String otherType = removeSpacesAndIdentation(typeSourceCode); - classSourceCode = removeSpacesAndIdentation(classSourceCode.replace(otherType, "")); - - } - } - - @Override - public void setResult(CKClassResult result) { - int qtyOfUniqueWords = WordCounter.wordsIn(classSourceCode).size(); - result.setUniqueWordsQty(qtyOfUniqueWords); - } -} +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; +import com.github.mauricioaniche.ck.util.WordCounter; +import org.eclipse.jdt.core.dom.AnonymousClassDeclaration; +import org.eclipse.jdt.core.dom.EnumDeclaration; +import org.eclipse.jdt.core.dom.RecordDeclaration; +import org.eclipse.jdt.core.dom.TypeDeclaration; + +import static com.github.mauricioaniche.ck.util.WordCounter.removeSpacesAndIdentation; + +public class ClassLevelWordCounter implements CKASTVisitor, ClassLevelMetric { + + private String classSourceCode; + + @Override + public void visit(RecordDeclaration node) { + String typeSourceCode = node.toString(); + setOrRemoveSourceCode(typeSourceCode); + } + + public void visit(TypeDeclaration node) { + + String typeSourceCode = node.toString(); + setOrRemoveSourceCode(typeSourceCode); + + } + + public void visit(AnonymousClassDeclaration node) { + setOrRemoveSourceCode(node.toString()); + + } + + public void visit(EnumDeclaration node) { + setOrRemoveSourceCode(node.toString()); + + } + + private void setOrRemoveSourceCode(String typeSourceCode) { + if (classSourceCode == null) { + classSourceCode = removeSpacesAndIdentation(typeSourceCode); + } else { + String otherType = removeSpacesAndIdentation(typeSourceCode); + classSourceCode = removeSpacesAndIdentation(classSourceCode.replace(otherType, "")); + + } + } + + @Override + public void setResult(CKClassResult result) { + int qtyOfUniqueWords = WordCounter.wordsIn(classSourceCode).size(); + result.setUniqueWordsQty(qtyOfUniqueWords); + } +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/Coupling.java b/src/main/java/com/github/mauricioaniche/ck/metric/Coupling.java index 3e298031..25fa3537 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/Coupling.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/Coupling.java @@ -1,336 +1,349 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import com.github.mauricioaniche.ck.CKMethodResult; -import com.github.mauricioaniche.ck.util.JDTUtils; - -import org.eclipse.jdt.core.dom.*; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -public class Coupling implements CKASTVisitor, ClassLevelMetric, MethodLevelMetric { - - private CouplingExtras extras; - private String className; - private String methodName; - - public Coupling() { - this.extras = CouplingExtras.getInstance(); - } - - @Override - public void visit(VariableDeclarationStatement node) { - if(this.className != null) { - coupleTo(node.getType()); - } - } - - @Override - public void visit(ClassInstanceCreation node) { - if(this.className != null) { - coupleTo(node.getType()); - } else if(this.methodName != null) { - IMethodBinding binding = node.resolveConstructorBinding(); - coupleTo(binding); - } - } - - @Override - public void visit(ArrayCreation node) { - if(this.className != null) { - coupleTo(node.getType()); - } - } - - @Override - public void visit(FieldDeclaration node) { - if(this.className != null) { - coupleTo(node.getType()); - } - } - - public void visit(ReturnStatement node) { - if(this.className != null){ - if (node.getExpression() != null) { - coupleTo(node.getExpression().resolveTypeBinding()); - } - } - } - - @Override - public void visit(TypeLiteral node) { - if(this.className != null) { - coupleTo(node.getType()); - } - } - - public void visit(ThrowStatement node) { - if(this.className != null) { - if(node.getExpression()!=null) - coupleTo(node.getExpression().resolveTypeBinding()); - } - } - - public void visit(TypeDeclaration node) { - if(this.className != null) { - ITypeBinding resolvedType = node.resolveBinding(); - - if(resolvedType!=null) { - ITypeBinding binding = resolvedType.getSuperclass(); - if (binding != null) - coupleTo(binding); - - for (ITypeBinding interfaces : resolvedType.getInterfaces()) { - coupleTo(interfaces); - } - } else { - coupleTo(node.getSuperclassType()); - List list = node.superInterfaceTypes(); - list.forEach(x -> coupleTo(x)); - } - } - - } - - public void visit(MethodDeclaration node) { - if(this.className != null) { - IMethodBinding resolvedMethod = node.resolveBinding(); - if (resolvedMethod != null) { - - coupleTo(resolvedMethod.getReturnType()); - - for (ITypeBinding param : resolvedMethod.getParameterTypes()) { - coupleTo(param); - } - } else { - coupleTo(node.getReturnType2()); - List list = node.typeParameters(); - list.forEach(x -> coupleTo(x.getName())); - } - } - - } - - @Override - public void visit(CastExpression node) { - if(this.className != null) { - coupleTo(node.getType()); - } - - } - - @Override - public void visit(InstanceofExpression node) { - if(this.className != null) { - coupleTo(node.getRightOperand()); - coupleTo(node.getLeftOperand().resolveTypeBinding()); - } - - } - - @Override - public void visit(MethodInvocation node) { - - IMethodBinding binding = node.resolveMethodBinding(); - if(binding!=null) { - if(this.className != null) { - coupleTo(binding.getDeclaringClass()); - } else if(this.methodName != null) { - coupleTo(binding); - } - } - - } - - public void visit(NormalAnnotation node) { - if(this.className != null) { - coupleTo(node); - } - } - - public void visit(MarkerAnnotation node) { - if(this.className != null) { - coupleTo(node); - } - } - - public void visit(SingleMemberAnnotation node) { - if(this.className != null) { - coupleTo(node); - } - } - - public void visit(ParameterizedType node) { - if(this.className != null) { - - try { - ITypeBinding binding = node.resolveBinding(); - if (binding != null) { - - coupleTo(binding); - - for (ITypeBinding types : binding.getTypeArguments()) { - coupleTo(types); - } - } else { - coupleTo(node.getType()); - } - } catch (NullPointerException e) { - // TODO: handle exception - } - } - - } - private void coupleTo(Annotation type) { - if(this.className != null) { - ITypeBinding resolvedType = type.resolveTypeBinding(); - if(resolvedType!=null) - coupleTo(resolvedType); - else { - addToSet(type.getTypeName().getFullyQualifiedName()); - } - } - } - - private void coupleTo(Type type) { - if(type==null) - return; - - if(this.className != null) { - ITypeBinding resolvedBinding = type.resolveBinding(); - if(resolvedBinding!=null) - coupleTo(resolvedBinding); - else { - if(type instanceof SimpleType) { - SimpleType castedType = (SimpleType) type; - addToSet(castedType.getName().getFullyQualifiedName()); - } - else if(type instanceof QualifiedType) { - QualifiedType castedType = (QualifiedType) type; - addToSet(castedType.getName().getFullyQualifiedName()); - } - else if(type instanceof NameQualifiedType) { - NameQualifiedType castedType = (NameQualifiedType) type; - addToSet(castedType.getName().getFullyQualifiedName()); - } - else if(type instanceof ParameterizedType) { - ParameterizedType castedType = (ParameterizedType) type; - coupleTo(castedType.getType()); - } - else if(type instanceof WildcardType) { - WildcardType castedType = (WildcardType) type; - coupleTo(castedType.getBound()); - } - else if(type instanceof ArrayType) { - ArrayType castedType = (ArrayType) type; - coupleTo(castedType.getElementType()); - } - else if(type instanceof IntersectionType) { - IntersectionType castedType = (IntersectionType) type; - List types = castedType.types(); - types.stream().forEach(x -> coupleTo(x)); - } - else if(type instanceof UnionType) { - UnionType castedType = (UnionType) type; - List types = castedType.types(); - types.stream().forEach(x -> coupleTo(x)); - } - } - } - } - - private void coupleTo(SimpleName name) { - if(this.className != null) { - addToSet(name.getFullyQualifiedName()); - } - } - - private void coupleTo(ITypeBinding binding) { - - if(this.className != null) { - if (binding == null) - return; - if (binding.isWildcardType()) - return; - if (binding.isNullType()) - return; - - String type = binding.getQualifiedName(); - if (type.equals("null")) - return; - - if (isFromJava(type) || binding.isPrimitive()) - return; - - - String cleanedType = cleanClassName(type); - addToSet(cleanedType); - } - } - - private void coupleTo(IMethodBinding binding) { - - if(binding == null) - return; - - String methodNameInvoked = JDTUtils.getQualifiedMethodFullName(binding); - - if (methodNameInvoked.equals("null")) - return; - - if (isFromJava(methodNameInvoked)) - return; - - addToSet(methodNameInvoked); - - } - - private String cleanClassName(String type) { - // remove possible array(s) in the class name - String cleanedType = type.replace("[]", "").replace("\\$", "."); - - // remove generics declaration, let's stype with the type - if(cleanedType.contains("<")) - cleanedType = cleanedType.substring(0, cleanedType.indexOf("<")); - - return cleanedType; - } - - private boolean isFromJava(String type) { - return type.startsWith("java.") || type.startsWith("javax."); - } - - private void addToSet(String name) { - if(className != null){ - this.extras.addToSetClassIn(name, this.className); - this.extras.addToSetClassOut(this.className, name); - } else { - this.extras.addToSetMethodIn(name, this.methodName); - this.extras.addToSetMethodOut(this.methodName, name); - } - } - - @Override - public void setResult(CKClassResult result) { - - } - - @Override - public void setResult(CKMethodResult result) { - - } - - @Override - public void setClassName(String className) { - this.className = className; - } - - @Override - public void setMethodName(String methodName) { - this.methodName = methodName; - } - -} +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; +import com.github.mauricioaniche.ck.CKMethodResult; +import com.github.mauricioaniche.ck.util.JDTUtils; + +import org.eclipse.jdt.core.dom.*; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class Coupling implements CKASTVisitor, ClassLevelMetric, MethodLevelMetric { + + private CouplingExtras extras; + private String className; + private String methodName; + + public Coupling() { + this.extras = CouplingExtras.getInstance(); + } + + @Override + public void visit(VariableDeclarationStatement node) { + if(this.className != null) { + coupleTo(node.getType()); + } + } + + @Override + public void visit(ClassInstanceCreation node) { + if(this.className != null) { + coupleTo(node.getType()); + } else if(this.methodName != null) { + IMethodBinding binding = node.resolveConstructorBinding(); + coupleTo(binding); + } + } + + @Override + public void visit(ArrayCreation node) { + if(this.className != null) { + coupleTo(node.getType()); + } + } + + @Override + public void visit(FieldDeclaration node) { + if(this.className != null) { + coupleTo(node.getType()); + } + } + + public void visit(ReturnStatement node) { + if(this.className != null){ + if (node.getExpression() != null) { + coupleTo(node.getExpression().resolveTypeBinding()); + } + } + } + + @Override + public void visit(TypeLiteral node) { + if(this.className != null) { + coupleTo(node.getType()); + } + } + + public void visit(ThrowStatement node) { + if(this.className != null) { + if(node.getExpression()!=null) + coupleTo(node.getExpression().resolveTypeBinding()); + } + } + + @Override + public void visit(RecordDeclaration node) { + if(this.className != null) { + ITypeBinding resolvedType = node.resolveBinding(); + + ITypeBinding binding = resolvedType.getSuperclass(); + coupleTo(binding); + for (ITypeBinding interfaces : resolvedType.getInterfaces()) { + coupleTo(interfaces); + } + } + } + + public void visit(TypeDeclaration node) { + if(this.className != null) { + ITypeBinding resolvedType = node.resolveBinding(); + + if(resolvedType!=null) { + ITypeBinding binding = resolvedType.getSuperclass(); + if (binding != null) + coupleTo(binding); + + for (ITypeBinding interfaces : resolvedType.getInterfaces()) { + coupleTo(interfaces); + } + } else { + coupleTo(node.getSuperclassType()); + List list = node.superInterfaceTypes(); + list.forEach(x -> coupleTo(x)); + } + } + + } + + public void visit(MethodDeclaration node) { + if(this.className != null) { + IMethodBinding resolvedMethod = node.resolveBinding(); + if (resolvedMethod != null) { + + coupleTo(resolvedMethod.getReturnType()); + + for (ITypeBinding param : resolvedMethod.getParameterTypes()) { + coupleTo(param); + } + } else { + coupleTo(node.getReturnType2()); + List list = node.typeParameters(); + list.forEach(x -> coupleTo(x.getName())); + } + } + + } + + @Override + public void visit(CastExpression node) { + if(this.className != null) { + coupleTo(node.getType()); + } + + } + + @Override + public void visit(InstanceofExpression node) { + if(this.className != null) { + coupleTo(node.getRightOperand()); + coupleTo(node.getLeftOperand().resolveTypeBinding()); + } + + } + + @Override + public void visit(MethodInvocation node) { + + IMethodBinding binding = node.resolveMethodBinding(); + if(binding!=null) { + if(this.className != null) { + coupleTo(binding.getDeclaringClass()); + } else if(this.methodName != null) { + coupleTo(binding); + } + } + + } + + public void visit(NormalAnnotation node) { + if(this.className != null) { + coupleTo(node); + } + } + + public void visit(MarkerAnnotation node) { + if(this.className != null) { + coupleTo(node); + } + } + + public void visit(SingleMemberAnnotation node) { + if(this.className != null) { + coupleTo(node); + } + } + + public void visit(ParameterizedType node) { + if(this.className != null) { + + try { + ITypeBinding binding = node.resolveBinding(); + if (binding != null) { + + coupleTo(binding); + + for (ITypeBinding types : binding.getTypeArguments()) { + coupleTo(types); + } + } else { + coupleTo(node.getType()); + } + } catch (NullPointerException e) { + // TODO: handle exception + } + } + + } + private void coupleTo(Annotation type) { + if(this.className != null) { + ITypeBinding resolvedType = type.resolveTypeBinding(); + if(resolvedType!=null) + coupleTo(resolvedType); + else { + addToSet(type.getTypeName().getFullyQualifiedName()); + } + } + } + + private void coupleTo(Type type) { + if(type==null) + return; + + if(this.className != null) { + ITypeBinding resolvedBinding = type.resolveBinding(); + if(resolvedBinding!=null) + coupleTo(resolvedBinding); + else { + if(type instanceof SimpleType) { + SimpleType castedType = (SimpleType) type; + addToSet(castedType.getName().getFullyQualifiedName()); + } + else if(type instanceof QualifiedType) { + QualifiedType castedType = (QualifiedType) type; + addToSet(castedType.getName().getFullyQualifiedName()); + } + else if(type instanceof NameQualifiedType) { + NameQualifiedType castedType = (NameQualifiedType) type; + addToSet(castedType.getName().getFullyQualifiedName()); + } + else if(type instanceof ParameterizedType) { + ParameterizedType castedType = (ParameterizedType) type; + coupleTo(castedType.getType()); + } + else if(type instanceof WildcardType) { + WildcardType castedType = (WildcardType) type; + coupleTo(castedType.getBound()); + } + else if(type instanceof ArrayType) { + ArrayType castedType = (ArrayType) type; + coupleTo(castedType.getElementType()); + } + else if(type instanceof IntersectionType) { + IntersectionType castedType = (IntersectionType) type; + List types = castedType.types(); + types.stream().forEach(x -> coupleTo(x)); + } + else if(type instanceof UnionType) { + UnionType castedType = (UnionType) type; + List types = castedType.types(); + types.stream().forEach(x -> coupleTo(x)); + } + } + } + } + + private void coupleTo(SimpleName name) { + if(this.className != null) { + addToSet(name.getFullyQualifiedName()); + } + } + + private void coupleTo(ITypeBinding binding) { + + if(this.className != null) { + if (binding == null) + return; + if (binding.isWildcardType()) + return; + if (binding.isNullType()) + return; + + String type = binding.getQualifiedName(); + if (type.equals("null")) + return; + + if (isFromJava(type) || binding.isPrimitive()) + return; + + + String cleanedType = cleanClassName(type); + addToSet(cleanedType); + } + } + + private void coupleTo(IMethodBinding binding) { + + if(binding == null) + return; + + String methodNameInvoked = JDTUtils.getQualifiedMethodFullName(binding); + + if (methodNameInvoked.equals("null")) + return; + + if (isFromJava(methodNameInvoked)) + return; + + addToSet(methodNameInvoked); + + } + + private String cleanClassName(String type) { + // remove possible array(s) in the class name + String cleanedType = type.replace("[]", "").replace("\\$", "."); + + // remove generics declaration, let's stype with the type + if(cleanedType.contains("<")) + cleanedType = cleanedType.substring(0, cleanedType.indexOf("<")); + + return cleanedType; + } + + private boolean isFromJava(String type) { + return type.startsWith("java.") || type.startsWith("javax."); + } + + private void addToSet(String name) { + if(className != null){ + this.extras.addToSetClassIn(name, this.className); + this.extras.addToSetClassOut(this.className, name); + } else { + this.extras.addToSetMethodIn(name, this.methodName); + this.extras.addToSetMethodOut(this.methodName, name); + } + } + + @Override + public void setResult(CKClassResult result) { + + } + + @Override + public void setResult(CKMethodResult result) { + + } + + @Override + public void setClassName(String className) { + this.className = className; + } + + @Override + public void setMethodName(String methodName) { + this.methodName = methodName; + } + +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/DIT.java b/src/main/java/com/github/mauricioaniche/ck/metric/DIT.java index 32f25f68..38e33daf 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/DIT.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/DIT.java @@ -1,35 +1,42 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.TypeDeclaration; - -public class DIT implements CKASTVisitor, ClassLevelMetric { - - int dit = 1; // Object is the father of everyone! - - @Override - public void visit(TypeDeclaration node) { - ITypeBinding binding = node.resolveBinding(); - if(binding!=null) calculate(binding); - - } - - private void calculate(ITypeBinding binding) { - ITypeBinding father = binding.getSuperclass(); - if (father != null) { - String fatherName = father.getQualifiedName(); - if (fatherName.endsWith("Object")) return; - dit++; - - calculate(father); - } - - } - - @Override - public void setResult(CKClassResult result) { - result.setDit(dit); - } - -} +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; +import org.eclipse.jdt.core.dom.ITypeBinding; +import org.eclipse.jdt.core.dom.RecordDeclaration; +import org.eclipse.jdt.core.dom.TypeDeclaration; + +public class DIT implements CKASTVisitor, ClassLevelMetric { + + int dit = 1; // Object is the father of everyone! + + @Override + public void visit(RecordDeclaration node) { + ITypeBinding binding = node.resolveBinding(); + if(binding!=null) calculate(binding); + } + + @Override + public void visit(TypeDeclaration node) { + ITypeBinding binding = node.resolveBinding(); + if(binding!=null) calculate(binding); + + } + + private void calculate(ITypeBinding binding) { + ITypeBinding father = binding.getSuperclass(); + if (father != null) { + String fatherName = father.getQualifiedName(); + if (fatherName.endsWith("Object")) return; + dit++; + + calculate(father); + } + + } + + @Override + public void setResult(CKClassResult result) { + result.setDit(dit); + } + +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/LCOM.java b/src/main/java/com/github/mauricioaniche/ck/metric/LCOM.java index 232514e3..ddaa521e 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/LCOM.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/LCOM.java @@ -1,71 +1,71 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import org.eclipse.jdt.core.dom.*; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; -import java.util.TreeSet; - -public class LCOM implements CKASTVisitor, ClassLevelMetric { - - ArrayList> methods = new ArrayList>(); - Set declaredFields; - - public LCOM() { - this.declaredFields = new HashSet(); - } - - public void visit(FieldDeclaration node) { - - for(Object o : node.fragments()) { - VariableDeclarationFragment vdf = (VariableDeclarationFragment) o; - declaredFields.add(vdf.getName().toString()); - } - - } - - public void visit(SimpleName node) { - String name = node.getFullyQualifiedName(); - if(declaredFields.contains(name)) { - acessed(name); - } - - } - - private void acessed(String name) { - if(!methods.isEmpty()){ - methods.get(methods.size() - 1).add(name); - } - } - - public void visit(MethodDeclaration node) { - methods.add(new TreeSet()); - - } - - @Override - public void setResult(CKClassResult result) { - - /* - * LCOM = |P| - |Q| if |P| - |Q| > 0 - * where - * P = set of all empty set intersections - * Q = set of all nonempty set intersections - */ - - // extracted from https://github.com/dspinellis/ckjm - int lcom = 0; - for (int i = 0; i < methods.size(); i++) - for (int j = i + 1; j < methods.size(); j++) { - - TreeSet intersection = (TreeSet)methods.get(i).clone(); - intersection.retainAll(methods.get(j)); - if (intersection.size() == 0) lcom++; - else lcom--; - } - result.setLcom(lcom > 0 ? lcom : 0); - } - -} +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; +import org.eclipse.jdt.core.dom.*; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; +import java.util.TreeSet; + +public class LCOM implements CKASTVisitor, ClassLevelMetric { + + ArrayList> methods = new ArrayList>(); + Set declaredFields; + + public LCOM() { + this.declaredFields = new HashSet(); + } + + public void visit(FieldDeclaration node) { + + for(Object o : node.fragments()) { + VariableDeclarationFragment vdf = (VariableDeclarationFragment) o; + declaredFields.add(vdf.getName().toString()); + } + + } + + public void visit(SimpleName node) { + String name = node.getFullyQualifiedName(); + if(declaredFields.contains(name)) { + acessed(name); + } + + } + + private void acessed(String name) { + if(!methods.isEmpty()){ + methods.get(methods.size() - 1).add(name); + } + } + + public void visit(MethodDeclaration node) { + methods.add(new TreeSet()); + + } + + @Override + public void setResult(CKClassResult result) { + + /* + * LCOM = |P| - |Q| if |P| - |Q| > 0 + * where + * P = set of all empty set intersections + * Q = set of all nonempty set intersections + */ + + // extracted from https://github.com/dspinellis/ckjm + int lcom = 0; + for (int i = 0; i < methods.size(); i++) + for (int j = i + 1; j < methods.size(); j++) { + + TreeSet intersection = (TreeSet)methods.get(i).clone(); + intersection.retainAll(methods.get(j)); + if (intersection.size() == 0) lcom++; + else lcom--; + } + result.setLcom(lcom > 0 ? lcom : 0); + } + +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/LCOMNormalized.java b/src/main/java/com/github/mauricioaniche/ck/metric/LCOMNormalized.java index e30a3229..666ac7e4 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/LCOMNormalized.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/LCOMNormalized.java @@ -1,108 +1,102 @@ -package com.github.mauricioaniche.ck.metric; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.TreeSet; - -import org.eclipse.jdt.core.dom.FieldDeclaration; -import org.eclipse.jdt.core.dom.IMethodBinding; -import org.eclipse.jdt.core.dom.MethodDeclaration; -import org.eclipse.jdt.core.dom.SimpleName; -import org.eclipse.jdt.core.dom.VariableDeclarationFragment; - -import com.github.mauricioaniche.ck.CKClassResult; -import com.github.mauricioaniche.ck.util.JDTUtils; - -public class LCOMNormalized implements CKASTVisitor, ClassLevelMetric { - - HashMap> declaredFields; - ArrayList methods; - ArrayList flags; - - public LCOMNormalized() { - this.declaredFields = new HashMap<>(); - this.methods = new ArrayList(); - this.flags = new ArrayList(); - } - - public void visit(FieldDeclaration node) { - - for(Object o : node.fragments()) { - VariableDeclarationFragment vdf = (VariableDeclarationFragment) o; - declaredFields.put(vdf.getName().toString(), new TreeSet()); - } - - } - - public void visit(SimpleName node) { - String name = node.getFullyQualifiedName(); - if(declaredFields.containsKey(name)) { - acessed(name); - } - - } - - private void acessed(String name) { - if(!methods.isEmpty()){ - this.declaredFields.get(name).add(this.methods.get(this.methods.size() - 1)); - } - } - - public void visit(MethodDeclaration node) { - - String currentMethodName = JDTUtils.getMethodFullName(node); - - if(!this.methods.isEmpty()){ - if(this.methods.get(this.methods.size() - 1).equals(currentMethodName)){ - if(this.flags.get(this.flags.size() - 1) == 0){ - this.flags.set((this.flags.size() - 1), 1); - }else{ - this.methods.add(currentMethodName); - this.flags.add(0); - } - } else{ - this.methods.add(currentMethodName); - this.flags.add(0); - } - } else { - this.methods.add(currentMethodName); - this.flags.add(0); - } - - } - - @Override - public void setResult(CKClassResult result) { - - /* - * LCOM = 1/a * (Σ{i=1 to a} {(m - μ(Ai)) / m}) - * where - * a = number of attributes - * m = number of methods - * Σ{i=1 to a} = sum from 1 to a (number of attributes) - * μ(Ai) = number of methods accessing attribute Ai - * - * This version of computing LCOM is based on Henderson-Sellers definition: - * Henderson-Sellers, Brian, Larry L. Constantine and Ian M. Graham. "Coupling and cohesion (towards a valid metrics suite for object-oriented analysis and design)." Object Oriented Systems 3 (1996): 143-158. - */ - - // formula (13) extracted from https://github.com/cqfn/jpeek/blob/master/papers/sellers96_LCOM2_LCOM3_LCOM5.pdf - float sum = 0; - float lcomNormalized = 0; - - int numberOfAttributes = this.declaredFields.size(); - int numberOfMethods = this.methods.size(); - - for (String key : this.declaredFields.keySet()) - sum = sum + (((float) (numberOfMethods - this.declaredFields.get(key).size())) / numberOfMethods); - - if(numberOfAttributes > 0) - lcomNormalized = (((float) 1) * sum) / numberOfAttributes; - - result.setLcomNormalized(lcomNormalized); - - } - -} +package com.github.mauricioaniche.ck.metric; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.TreeSet; + +import org.eclipse.jdt.core.dom.*; + +import com.github.mauricioaniche.ck.CKClassResult; +import com.github.mauricioaniche.ck.util.JDTUtils; + +public class LCOMNormalized implements CKASTVisitor, ClassLevelMetric { + + HashMap> declaredFields; + ArrayList methods; + ArrayList flags; + + public LCOMNormalized() { + this.declaredFields = new HashMap<>(); + this.methods = new ArrayList(); + this.flags = new ArrayList(); + } + + public void visit(FieldDeclaration node) { + + for(Object o : node.fragments()) { + VariableDeclarationFragment vdf = (VariableDeclarationFragment) o; + declaredFields.put(vdf.getName().toString(), new TreeSet()); + } + + } + + public void visit(SimpleName node) { + String name = node.getFullyQualifiedName(); + if(declaredFields.containsKey(name)) { + acessed(name); + } + + } + + private void acessed(String name) { + if(!methods.isEmpty()){ + this.declaredFields.get(name).add(this.methods.get(this.methods.size() - 1)); + } + } + + public void visit(MethodDeclaration node) { + + String currentMethodName = JDTUtils.getMethodFullName(node); + + if(!this.methods.isEmpty()){ + if(this.methods.get(this.methods.size() - 1).equals(currentMethodName)){ + if(this.flags.get(this.flags.size() - 1) == 0){ + this.flags.set((this.flags.size() - 1), 1); + }else{ + this.methods.add(currentMethodName); + this.flags.add(0); + } + } else{ + this.methods.add(currentMethodName); + this.flags.add(0); + } + } else { + this.methods.add(currentMethodName); + this.flags.add(0); + } + + } + + @Override + public void setResult(CKClassResult result) { + + /* + * LCOM = 1/a * (Σ{i=1 to a} {(m - μ(Ai)) / m}) + * where + * a = number of attributes + * m = number of methods + * Σ{i=1 to a} = sum from 1 to a (number of attributes) + * μ(Ai) = number of methods accessing attribute Ai + * + * This version of computing LCOM is based on Henderson-Sellers definition: + * Henderson-Sellers, Brian, Larry L. Constantine and Ian M. Graham. "Coupling and cohesion (towards a valid metrics suite for object-oriented analysis and design)." Object Oriented Systems 3 (1996): 143-158. + */ + + // formula (13) extracted from https://github.com/cqfn/jpeek/blob/master/papers/sellers96_LCOM2_LCOM3_LCOM5.pdf + float sum = 0; + float lcomNormalized = 0; + + int numberOfAttributes = this.declaredFields.size(); + int numberOfMethods = this.methods.size(); + + for (String key : this.declaredFields.keySet()) + sum = sum + (((float) (numberOfMethods - this.declaredFields.get(key).size())) / numberOfMethods); + + if(numberOfAttributes > 0) + lcomNormalized = (((float) 1) * sum) / numberOfAttributes; + + result.setLcomNormalized(lcomNormalized); + + } + +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/MethodInvocationsLocal.java b/src/main/java/com/github/mauricioaniche/ck/metric/MethodInvocationsLocal.java index 28664b57..13ba916d 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/MethodInvocationsLocal.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/MethodInvocationsLocal.java @@ -1,75 +1,76 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import com.github.mauricioaniche.ck.CKMethodResult; -import java.util.*; -import java.util.stream.Collectors; - -//we ignore invocations in the super class, because they are always outside the current class and can never return -@RunAfter(metrics={RFC.class, MethodLevelFieldUsageCount.class}) -public class MethodInvocationsLocal implements CKASTVisitor, ClassLevelMetric { - //Recursively extract all method invocations starting with the given method - //Explored contains all previously explored invocations - //Invocations contains all direct method invocations of interest - //The algorithm is a depth first search - private Map> invocations(String invokedMethod, Map> explored, HashMap> invocations){ - //only explore local method invocations that were not previously explored - Set exploredKeys = explored.keySet(); - Set nextInvocations = invocations.get(invokedMethod).stream() - .filter(invoked -> !exploredKeys.contains(invoked) && !invoked.equals(invokedMethod)) - .collect(Collectors.toSet()); - if(nextInvocations.size() > 0){ - explored.put(invokedMethod, nextInvocations); - - for (String nextInvocation : nextInvocations){ - explored = invocations(nextInvocation, explored, invocations); - } - } - - //Stops when all invocations are explored: there are no more invocations to be explored - return explored; - } - - //Generate an indirect method invocations map - //Method contains all methods of interest - //Invocations contains all indirect method invocations of interest with the calling method - private HashMap>> invocationsIndirect(Set methods, HashMap> methodInvocationsLocal){ - HashMap>> methodInvocationsIndirectLocal = new HashMap<>(); - - //extract all indirect local invocations for all methods in the current class - for (CKMethodResult method : methods){ - //extract all local invocations for the current method - Map> localInvocations = invocations(method.getQualifiedMethodName(), new HashMap(), methodInvocationsLocal); - methodInvocationsIndirectLocal.put(method.getQualifiedMethodName(), localInvocations); - } - return methodInvocationsIndirectLocal; - } - - //Extract all local(inner-class) method invocations and save them in a HashMap - private HashMap> extractLocalInvocations(Set methods){ - HashMap> methodInvocationsLocal = new HashMap<>(); - - Set methodNames = methods.stream().map(CKMethodResult::getQualifiedMethodName).collect(Collectors.toSet()); - for (CKMethodResult method : methods){ - Set invokedLocal = method.getMethodInvocations().stream() - .filter(methodNames::contains) - .collect(Collectors.toSet()); - methodInvocationsLocal.put(method.getQualifiedMethodName(), invokedLocal); - } - return methodInvocationsLocal; - } - - public void setResult(CKClassResult result) { - //extract all direct local invocations for all methods in the current class - Set methods = result.getMethods(); - HashMap> methodInvocationsLocal = extractLocalInvocations(methods); - for (CKMethodResult method : methods){ - method.setMethodInvocationLocal(methodInvocationsLocal.get(method.getQualifiedMethodName())); - } - - HashMap>> methodInvocationsIndirectLocal = invocationsIndirect(methods, methodInvocationsLocal); - for (CKMethodResult method : methods){ - method.setMethodInvocationsIndirectLocal(methodInvocationsIndirectLocal.get(method.getQualifiedMethodName())); - } - } +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; +import com.github.mauricioaniche.ck.CKMethodResult; + +import java.util.*; +import java.util.stream.Collectors; + +//we ignore invocations in the super class, because they are always outside the current class and can never return +@RunAfter(metrics={RFC.class, MethodLevelFieldUsageCount.class}) +public class MethodInvocationsLocal implements CKASTVisitor, ClassLevelMetric { + //Recursively extract all method invocations starting with the given method + //Explored contains all previously explored invocations + //Invocations contains all direct method invocations of interest + //The algorithm is a depth first search + private Map> invocations(String invokedMethod, Map> explored, HashMap> invocations){ + //only explore local method invocations that were not previously explored + Set exploredKeys = explored.keySet(); + Set nextInvocations = invocations.get(invokedMethod).stream() + .filter(invoked -> !exploredKeys.contains(invoked) && !invoked.equals(invokedMethod)) + .collect(Collectors.toSet()); + if(nextInvocations.size() > 0){ + explored.put(invokedMethod, nextInvocations); + + for (String nextInvocation : nextInvocations){ + explored = invocations(nextInvocation, explored, invocations); + } + } + + //Stops when all invocations are explored: there are no more invocations to be explored + return explored; + } + + //Generate an indirect method invocations map + //Method contains all methods of interest + //Invocations contains all indirect method invocations of interest with the calling method + private HashMap>> invocationsIndirect(Set methods, HashMap> methodInvocationsLocal){ + HashMap>> methodInvocationsIndirectLocal = new HashMap<>(); + + //extract all indirect local invocations for all methods in the current class + for (CKMethodResult method : methods){ + //extract all local invocations for the current method + Map> localInvocations = invocations(method.getQualifiedMethodName(), new HashMap(), methodInvocationsLocal); + methodInvocationsIndirectLocal.put(method.getQualifiedMethodName(), localInvocations); + } + return methodInvocationsIndirectLocal; + } + + //Extract all local(inner-class) method invocations and save them in a HashMap + private HashMap> extractLocalInvocations(Set methods){ + HashMap> methodInvocationsLocal = new HashMap<>(); + + Set methodNames = methods.stream().map(CKMethodResult::getQualifiedMethodName).collect(Collectors.toSet()); + for (CKMethodResult method : methods){ + Set invokedLocal = method.getMethodInvocations().stream() + .filter(methodNames::contains) + .collect(Collectors.toSet()); + methodInvocationsLocal.put(method.getQualifiedMethodName(), invokedLocal); + } + return methodInvocationsLocal; + } + + public void setResult(CKClassResult result) { + //extract all direct local invocations for all methods in the current class + Set methods = result.getMethods(); + HashMap> methodInvocationsLocal = extractLocalInvocations(methods); + for (CKMethodResult method : methods){ + method.setMethodInvocationLocal(methodInvocationsLocal.get(method.getQualifiedMethodName())); + } + + HashMap>> methodInvocationsIndirectLocal = invocationsIndirect(methods, methodInvocationsLocal); + for (CKMethodResult method : methods){ + method.setMethodInvocationsIndirectLocal(methodInvocationsIndirectLocal.get(method.getQualifiedMethodName())); + } + } } \ No newline at end of file diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/MethodLevelWordCounter.java b/src/main/java/com/github/mauricioaniche/ck/metric/MethodLevelWordCounter.java index 07792a98..005ffc38 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/MethodLevelWordCounter.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/MethodLevelWordCounter.java @@ -1,37 +1,36 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKMethodResult; -import com.github.mauricioaniche.ck.util.WordCounter; -import org.eclipse.jdt.core.dom.Initializer; -import org.eclipse.jdt.core.dom.MethodDeclaration; -import org.eclipse.jdt.core.dom.TypeDeclaration; - -import static com.github.mauricioaniche.ck.util.WordCounter.removeSpacesAndIdentation; - -public class MethodLevelWordCounter implements CKASTVisitor, MethodLevelMetric { - private String methodSourceCode; - - public void visit(MethodDeclaration node) { - this.methodSourceCode = removeSpacesAndIdentation(node.toString()); - } - - public void visit(Initializer node) { - this.methodSourceCode = removeSpacesAndIdentation(node.toString()); - } - - public void visit(TypeDeclaration node) { - - String otherType = removeSpacesAndIdentation(node.toString()); - - methodSourceCode = removeSpacesAndIdentation(methodSourceCode.replace(otherType, "")); - } - - @Override - public void setResult(CKMethodResult result) { - int qtyOfUniqueWords = WordCounter.wordsIn(methodSourceCode).size(); - - result.setUniqueWordsQty(qtyOfUniqueWords); - } - - -} +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKMethodResult; +import com.github.mauricioaniche.ck.util.WordCounter; +import org.eclipse.jdt.core.dom.Initializer; +import org.eclipse.jdt.core.dom.MethodDeclaration; +import org.eclipse.jdt.core.dom.RecordDeclaration; +import org.eclipse.jdt.core.dom.TypeDeclaration; + +import static com.github.mauricioaniche.ck.util.WordCounter.removeSpacesAndIdentation; + +public class MethodLevelWordCounter implements CKASTVisitor, MethodLevelMetric { + private String methodSourceCode; + + public void visit(MethodDeclaration node) { + this.methodSourceCode = removeSpacesAndIdentation(node.toString()); + } + + public void visit(Initializer node) { + this.methodSourceCode = removeSpacesAndIdentation(node.toString()); + } + + public void visit(TypeDeclaration node) { + + String otherType = removeSpacesAndIdentation(node.toString()); + + methodSourceCode = removeSpacesAndIdentation(methodSourceCode.replace(otherType, "")); + } + + @Override + public void setResult(CKMethodResult result) { + int qtyOfUniqueWords = WordCounter.wordsIn(methodSourceCode).size(); + + result.setUniqueWordsQty(qtyOfUniqueWords); + } +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/NOC.java b/src/main/java/com/github/mauricioaniche/ck/metric/NOC.java index 6e851c54..092c62ee 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/NOC.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/NOC.java @@ -1,58 +1,53 @@ -package com.github.mauricioaniche.ck.metric; - -import java.util.List; -import java.util.stream.Collectors; - -import org.eclipse.jdt.core.IType; -import org.eclipse.jdt.core.dom.ITypeBinding; -import org.eclipse.jdt.core.dom.ParameterizedType; -import org.eclipse.jdt.core.dom.SimpleType; -import org.eclipse.jdt.core.dom.Type; -import org.eclipse.jdt.core.dom.TypeDeclaration; - -import com.github.mauricioaniche.ck.CKClassResult; - -public class NOC implements CKASTVisitor, ClassLevelMetric{ - - private String name; - private NOCExtras extras; - - public NOC() { - this.extras = NOCExtras.getInstance(); - } - - @Override - public void visit(TypeDeclaration node){ - ITypeBinding binding = node.resolveBinding(); - - if(binding != null){ - this.name = binding.getQualifiedName(); - ITypeBinding father = binding.getSuperclass(); - if(father != null){ - this.extras.plusOne(father.getQualifiedName()); - } - } else { - this.name = node.getName().getFullyQualifiedName(); - Type type = node.getSuperclassType(); - - SimpleType castedFatherType = null; - - if(node.getSuperclassType() instanceof SimpleType) - castedFatherType = ((SimpleType) node.getSuperclassType()); - - if(castedFatherType != null){ - this.extras.plusOne(castedFatherType.getName().getFullyQualifiedName()); - } - List list = node.superInterfaceTypes(); - list = list.stream().filter(x -> (x instanceof SimpleType)).collect(Collectors.toList()); - list.stream().map(x -> (SimpleType) x).forEach(x -> this.extras.plusOne(x.getName().getFullyQualifiedName())); - } - - } - - @Override - public void setResult(CKClassResult result) { - - } - -} +package com.github.mauricioaniche.ck.metric; + +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.jdt.core.dom.*; + +import com.github.mauricioaniche.ck.CKClassResult; + +public class NOC implements CKASTVisitor, ClassLevelMetric{ + + private String name; + private NOCExtras extras; + + public NOC() { + this.extras = NOCExtras.getInstance(); + } + + @Override + public void visit(TypeDeclaration node){ + ITypeBinding binding = node.resolveBinding(); + + if(binding != null){ + this.name = binding.getQualifiedName(); + ITypeBinding father = binding.getSuperclass(); + if(father != null){ + this.extras.plusOne(father.getQualifiedName()); + } + } else { + this.name = node.getName().getFullyQualifiedName(); + Type type = node.getSuperclassType(); + + SimpleType castedFatherType = null; + + if(node.getSuperclassType() instanceof SimpleType) + castedFatherType = ((SimpleType) node.getSuperclassType()); + + if(castedFatherType != null){ + this.extras.plusOne(castedFatherType.getName().getFullyQualifiedName()); + } + List list = node.superInterfaceTypes(); + list = list.stream().filter(x -> (x instanceof SimpleType)).collect(Collectors.toList()); + list.stream().map(x -> (SimpleType) x).forEach(x -> this.extras.plusOne(x.getName().getFullyQualifiedName())); + } + + } + + @Override + public void setResult(CKClassResult result) { + + } + +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfFields.java b/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfFields.java index 5a431a56..c9a0638b 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfFields.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfFields.java @@ -1,70 +1,85 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import org.eclipse.jdt.core.dom.FieldDeclaration; -import org.eclipse.jdt.core.dom.Modifier; - -import java.util.HashSet; -import java.util.Set; - -import static com.github.mauricioaniche.ck.util.JDTUtils.getVariableName; - -public class NumberOfFields implements CKASTVisitor, ClassLevelMetric { - - private Set fieldNames = new HashSet<>(); - private int fields; - private int staticFields; - private int publicFields; - private int privateFields; - private int protectedFields; - private int defaultFields; - private int finalFields; - private int synchronizedFields; - - @Override - public void visit(FieldDeclaration node) { - fields++; - fieldNames.addAll(getVariableName(node.fragments())); - - boolean isPublic = Modifier.isPublic(node.getModifiers()); - boolean isPrivate = Modifier.isPrivate(node.getModifiers()); - boolean isProtected = Modifier.isProtected(node.getModifiers()); - - if(isPublic) - publicFields++; - else if(isPrivate) - privateFields++; - else if(isProtected) - protectedFields++; - else - defaultFields++; - - // other characteristics rather than visibility - boolean isStatic = Modifier.isStatic(node.getModifiers()); - boolean isFinal = Modifier.isFinal(node.getModifiers()); - boolean isSynchronized = Modifier.isSynchronized(node.getModifiers()); - - if(isStatic) - staticFields++; - - if(isFinal) - finalFields++; - - if(isSynchronized) - synchronizedFields++; - - } - - @Override - public void setResult(CKClassResult result) { - result.setNumberOfFields(fields); - result.setFieldNames(fieldNames); - result.setNumberOfStaticFields(staticFields); - result.setNumberOfPublicFields(publicFields); - result.setNumberOfPrivateFields(privateFields); - result.setNumberOfProtectedFields(protectedFields); - result.setNumberOfDefaultFields(defaultFields); - result.setNumberOfFinalFields(finalFields); - result.setNumberOfSynchronizedFields(synchronizedFields); - } +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; +import org.eclipse.jdt.core.dom.FieldDeclaration; +import org.eclipse.jdt.core.dom.Modifier; +import org.eclipse.jdt.core.dom.RecordDeclaration; +import org.eclipse.jdt.core.dom.SingleVariableDeclaration; + +import java.util.HashSet; +import java.util.Set; + +import static com.github.mauricioaniche.ck.util.JDTUtils.getVariableName; + +public class NumberOfFields implements CKASTVisitor, ClassLevelMetric { + + private Set fieldNames = new HashSet<>(); + private int fields; + private int staticFields; + private int publicFields; + private int privateFields; + private int protectedFields; + private int defaultFields; + private int finalFields; + private int synchronizedFields; + + @Override + public void visit(RecordDeclaration node) { + for(Object member : node.recordComponents()) { + SingleVariableDeclaration variable = (SingleVariableDeclaration) member; + + fields++; + fieldNames.add(variable.getName().getIdentifier()); + + privateFields++; + finalFields++; + } + } + + @Override + public void visit(FieldDeclaration node) { + fields++; + fieldNames.addAll(getVariableName(node.fragments())); + + boolean isPublic = Modifier.isPublic(node.getModifiers()); + boolean isPrivate = Modifier.isPrivate(node.getModifiers()); + boolean isProtected = Modifier.isProtected(node.getModifiers()); + + if(isPublic) + publicFields++; + else if(isPrivate) + privateFields++; + else if(isProtected) + protectedFields++; + else + defaultFields++; + + // other characteristics rather than visibility + boolean isStatic = Modifier.isStatic(node.getModifiers()); + boolean isFinal = Modifier.isFinal(node.getModifiers()); + boolean isSynchronized = Modifier.isSynchronized(node.getModifiers()); + + if(isStatic) + staticFields++; + + if(isFinal) + finalFields++; + + if(isSynchronized) + synchronizedFields++; + + } + + @Override + public void setResult(CKClassResult result) { + result.setNumberOfFields(fields); + result.setFieldNames(fieldNames); + result.setNumberOfStaticFields(staticFields); + result.setNumberOfPublicFields(publicFields); + result.setNumberOfPrivateFields(privateFields); + result.setNumberOfProtectedFields(protectedFields); + result.setNumberOfDefaultFields(defaultFields); + result.setNumberOfFinalFields(finalFields); + result.setNumberOfSynchronizedFields(synchronizedFields); + } } \ No newline at end of file diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfInnerClassesLambdasAndAnonymousClasses.java b/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfInnerClassesLambdasAndAnonymousClasses.java index eb67c09a..61328668 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfInnerClassesLambdasAndAnonymousClasses.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/NumberOfInnerClassesLambdasAndAnonymousClasses.java @@ -1,59 +1,67 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import com.github.mauricioaniche.ck.CKMethodResult; -import org.eclipse.jdt.core.dom.*; - -public class NumberOfInnerClassesLambdasAndAnonymousClasses implements CKASTVisitor, ClassLevelMetric, MethodLevelMetric { - - private int anonymousClassesQty = 0; - private int innerClassesQty = 0; - private int lambdasQty = 0; - - private String firstFound = null; - - public void visit(TypeDeclaration node) { - - if(firstFound == null) - firstFound = "type"; - - innerClassesQty++; - } - - public void visit(EnumDeclaration node) { - // we count enum as class declaration! - innerClassesQty++; - - if(firstFound == null) - firstFound = "enum"; - } - - public void visit(LambdaExpression node) { - lambdasQty++; - - if(firstFound == null) - firstFound = "lambda"; - } - - public void visit(AnonymousClassDeclaration node) { - anonymousClassesQty++; - - if(firstFound == null) - firstFound = "anonymous"; - } - - @Override - public void setResult(CKClassResult result) { - // the -1 there is because the main type under analysis here is counted as +1. - result.setAnonymousClassesQty(anonymousClassesQty - (firstFound.equals("anonymous")?1:0)); - result.setInnerClassesQty(innerClassesQty - (firstFound.equals("type") || firstFound.equals("enum")?1:0)); - result.setLambdasQty(lambdasQty - (firstFound.equals("lambda")?1:0)); - } - - @Override - public void setResult(CKMethodResult result) { - result.setAnonymousClassesQty(anonymousClassesQty); - result.setInnerClassesQty(innerClassesQty); - result.setLambdasQty(lambdasQty); - } -} +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; +import com.github.mauricioaniche.ck.CKMethodResult; +import org.eclipse.jdt.core.dom.*; + +public class NumberOfInnerClassesLambdasAndAnonymousClasses implements CKASTVisitor, ClassLevelMetric, MethodLevelMetric { + + private int anonymousClassesQty = 0; + private int innerClassesQty = 0; + private int lambdasQty = 0; + + private String firstFound = null; + + public void visit(TypeDeclaration node) { + + if(firstFound == null) + firstFound = "type"; + + innerClassesQty++; + } + + @Override + public void visit(RecordDeclaration node) { + if(firstFound == null) + firstFound = "record"; + + innerClassesQty++; + } + + public void visit(EnumDeclaration node) { + // we count enum as class declaration! + innerClassesQty++; + + if(firstFound == null) + firstFound = "enum"; + } + + public void visit(LambdaExpression node) { + lambdasQty++; + + if(firstFound == null) + firstFound = "lambda"; + } + + public void visit(AnonymousClassDeclaration node) { + anonymousClassesQty++; + + if(firstFound == null) + firstFound = "anonymous"; + } + + @Override + public void setResult(CKClassResult result) { + // the -1 there is because the main type under analysis here is counted as +1. + result.setAnonymousClassesQty(anonymousClassesQty - (firstFound.equals("anonymous")?1:0)); + result.setInnerClassesQty(innerClassesQty - (firstFound.equals("type") || firstFound.equals("enum")?1:0)); + result.setLambdasQty(lambdasQty - (firstFound.equals("lambda")?1:0)); + } + + @Override + public void setResult(CKMethodResult result) { + result.setAnonymousClassesQty(anonymousClassesQty); + result.setInnerClassesQty(innerClassesQty); + result.setLambdasQty(lambdasQty); + } +} diff --git a/src/main/java/com/github/mauricioaniche/ck/metric/TightClassCohesion.java b/src/main/java/com/github/mauricioaniche/ck/metric/TightClassCohesion.java index 78b2d604..eebe1626 100644 --- a/src/main/java/com/github/mauricioaniche/ck/metric/TightClassCohesion.java +++ b/src/main/java/com/github/mauricioaniche/ck/metric/TightClassCohesion.java @@ -1,132 +1,133 @@ -package com.github.mauricioaniche.ck.metric; - -import com.github.mauricioaniche.ck.CKClassResult; -import com.github.mauricioaniche.ck.CKMethodResult; -import com.google.common.collect.Sets; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.tuple.ImmutablePair; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; -import java.util.stream.Collectors; - -//Calculates the tight and loose class cohesion for a class. -//For more details see: https://www.aivosto.com/project/help/pm-oo-cohesion.html#TCC_LCC -@RunAfter(metrics={RFC.class, MethodLevelFieldUsageCount.class, MethodInvocationsLocal.class}) -public class TightClassCohesion implements CKASTVisitor, ClassLevelMetric { - private HashMap> accessedFields = new HashMap<>(); - - //Two methods are directly connected if: - //1. both access the same class-level variable - //2. their call trees access the same class-level variable (only within the class) - private Set> getDirectConnections(CKClassResult result){ - for (CKMethodResult method : result.getMethods()){ - accessedFields.put(method.getMethodName(), method.getFieldsAccessed()); - } - - HashMap> allAccessedFields = new HashMap<>(); - for (CKMethodResult method : result.getVisibleMethods()){ - Set allLocalFields = collectAccessedFields(method); - allLocalFields.addAll(method.getFieldsAccessed()); - allAccessedFields.put(method.getMethodName(), allLocalFields); - } - - Set> directConnections = new HashSet<>(); - for(String firstKey : allAccessedFields.keySet()){ - for(String secondKey : allAccessedFields.keySet()){ - Set accessedFieldsFirst = Sets.newHashSet(allAccessedFields.get(firstKey)); - Set accessedFieldsSecond = allAccessedFields.get(secondKey); - accessedFieldsFirst.retainAll(accessedFieldsSecond); - if(!firstKey.equals(secondKey) && accessedFieldsFirst.size() > 0){ - directConnections.add(new ImmutablePair(firstKey, secondKey)); - } - } - } - return directConnections; - } - - //Collect all accessed fields from the invocation tree of a method - private Set collectAccessedFields(CKMethodResult method){ - Set allLocalInvocations = method.getMethodInvocationsIndirectLocal().keySet(); - - Set allLocalFields = new HashSet<>(); - for (String invocation : allLocalInvocations){ - Set currentFields = accessedFields.get(invocation); - if(currentFields != null) - allLocalFields.addAll(currentFields); - } - - return allLocalFields; - } - - //Two methods are indirectly connected if: - //1. they are not directly connected - //2. they are connected via other methods, e.g. X -> Y -> Z - private Set> getIndirectConnections(CKClassResult result, Set> directConnections){ - //convert the direct connections into a Map in order to simplify the usage - HashMap> directConnectionsMap = new HashMap<>(); - for(CKMethodResult method : result.getMethods()){ - directConnectionsMap.put(method.getMethodName(), Sets.newHashSet(Sets.newHashSet(ArrayUtils.EMPTY_STRING_ARRAY))); - } - for(ImmutablePair pair : directConnections){ - directConnectionsMap.get(pair.left).add(pair.right); - } - - //extract all direct and indirect connections between methods from the direct connections - HashMap> indirectConnectionsMap = new HashMap<>(); - for (CKMethodResult method : result.getVisibleMethods()){ - Set localConnections = extractConnections(method.getMethodName(), new HashSet<>(), directConnectionsMap); - indirectConnectionsMap.put(method.getMethodName(), localConnections); - } - - //map the indirect connections into connection pairs - Set> indirectConnections = new HashSet<>(); - for(String key : indirectConnectionsMap.keySet()){ - indirectConnections.addAll(indirectConnectionsMap.get(key).stream() - .filter(right -> !key.equals(right)) - .map(right -> new ImmutablePair(key, right)) - .collect(Collectors.toSet())); - } - //remove all direct connections - indirectConnections.removeAll(directConnections); - return indirectConnections; - } - - //Recursively extract all indirect connections between methods starting with the given method - //Explored contains all previously explored connections - //connections contains all direct method connections of interest - private Set extractConnections(String currentConnection, Set explored, HashMap> connections){ - explored.add(currentConnection); - - //only explore connections that were not previously explored - Set nextConnections = connections.get(currentConnection).stream() - .filter(connection -> !explored.contains(connection)) - .collect(Collectors.toSet()); - explored.addAll(nextConnections); - for (String nextConnection : nextConnections){ - explored.addAll(extractConnections(nextConnection, explored, connections)); - } - - //Stops when all invocations are explored: there are no more invocations to be explored - return explored; - } - - public void setResult(CKClassResult result) { - //in case the class does not contain any visible methods, TCC and LCC have no reasonable value, thus set it to -1 - if(result.getVisibleMethods().size() < 1){ - result.setTightClassCohesion(-1); - result.setLooseClassCohesion(-1); - } else { - //maximum number of possible connections (N * (N -1)) - float np = result.getVisibleMethods().size() * (result.getVisibleMethods().size() - 1); - - //number of direct connections (number of edges in the connection graph) in this class - Set> directConnections = getDirectConnections(result); - result.setTightClassCohesion(directConnections.size() / np); - - //number of indirect connections in this class - Set> indirectConnections = getIndirectConnections(result, directConnections); - result.setLooseClassCohesion((directConnections.size() + indirectConnections.size()) / np); - } - } +package com.github.mauricioaniche.ck.metric; + +import com.github.mauricioaniche.ck.CKClassResult; +import com.github.mauricioaniche.ck.CKMethodResult; +import com.google.common.collect.Sets; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +//Calculates the tight and loose class cohesion for a class. +//For more details see: https://www.aivosto.com/project/help/pm-oo-cohesion.html#TCC_LCC +@RunAfter(metrics={RFC.class, MethodLevelFieldUsageCount.class, MethodInvocationsLocal.class}) +public class TightClassCohesion implements CKASTVisitor, ClassLevelMetric { + private HashMap> accessedFields = new HashMap<>(); + + //Two methods are directly connected if: + //1. both access the same class-level variable + //2. their call trees access the same class-level variable (only within the class) + private Set> getDirectConnections(CKClassResult result){ + for (CKMethodResult method : result.getMethods()){ + accessedFields.put(method.getMethodName(), method.getFieldsAccessed()); + } + + HashMap> allAccessedFields = new HashMap<>(); + for (CKMethodResult method : result.getVisibleMethods()){ + Set allLocalFields = collectAccessedFields(method); + allLocalFields.addAll(method.getFieldsAccessed()); + allAccessedFields.put(method.getMethodName(), allLocalFields); + } + + Set> directConnections = new HashSet<>(); + for(String firstKey : allAccessedFields.keySet()){ + for(String secondKey : allAccessedFields.keySet()){ + Set accessedFieldsFirst = Sets.newHashSet(allAccessedFields.get(firstKey)); + Set accessedFieldsSecond = allAccessedFields.get(secondKey); + accessedFieldsFirst.retainAll(accessedFieldsSecond); + if(!firstKey.equals(secondKey) && accessedFieldsFirst.size() > 0){ + directConnections.add(new ImmutablePair(firstKey, secondKey)); + } + } + } + return directConnections; + } + + //Collect all accessed fields from the invocation tree of a method + private Set collectAccessedFields(CKMethodResult method){ + Set allLocalInvocations = method.getMethodInvocationsIndirectLocal().keySet(); + + Set allLocalFields = new HashSet<>(); + for (String invocation : allLocalInvocations){ + Set currentFields = accessedFields.get(invocation); + if(currentFields != null) + allLocalFields.addAll(currentFields); + } + + return allLocalFields; + } + + //Two methods are indirectly connected if: + //1. they are not directly connected + //2. they are connected via other methods, e.g. X -> Y -> Z + private Set> getIndirectConnections(CKClassResult result, Set> directConnections){ + //convert the direct connections into a Map in order to simplify the usage + HashMap> directConnectionsMap = new HashMap<>(); + for(CKMethodResult method : result.getMethods()){ + directConnectionsMap.put(method.getMethodName(), Sets.newHashSet(Sets.newHashSet(ArrayUtils.EMPTY_STRING_ARRAY))); + } + for(ImmutablePair pair : directConnections){ + directConnectionsMap.get(pair.left).add(pair.right); + } + + //extract all direct and indirect connections between methods from the direct connections + HashMap> indirectConnectionsMap = new HashMap<>(); + for (CKMethodResult method : result.getVisibleMethods()){ + Set localConnections = extractConnections(method.getMethodName(), new HashSet<>(), directConnectionsMap); + indirectConnectionsMap.put(method.getMethodName(), localConnections); + } + + //map the indirect connections into connection pairs + Set> indirectConnections = new HashSet<>(); + for(String key : indirectConnectionsMap.keySet()){ + indirectConnections.addAll(indirectConnectionsMap.get(key).stream() + .filter(right -> !key.equals(right)) + .map(right -> new ImmutablePair(key, right)) + .collect(Collectors.toSet())); + } + //remove all direct connections + indirectConnections.removeAll(directConnections); + return indirectConnections; + } + + //Recursively extract all indirect connections between methods starting with the given method + //Explored contains all previously explored connections + //connections contains all direct method connections of interest + private Set extractConnections(String currentConnection, Set explored, HashMap> connections){ + explored.add(currentConnection); + + //only explore connections that were not previously explored + Set nextConnections = connections.get(currentConnection).stream() + .filter(connection -> !explored.contains(connection)) + .collect(Collectors.toSet()); + explored.addAll(nextConnections); + for (String nextConnection : nextConnections){ + explored.addAll(extractConnections(nextConnection, explored, connections)); + } + + //Stops when all invocations are explored: there are no more invocations to be explored + return explored; + } + + public void setResult(CKClassResult result) { + //in case the class does not contain any visible methods, TCC and LCC have no reasonable value, thus set it to -1 + if(result.getVisibleMethods().size() < 1){ + result.setTightClassCohesion(-1); + result.setLooseClassCohesion(-1); + } else { + //maximum number of possible connections (N * (N -1)) + float np = result.getVisibleMethods().size() * (result.getVisibleMethods().size() - 1); + + //number of direct connections (number of edges in the connection graph) in this class + Set> directConnections = getDirectConnections(result); + result.setTightClassCohesion(directConnections.size() / np); + + //number of indirect connections in this class + Set> indirectConnections = getIndirectConnections(result, directConnections); + result.setLooseClassCohesion((directConnections.size() + indirectConnections.size()) / np); + } + } } \ No newline at end of file diff --git a/src/main/java/com/github/mauricioaniche/ck/util/MetricsFinder.java b/src/main/java/com/github/mauricioaniche/ck/util/MetricsFinder.java index 7734e2f1..6f31d578 100644 --- a/src/main/java/com/github/mauricioaniche/ck/util/MetricsFinder.java +++ b/src/main/java/com/github/mauricioaniche/ck/util/MetricsFinder.java @@ -1,82 +1,79 @@ -package com.github.mauricioaniche.ck.util; - -import com.github.mauricioaniche.ck.metric.ClassLevelMetric; -import com.github.mauricioaniche.ck.metric.MethodLevelMetric; -import com.github.mauricioaniche.ck.metric.RunAfter; -import com.github.mauricioaniche.ck.metric.VariableOrFieldMetric; -import org.reflections.Reflections; - -import java.util.*; -import java.util.stream.Collectors; - -public class MetricsFinder { - - private static List> methodLevelClasses = null; - private static List> classLevelClasses = null; - private DependencySorter sorter; - - public MetricsFinder(DependencySorter sorter) { - this.sorter = sorter; - } - - public MetricsFinder() { - this(new DependencySorter()); - } - - public List allMethodLevelMetrics(boolean variablesAndFields) { - if(methodLevelClasses == null) - loadMethodLevelClasses(variablesAndFields); - - try { - ArrayList metrics = new ArrayList<>(); - for (Class aClass : methodLevelClasses) { - metrics.add(aClass.getDeclaredConstructor().newInstance()); - } - - return metrics; - } catch(Exception e) { - throw new RuntimeException("Could not instantiate a method level metric. Something is really wrong", e); - } - } - - public List allClassLevelMetrics() { - - if(classLevelClasses == null) - loadClassLevelClasses(); - - try { - ArrayList metrics = new ArrayList<>(); - for (Class aClass : classLevelClasses) { - metrics.add(aClass.getDeclaredConstructor().newInstance()); - } - - return metrics; - } catch(Exception e) { - throw new RuntimeException("Could not instantiate a method level metric. Something is really wrong", e); - } - } - - private void loadMethodLevelClasses(boolean variablesAndFields) { - try { - Reflections reflections = new Reflections("com.github.mauricioaniche.ck.metric"); - - methodLevelClasses = sorter.sort(reflections.getSubTypesOf(MethodLevelMetric.class).stream() - .filter(x -> variablesAndFields || !Arrays.asList(x.getInterfaces()).contains(VariableOrFieldMetric.class)) - .collect(Collectors.toList())); - - } catch(Exception e) { - throw new RuntimeException("Could not find method level metrics. Something is really wrong", e); - } - } - - private void loadClassLevelClasses() { - try { - Reflections reflections = new Reflections("com.github.mauricioaniche.ck.metric"); - classLevelClasses = sorter.sort(new ArrayList<>(reflections.getSubTypesOf(ClassLevelMetric.class))); - } catch(Exception e) { - throw new RuntimeException("Could not find class level metrics. Something is really wrong", e); - } - } - - -} +package com.github.mauricioaniche.ck.util; + +import com.github.mauricioaniche.ck.metric.*; +import org.reflections.Reflections; + +import java.util.*; +import java.util.stream.Collectors; + +public class MetricsFinder { + + private static List> methodLevelClasses = null; + private static List> classLevelClasses = null; + private DependencySorter sorter; + + public MetricsFinder(DependencySorter sorter) { + this.sorter = sorter; + } + + public MetricsFinder() { + this(new DependencySorter()); + } + + public List allMethodLevelMetrics(boolean variablesAndFields) { + if(methodLevelClasses == null) + loadMethodLevelClasses(variablesAndFields); + + try { + ArrayList metrics = new ArrayList<>(); + for (Class aClass : methodLevelClasses) { + metrics.add(aClass.getDeclaredConstructor().newInstance()); + } + + return metrics; + } catch(Exception e) { + throw new RuntimeException("Could not instantiate a method level metric. Something is really wrong", e); + } + } + + public List allClassLevelMetrics() { + + if(classLevelClasses == null) + loadClassLevelClasses(); + + try { + ArrayList metrics = new ArrayList<>(); + for (Class aClass : classLevelClasses) { + metrics.add(aClass.getDeclaredConstructor().newInstance()); + } + + return metrics; + } catch(Exception e) { + throw new RuntimeException("Could not instantiate a method level metric. Something is really wrong", e); + } + } + + private void loadMethodLevelClasses(boolean variablesAndFields) { + try { + Reflections reflections = new Reflections("com.github.mauricioaniche.ck.metric"); + + methodLevelClasses = sorter.sort(reflections.getSubTypesOf(MethodLevelMetric.class).stream() + .filter(x -> variablesAndFields || !Arrays.asList(x.getInterfaces()).contains(VariableOrFieldMetric.class)) + .collect(Collectors.toList())); + + } catch(Exception e) { + throw new RuntimeException("Could not find method level metrics. Something is really wrong", e); + } + } + + private void loadClassLevelClasses() { + try { + Reflections reflections = new Reflections("com.github.mauricioaniche.ck.metric"); + classLevelClasses = sorter.sort(new ArrayList<>(reflections.getSubTypesOf(ClassLevelMetric.class))); + } catch(Exception e) { + throw new RuntimeException("Could not find class level metrics. Something is really wrong", e); + } + } + + +} diff --git a/src/test/java/com/github/mauricioaniche/ck/ASTDebugger.java b/src/test/java/com/github/mauricioaniche/ck/ASTDebugger.java index 0d60bac9..d8f892fd 100644 --- a/src/test/java/com/github/mauricioaniche/ck/ASTDebugger.java +++ b/src/test/java/com/github/mauricioaniche/ck/ASTDebugger.java @@ -1,380 +1,381 @@ -package com.github.mauricioaniche.ck; - -import com.github.mauricioaniche.ck.metric.CKASTVisitor; -import com.github.mauricioaniche.ck.metric.ClassLevelMetric; -import org.eclipse.jdt.core.dom.*; - -public class ASTDebugger implements CKASTVisitor, ClassLevelMetric { - - - public void visit(AnnotationTypeDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(AnnotationTypeMemberDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(AnonymousClassDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ArrayAccess node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ArrayCreation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ArrayInitializer node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ArrayType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(AssertStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(Assignment node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(Block node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(BlockComment node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(BooleanLiteral node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(BreakStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(CastExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(CatchClause node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(CharacterLiteral node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ClassInstanceCreation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(CompilationUnit node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ConditionalExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ConstructorInvocation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ContinueStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(CreationReference node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(Dimension node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(DoStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(EmptyStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(EnhancedForStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(EnumConstantDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(EnumDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ExpressionMethodReference node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ExpressionStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(FieldAccess node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(FieldDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ForStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(IfStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ImportDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(InfixExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(Initializer node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(InstanceofExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(IntersectionType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(LabeledStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(LambdaExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(LineComment node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(MarkerAnnotation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(MemberRef node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(MemberValuePair node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(MethodRef node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(MethodRefParameter node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(MethodDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(MethodInvocation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(Modifier node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(NameQualifiedType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(NormalAnnotation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(NullLiteral node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(NumberLiteral node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(PackageDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ParameterizedType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ParenthesizedExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(PostfixExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(PrefixExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(PrimitiveType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(QualifiedName node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(QualifiedType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ReturnStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SimpleName node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SimpleType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SingleMemberAnnotation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SingleVariableDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(StringLiteral node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SuperConstructorInvocation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SuperFieldAccess node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SuperMethodInvocation node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SuperMethodReference node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SwitchCase node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SwitchStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(SynchronizedStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(TagElement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(TextElement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ThisExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(ThrowStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(TryStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(TypeDeclaration node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(TypeDeclarationStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(TypeLiteral node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(TypeMethodReference node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(TypeParameter node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(UnionType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(VariableDeclarationExpression node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(VariableDeclarationStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(VariableDeclarationFragment node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(WhileStatement node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - public void visit(WildcardType node) { - System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); - } - - - - @Override - public void setResult(CKClassResult result) { - - } -} +package com.github.mauricioaniche.ck; + +import com.github.mauricioaniche.ck.metric.CKASTVisitor; +import com.github.mauricioaniche.ck.metric.ClassLevelMetric; +import org.eclipse.jdt.core.dom.*; + +public class ASTDebugger implements CKASTVisitor, ClassLevelMetric { + + public void visit(AnnotationTypeDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(AnnotationTypeMemberDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(AnonymousClassDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ArrayAccess node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ArrayCreation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ArrayInitializer node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ArrayType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(AssertStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(Assignment node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(Block node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(BlockComment node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(BooleanLiteral node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(BreakStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(CastExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(CatchClause node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(CharacterLiteral node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ClassInstanceCreation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(CompilationUnit node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ConditionalExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ConstructorInvocation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ContinueStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(CreationReference node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(Dimension node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(DoStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(EmptyStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(EnhancedForStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(EnumConstantDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(EnumDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ExpressionMethodReference node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ExpressionStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(FieldAccess node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(FieldDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ForStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(IfStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ImportDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(InfixExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(Initializer node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(InstanceofExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(IntersectionType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(LabeledStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(LambdaExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(LineComment node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(MarkerAnnotation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(MemberRef node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(MemberValuePair node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(MethodRef node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(MethodRefParameter node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(MethodDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(MethodInvocation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(Modifier node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(NameQualifiedType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(NormalAnnotation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(NullLiteral node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(NumberLiteral node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(PackageDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ParameterizedType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ParenthesizedExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(PostfixExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(PrefixExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(PrimitiveType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(QualifiedName node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(QualifiedType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(RecordDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ReturnStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SimpleName node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SimpleType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SingleMemberAnnotation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SingleVariableDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(StringLiteral node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SuperConstructorInvocation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SuperFieldAccess node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SuperMethodInvocation node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SuperMethodReference node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SwitchCase node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SwitchStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(SynchronizedStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(TagElement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(TextElement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ThisExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(ThrowStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(TryStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(TypeDeclaration node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(TypeDeclarationStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(TypeLiteral node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(TypeMethodReference node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(TypeParameter node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(UnionType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(VariableDeclarationExpression node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(VariableDeclarationStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(VariableDeclarationFragment node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(WhileStatement node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + public void visit(WildcardType node) { + System.out.println("-- " + node.getClass().getSimpleName()); System.out.println(node.toString()); + } + + @Override + public void setResult(CKClassResult result) { + + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/CBOTest.java b/src/test/java/com/github/mauricioaniche/ck/CBOTest.java index 9e6e0d5c..d13b22cd 100644 --- a/src/test/java/com/github/mauricioaniche/ck/CBOTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/CBOTest.java @@ -1,141 +1,147 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class CBOTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/cbo"); - } - - @Test - public void ignoreJavaTypes() { - CKClassResult a = report.get("cbo.Coupling0"); - Assertions.assertEquals(0, a.getCbo()); - } - - @Test - public void countDifferentPossibilitiesOfDependencies() { - - CKClassResult a = report.get("cbo.Coupling1"); - Assertions.assertEquals(6, a.getCbo()); - } - - @Test - public void countEvenWhenNotResolved() { - - CKClassResult a = report.get("cbo.Coupling3"); - Assertions.assertEquals(1, a.getCbo()); - } - - @Test - public void countInterfacesAndInheritances() { - - CKClassResult b = report.get("cbo.Coupling2"); - Assertions.assertEquals(5, b.getCbo()); - } - - @Test - public void countClassCreations() { - CKClassResult b = report.get("cbo.Coupling4"); - Assertions.assertEquals(3, b.getCbo()); - } - - @Test - public void countMethodParameters() { - - CKClassResult b = report.get("cbo.MethodParams"); - Assertions.assertEquals(2, b.getCbo()); - } - - @Test - public void methodLevel() { - CKClassResult b = report.get("cbo.Coupling5"); - Assertions.assertEquals(0, b.getMethod("am1/0").get().getCbo()); - Assertions.assertEquals(1, b.getMethod("am2/0").get().getCbo()); - Assertions.assertEquals(1, b.getMethod("am3/0").get().getCbo()); - Assertions.assertEquals(2, b.getMethod("am4/0").get().getCbo()); - } - - @Test - public void fullOfNonResolvedTypes() { - CKClassResult b = report.get("cbo.NotResolved"); - Assertions.assertEquals(5, b.getCbo()); - } - - // based on issue #43 - @Test - public void couplingWithGenericsAndJavaType() { - CKClassResult b = report.get("cbo.Coupling6"); - Assertions.assertEquals(1, b.getCbo()); - - CKClassResult c = report.get("cbo.Coupling61"); - Assertions.assertEquals(1, c.getCbo()); - - CKClassResult d = report.get("cbo.Coupling62"); - Assertions.assertEquals(2, d.getCbo()); - - CKClassResult e = report.get("cbo.Coupling63"); - Assertions.assertEquals(2, e.getCbo()); - - CKClassResult f = report.get("cbo.Coupling64"); - Assertions.assertEquals(2, f.getCbo()); - - CKClassResult g = report.get("cbo.Coupling65"); - Assertions.assertEquals(2, g.getCbo()); - - } - - @Test - public void moreCouplingWithGenericsAndJavaType() { - CKClassResult b = report.get("cbo.Coupling7"); - Assertions.assertEquals(1, b.getCbo()); - - CKClassResult c = report.get("cbo.Coupling71"); - Assertions.assertEquals(1, c.getCbo()); - - CKClassResult d = report.get("cbo.Coupling72"); - Assertions.assertEquals(2, d.getCbo()); - - CKClassResult e = report.get("cbo.Coupling73"); - Assertions.assertEquals(2, e.getCbo()); - - CKClassResult f = report.get("cbo.Coupling74"); - Assertions.assertEquals(2, f.getCbo()); - - CKClassResult g = report.get("cbo.Coupling75"); - Assertions.assertEquals(2, g.getCbo()); - - } - - @Test - public void staticMethodCallInReturnStatement() { - CKClassResult a = report.get("cbo.Coupling12"); - Assertions.assertEquals(3, a.getCbo()); - } - - @Test - public void arrayCreation() { - CKClassResult a = report.get("cbo.Coupling9"); - Assertions.assertEquals(3, a.getCbo()); - } - - @Test - public void resolveNull() { - CKClassResult a = report.get("cbo.Coupling10"); - Assertions.assertEquals(2, a.getCbo()); - } - - @Test - public void annotationCheck() { - CKClassResult a = report.get("cbo.Coupling11"); - Assertions.assertEquals(6, a.getCbo()); - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.util.Map; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class CBOTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/cbo"); + } + + @Test + public void ignoreJavaTypes() { + CKClassResult a = report.get("cbo.Coupling0"); + Assertions.assertEquals(0, a.getCbo()); + } + + @Test + public void countDifferentPossibilitiesOfDependencies() { + + CKClassResult a = report.get("cbo.Coupling1"); + Assertions.assertEquals(6, a.getCbo()); + + CKClassResult b = report.get("cbo.RecordCoupling"); + Assertions.assertEquals(6, b.getCbo()); + } + + @Test + public void countEvenWhenNotResolved() { + + CKClassResult a = report.get("cbo.Coupling3"); + Assertions.assertEquals(1, a.getCbo()); + } + + @Test + public void countInterfacesAndInheritances() { + + CKClassResult b = report.get("cbo.Coupling2"); + Assertions.assertEquals(5, b.getCbo()); + + CKClassResult c = report.get("cbo.RecordCoupling"); + Assertions.assertEquals(6, c.getCbo()); + } + + @Test + public void countClassCreations() { + CKClassResult b = report.get("cbo.Coupling4"); + Assertions.assertEquals(3, b.getCbo()); + } + + @Test + public void countMethodParameters() { + + CKClassResult b = report.get("cbo.MethodParams"); + Assertions.assertEquals(2, b.getCbo()); + } + + @Test + public void methodLevel() { + CKClassResult b = report.get("cbo.Coupling5"); + Assertions.assertEquals(0, b.getMethod("am1/0").get().getCbo()); + Assertions.assertEquals(1, b.getMethod("am2/0").get().getCbo()); + Assertions.assertEquals(1, b.getMethod("am3/0").get().getCbo()); + Assertions.assertEquals(2, b.getMethod("am4/0").get().getCbo()); + } + + @Test + public void fullOfNonResolvedTypes() { + CKClassResult b = report.get("cbo.NotResolved"); + Assertions.assertEquals(5, b.getCbo()); + } + + // based on issue #43 + @Test + public void couplingWithGenericsAndJavaType() { + CKClassResult b = report.get("cbo.Coupling6"); + Assertions.assertEquals(1, b.getCbo()); + + CKClassResult c = report.get("cbo.Coupling61"); + Assertions.assertEquals(1, c.getCbo()); + + CKClassResult d = report.get("cbo.Coupling62"); + Assertions.assertEquals(2, d.getCbo()); + + CKClassResult e = report.get("cbo.Coupling63"); + Assertions.assertEquals(2, e.getCbo()); + + CKClassResult f = report.get("cbo.Coupling64"); + Assertions.assertEquals(2, f.getCbo()); + + CKClassResult g = report.get("cbo.Coupling65"); + Assertions.assertEquals(2, g.getCbo()); + + } + + @Test + public void moreCouplingWithGenericsAndJavaType() { + CKClassResult b = report.get("cbo.Coupling7"); + Assertions.assertEquals(1, b.getCbo()); + + CKClassResult c = report.get("cbo.Coupling71"); + Assertions.assertEquals(1, c.getCbo()); + + CKClassResult d = report.get("cbo.Coupling72"); + Assertions.assertEquals(2, d.getCbo()); + + CKClassResult e = report.get("cbo.Coupling73"); + Assertions.assertEquals(2, e.getCbo()); + + CKClassResult f = report.get("cbo.Coupling74"); + Assertions.assertEquals(2, f.getCbo()); + + CKClassResult g = report.get("cbo.Coupling75"); + Assertions.assertEquals(2, g.getCbo()); + + } + + @Test + public void staticMethodCallInReturnStatement() { + CKClassResult a = report.get("cbo.Coupling12"); + Assertions.assertEquals(3, a.getCbo()); + } + + @Test + public void arrayCreation() { + CKClassResult a = report.get("cbo.Coupling9"); + Assertions.assertEquals(3, a.getCbo()); + } + + @Test + public void resolveNull() { + CKClassResult a = report.get("cbo.Coupling10"); + Assertions.assertEquals(2, a.getCbo()); + } + + @Test + public void annotationCheck() { + CKClassResult a = report.get("cbo.Coupling11"); + Assertions.assertEquals(6, a.getCbo()); + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/ClassTypeTest.java b/src/test/java/com/github/mauricioaniche/ck/ClassTypeTest.java index 56c426f1..df94cfa8 100644 --- a/src/test/java/com/github/mauricioaniche/ck/ClassTypeTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/ClassTypeTest.java @@ -1,47 +1,47 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class ClassTypeTest extends BaseTest { - - private static Map report; - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/class-types"); - } - - - @Test - public void identifyTypesCorrectly() { - - Assertions.assertEquals(5, report.size()); - - CKClassResult a = report.get("classtypes.A"); - Assertions.assertEquals("class", a.getType()); - - CKClassResult b = report.get("classtypes.A$B"); - Assertions.assertEquals("innerclass", b.getType()); - - CKClassResult mathOperation = report.get("classtypes.MathOperation"); - Assertions.assertEquals("interface", mathOperation.getType()); - - CKClassResult anon1 = report.get("classtypes.A$Anonymous1"); - Assertions.assertEquals("anonymous", anon1.getType()); - - CKClassResult anon2 = report.get("classtypes.A$Anonymous2"); - Assertions.assertEquals("anonymous", anon2.getType()); - - - } - - -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Map; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class ClassTypeTest extends BaseTest { + + private static Map report; + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/class-types"); + } + + @Test + public void identifyTypesCorrectly() { + + Assertions.assertEquals(6, report.size()); + + CKClassResult a = report.get("classtypes.A"); + Assertions.assertEquals("class", a.getType()); + + CKClassResult b = report.get("classtypes.A$B"); + Assertions.assertEquals("innerclass", b.getType()); + + CKClassResult mathOperation = report.get("classtypes.MathOperation"); + Assertions.assertEquals("interface", mathOperation.getType()); + + CKClassResult anon1 = report.get("classtypes.A$Anonymous1"); + Assertions.assertEquals("anonymous", anon1.getType()); + + CKClassResult anon2 = report.get("classtypes.A$Anonymous2"); + Assertions.assertEquals("anonymous", anon2.getType()); + + CKClassResult aRecord = report.get("classtypes.ARecord"); + Assertions.assertEquals("record", aRecord.getType()); + } + + +} diff --git a/src/test/java/com/github/mauricioaniche/ck/DITTest.java b/src/test/java/com/github/mauricioaniche/ck/DITTest.java index aedf4aa7..1fee8641 100644 --- a/src/test/java/com/github/mauricioaniche/ck/DITTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/DITTest.java @@ -1,55 +1,60 @@ -package com.github.mauricioaniche.ck; - -import com.github.mauricioaniche.ck.metric.NOCExtras; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class DITTest extends BaseTest { - - private Map report; - - @BeforeAll - public void setUp() { - NOCExtras.resetInstance(); - report = run(fixturesDir() + "/dit"); - } - - @Test - public void everyOneHasObjectAsFather() { - CKClassResult a = report.get("dit.A"); - Assertions.assertEquals(1, a.getDit()); - } - - @Test - public void firstLevelInheritance() { - CKClassResult b = report.get("dit.B"); - Assertions.assertEquals(2, b.getDit()); - } - - @Test - public void twoLevelsInheritance() { - CKClassResult c = report.get("dit.C"); - Assertions.assertEquals(3, c.getDit()); - - CKClassResult c2 = report.get("dit.C2"); - Assertions.assertEquals(3, c2.getDit()); - } - - @Test - public void threeLevelsInheritance() { - CKClassResult d = report.get("dit.D"); - Assertions.assertEquals(4, d.getDit()); - } - - @Test - public void countEvenClassesNotResolved() { - CKClassResult a = report.get("dit.X"); - Assertions.assertEquals(2, a.getDit()); - } - -} +package com.github.mauricioaniche.ck; + +import com.github.mauricioaniche.ck.metric.NOCExtras; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.util.Map; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class DITTest extends BaseTest { + + private Map report; + + @BeforeAll + public void setUp() { + NOCExtras.resetInstance(); + report = run(fixturesDir() + "/dit"); + } + + @Test + public void everyOneHasObjectAsFather() { + CKClassResult a = report.get("dit.A"); + Assertions.assertEquals(1, a.getDit()); + } + + @Test + public void firstLevelInheritance() { + CKClassResult b = report.get("dit.B"); + Assertions.assertEquals(2, b.getDit()); + } + + @Test + public void twoLevelsInheritance() { + CKClassResult c = report.get("dit.C"); + Assertions.assertEquals(3, c.getDit()); + + CKClassResult c2 = report.get("dit.C2"); + Assertions.assertEquals(3, c2.getDit()); + } + + @Test + public void threeLevelsInheritance() { + CKClassResult d = report.get("dit.D"); + Assertions.assertEquals(4, d.getDit()); + } + + @Test + public void countEvenClassesNotResolved() { + CKClassResult a = report.get("dit.X"); + Assertions.assertEquals(2, a.getDit()); + } + + @Test + public void recordInheritance(){ + CKClassResult a = report.get("dit.RecordR"); + Assertions.assertEquals(2, a.getDit()); + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/FieldsTest.java b/src/test/java/com/github/mauricioaniche/ck/FieldsTest.java index 028852ef..c9f6a20d 100644 --- a/src/test/java/com/github/mauricioaniche/ck/FieldsTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/FieldsTest.java @@ -1,68 +1,89 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class FieldsTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/fields"); - } - - @Test - public void all() { - CKClassResult a = report.get("fields.Fields"); - Assertions.assertEquals(10, a.getNumberOfFields()); - } - - @Test - public void allPublic() { - CKClassResult a = report.get("fields.Fields"); - Assertions.assertEquals(3, a.getNumberOfPublicFields()); - } - - @Test - public void allStatic() { - CKClassResult a = report.get("fields.Fields"); - Assertions.assertEquals(3, a.getNumberOfStaticFields()); - } - - - @Test - public void allPrivate() { - CKClassResult a = report.get("fields.Fields"); - Assertions.assertEquals(4, a.getNumberOfPrivateFields()); - } - - - @Test - public void allDefault() { - CKClassResult a = report.get("fields.Fields"); - Assertions.assertEquals(2, a.getNumberOfDefaultFields()); - } - - @Test - public void allSynchronized() { - CKClassResult a = report.get("fields.Fields"); - Assertions.assertEquals(1, a.getNumberOfSynchronizedFields()); - } - - @Test - public void allProtected() { - CKClassResult a = report.get(("fields.Fields")); - Assertions.assertEquals(1, a.getNumberOfProtectedFields()); - } - - @Test - public void AllFinal() { - CKClassResult a = report.get(("fields.Fields")); - Assertions.assertEquals(1, a.getNumberOfFinalFields()); - - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class FieldsTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/fields"); + } + + @Test + public void all() { + CKClassResult a = report.get("fields.Fields"); + Assertions.assertEquals(10, a.getNumberOfFields()); + + CKClassResult b = report.get("fields.RecordFields"); + Assertions.assertEquals(4, b.getNumberOfFields()); + } + + @Test + public void allPublic() { + CKClassResult a = report.get("fields.Fields"); + Assertions.assertEquals(3, a.getNumberOfPublicFields()); + + CKClassResult b = report.get("fields.RecordFields"); + Assertions.assertEquals(0, b.getNumberOfPublicFields()); + } + + @Test + public void allStatic() { + CKClassResult a = report.get("fields.Fields"); + Assertions.assertEquals(3, a.getNumberOfStaticFields()); + + CKClassResult b = report.get("fields.RecordFields"); + Assertions.assertEquals(1, b.getNumberOfStaticFields()); + } + + + @Test + public void allPrivate() { + CKClassResult a = report.get("fields.Fields"); + Assertions.assertEquals(4, a.getNumberOfPrivateFields()); + + CKClassResult b = report.get("fields.RecordFields"); + Assertions.assertEquals(4, b.getNumberOfPrivateFields()); + } + + + @Test + public void allDefault() { + CKClassResult a = report.get("fields.Fields"); + Assertions.assertEquals(2, a.getNumberOfDefaultFields()); + + CKClassResult b = report.get("fields.RecordFields"); + Assertions.assertEquals(0, b.getNumberOfDefaultFields()); + } + + @Test + public void allSynchronized() { + CKClassResult a = report.get("fields.Fields"); + Assertions.assertEquals(1, a.getNumberOfSynchronizedFields()); + + CKClassResult b = report.get("fields.RecordFields"); + Assertions.assertEquals(0, b.getNumberOfSynchronizedFields()); + } + + @Test + public void allProtected() { + CKClassResult a = report.get(("fields.Fields")); + Assertions.assertEquals(1, a.getNumberOfProtectedFields()); + + CKClassResult b = report.get("fields.RecordFields"); + Assertions.assertEquals(0, b.getNumberOfProtectedFields()); + } + + @Test + public void AllFinal() { + CKClassResult a = report.get(("fields.Fields")); + Assertions.assertEquals(1, a.getNumberOfFinalFields()); + + CKClassResult b = report.get("fields.RecordFields"); + Assertions.assertEquals(4, b.getNumberOfFinalFields()); + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/MethodsTest.java b/src/test/java/com/github/mauricioaniche/ck/MethodsTest.java index 8e1952bd..ca186611 100644 --- a/src/test/java/com/github/mauricioaniche/ck/MethodsTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/MethodsTest.java @@ -1,114 +1,138 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; -import java.util.Optional; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class MethodsTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/methods"); - } - - @Test - public void all() { - CKClassResult a = report.get("methods.Methods"); - Assertions.assertEquals(9, a.getNumberOfMethods()); - } - - @Test - public void allPublic() { - CKClassResult a = report.get("methods.Methods"); - Assertions.assertEquals(4, a.getNumberOfPublicMethods()); - } - - @Test - public void allStatic() { - CKClassResult a = report.get("methods.Methods"); - Assertions.assertEquals(2, a.getNumberOfStaticMethods()); - } - - @Test - public void allDefault() { - CKClassResult a = report.get("methods.Methods"); - Assertions.assertEquals(1, a.getNumberOfDefaultMethods()); - } - - @Test - public void allPrivate() { - CKClassResult a = report.get("methods.Methods"); - Assertions.assertEquals(3, a.getNumberOfPrivateMethods()); - } - - @Test - public void allProtected() { - CKClassResult a = report.get("methods.Methods"); - Assertions.assertEquals(1, a.getNumberOfProtectedMethods()); - } - - - @Test - public void allSynchronized() { - CKClassResult a = report.get("methods.Methods"); - Assertions.assertEquals(1, a.getNumberOfSynchronizedMethods()); - } - - @Test - public void allAbstract() { - CKClassResult a = report.get("methods.Methods2"); - Assertions.assertEquals(3, a.getNumberOfMethods()); - Assertions.assertEquals(2, a.getNumberOfAbstractMethods()); - } - - @Test - public void constructors() { - CKClassResult a = report.get("methods.Methods3"); - Assertions.assertEquals(3, a.getNumberOfMethods()); - Assertions.assertEquals(3, a.getMethods().size()); - - CKMethodResult m1 = a.getMethods().stream().filter(x -> x.getMethodName().equals("Methods3/0")).findFirst().get(); - Assertions.assertTrue(m1.isConstructor()); - - CKMethodResult m2 = a.getMethods().stream().filter(x -> x.getMethodName().equals("Methods3/1[int]")).findFirst().get(); - Assertions.assertTrue(m2.isConstructor()); - - CKMethodResult m3 = a.getMethods().stream().filter(x -> x.getMethodName().equals("a/0")).findFirst().get(); - Assertions.assertFalse(m3.isConstructor()); - } - - @Test - public void staticInitializer() { - CKClassResult a = report.get("methods.StaticInitializer"); - - Optional init = a.getMethod("(initializer 1)"); - Assertions.assertTrue(init.isPresent()); - Assertions.assertEquals(1, init.get().getLoopQty()); - } - - // there can be multiple static initializers in a single class - // see https://github.com/mauricioaniche/ck/issues/53 - @Test - public void multipleStaticInitializer() { - CKClassResult a = report.get("methods.StaticInitializer2"); - - Optional init1 = a.getMethod("(initializer 1)"); - Assertions.assertTrue(init1.isPresent()); - Assertions.assertEquals(1, init1.get().getLoopQty()); - - Optional init2 = a.getMethod("(initializer 2)"); - Assertions.assertTrue(init2.isPresent()); - Assertions.assertEquals(0, init2.get().getLoopQty()); - } - - @Test - public void allFinal() { - CKClassResult a = report.get("methods.Methods"); - Assertions.assertEquals(1, a.getNumberOfFinalMethods()); - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.util.Optional; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class MethodsTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/methods"); + } + + @Test + public void all() { + CKClassResult a = report.get("methods.Methods"); + Assertions.assertEquals(9, a.getNumberOfMethods()); + + CKClassResult b = report.get("methods.OneRecord"); + Assertions.assertEquals(8, b.getNumberOfMethods()); + } + + @Test + public void allPublic() { + CKClassResult a = report.get("methods.Methods"); + Assertions.assertEquals(4, a.getNumberOfPublicMethods()); + + CKClassResult b = report.get("methods.OneRecord"); + Assertions.assertEquals(5, b.getNumberOfPublicMethods()); + } + + @Test + public void allStatic() { + CKClassResult a = report.get("methods.Methods"); + Assertions.assertEquals(2, a.getNumberOfStaticMethods()); + + CKClassResult b = report.get("methods.OneRecord"); + Assertions.assertEquals(1, b.getNumberOfStaticMethods()); + } + + @Test + public void allDefault() { + CKClassResult a = report.get("methods.Methods"); + Assertions.assertEquals(1, a.getNumberOfDefaultMethods()); + + CKClassResult b = report.get("methods.OneRecord"); + Assertions.assertEquals(1, b.getNumberOfDefaultMethods()); + } + + @Test + public void allPrivate() { + CKClassResult a = report.get("methods.Methods"); + Assertions.assertEquals(3, a.getNumberOfPrivateMethods()); + } + + @Test + public void allProtected() { + CKClassResult a = report.get("methods.Methods"); + Assertions.assertEquals(1, a.getNumberOfProtectedMethods()); + + CKClassResult b = report.get("methods.OneRecord"); + Assertions.assertEquals(1, b.getNumberOfProtectedMethods()); + } + + @Test + public void allSynchronized() { + CKClassResult a = report.get("methods.Methods"); + Assertions.assertEquals(1, a.getNumberOfSynchronizedMethods()); + + CKClassResult b = report.get("methods.OneRecord"); + Assertions.assertEquals(1, b.getNumberOfSynchronizedMethods()); + } + + @Test + public void allAbstract() { + CKClassResult a = report.get("methods.Methods2"); + Assertions.assertEquals(3, a.getNumberOfMethods()); + Assertions.assertEquals(2, a.getNumberOfAbstractMethods()); + } + + @Test + public void constructors() { + CKClassResult a = report.get("methods.Methods3"); + Assertions.assertEquals(3, a.getNumberOfMethods()); + Assertions.assertEquals(3, a.getMethods().size()); + + CKMethodResult m1 = a.getMethods().stream().filter(x -> x.getMethodName().equals("Methods3/0")).findFirst().get(); + Assertions.assertTrue(m1.isConstructor()); + + CKMethodResult m2 = a.getMethods().stream().filter(x -> x.getMethodName().equals("Methods3/1[int]")).findFirst().get(); + Assertions.assertTrue(m2.isConstructor()); + + CKMethodResult m3 = a.getMethods().stream().filter(x -> x.getMethodName().equals("a/0")).findFirst().get(); + Assertions.assertFalse(m3.isConstructor()); + + CKClassResult r = report.get("methods.OneRecord"); + System.out.println(r.getMethods()); + CKMethodResult rm1 = r.getMethods().stream().filter(x -> x.getMethodName().equals("OneRecord/2[java.lang.String,java.lang.Long]")).findFirst().get(); + Assertions.assertTrue(rm1.isConstructor()); + } + + @Test + public void staticInitializer() { + CKClassResult a = report.get("methods.StaticInitializer"); + + Optional init = a.getMethod("(initializer 1)"); + Assertions.assertTrue(init.isPresent()); + Assertions.assertEquals(1, init.get().getLoopQty()); + } + + // there can be multiple static initializers in a single class + // see https://github.com/mauricioaniche/ck/issues/53 + @Test + public void multipleStaticInitializer() { + CKClassResult a = report.get("methods.StaticInitializer2"); + + Optional init1 = a.getMethod("(initializer 1)"); + Assertions.assertTrue(init1.isPresent()); + Assertions.assertEquals(1, init1.get().getLoopQty()); + + Optional init2 = a.getMethod("(initializer 2)"); + Assertions.assertTrue(init2.isPresent()); + Assertions.assertEquals(0, init2.get().getLoopQty()); + } + + @Test + public void allFinal() { + CKClassResult a = report.get("methods.Methods"); + Assertions.assertEquals(1, a.getNumberOfFinalMethods()); + + CKClassResult b = report.get("methods.OneRecord"); + Assertions.assertEquals(1, b.getNumberOfFinalMethods()); + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/MetricsPerClassesAndInnerClassesTest.java b/src/test/java/com/github/mauricioaniche/ck/MetricsPerClassesAndInnerClassesTest.java index e4c70308..40297798 100644 --- a/src/test/java/com/github/mauricioaniche/ck/MetricsPerClassesAndInnerClassesTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/MetricsPerClassesAndInnerClassesTest.java @@ -1,61 +1,59 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class MetricsPerClassesAndInnerClassesTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/innerclasses"); - } - - @Test - public void metricsPerClass() { - - Assertions.assertEquals(9, report.values().size()); - - CKClassResult a = report.get("innerclasses.MessyClass"); - Assertions.assertEquals(6, a.getNumberOfMethods()); - Assertions.assertEquals("class", a.getType()); - - CKClassResult sc1 = report.get("innerclasses.MessyClass$InnerClass1"); - Assertions.assertEquals(2, sc1.getNumberOfMethods()); - Assertions.assertEquals(2, sc1.getMethods().stream().filter(x -> x.getMethodName().equals("m1/0")).findFirst().get().getMaxNestedBlocks()); - Assertions.assertEquals("innerclass", sc1.getType()); - - CKClassResult sc2 = report.get("innerclasses.MessyClass$InnerClass2"); - Assertions.assertEquals(3, sc2.getNumberOfMethods()); - Assertions.assertEquals("innerclass", sc2.getType()); - - CKClassResult sc3 = report.get("innerclasses.MessyClass$1InnerClass3"); - Assertions.assertEquals(1, sc3.getNumberOfMethods()); - Assertions.assertEquals("innerclass", sc3.getType()); - - CKClassResult an1 = report.get("innerclasses.MessyClass$Anonymous1"); - Assertions.assertEquals(1, an1.getNumberOfMethods()); - Assertions.assertEquals("anonymous", an1.getType()); - - CKClassResult an2 = report.get("innerclasses.MessyClass$Anonymous2"); - Assertions.assertEquals(2, an2.getNumberOfMethods()); - Assertions.assertEquals("anonymous", an2.getType()); - - - CKClassResult ysc2 = report.get("innerclasses.SC2"); - Assertions.assertEquals("class", ysc2.getType()); - CKClassResult ysc2a = report.get("innerclasses.SC2$Anonymous1"); - Assertions.assertEquals("anonymous", ysc2a.getType()); - CKClassResult ysc2x = report.get("innerclasses.SC2$1$1X"); - Assertions.assertEquals("innerclass", ysc2x.getType()); - - } - - - - -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class MetricsPerClassesAndInnerClassesTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/innerclasses"); + } + + @Test + public void metricsPerClass() { + + Assertions.assertEquals(18, report.values().size()); + + CKClassResult a = report.get("innerclasses.MessyClass"); + Assertions.assertEquals(6, a.getNumberOfMethods()); + Assertions.assertEquals("class", a.getType()); + + CKClassResult sc1 = report.get("innerclasses.MessyClass$InnerClass1"); + Assertions.assertEquals(2, sc1.getNumberOfMethods()); + Assertions.assertEquals(2, sc1.getMethods().stream().filter(x -> x.getMethodName().equals("m1/0")).findFirst().get().getMaxNestedBlocks()); + Assertions.assertEquals("innerclass", sc1.getType()); + + CKClassResult sc2 = report.get("innerclasses.MessyClass$InnerClass2"); + Assertions.assertEquals(3, sc2.getNumberOfMethods()); + Assertions.assertEquals("innerclass", sc2.getType()); + + CKClassResult sc3 = report.get("innerclasses.MessyClass$1InnerClass3"); + Assertions.assertEquals(1, sc3.getNumberOfMethods()); + Assertions.assertEquals("innerclass", sc3.getType()); + + CKClassResult an1 = report.get("innerclasses.MessyClass$Anonymous1"); + Assertions.assertEquals(1, an1.getNumberOfMethods()); + Assertions.assertEquals("anonymous", an1.getType()); + + CKClassResult an2 = report.get("innerclasses.MessyClass$Anonymous2"); + Assertions.assertEquals(2, an2.getNumberOfMethods()); + Assertions.assertEquals("anonymous", an2.getType()); + + + CKClassResult ysc2 = report.get("innerclasses.SC2"); + Assertions.assertEquals("class", ysc2.getType()); + CKClassResult ysc2a = report.get("innerclasses.SC2$Anonymous1"); + Assertions.assertEquals("anonymous", ysc2a.getType()); + CKClassResult ysc2x = report.get("innerclasses.SC2$1$1X"); + Assertions.assertEquals("innerclass", ysc2x.getType()); + + } + + + + +} diff --git a/src/test/java/com/github/mauricioaniche/ck/NumberOfAssignmentsTest.java b/src/test/java/com/github/mauricioaniche/ck/NumberOfAssignmentsTest.java index 83939c19..ce991919 100644 --- a/src/test/java/com/github/mauricioaniche/ck/NumberOfAssignmentsTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/NumberOfAssignmentsTest.java @@ -1,31 +1,39 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class NumberOfAssignmentsTest extends BaseTest { - - private Map report; - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/assignments"); - } - - @Test - public void count() { - CKClassResult a = report.get("assignments.Assignments"); - - Assertions.assertEquals(8, a.getAssignmentsQty()); - - Assertions.assertEquals(5, a.getMethod("m1/0").get().getAssignmentsQty()); - Assertions.assertEquals(3, a.getMethod("m2/0").get().getAssignmentsQty()); - Assertions.assertEquals(0, a.getMethod("m3/0").get().getAssignmentsQty()); - - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.util.Map; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class NumberOfAssignmentsTest extends BaseTest { + + private Map report; + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/assignments"); + } + + @Test + public void count() { + CKClassResult a = report.get("assignments.Assignments"); + + Assertions.assertEquals(8, a.getAssignmentsQty()); + + Assertions.assertEquals(5, a.getMethod("m1/0").get().getAssignmentsQty()); + Assertions.assertEquals(3, a.getMethod("m2/0").get().getAssignmentsQty()); + Assertions.assertEquals(0, a.getMethod("m3/0").get().getAssignmentsQty()); + + CKClassResult b = report.get("assignments.RecordAssignments"); + + Assertions.assertEquals(8, b.getAssignmentsQty()); + + Assertions.assertEquals(5, b.getMethod("m1/0").get().getAssignmentsQty()); + Assertions.assertEquals(3, b.getMethod("m2/0").get().getAssignmentsQty()); + Assertions.assertEquals(0, b.getMethod("m3/0").get().getAssignmentsQty()); + + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/NumberOfComparisonsTest.java b/src/test/java/com/github/mauricioaniche/ck/NumberOfComparisonsTest.java index bd59af05..bfd7f603 100644 --- a/src/test/java/com/github/mauricioaniche/ck/NumberOfComparisonsTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/NumberOfComparisonsTest.java @@ -1,30 +1,37 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class NumberOfComparisonsTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/comparison"); - } - - @Test - public void count() { - CKClassResult a = report.get("comparison.Comparison"); - - Assertions.assertEquals(4, a.getComparisonsQty()); - - Assertions.assertEquals(2, a.getMethod("m1/0").get().getComparisonsQty()); - Assertions.assertEquals(1, a.getMethod("m2/0").get().getComparisonsQty()); - Assertions.assertEquals(0, a.getMethod("m3/0").get().getComparisonsQty()); - Assertions.assertEquals(1, a.getMethod("m4/0").get().getComparisonsQty()); - - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class NumberOfComparisonsTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/comparison"); + } + + @Test + public void count() { + CKClassResult a = report.get("comparison.Comparison"); + + Assertions.assertEquals(4, a.getComparisonsQty()); + + Assertions.assertEquals(2, a.getMethod("m1/0").get().getComparisonsQty()); + Assertions.assertEquals(1, a.getMethod("m2/0").get().getComparisonsQty()); + Assertions.assertEquals(0, a.getMethod("m3/0").get().getComparisonsQty()); + Assertions.assertEquals(1, a.getMethod("m4/0").get().getComparisonsQty()); + + CKClassResult b = report.get("comparison.RecordComparison"); + + Assertions.assertEquals(4, b.getComparisonsQty()); + + Assertions.assertEquals(2, b.getMethod("m1/0").get().getComparisonsQty()); + Assertions.assertEquals(1, b.getMethod("m2/0").get().getComparisonsQty()); + Assertions.assertEquals(0, b.getMethod("m3/0").get().getComparisonsQty()); + Assertions.assertEquals(1, b.getMethod("m4/0").get().getComparisonsQty()); + + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/NumberOfInnerClassesLambdasAndAnonymousClassesTest.java b/src/test/java/com/github/mauricioaniche/ck/NumberOfInnerClassesLambdasAndAnonymousClassesTest.java index 74afb82b..7485521b 100644 --- a/src/test/java/com/github/mauricioaniche/ck/NumberOfInnerClassesLambdasAndAnonymousClassesTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/NumberOfInnerClassesLambdasAndAnonymousClassesTest.java @@ -1,77 +1,127 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class NumberOfInnerClassesLambdasAndAnonymousClassesTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/innerclasses"); - } - - @Test - public void count() { - CKClassResult a = report.get("innerclasses.MessyClass"); - - Assertions.assertEquals(2, a.getAnonymousClassesQty()); - Assertions.assertEquals(1, a.getLambdasQty()); - Assertions.assertEquals(3, a.getInnerClassesQty()); - - Assertions.assertEquals(0, a.getMethod("m1/0").get().getAnonymousClassesQty()); - Assertions.assertEquals(0, a.getMethod("m1/0").get().getLambdasQty()); - Assertions.assertEquals(0, a.getMethod("m1/0").get().getInnerClassesQty()); - - Assertions.assertEquals(0, a.getMethod("m2/0").get().getAnonymousClassesQty()); - Assertions.assertEquals(0, a.getMethod("m2/0").get().getLambdasQty()); - Assertions.assertEquals(0, a.getMethod("m2/0").get().getInnerClassesQty()); - - Assertions.assertEquals(1, a.getMethod("m3/0").get().getAnonymousClassesQty()); - Assertions.assertEquals(0, a.getMethod("m3/0").get().getLambdasQty()); - Assertions.assertEquals(0, a.getMethod("m3/0").get().getInnerClassesQty()); - - Assertions.assertEquals(1, a.getMethod("m4/0").get().getLambdasQty()); - Assertions.assertEquals(0, a.getMethod("m4/0").get().getAnonymousClassesQty()); - Assertions.assertEquals(0, a.getMethod("m4/0").get().getInnerClassesQty()); - - - Assertions.assertEquals(1, a.getMethod("m5/0").get().getAnonymousClassesQty()); - Assertions.assertEquals(0, a.getMethod("m5/0").get().getLambdasQty()); - Assertions.assertEquals(0, a.getMethod("m5/0").get().getInnerClassesQty()); - - Assertions.assertEquals(1, a.getMethod("m6/0").get().getInnerClassesQty()); - Assertions.assertEquals(0, a.getMethod("m6/0").get().getLambdasQty()); - Assertions.assertEquals(0, a.getMethod("m6/0").get().getAnonymousClassesQty()); - } - - @Test - public void innerclassesInsideAnonymousClasses() { - - CKClassResult a = report.get("innerclasses.SC2"); - // the innerclass is inside the anonymous method inside the method (two levels below...), and not the class... - Assertions.assertEquals(0, a.getInnerClassesQty()); - Assertions.assertEquals(1, a.getAnonymousClassesQty()); - Assertions.assertEquals(0, a.getLambdasQty()); - - Assertions.assertEquals(1, a.getMethod("m1/0").get().getAnonymousClassesQty()); - Assertions.assertEquals(0, a.getMethod("m1/0").get().getInnerClassesQty()); - Assertions.assertEquals(0, a.getMethod("m1/0").get().getLambdasQty()); - - CKClassResult b = report.get("innerclasses.SC2$Anonymous1"); - Assertions.assertEquals(1, b.getMethod("toString/0").get().getInnerClassesQty()); - Assertions.assertEquals(1, b.getInnerClassesQty()); - Assertions.assertEquals(0, b.getLambdasQty()); - Assertions.assertEquals(0, b.getAnonymousClassesQty()); - - CKClassResult sc = report.get("innerclasses.SC2$1$1X"); - Assertions.assertNotNull(sc); - Assertions.assertEquals(0, sc.getInnerClassesQty()); - Assertions.assertEquals(0, sc.getLambdasQty()); - Assertions.assertEquals(0, sc.getAnonymousClassesQty()); - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class NumberOfInnerClassesLambdasAndAnonymousClassesTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/innerclasses"); + } + + @Test + public void count() { + CKClassResult a = report.get("innerclasses.MessyClass"); + + Assertions.assertEquals(2, a.getAnonymousClassesQty()); + Assertions.assertEquals(1, a.getLambdasQty()); + Assertions.assertEquals(3, a.getInnerClassesQty()); + + Assertions.assertEquals(0, a.getMethod("m1/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, a.getMethod("m1/0").get().getLambdasQty()); + Assertions.assertEquals(0, a.getMethod("m1/0").get().getInnerClassesQty()); + + Assertions.assertEquals(0, a.getMethod("m2/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, a.getMethod("m2/0").get().getLambdasQty()); + Assertions.assertEquals(0, a.getMethod("m2/0").get().getInnerClassesQty()); + + Assertions.assertEquals(1, a.getMethod("m3/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, a.getMethod("m3/0").get().getLambdasQty()); + Assertions.assertEquals(0, a.getMethod("m3/0").get().getInnerClassesQty()); + + Assertions.assertEquals(1, a.getMethod("m4/0").get().getLambdasQty()); + Assertions.assertEquals(0, a.getMethod("m4/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, a.getMethod("m4/0").get().getInnerClassesQty()); + + Assertions.assertEquals(1, a.getMethod("m5/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, a.getMethod("m5/0").get().getLambdasQty()); + Assertions.assertEquals(0, a.getMethod("m5/0").get().getInnerClassesQty()); + + Assertions.assertEquals(1, a.getMethod("m6/0").get().getInnerClassesQty()); + Assertions.assertEquals(0, a.getMethod("m6/0").get().getLambdasQty()); + Assertions.assertEquals(0, a.getMethod("m6/0").get().getAnonymousClassesQty()); + + CKClassResult b = report.get("innerclasses.MessyClass"); + + Assertions.assertEquals(2, b.getAnonymousClassesQty()); + Assertions.assertEquals(1, b.getLambdasQty()); + Assertions.assertEquals(3, b.getInnerClassesQty()); + + Assertions.assertEquals(0, b.getMethod("m1/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, b.getMethod("m1/0").get().getLambdasQty()); + Assertions.assertEquals(0, b.getMethod("m1/0").get().getInnerClassesQty()); + + Assertions.assertEquals(0, b.getMethod("m2/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, b.getMethod("m2/0").get().getLambdasQty()); + Assertions.assertEquals(0, b.getMethod("m2/0").get().getInnerClassesQty()); + + Assertions.assertEquals(1, b.getMethod("m3/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, b.getMethod("m3/0").get().getLambdasQty()); + Assertions.assertEquals(0, b.getMethod("m3/0").get().getInnerClassesQty()); + + Assertions.assertEquals(1, b.getMethod("m4/0").get().getLambdasQty()); + Assertions.assertEquals(0, b.getMethod("m4/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, b.getMethod("m4/0").get().getInnerClassesQty()); + + + Assertions.assertEquals(1, b.getMethod("m5/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, b.getMethod("m5/0").get().getLambdasQty()); + Assertions.assertEquals(0, b.getMethod("m5/0").get().getInnerClassesQty()); + + Assertions.assertEquals(1, b.getMethod("m6/0").get().getInnerClassesQty()); + Assertions.assertEquals(0, b.getMethod("m6/0").get().getLambdasQty()); + Assertions.assertEquals(0, b.getMethod("m6/0").get().getAnonymousClassesQty()); + } + + @Test + public void innerclassesInsideAnonymousClasses() { + + CKClassResult a = report.get("innerclasses.SC2"); + // the innerclass is inside the anonymous method inside the method (two levels below...), and not the class... + Assertions.assertEquals(0, a.getInnerClassesQty()); + Assertions.assertEquals(1, a.getAnonymousClassesQty()); + Assertions.assertEquals(0, a.getLambdasQty()); + + Assertions.assertEquals(1, a.getMethod("m1/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, a.getMethod("m1/0").get().getInnerClassesQty()); + Assertions.assertEquals(0, a.getMethod("m1/0").get().getLambdasQty()); + + CKClassResult b = report.get("innerclasses.SC2$Anonymous1"); + Assertions.assertEquals(1, b.getMethod("toString/0").get().getInnerClassesQty()); + Assertions.assertEquals(1, b.getInnerClassesQty()); + Assertions.assertEquals(0, b.getLambdasQty()); + Assertions.assertEquals(0, b.getAnonymousClassesQty()); + + CKClassResult sc = report.get("innerclasses.SC2$1$1X"); + Assertions.assertNotNull(sc); + Assertions.assertEquals(0, sc.getInnerClassesQty()); + Assertions.assertEquals(0, sc.getLambdasQty()); + Assertions.assertEquals(0, sc.getAnonymousClassesQty()); + + CKClassResult x = report.get("innerclasses.RecordSC2"); + // the innerclass is inside the anonymous method inside the method (two levels below...), and not the class... + Assertions.assertEquals(0, x.getInnerClassesQty()); + Assertions.assertEquals(1, x.getAnonymousClassesQty()); + Assertions.assertEquals(0, x.getLambdasQty()); + + Assertions.assertEquals(1, x.getMethod("m1/0").get().getAnonymousClassesQty()); + Assertions.assertEquals(0, x.getMethod("m1/0").get().getInnerClassesQty()); + Assertions.assertEquals(0, x.getMethod("m1/0").get().getLambdasQty()); + + CKClassResult y = report.get("innerclasses.SC2$Anonymous1"); + Assertions.assertEquals(1, y.getMethod("toString/0").get().getInnerClassesQty()); + Assertions.assertEquals(1, y.getInnerClassesQty()); + Assertions.assertEquals(0, y.getLambdasQty()); + Assertions.assertEquals(0, y.getAnonymousClassesQty()); + + CKClassResult z = report.get("innerclasses.SC2$1$1X"); + Assertions.assertNotNull(z); + Assertions.assertEquals(0, z.getInnerClassesQty()); + Assertions.assertEquals(0, z.getLambdasQty()); + Assertions.assertEquals(0, z.getAnonymousClassesQty()); + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/NumberOfReturnsTest.java b/src/test/java/com/github/mauricioaniche/ck/NumberOfReturnsTest.java index ae1cdb69..632a9f08 100644 --- a/src/test/java/com/github/mauricioaniche/ck/NumberOfReturnsTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/NumberOfReturnsTest.java @@ -1,30 +1,37 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class NumberOfReturnsTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/returns"); - } - - @Test - public void count() { - CKClassResult a = report.get("returns.Returns"); - - Assertions.assertEquals(6, a.getReturnQty()); - - Assertions.assertEquals(3, a.getMethod("m1/0").get().getReturnQty()); - Assertions.assertEquals(2, a.getMethod("m2/0").get().getReturnQty()); - Assertions.assertEquals(1, a.getMethod("m3/0").get().getReturnQty()); - Assertions.assertEquals(0, a.getMethod("m4/0").get().getReturnQty()); - - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class NumberOfReturnsTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/returns"); + } + + @Test + public void count() { + CKClassResult a = report.get("returns.Returns"); + + Assertions.assertEquals(6, a.getReturnQty()); + + Assertions.assertEquals(3, a.getMethod("m1/0").get().getReturnQty()); + Assertions.assertEquals(2, a.getMethod("m2/0").get().getReturnQty()); + Assertions.assertEquals(1, a.getMethod("m3/0").get().getReturnQty()); + Assertions.assertEquals(0, a.getMethod("m4/0").get().getReturnQty()); + + CKClassResult b = report.get("returns.RecordReturns"); + + Assertions.assertEquals(6, b.getReturnQty()); + + Assertions.assertEquals(3, b.getMethod("m1/0").get().getReturnQty()); + Assertions.assertEquals(2, b.getMethod("m2/0").get().getReturnQty()); + Assertions.assertEquals(1, b.getMethod("m3/0").get().getReturnQty()); + Assertions.assertEquals(0, b.getMethod("m4/0").get().getReturnQty()); + + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/NumberOfVariablesTest.java b/src/test/java/com/github/mauricioaniche/ck/NumberOfVariablesTest.java index 97ace480..bedf45dd 100644 --- a/src/test/java/com/github/mauricioaniche/ck/NumberOfVariablesTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/NumberOfVariablesTest.java @@ -1,29 +1,34 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class NumberOfVariablesTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/variables"); - } - - @Test - public void count() { - CKClassResult a = report.get("variables.Variables"); - - Assertions.assertEquals(8, a.getVariablesQty()); - - Assertions.assertEquals(4, a.getMethod("m1/0").get().getVariablesQty()); - Assertions.assertEquals(4, a.getMethod("m2/0").get().getVariablesQty()); - Assertions.assertEquals(0, a.getMethod("m3/0").get().getVariablesQty()); - - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class NumberOfVariablesTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/variables"); + } + + @Test + public void count() { + CKClassResult a = report.get("variables.Variables"); + + Assertions.assertEquals(8, a.getVariablesQty()); + + Assertions.assertEquals(4, a.getMethod("m1/0").get().getVariablesQty()); + Assertions.assertEquals(4, a.getMethod("m2/0").get().getVariablesQty()); + Assertions.assertEquals(0, a.getMethod("m3/0").get().getVariablesQty()); + + CKClassResult b = report.get("variables.RecordVariables"); + + Assertions.assertEquals(4, b.getVariablesQty()); + + Assertions.assertEquals(2, b.getMethod("actionPerformed/1[java.awt.event.ActionEvent]").get().getVariablesQty()); + Assertions.assertEquals(2, b.getMethod("privateStaticMethod/0").get().getVariablesQty()); + Assertions.assertEquals(0, b.getMethod("defaultMethod/0").get().getVariablesQty()); + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/ParametersTest.java b/src/test/java/com/github/mauricioaniche/ck/ParametersTest.java index c6378356..57661952 100644 --- a/src/test/java/com/github/mauricioaniche/ck/ParametersTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/ParametersTest.java @@ -1,26 +1,29 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class ParametersTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/parameters"); - } - - @Test - public void testSignatureResolution() { - assertTrue(this.report.containsKey("A")); - CKClassResult clazz = this.report.get("A"); - assertTrue(clazz.getMethod("m1/6[pac.B,pac.B,Missing,pac.Missing,Missing2,pacmissing.Missing2]").isPresent()); - } - -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class ParametersTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/parameters"); + } + + @Test + public void testSignatureResolution() { + assertTrue(this.report.containsKey("A")); + assertTrue(this.report.containsKey("OneRecord")); + CKClassResult clazz = this.report.get("A"); + assertTrue(clazz.getMethod("m1/6[pac.B,pac.B,Missing,pac.Missing,Missing2,pacmissing.Missing2]").isPresent()); + + CKClassResult record = this.report.get("OneRecord"); + assertTrue(record.getMethod("actionPerformed/1[java.awt.event.ActionEvent]").isPresent()); + assertTrue(record.getMethod("simpleSum/1[int]").isPresent()); + } + +} diff --git a/src/test/java/com/github/mauricioaniche/ck/VariableNameExtractionTest.java b/src/test/java/com/github/mauricioaniche/ck/VariableNameExtractionTest.java index 71bfdad5..52ef089e 100644 --- a/src/test/java/com/github/mauricioaniche/ck/VariableNameExtractionTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/VariableNameExtractionTest.java @@ -1,24 +1,27 @@ -package com.github.mauricioaniche.ck; - -import com.google.common.collect.Sets; - -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class VariableNameExtractionTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/VariableDeclaration"); - } - - @Test - public void extractVariableNames(){ - CKClassResult a = report.get("VariableDeclaration.VariableDeclaration"); - assertEquals(Sets.newHashSet("a", "b", "c", "d", "e", "f", "g", "xx"), a.getFieldNames()); - } +package com.github.mauricioaniche.ck; + +import com.google.common.collect.Sets; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class VariableNameExtractionTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/VariableDeclaration"); + } + + @Test + public void extractVariableNames(){ + CKClassResult a = report.get("VariableDeclaration.VariableDeclaration"); + assertEquals(Sets.newHashSet("a", "b", "c", "d", "e", "f", "g", "xx"), a.getFieldNames()); + + CKClassResult b = report.get("VariableDeclaration.OneRecord"); + assertEquals(Sets.newHashSet("aString", "aLong", "anInteger"), b.getFieldNames()); + } } \ No newline at end of file diff --git a/src/test/java/com/github/mauricioaniche/ck/WMCTest.java b/src/test/java/com/github/mauricioaniche/ck/WMCTest.java index 400e7c24..fc4ddfe2 100644 --- a/src/test/java/com/github/mauricioaniche/ck/WMCTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/WMCTest.java @@ -1,112 +1,116 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestInstance; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class WMCTest extends BaseTest { - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/wmc"); - } - - @Test - public void someOldRandomTests() { - - CKClassResult a = report.get("wmc.CC1"); - CKClassResult b = report.get("wmc.CC2"); - CKClassResult c = report.get("wmc.CC3"); - - Assertions.assertEquals(7, a.getWmc()); - Assertions.assertEquals(6, b.getWmc()); - Assertions.assertEquals(11, c.getWmc()); - - Assertions.assertEquals(2, a.getMethod("m1/0").get().getWmc()); - Assertions.assertEquals(2, a.getMethod("m2/0").get().getWmc()); - Assertions.assertEquals(3, a.getMethod("m3/0").get().getWmc()); - Assertions.assertEquals(3, b.getMethod("m1/0").get().getWmc()); - Assertions.assertEquals(3, b.getMethod("m2/0").get().getWmc()); - Assertions.assertEquals(11, c.getMethod("m1/0").get().getWmc()); - } - - @Test - public void doNotCountSubClassesCode() { - CKClassResult c = report.get("wmc.CC4"); - Assertions.assertEquals(11, c.getMethod("m1/0").get().getWmc()); - Assertions.assertEquals(11, c.getWmc()); - - CKClassResult c2 = report.get("wmc.CC4$1MethodInner"); - Assertions.assertEquals(3, c2.getMethod("print/0").get().getWmc()); - } - - // related to issue #31 - // note that, although m1 and m2 are semantically similar, their WMC are currently differently. - // it would need some smarter analysis to figure out that the complexity of the boolean variable was - // already measured before. - @Test - public void inlineConditions() { - CKClassResult c = report.get("wmc.CC6"); - Assertions.assertEquals(7, c.getWmc()); - - Assertions.assertEquals(3, c.getMethod("m1/1[int]").get().getWmc()); - Assertions.assertEquals(4, c.getMethod("m2/1[int]").get().getWmc()); - } - - @Test - public void straightBooleanComparison() { - CKClassResult c = report.get("wmc.CC7"); - - Assertions.assertEquals(2, c.getMethod("m2/1[boolean]").get().getWmc()); - Assertions.assertEquals(2, c.getMethod("m1/1[boolean]").get().getWmc()); - } - - @Test - public void loops() { - - CKClassResult c = report.get("wmc.CC8"); - - Assertions.assertEquals(3, c.getMethod("m0/0").get().getWmc()); - Assertions.assertEquals(6, c.getMethod("m1/0").get().getWmc()); - Assertions.assertEquals(6, c.getMethod("m2/0").get().getWmc()); - Assertions.assertEquals(6, c.getMethod("m3/0").get().getWmc()); - Assertions.assertEquals(2, c.getMethod("m4/0").get().getWmc()); - Assertions.assertEquals(3, c.getMethod("m5/0").get().getWmc()); - Assertions.assertEquals(6, c.getMethod("m6/0").get().getWmc()); - - Assertions.assertEquals(3+6+6+6+2+3+6, c.getWmc()); - - } - - @Test - public void ifs() { - - CKClassResult c = report.get("wmc.CC9"); - - Assertions.assertEquals(1, c.getMethod("m0/0").get().getWmc()); - Assertions.assertEquals(2, c.getMethod("m1/0").get().getWmc()); - Assertions.assertEquals(3, c.getMethod("m2/0").get().getWmc()); - Assertions.assertEquals(2, c.getMethod("m3/0").get().getWmc()); - Assertions.assertEquals(4, c.getMethod("m4/0").get().getWmc()); - Assertions.assertEquals(8, c.getMethod("m5/0").get().getWmc()); - Assertions.assertEquals(9, c.getMethod("m6/0").get().getWmc()); - Assertions.assertEquals(5, c.getMethod("m7/0").get().getWmc()); - Assertions.assertEquals(4, c.getMethod("m8/0").get().getWmc()); - Assertions.assertEquals(8, c.getMethod("m9/0").get().getWmc()); - - // the final 2 is for the two other util methods we have there - Assertions.assertEquals(1+2+3+2+4+8+9+5+4+8 + 2, c.getWmc()); - - } - - @Test - public void nested() { - CKClassResult c = report.get("wmc.CC10"); - Assertions.assertEquals(9, c.getMethod("m2/0").get().getWmc()); - Assertions.assertEquals(12, c.getMethod("m1/0").get().getWmc()); - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.util.Map; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class WMCTest extends BaseTest { + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/wmc"); + } + + @Test + public void someOldRandomTests() { + + CKClassResult a = report.get("wmc.CC1"); + CKClassResult b = report.get("wmc.CC2"); + CKClassResult c = report.get("wmc.CC3"); + + Assertions.assertEquals(7, a.getWmc()); + Assertions.assertEquals(6, b.getWmc()); + Assertions.assertEquals(11, c.getWmc()); + + Assertions.assertEquals(2, a.getMethod("m1/0").get().getWmc()); + Assertions.assertEquals(2, a.getMethod("m2/0").get().getWmc()); + Assertions.assertEquals(3, a.getMethod("m3/0").get().getWmc()); + Assertions.assertEquals(3, b.getMethod("m1/0").get().getWmc()); + Assertions.assertEquals(3, b.getMethod("m2/0").get().getWmc()); + Assertions.assertEquals(11, c.getMethod("m1/0").get().getWmc()); + } + + @Test + public void doNotCountSubClassesCode() { + CKClassResult c = report.get("wmc.CC4"); + Assertions.assertEquals(11, c.getMethod("m1/0").get().getWmc()); + Assertions.assertEquals(11, c.getWmc()); + + CKClassResult c2 = report.get("wmc.CC4$1MethodInner"); + Assertions.assertEquals(3, c2.getMethod("print/0").get().getWmc()); + } + + // related to issue #31 + // note that, although m1 and m2 are semantically similar, their WMC are currently differently. + // it would need some smarter analysis to figure out that the complexity of the boolean variable was + // already measured before. + @Test + public void inlineConditions() { + CKClassResult c = report.get("wmc.CC6"); + Assertions.assertEquals(7, c.getWmc()); + + Assertions.assertEquals(3, c.getMethod("m1/1[int]").get().getWmc()); + Assertions.assertEquals(4, c.getMethod("m2/1[int]").get().getWmc()); + } + + @Test + public void straightBooleanComparison() { + CKClassResult c = report.get("wmc.CC7"); + + Assertions.assertEquals(2, c.getMethod("m2/1[boolean]").get().getWmc()); + Assertions.assertEquals(2, c.getMethod("m1/1[boolean]").get().getWmc()); + + CKClassResult r = report.get("wmc.RecordWMC"); + Assertions.assertEquals(2, r.getMethod("m2/1[boolean]").get().getWmc()); + Assertions.assertEquals(2, r.getMethod("m1/1[boolean]").get().getWmc()); + } + + @Test + public void loops() { + + CKClassResult c = report.get("wmc.CC8"); + + Assertions.assertEquals(3, c.getMethod("m0/0").get().getWmc()); + Assertions.assertEquals(6, c.getMethod("m1/0").get().getWmc()); + Assertions.assertEquals(6, c.getMethod("m2/0").get().getWmc()); + Assertions.assertEquals(6, c.getMethod("m3/0").get().getWmc()); + Assertions.assertEquals(2, c.getMethod("m4/0").get().getWmc()); + Assertions.assertEquals(3, c.getMethod("m5/0").get().getWmc()); + Assertions.assertEquals(6, c.getMethod("m6/0").get().getWmc()); + + Assertions.assertEquals(3+6+6+6+2+3+6, c.getWmc()); + + } + + @Test + public void ifs() { + + CKClassResult c = report.get("wmc.CC9"); + + Assertions.assertEquals(1, c.getMethod("m0/0").get().getWmc()); + Assertions.assertEquals(2, c.getMethod("m1/0").get().getWmc()); + Assertions.assertEquals(3, c.getMethod("m2/0").get().getWmc()); + Assertions.assertEquals(2, c.getMethod("m3/0").get().getWmc()); + Assertions.assertEquals(4, c.getMethod("m4/0").get().getWmc()); + Assertions.assertEquals(8, c.getMethod("m5/0").get().getWmc()); + Assertions.assertEquals(9, c.getMethod("m6/0").get().getWmc()); + Assertions.assertEquals(5, c.getMethod("m7/0").get().getWmc()); + Assertions.assertEquals(4, c.getMethod("m8/0").get().getWmc()); + Assertions.assertEquals(8, c.getMethod("m9/0").get().getWmc()); + + // the final 2 is for the two other util methods we have there + Assertions.assertEquals(1+2+3+2+4+8+9+5+4+8 + 2, c.getWmc()); + + } + + @Test + public void nested() { + CKClassResult c = report.get("wmc.CC10"); + Assertions.assertEquals(9, c.getMethod("m2/0").get().getWmc()); + Assertions.assertEquals(12, c.getMethod("m1/0").get().getWmc()); + } +} diff --git a/src/test/java/com/github/mauricioaniche/ck/WordCountsTest.java b/src/test/java/com/github/mauricioaniche/ck/WordCountsTest.java index 24b873fb..44dc37a7 100644 --- a/src/test/java/com/github/mauricioaniche/ck/WordCountsTest.java +++ b/src/test/java/com/github/mauricioaniche/ck/WordCountsTest.java @@ -1,61 +1,66 @@ -package com.github.mauricioaniche.ck; - -import org.junit.jupiter.api.*; - -import java.util.Map; - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -public class WordCountsTest extends BaseTest { - - private CKClassResult w1; - private CKClassResult w2; - private CKClassResult w3; - - @BeforeAll - public void setUp() { - report = run(fixturesDir() + "/wordcounts"); - } - - @BeforeEach - public void getClasses() { - this.w1 = report.get("wordcounts.WordCounts"); - this.w2 = report.get("wordcounts.WordCounts2"); - this.w3 = report.get("wordcounts.WordCounts3"); - } - - @Test - public void count() { - Assertions.assertEquals(1, w1.getMethod("m1/0").get().getUniqueWordsQty()); - Assertions.assertEquals(7, w1.getMethod("m2/0").get().getUniqueWordsQty()); - } - - // related to issue #33 - @Test - public void countStaticInitializer() { - Assertions.assertEquals(1, w2.getMethod("m1/0").get().getUniqueWordsQty()); - Assertions.assertEquals(7, w2.getMethod("m2/0").get().getUniqueWordsQty()); - Assertions.assertEquals(3, w2.getMethod("(initializer 1)").get().getUniqueWordsQty()); - } - - @Test - public void countAtClassLevel() { - Assertions.assertEquals(10, w1.getUniqueWordsQty()); - Assertions.assertEquals(13, w2.getUniqueWordsQty()); - } - - // related to issue #34 - @Test - public void subclasses() { - Assertions.assertEquals(7, w3.getMethod("m2/0").get().getUniqueWordsQty()); - Assertions.assertEquals(10, w3.getUniqueWordsQty()); - - // numbers in the subclass - CKClassResult subclass = report.get("wordcounts.WordCounts3$1X"); - Assertions.assertEquals(3, subclass.getMethod("xxx/0").get().getUniqueWordsQty()); - Assertions.assertEquals(4, subclass.getUniqueWordsQty()); - - CKClassResult subclass2 = report.get("wordcounts.WordCounts3$Y"); - Assertions.assertEquals(2, subclass2.getMethod("yyy/0").get().getUniqueWordsQty()); - Assertions.assertEquals(3, subclass2.getUniqueWordsQty()); - } -} +package com.github.mauricioaniche.ck; + +import org.junit.jupiter.api.*; + +import java.util.Map; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class WordCountsTest extends BaseTest { + + private CKClassResult w1; + private CKClassResult w2; + private CKClassResult w3; + private CKClassResult w4; + + @BeforeAll + public void setUp() { + report = run(fixturesDir() + "/wordcounts"); + } + + @BeforeEach + public void getClasses() { + this.w1 = report.get("wordcounts.WordCounts"); + this.w2 = report.get("wordcounts.WordCounts2"); + this.w3 = report.get("wordcounts.WordCounts3"); + this.w4 = report.get("wordcounts.RecordCount"); + } + + @Test + public void count() { + Assertions.assertEquals(1, w1.getMethod("m1/0").get().getUniqueWordsQty()); + Assertions.assertEquals(7, w1.getMethod("m2/0").get().getUniqueWordsQty()); + + Assertions.assertEquals(1, w4.getMethod("m1/0").get().getUniqueWordsQty()); + Assertions.assertEquals(7, w4.getMethod("m2/0").get().getUniqueWordsQty()); + } + + // related to issue #33 + @Test + public void countStaticInitializer() { + Assertions.assertEquals(1, w2.getMethod("m1/0").get().getUniqueWordsQty()); + Assertions.assertEquals(7, w2.getMethod("m2/0").get().getUniqueWordsQty()); + Assertions.assertEquals(3, w2.getMethod("(initializer 1)").get().getUniqueWordsQty()); + } + + @Test + public void countAtClassLevel() { + Assertions.assertEquals(10, w1.getUniqueWordsQty()); + Assertions.assertEquals(13, w2.getUniqueWordsQty()); + } + + // related to issue #34 + @Test + public void subclasses() { + Assertions.assertEquals(7, w3.getMethod("m2/0").get().getUniqueWordsQty()); + Assertions.assertEquals(10, w3.getUniqueWordsQty()); + + // numbers in the subclass + CKClassResult subclass = report.get("wordcounts.WordCounts3$1X"); + Assertions.assertEquals(3, subclass.getMethod("xxx/0").get().getUniqueWordsQty()); + Assertions.assertEquals(4, subclass.getUniqueWordsQty()); + + CKClassResult subclass2 = report.get("wordcounts.WordCounts3$Y"); + Assertions.assertEquals(2, subclass2.getMethod("yyy/0").get().getUniqueWordsQty()); + Assertions.assertEquals(3, subclass2.getUniqueWordsQty()); + } +}