From 4b671f5d122bf68f93812dcc216b54eb5cbad93e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Mon, 27 Mar 2017 20:22:41 +0200 Subject: [PATCH] Abstracted signatures --- .../pmd/lang/java/metrics/AtfdMetric.java | 27 +++++++------- .../pmd/lang/java/metrics/ClassMetric.java | 2 +- .../pmd/lang/java/metrics/FieldSigMask.java | 12 +++++++ .../pmd/lang/java/metrics/FieldSignature.java | 24 ++++++++++--- .../pmd/lang/java/metrics/MethodMetric.java | 14 -------- .../pmd/lang/java/metrics/Metrics.java | 10 +++--- .../lang/java/metrics/OperationMetric.java | 17 +++++++++ .../lang/java/metrics/OperationSigMask.java | 25 +++---------- .../lang/java/metrics/OperationSignature.java | 31 ++++++++-------- .../pmd/lang/java/metrics/PackageStats.java | 11 +++--- .../pmd/lang/java/metrics/SigMask.java | 36 +++++++++++++++++++ .../pmd/lang/java/metrics/Signature.java | 16 ++++++--- 12 files changed, 141 insertions(+), 84 deletions(-) create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/FieldSigMask.java delete mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/MethodMetric.java create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationMetric.java create mode 100644 pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/SigMask.java diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/AtfdMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/AtfdMetric.java index d9bdf465b0..ee2c04d305 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/AtfdMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/AtfdMetric.java @@ -1,6 +1,7 @@ /** - * + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ + package net.sourceforge.pmd.lang.java.metrics; import java.util.List; @@ -8,42 +9,42 @@ import java.util.List; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.metrics.OperationSignature.Role; -import net.sourceforge.pmd.lang.java.metrics.OperationSignature.Visibility; +import net.sourceforge.pmd.lang.java.metrics.Signature.Visibility; /** * @author Clément Fournier (clement.fournier@insa-rennes.fr) * */ -public class AtfdMetric extends AbstractMetric implements ClassMetric, MethodMetric { - +public class AtfdMetric extends AbstractMetric implements ClassMetric, OperationMetric { + static { operationMask = new OperationSigMask(); operationMask.setAllVisibility(); operationMask.setAllRoles(); operationMask.remove(Role.CONSTRUCTOR); } - + @Override public double computeFor(ASTMethodDeclaration node, PackageStats holder) { if (!checkMaskIsMatching(node)) { return Double.NaN; } - + OperationSigMask targetOps = new OperationSigMask(); targetOps.setVisibilityMask(Visibility.PUBLIC); - targetOps.setRoleMask(Role.GETTERORSETTER); - + targetOps.setRoleMask(Role.GETTER_OR_SETTER); + List callQNames = findAllCalls(node); - int atfd = 0; + int foreignCalls = 0; for (String name : callQNames) { if (holder.hasMatchingSig(name, targetOps)) { - atfd++; + foreignCalls++; } } - - return atfd; - } + return foreignCalls / callQNames.size(); + } + @Override public double computeFor(ASTClassOrInterfaceDeclaration node, PackageStats holder) { // TODO diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassMetric.java index cf6bf4029b..c0ad486acb 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassMetric.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/ClassMetric.java @@ -10,5 +10,5 @@ import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; * */ public interface ClassMetric extends Metric { - public double computeFor(ASTClassOrInterfaceDeclaration node, PackageStats holder); + double computeFor(ASTClassOrInterfaceDeclaration node, PackageStats holder); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/FieldSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/FieldSigMask.java new file mode 100644 index 0000000000..45644873c2 --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/FieldSigMask.java @@ -0,0 +1,12 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package net.sourceforge.pmd.lang.java.metrics; + +/** + * @author Clément Fournier (clement.fournier@insa-rennes.fr) + * + */ +public class FieldSigMask extends SigMask { + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/FieldSignature.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/FieldSignature.java index 0af1f38d2a..4b85c3664d 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/FieldSignature.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/FieldSignature.java @@ -3,20 +3,34 @@ */ package net.sourceforge.pmd.lang.java.metrics; +import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; + /** * @author Clément Fournier (clement.fournier@insa-rennes.fr) * */ public class FieldSignature extends Signature { - public final Visibility visibility; - public final boolean isStatic; - public final boolean isFinal; - + public final boolean isStatic; + public final boolean isFinal; + public FieldSignature(Visibility visibility, boolean isStatic, boolean isFinal) { - this.visibility = visibility; + super(visibility); this.isStatic = isStatic; this.isFinal = isFinal; } + + @Override + public boolean equals(Object o) { + if (o instanceof FieldSignature) { + // TODO + return true; + } + return false; + } + + public FieldSignature buildFor(ASTFieldDeclaration node) { + return new FieldSignature(getVisibility(node), node.isStatic(), node.isFinal()); + } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/MethodMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/MethodMetric.java deleted file mode 100644 index 79f9410edf..0000000000 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/MethodMetric.java +++ /dev/null @@ -1,14 +0,0 @@ -/** - * - */ -package net.sourceforge.pmd.lang.java.metrics; - -import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; - -/** - * @author Clément Fournier (clement.fournier@insa-rennes.fr) - * - */ -public interface MethodMetric extends Metric { - public double computeFor(ASTMethodDeclaration node, PackageStats holder); -} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/Metrics.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/Metrics.java index 2901f0a178..2d106e4b9c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/Metrics.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/Metrics.java @@ -34,19 +34,19 @@ public class Metrics { } /* References all available method metrics */ - public static enum MethodMetricKey { + public static enum OperationMetricKey { ATFD(new AtfdMetric()), // ... ; /* The object used to calculate the metric */ - private final MethodMetric calculator; + private final OperationMetric calculator; - MethodMetricKey(MethodMetric m) { + OperationMetricKey(OperationMetric m) { calculator = m; } - MethodMetric getCalculator() { + OperationMetric getCalculator() { return calculator; } } @@ -63,7 +63,7 @@ public class Metrics { * Computes a metric identified by its code on the method AST node being * passed. */ - public static double get(MethodMetricKey key, ASTMethodDeclaration node) { + public static double get(OperationMetricKey key, ASTMethodDeclaration node) { return key.getCalculator().computeFor(node, m_holder); } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationMetric.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationMetric.java new file mode 100644 index 0000000000..f4fc2cc72e --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationMetric.java @@ -0,0 +1,17 @@ +/** + * + */ +package net.sourceforge.pmd.lang.java.metrics; + +import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; + +/** + * @author Clément Fournier (clement.fournier@insa-rennes.fr) + * + */ +public interface OperationMetric extends Metric { + double computeFor(ASTMethodDeclaration node, PackageStats holder); + + double computeFor(ASTConstructorDeclaration node, PackageStats holder); +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationSigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationSigMask.java index 0acdf8dfc7..6a8804e625 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationSigMask.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationSigMask.java @@ -9,22 +9,15 @@ import java.util.HashSet; import java.util.Set; import net.sourceforge.pmd.lang.java.metrics.OperationSignature.Role; -import net.sourceforge.pmd.lang.java.metrics.Signature.Visibility; /** * @author Clément Fournier (clement.fournier@insa-rennes.fr) * */ -public class OperationSigMask { +public class OperationSigMask extends SigMask { - private Set visMask = new HashSet<>(); - private Set roleMask = new HashSet<>(); - private boolean isAbstractIncluded = false; - - public void setVisibilityMask(Visibility... visibilities) { - visMask.clear(); - visMask.addAll(Arrays.asList(visibilities)); - } + private Set roleMask = new HashSet<>(); + private boolean isAbstractIncluded = false; public void setRoleMask(Role... roles) { roleMask.clear(); @@ -35,25 +28,17 @@ public class OperationSigMask { this.isAbstractIncluded = isAbstractIncluded; } - public void setAllVisibility() { - visMask.addAll(Arrays.asList(Visibility.ALL)); - } - public void setAllRoles() { roleMask.addAll(Arrays.asList(Role.ALL)); } - public void remove(Visibility... visibilities) { - visMask.removeAll(Arrays.asList(visibilities)); - } - public void remove(Role... roles) { roleMask.removeAll(Arrays.asList(roles)); } + @Override public boolean covers(OperationSignature sig) { - return visMask.contains(sig.visibility) && roleMask.contains(sig.role) - && (isAbstractIncluded || !sig.isAbstract); + return super.covers(sig) && roleMask.contains(sig.role) && (isAbstractIncluded || !sig.isAbstract); } } diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationSignature.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationSignature.java index eb2c77ab90..b70787d4df 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationSignature.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/OperationSignature.java @@ -10,24 +10,23 @@ import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; * @author Clément Fournier (clement.fournier@insa-rennes.fr) * */ -public class OperationSignature extends Signature { // TODO use enums +public class OperationSignature extends Signature { + + public final Role role; + public final boolean isAbstract; public static enum Role { - GETTERORSETTER, CONSTRUCTOR, METHOD, STATIC; - - public static final Role[] ALL = new Role[] { GETTERORSETTER, CONSTRUCTOR, METHOD, STATIC }; + GETTER_OR_SETTER, CONSTRUCTOR, METHOD, STATIC; + + public static final Role[] ALL = new Role[] { GETTER_OR_SETTER, CONSTRUCTOR, METHOD, STATIC }; } - - public final Visibility visibility; - public final Role role; - public final boolean isAbstract; - + public OperationSignature(Visibility visibility, Role role, boolean isAbstract) { - this.visibility = visibility; + super(visibility); this.role = role; this.isAbstract = isAbstract; } - + @Override public boolean equals(Object o) { if (o instanceof OperationSignature) { @@ -36,17 +35,17 @@ public class OperationSignature extends Signature { // TODO use enums } return false; } - + public static OperationSignature buildFor(ASTMethodDeclaration node) { // TODO better getter or setter detection boolean isGetterOrSetter = node.getName().startsWith("get") || node.getName().startsWith("set"); - Role role = isGetterOrSetter ? Role.GETTERORSETTER : node.isStatic() ? Role.STATIC : Role.METHOD; - + Role role = isGetterOrSetter ? Role.GETTER_OR_SETTER : node.isStatic() ? Role.STATIC : Role.METHOD; + return new OperationSignature(getVisibility(node), role, node.isAbstract()); } - + public static OperationSignature buildFor(ASTConstructorDeclaration node) { return new OperationSignature(getVisibility(node), Role.CONSTRUCTOR, node.isAbstract()); } - + } \ No newline at end of file diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java index bf560139c5..80ff9b7f55 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/PackageStats.java @@ -1,6 +1,7 @@ /** - * + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ + package net.sourceforge.pmd.lang.java.metrics; import java.util.HashMap; @@ -11,20 +12,20 @@ import java.util.Map; * */ public class PackageStats { - + private Map m_subPackages = new HashMap<>(); private Map m_classes = new HashMap<>(); - + public PackageStats getSubPackage(String[] qname, int index) { // ... // recursive navigation method return null; } - + public ClassStats getClassStats(String name) { return m_classes.get(name); } - + public boolean hasMatchingSig(String qname, OperationSigMask sigMask) { // navigate to the class in the tree // return true if the signature of the qualified name is covered by the diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/SigMask.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/SigMask.java new file mode 100644 index 0000000000..38826bf21d --- /dev/null +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/SigMask.java @@ -0,0 +1,36 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ +package net.sourceforge.pmd.lang.java.metrics; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +import net.sourceforge.pmd.lang.java.metrics.Signature.Visibility; + +/** + * @author Clément Fournier (clement.fournier@insa-rennes.fr) + * + */ +public abstract class SigMask { + protected Set visMask = new HashSet<>(); + + public void setVisibilityMask(Visibility... visibilities) { + visMask.clear(); + visMask.addAll(Arrays.asList(visibilities)); + } + + public void setAllVisibility() { + visMask.addAll(Arrays.asList(Visibility.ALL)); + } + + public void remove(Visibility... visibilities) { + visMask.removeAll(Arrays.asList(visibilities)); + } + + public boolean covers(T sig) { + return visMask.contains(sig.visibility); + } + +} diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/Signature.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/Signature.java index e37a79e4b3..ef888a4a6c 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/Signature.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/metrics/Signature.java @@ -10,19 +10,25 @@ import net.sourceforge.pmd.lang.java.ast.AbstractJavaAccessNode; * */ public class Signature { - + + public final Visibility visibility; + public static enum Visibility { PUBLIC, PACKAGE, PROTECTED, PRIVATE, UNDEF; - - public static final Visibility[] ALL = new Visibility[] { PUBLIC, PACKAGE, PROTECTED, PRIVATE }; - - } + public static final Visibility[] ALL = new Visibility[] { PUBLIC, PACKAGE, PROTECTED, PRIVATE }; + + } + public static Visibility getVisibility(AbstractJavaAccessNode node) { return node.isPublic() ? Visibility.PUBLIC : node.isPackagePrivate() ? Visibility.PACKAGE : node.isProtected() ? Visibility.PROTECTED : node.isPrivate() ? Visibility.PRIVATE : Visibility.UNDEF; } + + public Signature(Visibility visibility) { + this.visibility = visibility; + } }