Metastatic.Analysis.Complexity.Cognitive
(Metastatic v0.10.4)
View Source
Cognitive complexity calculation.
Cognitive complexity measures how difficult code is to understand, taking into account nested structures that increase the mental burden on readers.
3-Tuple Format
All MetaAST nodes use the uniform 3-tuple structure:
{type_atom, keyword_meta, children_or_value}
Algorithm
Based on the Sonar cognitive complexity specification:
Base Increments: Structural elements add to complexity
conditional- +1 (+nesting level)loop- +1 (+nesting level)binary_opwith:booleanand:and/:or- +1pattern_match- +1 (+nesting level per branch)exception_handling- +1 (+nesting level)
Nesting Penalty: Each level of nesting adds to the increment
- Conditional at level 0: +1
- Conditional at level 1: +2
- Conditional at level 2: +3
Difference from Cyclomatic
Cognitive complexity differs from cyclomatic in that it:
- Applies nesting penalties (deeper = more complex)
- Doesn't count boolean operators in conditions the same way
- Emphasizes understandability over testability
Examples
# Simple conditional: cognitive = 1
iex> ast = {:conditional, [], [{:variable, [], "x"}, {:literal, [subtype: :integer], 1}, {:literal, [subtype: :integer], 2}]}
iex> Metastatic.Analysis.Complexity.Cognitive.calculate(ast)
1
# Nested conditional: cognitive = 3 (1 + 2)
iex> ast = {:conditional, [], [
...> {:variable, [], "x"},
...> {:conditional, [], [{:variable, [], "y"}, {:literal, [subtype: :integer], 1}, {:literal, [subtype: :integer], 2}]},
...> {:literal, [subtype: :integer], 3}]}
iex> Metastatic.Analysis.Complexity.Cognitive.calculate(ast)
3
Summary
Functions
Calculates cognitive complexity for a MetaAST node.
Functions
@spec calculate(Metastatic.AST.meta_ast()) :: non_neg_integer()
Calculates cognitive complexity for a MetaAST node.
Returns the complexity as a non-negative integer (minimum 0).
Examples
iex> ast = {:literal, [subtype: :integer], 42}
iex> Metastatic.Analysis.Complexity.Cognitive.calculate(ast)
0
iex> ast = {:conditional, [], [
...> {:variable, [], "x"},
...> {:literal, [subtype: :integer], 1},
...> {:literal, [subtype: :integer], 2}]}
iex> Metastatic.Analysis.Complexity.Cognitive.calculate(ast)
1