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.
@@ -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("准备clone源代码到临时目录下的target文件夹");
140
- await import_utils.execa.execa(`git clone ${gitUrl} ${today}/target`, { shell: "/bin/bash" });
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}/target && git fetch origin ${branchName}:${branchName} && git checkout ${branchName}`, { shell: "/bin/bash" });
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}/target && git diff master..${branchName} --unified=0 --output=${gitDiffFileName}`, { shell: "/bin/bash" });
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.ready("准备生成插件文件");
152
- (0, import_fs2.writeFileSync)((0, import_path.join)(process.cwd(), today, "target", "plugin.ts"), pluginFileContent, { encoding: "utf-8", flag: "w" });
153
- import_utils.logger.info("插件文件生成完成");
154
- import_utils.logger.wait("准备生成报告");
155
- await import_utils.execa.execa(`cd ${today}/target && yarn install && npm run build`, { shell: "/bin/bash" });
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, "target", jsonName), "utf-8");
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
- return `${node.name || node.type}「${startLine}:${startColumn}, ${endLine}:${endColumn}」`;
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
- const id = cur.id;
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.findIdOfVariable(cur, (id) => {
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
- const params = node.params;
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 { nodeCollection, dependenceIds, holdingIdNameMap } = node._util;
211
- nodeCollection.forEach((e) => {
212
- this.findExportIdentifiers(e, (id) => dependenceIds.add(id));
213
- this.collectExpressionIdentifiers(e, (id) => dependenceIds.add(id));
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
- const sameNameIds = [...holdingIdNameMap.get(dependenceId.name) || []];
218
- dependenceId._util.variableScope.push(...sameNameIds);
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.effectIds.add(dependenceId);
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 { id, init } = node;
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 { id, init } = node;
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, _c;
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._util.effectIds.add(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._util.effectIds.add(id);
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 idSet = /* @__PURE__ */ new Set();
329
- this._deepFindIdentifier(id, (ele) => idSet.add(ele));
330
- const createdExpIdSet = /* @__PURE__ */ new Set();
331
- ["Identifier", "ArrowFunctionExpression", "FunctionExpression"].includes(init.type) ? createdExpIdSet.add(init) : this.collectExpressionIdentifiers(init, (id2) => createdExpIdSet.add(id2));
332
- for (const createdId of idSet) {
333
- createdId._util.effectIds = /* @__PURE__ */ new Set([...createdExpIdSet, ...createdId._util.effectIds]);
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
- if (left.type === "Identifier") {
380
- const { left: left2 } = node;
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 collectExpressionIdentifiers(exp, callback) {
519
+ static collectExpressionIdentifiersShallow(exp, callback) {
422
520
  if (!exp || exp.type === "ThisExpression") {
423
521
  return;
424
522
  }
425
- this._collectExpressionIdentifiers(exp, callback);
523
+ this._collectExpressionIdentifiersShallow(exp, callback);
426
524
  }
427
- static _collectExpressionIdentifiers(exp, callback) {
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 deepFindIdOfExpression(exp, callback) {
548
+ static collectExpressionIdentifiers(exp, callback) {
452
549
  if (!exp || exp.type === "ThisExpression") {
453
550
  return;
454
551
  }
455
- this._deepFindIdOfExpression(exp, callback);
552
+ this._collectExpressionIdentifiers(exp, callback);
456
553
  }
457
- static _deepFindIdOfExpression(exp, callback) {
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.type === "IfStatement") {
463
- const { test, alternate, consequent } = exp;
464
- test.type === "Identifier" ? callback(test) : this._deepFindIdOfExpression(test, callback);
465
- this._deepFindIdOfExpression(consequent, callback);
466
- this._deepFindIdOfExpression(alternate, callback);
467
- } else if (exp.type === "TryStatement") {
468
- const { block, finalizer } = exp;
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
- } else if (exp.type === "ArrayExpression") {
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
- static getRootIdentifierOfMemberExpression(memExp) {
539
- if (memExp.type === "MemberExpression" || memExp.type === "JSXMemberExpression") {
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
- return memExp;
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 fileContent = require("fs").readFileSync(filePath, "utf8");
135
- return this.parseFile(filePath, fileContent)[1];
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, index) => files.map((file) => " ".repeat(index) + `- ${file}`)).flat().join("\n")}` : "",
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, index) {
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 { mapFileLineToNodeSet, mapUuidToNode } = (0, import_getAstKitByFilePath.default)(filePath, absPathPrefix);
64
- const filePathOfOld = (0, import_path.join)(process.cwd(), "..", import_constants.SOURCE, filePath);
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,3 @@
1
+ export declare function generateGitDiffReport(arg: {
2
+ targetDirPath: string;
3
+ }): Promise<void>;
@@ -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" | "add" | "modify";
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: [...effectIds].map((e) => import_AstUtil.default.getShortNodeMsg(e))
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.20",
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
- }