js-code-detector 0.0.21 → 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.js +6 -10
- package/dist/cjs/util/ast_util/AstUtil.d.ts +6 -5
- package/dist/cjs/util/ast_util/AstUtil.js +106 -136
- package/dist/cjs/util/report_util/createMdByJson.js +11 -9
- package/dist/cjs/util/report_util.d.ts +2 -1
- package/dist/cjs/util/report_util.js +8 -4
- package/package.json +1 -1
- 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.js
CHANGED
|
@@ -139,33 +139,29 @@ async function gitDiffDetect() {
|
|
|
139
139
|
import_utils.logger.ready("准备生成临时工作目录...");
|
|
140
140
|
await import_utils.execa.execa(`mkdir -p ${today}`, { shell: "/bin/bash" });
|
|
141
141
|
import_utils.logger.info("临时目录建立完成");
|
|
142
|
-
import_utils.logger.ready(
|
|
143
|
-
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" });
|
|
144
144
|
import_utils.logger.info("源代码clone完成");
|
|
145
145
|
import_utils.logger.ready(`准备clone源代码到临时目录下的 ${import_constants.SOURCE} 文件夹`);
|
|
146
146
|
await import_utils.execa.execa(`git clone ${gitUrl} ${today}/${import_constants.SOURCE}`, { shell: "/bin/bash" });
|
|
147
147
|
import_utils.logger.info("源代码clone完成");
|
|
148
148
|
import_utils.logger.ready("准备切换到目标分支");
|
|
149
|
-
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" });
|
|
150
150
|
import_utils.logger.info("分支切换完成");
|
|
151
151
|
import_utils.logger.ready("准备生成git_diff.txt文件");
|
|
152
|
-
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" });
|
|
153
153
|
import_utils.logger.info("git_diff.txt文件生成完成");
|
|
154
|
-
import_utils.logger.ready("准备生成插件文件");
|
|
155
|
-
(0, import_fs2.writeFileSync)((0, import_path.join)(process.cwd(), today, "target", "plugin.ts"), pluginFileContent, { encoding: "utf-8", flag: "w" });
|
|
156
|
-
import_utils.logger.info("插件文件生成完成");
|
|
157
154
|
import_utils.logger.wait("准备生成 入口文件");
|
|
158
|
-
await import_utils.execa.execa(`cd ${today}
|
|
155
|
+
await import_utils.execa.execa(`cd ${today}/${import_constants.TARGET} && npx max setup`, { shell: "/bin/bash" });
|
|
159
156
|
import_utils.logger.info("入口文件 生成完成!");
|
|
160
157
|
import_utils.logger.ready("准备生成报告");
|
|
161
158
|
await (0, import_generateGitDiffReport.generateGitDiffReport)({ targetDirPath: (0, import_path.join)(process.cwd(), today, "target") });
|
|
162
159
|
import_utils.logger.info("报告完成");
|
|
163
160
|
import_utils.logger.ready("准备移动报告");
|
|
164
|
-
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");
|
|
165
162
|
const mdFileName = `${(0, import_dayjs.default)().format("YYYYMDD_HHmm")}_${jsonName}`;
|
|
166
163
|
(0, import_fs2.writeFileSync)((0, import_path.join)(process.cwd(), mdFileName), content, { encoding: "utf-8", flag: "w" });
|
|
167
164
|
import_utils.logger.info("报告完成: " + mdFileName);
|
|
168
|
-
await getEslintCheckResult(today);
|
|
169
165
|
(0, import_utils.rimraf)((0, import_path.join)(process.cwd(), today), () => {
|
|
170
166
|
import_utils.logger.info("临时目录已删除");
|
|
171
167
|
});
|
|
@@ -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', {
|
|
@@ -32,12 +32,16 @@ export interface AstNode {
|
|
|
32
32
|
inject: Set<AstNode>;
|
|
33
33
|
provide: Set<AstNode>;
|
|
34
34
|
effectIds: Set<AstNode>;
|
|
35
|
+
occupation: Set<AstNode>;
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
export default class AstUtil {
|
|
38
39
|
static invalidNodeKey: string[];
|
|
39
40
|
static getNodePath(node: AstNode): string;
|
|
40
|
-
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;
|
|
41
45
|
static deepFirstTravel(node: AstNode, filePath: string, mapUuidToNode: Map<string, AstNode>, mapFileLineToNodeSet: Map<number, Set<AstNode>>, mapPathToNodeSet: Map<string, Set<AstNode>>): AstNode | undefined;
|
|
42
46
|
private static _deepFirstTravel;
|
|
43
47
|
private static collectInjectAndProvide;
|
|
@@ -64,9 +68,6 @@ export default class AstUtil {
|
|
|
64
68
|
private static _collectExpressionIdentifiersShallow;
|
|
65
69
|
static collectExpressionIdentifiers(exp: AstNode | null, callback: (identifier: AstNode) => void): void;
|
|
66
70
|
private static _collectExpressionIdentifiers;
|
|
67
|
-
static deepFindIdOfExpression(exp: AstNode | null, callback: (identifier: AstNode) => void): void;
|
|
68
|
-
private static _deepFindIdOfExpression;
|
|
69
|
-
private static getRootIdentifierOfMemberExpression;
|
|
70
71
|
private static findIdOfImport;
|
|
71
72
|
private static findIdOfVariable;
|
|
72
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();
|
|
@@ -63,7 +117,8 @@ var _AstUtil = class {
|
|
|
63
117
|
holdingIdNameMap: /* @__PURE__ */ new Map(),
|
|
64
118
|
inject: /* @__PURE__ */ new Set(),
|
|
65
119
|
provide: /* @__PURE__ */ new Set(),
|
|
66
|
-
effectIds: /* @__PURE__ */ new Set()
|
|
120
|
+
effectIds: /* @__PURE__ */ new Set(),
|
|
121
|
+
occupation: /* @__PURE__ */ new Set()
|
|
67
122
|
};
|
|
68
123
|
node._util = _util;
|
|
69
124
|
const { nodeCollection, children } = _util;
|
|
@@ -211,7 +266,7 @@ var _AstUtil = class {
|
|
|
211
266
|
}
|
|
212
267
|
});
|
|
213
268
|
}
|
|
214
|
-
if (["FunctionDeclaration", "ArrowFunctionExpression", "FunctionExpression", "ObjectMethod"].includes(node.type)) {
|
|
269
|
+
if (["FunctionDeclaration", "ArrowFunctionExpression", "FunctionExpression", "ObjectMethod", "ClassMethod"].includes(node.type)) {
|
|
215
270
|
node.params.forEach((param) => this._deepFindIdentifier(param, (id) => {
|
|
216
271
|
holdingIds.add(id || node);
|
|
217
272
|
id._util.variableScope = [id];
|
|
@@ -220,6 +275,8 @@ var _AstUtil = class {
|
|
|
220
275
|
}
|
|
221
276
|
holdingIds.forEach((holdingId) => {
|
|
222
277
|
const holdingIdName = holdingId.name;
|
|
278
|
+
if (typeof holdingIdName !== "string")
|
|
279
|
+
return;
|
|
223
280
|
const nodeSetOfIdName = holdingIdNameMap.get(holdingIdName) || /* @__PURE__ */ new Set();
|
|
224
281
|
nodeSetOfIdName.add(holdingId);
|
|
225
282
|
holdingIdNameMap.set(holdingIdName, nodeSetOfIdName);
|
|
@@ -234,7 +291,7 @@ var _AstUtil = class {
|
|
|
234
291
|
return node._util.parentProperty === "argument" && ((_a = node._util.parent) == null ? void 0 : _a.type) === "ReturnStatement";
|
|
235
292
|
}
|
|
236
293
|
static collectDependenceIds(node) {
|
|
237
|
-
const {
|
|
294
|
+
const { _util } = node;
|
|
238
295
|
const { dependenceIds, holdingIdNameMap, children, dependenceIdsNoScope } = _util;
|
|
239
296
|
children.forEach((child) => {
|
|
240
297
|
if (child._util.dependenceIdsNoScope.size > 0) {
|
|
@@ -244,18 +301,16 @@ var _AstUtil = class {
|
|
|
244
301
|
this.collectExpressionIdentifiersShallow(child, (id) => dependenceIds.add(id));
|
|
245
302
|
});
|
|
246
303
|
for (const dependenceId of dependenceIds) {
|
|
247
|
-
if (dependenceId._util.variableScope.length === 0) {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (firstPick && firstPick._util.uuid !== dependenceId._util.uuid) {
|
|
253
|
-
firstPick._util.effectIds.add(dependenceId);
|
|
254
|
-
}
|
|
255
|
-
} else {
|
|
256
|
-
dependenceIdsNoScope.add(dependenceId);
|
|
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];
|
|
307
|
+
if (firstPick && firstPick._util.uuid !== dependenceId._util.uuid) {
|
|
308
|
+
firstPick._util.occupation.add(dependenceId);
|
|
257
309
|
}
|
|
258
310
|
}
|
|
311
|
+
if (dependenceId._util.variableScope.length === 0) {
|
|
312
|
+
dependenceIdsNoScope.add(dependenceId);
|
|
313
|
+
}
|
|
259
314
|
}
|
|
260
315
|
}
|
|
261
316
|
static isUseStateVarDec(node) {
|
|
@@ -270,7 +325,7 @@ var _AstUtil = class {
|
|
|
270
325
|
static isUseMemoVarDec(node) {
|
|
271
326
|
if (node.type !== "VariableDeclarator")
|
|
272
327
|
return false;
|
|
273
|
-
const {
|
|
328
|
+
const { init } = node;
|
|
274
329
|
if (init.type !== "CallExpression")
|
|
275
330
|
return false;
|
|
276
331
|
const { callee } = init;
|
|
@@ -279,7 +334,7 @@ var _AstUtil = class {
|
|
|
279
334
|
static isUseCallbackVarDec(node) {
|
|
280
335
|
if (node.type !== "VariableDeclarator")
|
|
281
336
|
return false;
|
|
282
|
-
const {
|
|
337
|
+
const { init } = node;
|
|
283
338
|
if (init.type !== "CallExpression")
|
|
284
339
|
return false;
|
|
285
340
|
const { callee } = init;
|
|
@@ -305,7 +360,7 @@ var _AstUtil = class {
|
|
|
305
360
|
}
|
|
306
361
|
}
|
|
307
362
|
static collectEffectIdOfFnCall(node) {
|
|
308
|
-
var _a, _b
|
|
363
|
+
var _a, _b;
|
|
309
364
|
if (node.type !== "CallExpression") {
|
|
310
365
|
return;
|
|
311
366
|
}
|
|
@@ -321,14 +376,29 @@ var _AstUtil = class {
|
|
|
321
376
|
const fnNode = scopeId._util.parent;
|
|
322
377
|
if (fnNode.type === "FunctionExpression" || fnNode.type === "ArrowFunctionExpression") {
|
|
323
378
|
if (fnNode._util.parentProperty === "init" && ((_a = fnNode._util.parent) == null ? void 0 : _a.type) === "VariableDeclarator") {
|
|
324
|
-
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
|
+
}
|
|
325
385
|
} else if (fnNode._util.parentProperty === "right" && ((_b = fnNode._util.parent) == null ? void 0 : _b.type) === "AssignmentExpression") {
|
|
326
386
|
fnNode._util.parent.left._util.effectIds.add(id);
|
|
327
|
-
} else if (fnNode._util.parentProperty === "value" && ((_c = fnNode._util.parent) == null ? void 0 : _c.type) === "MethodDefinition") {
|
|
328
|
-
fnNode._util.parent.key._util.effectIds.add(id);
|
|
329
387
|
}
|
|
330
388
|
} else if (fnNode.type === "FunctionDeclaration") {
|
|
331
|
-
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
|
+
}
|
|
332
402
|
}
|
|
333
403
|
}
|
|
334
404
|
const kindOfParamsElement = [...scopeId._util.effectIds].filter((e) => {
|
|
@@ -360,12 +430,12 @@ var _AstUtil = class {
|
|
|
360
430
|
this.collectEffectIdOfUseCallback(node);
|
|
361
431
|
return;
|
|
362
432
|
}
|
|
363
|
-
const
|
|
364
|
-
this._deepFindIdentifier(id, (ele) =>
|
|
365
|
-
const
|
|
366
|
-
["Identifier", "ArrowFunctionExpression", "FunctionExpression"].includes(init.type) ?
|
|
367
|
-
for (const
|
|
368
|
-
|
|
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]);
|
|
369
439
|
}
|
|
370
440
|
}
|
|
371
441
|
static collectEffectIdOfUseState(node) {
|
|
@@ -409,20 +479,13 @@ var _AstUtil = class {
|
|
|
409
479
|
}
|
|
410
480
|
static collectEffectIdOfAssign(node) {
|
|
411
481
|
const { left, right } = node;
|
|
482
|
+
const idSetOfLeft = /* @__PURE__ */ new Set();
|
|
483
|
+
this.collectExpressionIdentifiers(left, (id) => idSetOfLeft.add(id));
|
|
412
484
|
const idSetOfRight = /* @__PURE__ */ new Set();
|
|
413
485
|
this.collectExpressionIdentifiers(right, (id) => idSetOfRight.add(id));
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
left2._util.effectIds = /* @__PURE__ */ new Set([...idSetOfRight, ...left2._util.effectIds]);
|
|
417
|
-
} else {
|
|
418
|
-
const { left: left2 } = node;
|
|
419
|
-
const idSetOfLeft = /* @__PURE__ */ new Set();
|
|
420
|
-
this.collectExpressionIdentifiers(left2, (id) => idSetOfLeft.add(id));
|
|
421
|
-
for (const id of idSetOfLeft) {
|
|
422
|
-
id._util.effectIds = /* @__PURE__ */ new Set([...idSetOfRight, ...id._util.effectIds]);
|
|
423
|
-
}
|
|
486
|
+
for (const id of idSetOfLeft) {
|
|
487
|
+
id._util.effectIds = /* @__PURE__ */ new Set([...idSetOfRight, ...id._util.effectIds]);
|
|
424
488
|
}
|
|
425
|
-
;
|
|
426
489
|
}
|
|
427
490
|
static collectEffectIdOfUnaryUpdate(node) {
|
|
428
491
|
const { argument } = node;
|
|
@@ -512,99 +575,6 @@ var _AstUtil = class {
|
|
|
512
575
|
}
|
|
513
576
|
exp._util.nodeCollection.forEach((ele) => this._collectExpressionIdentifiers(ele, callback));
|
|
514
577
|
}
|
|
515
|
-
static deepFindIdOfExpression(exp, callback) {
|
|
516
|
-
if (!exp || exp.type === "ThisExpression") {
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
this._deepFindIdOfExpression(exp, callback);
|
|
520
|
-
}
|
|
521
|
-
static _deepFindIdOfExpression(exp, callback) {
|
|
522
|
-
var _a;
|
|
523
|
-
if (!exp || exp.type === "ThisExpression") {
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
|
-
if (exp.type === "IfStatement") {
|
|
527
|
-
const { test, alternate, consequent } = exp;
|
|
528
|
-
test.type === "Identifier" ? callback(test) : this._deepFindIdOfExpression(test, callback);
|
|
529
|
-
this._deepFindIdOfExpression(consequent, callback);
|
|
530
|
-
this._deepFindIdOfExpression(alternate, callback);
|
|
531
|
-
} else if (exp.type === "TryStatement") {
|
|
532
|
-
const { block, finalizer } = exp;
|
|
533
|
-
this._deepFindIdOfExpression(block, callback);
|
|
534
|
-
finalizer && this._deepFindIdOfExpression(finalizer, callback);
|
|
535
|
-
} else if (exp.type === "SpreadElement") {
|
|
536
|
-
const { argument } = exp;
|
|
537
|
-
this.expressionTypeIsIdentifier(argument) && callback(argument);
|
|
538
|
-
} else if (exp.type === "JSXSpreadChild") {
|
|
539
|
-
const expression = exp.expression;
|
|
540
|
-
callback(expression);
|
|
541
|
-
} else if (exp.type === "MemberExpression" || exp.type === "JSXMemberExpression") {
|
|
542
|
-
const rootIdentifier = this.getRootIdentifierOfMemberExpression(exp);
|
|
543
|
-
this.expressionTypeIsIdentifier(rootIdentifier) && callback(rootIdentifier);
|
|
544
|
-
} else if (exp.type === "ObjectExpression") {
|
|
545
|
-
const properties = exp.properties;
|
|
546
|
-
for (const property of properties) {
|
|
547
|
-
if (property.type === "SpreadElement") {
|
|
548
|
-
this._deepFindIdOfExpression(property, callback);
|
|
549
|
-
} else {
|
|
550
|
-
const value = property.value;
|
|
551
|
-
this.expressionTypeIsIdentifier(value) ? callback(value) : this._deepFindIdOfExpression(value, callback);
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
} else if (exp.type === "ArrayExpression") {
|
|
555
|
-
const elements = exp.elements;
|
|
556
|
-
for (const element of elements) {
|
|
557
|
-
this.expressionTypeIsIdentifier(element) ? callback(element) : this._deepFindIdOfExpression(element, callback);
|
|
558
|
-
}
|
|
559
|
-
} else if (exp.type === "ArrowFunctionExpression") {
|
|
560
|
-
const body = exp.body;
|
|
561
|
-
this.expressionTypeIsIdentifier(body) ? callback(body) : this._deepFindIdOfExpression(body, callback);
|
|
562
|
-
} else if (exp.type === "CallExpression") {
|
|
563
|
-
const callee = exp.callee;
|
|
564
|
-
this.expressionTypeIsIdentifier(callee) ? callback(callee) : this._deepFindIdOfExpression(callee, callback);
|
|
565
|
-
const args = exp.arguments;
|
|
566
|
-
for (const argument of args) {
|
|
567
|
-
this.expressionTypeIsIdentifier(argument) ? callback(argument) : this._deepFindIdOfExpression(argument, callback);
|
|
568
|
-
}
|
|
569
|
-
} else if (exp.type === "AssignmentExpression" || exp.type === "BinaryExpression" || exp.type === "LogicalExpression") {
|
|
570
|
-
const { left, right } = exp;
|
|
571
|
-
[left, right].forEach((e) => this.expressionTypeIsIdentifier(e) ? callback(e) : this._deepFindIdOfExpression(e, callback));
|
|
572
|
-
} else if (exp.type === "UpdateExpression") {
|
|
573
|
-
const argument = exp.argument;
|
|
574
|
-
this.expressionTypeIsIdentifier(argument) ? callback(argument) : this._deepFindIdOfExpression(argument, callback);
|
|
575
|
-
} else if (exp.type === "SequenceExpression") {
|
|
576
|
-
const { expressions } = exp;
|
|
577
|
-
for (const expression of expressions) {
|
|
578
|
-
this.expressionTypeIsIdentifier(expression) ? callback(expression) : this._deepFindIdOfExpression(expression, callback);
|
|
579
|
-
}
|
|
580
|
-
} else if (exp.type === "ConditionalExpression") {
|
|
581
|
-
const { test, consequent, alternate } = exp;
|
|
582
|
-
[test, consequent, alternate].forEach((e) => this._deepFindIdOfExpression(e, callback));
|
|
583
|
-
} else if (exp.type === "JSXExpressionContainer") {
|
|
584
|
-
const { expression } = exp;
|
|
585
|
-
expression.name && callback(expression);
|
|
586
|
-
} else if (exp.type === "JSXIdentifier" && ((_a = exp._util.parent) == null ? void 0 : _a.type) !== "JSXAttribute") {
|
|
587
|
-
callback(exp);
|
|
588
|
-
} else if (exp.type === "JSXAttribute") {
|
|
589
|
-
const value = exp.value;
|
|
590
|
-
value && this._deepFindIdOfExpression(value, callback);
|
|
591
|
-
} else if (exp.type === "JSXElement") {
|
|
592
|
-
const openingElement = exp.openingElement;
|
|
593
|
-
this._deepFindIdOfExpression(openingElement, callback);
|
|
594
|
-
} else if (exp.type === "JSXOpeningElement") {
|
|
595
|
-
const { name, attributes } = exp;
|
|
596
|
-
this._deepFindIdOfExpression(name, callback);
|
|
597
|
-
for (const attribute of attributes) {
|
|
598
|
-
this._deepFindIdOfExpression(attribute, callback);
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
static getRootIdentifierOfMemberExpression(memExp) {
|
|
603
|
-
if (memExp.type === "MemberExpression" || memExp.type === "JSXMemberExpression") {
|
|
604
|
-
return this.getRootIdentifierOfMemberExpression(memExp.object);
|
|
605
|
-
}
|
|
606
|
-
return memExp;
|
|
607
|
-
}
|
|
608
578
|
static findIdOfImport(node, callback) {
|
|
609
579
|
const specifiers = node.specifiers;
|
|
610
580
|
for (const specifier of specifiers) {
|
|
@@ -709,14 +679,14 @@ var _AstUtil = class {
|
|
|
709
679
|
return id._util.variableScope.length === 0 && !this.isPropertyOfGlobal(id) && !this.isIntrinsicElement(id) && !this.isStandardAttribute(id);
|
|
710
680
|
}
|
|
711
681
|
static isPropertyOfGlobal(node) {
|
|
712
|
-
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);
|
|
713
683
|
}
|
|
714
684
|
static isIntrinsicElement(node) {
|
|
715
685
|
var _a;
|
|
716
|
-
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);
|
|
717
687
|
}
|
|
718
688
|
static isStandardAttribute(node) {
|
|
719
|
-
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);
|
|
720
690
|
}
|
|
721
691
|
static getTopScopeNodesByLineNumberRange(mapFileLineToNodeSet, lineNumberStart, lineNumberEnd) {
|
|
722
692
|
const nodeSet = /* @__PURE__ */ new Set();
|
|
@@ -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.slice(0, 1).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:
|
|
@@ -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[];
|
|
@@ -76,15 +76,19 @@ function createDetectReport(arg) {
|
|
|
76
76
|
const addNodeAndPaths = blockReport.addNodeAndPaths.filter((e) => fileAddedNodesPaths.includes(e.nodePath));
|
|
77
77
|
const infosList = addNodeAndPaths.map((item) => {
|
|
78
78
|
const { node } = item;
|
|
79
|
-
const { effectIds } = node._util;
|
|
79
|
+
const { effectIds, occupation, holdingIdType } = node._util;
|
|
80
80
|
return {
|
|
81
|
-
causeBy: import_AstUtil.default.getShortNodeMsg(node),
|
|
82
|
-
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))
|
|
83
87
|
};
|
|
84
88
|
});
|
|
85
89
|
return {
|
|
86
90
|
diff_txt,
|
|
87
|
-
infos: infosList.filter((e) => e.effects.length > 0)
|
|
91
|
+
infos: infosList.filter((e) => e.effects.length > 0 || e.occupations.length > 0)
|
|
88
92
|
};
|
|
89
93
|
}).filter((e) => e.infos.length > 0)
|
|
90
94
|
};
|
package/package.json
CHANGED
|
@@ -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
|
-
}
|