Abstracted signatures
This commit is contained in:
committed by
Clément Fournier
parent
7a5894c856
commit
4b671f5d12
@@ -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<String> 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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<FieldSignature> {
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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<OperationSignature> {
|
||||
|
||||
private Set<Visibility> visMask = new HashSet<>();
|
||||
private Set<Role> roleMask = new HashSet<>();
|
||||
private boolean isAbstractIncluded = false;
|
||||
|
||||
public void setVisibilityMask(Visibility... visibilities) {
|
||||
visMask.clear();
|
||||
visMask.addAll(Arrays.asList(visibilities));
|
||||
}
|
||||
private Set<Role> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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<String, PackageStats> m_subPackages = new HashMap<>();
|
||||
private Map<String, ClassStats> 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
|
||||
|
||||
@@ -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<T extends Signature> {
|
||||
protected Set<Visibility> 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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user