import ast
from pathlib import Path
class FunctionComplexityAnalyzer(ast.NodeVisitor):
def __init__(self):
self.functions = []
self.current_class = None
def visit_ClassDef(self, node):
self.current_class = node.name
self.generic_visit(node)
self.current_class = None
def visit_FunctionDef(self, node):
# 计算圈复杂度
complexity = 1
for child in ast.walk(node):
if isinstance(child, (ast.If, ast.For, ast.While, ast.With, ast.ExceptHandler)):
complexity += 1
# 获取函数信息
func_info = {
'name': node.name,
'class': self.current_class,
'line': node.lineno,
'complexity': complexity,
'end_line': getattr(node, 'end_lineno', node.lineno)
}
self.functions.append(func_info)
self.generic_visit(node)
def get_high_complexity_functions(self, threshold=10):
return [f for f in self.functions if f['complexity'] > threshold]
def analyze_file_complexity(filepath):
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
try:
tree = ast.parse(content)
analyzer = FunctionComplexityAnalyzer()
analyzer.visit(tree)
high_complexity = analyzer.get_high_complexity_functions()
return {
'file': str(filepath),
'total_functions': len(analyzer.functions),
'high_complexity_count': len(high_complexity),
'high_complexity_functions': high_complexity
}
except Exception as e:
return {
'file': str(filepath),
'error': str(e)
}
if __name__ == "__main__":
# 分析特定文件
files_to_check = [
"src/tools/template_tools.py",
"src/utils/version_manager.py",
"src/utils/config_manager.py",
"src/tools/batch_tools.py",
"src/tools/readme_tools.py",
"src/tools/analysis_tools.py"
]
print("=" * 80)
print("函数复杂度分析报告")
print("=" * 80)
all_high_complexity = []
for filepath in files_to_check:
result = analyze_file_complexity(Path(filepath))
if 'error' in result:
print(f"\n❌ {result['file']}: {result['error']}")
continue
print(f"\n📁 {result['file']}")
print(f" 总函数数: {result['total_functions']}")
print(f" 高复杂度函数数: {result['high_complexity_count']}")
if result['high_complexity_functions']:
print(" 高复杂度函数列表:")
for func in result['high_complexity_functions']:
class_prefix = f"{func['class']}." if func['class'] else ""
print(f" - {class_prefix}{func['name']} (复杂度: {func['complexity']}, 行: {func['line']}-{func['end_line']})")
all_high_complexity.append({
'file': result['file'],
**func
})
print(f"\n📊 总结: 发现 {len(all_high_complexity)} 个高复杂度函数")
# 按复杂度排序
all_high_complexity.sort(key=lambda x: x['complexity'], reverse=True)
print("\n🔝 复杂度排行榜:")
for i, func in enumerate(all_high_complexity, 1):
class_prefix = f"{func['class']}." if func['class'] else ""
print(f" {i}. {func['file']}:{class_prefix}{func['name']} (复杂度: {func['complexity']})")