#!/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 ') 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()