diff --git a/rust-code-analysis-web/src/web/server.rs b/rust-code-analysis-web/src/web/server.rs index 8ab5a1fe7..dc5a3184d 100644 --- a/rust-code-analysis-web/src/web/server.rs +++ b/rust-code-analysis-web/src/web/server.rs @@ -632,7 +632,7 @@ mod tests { "start_line": 1, "end_line": 4, "metrics": {"cyclomatic": {"sum": 2.0, "average": 1.0, "min":1.0, "max":1.0}, - "cognitive": {"sum": 0.0, "average": 0.0}, + "cognitive": {"sum": 0.0, "average": 0.0, "min":0.0, "max":0.0}, "nargs": {"total_functions": 0.0, "average_functions": 0.0, "total_closures": 0.0, "average_closures": 0.0, "total": 0.0, "average": 0.0}, "nexits": {"sum": 0.0, "average": 0.0,"min":0.0,"max":0.0}, "halstead": {"bugs": 0.000_942_552_557_372_941_4, @@ -659,7 +659,7 @@ mod tests { "start_line": 3, "end_line": 4, "metrics": {"cyclomatic": {"sum": 1.0, "average": 1.0, "min":1.0, "max":1.0}, - "cognitive": {"sum": 0.0, "average": 0.0}, + "cognitive": {"sum": 0.0, "average": 0.0 , "min":0.0, "max":0.0}, "nargs": {"total_functions": 0.0, "average_functions": 0.0, "total_closures": 0.0, "average_closures": 0.0, "total": 0.0, "average": 0.0}, "nexits": {"sum": 0.0, "average": 0.0,"min":0.0,"max":0.0}, "halstead": {"bugs": 0.000_942_552_557_372_941_4, @@ -712,7 +712,7 @@ mod tests { "start_line": 1, "end_line": 2, "metrics": {"cyclomatic": {"sum": 2.0, "average": 1.0, "min":1.0, "max":1.0}, - "cognitive": {"sum": 0.0, "average": 0.0}, + "cognitive": {"sum": 0.0, "average": 0.0 , "min":0.0, "max":0.0}, "nargs": {"total_functions": 0.0, "average_functions": 0.0, "total_closures": 0.0, "average_closures": 0.0, "total": 0.0, "average": 0.0}, "nexits": {"sum": 0.0, "average": 0.0,"min":0.0,"max":0.0}, "halstead": {"bugs": 0.000_942_552_557_372_941_4, @@ -761,7 +761,7 @@ mod tests { "start_line": 1, "end_line": 2, "metrics": {"cyclomatic": {"sum": 2.0, "average": 1.0, "min": 1.0,"max": 1.0}, - "cognitive": {"sum": 0.0, "average": 0.0}, + "cognitive": {"sum": 0.0, "average": 0.0 , "min":0.0, "max":0.0}, "nargs": {"total_functions": 0.0, "average_functions": 0.0, "total_closures": 0.0, "average_closures": 0.0, "total": 0.0, "average": 0.0}, "nexits": {"sum": 0.0, "average": 0.0,"min":0.0,"max":0.0}, "halstead": {"bugs": 0.000_942_552_557_372_941_4, @@ -788,7 +788,7 @@ mod tests { "start_line": 1, "end_line": 2, "metrics": {"cyclomatic": {"sum": 1.0, "average": 1.0, "min": 1.0,"max": 1.0}, - "cognitive": {"sum": 0.0, "average": 0.0}, + "cognitive": {"sum": 0.0, "average": 0.0 , "min":0.0, "max":0.0}, "nargs": {"total_functions": 0.0, "average_functions": 0.0, "total_closures": 0.0, "average_closures": 0.0, "total": 0.0, "average": 0.0}, "nexits": {"sum": 0.0, "average": 0.0,"min":0.0,"max":0.0}, "halstead": {"bugs": 0.000_942_552_557_372_941_4, diff --git a/src/metrics/cognitive.rs b/src/metrics/cognitive.rs index 0e7a20f34..0c80b46d0 100644 --- a/src/metrics/cognitive.rs +++ b/src/metrics/cognitive.rs @@ -18,6 +18,9 @@ use crate::*; #[derive(Debug, Clone)] pub struct Stats { structural: usize, + structural_sum: usize, + structural_min: usize, + structural_max: usize, nesting: usize, total_space_functions: usize, boolean_seq: BoolSequence, @@ -27,6 +30,9 @@ impl Default for Stats { fn default() -> Self { Self { structural: 0, + structural_sum: 0, + structural_min: usize::MAX, + structural_max: 0, nesting: 0, total_space_functions: 1, boolean_seq: BoolSequence::default(), @@ -39,9 +45,11 @@ impl Serialize for Stats { where S: Serializer, { - let mut st = serializer.serialize_struct("cognitive", 2)?; - st.serialize_field("sum", &self.cognitive())?; + let mut st = serializer.serialize_struct("cognitive", 4)?; + st.serialize_field("sum", &self.cognitive_sum())?; st.serialize_field("average", &self.cognitive_average())?; + st.serialize_field("min", &self.cognitive_min())?; + st.serialize_field("max", &self.cognitive_max())?; st.end() } } @@ -50,9 +58,11 @@ impl fmt::Display for Stats { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "sum: {}, average: {}", + "sum: {}, average: {}, min:{}, max: {}", self.cognitive(), - self.cognitive_average() + self.cognitive_average(), + self.cognitive_min(), + self.cognitive_max() ) } } @@ -60,13 +70,28 @@ impl fmt::Display for Stats { impl Stats { /// Merges a second `Cognitive Complexity` metric into the first one pub fn merge(&mut self, other: &Stats) { - self.structural += other.structural; + self.structural_min = self.structural_min.min(other.structural_min); + self.structural_max = self.structural_max.max(other.structural_max); + self.structural_sum += other.structural_sum; } /// Returns the `Cognitive Complexity` metric value pub fn cognitive(&self) -> f64 { self.structural as f64 } + /// Returns the `Cognitive Complexity` sum metric value + pub fn cognitive_sum(&self) -> f64 { + self.structural_sum as f64 + } + + /// Returns the `Cognitive Complexity` minimum metric value + pub fn cognitive_min(&self) -> f64 { + self.structural_min as f64 + } + /// Returns the `Cognitive Complexity` maximum metric value + pub fn cognitive_max(&self) -> f64 { + self.structural_max as f64 + } /// Returns the `Cognitive Complexity` metric average value /// @@ -75,7 +100,12 @@ impl Stats { /// /// If there are no functions in a code, its value is `NAN`. pub fn cognitive_average(&self) -> f64 { - self.cognitive() / self.total_space_functions as f64 + self.cognitive_sum() / self.total_space_functions as f64 + } + pub fn compute_minmax(&mut self) { + self.structural_min = self.structural_min.min(self.structural); + self.structural_max = self.structural_max.max(self.structural); + self.structural_sum += self.structural; } pub(crate) fn finalize(&mut self, total_space_functions: usize) { @@ -427,7 +457,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 0, usize)], + [ + (cognitive_sum, 0, usize), + (cognitive_min, 0, usize), + (cognitive_max, 0, usize) + ], [(cognitive_average, f64::NAN)] ); } @@ -439,7 +473,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 0, usize)], + [ + (cognitive_sum, 0, usize), + (cognitive_min, 0, usize), + (cognitive_max, 0, usize) + ], [(cognitive_average, f64::NAN)] ); } @@ -451,7 +489,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 0, usize)], + [ + (cognitive_sum, 0, usize), + (cognitive_min, 0, usize), + (cognitive_max, 0, usize) + ], [(cognitive_average, f64::NAN)] ); } @@ -463,7 +505,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 0, usize)], + [ + (cognitive_sum, 0, usize), + (cognitive_min, 0, usize), + (cognitive_max, 0, usize) + ], [(cognitive_average, f64::NAN)] ); } @@ -479,7 +525,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -494,7 +544,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 1, usize)], + [ + (cognitive_sum, 1, usize), + (cognitive_min, 0, usize), + (cognitive_max, 1, usize) + ], [(cognitive_average, 1.0)] ); } @@ -509,7 +563,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); } @@ -527,7 +585,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -547,7 +609,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 6, usize)], + [ + (cognitive_sum, 6, usize), + (cognitive_min, 0, usize), + (cognitive_max, 6, usize) + ], [(cognitive_average, 6.0)] ); } @@ -566,7 +632,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -585,7 +655,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -604,7 +678,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -618,7 +696,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); } @@ -634,7 +716,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); @@ -647,7 +733,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); } @@ -663,7 +753,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); @@ -676,7 +770,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); } @@ -692,7 +790,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); @@ -705,7 +807,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); } @@ -721,7 +827,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 2, usize)], + [ + (cognitive_sum, 2, usize), + (cognitive_min, 0, usize), + (cognitive_max, 2, usize) + ], [(cognitive_average, 2.0)] ); @@ -734,7 +844,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); @@ -747,7 +861,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -763,7 +881,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); @@ -776,7 +898,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -792,7 +918,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); @@ -805,7 +935,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -819,7 +953,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -835,7 +973,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -851,7 +993,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -867,7 +1013,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -884,7 +1034,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -899,7 +1053,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -925,7 +1083,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 11, usize)], + [ + (cognitive_sum, 11, usize), + (cognitive_min, 0, usize), + (cognitive_max, 11, usize) + ], [(cognitive_average, 11.0)] ); @@ -941,7 +1103,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -967,7 +1133,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 11, usize)], + [ + (cognitive_sum, 11, usize), + (cognitive_min, 0, usize), + (cognitive_max, 11, usize) + ], [(cognitive_average, 11.0)] ); } @@ -993,7 +1163,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 11, usize)], + [ + (cognitive_sum, 11, usize), + (cognitive_min, 0, usize), + (cognitive_max, 11, usize) + ], [(cognitive_average, 11.0)] ); } @@ -1009,7 +1183,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 6, usize)], + [ + (cognitive_sum, 6, usize), + (cognitive_min, 0, usize), + (cognitive_max, 6, usize) + ], [(cognitive_average, 6.0)] ); } @@ -1030,7 +1208,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 6, usize)], + [ + (cognitive_sum, 6, usize), + (cognitive_min, 0, usize), + (cognitive_max, 6, usize) + ], [(cognitive_average, 6.0)] ); } @@ -1048,7 +1230,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -1072,7 +1258,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -1099,7 +1289,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 11, usize)], + [ + (cognitive_sum, 11, usize), + (cognitive_min, 0, usize), + (cognitive_max, 11, usize) + ], [(cognitive_average, 11.0)] ); } @@ -1119,7 +1313,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 7, usize)], + [ + (cognitive_sum, 7, usize), + (cognitive_min, 0, usize), + (cognitive_max, 7, usize) + ], [(cognitive_average, 7.0)] ); } @@ -1146,7 +1344,11 @@ mod tests { "foo.c", CppParser, cognitive, - [(cognitive, 1, usize)], + [ + (cognitive_sum, 1, usize), + (cognitive_min, 0, usize), + (cognitive_max, 1, usize) + ], [(cognitive_average, 1.0)] ); } @@ -1173,7 +1375,11 @@ mod tests { "foo.js", MozjsParser, cognitive, - [(cognitive, 1, usize)], + [ + (cognitive_sum, 1, usize), + (cognitive_min, 0, usize), + (cognitive_max, 1, usize) + ], [(cognitive_average, 1.0)] ); } @@ -1188,7 +1394,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } @@ -1206,7 +1416,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 5, usize)], + [ + (cognitive_sum, 5, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 1.25)] // 2 functions + 2 lamdas = 4 ); } @@ -1231,7 +1445,11 @@ mod tests { "foo.py", PythonParser, cognitive, - [(cognitive, 9, usize)], + [ + (cognitive_sum, 9, usize), + (cognitive_min, 0, usize), + (cognitive_max, 9, usize) + ], [(cognitive_average, 9.0)] ); } @@ -1252,7 +1470,11 @@ mod tests { "foo.rs", RustParser, cognitive, - [(cognitive, 3, usize)], + [ + (cognitive_sum, 3, usize), + (cognitive_min, 0, usize), + (cognitive_max, 3, usize) + ], [(cognitive_average, 3.0)] ); } @@ -1275,7 +1497,11 @@ mod tests { "foo.ts", TypescriptParser, cognitive, - [(cognitive, 4, usize)], + [ + (cognitive_sum, 4, usize), + (cognitive_min, 0, usize), + (cognitive_max, 4, usize) + ], [(cognitive_average, 4.0)] ); } diff --git a/src/spaces.rs b/src/spaces.rs index 162489bc6..d47cf0737 100644 --- a/src/spaces.rs +++ b/src/spaces.rs @@ -199,6 +199,7 @@ fn compute_averages(state: &mut State) { fn compute_minmax(state: &mut State) { state.space.metrics.cyclomatic.compute_minmax(); state.space.metrics.nexits.compute_minmax(); + state.space.metrics.cognitive.compute_minmax(); } fn finalize(state_stack: &mut Vec, diff_level: usize) {