Documentation
This commit is contained in:
@ -9,12 +9,12 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Represents Qualified Names for use within PackageStats
|
||||
* Represents Qualified Names for use within PackageStats.
|
||||
* TODO make unit tests once the visitor is working to ensure new implementations won't break it
|
||||
*/
|
||||
public class QualifiedName {
|
||||
|
||||
/** {@link QualifiedName#parseName(String)} */
|
||||
/** See {@link QualifiedName#parseName(String)}. */
|
||||
public static final Pattern FORMAT = Pattern.compile("((\\w+\\.)+|\\.)((\\w+)(\\$\\w+)*)(#(\\w+)\\(((\\w+)(, \\w+)*)?\\))?");
|
||||
|
||||
private String[] packages = null; // unnamed package
|
||||
@ -26,7 +26,7 @@ public class QualifiedName {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the qualified name of a method declaration
|
||||
* Builds the qualified name of a method declaration.
|
||||
*
|
||||
* @param node The method declaration node
|
||||
*
|
||||
@ -44,7 +44,7 @@ public class QualifiedName {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the qualified name of a constructor declaration
|
||||
* Builds the qualified name of a constructor declaration.
|
||||
*
|
||||
* @param node The constructor declaration node
|
||||
*
|
||||
@ -64,7 +64,7 @@ public class QualifiedName {
|
||||
|
||||
|
||||
/**
|
||||
* Builds a nested class QName using the QName of its immediate parent
|
||||
* Builds the qualified name of a nested class using the qualified name of its immediate parent.
|
||||
*
|
||||
* @param parent The qname of the immediate parent
|
||||
* @param className The name of the class
|
||||
@ -85,7 +85,7 @@ public class QualifiedName {
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the QName of an outer (not nested) class.
|
||||
* Builds the qualified name of an outer (not nested) class.
|
||||
*
|
||||
* @param node The class node
|
||||
*
|
||||
@ -109,24 +109,24 @@ public class QualifiedName {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a qualified name given in the format defined for this implementation.
|
||||
* The pattern is available as a static class member.The format
|
||||
* Parses a qualified name given in the format defined for this implementation. The format
|
||||
* is described as the following regex pattern :
|
||||
* <p>
|
||||
* {@code ((\w+\.)+|\.)(\w+)(\$\w+)*(#(\w+)\(((\w+)(,\w+)*)?\))?}
|
||||
* <p>
|
||||
* Notes:
|
||||
*
|
||||
* <p>{@code ((\w+\.)+|\.)((\w+)(\$\w+)*)(#(\w+)\(((\w+)(, \w+)*)?\))?}
|
||||
*
|
||||
* <p>Notes:
|
||||
* <ul>
|
||||
* <li> Group 1 : dot separated packages, or just dot if unnamed package;
|
||||
* <li> Group 5 : nested classes are separated by a dollar symbol;
|
||||
* <li> Group 6 : the optional method suffix is separated from the class with a hashtag;
|
||||
* <li> Group 8 : method arguments. Note the absence of whitespace after commas.
|
||||
* <li> Group 8 : method arguments. Note the presence of a single space after commas.
|
||||
* </ul>
|
||||
* <p>
|
||||
*
|
||||
* @param name
|
||||
* <p>The pattern is available as a static class member.
|
||||
*
|
||||
* @return
|
||||
* @param name The name to parse.
|
||||
*
|
||||
* @return A qualified name instance corresponding to the parsed string.
|
||||
*/
|
||||
public static QualifiedName parseName(String name) {
|
||||
QualifiedName qname = new QualifiedName();
|
||||
@ -137,24 +137,14 @@ public class QualifiedName {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (".".equals(matcher.group(1))) {
|
||||
qname.packages = null;
|
||||
} else {
|
||||
qname.packages = matcher.group(1).split("\\.");
|
||||
}
|
||||
|
||||
qname.packages = ".".equals(matcher.group(1)) ? null : matcher.group(1).split("\\.");
|
||||
qname.classes = matcher.group(3).split("\\$");
|
||||
|
||||
String op = matcher.group(6);
|
||||
|
||||
if (op != null) {
|
||||
qname.operation = op.substring(1);
|
||||
}
|
||||
qname.operation = matcher.group(6) == null ? null : matcher.group(6).substring(1);
|
||||
|
||||
return qname;
|
||||
}
|
||||
|
||||
/** Returns a normalized method name (not Java-canonical!) */
|
||||
/** Returns a normalized method name (not Java-canonical!). */
|
||||
private static String getOperationName(String methodName, ASTFormalParameters params) {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -200,10 +190,12 @@ public class QualifiedName {
|
||||
return packages;
|
||||
}
|
||||
|
||||
/** Returns the classes. @return The classes. */
|
||||
public String[] getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
/** Returns the operation string. @return The operation string. */
|
||||
public String getOperation() {
|
||||
return operation;
|
||||
}
|
||||
@ -268,6 +260,4 @@ public class QualifiedName {
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -30,8 +30,8 @@ public class AtfdMetric extends AbstractMetric implements ClassMetric, Operation
|
||||
}
|
||||
|
||||
OperationSigMask targetOps = new OperationSigMask();
|
||||
targetOps.setVisibilityMask(Visibility.PUBLIC);
|
||||
targetOps.setRoleMask(Role.GETTER_OR_SETTER);
|
||||
targetOps.restrictVisibilitiesTo(Visibility.PUBLIC);
|
||||
targetOps.restrictRolesTo(Role.GETTER_OR_SETTER);
|
||||
|
||||
List<QualifiedName> callQNames = findAllCalls(node);
|
||||
int foreignCalls = 0;
|
||||
|
@ -10,5 +10,21 @@ package net.sourceforge.pmd.lang.java.oom.visitor;
|
||||
* @author Clément Fournier
|
||||
*/
|
||||
public class FieldSigMask extends SigMask<FieldSignature> {
|
||||
//TODO
|
||||
|
||||
private boolean coverFinal = true;
|
||||
private boolean coverStatic = true;
|
||||
|
||||
public FieldSigMask() {
|
||||
super();
|
||||
}
|
||||
|
||||
/** Include final fields? */
|
||||
public void coverFinal(boolean coverFinal) {
|
||||
this.coverFinal = coverFinal;
|
||||
}
|
||||
|
||||
/** Include static fields? */
|
||||
public void coverStatic(boolean coverStatic) {
|
||||
this.coverStatic = coverStatic;
|
||||
}
|
||||
}
|
||||
|
@ -16,29 +16,51 @@ import java.util.Set;
|
||||
public class OperationSigMask extends SigMask<OperationSignature> {
|
||||
|
||||
private Set<OperationSignature.Role> roleMask = new HashSet<>();
|
||||
private boolean isAbstractIncluded = false;
|
||||
private boolean coverAbstract = false;
|
||||
|
||||
public void setRoleMask(OperationSignature.Role... roles) {
|
||||
public OperationSigMask() {
|
||||
super();
|
||||
coverAllRoles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Restricts the roles covered by the mask to the parameters.
|
||||
*
|
||||
* @param roles The roles to cover.
|
||||
*/
|
||||
public void restrictRolesTo(OperationSignature.Role... roles) {
|
||||
roleMask.clear();
|
||||
roleMask.addAll(Arrays.asList(roles));
|
||||
}
|
||||
|
||||
public void setAbstractIncluded(boolean isAbstractIncluded) {
|
||||
this.isAbstractIncluded = isAbstractIncluded;
|
||||
}
|
||||
|
||||
public void setAllRoles() {
|
||||
/**
|
||||
* Sets the mask to cover all roles.
|
||||
*/
|
||||
public void coverAllRoles() {
|
||||
roleMask.addAll(Arrays.asList(OperationSignature.Role.values()));
|
||||
}
|
||||
|
||||
public void remove(OperationSignature.Role... roles) {
|
||||
/**
|
||||
* Forbid all mentioned roles.
|
||||
*
|
||||
* @param roles The roles to forbid.
|
||||
*/
|
||||
public void forbid(OperationSignature.Role... roles) {
|
||||
roleMask.removeAll(Arrays.asList(roles));
|
||||
}
|
||||
|
||||
/**
|
||||
* Forbid all mentioned visibilities.
|
||||
*
|
||||
* @param coverAbstract The visibilities to forbid.
|
||||
*/
|
||||
public void coverAbstract(boolean coverAbstract) {
|
||||
this.coverAbstract = coverAbstract;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean covers(OperationSignature sig) {
|
||||
return super.covers(sig) && roleMask.contains(sig.role) && (isAbstractIncluded
|
||||
return super.covers(sig) && roleMask.contains(sig.role) && (coverAbstract
|
||||
|| !sig.isAbstract);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Generic signature mask. Masks are initially created empty and cover nothing.
|
||||
* Generic signature mask. Newly created masks cover everything.
|
||||
*
|
||||
* @param <T> The type of Signature to handle.
|
||||
*
|
||||
@ -20,12 +20,16 @@ public abstract class SigMask<T extends Signature> {
|
||||
/** Visibility mask. */
|
||||
protected Set<Signature.Visibility> visMask = new HashSet<>();
|
||||
|
||||
public SigMask(){
|
||||
coverAllVisibilities();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the visibility mask and adds all parameters.
|
||||
* Restricts the visibilities covered by the mask to the parameters.
|
||||
*
|
||||
* @param visibilities The visibilities to add
|
||||
* @param visibilities The visibilities to cover.
|
||||
*/
|
||||
public void setVisibilityMask(Signature.Visibility... visibilities) {
|
||||
public void restrictVisibilitiesTo(Signature.Visibility... visibilities) {
|
||||
visMask.clear();
|
||||
visMask.addAll(Arrays.asList(visibilities));
|
||||
}
|
||||
@ -33,28 +37,27 @@ public abstract class SigMask<T extends Signature> {
|
||||
/**
|
||||
* Sets the mask to cover all visibilities.
|
||||
*/
|
||||
public void setAllVisibilities() {
|
||||
public void coverAllVisibilities() {
|
||||
visMask.addAll(Arrays.asList(Signature.Visibility.values()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all mentioned visibilities from the mask.
|
||||
* Forbid all mentioned visibilities.
|
||||
*
|
||||
* @param visibilities The visibilities to remove
|
||||
* @param visibilities The visibilities to forbid.
|
||||
*/
|
||||
public void remove(Signature.Visibility... visibilities) {
|
||||
public void forbid(Signature.Visibility... visibilities) {
|
||||
visMask.removeAll(Arrays.asList(visibilities));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the parameter is covered by this mask.
|
||||
*
|
||||
* @param sig The signature to test
|
||||
* @param sig The signature to test.
|
||||
*
|
||||
* @return True if the parameter is covered by this mask
|
||||
*/
|
||||
public boolean covers(T sig) {
|
||||
return visMask.contains(sig.visibility);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,10 +4,8 @@
|
||||
|
||||
package net.sourceforge.pmd.lang.java.oom;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
@ -15,7 +13,6 @@ import org.junit.Test;
|
||||
import net.sourceforge.pmd.lang.java.ParserTst;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.oom.visitor.FieldSigMask;
|
||||
import net.sourceforge.pmd.lang.java.oom.visitor.FieldSignature;
|
||||
import net.sourceforge.pmd.lang.java.oom.visitor.OperationSigMask;
|
||||
@ -28,7 +25,7 @@ import net.sourceforge.pmd.lang.java.oom.visitor.SigMask;
|
||||
public class SigMaskTest extends ParserTst {
|
||||
|
||||
/**
|
||||
* Ensure nothing is covered by an empty mask
|
||||
* Ensure any method is covered by an empty mask.
|
||||
*/
|
||||
@Test
|
||||
public void testEmptyOperationMask() {
|
||||
@ -38,17 +35,16 @@ public class SigMaskTest extends ParserTst {
|
||||
+ "protected void foo(int x){} "
|
||||
+ "private void rand(){}}";
|
||||
|
||||
|
||||
List<ASTMethodDeclaration> nodes = getOrderedNodes(ASTMethodDeclaration.class, TEST);
|
||||
SigMask<OperationSignature> mask = new OperationSigMask();
|
||||
|
||||
for (ASTMethodDeclaration node : nodes) {
|
||||
assertFalse(mask.covers(OperationSignature.buildFor(node)));
|
||||
assertTrue(mask.covers(OperationSignature.buildFor(node)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure nothing is covered by an empty mask
|
||||
* Ensure any field is covered by an empty mask.
|
||||
*/
|
||||
@Test
|
||||
public void testEmptyFieldMask() {
|
||||
@ -68,10 +64,9 @@ public class SigMaskTest extends ParserTst {
|
||||
SigMask<FieldSignature> mask = new FieldSigMask();
|
||||
|
||||
for (ASTFieldDeclaration node : nodes) {
|
||||
assertFalse(mask.covers(FieldSignature.buildFor(node)));
|
||||
assertTrue(mask.covers(FieldSignature.buildFor(node)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user