@kezh/my-custom-js-converter 0.2.1 → 1.0.1
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/core/context/map_context.js +12 -5
- package/core/util/ast.js +0 -1
- package/package.json +1 -1
- package/core/decode.d.ts +0 -1
- package/core/decode.js +0 -122
- package/core/encode.d.ts +0 -1
- package/core/encode.js +0 -376
|
@@ -50,11 +50,18 @@ class MapContext {
|
|
|
50
50
|
static readFromLocal(inDir) {
|
|
51
51
|
const inPath = path_1.default.join(inDir, MapContext.SAVE_FILE);
|
|
52
52
|
console.log(`input map => ${inPath}`);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
try {
|
|
54
|
+
const json = fs_1.default.readFileSync(inPath, { encoding: "utf-8" });
|
|
55
|
+
const map = JSON.parse(json);
|
|
56
|
+
const mapContext = new MapContext();
|
|
57
|
+
Object.keys(map).forEach((name) => mapContext.appendModMap(map[name], false, name));
|
|
58
|
+
return mapContext;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
console.log("the map is not found!");
|
|
62
|
+
console.log(err);
|
|
63
|
+
}
|
|
64
|
+
return new MapContext();
|
|
58
65
|
}
|
|
59
66
|
init() {
|
|
60
67
|
this.buildMapContext(this.srcPath, this.entry, true);
|
package/core/util/ast.js
CHANGED
|
@@ -278,7 +278,6 @@ function modifyObjectMethods(srcAst, entry, mod, methods, root = false) {
|
|
|
278
278
|
if (core_1.types.isIdentifier(path.node.key)) {
|
|
279
279
|
path.node.key.name = `${path.node.key.name}__${entry}`;
|
|
280
280
|
}
|
|
281
|
-
core_1.types.addComment(path.node.body, "inner", "auto-generated: Please do not modify the.");
|
|
282
281
|
}
|
|
283
282
|
});
|
|
284
283
|
}
|
package/package.json
CHANGED
package/core/decode.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/core/decode.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
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
|
-
const fs_1 = __importDefault(require("fs"));
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const prettier_1 = __importDefault(require("prettier"));
|
|
9
|
-
const parser_1 = require("@babel/parser");
|
|
10
|
-
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
11
|
-
const generator_1 = __importDefault(require("@babel/generator"));
|
|
12
|
-
const core_1 = require("@babel/core");
|
|
13
|
-
const scanf_1 = require("./scanf");
|
|
14
|
-
const config_1 = __importDefault(require("./config"));
|
|
15
|
-
const TARGET_DIR = (0, scanf_1.scanfCodeDirs)(config_1.default.baseDir, config_1.default.target);
|
|
16
|
-
const DECODE_FILE = config_1.default.decode.file;
|
|
17
|
-
const OUTPUT_FILE = config_1.default.decode.output;
|
|
18
|
-
const MOUNT = config_1.default.decode.mount;
|
|
19
|
-
const WORK_DIR = config_1.default.workDir;
|
|
20
|
-
const CUSTOM_CONFIG = config_1.default.customConfig;
|
|
21
|
-
(function decoding(targetDirs = TARGET_DIR) {
|
|
22
|
-
console.log("scanf dirs => ");
|
|
23
|
-
console.log(targetDirs);
|
|
24
|
-
const codeFiles = (0, scanf_1.scanfCodeFiles)(targetDirs, DECODE_FILE);
|
|
25
|
-
codeFiles.forEach((file) => {
|
|
26
|
-
console.log(`scanf file => ${file}`);
|
|
27
|
-
const outPath = path_1.default.join(path_1.default.dirname(file), OUTPUT_FILE);
|
|
28
|
-
decoding$0(file, outPath);
|
|
29
|
-
console.log(`output => ${outPath}`);
|
|
30
|
-
});
|
|
31
|
-
})();
|
|
32
|
-
/**
|
|
33
|
-
* 解码
|
|
34
|
-
* @param inPath - 源文件路径
|
|
35
|
-
* @param outPath - 输入文件路径
|
|
36
|
-
* @param mount - 方法挂载点
|
|
37
|
-
*/
|
|
38
|
-
function decoding$0(inPath, outPath, mount = MOUNT) {
|
|
39
|
-
const customConfig = loadCustomConfig(path_1.default.dirname(inPath));
|
|
40
|
-
let src = fs_1.default.readFileSync(inPath, {
|
|
41
|
-
encoding: "utf-8"
|
|
42
|
-
});
|
|
43
|
-
src = `const ${mount} = {${src}};`;
|
|
44
|
-
const srcAst = (0, parser_1.parse)(src);
|
|
45
|
-
importMods(path_1.default.dirname(outPath), customConfig.mod, srcAst);
|
|
46
|
-
deleteModMethods(customConfig.mod, srcAst);
|
|
47
|
-
let { code: dist } = (0, generator_1.default)(srcAst);
|
|
48
|
-
dist = dist.replace(/},\n\n/g, "},\n");
|
|
49
|
-
dist = prettier_1.default.format(dist, {
|
|
50
|
-
parser: "babel",
|
|
51
|
-
trailingComma: "none"
|
|
52
|
-
});
|
|
53
|
-
fs_1.default.writeFileSync(outPath, dist, "utf-8");
|
|
54
|
-
}
|
|
55
|
-
function importMods(outDir, mods, srcAst) {
|
|
56
|
-
const importMods = mods.map((mod) => {
|
|
57
|
-
const requireFrom = path_1.default
|
|
58
|
-
.relative(outDir, mod.path.replace(/index\.js$/, ""))
|
|
59
|
-
.replace(/[\\]+/g, "/");
|
|
60
|
-
const variableDeclarator = core_1.types.variableDeclarator(core_1.types.identifier(mod.name), core_1.types.callExpression(core_1.types.identifier("require"), [
|
|
61
|
-
core_1.types.stringLiteral(requireFrom)
|
|
62
|
-
]));
|
|
63
|
-
return core_1.types.variableDeclaration("const", [variableDeclarator]);
|
|
64
|
-
});
|
|
65
|
-
(0, traverse_1.default)(srcAst, {
|
|
66
|
-
Program(path) {
|
|
67
|
-
path.node.body.unshift(...importMods);
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* 去除第三方模块方法
|
|
73
|
-
* @param srcAst - 源码AST
|
|
74
|
-
*/
|
|
75
|
-
function deleteModMethods(mods, srcAst) {
|
|
76
|
-
const modNames = mods.map((m) => m.name);
|
|
77
|
-
(0, traverse_1.default)(srcAst, {
|
|
78
|
-
ObjectMethod(path) {
|
|
79
|
-
if (!core_1.types.isIdentifier(path.node.key)) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
const methodName = path.node.key.name;
|
|
83
|
-
modNames
|
|
84
|
-
.filter((name) => methodName.lastIndexOf(`__${name}`) !== -1)
|
|
85
|
-
.forEach(() => {
|
|
86
|
-
path.remove();
|
|
87
|
-
});
|
|
88
|
-
},
|
|
89
|
-
Identifier(path) {
|
|
90
|
-
const id = path.node.name;
|
|
91
|
-
modNames
|
|
92
|
-
.filter((name) => id.lastIndexOf(`__${name}`) !== -1)
|
|
93
|
-
.forEach((name) => {
|
|
94
|
-
path.node.name = id.replace(`__${name}`, "");
|
|
95
|
-
const expression = path.findParent((path) => path.isMemberExpression());
|
|
96
|
-
if (!core_1.types.isThisExpression(expression === null || expression === void 0 ? void 0 : expression.object)) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
expression.object = core_1.types.identifier(name);
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
function loadCustomConfig(inPath, workDir = WORK_DIR, config = CUSTOM_CONFIG) {
|
|
105
|
-
const configPath = path_1.default.join(inPath, workDir, config);
|
|
106
|
-
let configObj = {
|
|
107
|
-
mod: [],
|
|
108
|
-
};
|
|
109
|
-
try {
|
|
110
|
-
fs_1.default.accessSync(configPath, fs_1.default.constants.F_OK);
|
|
111
|
-
console.log(`load custom config => ${configPath}`);
|
|
112
|
-
const data = fs_1.default.readFileSync(configPath, { encoding: "utf-8" });
|
|
113
|
-
configObj = JSON.parse(data);
|
|
114
|
-
configObj.mod.forEach((m) => {
|
|
115
|
-
m.name = m.name.replace("\\", "\\\\");
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
console.log(`not found custom config => ${configPath}`);
|
|
120
|
-
}
|
|
121
|
-
return configObj;
|
|
122
|
-
}
|
package/core/encode.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/core/encode.js
DELETED
|
@@ -1,376 +0,0 @@
|
|
|
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 (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
const fs_1 = __importDefault(require("fs"));
|
|
30
|
-
const path_1 = __importDefault(require("path"));
|
|
31
|
-
const parser_1 = require("@babel/parser");
|
|
32
|
-
const traverse_1 = __importDefault(require("@babel/traverse"));
|
|
33
|
-
const generator_1 = __importDefault(require("@babel/generator"));
|
|
34
|
-
const core_1 = require("@babel/core");
|
|
35
|
-
const scanf_1 = require("./scanf");
|
|
36
|
-
const config_1 = __importStar(require("./config"));
|
|
37
|
-
const TARGET_DIR = (0, scanf_1.scanfCodeDirs)(config_1.default.baseDir, config_1.default.target);
|
|
38
|
-
const ENCODE_FILE = config_1.default.encode.file;
|
|
39
|
-
const OUTPUT_FILE = config_1.default.encode.output;
|
|
40
|
-
const ENTRY = config_1.default.encode.entry;
|
|
41
|
-
const IGNORE_MOD = config_1.default.encode.ignoreMod;
|
|
42
|
-
const WORK_DIR = config_1.default.workDir;
|
|
43
|
-
const CUSTOM_CONFIG = config_1.default.customConfig;
|
|
44
|
-
(function encoding(targetDirs = TARGET_DIR) {
|
|
45
|
-
console.log("scanf dirs => ");
|
|
46
|
-
console.log(targetDirs);
|
|
47
|
-
const codeFiles = (0, scanf_1.scanfCodeFiles)(targetDirs, ENCODE_FILE);
|
|
48
|
-
codeFiles.forEach((file) => {
|
|
49
|
-
console.log(`scanf file => ${file}`);
|
|
50
|
-
const outPath = path_1.default.join(path_1.default.dirname(file), OUTPUT_FILE);
|
|
51
|
-
encoding$0(file, outPath);
|
|
52
|
-
console.log(`output => ${outPath}`);
|
|
53
|
-
});
|
|
54
|
-
})();
|
|
55
|
-
/**
|
|
56
|
-
* 编码
|
|
57
|
-
* @param inPath - 源文件路径
|
|
58
|
-
* @param outPath - 输入文件路径
|
|
59
|
-
*/
|
|
60
|
-
function encoding$0(inPath, outPath) {
|
|
61
|
-
const src = fs_1.default.readFileSync(inPath, {
|
|
62
|
-
encoding: "utf-8"
|
|
63
|
-
});
|
|
64
|
-
const srcAst = (0, parser_1.parse)(src);
|
|
65
|
-
const methods = [];
|
|
66
|
-
const customMethodNames = getSrcMethodNames(ENTRY, srcAst);
|
|
67
|
-
if (!customMethodNames.length) {
|
|
68
|
-
console.log(`not found entry => ${ENTRY}`);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const importModPathByName = getImportModPaths(path_1.default.dirname(inPath), srcAst);
|
|
72
|
-
const importMethodNamesByMod = getImportMethodNames([...importModPathByName.keys()], srcAst);
|
|
73
|
-
const importMethods = getImportMethods(importModPathByName, importMethodNamesByMod);
|
|
74
|
-
modifyCallObjectAndMethodNames(customMethodNames, [...importModPathByName.keys()], srcAst);
|
|
75
|
-
const customMethods = getMethods(ENTRY, srcAst);
|
|
76
|
-
methods.push(...customMethods, ...importMethods);
|
|
77
|
-
const dist = methods
|
|
78
|
-
.map((m) => {
|
|
79
|
-
var _a;
|
|
80
|
-
if ((_a = m.leadingComments) === null || _a === void 0 ? void 0 : _a.length) {
|
|
81
|
-
m.leadingComments = undefined;
|
|
82
|
-
}
|
|
83
|
-
return m;
|
|
84
|
-
})
|
|
85
|
-
.map((m) => (0, generator_1.default)(m))
|
|
86
|
-
.map((m) => m.code)
|
|
87
|
-
.join(",\n");
|
|
88
|
-
fs_1.default.writeFileSync(outPath, dist, "utf-8");
|
|
89
|
-
refreshCustomConfig(importModPathByName, path_1.default.dirname(inPath));
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* 获取所有依赖方法
|
|
93
|
-
* @param modPathByName - 模块路径
|
|
94
|
-
* @param methodNamesByMod - 依赖模块方法名
|
|
95
|
-
* @returns
|
|
96
|
-
*/
|
|
97
|
-
function getImportMethods(modPathByName, methodNamesByMod) {
|
|
98
|
-
const importModNames = [...modPathByName.entries()].map(([name]) => name);
|
|
99
|
-
if (!importModNames.length) {
|
|
100
|
-
return [];
|
|
101
|
-
}
|
|
102
|
-
console.log(`import => ${importModNames}`);
|
|
103
|
-
return [...modPathByName.entries()].flatMap(([name, modPath]) => {
|
|
104
|
-
const mod = fs_1.default.readFileSync(modPath, { encoding: "utf-8" });
|
|
105
|
-
const modAst = (0, parser_1.parse)(mod);
|
|
106
|
-
const modMethods = getMethods(name, modAst);
|
|
107
|
-
if (!methodNamesByMod.has(name)) {
|
|
108
|
-
return [];
|
|
109
|
-
}
|
|
110
|
-
const modMethodNames = modMethods.map((m) => m.key.name);
|
|
111
|
-
// console.log(`mod methods => ${modMethodNames}`);
|
|
112
|
-
const useMethodNames = methodNamesByMod.get(name);
|
|
113
|
-
// console.log(`use methods => ${useMethodNames}`);
|
|
114
|
-
const inlineMethodNames = getInlineThisMethodNames(modMethodNames, useMethodNames, modAst);
|
|
115
|
-
// console.log(`inline methods => ${inlineMethodNames}`);
|
|
116
|
-
let mergeMethodNames = [
|
|
117
|
-
...new Set([...useMethodNames, ...inlineMethodNames])
|
|
118
|
-
];
|
|
119
|
-
modifyModMethods(name, mergeMethodNames, modAst);
|
|
120
|
-
// console.log(generate(modAst).code);
|
|
121
|
-
const mergeMethods = mergeMethodNames
|
|
122
|
-
.map((name) => {
|
|
123
|
-
return modMethods.find((m) => core_1.types.isIdentifier(m.key) && m.key.name === name);
|
|
124
|
-
})
|
|
125
|
-
.filter((m) => m);
|
|
126
|
-
// console.log(`inline methods size => ${inlineMethodNames.length}`);
|
|
127
|
-
// console.log(`import methods size => ${mergeMethods.length}`);
|
|
128
|
-
return mergeMethods.map((m) => {
|
|
129
|
-
if (core_1.types.isIdentifier(m.key)) {
|
|
130
|
-
const key = m.key;
|
|
131
|
-
key.name = `${key.name}__${name}`;
|
|
132
|
-
}
|
|
133
|
-
m.body = core_1.types.addComment(m.body, "inner", "auto-generated: Please do not modify the.");
|
|
134
|
-
return m;
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* 获取调用的方法内的this方法
|
|
140
|
-
* @param modMethodNames - 模块所有方法名
|
|
141
|
-
* @param useMethodNames - 调用的方法名
|
|
142
|
-
* @param modAst - 模块AST
|
|
143
|
-
* @returns
|
|
144
|
-
*/
|
|
145
|
-
function getInlineThisMethodNames(modMethodNames, useMethodNames, modAst) {
|
|
146
|
-
if (!useMethodNames.length) {
|
|
147
|
-
return [];
|
|
148
|
-
}
|
|
149
|
-
const thisMethodNames = new Set();
|
|
150
|
-
(0, traverse_1.default)(modAst, {
|
|
151
|
-
ThisExpression(path) {
|
|
152
|
-
const objectMethod = path.findParent((path) => path.isObjectMethod());
|
|
153
|
-
const id = objectMethod === null || objectMethod === void 0 ? void 0 : objectMethod.node.key;
|
|
154
|
-
if (!core_1.types.isIdentifier(id)) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
if (useMethodNames.includes(id.name)) {
|
|
158
|
-
const memberExpression = path.findParent((path) => path.isMemberExpression());
|
|
159
|
-
const property = memberExpression === null || memberExpression === void 0 ? void 0 : memberExpression.node.property;
|
|
160
|
-
if (!core_1.types.isIdentifier(property)) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
if (modMethodNames.includes(property.name)) {
|
|
164
|
-
thisMethodNames.add(property.name);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
return [
|
|
170
|
-
...thisMethodNames,
|
|
171
|
-
...getInlineThisMethodNames(modMethodNames, [...thisMethodNames], modAst)
|
|
172
|
-
];
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* 获取所有依赖第三方模块路径
|
|
176
|
-
* @param curDir - 源码所在文件夹目录
|
|
177
|
-
* @param srcAst - 源码AST
|
|
178
|
-
* @param ignoreMod - 忽略模块
|
|
179
|
-
* @returns
|
|
180
|
-
*/
|
|
181
|
-
function getImportModPaths(curDir, srcAst, ignoreMod = IGNORE_MOD) {
|
|
182
|
-
const modPathByName = new Map();
|
|
183
|
-
(0, traverse_1.default)(srcAst, {
|
|
184
|
-
Identifier(nodePath) {
|
|
185
|
-
if (nodePath.node.name === "require") {
|
|
186
|
-
const callExpression = nodePath.findParent((path) => path.isCallExpression());
|
|
187
|
-
const args = callExpression === null || callExpression === void 0 ? void 0 : callExpression.node.arguments;
|
|
188
|
-
if ((args === null || args === void 0 ? void 0 : args.length) != 1) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
let modPath = args[0].value;
|
|
192
|
-
modPath = (0, scanf_1.scanfRequieMod)(curDir, modPath);
|
|
193
|
-
const variableDeclarator = nodePath.findParent((path) => path.isVariableDeclarator());
|
|
194
|
-
if (!variableDeclarator) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
const id = variableDeclarator.node.id;
|
|
198
|
-
const ignore = ignoreMod.includes(id.name);
|
|
199
|
-
ignore && console.log(`ignore => ${id.name}`);
|
|
200
|
-
!ignore && modPathByName.set(id.name, modPath);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
return modPathByName;
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* 获取源码中第三方模块方法名
|
|
208
|
-
* @param mod - 依赖模块
|
|
209
|
-
* @param srcAst - 源码AST
|
|
210
|
-
* @returns
|
|
211
|
-
*/
|
|
212
|
-
function getImportMethodNames(mod, srcAst) {
|
|
213
|
-
const methodsByMod = new Map();
|
|
214
|
-
(0, traverse_1.default)(srcAst, {
|
|
215
|
-
MemberExpression(path) {
|
|
216
|
-
const invokeObj = path.node.object;
|
|
217
|
-
if (!core_1.types.isIdentifier(invokeObj)) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
const invokeMethod = path.node.property;
|
|
221
|
-
if (!core_1.types.isIdentifier(invokeMethod)) {
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
const key = invokeObj.name;
|
|
225
|
-
if (!mod.includes(key)) {
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
let methods = [];
|
|
229
|
-
if (methodsByMod.has(key)) {
|
|
230
|
-
methods = methodsByMod.get(key);
|
|
231
|
-
}
|
|
232
|
-
!methods.includes(invokeMethod.name) && methods.push(invokeMethod.name);
|
|
233
|
-
methodsByMod.set(key, methods);
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
return methodsByMod;
|
|
237
|
-
}
|
|
238
|
-
/**
|
|
239
|
-
* 获取源码入口对象所有方法名
|
|
240
|
-
* @param entry - 入口对象
|
|
241
|
-
* @param srcAst - 源码Ast
|
|
242
|
-
* @returns
|
|
243
|
-
*/
|
|
244
|
-
function getSrcMethodNames(entry, srcAst) {
|
|
245
|
-
return getMethods(entry, srcAst)
|
|
246
|
-
.filter((node) => core_1.types.isIdentifier(node.key))
|
|
247
|
-
.map((node) => node.key)
|
|
248
|
-
.map((key) => key.name);
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* 获取源码入口对象所有方法
|
|
252
|
-
* todo: 重复获取方法
|
|
253
|
-
* @param entry - 入口对象
|
|
254
|
-
* @param ast - AST
|
|
255
|
-
* @returns
|
|
256
|
-
*/
|
|
257
|
-
function getMethods(entry, ast) {
|
|
258
|
-
const methods = [];
|
|
259
|
-
(0, traverse_1.default)(ast, {
|
|
260
|
-
Program(path) {
|
|
261
|
-
path.node.body.forEach((statement) => {
|
|
262
|
-
if (core_1.types.isVariableDeclaration(statement)) {
|
|
263
|
-
const variableDeclaration = statement;
|
|
264
|
-
variableDeclaration.declarations
|
|
265
|
-
.filter((declaration) => {
|
|
266
|
-
if (core_1.types.isIdentifier(declaration.id)) {
|
|
267
|
-
const id = declaration.id;
|
|
268
|
-
if (id.name === entry) {
|
|
269
|
-
return true;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
return false;
|
|
273
|
-
})
|
|
274
|
-
.forEach((declaration) => {
|
|
275
|
-
if (core_1.types.isObjectExpression(declaration.init)) {
|
|
276
|
-
const init = declaration.init;
|
|
277
|
-
const objectMethods = init.properties.filter((property) => core_1.types.isObjectMethod(property));
|
|
278
|
-
methods.push(...objectMethods);
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
});
|
|
285
|
-
return methods;
|
|
286
|
-
}
|
|
287
|
-
/**
|
|
288
|
-
* 修改源码第三方模块调用方法名和指向
|
|
289
|
-
* e.g. from util.func() to this.func__util()
|
|
290
|
-
* @param methodNames - 需调用方法
|
|
291
|
-
* @param importMod - 导入模块
|
|
292
|
-
* @param srcAst - AST
|
|
293
|
-
*/
|
|
294
|
-
function modifyCallObjectAndMethodNames(methodNames, importMod, srcAst) {
|
|
295
|
-
(0, traverse_1.default)(srcAst, {
|
|
296
|
-
MemberExpression(path) {
|
|
297
|
-
const objectMethod = path.findParent((path) => path.isObjectMethod());
|
|
298
|
-
if (!core_1.types.isIdentifier(objectMethod === null || objectMethod === void 0 ? void 0 : objectMethod.node.key)) {
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
if (!methodNames.includes((objectMethod === null || objectMethod === void 0 ? void 0 : objectMethod.node.key).name)) {
|
|
302
|
-
return;
|
|
303
|
-
}
|
|
304
|
-
if (core_1.types.isThisExpression(path.node.object)) {
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
if (!core_1.types.isIdentifier(path.node.object)) {
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
const name = path.node.object.name;
|
|
311
|
-
if (!importMod.includes(name)) {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
path.node.object = core_1.types.thisExpression();
|
|
315
|
-
if (!core_1.types.isIdentifier(path.node.property)) {
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
const property = path.node.property;
|
|
319
|
-
property.name = `${property.name}__${name}`;
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
/**
|
|
324
|
-
* 修改导入模块方法名
|
|
325
|
-
* e.g. from util.func() to this.func__util()
|
|
326
|
-
* @param mod - 模块名
|
|
327
|
-
* @param methodNames - 需调用方法
|
|
328
|
-
* @param modAst - AST
|
|
329
|
-
*/
|
|
330
|
-
function modifyModMethods(mod, methodNames, modAst) {
|
|
331
|
-
(0, traverse_1.default)(modAst, {
|
|
332
|
-
MemberExpression(path) {
|
|
333
|
-
if (core_1.types.isIdentifier(path.node.property)) {
|
|
334
|
-
const property = path.node.property;
|
|
335
|
-
if (methodNames.includes(property.name)) {
|
|
336
|
-
if (core_1.types.isIdentifier(path.node.object) ||
|
|
337
|
-
core_1.types.isThisExpression(path.node.object)) {
|
|
338
|
-
if (core_1.types.isIdentifier(path.node.object)) {
|
|
339
|
-
const object = path.node.object;
|
|
340
|
-
if (object.name !== mod) {
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
property.name = `${property.name}__${mod}`;
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
function refreshCustomConfig(modPathByName, inPath, workDir = WORK_DIR, custConfig = CUSTOM_CONFIG) {
|
|
352
|
-
const configPath = path_1.default.join(inPath, workDir, custConfig);
|
|
353
|
-
let configObj = {
|
|
354
|
-
mod: []
|
|
355
|
-
};
|
|
356
|
-
try {
|
|
357
|
-
mkWorkDir(inPath);
|
|
358
|
-
fs_1.default.accessSync(configPath, fs_1.default.constants.F_OK);
|
|
359
|
-
const data = fs_1.default.readFileSync(configPath, { encoding: "utf-8" });
|
|
360
|
-
configObj = JSON.parse(data);
|
|
361
|
-
}
|
|
362
|
-
catch (err) {
|
|
363
|
-
console.log(`not found custom config => ${configPath}`);
|
|
364
|
-
}
|
|
365
|
-
configObj.mod = [...modPathByName.entries()].map(([key, value]) => new config_1.Config.Mod(key, value));
|
|
366
|
-
fs_1.default.writeFileSync(configPath, JSON.stringify(configObj, null, 4), "utf-8");
|
|
367
|
-
}
|
|
368
|
-
function mkWorkDir(inPath, workDir = WORK_DIR) {
|
|
369
|
-
const workDirPath = path_1.default.join(inPath, workDir);
|
|
370
|
-
try {
|
|
371
|
-
fs_1.default.accessSync(workDirPath);
|
|
372
|
-
}
|
|
373
|
-
catch (err) {
|
|
374
|
-
fs_1.default.mkdirSync(workDirPath);
|
|
375
|
-
}
|
|
376
|
-
}
|