scancscode 1.0.29 → 1.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/CSCodeScanner.js +288 -0
- package/dist/src/CSVUtils.js +220 -0
- package/dist/src/CSharpStringExtractor.js +925 -0
- package/dist/src/CmdExecutor.js +109 -0
- package/dist/src/LiteralCollector.js +160 -0
- package/dist/src/RunConvert.js +4 -0
- package/dist/src/RunSlimLangs.js +4 -0
- package/dist/src/TableScanner.js +129 -0
- package/dist/test/CSharpStringExtractor.test.js +887 -0
- package/dist/test/TestConvert.test.js +8 -0
- package/package.json +1 -1
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CmdExecutor = void 0;
|
|
7
|
+
const CSVUtils_1 = require("./CSVUtils");
|
|
8
|
+
const LiteralCollector_1 = require("./LiteralCollector");
|
|
9
|
+
const command_line_args_1 = __importDefault(require("command-line-args"));
|
|
10
|
+
function isNullOrEmpty(arr) {
|
|
11
|
+
return arr == null || arr.length == 0;
|
|
12
|
+
}
|
|
13
|
+
class CmdExecutor {
|
|
14
|
+
static testConvert() {
|
|
15
|
+
let cwd = "E:/DATA/Projects/ZhiYou/ProjectFClient/GameClient/";
|
|
16
|
+
let cscodeFolders = [cwd + "Assets/Bundles/FGUI/"];
|
|
17
|
+
let gameConfigFolders = [cwd + "Assets/Bundles/GameConfigs/"];
|
|
18
|
+
let outCsvFile = "E:/DATA/Projects/e-gbl-client/client/Assets/Bundles/GameConfigs/Translation/hello.csv";
|
|
19
|
+
let langs = ["zh_cn"];
|
|
20
|
+
let literalCollector = new LiteralCollector_1.LiteralCollector();
|
|
21
|
+
// return literalCollector.convert(cscodeFolders, gameConfigFolders, outCsvFile, langs,undefined,false,true)
|
|
22
|
+
return literalCollector.convert(cscodeFolders,
|
|
23
|
+
// [
|
|
24
|
+
// "E:/DATA/Projects/ZhiYou/DXTSProject/Client/Assets/Bundles/UI/",
|
|
25
|
+
// "E:/DATA/Projects/ZhiYou/DXTSProject/Client/Assets/Bundles/Battle/",
|
|
26
|
+
// "E:/DATA/Projects/ZhiYou/DXTSProject/Client/Assets/Scripts/",
|
|
27
|
+
// "E:/DATA/Projects/ZhiYou/ProjectFClient/GameClient/Assets/Bundles/FGUI/",
|
|
28
|
+
// ],
|
|
29
|
+
gameConfigFolders, outCsvFile, langs);
|
|
30
|
+
// node . --cscodedir ../../../GameClient/Assets/Bundles/FGUI/ --configdir ../../../GameClient/Assets/Bundles/GameConfigs/ --outcsv E:/DATA/Projects/e-gbl-client/client/Assets/Bundles/GameConfigs/Translation/hello.csv --langs zh_cn
|
|
31
|
+
}
|
|
32
|
+
static async runConvertWithCmdOptions() {
|
|
33
|
+
const optionDefinitions = [
|
|
34
|
+
{ name: 'cscodedir', type: String, multiple: true },
|
|
35
|
+
{ name: 'configdir', type: String, multiple: true },
|
|
36
|
+
{ name: 'outcsv', type: String },
|
|
37
|
+
{ name: "langs", type: String, multiple: true, defaultOption: true },
|
|
38
|
+
{ name: "verbose", alias: 'v', type: Boolean },
|
|
39
|
+
{ name: "scanonly", type: Boolean, defaultOption: false },
|
|
40
|
+
{ name: "trmethod", type: String }
|
|
41
|
+
];
|
|
42
|
+
const options = (0, command_line_args_1.default)(optionDefinitions);
|
|
43
|
+
let cscodedir = options.cscodedir ?? [];
|
|
44
|
+
let configdir = options.configdir ?? [];
|
|
45
|
+
let outcsv = options.outcsv;
|
|
46
|
+
let langs = options.langs ?? ["zh_cn"];
|
|
47
|
+
let verbose = options.verbose ?? false;
|
|
48
|
+
let scanonly = options.scanonly ?? false;
|
|
49
|
+
let trmethod = options.trmethod ?? "Tr.TR";
|
|
50
|
+
let argv = process.argv;
|
|
51
|
+
if (isNullOrEmpty(cscodedir) && isNullOrEmpty(configdir)) {
|
|
52
|
+
if (isNullOrEmpty(cscodedir)) {
|
|
53
|
+
console.error(`cscodedir missing:`, argv);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
if (isNullOrEmpty(configdir)) {
|
|
57
|
+
console.error(`configdir missing:`, argv);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (outcsv == null) {
|
|
62
|
+
console.error(`outcsv missing:`, argv);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (isNullOrEmpty(langs)) {
|
|
66
|
+
console.error(`langs missing:`, argv);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
console.log(`convert cmd options: `, cscodedir, configdir, outcsv, langs, verbose);
|
|
70
|
+
let literalCollector = new LiteralCollector_1.LiteralCollector();
|
|
71
|
+
await literalCollector.convert(cscodedir, configdir, outcsv, langs, trmethod, scanonly, verbose);
|
|
72
|
+
console.log("convert done.");
|
|
73
|
+
}
|
|
74
|
+
static testSlimCsv() {
|
|
75
|
+
let inCsvFile = ["E:/DATA/Projects/e-gbl-client/client/Assets/Bundles/GameConfigs/Translation/hello.csv"];
|
|
76
|
+
let outCsvFile = "E:/DATA/Projects/e-gbl-client/client/Assets/Bundles/GameConfigs/Translation/hello-out.csv";
|
|
77
|
+
let langs = ["zh_cn"];
|
|
78
|
+
CSVUtils_1.CSVUtils.slimCsvWithLangs(inCsvFile, outCsvFile, langs);
|
|
79
|
+
// node bin/slimlangs.js --incsv E:/DATA/Projects/e-gbl-client/client/Assets/Bundles/GameConfigs/Translation/hello.csv --outcsv E:/DATA/Projects/e-gbl-client/client/Assets/Bundles/GameConfigs/Translation/hello-out.csv --langs zh_cn
|
|
80
|
+
}
|
|
81
|
+
static async runSlimCsvWithLangs() {
|
|
82
|
+
const optionDefinitions = [
|
|
83
|
+
{ name: 'incsv', type: String, multiple: true },
|
|
84
|
+
{ name: 'outcsv', type: String },
|
|
85
|
+
{ name: 'langs', type: String, multiple: true, defaultOption: true },
|
|
86
|
+
];
|
|
87
|
+
const options = (0, command_line_args_1.default)(optionDefinitions);
|
|
88
|
+
let incsv = options.incsv ?? [];
|
|
89
|
+
let outcsv = options.outcsv;
|
|
90
|
+
let langs = options.langs ?? ["zh_cn"];
|
|
91
|
+
console.log(`slim csv cmd options: `, incsv, outcsv, langs);
|
|
92
|
+
let argv = process.argv;
|
|
93
|
+
if (isNullOrEmpty(incsv)) {
|
|
94
|
+
console.error(`incsv missing:`, argv);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (outcsv == null) {
|
|
98
|
+
console.error(`outcsv missing:`, argv);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (isNullOrEmpty(langs)) {
|
|
102
|
+
console.error(`langs missing:`, argv);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
await CSVUtils_1.CSVUtils.slimCsvWithLangs(incsv, outcsv, langs);
|
|
106
|
+
console.log("slim csv with langs done.");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.CmdExecutor = CmdExecutor;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.LiteralCollector = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const glob_1 = require("glob");
|
|
39
|
+
const CSCodeScanner_1 = require("./CSCodeScanner");
|
|
40
|
+
const CSVUtils_1 = require("./CSVUtils");
|
|
41
|
+
const TableScanner_1 = require("./TableScanner");
|
|
42
|
+
class LiteralCollector {
|
|
43
|
+
async scanCodeInFolder(folder, literals, unexpects, trmethod, scanonly, verbose) {
|
|
44
|
+
if (fs.existsSync(folder) == false) {
|
|
45
|
+
console.warn(`代码目录不存在: ${folder}`);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
let files = glob_1.glob.sync("**/*.cs", { cwd: folder });
|
|
49
|
+
let testFullPath = "@";
|
|
50
|
+
// let testFullPath = "E:/DATA/Projects/ZhiYou/ProjectFClient/GameClient/Assets/Bundles/GameConfigs/Main/UnitAttributeTable-UnitAttributeTable.cs";
|
|
51
|
+
// 限制并行处理的文件数量,避免内存占用过高
|
|
52
|
+
const batchSize = 10;
|
|
53
|
+
for (let i = 0; i < files.length; i += batchSize) {
|
|
54
|
+
const batchFiles = files.slice(i, i + batchSize);
|
|
55
|
+
const batchPromises = batchFiles.map(async (filePath) => {
|
|
56
|
+
let fullPath = folder + filePath;
|
|
57
|
+
if (testFullPath != "@") {
|
|
58
|
+
fullPath = testFullPath;
|
|
59
|
+
}
|
|
60
|
+
if (verbose) {
|
|
61
|
+
console.log(`处理文件: ${filePath}, ${fullPath}`);
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const content = await fs.promises.readFile(fullPath, "utf-8");
|
|
65
|
+
const snippets = CSCodeScanner_1.CSCodeScanner.scanFile(fullPath, content, trmethod);
|
|
66
|
+
CSCodeScanner_1.CSCodeScanner.filterSnippets(snippets);
|
|
67
|
+
if (snippets.length > 0) {
|
|
68
|
+
if (!scanonly) {
|
|
69
|
+
let convertedContent = CSCodeScanner_1.CSCodeScanner.replaceInFile(content, snippets);
|
|
70
|
+
if (convertedContent != content) {
|
|
71
|
+
await fs.promises.writeFile(fullPath, convertedContent, "utf-8");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const fileLiterals = [];
|
|
75
|
+
const fileUnexpects = [];
|
|
76
|
+
for (const snippet of snippets) {
|
|
77
|
+
fileLiterals.push(...snippet.literals);
|
|
78
|
+
fileUnexpects.push(...snippet.unexpects);
|
|
79
|
+
}
|
|
80
|
+
return { literals: fileLiterals, unexpects: fileUnexpects };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
console.error(`处理文件失败: ${fullPath}`, error);
|
|
85
|
+
}
|
|
86
|
+
return { literals: [], unexpects: [] };
|
|
87
|
+
});
|
|
88
|
+
const batchResults = await Promise.all(batchPromises);
|
|
89
|
+
for (const result of batchResults) {
|
|
90
|
+
literals.push(...result.literals);
|
|
91
|
+
unexpects.push(...result.unexpects);
|
|
92
|
+
}
|
|
93
|
+
if (testFullPath != "@") {
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
unexpects = [...new Set(unexpects)];
|
|
98
|
+
}
|
|
99
|
+
async scanTablesInFolder(folder, literals, verbose) {
|
|
100
|
+
if (fs.existsSync(folder) == false) {
|
|
101
|
+
console.warn(`表格目录不存在: ${folder}`);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
let scanner = new TableScanner_1.TableScanner();
|
|
105
|
+
await scanner.scanTablesLiterals(folder + "Main/", literals, verbose);
|
|
106
|
+
}
|
|
107
|
+
static needTranslate(literal) {
|
|
108
|
+
let match = literal.match(/^[\da-zA-Z!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/? ]+$/m);
|
|
109
|
+
return match == null;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 去重
|
|
113
|
+
* @param literals
|
|
114
|
+
*/
|
|
115
|
+
filterLiterals(literals) {
|
|
116
|
+
let literalsSet = new Set(literals);
|
|
117
|
+
literalsSet.delete("");
|
|
118
|
+
for (let literal of literals) {
|
|
119
|
+
let needTr = LiteralCollector.needTranslate(literal);
|
|
120
|
+
if (!needTr) {
|
|
121
|
+
literalsSet.delete(literal);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
literals.length = 0;
|
|
125
|
+
literals.push(...literalsSet);
|
|
126
|
+
}
|
|
127
|
+
async convert(cscodeFolders, gameConfigFolders, outCsvFile, langs, trmethod = "Tr.TR", scanonly = false, verbose = false) {
|
|
128
|
+
let literals = [];
|
|
129
|
+
let unexpects = [];
|
|
130
|
+
// 并行处理代码文件夹
|
|
131
|
+
const codeFolderPromises = cscodeFolders.map(async (cscodeFolder) => {
|
|
132
|
+
const folderLiterals = [];
|
|
133
|
+
const folderUnexpects = [];
|
|
134
|
+
await this.scanCodeInFolder(cscodeFolder, folderLiterals, folderUnexpects, trmethod, scanonly, verbose);
|
|
135
|
+
return { literals: folderLiterals, unexpects: folderUnexpects };
|
|
136
|
+
});
|
|
137
|
+
const codeFolderResults = await Promise.all(codeFolderPromises);
|
|
138
|
+
for (const result of codeFolderResults) {
|
|
139
|
+
literals.push(...result.literals);
|
|
140
|
+
unexpects.push(...result.unexpects);
|
|
141
|
+
}
|
|
142
|
+
// 并行处理表格文件夹
|
|
143
|
+
const tableFolderPromises = gameConfigFolders.map(async (gameConfigFolder) => {
|
|
144
|
+
await this.scanTablesInFolder(gameConfigFolder, literals, verbose);
|
|
145
|
+
});
|
|
146
|
+
await Promise.all(tableFolderPromises);
|
|
147
|
+
// 去重和过滤
|
|
148
|
+
this.filterLiterals(literals);
|
|
149
|
+
if (verbose) {
|
|
150
|
+
console.log("扫描合并结果:", literals);
|
|
151
|
+
}
|
|
152
|
+
if (!scanonly) {
|
|
153
|
+
await CSVUtils_1.CSVUtils.updateToFile(outCsvFile, literals, langs);
|
|
154
|
+
}
|
|
155
|
+
for (const unexpect of unexpects) {
|
|
156
|
+
console.error(unexpect);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.LiteralCollector = LiteralCollector;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.TableScanner = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const glob_1 = require("glob");
|
|
39
|
+
class TableScanner {
|
|
40
|
+
parseTrStrFields(content) {
|
|
41
|
+
let m = content.match(/\/\/ NeedTranslateFields\: \[([a-zA-Z_,\s0-9]*)\]$/m);
|
|
42
|
+
if (m != null) {
|
|
43
|
+
let wordsContent = m[1];
|
|
44
|
+
let words = wordsContent.split(", ");
|
|
45
|
+
return words;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
scanJsonWords(jsonContent, fields, literals) {
|
|
52
|
+
try {
|
|
53
|
+
let arr = JSON.parse(jsonContent);
|
|
54
|
+
for (const jsonRow of arr) {
|
|
55
|
+
for (const key of fields) {
|
|
56
|
+
let value = jsonRow[key];
|
|
57
|
+
if (typeof (value) == "string") {
|
|
58
|
+
literals.push(value);
|
|
59
|
+
}
|
|
60
|
+
else if (Array.isArray(value)) {
|
|
61
|
+
literals.push(...value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error(`解析JSON失败: ${error}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async scanTableLiterals(csFullPath, literals, verbose) {
|
|
71
|
+
// csFullPath = "E:/DATA/Projects/ZhiYou/ProjectFClient/GameClient/Assets/Bundles/GameConfigs/Main/RefinerTable-RefinerEventTable.cs";
|
|
72
|
+
let jsonFullPath = csFullPath.replace("/Main/", "/Auto/").replace(/\.cs$/, ".json");
|
|
73
|
+
try {
|
|
74
|
+
const [csExists, jsonExists] = await Promise.all([
|
|
75
|
+
fs.promises.access(csFullPath).then(() => true).catch(() => false),
|
|
76
|
+
fs.promises.access(jsonFullPath).then(() => true).catch(() => false)
|
|
77
|
+
]);
|
|
78
|
+
if (jsonExists && csExists) {
|
|
79
|
+
const [csContent, jsonContent] = await Promise.all([
|
|
80
|
+
fs.promises.readFile(csFullPath, "utf-8"),
|
|
81
|
+
fs.promises.readFile(jsonFullPath, "utf-8")
|
|
82
|
+
]);
|
|
83
|
+
let trstrFields = this.parseTrStrFields(csContent);
|
|
84
|
+
if (trstrFields.length > 0) {
|
|
85
|
+
if (verbose) {
|
|
86
|
+
console.log(`扫描表格: ${csFullPath} , 需要翻译字段: ${trstrFields}`);
|
|
87
|
+
}
|
|
88
|
+
this.scanJsonWords(jsonContent, trstrFields, literals);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
if (verbose) {
|
|
92
|
+
console.log(`跳过表格: ${csFullPath}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
if (verbose) {
|
|
98
|
+
if (!csExists) {
|
|
99
|
+
console.warn(`表格 CS 文件不存在: ${jsonFullPath}`);
|
|
100
|
+
}
|
|
101
|
+
if (!jsonExists) {
|
|
102
|
+
console.warn(`表格 JSON 文件不存在: ${csFullPath}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
console.error(`处理表格文件失败: ${csFullPath}`, error);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* 扫描
|
|
113
|
+
*/
|
|
114
|
+
async scanTablesLiterals(folder, literals, verbose) {
|
|
115
|
+
let dir = folder;
|
|
116
|
+
let files = glob_1.glob.sync("*.cs", { cwd: dir });
|
|
117
|
+
// 限制并行处理的文件数量,避免内存占用过高
|
|
118
|
+
const batchSize = 10;
|
|
119
|
+
for (let i = 0; i < files.length; i += batchSize) {
|
|
120
|
+
const batchFiles = files.slice(i, i + batchSize).reverse();
|
|
121
|
+
const batchPromises = batchFiles.map(async (filePath) => {
|
|
122
|
+
let csFullPath = folder + filePath;
|
|
123
|
+
await this.scanTableLiterals(csFullPath, literals, verbose);
|
|
124
|
+
});
|
|
125
|
+
await Promise.all(batchPromises);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
exports.TableScanner = TableScanner;
|