131 lines
4.1 KiB
Python
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()
|