From 76f3c9eeb225ceb2712e811a55a4ae7ec69a213f Mon Sep 17 00:00:00 2001 From: Marco Ballario Date: Tue, 27 Sep 2022 22:53:18 +0200 Subject: [PATCH 1/3] Replace single WMC field with class and interface sums --- src/metrics/wmc.rs | 154 ++++++++++++++++++++++++++++++------- src/output/dump_metrics.rs | 16 +++- src/spaces.rs | 1 + 3 files changed, 138 insertions(+), 33 deletions(-) diff --git a/src/metrics/wmc.rs b/src/metrics/wmc.rs index 4b9b90a51..2b9b60909 100644 --- a/src/metrics/wmc.rs +++ b/src/metrics/wmc.rs @@ -19,8 +19,11 @@ use crate::*; /// #[derive(Debug, Clone, Default)] pub struct Stats { - wmc: f64, cc: f64, + class_wmc: f64, + interface_wmc: f64, + class_wmc_sum: f64, + interface_wmc_sum: f64, space_kind: SpaceKind, } @@ -29,15 +32,23 @@ impl Serialize for Stats { where S: Serializer, { - let mut st = serializer.serialize_struct("wmc", 1)?; - st.serialize_field("wmc", &self.wmc())?; + let mut st = serializer.serialize_struct("wmc", 3)?; + st.serialize_field("classes", &self.class_wmc_sum())?; + st.serialize_field("interfaces", &self.interface_wmc_sum())?; + st.serialize_field("total", &self.total_wmc())?; st.end() } } impl fmt::Display for Stats { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "wmc: {}", self.wmc(),) + write!( + f, + "classes: {}, interfaces: {}, total: {}", + self.class_wmc_sum(), + self.interface_wmc_sum(), + self.total_wmc() + ) } } @@ -46,23 +57,56 @@ impl Stats { pub fn merge(&mut self, other: &Stats) { use SpaceKind::*; - match (self.space_kind, other.space_kind) { - (Unit, Class | Interface) => { - self.wmc += other.wmc; + // Merges the cyclomatic complexity of a method + // into the `Wmc` metric value of a class or interface + if let Function = other.space_kind { + match self.space_kind { + Class => self.class_wmc += other.cc, + Interface => self.interface_wmc += other.cc, + _ => {} } - (Class | Interface, Function) => { - // Merges the cyclomatic complexity of the method - // into the `Wmc` metric of the class or interface - self.wmc += other.cc; - } - _ => {} } + + self.class_wmc_sum += other.class_wmc_sum; + self.interface_wmc_sum += other.interface_wmc_sum; + } + + /// Returns the `Wmc` metric value of the classes in a space. + #[inline(always)] + pub fn class_wmc(&self) -> f64 { + self.class_wmc + } + + /// Returns the `Wmc` metric value of the interfaces in a space. + #[inline(always)] + pub fn interface_wmc(&self) -> f64 { + self.interface_wmc + } + + /// Returns the sum of the `Wmc` metric values of the classes in a space. + #[inline(always)] + pub fn class_wmc_sum(&self) -> f64 { + self.class_wmc_sum + } + + /// Returns the sum of the `Wmc` metric values of the interfaces in a space. + #[inline(always)] + pub fn interface_wmc_sum(&self) -> f64 { + self.interface_wmc_sum + } + + /// Returns the total `Wmc` metric value in a space. + #[inline(always)] + pub fn total_wmc(&self) -> f64 { + self.class_wmc_sum() + self.interface_wmc_sum() } - /// Returns the `Wmc` metric value. + // Accumulates the `Wmc` metric values + // of classes and interfaces into the sums #[inline(always)] - pub fn wmc(&self) -> f64 { - self.wmc + pub(crate) fn compute_sum(&mut self) { + self.class_wmc_sum += self.class_wmc; + self.interface_wmc_sum += self.interface_wmc; } // Checks if the `Wmc` metric is disabled @@ -160,7 +204,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 13.0)] // 1 top level class + [ + (class_wmc_sum, 13.0), // 1 class + (interface_wmc_sum, 0.0), + (total_wmc, 13.0) + ] ); } @@ -194,7 +242,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 5.0)] // 2 top level classes (wmc total = 3 + 2) + [ + (class_wmc_sum, 5.0), // 2 classes (3 + 2) + (interface_wmc_sum, 0.0), + (total_wmc, 5.0) + ] ); } @@ -211,7 +263,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 0.0)] // 1 top level class + [ + (class_wmc_sum, 1.0), // 2 classes (0 + 1) + (interface_wmc_sum, 0.0), + (total_wmc, 1.0) + ] ); } @@ -270,7 +326,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 2.0)] // 1 top level class + [ + (class_wmc_sum, 9.0), // 6 classes (2 + 1 + 2 + 1 + 1 + 2) + (interface_wmc_sum, 0.0), + (total_wmc, 9.0) + ] ); } @@ -298,7 +358,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 5.0)] // 1 top level class + [ + (class_wmc_sum, 7.0), // 2 classes (5 + 2) + (interface_wmc_sum, 0.0), + (total_wmc, 7.0) + ] ); } @@ -323,7 +387,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 4.0)] // 2 top level classes (wmc total = 1 + 3) + [ + (class_wmc_sum, 4.0), // 2 classes (1 + 3) + (interface_wmc_sum, 0.0), + (total_wmc, 4.0) + ] ); } @@ -362,7 +430,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 8.0)] // 2 top level classes (wmc total = 2 + 6) + [ + (class_wmc_sum, 8.0), // 2 classes (2 + 6) + (interface_wmc_sum, 0.0), + (total_wmc, 8.0) + ] ); } @@ -388,7 +460,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 2.0)] // 1 top level class + [ + (class_wmc_sum, 2.0), // 1 class + (interface_wmc_sum, 0.0), + (total_wmc, 2.0) + ] ); } @@ -407,7 +483,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 6.0)] // 1 top level interface + [ + (class_wmc_sum, 0.0), + (interface_wmc_sum, 6.0), // 1 interface + (total_wmc, 6.0) + ] ); } @@ -428,7 +508,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 3.0)] // 2 top level interfaces (wmc total = 1 + 2) + [ + (class_wmc_sum, 0.0), + (interface_wmc_sum, 3.0), // 2 interfaces (1 + 2) + (total_wmc, 3.0) + ] ); } @@ -453,7 +537,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 1.0)] // 1 top level interface + [ + (class_wmc_sum, 0.0), + (interface_wmc_sum, 5.0), // 4 interfaces (1 + 1 + 2 + 1) + (total_wmc, 5.0) + ] ); } @@ -478,7 +566,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 2.0)] // 1 top level interface + [ + (class_wmc_sum, 2.0), // 1 class + (interface_wmc_sum, 2.0), // 1 interface + (total_wmc, 4.0) + ] ); } @@ -503,7 +595,11 @@ mod tests { "foo.java", JavaParser, wmc, - [(wmc, 2.0)] // 1 top level class + [ + (class_wmc_sum, 2.0), // 1 class + (interface_wmc_sum, 2.0), // 1 interface + (total_wmc, 4.0) + ] ); } } diff --git a/src/output/dump_metrics.rs b/src/output/dump_metrics.rs index ab3b42986..4268e5d36 100644 --- a/src/output/dump_metrics.rs +++ b/src/output/dump_metrics.rs @@ -339,16 +339,24 @@ fn dump_wmc( return Ok(()); } - let pref = if last { "`- " } else { "|- " }; + let (pref_child, pref) = if last { (" ", "`- ") } else { ("| ", "|- ") }; color!(stdout, Blue); write!(stdout, "{}{}", prefix, pref)?; color!(stdout, Green, true); - write!(stdout, "wmc: ")?; + writeln!(stdout, "wmc")?; - color!(stdout, White); - writeln!(stdout, "{}", stats.wmc()) + let prefix = format!("{}{}", prefix, pref_child); + dump_value("classes", stats.class_wmc_sum(), &prefix, false, stdout)?; + dump_value( + "interfaces", + stats.interface_wmc_sum(), + &prefix, + false, + stdout, + )?; + dump_value("total", stats.total_wmc(), &prefix, true, stdout) } fn dump_npm( diff --git a/src/spaces.rs b/src/spaces.rs index 459a6d391..4f98190bd 100644 --- a/src/spaces.rs +++ b/src/spaces.rs @@ -222,6 +222,7 @@ fn compute_minmax(state: &mut State) { #[inline(always)] fn compute_sum(state: &mut State) { + state.space.metrics.wmc.compute_sum(); state.space.metrics.npm.compute_sum(); state.space.metrics.npa.compute_sum(); } From c0a16cc6bb12a2b33867ec1d8fa78ffccb51dddd Mon Sep 17 00:00:00 2001 From: Marco Ballario Date: Tue, 27 Sep 2022 22:54:26 +0200 Subject: [PATCH 2/3] Rename WMC Cyclomatic Complexity field --- src/metrics/wmc.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/metrics/wmc.rs b/src/metrics/wmc.rs index 2b9b60909..2193df446 100644 --- a/src/metrics/wmc.rs +++ b/src/metrics/wmc.rs @@ -19,7 +19,7 @@ use crate::*; /// #[derive(Debug, Clone, Default)] pub struct Stats { - cc: f64, + cyclomatic: f64, class_wmc: f64, interface_wmc: f64, class_wmc_sum: f64, @@ -61,8 +61,8 @@ impl Stats { // into the `Wmc` metric value of a class or interface if let Function = other.space_kind { match self.space_kind { - Class => self.class_wmc += other.cc, - Interface => self.interface_wmc += other.cc, + Class => self.class_wmc += other.cyclomatic, + Interface => self.interface_wmc += other.cyclomatic, _ => {} } } @@ -142,7 +142,7 @@ impl Wmc for JavaCode { Function => { stats.space_kind = space_kind; // Saves the cyclomatic complexity of the method - stats.cc = cyclomatic.cyclomatic_sum(); + stats.cyclomatic = cyclomatic.cyclomatic_sum(); } Class | Interface | Unit => { stats.space_kind = space_kind; From 03f64d14cbaa5ea54aab7fff68d25bc235286ed0 Mon Sep 17 00:00:00 2001 From: Marco Ballario Date: Wed, 28 Sep 2022 16:23:42 +0200 Subject: [PATCH 3/3] Update WMC space kind field at most once --- src/metrics/wmc.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/metrics/wmc.rs b/src/metrics/wmc.rs index 2193df446..c5d7fb793 100644 --- a/src/metrics/wmc.rs +++ b/src/metrics/wmc.rs @@ -138,16 +138,14 @@ impl Wmc for JavaCode { fn compute(space_kind: SpaceKind, cyclomatic: &cyclomatic::Stats, stats: &mut Stats) { use SpaceKind::*; - match space_kind { - Function => { + if let Unit | Class | Interface | Function = space_kind { + if stats.space_kind == Unknown { stats.space_kind = space_kind; + } + if space_kind == Function { // Saves the cyclomatic complexity of the method stats.cyclomatic = cyclomatic.cyclomatic_sum(); } - Class | Interface | Unit => { - stats.space_kind = space_kind; - } - _ => {} } } }