Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/yegor256/jpeek into 68
Browse files Browse the repository at this point in the history
  • Loading branch information
llorllale committed Feb 1, 2018
2 parents 54e0bc5 + 250ed06 commit aae0a5f
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 5 deletions.
6 changes: 4 additions & 2 deletions src/main/java/org/jpeek/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,11 @@ public void analyze() throws IOException {
final Iterable<Report> reports = new ListOf<>(
new Report(skeleton, "LCOM", this.params, 10.0d, -5.0d),
new Report(skeleton, "MMAC", this.params, 0.5d, 0.25d),
new Report(skeleton, "LCOM5", this.params, 0.5d, 0.1d),
new Report(skeleton, "LCOM5", this.params),
new Report(skeleton, "NHD"),
new Report(skeleton, "SCOM", this.params, 0.5d, 0.1d)
new Report(skeleton, "LCOM2", this.params),
new Report(skeleton, "LCOM3", this.params),
new Report(skeleton, "SCOM", this.params)
);
new IoCheckedScalar<>(
new AndInThreads(
Expand Down
27 changes: 25 additions & 2 deletions src/main/java/org/jpeek/Report.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@
* @checkstyle ClassDataAbstractionCouplingCheck (500 lines)
*/
final class Report {
/**
* Default mean.
*/
private static final double DEFAULT_MEAN = 0.5d;
/**
* Default sigma.
*/
private static final double DEFAULT_SIGMA = 0.1d;

/**
* XSD schema.
Expand Down Expand Up @@ -95,8 +103,23 @@ final class Report {
* @param name Name of the metric
*/
Report(final XML xml, final String name) {
// @checkstyle MagicNumberCheck (1 line)
this(xml, name, new HashMap<>(0), 0.5d, 0.1d);
this(
xml, name, new HashMap<>(0),
Report.DEFAULT_MEAN, Report.DEFAULT_SIGMA
);
}

/**
* Ctor.
* @param xml Skeleton
* @param name Name of metric
* @param args Params for XSL
*/
Report(final XML xml, final String name, final Map<String, Object> args) {
this(
xml, name, args,
Report.DEFAULT_MEAN, Report.DEFAULT_SIGMA
);
}

/**
Expand Down
93 changes: 93 additions & 0 deletions src/main/resources/org/jpeek/metrics/LCOM2.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?xml version="1.0"?>
<!--
The MIT License (MIT)
Copyright (c) 2017-2018 Yegor Bugayenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:param name="ctors" select="0"/>
<xsl:template match="skeleton">
<metric>
<xsl:apply-templates select="@*"/>
<title>LCOM2</title>
<description>
<xsl:text>LCOM2 is an attempt to address some shortcomings of the
original LCOM:
- LCOM gives a value of zero for very different classes
- Its definition is based on method-data interaction, which may not
be a correct way to define cohesiveness in the object-oriented world
- Very different classes may have an equal value
- As LCOM is defined on variable access, it's not well suited for
classes that internally access their data via properties
LCOM2 equals the percentage of methods that do not access a specific
attribute averaged over all attributes in the class. If the number
of methods or attributes is zero, LCOM2 is undefined and displayed
as zero. Values for LCOM2 are in the range [0, 1]. A low value indicates
high cohesion and a well-designed class. It is likely that the system has
good class subdivision implying simplicity and high reusability. A
cohesive class will tend to provide a high degree of encapsulation.
A higher value of LCOM2 indicates decreased encapsulation and
increased complexity, thereby increasing the likelihood of errors.</xsl:text>
</description>
<xsl:apply-templates select="node()"/>
</metric>
</xsl:template>
<xsl:template match="class">
<xsl:variable name="attrs" select="attributes/attribute/text()"/>
<xsl:variable name="attrs_count" select="count($attrs)"/>
<xsl:variable name="methods" select="methods/method[($ctors=0 and @ctor='false') or $ctors=1]"/>
<xsl:variable name="methods_count" select="count($methods)"/>
<xsl:variable name="attr_use">
<xsl:for-each select="$attrs">
<xsl:variable name="attr" select="."/>
<count>
<xsl:value-of select="count($methods/ops[op = $attr])"/>
</count>
</xsl:for-each>
</xsl:variable>
<xsl:copy>
<xsl:attribute name="value">
<xsl:choose>
<xsl:when test="$methods_count = 0 or $attrs_count = 0">
<xsl:text>0</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="format-number(1 - (sum($attr_use/count) div ($methods_count * $attrs_count)), '0.####')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="@*"/>
<vars>
<var id="methods">
<xsl:value-of select="$methods_count"/>
</var>
<var id="attributes">
<xsl:value-of select="$attrs_count"/>
</var>
</vars>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
91 changes: 91 additions & 0 deletions src/main/resources/org/jpeek/metrics/LCOM3.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0"?>
<!--
The MIT License (MIT)
Copyright (c) 2017-2018 Yegor Bugayenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:param name="ctors" select="0"/>
<xsl:template match="skeleton">
<metric>
<xsl:apply-templates select="@*"/>
<title>LCOM3</title>
<description>
<xsl:text>LCOM3, like LCOM2, is an attempt to address some shortcomings
of the original LCOM:
- LCOM gives a value of zero for very different classes
- Its definition is based on method-data interaction, which may not
be a correct way to define cohesiveness in the object-oriented world
- Very different classes may have an equal value
- As LCOM is defined on variable access, it's not well suited for
classes that internally access their data via properties
LCOM3 values are in the range [0, 2], where 0 = "high cohesion",
1 = "no cohesion" (class should be split), and values &gt;= 1 suggest
serious design flaws in the class, such as unused ("dead") attributes
or perhaps the attributes are accessed only from outside the class.
If there are no more than one method in a class, LCOM3 is undefined.
If there are no variables in a class, LCOM3 is undefined. An
undefined LCOM3 is displayed as zero.</xsl:text>
</description>
<xsl:apply-templates select="node()"/>
</metric>
</xsl:template>
<xsl:template match="class">
<xsl:variable name="attrs" select="attributes/attribute/text()"/>
<xsl:variable name="attrs_count" select="count($attrs)"/>
<xsl:variable name="methods" select="methods/method[($ctors=0 and @ctor='false') or $ctors=1]"/>
<xsl:variable name="methods_count" select="count($methods)"/>
<xsl:variable name="attr_use">
<xsl:for-each select="$attrs">
<xsl:variable name="attr" select="."/>
<count>
<xsl:value-of select="count($methods/ops[op = $attr])"/>
</count>
</xsl:for-each>
</xsl:variable>
<xsl:copy>
<xsl:attribute name="value">
<xsl:choose>
<xsl:when test="$methods_count &lt; 2 or $attrs_count = 0">
<xsl:text>0</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="format-number((($methods_count - (sum($attr_use/count) div $attrs_count)) div ($methods_count - 1)), '0.####')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="@*"/>
<vars>
<var id="methods">
<xsl:value-of select="$methods_count"/>
</var>
<var id="attributes">
<xsl:value-of select="$attrs_count"/>
</var>
</vars>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
23 changes: 22 additions & 1 deletion src/test/java/org/jpeek/MetricsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@
// @todo #68:30min SCOM has an impediment on issue #114: cannot currently
// be tested against "Bar" because the skeleton is incorrectly excluding
// some attributes from some methods that are using them.
// @todo #92:30min Impediment: test for LCOM2/3 with "Bar" is not working
// because the generated skeleton.xml is not including all attributes
// being used by a method. See #114.
// @todo #92:30min Impediment: test for LCOM3 with "OneMethodCreatesLambda"
// does not work because the skeleton.xml creates a <method> for the
// lambda with no way to discriminate it from regular methods.
/**
* Tests for all metrics.
* @author Yegor Bugayenko (yegor256@gmail.com)
Expand Down Expand Up @@ -110,7 +116,22 @@ public static Collection<Object[]> targets() {
new Object[] {"Foo", "SCOM", 1.0d},
new Object[] {"MethodsWithDiffParamTypes", "SCOM", 0.2d},
new Object[] {"OverloadMethods", "SCOM", 1.0d},
new Object[] {"TwoCommonAttributes", "SCOM", 0.0d}
new Object[] {"TwoCommonAttributes", "SCOM", 0.0d},
new Object[] {"Foo", "LCOM2", 0.0d},
new Object[] {"MethodsWithDiffParamTypes", "LCOM2", 0.5d},
new Object[] {"NoMethods", "LCOM2", 0.0d},
new Object[] {"OneVoidMethodWithoutParams", "LCOM2", 0.0d},
new Object[] {"OverloadMethods", "LCOM2", 0.0d},
new Object[] {"TwoCommonAttributes", "LCOM2", 0.6667d},
new Object[] {"WithoutAttributes", "LCOM2", 0.0d},
new Object[] {"OneMethodCreatesLambda", "LCOM2", 1.0d},
new Object[] {"Foo", "LCOM3", 0.0d},
new Object[] {"MethodsWithDiffParamTypes", "LCOM3", 0.6d},
new Object[] {"NoMethods", "LCOM3", 0.0d},
new Object[] {"OneVoidMethodWithoutParams", "LCOM3", 0.0d},
new Object[] {"OverloadMethods", "LCOM3", 0.0d},
new Object[] {"TwoCommonAttributes", "LCOM3", 1.0d},
new Object[] {"WithoutAttributes", "LCOM3", 0.0d}
);
}

Expand Down

3 comments on commit aae0a5f

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on aae0a5f Feb 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 68-6427b294 discovered in src/test/java/org/jpeek/MetricsTest.java and submitted as #140. Please, remember that the puzzle was not necessarily added in this particular commit. Maybe it was added earlier, but
we discovered it only now.

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on aae0a5f Feb 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 68-96e0ea92 discovered in src/test/java/org/jpeek/MetricsTest.java and submitted as #141. Please, remember that the puzzle was not necessarily added in this particular commit. Maybe it was added earlier, but
we discovered it only now.

@0pdd
Copy link
Collaborator

@0pdd 0pdd commented on aae0a5f Feb 1, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 68-03d5665d discovered in src/main/resources/org/jpeek/metrics/SCOM.xsl and submitted as #142. Please, remember that the puzzle was not necessarily added in this particular commit. Maybe it was added earlier, but
we discovered it only now.

Please sign in to comment.