Metastatic.Analysis.Complexity
(Metastatic v0.10.4)
View Source
Code complexity analysis at the MetaAST level.
Analyzes code to compute comprehensive complexity metrics that work uniformly across all supported languages by operating on the unified MetaAST representation.
Metrics
- Cyclomatic Complexity - McCabe metric, decision points + 1
- Cognitive Complexity - Structural complexity with nesting penalties
- Nesting Depth - Maximum nesting level
- Halstead Metrics - Volume, difficulty, effort
- Lines of Code - Physical, logical, comments
- Function Metrics - Statements, returns, variables
Usage
alias Metastatic.{Document, Analysis.Complexity}
# Analyze a document
ast = {:conditional, [], [
{:variable, [], "x"},
{:literal, [subtype: :integer], 1},
{:literal, [subtype: :integer], 2}]}
doc = Document.new(ast, :python)
{:ok, result} = Complexity.analyze(doc)
result.cyclomatic # => 2
result.cognitive # => 1
result.max_nesting # => 1
result.warnings # => []
result.summary # => "Code has low complexity"Options
:thresholds- Configurable threshold map (seeMetastatic.Analysis.Complexity.Result):metrics- List of metrics to calculate (default: all)
Examples
# Simple arithmetic: complexity = 1
iex> ast = {:binary_op, [category: :arithmetic, operator: :+], [{:literal, [subtype: :integer], 1}, {:literal, [subtype: :integer], 2}]}
iex> doc = Metastatic.Document.new(ast, :python)
iex> {:ok, result} = Metastatic.Analysis.Complexity.analyze(doc)
iex> result.cyclomatic
1
# Conditional: complexity = 2
iex> ast = {:conditional, [], [
...> {:variable, [], "x"},
...> {:literal, [subtype: :integer], 1},
...> {:literal, [subtype: :integer], 2}]}
iex> doc = Metastatic.Document.new(ast, :elixir)
iex> {:ok, result} = Metastatic.Analysis.Complexity.analyze(doc)
iex> result.cyclomatic
2
Summary
Functions
@spec analyze(Metastatic.language(), term(), keyword()) :: {:ok, map()} | {:error, term()}
Analyzes a document for complexity.
Accepts either:
- A
Metastatic.Documentstruct - A
{language, native_ast}tuple
Returns {:ok, result} where result is a Metastatic.Analysis.Complexity.Result struct.
Options
:thresholds- Threshold map for warnings (default thresholds used if not provided):metrics- List of metrics to calculate (default::all)
Examples
# Using Document
iex> ast = {:literal, [subtype: :integer], 42}
iex> doc = Metastatic.Document.new(ast, :python)
iex> {:ok, result} = Metastatic.Analysis.Complexity.analyze(doc)
iex> result.cyclomatic
1
iex> result.cognitive
0
# Using {language, native_ast} tuple
iex> python_ast = %{"_type" => "Constant", "value" => 42}
iex> {:ok, result} = Metastatic.Analysis.Complexity.analyze(:python, python_ast, [])
iex> result.cyclomatic
1
@spec analyze!(Metastatic.language(), term(), keyword()) :: map()
Analyzes a document for complexity.
Accepts either:
- A
Metastatic.Documentstruct - A
{language, native_ast}tuple
Returns {:ok, result} where result is a Metastatic.Analysis.Complexity.Result struct.
Options
:thresholds- Threshold map for warnings (default thresholds used if not provided):metrics- List of metrics to calculate (default::all)
Examples
# Using Document
iex> ast = {:literal, [subtype: :integer], 42}
iex> doc = Metastatic.Document.new(ast, :python)
iex> {:ok, result} = Metastatic.Analysis.Complexity.analyze(doc)
iex> result.cyclomatic
1
iex> result.cognitive
0
# Using {language, native_ast} tuple
iex> python_ast = %{"_type" => "Constant", "value" => 42}
iex> {:ok, result} = Metastatic.Analysis.Complexity.analyze(:python, python_ast, [])
iex> result.cyclomatic
1Unlike not-banged version, this one either returns a result or raises