Façade and Computer

This commit is contained in:
oowekyala
2017-07-30 15:25:58 +02:00
parent e02dfae300
commit d9273add4f
5 changed files with 201 additions and 2 deletions

View File

@ -36,9 +36,10 @@ a singleton.
your `MetricsComputer`. It backs the real end user façade, and handles user provided parameters before delegating to
your `MetricsComputer`.
* Create the static façade of your framework. This one has an instance of your `MetricsFaçade` object and delegates
static methods to that instance. It should be able to give back
static methods to that instance.
* If you want to implement signature matching, create an `AbstractMetric` class, which gives access to a
`SignatureMatcher` to your metrics.
`SignatureMatcher` to your metrics. Typically, your implementation of `ProjectMirror` implements a
custom `SignatureMatcher` interface, and your façade can give back its instance of the project mirror.
* Create classes `AbstractOperationMetric` and `AbstractClassMetric`. These must implement `Metric<T>` and
`Metric<O>`, respectively. They typically provide defaults for the `supports` method of each metric.
* Create enums `ClassMetricKey` and `OperationMetricKey`. These must implement `MetricKey<T>` and `MetricKey<O>`. The

View File

@ -0,0 +1,132 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.metrics;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.metrics.Metric.Version;
import net.sourceforge.pmd.lang.metrics.MetricKey;
import net.sourceforge.pmd.lang.metrics.MetricVersion;
import net.sourceforge.pmd.lang.metrics.ResultOption;
/**
* @author Clément Fournier
*/
public final class ApexMetrics {
private static final ApexMetricsFacade FACADE = new ApexMetricsFacade();
private ApexMetrics() { // Cannot be instantiated
}
/**
* Returns the project mirror of the analysed project.
*
* @return The project mirror
*/
static ApexProjectMirror getTopLevelPackageStats() {
return FACADE.getLanguageSpecificProjectMirror();
}
/** Resets the entire data structure. Used for tests. */
static void reset() {
FACADE.reset();
}
/**
* Computes the standard value of the metric identified by its code on a class AST node.
*
* @param key The key identifying the metric to be computed
* @param node The node on which to compute the metric
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed
*/
public static double get(MetricKey<ASTUserClass> key, ASTUserClass node) {
return FACADE.computeForType(key, node, Version.STANDARD);
}
/**
* Computes a metric identified by its code on a class AST node, possibly selecting a variant with the {@code
* MetricVersion} parameter.
*
* @param key The key identifying the metric to be computed
* @param node The node on which to compute the metric
* @param version The version of the metric
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed
*/
public static double get(MetricKey<ASTUserClass> key, ASTUserClass node, MetricVersion version) {
return FACADE.computeForType(key, node, version);
}
/**
* Computes the standard version of the metric identified by the key on a operation AST node.
*
* @param key The key identifying the metric to be computed
* @param node The node on which to compute the metric
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed
*/
public static double get(MetricKey<ASTMethod> key, ASTMethod node) {
return FACADE.computeForOperation(key, node, Version.STANDARD);
}
/**
* Computes a metric identified by its key on a operation AST node.
*
* @param key The key identifying the metric to be computed
* @param node The node on which to compute the metric
* @param version The version of the metric
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed
*/
public static double get(MetricKey<ASTMethod> key, ASTMethod node, MetricVersion version) {
return FACADE.computeForOperation(key, node, version);
}
/**
* Compute the sum, average, or highest value of the standard operation metric on all operations of the class node.
* The type of operation is specified by the {@link ResultOption} parameter.
*
* @param key The key identifying the metric to be computed
* @param node The node on which to compute the metric
* @param option The result option to use
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed or {@code option} is
* {@code null}
*/
public static double get(MetricKey<ASTMethod> key, ASTUserClass node, ResultOption option) {
return FACADE.computeWithResultOption(key, node, Version.STANDARD, option);
}
/**
* Compute the sum, average, or highest value of the operation metric on all operations of the class node. The type
* of operation is specified by the {@link ResultOption} parameter.
*
* @param key The key identifying the metric to be computed
* @param node The node on which to compute the metric
* @param version The version of the metric
* @param option The result option to use
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed or {@code option} is
* {@code null}
*/
public static double get(MetricKey<ASTMethod> key, ASTUserClass node, MetricVersion version,
ResultOption option) {
return FACADE.computeWithResultOption(key, node, version, option);
}
}

View File

@ -0,0 +1,24 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.metrics;
import java.util.List;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.metrics.AbstractMetricsComputer;
/**
* @author Clément Fournier
*/
public class ApexMetricsComputer extends AbstractMetricsComputer<ASTUserClass, ASTMethod> {
public static final ApexMetricsComputer INSTANCE = new ApexMetricsComputer();
@Override
protected List<ASTMethod> findOperations(ASTUserClass node) {
return node.findChildrenOfType(ASTMethod.class);
}
}

View File

@ -0,0 +1,36 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex.metrics;
import net.sourceforge.pmd.lang.apex.ast.ASTMethod;
import net.sourceforge.pmd.lang.apex.ast.ASTUserClass;
import net.sourceforge.pmd.lang.metrics.AbstractMetricsFacade;
import net.sourceforge.pmd.lang.metrics.MetricsComputer;
/**
* @author Clément Fournier
*/
public class ApexMetricsFacade extends AbstractMetricsFacade<ASTUserClass, ASTMethod> {
private final ApexProjectMirror projectMirror = new ApexProjectMirror();
/** Resets the entire project mirror. Used for tests. */
void reset() {
projectMirror.reset();
}
@Override
protected MetricsComputer<ASTUserClass, ASTMethod> getLanguageSpecificComputer() {
return ApexMetricsComputer.INSTANCE;
}
@Override
protected ApexProjectMirror getLanguageSpecificProjectMirror() {
return projectMirror;
}
}

View File

@ -25,6 +25,12 @@ public class ApexProjectMirror implements ProjectMirror<ASTUserClass, ASTMethod>
private final Map<ApexQualifiedName, ApexClassStats> classes = new HashMap<>();
void reset() {
operations.clear();
classes.clear();
}
ApexOperationStats addOperation(ApexQualifiedName qname, ApexOperationSignature sig) {
if (!operations.containsKey(sig)) {
operations.put(sig, new HashMap<>());