Skip to content

Commit

Permalink
Varargs options -> bad
Browse files Browse the repository at this point in the history
  • Loading branch information
oowekyala committed Aug 18, 2017
1 parent 0351b88 commit 6408b57
Show file tree
Hide file tree
Showing 25 changed files with 1,018 additions and 176 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
public class ApexProjectMirrorTest {

private static ApexNode<Compilation> acu;
private MetricKey<ASTUserClassOrInterface<?>> classMetricKey = MetricKeyUtil.of(new RandomClassMetric(), null);
private MetricKey<ASTMethod> opMetricKey = MetricKeyUtil.of(new RandomOperationMetric(), null);
private MetricKey<ASTUserClassOrInterface<?>> classMetricKey = MetricKeyUtil.of(null, new RandomClassMetric());
private MetricKey<ASTMethod> opMetricKey = MetricKeyUtil.of(null, new RandomOperationMetric());


static {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.util.Objects;

import net.sourceforge.pmd.lang.ast.QualifiableNode;
import net.sourceforge.pmd.lang.metrics.Metric.Version;

/**
* Base class for a façade that can compute metrics for types, operations and compute aggregate results with a result
Expand Down Expand Up @@ -43,23 +42,24 @@ public abstract class AbstractMetricsFacade<T extends QualifiableNode, O extends
*
* @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 options The options of the metric
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed
* @return The value of the metric, or {@code Double.NaN} if the value couldn't be computed
*/
public double computeForType(MetricKey<T> key, T node, MetricVersion version) {
public double computeForType(MetricKey<T> key, T node, MetricOption... options) {

Objects.requireNonNull(key, "The metric key must not be null");

if (!key.supports(node)) {
return Double.NaN;
}

MetricVersion safeVersion = (version == null) ? Version.STANDARD : version;
MetricVersion version = MetricVersion.ofOptions(options);
MetricMemoizer<T> memoizer = getLanguageSpecificProjectMemoizer().getClassMemoizer(node.getQualifiedName());

return memoizer == null ? Double.NaN
: getLanguageSpecificComputer().computeForType(key, node, false, safeVersion, memoizer);
: getLanguageSpecificComputer().computeForType(key, node, false,
version, memoizer);
}


Expand All @@ -68,25 +68,24 @@ public double computeForType(MetricKey<T> key, T node, MetricVersion version) {
*
* @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 options The options of the metric
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed
* @return The value of the metric, or {@code Double.NaN} if the value couldn't be computed
*/
public double computeForOperation(MetricKey<O> key, O node,
MetricVersion version) {
public double computeForOperation(MetricKey<O> key, O node, MetricOption... options) {

Objects.requireNonNull(key, "The metric key must not be null");

if (!key.supports(node)) {
return Double.NaN;
}

MetricVersion safeVersion = (version == null) ? Version.STANDARD : version;
MetricVersion version = MetricVersion.ofOptions(options);
MetricMemoizer<O> memoizer = getLanguageSpecificProjectMemoizer().getOperationMemoizer(node.getQualifiedName());

return memoizer == null ? Double.NaN
: getLanguageSpecificComputer().computeForOperation(key, node, false,
safeVersion, memoizer);
version, memoizer);

}

Expand All @@ -95,23 +94,23 @@ public double computeForOperation(MetricKey<O> key, O node,
* 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
* @param key The key identifying the metric to be computed
* @param node The node on which to compute the metric
* @param resultOption The result option to use
* @param options The options of the metric
*
* @return The value of the metric, or {@code Double.NaN} if the value couln't be computed or {@code option} is
* {@code null}
* @return The value of the metric, or {@code Double.NaN} if the value couldn't be computed or {@code resultOption}
* is {@code null}
*/
public double computeWithResultOption(MetricKey<O> key, T node,
MetricVersion version, ResultOption option) {
ResultOption resultOption, MetricOption... options) {

Objects.requireNonNull(key, "The metric key must not be null");
Objects.requireNonNull(option, "The result option must not be null");
Objects.requireNonNull(resultOption, "The result option must not be null");

MetricVersion safeVersion = (version == null) ? Version.STANDARD : version;
MetricVersion version = MetricVersion.ofOptions(options);

return getLanguageSpecificComputer().computeWithResultOption(key, node, false, safeVersion,
option, getLanguageSpecificProjectMemoizer());
return getLanguageSpecificComputer().computeWithResultOption(key, node, false, version,
resultOption, getLanguageSpecificProjectMemoizer());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import net.sourceforge.pmd.lang.ast.Node;

/**
* Object computing a metric on a node. Metric objects are be stateless, which means that instances of the same
* Object computing a metric on a node. Metric objects are stateless, which means that instances of the same
* metric are all equal.
*
* @param <N> Type of nodes the metric can be computed on
Expand Down Expand Up @@ -37,11 +37,4 @@ public interface Metric<N extends Node> {
*/
double computeFor(N node, MetricVersion version);


/** Default metric versions. */
enum Version implements MetricVersion {
/** Standard option, used as a default. */
STANDARD
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@ private MetricKeyUtil() {

}


/**
* Creates a new metric key holding a metric which can be computed on a class.
*
* TODO:cf Move that to the MetricKey interface once we upgrade the compiler
*
* @param metric The metric to use
* @param name The name of the metric
* @param metric The metric to use
*
* @return The metric key
*/
public static <T extends Node> MetricKey<T> of(final Metric<T> metric, final String name) {
public static <T extends Node> MetricKey<T> of(final String name, final Metric<T> metric) {
return new MetricKey<T>() {
@Override
public String name() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/

package net.sourceforge.pmd.lang.metrics;

/**
* Option to pass to a metric. This is use to combine several behaviours together.
*
* @author Clément Fournier
*/
public interface MetricOption {

/**
* Returns the name of the option.
*
* @return The name of the option.
*/
String name();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,119 @@

package net.sourceforge.pmd.lang.metrics;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
* Version of a metric. Only one version can be active on a metric. Versions should typically be defined in an enum
* named {@literal '<short name of metric>Version'} nested inside the implementation class of the metric.
* Gathers a set of options to pass to a metric. Metrics may use these options as they see fit. That's used internally
* to pass all options at once to a metric.
*
* @author Clément Fournier
*/
public interface MetricVersion {
public class MetricVersion {

private static final Map<MetricVersion, MetricVersion> POOL = new HashMap<>();
private Set<MetricOption> options;


static {
MetricVersion emptyVersion = new MetricVersion();
POOL.put(emptyVersion, emptyVersion);
}


private MetricVersion(Set<MetricOption> opts) {

switch (opts.size()) {
case 0:
options = Collections.emptySet();
break;
case 1:
options = Collections.singleton(opts.iterator().next());
break;
default:
options = Collections.unmodifiableSet(opts);
break;
}
}


@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

MetricVersion version = (MetricVersion) o;

return options.equals(version.options);
}


@Override
public int hashCode() {
return options.hashCode();
}


/**
* Returns the name of the version.
* Returns an immutable set of options. Metrics may use these options as they see fit.
*
* @return The name of the version.
* @return The set of options of this version
*/
String name();
public Set<MetricOption> getOptions() {
return options;
}


@Override
public String toString() {
return "MetricVersion{" +
"options=" + options +
'}';
}


/**
* Gets a version from a list of options.
*
* @param opts The options to build the version from
*
* @return A metric version
*/
public static MetricVersion ofOptions(MetricOption... opts) {

}

public static MetricVersion ofOptions(Collection<MetricOption> opts) {
MetricVersion version = new MetricVersion(new HashSet<>(opts));
if (!POOL.containsKey(version)) {
POOL.put(version, version);
}

return POOL.get(version);
}


/**
* Gets an array of options from a version.
*
* @param version The version to decompose
*
* @return An array of options
*/
public static MetricOption[] toOptions(MetricVersion version) {
Set<MetricOption> options = version.getOptions();
return options.toArray(new MetricOption[options.size()]);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private ParameterizedMetricKey(MetricKey<N> key, MetricVersion version) {

@Override
public String toString() {
return "ParameterizedMetricKey{key=" + key.name() + ", version=" + version.name() + '}';
return "ParameterizedMetricKey{key=" + key.name() + ", version=" + version + '}';
}


Expand Down
Loading

0 comments on commit 6408b57

Please sign in to comment.