js-code-detector 0.0.20 → 0.0.22
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/cjs/index.d.ts +2 -0
- package/dist/cjs/index.js +16 -12
- package/dist/cjs/util/ast_util/AstUtil.d.ts +10 -5
- package/dist/cjs/util/ast_util/AstUtil.js +170 -132
- package/dist/cjs/util/ast_util/FileUtil.js +8 -2
- package/dist/cjs/util/ast_util/getAstKitByFilePath.js +1 -1
- package/dist/cjs/util/report_util/createMdByJson.js +11 -9
- package/dist/cjs/util/report_util/diffBlockDetect.js +3 -2
- package/dist/cjs/util/report_util/generateGitDiffReport.d.ts +3 -0
- package/dist/cjs/util/report_util/generateGitDiffReport.js +145 -0
- package/dist/cjs/util/report_util/getMadgeInstance.d.ts +1 -0
- package/dist/cjs/util/report_util/getMadgeInstance.js +66 -0
- package/dist/cjs/util/report_util.d.ts +2 -1
- package/dist/cjs/util/report_util.js +11 -6
- package/package.json +2 -2
- package/dist/cjs/util/report_util/code_block_detect.d.ts +0 -32
- package/dist/cjs/util/report_util/code_block_detect.js +0 -277
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare const gitDiffFileName = "git_diff.txt";
|
|
2
|
+
export declare const gitDiffJsonName = "git_diff.json";
|
|
1
3
|
export declare function umiPluginCallback(api: any): Promise<void>;
|
|
2
4
|
export declare function writeGitDiffTxt(gitUrl: string, branchName: string): Promise<string>;
|
|
3
5
|
export declare function getGitRepositoryAndBranch(): Promise<{
|
package/dist/cjs/index.js
CHANGED
|
@@ -33,6 +33,8 @@ __export(src_exports, {
|
|
|
33
33
|
getEslintCheckResult: () => getEslintCheckResult,
|
|
34
34
|
getGitRepositoryAndBranch: () => getGitRepositoryAndBranch,
|
|
35
35
|
gitDiffDetect: () => gitDiffDetect,
|
|
36
|
+
gitDiffFileName: () => gitDiffFileName,
|
|
37
|
+
gitDiffJsonName: () => gitDiffJsonName,
|
|
36
38
|
sameCodeDetect: () => sameCodeDetect,
|
|
37
39
|
umiPluginCallback: () => umiPluginCallback,
|
|
38
40
|
writeGitDiffTxt: () => writeGitDiffTxt
|
|
@@ -51,6 +53,7 @@ var import_readDirFiles = require("./util/shared/readDirFiles");
|
|
|
51
53
|
var import_Core = __toESM(require("./util/ast_util/Core"));
|
|
52
54
|
var import_constants = require("./util/constants");
|
|
53
55
|
var import_await_to_js = __toESM(require("await-to-js"));
|
|
56
|
+
var import_generateGitDiffReport = require("./util/report_util/generateGitDiffReport");
|
|
54
57
|
var jsonName = "git_diff_report.md";
|
|
55
58
|
var gitDiffFileName = "git_diff.txt";
|
|
56
59
|
var gitDiffJsonName = "git_diff.json";
|
|
@@ -136,30 +139,29 @@ async function gitDiffDetect() {
|
|
|
136
139
|
import_utils.logger.ready("准备生成临时工作目录...");
|
|
137
140
|
await import_utils.execa.execa(`mkdir -p ${today}`, { shell: "/bin/bash" });
|
|
138
141
|
import_utils.logger.info("临时目录建立完成");
|
|
139
|
-
import_utils.logger.ready(
|
|
140
|
-
await import_utils.execa.execa(`git clone ${gitUrl} ${today}
|
|
142
|
+
import_utils.logger.ready(`准备clone源代码到临时目录下的 ${import_constants.TARGET} 文件夹`);
|
|
143
|
+
await import_utils.execa.execa(`git clone ${gitUrl} ${today}/${import_constants.TARGET}`, { shell: "/bin/bash" });
|
|
141
144
|
import_utils.logger.info("源代码clone完成");
|
|
142
145
|
import_utils.logger.ready(`准备clone源代码到临时目录下的 ${import_constants.SOURCE} 文件夹`);
|
|
143
146
|
await import_utils.execa.execa(`git clone ${gitUrl} ${today}/${import_constants.SOURCE}`, { shell: "/bin/bash" });
|
|
144
147
|
import_utils.logger.info("源代码clone完成");
|
|
145
148
|
import_utils.logger.ready("准备切换到目标分支");
|
|
146
|
-
await import_utils.execa.execa(`cd ${today}
|
|
149
|
+
await import_utils.execa.execa(`cd ${today}/${import_constants.TARGET} && git fetch origin ${branchName}:${branchName} && git checkout ${branchName}`, { shell: "/bin/bash" });
|
|
147
150
|
import_utils.logger.info("分支切换完成");
|
|
148
151
|
import_utils.logger.ready("准备生成git_diff.txt文件");
|
|
149
|
-
await import_utils.execa.execa(`cd ${today}
|
|
152
|
+
await import_utils.execa.execa(`cd ${today}/${import_constants.TARGET} && git diff master..${branchName} --unified=0 --output=${gitDiffFileName}`, { shell: "/bin/bash" });
|
|
150
153
|
import_utils.logger.info("git_diff.txt文件生成完成");
|
|
151
|
-
import_utils.logger.
|
|
152
|
-
|
|
153
|
-
import_utils.logger.info("
|
|
154
|
-
import_utils.logger.
|
|
155
|
-
await
|
|
156
|
-
import_utils.logger.info("
|
|
154
|
+
import_utils.logger.wait("准备生成 入口文件");
|
|
155
|
+
await import_utils.execa.execa(`cd ${today}/${import_constants.TARGET} && npx max setup`, { shell: "/bin/bash" });
|
|
156
|
+
import_utils.logger.info("入口文件 生成完成!");
|
|
157
|
+
import_utils.logger.ready("准备生成报告");
|
|
158
|
+
await (0, import_generateGitDiffReport.generateGitDiffReport)({ targetDirPath: (0, import_path.join)(process.cwd(), today, "target") });
|
|
159
|
+
import_utils.logger.info("报告完成");
|
|
157
160
|
import_utils.logger.ready("准备移动报告");
|
|
158
|
-
const content = (0, import_fs.readFileSync)((0, import_path.join)(process.cwd(), today,
|
|
161
|
+
const content = (0, import_fs.readFileSync)((0, import_path.join)(process.cwd(), today, import_constants.TARGET, jsonName), "utf-8");
|
|
159
162
|
const mdFileName = `${(0, import_dayjs.default)().format("YYYYMDD_HHmm")}_${jsonName}`;
|
|
160
163
|
(0, import_fs2.writeFileSync)((0, import_path.join)(process.cwd(), mdFileName), content, { encoding: "utf-8", flag: "w" });
|
|
161
164
|
import_utils.logger.info("报告完成: " + mdFileName);
|
|
162
|
-
await getEslintCheckResult(today);
|
|
163
165
|
(0, import_utils.rimraf)((0, import_path.join)(process.cwd(), today), () => {
|
|
164
166
|
import_utils.logger.info("临时目录已删除");
|
|
165
167
|
});
|
|
@@ -192,6 +194,8 @@ async function getEslintCheckResult(today) {
|
|
|
192
194
|
getEslintCheckResult,
|
|
193
195
|
getGitRepositoryAndBranch,
|
|
194
196
|
gitDiffDetect,
|
|
197
|
+
gitDiffFileName,
|
|
198
|
+
gitDiffJsonName,
|
|
195
199
|
sameCodeDetect,
|
|
196
200
|
umiPluginCallback,
|
|
197
201
|
writeGitDiffTxt
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export interface AstNode {
|
|
2
2
|
computed?: boolean;
|
|
3
3
|
type: string;
|
|
4
|
-
name?: string;
|
|
4
|
+
name?: string | AstNode;
|
|
5
5
|
start?: number | null;
|
|
6
6
|
end?: number | null;
|
|
7
7
|
loc?: Record<'start' | 'end', {
|
|
@@ -25,21 +25,27 @@ export interface AstNode {
|
|
|
25
25
|
uuid: string;
|
|
26
26
|
variableScope: AstNode[];
|
|
27
27
|
dependenceIds: Set<AstNode>;
|
|
28
|
+
dependenceIdsNoScope: Set<AstNode>;
|
|
28
29
|
holdingIds: Set<AstNode>;
|
|
29
30
|
holdingIdNameMap: Map<string, Set<AstNode>>;
|
|
30
31
|
holdingIdType: 'Import' | 'Variable' | 'Function' | 'Class' | 'Param' | null;
|
|
31
32
|
inject: Set<AstNode>;
|
|
32
33
|
provide: Set<AstNode>;
|
|
33
34
|
effectIds: Set<AstNode>;
|
|
35
|
+
occupation: Set<AstNode>;
|
|
34
36
|
};
|
|
35
37
|
}
|
|
36
38
|
export default class AstUtil {
|
|
37
39
|
static invalidNodeKey: string[];
|
|
38
40
|
static getNodePath(node: AstNode): string;
|
|
39
|
-
static getShortNodeMsg(node: AstNode): string;
|
|
41
|
+
static getShortNodeMsg(node: AstNode, hideParentProperty?: boolean): string;
|
|
42
|
+
static getAncestorsFromBirth(occupationId: AstNode, sourceId: AstNode): AstNode[];
|
|
43
|
+
static getNearestImpactedNode(ancestors: AstNode[]): AstNode | undefined;
|
|
44
|
+
private static getImpactedNode;
|
|
40
45
|
static deepFirstTravel(node: AstNode, filePath: string, mapUuidToNode: Map<string, AstNode>, mapFileLineToNodeSet: Map<number, Set<AstNode>>, mapPathToNodeSet: Map<string, Set<AstNode>>): AstNode | undefined;
|
|
41
46
|
private static _deepFirstTravel;
|
|
42
47
|
private static collectInjectAndProvide;
|
|
48
|
+
private static handleDeclaration;
|
|
43
49
|
private static collectHoldingIds;
|
|
44
50
|
private static isVarInit;
|
|
45
51
|
static isReturnArgument(node: AstNode): boolean;
|
|
@@ -58,11 +64,10 @@ export default class AstUtil {
|
|
|
58
64
|
private static isBodyArray;
|
|
59
65
|
private static findExportIdentifiers;
|
|
60
66
|
private static expressionTypeIsIdentifier;
|
|
67
|
+
static collectExpressionIdentifiersShallow(exp: AstNode | null, callback: (identifier: AstNode) => void): void;
|
|
68
|
+
private static _collectExpressionIdentifiersShallow;
|
|
61
69
|
static collectExpressionIdentifiers(exp: AstNode | null, callback: (identifier: AstNode) => void): void;
|
|
62
70
|
private static _collectExpressionIdentifiers;
|
|
63
|
-
static deepFindIdOfExpression(exp: AstNode | null, callback: (identifier: AstNode) => void): void;
|
|
64
|
-
private static _deepFindIdOfExpression;
|
|
65
|
-
private static getRootIdentifierOfMemberExpression;
|
|
66
71
|
private static findIdOfImport;
|
|
67
72
|
private static findIdOfVariable;
|
|
68
73
|
private static _deepFindIdentifier;
|
|
@@ -28,9 +28,63 @@ var _AstUtil = class {
|
|
|
28
28
|
static getNodePath(node) {
|
|
29
29
|
return [...node._util.ancestors, node].map((n) => n.type).join(":") + ":" + node.name;
|
|
30
30
|
}
|
|
31
|
-
static getShortNodeMsg(node) {
|
|
32
|
-
const { _util: { startLine, startColumn, endLine, endColumn } } = node;
|
|
33
|
-
|
|
31
|
+
static getShortNodeMsg(node, hideParentProperty = false) {
|
|
32
|
+
const { _util: { startLine, startColumn, endLine, endColumn, parentProperty, indexOfProperty } } = node;
|
|
33
|
+
let type = node.type;
|
|
34
|
+
let name = node.name;
|
|
35
|
+
if (name && typeof name === "object") {
|
|
36
|
+
type = name.type;
|
|
37
|
+
name = name.name;
|
|
38
|
+
}
|
|
39
|
+
const msg = [
|
|
40
|
+
hideParentProperty ? [] : [parentProperty, indexOfProperty !== null ? String(indexOfProperty) : null],
|
|
41
|
+
[type, name]
|
|
42
|
+
].map((e) => e.filter(Boolean).join(":")).filter(Boolean).join(" ");
|
|
43
|
+
return `${msg}「${startLine}:${startColumn}, ${endLine}:${endColumn}」`;
|
|
44
|
+
}
|
|
45
|
+
static getAncestorsFromBirth(occupationId, sourceId) {
|
|
46
|
+
const { _util: { ancestors } } = occupationId;
|
|
47
|
+
return ancestors.filter((ancestor) => !sourceId._util.ancestors.includes(ancestor));
|
|
48
|
+
}
|
|
49
|
+
static getNearestImpactedNode(ancestors) {
|
|
50
|
+
for (const ancestor of ancestors) {
|
|
51
|
+
const impactedNode = this.getImpactedNode(ancestor);
|
|
52
|
+
if (impactedNode) {
|
|
53
|
+
return impactedNode;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
static getImpactedNode(ancestor) {
|
|
58
|
+
const { type } = ancestor;
|
|
59
|
+
if (type === "JSXOpeningElement") {
|
|
60
|
+
const { name } = ancestor.name;
|
|
61
|
+
if (name && typeof name === "object") {
|
|
62
|
+
const realName = name.name;
|
|
63
|
+
if (!this.intrinsicElements.includes(realName)) {
|
|
64
|
+
return name;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (type === "JSXElement") {
|
|
69
|
+
const { openingElement } = ancestor;
|
|
70
|
+
const { name } = openingElement;
|
|
71
|
+
if (name && typeof name === "object") {
|
|
72
|
+
const realName = name.name;
|
|
73
|
+
if (!this.intrinsicElements.includes(realName)) {
|
|
74
|
+
return name;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (type === "VariableDeclarator") {
|
|
79
|
+
return ancestor.id;
|
|
80
|
+
}
|
|
81
|
+
if (type === "AssignmentExpression") {
|
|
82
|
+
return ancestor.left;
|
|
83
|
+
}
|
|
84
|
+
if (type === "FunctionDeclaration") {
|
|
85
|
+
return ancestor.id || ancestor;
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
34
88
|
}
|
|
35
89
|
static deepFirstTravel(node, filePath, mapUuidToNode, mapFileLineToNodeSet, mapPathToNodeSet) {
|
|
36
90
|
const visitedNodeSet = /* @__PURE__ */ new Set();
|
|
@@ -57,12 +111,14 @@ var _AstUtil = class {
|
|
|
57
111
|
uuid: "",
|
|
58
112
|
variableScope: [],
|
|
59
113
|
dependenceIds: /* @__PURE__ */ new Set(),
|
|
114
|
+
dependenceIdsNoScope: /* @__PURE__ */ new Set(),
|
|
60
115
|
holdingIdType: null,
|
|
61
116
|
holdingIds: /* @__PURE__ */ new Set(),
|
|
62
117
|
holdingIdNameMap: /* @__PURE__ */ new Map(),
|
|
63
118
|
inject: /* @__PURE__ */ new Set(),
|
|
64
119
|
provide: /* @__PURE__ */ new Set(),
|
|
65
|
-
effectIds: /* @__PURE__ */ new Set()
|
|
120
|
+
effectIds: /* @__PURE__ */ new Set(),
|
|
121
|
+
occupation: /* @__PURE__ */ new Set()
|
|
66
122
|
};
|
|
67
123
|
node._util = _util;
|
|
68
124
|
const { nodeCollection, children } = _util;
|
|
@@ -137,6 +193,18 @@ var _AstUtil = class {
|
|
|
137
193
|
}
|
|
138
194
|
});
|
|
139
195
|
}
|
|
196
|
+
static handleDeclaration(node, callback) {
|
|
197
|
+
if (node.type === "FunctionDeclaration" || node.type === "ClassDeclaration") {
|
|
198
|
+
const id = node.id;
|
|
199
|
+
if (id) {
|
|
200
|
+
callback(id);
|
|
201
|
+
}
|
|
202
|
+
} else if (node.type === "VariableDeclaration") {
|
|
203
|
+
this.findIdOfVariable(node, (id) => {
|
|
204
|
+
callback(id);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
140
208
|
static collectHoldingIds(node) {
|
|
141
209
|
const { holdingIds, holdingIdNameMap } = node._util;
|
|
142
210
|
if (this.isBodyArray(node)) {
|
|
@@ -149,18 +217,33 @@ var _AstUtil = class {
|
|
|
149
217
|
id._util.holdingIdType = "Import";
|
|
150
218
|
});
|
|
151
219
|
} else if (cur.type === "FunctionDeclaration" || cur.type === "ClassDeclaration") {
|
|
152
|
-
|
|
153
|
-
if (id) {
|
|
220
|
+
this.handleDeclaration(cur, (id) => {
|
|
154
221
|
holdingIds.add(id);
|
|
155
222
|
id._util.variableScope = [id];
|
|
156
223
|
id._util.holdingIdType = cur.type === "ClassDeclaration" ? "Class" : "Function";
|
|
157
|
-
}
|
|
224
|
+
});
|
|
158
225
|
} else if (cur.type === "VariableDeclaration") {
|
|
159
|
-
this.
|
|
226
|
+
this.handleDeclaration(cur, (id) => {
|
|
160
227
|
holdingIds.add(id);
|
|
161
228
|
id._util.variableScope = [id];
|
|
162
229
|
id._util.holdingIdType = "Variable";
|
|
163
230
|
});
|
|
231
|
+
} else if (cur.type === "ExportDefaultDeclaration") {
|
|
232
|
+
const declaration = cur.declaration;
|
|
233
|
+
this.handleDeclaration(declaration, (id) => {
|
|
234
|
+
holdingIds.add(id);
|
|
235
|
+
id._util.variableScope = [id];
|
|
236
|
+
id._util.holdingIdType = cur.type === "ClassDeclaration" ? "Class" : "Function";
|
|
237
|
+
});
|
|
238
|
+
} else if (cur.type === "ExportNamedDeclaration") {
|
|
239
|
+
const { declaration } = cur;
|
|
240
|
+
if (declaration) {
|
|
241
|
+
this.handleDeclaration(declaration, (id) => {
|
|
242
|
+
holdingIds.add(id);
|
|
243
|
+
id._util.variableScope = [id];
|
|
244
|
+
id._util.holdingIdType = "Variable";
|
|
245
|
+
});
|
|
246
|
+
}
|
|
164
247
|
}
|
|
165
248
|
});
|
|
166
249
|
}
|
|
@@ -183,9 +266,8 @@ var _AstUtil = class {
|
|
|
183
266
|
}
|
|
184
267
|
});
|
|
185
268
|
}
|
|
186
|
-
if (["FunctionDeclaration", "ArrowFunctionExpression", "FunctionExpression"].includes(node.type)) {
|
|
187
|
-
|
|
188
|
-
params.forEach((param) => this._deepFindIdentifier(param, (id) => {
|
|
269
|
+
if (["FunctionDeclaration", "ArrowFunctionExpression", "FunctionExpression", "ObjectMethod", "ClassMethod"].includes(node.type)) {
|
|
270
|
+
node.params.forEach((param) => this._deepFindIdentifier(param, (id) => {
|
|
189
271
|
holdingIds.add(id || node);
|
|
190
272
|
id._util.variableScope = [id];
|
|
191
273
|
id._util.holdingIdType = "Param";
|
|
@@ -193,6 +275,8 @@ var _AstUtil = class {
|
|
|
193
275
|
}
|
|
194
276
|
holdingIds.forEach((holdingId) => {
|
|
195
277
|
const holdingIdName = holdingId.name;
|
|
278
|
+
if (typeof holdingIdName !== "string")
|
|
279
|
+
return;
|
|
196
280
|
const nodeSetOfIdName = holdingIdNameMap.get(holdingIdName) || /* @__PURE__ */ new Set();
|
|
197
281
|
nodeSetOfIdName.add(holdingId);
|
|
198
282
|
holdingIdNameMap.set(holdingIdName, nodeSetOfIdName);
|
|
@@ -207,20 +291,26 @@ var _AstUtil = class {
|
|
|
207
291
|
return node._util.parentProperty === "argument" && ((_a = node._util.parent) == null ? void 0 : _a.type) === "ReturnStatement";
|
|
208
292
|
}
|
|
209
293
|
static collectDependenceIds(node) {
|
|
210
|
-
const {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
294
|
+
const { _util } = node;
|
|
295
|
+
const { dependenceIds, holdingIdNameMap, children, dependenceIdsNoScope } = _util;
|
|
296
|
+
children.forEach((child) => {
|
|
297
|
+
if (child._util.dependenceIdsNoScope.size > 0) {
|
|
298
|
+
child._util.dependenceIdsNoScope.forEach((id) => dependenceIds.add(id));
|
|
299
|
+
}
|
|
300
|
+
this.findExportIdentifiers(child, (id) => dependenceIds.add(id));
|
|
301
|
+
this.collectExpressionIdentifiersShallow(child, (id) => dependenceIds.add(id));
|
|
214
302
|
});
|
|
215
303
|
for (const dependenceId of dependenceIds) {
|
|
216
|
-
if (dependenceId._util.variableScope.length === 0) {
|
|
217
|
-
|
|
218
|
-
dependenceId._util.variableScope
|
|
219
|
-
const firstPick = sameNameIds[0];
|
|
304
|
+
if (dependenceId._util.variableScope.length === 0 && typeof dependenceId.name === "string" && holdingIdNameMap.has(dependenceId.name)) {
|
|
305
|
+
dependenceId._util.variableScope.push(...[...holdingIdNameMap.get(dependenceId.name)]);
|
|
306
|
+
const firstPick = dependenceId._util.variableScope[0];
|
|
220
307
|
if (firstPick && firstPick._util.uuid !== dependenceId._util.uuid) {
|
|
221
|
-
firstPick._util.
|
|
308
|
+
firstPick._util.occupation.add(dependenceId);
|
|
222
309
|
}
|
|
223
310
|
}
|
|
311
|
+
if (dependenceId._util.variableScope.length === 0) {
|
|
312
|
+
dependenceIdsNoScope.add(dependenceId);
|
|
313
|
+
}
|
|
224
314
|
}
|
|
225
315
|
}
|
|
226
316
|
static isUseStateVarDec(node) {
|
|
@@ -235,7 +325,7 @@ var _AstUtil = class {
|
|
|
235
325
|
static isUseMemoVarDec(node) {
|
|
236
326
|
if (node.type !== "VariableDeclarator")
|
|
237
327
|
return false;
|
|
238
|
-
const {
|
|
328
|
+
const { init } = node;
|
|
239
329
|
if (init.type !== "CallExpression")
|
|
240
330
|
return false;
|
|
241
331
|
const { callee } = init;
|
|
@@ -244,7 +334,7 @@ var _AstUtil = class {
|
|
|
244
334
|
static isUseCallbackVarDec(node) {
|
|
245
335
|
if (node.type !== "VariableDeclarator")
|
|
246
336
|
return false;
|
|
247
|
-
const {
|
|
337
|
+
const { init } = node;
|
|
248
338
|
if (init.type !== "CallExpression")
|
|
249
339
|
return false;
|
|
250
340
|
const { callee } = init;
|
|
@@ -270,7 +360,7 @@ var _AstUtil = class {
|
|
|
270
360
|
}
|
|
271
361
|
}
|
|
272
362
|
static collectEffectIdOfFnCall(node) {
|
|
273
|
-
var _a, _b
|
|
363
|
+
var _a, _b;
|
|
274
364
|
if (node.type !== "CallExpression") {
|
|
275
365
|
return;
|
|
276
366
|
}
|
|
@@ -286,14 +376,29 @@ var _AstUtil = class {
|
|
|
286
376
|
const fnNode = scopeId._util.parent;
|
|
287
377
|
if (fnNode.type === "FunctionExpression" || fnNode.type === "ArrowFunctionExpression") {
|
|
288
378
|
if (fnNode._util.parentProperty === "init" && ((_a = fnNode._util.parent) == null ? void 0 : _a.type) === "VariableDeclarator") {
|
|
289
|
-
fnNode._util.parent.id
|
|
379
|
+
const fnId = fnNode._util.parent.id;
|
|
380
|
+
if (fnId) {
|
|
381
|
+
fnId._util.effectIds.add(id);
|
|
382
|
+
} else {
|
|
383
|
+
fnNode._util.effectIds.add(id);
|
|
384
|
+
}
|
|
290
385
|
} else if (fnNode._util.parentProperty === "right" && ((_b = fnNode._util.parent) == null ? void 0 : _b.type) === "AssignmentExpression") {
|
|
291
386
|
fnNode._util.parent.left._util.effectIds.add(id);
|
|
292
|
-
} else if (fnNode._util.parentProperty === "value" && ((_c = fnNode._util.parent) == null ? void 0 : _c.type) === "MethodDefinition") {
|
|
293
|
-
fnNode._util.parent.key._util.effectIds.add(id);
|
|
294
387
|
}
|
|
295
388
|
} else if (fnNode.type === "FunctionDeclaration") {
|
|
296
|
-
fnNode
|
|
389
|
+
const { id: fnId } = fnNode;
|
|
390
|
+
if (fnId) {
|
|
391
|
+
fnId._util.effectIds.add(id);
|
|
392
|
+
} else {
|
|
393
|
+
fnNode._util.effectIds.add(id);
|
|
394
|
+
}
|
|
395
|
+
} else if (fnNode.type === "ClassMethod") {
|
|
396
|
+
const { key: fnId } = fnNode;
|
|
397
|
+
if (fnId) {
|
|
398
|
+
fnId._util.effectIds.add(id);
|
|
399
|
+
} else {
|
|
400
|
+
fnNode._util.effectIds.add(id);
|
|
401
|
+
}
|
|
297
402
|
}
|
|
298
403
|
}
|
|
299
404
|
const kindOfParamsElement = [...scopeId._util.effectIds].filter((e) => {
|
|
@@ -325,12 +430,12 @@ var _AstUtil = class {
|
|
|
325
430
|
this.collectEffectIdOfUseCallback(node);
|
|
326
431
|
return;
|
|
327
432
|
}
|
|
328
|
-
const
|
|
329
|
-
this._deepFindIdentifier(id, (ele) =>
|
|
330
|
-
const
|
|
331
|
-
["Identifier", "ArrowFunctionExpression", "FunctionExpression"].includes(init.type) ?
|
|
332
|
-
for (const
|
|
333
|
-
|
|
433
|
+
const leftIdSet = /* @__PURE__ */ new Set();
|
|
434
|
+
this._deepFindIdentifier(id, (ele) => leftIdSet.add(ele));
|
|
435
|
+
const rightIdSet = /* @__PURE__ */ new Set();
|
|
436
|
+
["Identifier", "ArrowFunctionExpression", "FunctionExpression"].includes(init.type) ? rightIdSet.add(init) : this.collectExpressionIdentifiers(init, (id2) => rightIdSet.add(id2));
|
|
437
|
+
for (const item of leftIdSet) {
|
|
438
|
+
item._util.effectIds = /* @__PURE__ */ new Set([...rightIdSet, ...item._util.effectIds]);
|
|
334
439
|
}
|
|
335
440
|
}
|
|
336
441
|
static collectEffectIdOfUseState(node) {
|
|
@@ -374,20 +479,13 @@ var _AstUtil = class {
|
|
|
374
479
|
}
|
|
375
480
|
static collectEffectIdOfAssign(node) {
|
|
376
481
|
const { left, right } = node;
|
|
482
|
+
const idSetOfLeft = /* @__PURE__ */ new Set();
|
|
483
|
+
this.collectExpressionIdentifiers(left, (id) => idSetOfLeft.add(id));
|
|
377
484
|
const idSetOfRight = /* @__PURE__ */ new Set();
|
|
378
485
|
this.collectExpressionIdentifiers(right, (id) => idSetOfRight.add(id));
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
left2._util.effectIds = /* @__PURE__ */ new Set([...idSetOfRight, ...left2._util.effectIds]);
|
|
382
|
-
} else {
|
|
383
|
-
const { left: left2 } = node;
|
|
384
|
-
const idSetOfLeft = /* @__PURE__ */ new Set();
|
|
385
|
-
this.collectExpressionIdentifiers(left2, (id) => idSetOfLeft.add(id));
|
|
386
|
-
for (const id of idSetOfLeft) {
|
|
387
|
-
id._util.effectIds = /* @__PURE__ */ new Set([...idSetOfRight, ...id._util.effectIds]);
|
|
388
|
-
}
|
|
486
|
+
for (const id of idSetOfLeft) {
|
|
487
|
+
id._util.effectIds = /* @__PURE__ */ new Set([...idSetOfRight, ...id._util.effectIds]);
|
|
389
488
|
}
|
|
390
|
-
;
|
|
391
489
|
}
|
|
392
490
|
static collectEffectIdOfUnaryUpdate(node) {
|
|
393
491
|
const { argument } = node;
|
|
@@ -418,13 +516,13 @@ var _AstUtil = class {
|
|
|
418
516
|
static expressionTypeIsIdentifier(exp) {
|
|
419
517
|
return (exp == null ? void 0 : exp.type) === "Identifier";
|
|
420
518
|
}
|
|
421
|
-
static
|
|
519
|
+
static collectExpressionIdentifiersShallow(exp, callback) {
|
|
422
520
|
if (!exp || exp.type === "ThisExpression") {
|
|
423
521
|
return;
|
|
424
522
|
}
|
|
425
|
-
this.
|
|
523
|
+
this._collectExpressionIdentifiersShallow(exp, callback);
|
|
426
524
|
}
|
|
427
|
-
static
|
|
525
|
+
static _collectExpressionIdentifiersShallow(exp, callback) {
|
|
428
526
|
var _a, _b, _c;
|
|
429
527
|
if (!exp || exp.type === "ThisExpression") {
|
|
430
528
|
return;
|
|
@@ -446,100 +544,36 @@ var _AstUtil = class {
|
|
|
446
544
|
callback(exp);
|
|
447
545
|
return;
|
|
448
546
|
}
|
|
449
|
-
exp._util.nodeCollection.forEach((ele) => this._collectExpressionIdentifiers(ele, callback));
|
|
450
547
|
}
|
|
451
|
-
static
|
|
548
|
+
static collectExpressionIdentifiers(exp, callback) {
|
|
452
549
|
if (!exp || exp.type === "ThisExpression") {
|
|
453
550
|
return;
|
|
454
551
|
}
|
|
455
|
-
this.
|
|
552
|
+
this._collectExpressionIdentifiers(exp, callback);
|
|
456
553
|
}
|
|
457
|
-
static
|
|
458
|
-
var _a;
|
|
554
|
+
static _collectExpressionIdentifiers(exp, callback) {
|
|
555
|
+
var _a, _b, _c;
|
|
459
556
|
if (!exp || exp.type === "ThisExpression") {
|
|
460
557
|
return;
|
|
461
558
|
}
|
|
462
|
-
if (exp.
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
this._deepFindIdOfExpression(block, callback);
|
|
470
|
-
finalizer && this._deepFindIdOfExpression(finalizer, callback);
|
|
471
|
-
} else if (exp.type === "SpreadElement") {
|
|
472
|
-
const { argument } = exp;
|
|
473
|
-
this.expressionTypeIsIdentifier(argument) && callback(argument);
|
|
474
|
-
} else if (exp.type === "JSXSpreadChild") {
|
|
475
|
-
const expression = exp.expression;
|
|
476
|
-
callback(expression);
|
|
477
|
-
} else if (exp.type === "MemberExpression" || exp.type === "JSXMemberExpression") {
|
|
478
|
-
const rootIdentifier = this.getRootIdentifierOfMemberExpression(exp);
|
|
479
|
-
this.expressionTypeIsIdentifier(rootIdentifier) && callback(rootIdentifier);
|
|
480
|
-
} else if (exp.type === "ObjectExpression") {
|
|
481
|
-
const properties = exp.properties;
|
|
482
|
-
for (const property of properties) {
|
|
483
|
-
if (property.type === "SpreadElement") {
|
|
484
|
-
this._deepFindIdOfExpression(property, callback);
|
|
485
|
-
} else {
|
|
486
|
-
const value = property.value;
|
|
487
|
-
this.expressionTypeIsIdentifier(value) ? callback(value) : this._deepFindIdOfExpression(value, callback);
|
|
559
|
+
if (exp._util.holdingIdType !== null) {
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
562
|
+
if (exp.type === "Identifier") {
|
|
563
|
+
if (exp._util.parentProperty === "property" || exp._util.parentProperty === "key") {
|
|
564
|
+
if (exp._util.parent.computed) {
|
|
565
|
+
callback(exp);
|
|
488
566
|
}
|
|
567
|
+
} else if (!((_b = (_a = exp._util.parent) == null ? void 0 : _a.type) == null ? void 0 : _b.startsWith("TS"))) {
|
|
568
|
+
callback(exp);
|
|
489
569
|
}
|
|
490
|
-
|
|
491
|
-
const elements = exp.elements;
|
|
492
|
-
for (const element of elements) {
|
|
493
|
-
this.expressionTypeIsIdentifier(element) ? callback(element) : this._deepFindIdOfExpression(element, callback);
|
|
494
|
-
}
|
|
495
|
-
} else if (exp.type === "ArrowFunctionExpression") {
|
|
496
|
-
const body = exp.body;
|
|
497
|
-
this.expressionTypeIsIdentifier(body) ? callback(body) : this._deepFindIdOfExpression(body, callback);
|
|
498
|
-
} else if (exp.type === "CallExpression") {
|
|
499
|
-
const callee = exp.callee;
|
|
500
|
-
this.expressionTypeIsIdentifier(callee) ? callback(callee) : this._deepFindIdOfExpression(callee, callback);
|
|
501
|
-
const args = exp.arguments;
|
|
502
|
-
for (const argument of args) {
|
|
503
|
-
this.expressionTypeIsIdentifier(argument) ? callback(argument) : this._deepFindIdOfExpression(argument, callback);
|
|
504
|
-
}
|
|
505
|
-
} else if (exp.type === "AssignmentExpression" || exp.type === "BinaryExpression" || exp.type === "LogicalExpression") {
|
|
506
|
-
const { left, right } = exp;
|
|
507
|
-
[left, right].forEach((e) => this.expressionTypeIsIdentifier(e) ? callback(e) : this._deepFindIdOfExpression(e, callback));
|
|
508
|
-
} else if (exp.type === "UpdateExpression") {
|
|
509
|
-
const argument = exp.argument;
|
|
510
|
-
this.expressionTypeIsIdentifier(argument) ? callback(argument) : this._deepFindIdOfExpression(argument, callback);
|
|
511
|
-
} else if (exp.type === "SequenceExpression") {
|
|
512
|
-
const { expressions } = exp;
|
|
513
|
-
for (const expression of expressions) {
|
|
514
|
-
this.expressionTypeIsIdentifier(expression) ? callback(expression) : this._deepFindIdOfExpression(expression, callback);
|
|
515
|
-
}
|
|
516
|
-
} else if (exp.type === "ConditionalExpression") {
|
|
517
|
-
const { test, consequent, alternate } = exp;
|
|
518
|
-
[test, consequent, alternate].forEach((e) => this._deepFindIdOfExpression(e, callback));
|
|
519
|
-
} else if (exp.type === "JSXExpressionContainer") {
|
|
520
|
-
const { expression } = exp;
|
|
521
|
-
expression.name && callback(expression);
|
|
522
|
-
} else if (exp.type === "JSXIdentifier" && ((_a = exp._util.parent) == null ? void 0 : _a.type) !== "JSXAttribute") {
|
|
523
|
-
callback(exp);
|
|
524
|
-
} else if (exp.type === "JSXAttribute") {
|
|
525
|
-
const value = exp.value;
|
|
526
|
-
value && this._deepFindIdOfExpression(value, callback);
|
|
527
|
-
} else if (exp.type === "JSXElement") {
|
|
528
|
-
const openingElement = exp.openingElement;
|
|
529
|
-
this._deepFindIdOfExpression(openingElement, callback);
|
|
530
|
-
} else if (exp.type === "JSXOpeningElement") {
|
|
531
|
-
const { name, attributes } = exp;
|
|
532
|
-
this._deepFindIdOfExpression(name, callback);
|
|
533
|
-
for (const attribute of attributes) {
|
|
534
|
-
this._deepFindIdOfExpression(attribute, callback);
|
|
535
|
-
}
|
|
570
|
+
return;
|
|
536
571
|
}
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
return this.getRootIdentifierOfMemberExpression(memExp.object);
|
|
572
|
+
if (exp.type === "JSXIdentifier" && ((_c = exp._util.parent) == null ? void 0 : _c.type) !== "JSXAttribute") {
|
|
573
|
+
callback(exp);
|
|
574
|
+
return;
|
|
541
575
|
}
|
|
542
|
-
|
|
576
|
+
exp._util.nodeCollection.forEach((ele) => this._collectExpressionIdentifiers(ele, callback));
|
|
543
577
|
}
|
|
544
578
|
static findIdOfImport(node, callback) {
|
|
545
579
|
const specifiers = node.specifiers;
|
|
@@ -564,6 +598,10 @@ var _AstUtil = class {
|
|
|
564
598
|
if (!id) {
|
|
565
599
|
return;
|
|
566
600
|
}
|
|
601
|
+
if (id.type === "AssignmentPattern") {
|
|
602
|
+
const left = id.left;
|
|
603
|
+
this._deepFindIdentifier(left, callback);
|
|
604
|
+
}
|
|
567
605
|
if (id.type === "Identifier") {
|
|
568
606
|
callback(id);
|
|
569
607
|
}
|
|
@@ -641,14 +679,14 @@ var _AstUtil = class {
|
|
|
641
679
|
return id._util.variableScope.length === 0 && !this.isPropertyOfGlobal(id) && !this.isIntrinsicElement(id) && !this.isStandardAttribute(id);
|
|
642
680
|
}
|
|
643
681
|
static isPropertyOfGlobal(node) {
|
|
644
|
-
return node.type === "Identifier" && !node._util.variableScope.length && this.windowProperties.includes(node.name);
|
|
682
|
+
return node.type === "Identifier" && !node._util.variableScope.length && typeof node.name === "string" && this.windowProperties.includes(node.name);
|
|
645
683
|
}
|
|
646
684
|
static isIntrinsicElement(node) {
|
|
647
685
|
var _a;
|
|
648
|
-
return node.type === "JSXIdentifier" && ((_a = node._util.parent) == null ? void 0 : _a.type) && ["JSXOpeningElement", "JSXClosingElement"].includes(node._util.parent.type) && this.intrinsicElements.includes(node.name);
|
|
686
|
+
return node.type === "JSXIdentifier" && ((_a = node._util.parent) == null ? void 0 : _a.type) && ["JSXOpeningElement", "JSXClosingElement"].includes(node._util.parent.type) && typeof node.name === "string" && this.intrinsicElements.includes(node.name);
|
|
649
687
|
}
|
|
650
688
|
static isStandardAttribute(node) {
|
|
651
|
-
return node._util.parent.type === "JSXAttribute" && this.standardAttributes.includes(node.name);
|
|
689
|
+
return node._util.parent.type === "JSXAttribute" && typeof node.name === "string" && this.standardAttributes.includes(node.name);
|
|
652
690
|
}
|
|
653
691
|
static getTopScopeNodesByLineNumberRange(mapFileLineToNodeSet, lineNumberStart, lineNumberEnd) {
|
|
654
692
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
@@ -36,6 +36,7 @@ __export(FileUtil_exports, {
|
|
|
36
36
|
module.exports = __toCommonJS(FileUtil_exports);
|
|
37
37
|
var babelParse = __toESM(require("@babel/parser"));
|
|
38
38
|
var vueParse = __toESM(require("vue-eslint-parser"));
|
|
39
|
+
var import_fs = __toESM(require("fs"));
|
|
39
40
|
var extensionsOfJs = [".js", ".jsx", ".ts", ".tsx"];
|
|
40
41
|
var extensions = [...extensionsOfJs, ".vue"];
|
|
41
42
|
var commonParsePlugins = [
|
|
@@ -131,8 +132,13 @@ var FileUtil = class {
|
|
|
131
132
|
return ["", null];
|
|
132
133
|
}
|
|
133
134
|
static getASTByFilePath(filePath) {
|
|
134
|
-
const
|
|
135
|
-
|
|
135
|
+
const existFlag = import_fs.default.existsSync(filePath);
|
|
136
|
+
if (existFlag) {
|
|
137
|
+
const fileContent = import_fs.default.readFileSync(filePath, "utf8");
|
|
138
|
+
return this.parseFile(filePath, fileContent)[1];
|
|
139
|
+
}
|
|
140
|
+
console.warn("文件不存在: " + filePath);
|
|
141
|
+
return null;
|
|
136
142
|
}
|
|
137
143
|
};
|
|
138
144
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -36,10 +36,10 @@ var import_AstUtil = __toESM(require("./AstUtil"));
|
|
|
36
36
|
var import_FileUtil = __toESM(require("./FileUtil"));
|
|
37
37
|
var mapFilePathToTools = /* @__PURE__ */ new Map();
|
|
38
38
|
var createMapFileLineToNodeSet = (file, absPathPrefix) => {
|
|
39
|
-
const ast = import_FileUtil.default.getASTByFilePath(file);
|
|
40
39
|
const mapUuidToNode = /* @__PURE__ */ new Map();
|
|
41
40
|
const mapPathToNodeSet = /* @__PURE__ */ new Map();
|
|
42
41
|
const mapFileLineToNodeSet = /* @__PURE__ */ new Map();
|
|
42
|
+
const ast = import_FileUtil.default.getASTByFilePath(file);
|
|
43
43
|
const filePathRelative = file.replace(absPathPrefix, "");
|
|
44
44
|
import_AstUtil.default.deepFirstTravel(ast, filePathRelative, mapUuidToNode, mapFileLineToNodeSet, mapPathToNodeSet);
|
|
45
45
|
return { mapFileLineToNodeSet, mapUuidToNode, mapPathToNodeSet };
|
|
@@ -28,7 +28,7 @@ var mapReportType = {
|
|
|
28
28
|
delete: "删除"
|
|
29
29
|
};
|
|
30
30
|
function createMdByJson(report) {
|
|
31
|
-
const allFiles = `#
|
|
31
|
+
const allFiles = `# 改动文件汇总
|
|
32
32
|
${report.map((r) => `- ${r.filePath}`).join("\n")}
|
|
33
33
|
|
|
34
34
|
`;
|
|
@@ -39,12 +39,11 @@ function reportItemToMd(report) {
|
|
|
39
39
|
return [
|
|
40
40
|
`## ${filePath}`,
|
|
41
41
|
`### 类型: ${mapReportType[type]}`,
|
|
42
|
-
filesDependsOnMe.length > 0 ? `### 所影响的文件
|
|
43
|
-
${filesDependsOnMe.map((files
|
|
42
|
+
filesDependsOnMe.length > 0 ? `### 所影响的文件
|
|
43
|
+
${filesDependsOnMe.slice(0, 1).map((files) => files.map((file) => `- ${file}`)).flat().join("\n")}` : "",
|
|
44
44
|
undefinedIdentifiers.length > 0 ? `### 未定义的变量
|
|
45
45
|
> ${undefinedIdentifiers.map((e) => `**${e}**`).join(", ")}` : "",
|
|
46
|
-
dangerIdentifiers.length > 0 ? `###
|
|
47
|
-
> ${dangerIdentifiers.join(", ")}` : "",
|
|
46
|
+
// dangerIdentifiers.length > 0 ? `### 重点检查使用的变量\n> ${dangerIdentifiers.join(', ')}` : '',
|
|
48
47
|
blockReports.length > 0 ? `### 对比分析 共${blockReports.length}处` : "",
|
|
49
48
|
...blockReports.map(blockReportToMd)
|
|
50
49
|
].filter(Boolean).join("\n\n");
|
|
@@ -63,16 +62,19 @@ ${diff_txt.join("\n")}
|
|
|
63
62
|
...infos.map(blockReportInfoItemToMd)
|
|
64
63
|
].filter(Boolean).join("\n\n");
|
|
65
64
|
}
|
|
66
|
-
function blockReportInfoItemToMd(info
|
|
65
|
+
function blockReportInfoItemToMd(info) {
|
|
67
66
|
const {
|
|
68
67
|
causeBy,
|
|
69
|
-
effects
|
|
68
|
+
effects,
|
|
69
|
+
occupations
|
|
70
70
|
} = info;
|
|
71
71
|
return [
|
|
72
|
-
`#### 序号${index + 1}`,
|
|
73
72
|
effects.length > 0 ? `#### ${causeBy}
|
|
74
73
|
- 影响:
|
|
75
|
-
${effects.map((e) => `> ${e}`).join("\n")}` : ""
|
|
74
|
+
${effects.map((e) => `> ${e}`).join("\n")}` : "- 无影响",
|
|
75
|
+
occupations.length > 0 ? `#### ${causeBy}
|
|
76
|
+
- 使用:
|
|
77
|
+
${occupations.map((e) => `> ${e}`).join("\n")}` : "- 无"
|
|
76
78
|
].filter(Boolean).join("\n\n");
|
|
77
79
|
}
|
|
78
80
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -60,8 +60,9 @@ function diffBlockDetect(gitDiffDetail, index, extra) {
|
|
|
60
60
|
const { reportItem, absPathPrefix } = extra;
|
|
61
61
|
const { blockReports, _fileRemovedNodesPaths, _fileAddedNodesPaths } = reportItem;
|
|
62
62
|
const blockReportItem = findOrCreateBlockReport(blockReports, index);
|
|
63
|
-
const
|
|
64
|
-
const
|
|
63
|
+
const filePathOfOld = (0, import_path.join)((0, import_path.dirname)(absPathPrefix), import_constants.SOURCE, filePath);
|
|
64
|
+
const filePathOfNew = (0, import_path.join)((0, import_path.dirname)(absPathPrefix), import_constants.TARGET, filePath);
|
|
65
|
+
const { mapFileLineToNodeSet, mapUuidToNode } = (0, import_getAstKitByFilePath.default)(filePathOfNew, absPathPrefix);
|
|
65
66
|
const { mapFileLineToNodeSet: mapFileLineToNodeSetOld } = (0, import_getAstKitByFilePath.default)(filePathOfOld, absPathPrefix.replace(`${import_constants.TARGET}/`, `${import_constants.SOURCE}/`));
|
|
66
67
|
const programNode = mapUuidToNode.get("Program");
|
|
67
68
|
if (programNode) {
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/util/report_util/generateGitDiffReport.ts
|
|
20
|
+
var generateGitDiffReport_exports = {};
|
|
21
|
+
__export(generateGitDiffReport_exports, {
|
|
22
|
+
generateGitDiffReport: () => generateGitDiffReport
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(generateGitDiffReport_exports);
|
|
25
|
+
var import_fs = require("fs");
|
|
26
|
+
var import_path = require("path");
|
|
27
|
+
var import__ = require("../../index");
|
|
28
|
+
var import_format_git_diff_content = require("../format_git_diff_content");
|
|
29
|
+
var import_utils = require("@umijs/utils");
|
|
30
|
+
var import_report_util = require("../report_util");
|
|
31
|
+
var import_createMdByJson = require("./createMdByJson");
|
|
32
|
+
var MADGE_NAME = "madge";
|
|
33
|
+
var userAliasGetter = (cwd, appData) => {
|
|
34
|
+
var _a;
|
|
35
|
+
return ((_a = appData.config) == null ? void 0 : _a.alias) || {
|
|
36
|
+
umi: "@@/exports",
|
|
37
|
+
"@": cwd + "/src",
|
|
38
|
+
"@@": cwd + "/src/.umi",
|
|
39
|
+
"@umijs/max": "@@/exports"
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
var reportFileName = "git_diff_report.md";
|
|
43
|
+
async function generateGitDiffReport(arg) {
|
|
44
|
+
const { targetDirPath } = arg;
|
|
45
|
+
const absSrcPath = (0, import_path.join)(targetDirPath, "src");
|
|
46
|
+
const diff_txt = (0, import_fs.readFileSync)((0, import_path.join)(targetDirPath, import__.gitDiffFileName), "utf-8");
|
|
47
|
+
const gitDiffDetail = (0, import_format_git_diff_content.formatGitDiffContent)(diff_txt);
|
|
48
|
+
(0, import_fs.writeFileSync)((0, import_path.join)(targetDirPath, import__.gitDiffJsonName), JSON.stringify(gitDiffDetail, null, 2), { encoding: "utf-8", flag: "w" });
|
|
49
|
+
const tsconfig = await import_utils.tsconfigPaths.loadConfig(targetDirPath);
|
|
50
|
+
const appDataContent = (0, import_fs.readFileSync)((0, import_path.join)(targetDirPath, "src", ".umi", "appData.json"), "utf-8");
|
|
51
|
+
let appData = { config: null };
|
|
52
|
+
try {
|
|
53
|
+
appData = JSON.parse(appDataContent);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
console.warn("appData.json 解析失败,将使用默认别名");
|
|
56
|
+
}
|
|
57
|
+
const userAlias = userAliasGetter(targetDirPath, appData);
|
|
58
|
+
const exclude = [/node_modules/, /\.d\.ts$/, /\.umi/];
|
|
59
|
+
const isExclude = (path) => {
|
|
60
|
+
return exclude.some((reg) => reg.test(path));
|
|
61
|
+
};
|
|
62
|
+
const parsedAlias = import_utils.aliasUtils.parseCircleAlias({
|
|
63
|
+
alias: userAlias
|
|
64
|
+
});
|
|
65
|
+
const filteredAlias = Object.keys(parsedAlias).reduce(
|
|
66
|
+
(acc, key) => {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
const value = parsedAlias[key];
|
|
69
|
+
if (isExclude(value)) {
|
|
70
|
+
return acc;
|
|
71
|
+
}
|
|
72
|
+
if ((_a = tsconfig.paths) == null ? void 0 : _a[key]) {
|
|
73
|
+
return acc;
|
|
74
|
+
}
|
|
75
|
+
const tsconfigValue = [(0, import_path.join)((0, import_path.relative)(targetDirPath, value), "/*")];
|
|
76
|
+
const tsconfigKey = `${key}/*`;
|
|
77
|
+
if ((_b = tsconfig.paths) == null ? void 0 : _b[tsconfigKey]) {
|
|
78
|
+
return acc;
|
|
79
|
+
}
|
|
80
|
+
acc[tsconfigKey] = tsconfigValue;
|
|
81
|
+
return acc;
|
|
82
|
+
},
|
|
83
|
+
{}
|
|
84
|
+
);
|
|
85
|
+
const devTmpDir = (0, import_path.join)(absSrcPath, ".umi");
|
|
86
|
+
const exportsFile = (0, import_path.join)(devTmpDir, "exports.ts");
|
|
87
|
+
const madgePkg = (0, import_path.dirname)(
|
|
88
|
+
import_utils.resolve.sync(`${MADGE_NAME}/package.json`, {
|
|
89
|
+
basedir: process.cwd()
|
|
90
|
+
})
|
|
91
|
+
);
|
|
92
|
+
const madge = require(madgePkg);
|
|
93
|
+
const madgeConfig = {
|
|
94
|
+
tsConfig: {
|
|
95
|
+
compilerOptions: {
|
|
96
|
+
baseUrl: targetDirPath,
|
|
97
|
+
paths: {
|
|
98
|
+
...filteredAlias,
|
|
99
|
+
...tsconfig.paths,
|
|
100
|
+
umi: [exportsFile],
|
|
101
|
+
"@umijs/max": [exportsFile]
|
|
102
|
+
},
|
|
103
|
+
target: "esnext",
|
|
104
|
+
module: "esnext",
|
|
105
|
+
moduleResolution: "node",
|
|
106
|
+
importHelpers: true,
|
|
107
|
+
jsx: "react-jsx",
|
|
108
|
+
esModuleInterop: true,
|
|
109
|
+
strict: true,
|
|
110
|
+
resolveJsonModule: true,
|
|
111
|
+
allowSyntheticDefaultImports: true
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
fileExtensions: ["ts", "tsx", "js", "jsx"],
|
|
115
|
+
excludeRegExp: exclude,
|
|
116
|
+
baseDir: targetDirPath
|
|
117
|
+
};
|
|
118
|
+
const res = await madge((0, import_path.join)(devTmpDir, "umi.ts"), madgeConfig);
|
|
119
|
+
const treeMap = res.tree;
|
|
120
|
+
const dependenceMap = Object.keys(treeMap).reduce(
|
|
121
|
+
(acc, key) => {
|
|
122
|
+
const path = (0, import_utils.winPath)((0, import_path.join)(targetDirPath, key));
|
|
123
|
+
acc[path] = true;
|
|
124
|
+
return acc;
|
|
125
|
+
},
|
|
126
|
+
{}
|
|
127
|
+
);
|
|
128
|
+
const usingFiles = (0, import_utils.readDirFiles)({
|
|
129
|
+
dir: absSrcPath,
|
|
130
|
+
exclude
|
|
131
|
+
}).filter(({ filePath }) => dependenceMap[filePath]);
|
|
132
|
+
const tree = res.tree;
|
|
133
|
+
const absPathPrefix = targetDirPath + "/";
|
|
134
|
+
const usingFileNoPrefix = usingFiles.map((item) => item.filePath.replace(absPathPrefix, ""));
|
|
135
|
+
const groupGitDiffLines = gitDiffDetail.filter((item) => usingFileNoPrefix.includes(item.filePath));
|
|
136
|
+
(0, import_fs.writeFileSync)((0, import_path.join)(targetDirPath, "reports_helper.json"), JSON.stringify({ groupGitDiffLines, absPathPrefix, tree, filteredAlias, parsedAlias, tsconfig, madgeConfig }, null, 2), { encoding: "utf-8", flag: "w" });
|
|
137
|
+
const reports = (0, import_report_util.createDetectReport)({ groupGitDiffLines, tree, absPathPrefix });
|
|
138
|
+
(0, import_fs.writeFileSync)((0, import_path.join)(targetDirPath, "reports.json"), JSON.stringify(reports, null, 2), { encoding: "utf-8", flag: "w" });
|
|
139
|
+
const mdContent = (0, import_createMdByJson.createMdByJson)(reports);
|
|
140
|
+
(0, import_fs.writeFileSync)((0, import_path.join)(targetDirPath, reportFileName), mdContent, { encoding: "utf-8", flag: "w" });
|
|
141
|
+
}
|
|
142
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
143
|
+
0 && (module.exports = {
|
|
144
|
+
generateGitDiffReport
|
|
145
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getMadgeInstance(devTmpDir: string, targetDirPath: string, exclude: RegExp[], filteredAlias: Record<string, string[]>, tsconfig?: any): Promise<void>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __export = (target, all) => {
|
|
6
|
+
for (var name in all)
|
|
7
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
+
};
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
+
|
|
19
|
+
// src/util/report_util/getMadgeInstance.ts
|
|
20
|
+
var getMadgeInstance_exports = {};
|
|
21
|
+
__export(getMadgeInstance_exports, {
|
|
22
|
+
getMadgeInstance: () => getMadgeInstance
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(getMadgeInstance_exports);
|
|
25
|
+
var import_path = require("path");
|
|
26
|
+
var import_utils = require("@umijs/utils");
|
|
27
|
+
var MADGE_NAME = "madge";
|
|
28
|
+
async function getMadgeInstance(devTmpDir, targetDirPath, exclude, filteredAlias, tsconfig = {}) {
|
|
29
|
+
const exportsFile = (0, import_path.join)(devTmpDir, "exports.ts");
|
|
30
|
+
const madgePkg = (0, import_path.dirname)(
|
|
31
|
+
import_utils.resolve.sync(`${MADGE_NAME}/package.json`, {
|
|
32
|
+
basedir: process.cwd()
|
|
33
|
+
})
|
|
34
|
+
);
|
|
35
|
+
const madge = require(madgePkg);
|
|
36
|
+
const madgeConfig = {
|
|
37
|
+
tsConfig: {
|
|
38
|
+
compilerOptions: {
|
|
39
|
+
baseUrl: tsconfig.baseUrl,
|
|
40
|
+
paths: {
|
|
41
|
+
...filteredAlias,
|
|
42
|
+
...tsconfig.paths,
|
|
43
|
+
umi: [exportsFile],
|
|
44
|
+
"@umijs/max": [exportsFile]
|
|
45
|
+
},
|
|
46
|
+
target: "esnext",
|
|
47
|
+
module: "esnext",
|
|
48
|
+
moduleResolution: "node",
|
|
49
|
+
importHelpers: true,
|
|
50
|
+
jsx: "react-jsx",
|
|
51
|
+
esModuleInterop: true,
|
|
52
|
+
strict: true,
|
|
53
|
+
resolveJsonModule: true,
|
|
54
|
+
allowSyntheticDefaultImports: true
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
fileExtensions: ["ts", "tsx", "js", "jsx"],
|
|
58
|
+
excludeRegExp: exclude,
|
|
59
|
+
baseDir: targetDirPath
|
|
60
|
+
};
|
|
61
|
+
const res = await madge((0, import_path.join)(devTmpDir, "umi.ts"), madgeConfig);
|
|
62
|
+
}
|
|
63
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
64
|
+
0 && (module.exports = {
|
|
65
|
+
getMadgeInstance
|
|
66
|
+
});
|
|
@@ -30,9 +30,10 @@ export declare function createDetectReport(arg: Arg): {
|
|
|
30
30
|
infos: {
|
|
31
31
|
causeBy: string;
|
|
32
32
|
effects: string[];
|
|
33
|
+
occupations: string[];
|
|
33
34
|
}[];
|
|
34
35
|
}[];
|
|
35
|
-
type: "delete" | "
|
|
36
|
+
type: "delete" | "modify" | "add";
|
|
36
37
|
filesDependsOnMe: string[][];
|
|
37
38
|
undefinedIdentifiers: string[];
|
|
38
39
|
dangerIdentifiers: string[];
|
|
@@ -36,6 +36,7 @@ var import_AstUtil = __toESM(require("./ast_util/AstUtil"));
|
|
|
36
36
|
var import_file_identifier_detect = require("./report_util/file_identifier_detect");
|
|
37
37
|
var import_getFileDepends = __toESM(require("./report_util/getFileDepends"));
|
|
38
38
|
var import_diffBlockDetect = require("./report_util/diffBlockDetect");
|
|
39
|
+
var import_path = require("path");
|
|
39
40
|
function createDetectReport(arg) {
|
|
40
41
|
const { groupGitDiffLines, tree, absPathPrefix } = arg;
|
|
41
42
|
const reports = [];
|
|
@@ -56,8 +57,8 @@ function createDetectReport(arg) {
|
|
|
56
57
|
};
|
|
57
58
|
reports.push(reportItem);
|
|
58
59
|
}
|
|
59
|
-
reportItem.undefinedIdentifiers = (0, import_file_identifier_detect.extractUndefinedIdentifiers)(filePath, absPathPrefix);
|
|
60
|
-
reportItem.dangerIdentifiers = (0, import_file_identifier_detect.fileIdentifierDetect)(filePath, absPathPrefix);
|
|
60
|
+
reportItem.undefinedIdentifiers = (0, import_file_identifier_detect.extractUndefinedIdentifiers)((0, import_path.join)(absPathPrefix, filePath), absPathPrefix);
|
|
61
|
+
reportItem.dangerIdentifiers = (0, import_file_identifier_detect.fileIdentifierDetect)((0, import_path.join)(absPathPrefix, filePath), absPathPrefix);
|
|
61
62
|
if (type === "modify") {
|
|
62
63
|
(0, import_diffBlockDetect.diffBlockDetect)(item, index, { reportItem, absPathPrefix });
|
|
63
64
|
}
|
|
@@ -75,15 +76,19 @@ function createDetectReport(arg) {
|
|
|
75
76
|
const addNodeAndPaths = blockReport.addNodeAndPaths.filter((e) => fileAddedNodesPaths.includes(e.nodePath));
|
|
76
77
|
const infosList = addNodeAndPaths.map((item) => {
|
|
77
78
|
const { node } = item;
|
|
78
|
-
const { effectIds } = node._util;
|
|
79
|
+
const { effectIds, occupation, holdingIdType } = node._util;
|
|
79
80
|
return {
|
|
80
|
-
causeBy: import_AstUtil.default.getShortNodeMsg(node),
|
|
81
|
-
effects: [...
|
|
81
|
+
causeBy: import_AstUtil.default.getShortNodeMsg(node, true),
|
|
82
|
+
effects: holdingIdType ? [...occupation].map((occupationId) => {
|
|
83
|
+
const ans = import_AstUtil.default.getAncestorsFromBirth(occupationId, node);
|
|
84
|
+
return import_AstUtil.default.getNearestImpactedNode(ans.reverse());
|
|
85
|
+
}).filter(Boolean).map((e) => import_AstUtil.default.getShortNodeMsg(e, true)) : [...effectIds].map((e) => import_AstUtil.default.getShortNodeMsg(e, true)),
|
|
86
|
+
occupations: [...occupation].map((e) => import_AstUtil.default.getShortNodeMsg(e, true))
|
|
82
87
|
};
|
|
83
88
|
});
|
|
84
89
|
return {
|
|
85
90
|
diff_txt,
|
|
86
|
-
infos: infosList.filter((e) => e.effects.length > 0)
|
|
91
|
+
infos: infosList.filter((e) => e.effects.length > 0 || e.occupations.length > 0)
|
|
87
92
|
};
|
|
88
93
|
}).filter((e) => e.infos.length > 0)
|
|
89
94
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "js-code-detector",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.22",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"types": "dist/cjs/index.d.ts",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"dev": "father dev",
|
|
9
9
|
"build": "father build",
|
|
10
10
|
"build:deps": "father prebundle",
|
|
11
|
-
"prepublishOnly": "father doctor && npm run build"
|
|
11
|
+
"prepublishOnly": "nrm use npm && father doctor && npm run build"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [],
|
|
14
14
|
"authors": [
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { AstNode } from "../ast_util/AstUtil";
|
|
2
|
-
import { GitDiffDetail } from "../format_git_diff_content";
|
|
3
|
-
type BlockReportKind = "Import" | "Declaration" | "Assignment" | "SelfUpdate" | "Invoke" | "Other";
|
|
4
|
-
type EffectItem = {
|
|
5
|
-
causeBy: AstNode;
|
|
6
|
-
effects: AstNode[];
|
|
7
|
-
};
|
|
8
|
-
type BlockReportInfoItem = {
|
|
9
|
-
kind: BlockReportKind;
|
|
10
|
-
topAdded: AstNode[];
|
|
11
|
-
topRemoved: AstNode[];
|
|
12
|
-
added: string[];
|
|
13
|
-
addedNotUsed: string[];
|
|
14
|
-
addedNotFound: string[];
|
|
15
|
-
addedEffects: EffectItem[];
|
|
16
|
-
removed: string[];
|
|
17
|
-
removedStillUsing: string[];
|
|
18
|
-
removedEffects: EffectItem[];
|
|
19
|
-
};
|
|
20
|
-
export type BlockReport = {
|
|
21
|
-
index: number;
|
|
22
|
-
diff_txt: string[];
|
|
23
|
-
infos: BlockReportInfoItem[];
|
|
24
|
-
};
|
|
25
|
-
type Arg = {
|
|
26
|
-
gitDiffItem: GitDiffDetail;
|
|
27
|
-
absPathPrefix: string;
|
|
28
|
-
blockReports: BlockReport[];
|
|
29
|
-
index: number;
|
|
30
|
-
};
|
|
31
|
-
export default function codeBlockDetect(arg: Arg): void;
|
|
32
|
-
export {};
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
24
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
25
|
-
mod
|
|
26
|
-
));
|
|
27
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
|
|
29
|
-
// src/util/report_util/code_block_detect.ts
|
|
30
|
-
var code_block_detect_exports = {};
|
|
31
|
-
__export(code_block_detect_exports, {
|
|
32
|
-
default: () => codeBlockDetect
|
|
33
|
-
});
|
|
34
|
-
module.exports = __toCommonJS(code_block_detect_exports);
|
|
35
|
-
var import_path = require("path");
|
|
36
|
-
var import_getAstKitByFilePath = __toESM(require("../ast_util/getAstKitByFilePath"));
|
|
37
|
-
var import_AstUtil = __toESM(require("../ast_util/AstUtil"));
|
|
38
|
-
var import_constants = require("../constants");
|
|
39
|
-
var createBlockReport = (kind, index) => ({
|
|
40
|
-
index,
|
|
41
|
-
diff_txt: [],
|
|
42
|
-
infos: []
|
|
43
|
-
});
|
|
44
|
-
var createBlockReportInfoItem = (kind) => ({
|
|
45
|
-
kind,
|
|
46
|
-
topAdded: [],
|
|
47
|
-
topRemoved: [],
|
|
48
|
-
added: [],
|
|
49
|
-
addedNotUsed: [],
|
|
50
|
-
addedNotFound: [],
|
|
51
|
-
addedEffects: [],
|
|
52
|
-
removed: [],
|
|
53
|
-
removedStillUsing: [],
|
|
54
|
-
removedEffects: []
|
|
55
|
-
});
|
|
56
|
-
var findOrCreateBlockReport = (blockReports, kind, index, diff_txt) => {
|
|
57
|
-
const res = blockReports.find((item) => item.index === index) || createBlockReport(kind, index);
|
|
58
|
-
res.diff_txt = diff_txt;
|
|
59
|
-
if (!blockReports.includes(res)) {
|
|
60
|
-
blockReports.push(res);
|
|
61
|
-
}
|
|
62
|
-
const tmpInfo = res.infos.find((info) => info.kind === kind) || createBlockReportInfoItem(kind);
|
|
63
|
-
if (!res.infos.includes(tmpInfo)) {
|
|
64
|
-
res.infos.push(tmpInfo);
|
|
65
|
-
}
|
|
66
|
-
return tmpInfo;
|
|
67
|
-
};
|
|
68
|
-
function codeBlockDetect(arg) {
|
|
69
|
-
const { gitDiffItem, absPathPrefix, blockReports, index } = arg;
|
|
70
|
-
const { filePath, startLineOfNew, items, startLineOfOld } = gitDiffItem;
|
|
71
|
-
const { mapFileLineToNodeSet, mapUuidToNode } = (0, import_getAstKitByFilePath.default)(filePath, absPathPrefix);
|
|
72
|
-
const filePathOfOld = (0, import_path.join)(process.cwd(), "..", import_constants.SOURCE, filePath);
|
|
73
|
-
const { mapFileLineToNodeSet: mapFileLineToNodeSetOld } = (0, import_getAstKitByFilePath.default)(filePathOfOld, absPathPrefix);
|
|
74
|
-
const programNode = mapUuidToNode.get("Program");
|
|
75
|
-
if (programNode) {
|
|
76
|
-
const lineNumberStartNew = Number(startLineOfNew);
|
|
77
|
-
const lineNumberEndNew = lineNumberStartNew + items.filter((item) => item.startsWith("+")).length - 1;
|
|
78
|
-
const lineNumberStartOld = Number(startLineOfOld);
|
|
79
|
-
const lineNumberEndOld = lineNumberStartOld + items.filter((item) => item.startsWith("-")).length - 1;
|
|
80
|
-
const addNodes = import_AstUtil.default.getTopScopeNodesByLineNumberRange(mapFileLineToNodeSet, lineNumberStartNew, lineNumberEndNew);
|
|
81
|
-
const removeNodes = import_AstUtil.default.getTopScopeNodesByLineNumberRange(mapFileLineToNodeSetOld, lineNumberStartOld, lineNumberEndOld);
|
|
82
|
-
iterateNodes(addNodes, "add", { blockReports, programNode, diff_txt: items }, index);
|
|
83
|
-
iterateNodes(removeNodes, "remove", { blockReports, programNode, diff_txt: items }, index);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
function getPathsOfNode(topScopeNodes) {
|
|
87
|
-
const paths = [];
|
|
88
|
-
for (const topScopeNode of topScopeNodes) {
|
|
89
|
-
const nodeCollection = topScopeNode._util.nodeCollection;
|
|
90
|
-
for (const nodeItem of nodeCollection) {
|
|
91
|
-
if (nodeItem.type.endsWith("Identifier") || nodeItem.type.endsWith("Literal")) {
|
|
92
|
-
paths.push(import_AstUtil.default.getNodePath(nodeItem));
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return [...new Set(paths)];
|
|
97
|
-
}
|
|
98
|
-
function mapNodePath(list) {
|
|
99
|
-
return list.map((item) => ({ ...item, effects: item.effects.map((ele) => ({ ele, path: import_AstUtil.default.getNodePath(ele) })) }));
|
|
100
|
-
}
|
|
101
|
-
function filterBySamePathAndLen(list, sameEffectsPaths) {
|
|
102
|
-
return list.map((e) => ({ ...e, effects: e.effects.filter((item) => !sameEffectsPaths.includes(item.path)) })).filter((e) => e.effects.length);
|
|
103
|
-
}
|
|
104
|
-
function extractEffectItem(list) {
|
|
105
|
-
return list.map((e) => ({ ...e, effects: e.effects.map((item) => item.ele) }));
|
|
106
|
-
}
|
|
107
|
-
function pushBlockReport(blockReportInfoItem, programNode, index) {
|
|
108
|
-
if (blockReportInfoItem.kind === "Other") {
|
|
109
|
-
["added", "removed"].forEach((key) => {
|
|
110
|
-
const tailElements = blockReportInfoItem[key].map((ele) => ele.split(":").at(-1)).filter((e) => e && e !== "undefined");
|
|
111
|
-
blockReportInfoItem[key] = [...new Set(tailElements)];
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
const sameNames = blockReportInfoItem.added.filter((path) => blockReportInfoItem.removed.includes(path));
|
|
115
|
-
if (sameNames.length) {
|
|
116
|
-
["added", "removed"].forEach((key) => {
|
|
117
|
-
blockReportInfoItem[key] = blockReportInfoItem[key].filter((path) => !sameNames.includes(path));
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
const addedEffectsList = mapNodePath(blockReportInfoItem.addedEffects);
|
|
121
|
-
const removedEffectsList = mapNodePath(blockReportInfoItem.removedEffects);
|
|
122
|
-
const addedEffectsPaths = addedEffectsList.map((item) => item.effects.map(({ path }) => path)).flat();
|
|
123
|
-
const removedEffectsPaths = removedEffectsList.map((item) => item.effects.map(({ path }) => path)).flat();
|
|
124
|
-
const sameEffectsPaths = addedEffectsPaths.filter((path) => removedEffectsPaths.includes(path));
|
|
125
|
-
if (sameEffectsPaths.length) {
|
|
126
|
-
const addedEffects = filterBySamePathAndLen(addedEffectsList, sameEffectsPaths);
|
|
127
|
-
const removedEffects = filterBySamePathAndLen(removedEffectsList, sameEffectsPaths);
|
|
128
|
-
blockReportInfoItem.addedEffects = extractEffectItem(addedEffects);
|
|
129
|
-
blockReportInfoItem.removedEffects = extractEffectItem(removedEffects);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
function iterateNodes(topScopeNodes, operation, extra, index) {
|
|
133
|
-
for (const topScopeNode of topScopeNodes) {
|
|
134
|
-
if (["ImportDeclaration", "ImportSpecifier", "ImportDefaultSpecifier"].includes(topScopeNode.type)) {
|
|
135
|
-
detectImport({ topScopeNode, operation, extra }, index);
|
|
136
|
-
} else if (["VariableDeclaration", "VariableDeclarator"].includes(topScopeNode.type) || import_AstUtil.default.isSubNodeOfVariableDeclarator(topScopeNode)) {
|
|
137
|
-
detectVariableDeclaration({ topScopeNode, operation, extra }, index);
|
|
138
|
-
} else if (["FunctionDeclaration", "ClassDeclaration"].includes(topScopeNode.type)) {
|
|
139
|
-
detectFnClsDeclaration({ topScopeNode, operation, extra }, index);
|
|
140
|
-
} else if (["UnaryExpression", "UpdateExpression"].includes(topScopeNode.type)) {
|
|
141
|
-
detectUpdateEffectExp({ topScopeNode, operation, extra }, index);
|
|
142
|
-
} else if (["CallExpression"].includes(topScopeNode.type)) {
|
|
143
|
-
detectFnCallExp({ topScopeNode, operation, extra }, index);
|
|
144
|
-
} else if (["AssignmentExpression"].includes(topScopeNode.type)) {
|
|
145
|
-
detectAssignmentEffectExp({ topScopeNode, operation, extra }, index);
|
|
146
|
-
} else if (["ExpressionStatement"].includes(topScopeNode.type)) {
|
|
147
|
-
const { expression } = topScopeNode;
|
|
148
|
-
iterateNodes([expression], operation, extra, index);
|
|
149
|
-
} else {
|
|
150
|
-
detectOther({ topScopeNode, operation, extra }, index);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
function detectOther(arg, index) {
|
|
155
|
-
const { topScopeNode, operation, extra: { blockReports, programNode, diff_txt } } = arg;
|
|
156
|
-
const blockReportInfoItem = findOrCreateBlockReport(blockReports, "Other", index, diff_txt);
|
|
157
|
-
const { added, removed } = blockReportInfoItem;
|
|
158
|
-
const nodePaths = getPathsOfNode(topScopeNode._util.nodeCollection);
|
|
159
|
-
(operation === "add" ? added : removed).push(...nodePaths);
|
|
160
|
-
pushBlockReport(blockReportInfoItem, programNode, index);
|
|
161
|
-
}
|
|
162
|
-
function detectImport(arg, index) {
|
|
163
|
-
const { topScopeNode, operation, extra: { blockReports, programNode, diff_txt } } = arg;
|
|
164
|
-
const blockReport = findOrCreateBlockReport(blockReports, "Import", index, diff_txt);
|
|
165
|
-
const { added, removed, addedEffects, removedEffects } = blockReport;
|
|
166
|
-
const specifiers = topScopeNode.type === "ImportDeclaration" ? topScopeNode.specifiers : [topScopeNode];
|
|
167
|
-
if (Array.isArray(specifiers)) {
|
|
168
|
-
specifiers.forEach((s) => {
|
|
169
|
-
const { local } = s;
|
|
170
|
-
(operation === "add" ? added : removed).push(local.name);
|
|
171
|
-
(operation === "add" ? addedEffects : removedEffects).push({ causeBy: local, effects: [...local._util.effectIds] });
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
pushBlockReport(blockReport, programNode, index);
|
|
175
|
-
}
|
|
176
|
-
function detectFnClsDeclaration(arg, index) {
|
|
177
|
-
const { topScopeNode, operation, extra: { blockReports, programNode, diff_txt } } = arg;
|
|
178
|
-
const blockReport = findOrCreateBlockReport(blockReports, "Declaration", index, diff_txt);
|
|
179
|
-
const { added, removed, addedEffects, removedEffects } = blockReport;
|
|
180
|
-
const { id } = topScopeNode;
|
|
181
|
-
(operation === "add" ? added : removed).push(id.name);
|
|
182
|
-
(operation === "add" ? addedEffects : removedEffects).push({ causeBy: id, effects: [...id._util.effectIds] });
|
|
183
|
-
pushBlockReport(blockReport, programNode, index);
|
|
184
|
-
}
|
|
185
|
-
function insertPrefix(n, prefix, sep = ":") {
|
|
186
|
-
return [prefix, n].join(sep);
|
|
187
|
-
}
|
|
188
|
-
function detectVariableDeclaration(arg, index) {
|
|
189
|
-
const { topScopeNode, operation, extra: { blockReports, programNode, diff_txt } } = arg;
|
|
190
|
-
const blockReport = findOrCreateBlockReport(blockReports, "Declaration", index, diff_txt);
|
|
191
|
-
const { added, removed, addedEffects, removedEffects } = blockReport;
|
|
192
|
-
if (["VariableDeclaration", "VariableDeclarator"].includes(topScopeNode.type)) {
|
|
193
|
-
let declarations = [];
|
|
194
|
-
if (topScopeNode.type === "VariableDeclarator") {
|
|
195
|
-
declarations = [topScopeNode];
|
|
196
|
-
} else {
|
|
197
|
-
declarations = topScopeNode.declarations;
|
|
198
|
-
}
|
|
199
|
-
if (Array.isArray(declarations)) {
|
|
200
|
-
for (const declaration of declarations) {
|
|
201
|
-
const { id, init } = declaration;
|
|
202
|
-
if (id) {
|
|
203
|
-
id._util.nodeCollection.forEach((item) => {
|
|
204
|
-
if (item.type === "Identifier") {
|
|
205
|
-
(operation === "add" ? added : removed).push(insertPrefix(item.name, "id"));
|
|
206
|
-
(operation === "add" ? addedEffects : removedEffects).push({ causeBy: item, effects: [...item._util.effectIds] });
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
const initIdSet = /* @__PURE__ */ new Set();
|
|
211
|
-
if (init && !["ArrowFunctionExpression", "FunctionExpression"].includes(init.type)) {
|
|
212
|
-
["Identifier"].includes(init.type) ? initIdSet.add(init) : import_AstUtil.default.deepFindIdOfExpression(init, (id2) => initIdSet.add(id2));
|
|
213
|
-
for (const initId of initIdSet) {
|
|
214
|
-
operation === "add" ? blockReport.added.push(insertPrefix(initId.name, "init")) : blockReport.removed.push(insertPrefix(initId.name, "init"));
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
} else {
|
|
220
|
-
topScopeNode._util.nodeCollection.forEach((item) => {
|
|
221
|
-
if (item.type === "Identifier") {
|
|
222
|
-
(operation === "add" ? added : removed).push(insertPrefix(item.name, "id"));
|
|
223
|
-
(operation === "add" ? addedEffects : removedEffects).push({ causeBy: item, effects: [...item._util.effectIds] });
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
pushBlockReport(blockReport, programNode, index);
|
|
228
|
-
}
|
|
229
|
-
function detectUpdateEffectExp(arg, index) {
|
|
230
|
-
const { topScopeNode, operation, extra: { blockReports, programNode, diff_txt } } = arg;
|
|
231
|
-
const blockReport = findOrCreateBlockReport(blockReports, "SelfUpdate", index, diff_txt);
|
|
232
|
-
const { added, removed, addedEffects, removedEffects } = blockReport;
|
|
233
|
-
const { argument: args } = topScopeNode;
|
|
234
|
-
const createdExpIdSet = /* @__PURE__ */ new Set();
|
|
235
|
-
import_AstUtil.default.deepFindIdOfExpression(args, (id) => createdExpIdSet.add(id));
|
|
236
|
-
for (const createdExpId of createdExpIdSet) {
|
|
237
|
-
(operation === "add" ? added : removed).push(createdExpId.name);
|
|
238
|
-
(operation === "add" ? addedEffects : removedEffects).push({ causeBy: createdExpId, effects: [...createdExpId._util.effectIds] });
|
|
239
|
-
}
|
|
240
|
-
pushBlockReport(blockReport, programNode, index);
|
|
241
|
-
}
|
|
242
|
-
function detectFnCallExp(arg, index) {
|
|
243
|
-
const { topScopeNode, operation, extra: { blockReports, programNode, diff_txt } } = arg;
|
|
244
|
-
const blockReport = findOrCreateBlockReport(blockReports, "Invoke", index, diff_txt);
|
|
245
|
-
const { added, removed, addedEffects, removedEffects } = blockReport;
|
|
246
|
-
const { callee, arguments: args } = topScopeNode;
|
|
247
|
-
const argsIds = args.map((arg2) => arg2._util.nodeCollection.filter((n) => n.type === "Identifier")).flat();
|
|
248
|
-
for (const argsId of argsIds) {
|
|
249
|
-
(operation === "add" ? added : removed).push(argsId.name);
|
|
250
|
-
(operation === "add" ? addedEffects : removedEffects).push({ causeBy: argsId, effects: [...argsId._util.effectIds] });
|
|
251
|
-
}
|
|
252
|
-
const createdExpIdSet = /* @__PURE__ */ new Set();
|
|
253
|
-
import_AstUtil.default.deepFindIdOfExpression(callee, (id) => createdExpIdSet.add(id));
|
|
254
|
-
for (const createdExpId of createdExpIdSet) {
|
|
255
|
-
(operation === "add" ? added : removed).push(createdExpId.name);
|
|
256
|
-
(operation === "add" ? addedEffects : removedEffects).push({ causeBy: createdExpId, effects: [...createdExpId._util.effectIds] });
|
|
257
|
-
}
|
|
258
|
-
pushBlockReport(blockReport, programNode, index);
|
|
259
|
-
}
|
|
260
|
-
function detectAssignmentEffectExp(arg, index) {
|
|
261
|
-
const { topScopeNode, operation, extra: { blockReports, programNode, diff_txt } } = arg;
|
|
262
|
-
const blockReport = findOrCreateBlockReport(blockReports, "Assignment", index, diff_txt);
|
|
263
|
-
const { added, removed, addedEffects, removedEffects } = blockReport;
|
|
264
|
-
const { left, right } = topScopeNode;
|
|
265
|
-
const idSetLeft = /* @__PURE__ */ new Set();
|
|
266
|
-
["Identifier"].includes(left.type) ? idSetLeft.add(left) : import_AstUtil.default.deepFindIdOfExpression(left, (id) => idSetLeft.add(id));
|
|
267
|
-
for (const createdExp of idSetLeft) {
|
|
268
|
-
(operation === "add" ? added : removed).push(insertPrefix(createdExp.name, "left"));
|
|
269
|
-
(operation === "add" ? addedEffects : removedEffects).push({ causeBy: createdExp, effects: [...createdExp._util.effectIds] });
|
|
270
|
-
}
|
|
271
|
-
const idSetRight = /* @__PURE__ */ new Set();
|
|
272
|
-
["Identifier", "ArrowFunctionExpression", "FunctionExpression"].includes(right.type) ? idSetRight.add(right) : import_AstUtil.default.deepFindIdOfExpression(right, (id) => idSetRight.add(id));
|
|
273
|
-
for (const createdExp of idSetRight) {
|
|
274
|
-
(operation === "add" ? added : removed).push(insertPrefix(createdExp.name, "right"));
|
|
275
|
-
}
|
|
276
|
-
pushBlockReport(blockReport, programNode, index);
|
|
277
|
-
}
|