Metastatic.Analysis.Complexity.Cyclomatic (Metastatic v0.10.4)

View Source

Cyclomatic complexity calculation (McCabe metric).

Cyclomatic complexity measures the number of linearly independent paths through a program's source code. It is calculated as the number of decision points plus one.

3-Tuple Format

All MetaAST nodes use the uniform 3-tuple structure: {type_atom, keyword_meta, children_or_value}

Decision Points

  • conditional - if/else statements (+1)
  • loop - while/for loops (+1)
  • binary_op with :boolean and :or/:and operators (+1 each)
  • exception_handling - try/catch blocks (+1 per catch clause)
  • pattern_match - case statements (+1 per branch)

Thresholds

  • 1-10: Simple, low risk
  • 11-20: More complex, moderate risk
  • 21-50: Complex, high risk
  • 51+: Untestable, very high risk

Examples

# Simple sequence: complexity = 1
iex> ast = {:literal, [subtype: :integer], 42}
iex> Metastatic.Analysis.Complexity.Cyclomatic.calculate(ast)
1

# Single conditional: complexity = 2
iex> ast = {:conditional, [], [{:variable, [], "x"}, {:literal, [subtype: :integer], 1}, {:literal, [subtype: :integer], 2}]}
iex> Metastatic.Analysis.Complexity.Cyclomatic.calculate(ast)
2

# Conditional with loop: complexity = 3
iex> ast = {:conditional, [], [
...>   {:variable, [], "x"},
...>   {:loop, [loop_type: :while], [{:variable, [], "y"}, {:literal, [subtype: :integer], 1}]},
...>   {:literal, [subtype: :integer], 2}]}
iex> Metastatic.Analysis.Complexity.Cyclomatic.calculate(ast)
3

Summary

Functions

Calculates cyclomatic complexity for a MetaAST node.

Functions

calculate(ast)

@spec calculate(Metastatic.AST.meta_ast()) :: non_neg_integer()

Calculates cyclomatic complexity for a MetaAST node.

Returns the complexity as a non-negative integer (minimum 1).

Examples

iex> ast = {:binary_op, [category: :arithmetic, operator: :+], [{:variable, [], "x"}, {:literal, [subtype: :integer], 5}]}
iex> Metastatic.Analysis.Complexity.Cyclomatic.calculate(ast)
1

iex> ast = {:conditional, [], [
...>   {:variable, [], "condition"},
...>   {:literal, [subtype: :integer], 1},
...>   {:literal, [subtype: :integer], 2}]}
iex> Metastatic.Analysis.Complexity.Cyclomatic.calculate(ast)
2