import 'dart:io'; void main(List args) async { final targetPath = args.isNotEmpty ? args[0] : Directory.current.path; final type = FileSystemEntity.typeSync(targetPath); if (type == FileSystemEntityType.notFound) { print('路径不存在: $targetPath'); return; } if (type == FileSystemEntityType.file && targetPath.endsWith('.dart')) { await processDartFile(File(targetPath)); } else if (type == FileSystemEntityType.directory) { final directory = Directory(targetPath); print('扫描目录: $targetPath'); await for (final entity in directory.list(recursive: true, followLinks: false)) { if (entity is File && entity.path.endsWith('.dart')) { await processDartFile(entity); } } print('处理完成'); } else { print('不支持的路径类型: $targetPath'); } } Future processDartFile(File file) async { final content = await file.readAsString(); // 获取注释范围 final commentRanges = getCommentRanges(content); // 匹配带中文的引号字符串(单/双引号) final regex = RegExp(r'''(['"])([^'"]*?[\u4e00-\u9fa5][^'"]*?)\1'''); final matches = regex.allMatches(content).toList(); if (matches.isEmpty) return; final sb = StringBuffer(); int lastIndex = 0; for (final match in matches) { final start = match.start; final end = match.end; // 跳过注释中的内容 if (commentRanges.any((range) => start >= range[0] && start < range[1])) { continue; } // 插入上次结束到当前匹配之间的代码 sb.write(content.substring(lastIndex, start)); final fullMatch = match.group(0)!; // 判断是否已处于 .tr 表达式中 if (isAlreadyTrCall(content, start, end)) { sb.write(fullMatch); // 不修改 } else { sb.write('$fullMatch.tr'); // 添加 .tr } lastIndex = end; } sb.write(content.substring(lastIndex)); final result = sb.toString(); if (result != content) { await file.writeAsString(result); print('✅ 修改完成: ${file.path}'); } else { print('✔ 无需修改: ${file.path}'); } } /// 判断该字符串是否已是 .tr 调用的一部分 bool isAlreadyTrCall(String content, int start, int end) { final after = content.substring(end); final before = content.substring(0, start); // 检查匹配后是否直接跟 .tr (允许空格) final hasTrAfter = RegExp(r'^\s*\.tr\b').hasMatch(after); // 检查匹配前是否已经出现 .tr (形如 .tr'xxx' 也考虑在内) final hasTrBefore = RegExp(r'\.tr\s*$').hasMatch(before); return hasTrAfter || hasTrBefore; } /// 找出所有注释区间 (start, end) List> getCommentRanges(String content) { final ranges = >[]; final multiLine = RegExp(r'/\*[\s\S]*?\*/'); final singleLine = RegExp(r'//.*'); for (final m in multiLine.allMatches(content)) { ranges.add([m.start, m.end]); } for (final m in singleLine.allMatches(content)) { ranges.add([m.start, m.end]); } return ranges; }