swagger_generator_flutter/fix_cascades.py

131 lines
4.1 KiB
Python

#!/usr/bin/env python3
"""
自动修复 Dart 代码中的 cascade_invocations lint 问题
将连续的 buffer.writeln() 和 buffer.write() 调用转换为使用级联操作符 (..)
"""
import re
import sys
from pathlib import Path
def fix_cascade_invocations(content: str) -> str:
"""修复 cascade_invocations 问题"""
lines = content.split('\n')
result = []
i = 0
while i < len(lines):
line = lines[i]
# 检测是否是 buffer.writeln() 或 buffer.write() 调用
if re.match(r'\s+buffer\.(writeln|write)\(', line):
# 收集连续的 buffer 调用
buffer_calls = [line]
indent = len(line) - len(line.lstrip())
j = i + 1
# 查找连续的 buffer 调用
while j < len(lines):
next_line = lines[j]
# 跳过空行和注释
if not next_line.strip() or next_line.strip().startswith('//'):
j += 1
continue
# 检查是否是相同缩进的 buffer 调用
if re.match(r'\s+buffer\.(writeln|write)\(', next_line):
next_indent = len(next_line) - len(next_line.lstrip())
if next_indent == indent:
buffer_calls.append(next_line)
j += 1
else:
break
else:
break
# 如果有多个连续的 buffer 调用,转换为级联
if len(buffer_calls) >= 2:
# 第一行改为 buffer
first_line = buffer_calls[0]
indent_str = ' ' * indent
# 提取第一个调用
match = re.match(r'(\s+)buffer\.(writeln|write)\((.*)\);?', first_line)
if match:
method = match.group(2)
args = match.group(3)
result.append(f'{indent_str}buffer')
result.append(f'{indent_str} ..{method}({args})')
# 处理后续调用
for call in buffer_calls[1:]:
match = re.match(r'\s+buffer\.(writeln|write)\((.*)\);?', call)
if match:
method = match.group(1)
args = match.group(2)
result.append(f'{indent_str} ..{method}({args})')
# 添加分号
result[-1] = result[-1].rstrip() + ';'
i = j
continue
result.append(line)
i += 1
return '\n'.join(result)
def process_file(file_path: Path) -> bool:
"""处理单个文件"""
try:
content = file_path.read_text(encoding='utf-8')
fixed_content = fix_cascade_invocations(content)
if content != fixed_content:
file_path.write_text(fixed_content, encoding='utf-8')
print(f'✓ Fixed: {file_path}')
return True
else:
print(f'- Skipped: {file_path} (no changes needed)')
return False
except Exception as e:
print(f'✗ Error processing {file_path}: {e}')
return False
def main():
"""主函数"""
if len(sys.argv) < 2:
print('Usage: python fix_cascades.py <file_or_directory>')
sys.exit(1)
path = Path(sys.argv[1])
if not path.exists():
print(f'Error: {path} does not exist')
sys.exit(1)
files_to_process = []
if path.is_file():
files_to_process = [path]
else:
# 递归查找所有 .dart 文件
files_to_process = list(path.rglob('*.dart'))
print(f'Processing {len(files_to_process)} files...\n')
fixed_count = 0
for file_path in files_to_process:
if process_file(file_path):
fixed_count += 1
print(f'\n✓ Fixed {fixed_count} files')
if __name__ == '__main__':
main()