Static code analysis with AST parsing, complexity metrics, dependency graphs, and quality scoring
Scanned 2/12/2026
Install via CLI
openskills install gitwalter/cursor-agent-factory---
name: code-analysis
description: Static code analysis with AST parsing, complexity metrics, dependency graphs, and quality scoring
type: skill
agents: [documentation-agent, code-reviewer]
templates: []
patterns: []
knowledge: [best-practices.json, design-patterns.json, review-checklist.json]
---
# Code Analysis Skill
Performs static analysis using AST parsing, computes complexity metrics (cyclomatic, maintainability), maps dependencies, and produces quality scores.
## When to Use
- During code review
- Before merging PRs
- When assessing technical debt
- When generating quality reports
- When identifying refactoring targets
## Prerequisites
```bash
pip install radon pylint
# ast is stdlib
```
## Process
### Step 1: AST Parsing
Parse source into AST and extract structure:
```python
import ast
from pathlib import Path
from typing import Any
def parse_file(filepath: str) -> ast.AST:
"""Parse Python file to AST.
Args:
filepath: Path to source file.
Returns:
Parsed AST.
"""
with open(filepath) as f:
return ast.parse(f.read())
def extract_functions(tree: ast.AST) -> list[dict[str, Any]]:
"""Extract function and method definitions."""
result = []
for node in ast.walk(tree):
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
result.append({"name": node.name, "lineno": node.lineno})
return result
```
### Step 2: Complexity Calculation
Compute cyclomatic complexity and maintainability index:
```python
from radon.complexity import cc_visit
from radon.metrics import mi_visit
def compute_complexity(filepath: str) -> dict[str, Any]:
"""Compute cyclomatic complexity and maintainability index.
Args:
filepath: Path to Python file.
Returns:
Dict with cc_results and mi_score.
"""
with open(filepath) as f:
content = f.read()
cc_results = cc_visit(content)
mi_score = mi_visit(content, True)
return {
"complexity": [{"name": r.name, "complexity": r.complexity} for r in cc_results],
"maintainability": mi_score,
}
```
### Step 3: Dependency Mapping
Map import dependencies:
```python
def map_dependencies(tree: ast.AST) -> list[str]:
"""Extract import statements from AST.
Args:
tree: Parsed AST.
Returns:
List of imported module names.
"""
deps = []
for node in ast.walk(tree):
if isinstance(node, ast.Import):
deps.extend(alias.name for alias in node.names)
elif isinstance(node, ast.ImportFrom) and node.module:
deps.append(node.module)
return deps
```
### Step 4: Quality Scoring
Compute aggregate quality score:
```python
def compute_quality_score(complexity_result: dict[str, Any], max_cc: int = 10) -> float:
"""Compute normalized quality score 0.0–1.0.
Args:
complexity_result: Output from compute_complexity.
max_cc: Max acceptable cyclomatic complexity.
Returns:
Quality score.
"""
cc_items = complexity_result.get("complexity", [])
bad_cc = sum(1 for c in cc_items if c["complexity"] > max_cc)
mi = complexity_result.get("maintainability", 20)
cc_penalty = min(1.0, bad_cc * 0.2)
mi_bonus = min(1.0, mi / 100) if mi else 0
return max(0.0, min(1.0, mi_bonus - cc_penalty + 0.5))
```
### Step 5: Report Generation
Generate analysis report:
```python
def generate_analysis_report(filepath: str) -> dict[str, Any]:
"""Generate full code analysis report.
Args:
filepath: Path to Python file.
Returns:
Report dict with scores and findings.
"""
tree = parse_file(filepath)
complexity = compute_complexity(filepath)
deps = map_dependencies(tree)
score = compute_quality_score(complexity)
return {
"file": filepath,
"quality_score": score,
"maintainability_index": complexity.get("maintainability"),
"dependencies": deps,
"complexity_items": complexity.get("complexity", []),
"recommendation": "Refactor" if score < 0.5 else "Acceptable",
}
```
## Best Practices
- Run analysis in CI with thresholds
- Focus on functions with CC > 10
- Track maintainability index over time
- Use dependency maps for impact analysis
## References
- [Radon Documentation](https://radon.readthedocs.io/)
- [Pylint](https://pylint.org/)
- [Python AST](https://docs.python.org/3/library/ast.html)
No comments yet. Be the first to comment!