diff --git a/rust-code-analysis-web/src/web/server.rs b/rust-code-analysis-web/src/web/server.rs index d5d90617b..ba902501e 100644 --- a/rust-code-analysis-web/src/web/server.rs +++ b/rust-code-analysis-web/src/web/server.rs @@ -650,7 +650,7 @@ mod tests { "n1": 2.0, "volume": 4.754_887_502_163_468}, "loc": {"cloc": 1.0, "ploc": 2.0, "lloc": 1.0, "sloc": 4.0, "blank": 1.0}, - "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0}, + "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0, "closures_min": 0.0, "closures_max": 0.0, "functions_min": 0.0, "functions_max": 1.0}, "mi": {"mi_original": 139.974_331_558_152_1, "mi_sei": 161.414_455_240_662_22, "mi_visual_studio": 81.856_334_244_533_39}}, @@ -677,7 +677,7 @@ mod tests { "n1": 2.0, "volume": 4.754_887_502_163_468}, "loc": {"cloc": 0.0, "ploc": 2.0, "lloc": 1.0, "sloc": 2.0, "blank": 0.0}, - "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0}, + "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0, "closures_min": 0.0, "closures_max": 0.0, "functions_min": 1.0, "functions_max": 1.0}, "mi": {"mi_original": 151.433_315_883_223_23, "mi_sei": 142.873_061_717_489_78, "mi_visual_studio": 88.557_494_668_551_6}}, @@ -730,7 +730,7 @@ mod tests { "n1": 2.0, "volume": 4.754_887_502_163_468}, "loc": {"cloc": 0.0, "ploc": 2.0, "lloc": 1.0, "sloc": 2.0, "blank": 0.0}, - "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0}, + "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0, "closures_min": 0.0, "closures_max": 0.0, "functions_min": 0.0, "functions_max": 1.0}, "mi": {"mi_original": 151.203_315_883_223_2, "mi_sei": 142.643_061_717_489_76, "mi_visual_studio": 88.422_991_744_574_97}}, @@ -779,7 +779,7 @@ mod tests { "n1": 2.0, "volume": 4.754_887_502_163_468}, "loc": {"cloc": 0.0, "ploc": 2.0, "lloc": 1.0, "sloc": 2.0, "blank": 0.0}, - "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0}, + "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0, "closures_min": 0.0, "closures_max": 0.0, "functions_min": 0.0, "functions_max": 1.0}, "mi": {"mi_original": 151.203_315_883_223_2, "mi_sei": 142.643_061_717_489_76, "mi_visual_studio": 88.422_991_744_574_97}}, @@ -806,7 +806,7 @@ mod tests { "n1": 2.0, "volume": 4.754_887_502_163_468}, "loc": {"cloc": 0.0, "ploc": 2.0, "lloc": 1.0, "sloc": 2.0, "blank": 0.0}, - "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0}, + "nom": {"functions": 1.0, "closures": 0.0, "total": 1.0, "closures_min": 0.0, "closures_max": 0.0, "functions_min": 1.0, "functions_max": 1.0}, "mi": {"mi_original": 151.433_315_883_223_23, "mi_sei": 142.873_061_717_489_78, "mi_visual_studio": 88.557_494_668_551_6}}, diff --git a/src/metrics/nom.rs b/src/metrics/nom.rs index 13eb0a2fe..7ee3628eb 100644 --- a/src/metrics/nom.rs +++ b/src/metrics/nom.rs @@ -7,21 +7,44 @@ use crate::checker::Checker; use crate::*; /// The `Nom` metric suite. -#[derive(Default, Clone, Debug)] +#[derive(Clone, Debug)] pub struct Stats { functions: usize, closures: usize, + functions_sum: usize, + closures_sum: usize, + functions_min: usize, + functions_max: usize, + closures_min: usize, + closures_max: usize, +} +impl Default for Stats { + fn default() -> Self { + Self { + functions: 0, + closures: 0, + functions_sum: 0, + closures_sum: 0, + functions_min: usize::MAX, + functions_max: 0, + closures_min: usize::MAX, + closures_max: 0, + } + } } - impl Serialize for Stats { fn serialize(&self, serializer: S) -> Result where S: Serializer, { - let mut st = serializer.serialize_struct("nom", 3)?; - st.serialize_field("functions", &self.functions())?; - st.serialize_field("closures", &self.closures())?; + let mut st = serializer.serialize_struct("nom", 7)?; + st.serialize_field("functions", &self.functions_sum())?; + st.serialize_field("closures", &self.closures_sum())?; st.serialize_field("total", &self.total())?; + st.serialize_field("functions_min", &self.functions_min())?; + st.serialize_field("functions_max", &self.functions_max())?; + st.serialize_field("closures_min", &self.closures_min())?; + st.serialize_field("closures_max", &self.closures_max())?; st.end() } } @@ -32,10 +55,18 @@ impl fmt::Display for Stats { f, "functions: {}, \ closures: {}, \ - total: {}", - self.functions(), - self.closures(), + total: {} \ + functions_min: {} \ + functions_max: {} \ + closures_min: {} \ + closures_max: {}", + self.functions_sum(), + self.closures_sum(), self.total(), + self.functions_min(), + self.functions_max(), + self.closures_min(), + self.closures_max(), ) } } @@ -43,8 +74,12 @@ impl fmt::Display for Stats { impl Stats { /// Merges a second `Nom` metric suite into the first one pub fn merge(&mut self, other: &Stats) { - self.functions += other.functions; - self.closures += other.closures; + self.functions_min = self.functions_min.min(other.functions_min); + self.functions_max = self.functions_max.max(other.functions_max); + self.closures_min = self.closures_min.min(other.closures_min); + self.closures_max = self.closures_max.max(other.closures_max); + self.functions_sum += other.functions_sum; + self.closures_sum += other.closures_sum; } /// Counts the number of function definitions in a scope @@ -60,11 +95,56 @@ impl Stats { self.closures as f64 } + /// Return the sum metric for functions + #[inline(always)] + pub fn functions_sum(&self) -> f64 { + // Only function definitions are considered, not general declarations + self.functions_sum as f64 + } + + /// Return the sum metric for closures + #[inline(always)] + pub fn closures_sum(&self) -> f64 { + self.closures_sum as f64 + } + + /// Counts the number of function definitions in a scope + #[inline(always)] + pub fn functions_min(&self) -> f64 { + // Only function definitions are considered, not general declarations + self.functions_min as f64 + } + + /// Counts the number of closures in a scope + #[inline(always)] + pub fn closures_min(&self) -> f64 { + self.closures_min as f64 + } + /// Counts the number of function definitions in a scope + #[inline(always)] + pub fn functions_max(&self) -> f64 { + // Only function definitions are considered, not general declarations + self.functions_max as f64 + } + + /// Counts the number of closures in a scope + #[inline(always)] + pub fn closures_max(&self) -> f64 { + self.closures_max as f64 + } /// Returns the total number of function definitions and /// closures in a scope #[inline(always)] pub fn total(&self) -> f64 { - self.functions() + self.closures() + self.functions_sum() + self.closures_sum() + } + pub fn compute_minmax(&mut self) { + self.functions_min = self.functions_min.min(self.functions); + self.functions_max = self.functions_max.max(self.functions); + self.closures_min = self.closures_min.min(self.closures); + self.closures_max = self.closures_max.max(self.closures); + self.functions_sum += self.functions; + self.closures_sum += self.closures; } } @@ -115,9 +195,13 @@ mod tests { PythonParser, nom, [ - (functions, 3, usize), - (closures, 1, usize), - (total, 4, usize) + (functions_sum, 3, usize), + (closures_sum, 1, usize), + (total, 4, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 1, usize), ] ); } @@ -132,9 +216,13 @@ mod tests { RustParser, nom, [ - (functions, 2, usize), - (closures, 1, usize), - (total, 3, usize) + (functions_sum, 2, usize), + (closures_sum, 1, usize), + (total, 3, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 1, usize), ] ); } @@ -151,9 +239,13 @@ mod tests { CppParser, nom, [ - (functions, 1, usize), - (closures, 0, usize), - (total, 1, usize) + (functions_sum, 1, usize), + (closures_sum, 0, usize), + (total, 1, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 0, usize), ] ); } @@ -170,9 +262,13 @@ mod tests { CppParser, nom, [ - (functions, 2, usize), - (closures, 1, usize), - (total, 3, usize) + (functions_sum, 2, usize), + (closures_sum, 1, usize), + (total, 3, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 1, usize), ] ); } @@ -197,9 +293,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 3, usize), // f, foo, bar - (closures, 1, usize), // return function () - (total, 4, usize) + (functions_sum, 3, usize), // f, foo, bar + (closures_sum, 1, usize), // return function () + (total, 4, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 1, usize), ] ); } @@ -214,9 +314,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 1, usize), // test_safe_mode - (closures, 0, usize), - (total, 1, usize) + (functions_sum, 1, usize), // test_safe_mode + (closures_sum, 0, usize), + (total, 1, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 0, usize), ] ); } @@ -229,9 +333,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 1, usize), - (closures, 0, usize), - (total, 1, usize) + (functions_sum, 1, usize), + (closures_sum, 0, usize), + (total, 1, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 0, usize), ] ); } @@ -246,9 +354,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 1, usize), - (closures, 0, usize), - (total, 1, usize) + (functions_sum, 1, usize), + (closures_sum, 0, usize), + (total, 1, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 0, usize), ] ); } @@ -263,9 +375,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 1, usize), - (closures, 0, usize), - (total, 1, usize) + (functions_sum, 1, usize), + (closures_sum, 0, usize), + (total, 1, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 0, usize), ] ); } @@ -282,9 +398,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 1, usize), - (closures, 0, usize), - (total, 1, usize) + (functions_sum, 1, usize), + (closures_sum, 0, usize), + (total, 1, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 0, usize), ] ); } @@ -301,9 +421,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 0, usize), - (closures, 2, usize), - (total, 2, usize) + (functions_sum, 0, usize), + (closures_sum, 2, usize), + (total, 2, usize), + (functions_max, 0, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 1, usize), ] ); } @@ -318,9 +442,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 1, usize), // add - (closures, 1, usize), // materials.map - (total, 2, usize) + (functions_sum, 1, usize), // add + (closures_sum, 1, usize), // materials.map + (total, 2, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 1, usize), ] ); } @@ -333,9 +461,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 1, usize), - (closures, 0, usize), - (total, 1, usize) + (functions_sum, 1, usize), + (closures_sum, 0, usize), + (total, 1, usize), + (functions_max, 1, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 0, usize), ] ); } @@ -348,9 +480,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 0, usize), - (closures, 1, usize), - (total, 1, usize) + (functions_sum, 0, usize), + (closures_sum, 1, usize), + (total, 1, usize), + (functions_max, 0, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 1, usize), ] ); } @@ -365,9 +501,13 @@ mod tests { JavascriptParser, nom, [ - (functions, 0, usize), - (closures, 1, usize), - (total, 1, usize) + (functions_sum, 0, usize), + (closures_sum, 1, usize), + (total, 1, usize), + (functions_max, 0, usize), + (functions_min, 0, usize), + (closures_min, 0, usize), + (closures_max, 1, usize), ] ); } diff --git a/src/spaces.rs b/src/spaces.rs index b6327cda5..cb41dbca2 100644 --- a/src/spaces.rs +++ b/src/spaces.rs @@ -181,8 +181,8 @@ fn compute_halstead_and_mi(state: &mut State) { #[inline(always)] fn compute_averages(state: &mut State) { - let nom_functions = state.space.metrics.nom.functions() as usize; - let nom_closures = state.space.metrics.nom.closures() as usize; + let nom_functions = state.space.metrics.nom.functions_sum() as usize; + let nom_closures = state.space.metrics.nom.closures_sum() as usize; let nom_total = state.space.metrics.nom.total() as usize; // Cognitive average state.space.metrics.cognitive.finalize(nom_total); @@ -201,6 +201,7 @@ fn compute_minmax(state: &mut State) { state.space.metrics.nexits.compute_minmax(); state.space.metrics.cognitive.compute_minmax(); state.space.metrics.nargs.compute_minmax(); + state.space.metrics.nom.compute_minmax(); } fn finalize(state_stack: &mut Vec, diff_level: usize) {