A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/pmd/pmd/commit/63395684c4e333ccec3fdc489e6a21b92aadf370 below:

Merge branch 'pr-2076' · pmd/pmd@6339568 · GitHub

File tree Expand file treeCollapse file tree 10 files changed

+345

-4

lines changed

Filter options

Expand file treeCollapse file tree 10 files changed

+345

-4

lines changed Original file line number Diff line number Diff line change

@@ -23,6 +23,44 @@ it uses instead of the services they provide.

23 23 24 24

ATFD can be used to detect God Classes and Feature Envy. \[[Lanza05](#Lanza05)\]

25 25 26 +

## Class Fan Out Complexity (CLASS_FAN_OUT)

27 + 28 +

*Operation metric, class metric.* Can be computed on classes, enums and

29 +

concrete operations.

30 + 31 +

### Description

32 +

This counts the number of other classes a given class or operation relies on.

33 +

Classes from the package `java.lang` are ignored by default (can be changed via options).

34 +

Also primitives are not included into the count.

35 + 36 +

### Code example

37 + 38 +

```java

39 +

import java.util.*;

40 +

import java.io.IOException;

41 + 42 +

public class Foo { // total 8

43 +

public Set set = new HashSet(); // +2

44 +

public Map map = new HashMap(); // +2

45 +

public String string = ""; // from java.lang -> does not count by default

46 +

public Double number = 0.0; // from java.lang -> does not count by default

47 +

public int[] intArray = new int[3]; // primitive -> does not count

48 + 49 +

@Deprecated // from java.lang -> does not count by default

50 +

@Override // from java.lang -> does not count by default

51 +

public void foo(List list) throws Exception { // +1 (Exception is from java.lang)

52 +

throw new IOException(); // +1

53 +

}

54 + 55 +

public int getMapSize() {

56 +

return map.size(); // +1 because it uses the Class from the 'map' field

57 +

}

58 +

}

59 +

```

60 + 61 +

### Options

62 + 63 +

* Option `includeJavaLang`: Also include classes from the package `java.lang`

26 64 27 65

## Cyclomatic Complexity (CYCLO)

28 66 Original file line number Diff line number Diff line change

@@ -34,6 +34,11 @@ This is a {{ site.pmd.release_type }} release.

34 34

usages of `Executors` and `ExecutorService`. Both create new threads, which are not managed by a J2EE

35 35

server.

36 36 37 +

#### Java Metrics

38 + 39 +

* The new metric "Class Fan Out Complexity" has been added. See

40 +

[Java Metrics Documentation](pmd_java_metrics_index.html#class-fan-out-complexity-class_fan_out) for details.

41 + 37 42

### Fixed Issues

38 43 39 44

* core

@@ -61,7 +66,6 @@ This is a {{ site.pmd.release_type }} release.

61 66 62 67

### API Changes

63 68 64 - 65 69

#### Deprecated APIs

66 70 67 71

##### For removal

@@ -104,10 +108,11 @@ This is a {{ site.pmd.release_type }} release.

104 108

* [#2010](https://github.com/pmd/pmd/pull/2010): \[java] LawOfDemeter to support inner builder pattern - [Gregor Riegler](https://github.com/gregorriegler)

105 109

* [#2012](https://github.com/pmd/pmd/pull/2012): \[java] Fixes 336, slf4j log4j2 support - [Mark Hall](https://github.com/markhall82)

106 110

* [#2032](https://github.com/pmd/pmd/pull/2032): \[core] Allow adding SourceCode directly into CPD - [Nathan Braun](https://github.com/nbraun-Google)

107 -

* [#2047](https://github.com/pmd/pmd/pull/2047): \[java] Fix computation of metrics with annotations - [Andi](https://github.com/andipabst)

111 +

* [#2047](https://github.com/pmd/pmd/pull/2047): \[java] Fix computation of metrics with annotations - [Andi Pabst](https://github.com/andipabst)

108 112

* [#2065](https://github.com/pmd/pmd/pull/2065): \[java] Stop checking UR anomalies - [Carlos Macasaet](https://github.com/l0s)

109 113

* [#2070](https://github.com/pmd/pmd/pull/2070): \[core] Fix renderer tests for windows builds - [Saladoc](https://github.com/Saladoc)

110 114

* [#2073](https://github.com/pmd/pmd/pull/2073): \[test]\[core] Add expected and actual line of numbers to message wording - [snuyanzin](https://github.com/snuyanzin)

115 +

* [#2076](https://github.com/pmd/pmd/pull/2076): \[java] Add Metric ClassFanOutComplexity - [Andi Pabst](https://github.com/andipabst)

111 116

* [#2078](https://github.com/pmd/pmd/pull/2078): \[java] DoNotUseThreads should not warn on Runnable #1627 - [Michael Clay](https://github.com/mclay)

112 117 113 118

{% endtocmaker %}

Original file line number Diff line number Diff line change

@@ -6,6 +6,7 @@

6 6 7 7

import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;

8 8

import net.sourceforge.pmd.lang.java.metrics.impl.AtfdMetric.AtfdClassMetric;

9 +

import net.sourceforge.pmd.lang.java.metrics.impl.ClassFanOutMetric.ClassFanOutClassMetric;

9 10

import net.sourceforge.pmd.lang.java.metrics.impl.LocMetric.LocClassMetric;

10 11

import net.sourceforge.pmd.lang.java.metrics.impl.NcssMetric.NcssClassMetric;

11 12

import net.sourceforge.pmd.lang.java.metrics.impl.NoamMetric;

@@ -74,7 +75,14 @@ public enum JavaClassMetricKey implements MetricKey<ASTAnyTypeDeclaration> {

74 75

*

75 76

* @see TccMetric

76 77

*/

77 -

TCC(new TccMetric());

78 +

TCC(new TccMetric()),

79 + 80 +

/**

81 +

* ClassFanOut Complexity

82 +

*

83 +

* @see ClassFanOutClassMetric

84 +

*/

85 +

CLASS_FAN_OUT(new ClassFanOutClassMetric());

78 86 79 87 80 88

private final JavaClassMetric calculator;

Original file line number Diff line number Diff line change

@@ -7,6 +7,7 @@

7 7

import net.sourceforge.pmd.lang.java.ast.ASTMethodOrConstructorDeclaration;

8 8

import net.sourceforge.pmd.lang.java.ast.MethodLikeNode;

9 9

import net.sourceforge.pmd.lang.java.metrics.impl.AtfdMetric.AtfdOperationMetric;

10 +

import net.sourceforge.pmd.lang.java.metrics.impl.ClassFanOutMetric.ClassFanOutOperationMetric;

10 11

import net.sourceforge.pmd.lang.java.metrics.impl.CycloMetric;

11 12

import net.sourceforge.pmd.lang.java.metrics.impl.LocMetric.LocOperationMetric;

12 13

import net.sourceforge.pmd.lang.java.metrics.impl.NcssMetric.NcssOperationMetric;

@@ -53,7 +54,14 @@ public enum JavaOperationMetricKey implements MetricKey<MethodLikeNode> {

53 54

*

54 55

* @see NpathMetric

55 56

*/

56 -

NPATH(new NpathMetric());

57 +

NPATH(new NpathMetric()),

58 + 59 +

/**

60 +

* ClassFanOut Complexity

61 +

*

62 +

* @see ClassFanOutOperationMetric

63 +

*/

64 +

CLASS_FAN_OUT(new ClassFanOutOperationMetric());

57 65 58 66 59 67

private final JavaOperationMetric calculator;

Original file line number Diff line number Diff line change

@@ -0,0 +1,71 @@

1 +

/**

2 +

* BSD-style license; for more info see http://pmd.sourceforge.net/license.html

3 +

*/

4 + 5 +

package net.sourceforge.pmd.lang.java.metrics.impl;

6 + 7 +

import org.apache.commons.lang3.mutable.MutableInt;

8 + 9 +

import net.sourceforge.pmd.lang.java.ast.ASTAnyTypeDeclaration;

10 +

import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceBodyDeclaration;

11 +

import net.sourceforge.pmd.lang.java.ast.MethodLikeNode;

12 +

import net.sourceforge.pmd.lang.java.metrics.impl.internal.ClassFanOutVisitor;

13 +

import net.sourceforge.pmd.lang.metrics.MetricOption;

14 +

import net.sourceforge.pmd.lang.metrics.MetricOptions;

15 + 16 + 17 +

/**

18 +

* The ClassFanOutComplexity counts the usage of other classes within this class.

19 +

*

20 +

* @author Andreas Pabst

21 +

* @since October 2019

22 +

*/

23 +

public final class ClassFanOutMetric {

24 + 25 +

public enum ClassFanOutOption implements MetricOption {

26 +

/** Whether to include Classes in the java.lang package. */

27 +

INCLUDE_JAVA_LANG("includeJavaLang");

28 + 29 +

private final String vName;

30 + 31 +

ClassFanOutOption(String valueName) {

32 +

this.vName = valueName;

33 +

}

34 + 35 +

@Override

36 +

public String valueName() {

37 +

return vName;

38 +

}

39 +

}

40 + 41 +

public static final class ClassFanOutClassMetric extends AbstractJavaClassMetric {

42 + 43 +

@Override

44 +

public double computeFor(ASTAnyTypeDeclaration node, MetricOptions options) {

45 +

MutableInt cfo = (MutableInt) node.jjtAccept(new ClassFanOutVisitor(options, node), new MutableInt(0));

46 +

return (double) cfo.getValue();

47 +

}

48 +

}

49 + 50 +

public static final class ClassFanOutOperationMetric extends AbstractJavaOperationMetric {

51 + 52 +

@Override

53 +

public boolean supports(MethodLikeNode node) {

54 +

return true;

55 +

}

56 + 57 +

@Override

58 +

public double computeFor(MethodLikeNode node, MetricOptions options) {

59 +

MutableInt cfo;

60 +

// look at the parent to catch annotations

61 +

if (node.jjtGetParent() instanceof ASTClassOrInterfaceBodyDeclaration) {

62 +

ASTClassOrInterfaceBodyDeclaration parent = (ASTClassOrInterfaceBodyDeclaration) node.jjtGetParent();

63 +

cfo = (MutableInt) parent.jjtAccept(new ClassFanOutVisitor(options, node), new MutableInt(0));

64 +

} else {

65 +

cfo = (MutableInt) node.jjtAccept(new ClassFanOutVisitor(options, node), new MutableInt(0));

66 +

}

67 + 68 +

return (double) cfo.getValue();

69 +

}

70 +

}

71 +

}

Original file line number Diff line number Diff line change

@@ -0,0 +1,72 @@

1 +

/**

2 +

* BSD-style license; for more info see http://pmd.sourceforge.net/license.html

3 +

*/

4 + 5 +

package net.sourceforge.pmd.lang.java.metrics.impl.internal;

6 + 7 +

import java.util.HashSet;

8 +

import java.util.Set;

9 + 10 +

import org.apache.commons.lang3.mutable.MutableInt;

11 + 12 +

import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;

13 +

import net.sourceforge.pmd.lang.java.ast.ASTName;

14 +

import net.sourceforge.pmd.lang.java.ast.JavaNode;

15 +

import net.sourceforge.pmd.lang.java.ast.JavaParserVisitorAdapter;

16 +

import net.sourceforge.pmd.lang.java.ast.TypeNode;

17 +

import net.sourceforge.pmd.lang.java.metrics.impl.ClassFanOutMetric.ClassFanOutOption;

18 +

import net.sourceforge.pmd.lang.metrics.MetricOptions;

19 + 20 + 21 +

/**

22 +

* Visitor for the ClassFanOut metric.

23 +

*

24 +

* @author Andreas Pabst

25 +

*/

26 +

public class ClassFanOutVisitor extends JavaParserVisitorAdapter {

27 + 28 +

private static final String JAVA_LANG_PACKAGE_NAME = "java.lang";

29 +

protected Set<Class<?>> classes = new HashSet<>();

30 +

private final boolean includeJavaLang;

31 + 32 +

@SuppressWarnings("PMD.UnusedFormalParameter")

33 +

public ClassFanOutVisitor(MetricOptions options, JavaNode topNode) {

34 +

includeJavaLang = options.getOptions().contains(ClassFanOutOption.INCLUDE_JAVA_LANG);

35 +

// topNode is unused, but we'll need it if we want to discount lambdas

36 +

// if we add it later, we break binary compatibility

37 +

}

38 + 39 +

@Override

40 +

public Object visit(ASTClassOrInterfaceType node, Object data) {

41 +

check(node, (MutableInt) data);

42 +

return super.visit(node, data);

43 +

}

44 + 45 +

@Override

46 +

public Object visit(ASTName node, Object data) {

47 +

check(node, (MutableInt) data);

48 +

return super.visit(node, data);

49 +

}

50 + 51 +

private void check(TypeNode node, MutableInt counter) {

52 +

if (!classes.contains(node.getType()) && shouldBeIncluded(node.getType())) {

53 +

classes.add(node.getType());

54 +

counter.increment();

55 +

}

56 +

}

57 + 58 +

private boolean shouldBeIncluded(Class<?> classToCheck) {

59 +

if (includeJavaLang || classToCheck == null) {

60 +

// include all packages

61 +

return true;

62 +

} else {

63 +

// exclude the java.lang package

64 +

Package packageToCheck = classToCheck.getPackage();

65 +

if (packageToCheck == null) {

66 +

return true;

67 +

}

68 + 69 +

return !JAVA_LANG_PACKAGE_NAME.equals(packageToCheck.getName());

70 +

}

71 +

}

72 +

}

Original file line number Diff line number Diff line change

@@ -38,6 +38,7 @@ public void setUp() {

38 38

addRule(RULESET, "WocTest");

39 39

addRule(RULESET, "TccTest");

40 40

addRule(RULESET, "AtfdTest");

41 +

addRule(RULESET, "CfoTest");

41 42

}

42 43 43 44

}

Original file line number Diff line number Diff line change

@@ -0,0 +1,36 @@

1 +

/**

2 +

* BSD-style license; for more info see http://pmd.sourceforge.net/license.html

3 +

*/

4 + 5 +

package net.sourceforge.pmd.lang.java.metrics.impl;

6 + 7 +

import java.util.Map;

8 + 9 +

import net.sourceforge.pmd.lang.java.metrics.api.JavaClassMetricKey;

10 +

import net.sourceforge.pmd.lang.java.metrics.api.JavaOperationMetricKey;

11 +

import net.sourceforge.pmd.lang.java.metrics.impl.ClassFanOutMetric.ClassFanOutOption;

12 +

import net.sourceforge.pmd.lang.metrics.MetricOption;

13 + 14 +

/**

15 +

* @author Andreas Pabst

16 +

*/

17 +

public class CfoTestRule extends AbstractMetricTestRule {

18 + 19 +

@Override

20 +

protected JavaClassMetricKey getClassKey() {

21 +

return JavaClassMetricKey.CLASS_FAN_OUT;

22 +

}

23 + 24 + 25 +

@Override

26 +

protected JavaOperationMetricKey getOpKey() {

27 +

return JavaOperationMetricKey.CLASS_FAN_OUT;

28 +

}

29 + 30 +

@Override

31 +

protected Map<String, MetricOption> optionMappings() {

32 +

Map<String, MetricOption> mappings = super.optionMappings();

33 +

mappings.put(ClassFanOutOption.INCLUDE_JAVA_LANG.valueName(), ClassFanOutOption.INCLUDE_JAVA_LANG);

34 +

return mappings;

35 +

}

36 +

}

You can’t perform that action at this time.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4