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 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("准备clone源代码到临时目录下的target文件夹");
143
- 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" });
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}/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" });
150
150
  import_utils.logger.info("分支切换完成");
151
151
  import_utils.logger.ready("准备生成git_diff.txt文件");
152
- 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" });
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}/target && npx max setup`, { shell: "/bin/bash" });
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, "target", jsonName), "utf-8");
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
- 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();
@@ -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 { type, _util } = node;
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
- const sameNameIds = [...holdingIdNameMap.get(dependenceId.name) || []];
249
- if (sameNameIds.length > 0) {
250
- dependenceId._util.variableScope.push(...sameNameIds);
251
- const firstPick = sameNameIds[0];
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 { id, init } = node;
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 { id, init } = node;
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, _c;
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._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
+ }
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._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
+ }
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 idSet = /* @__PURE__ */ new Set();
364
- this._deepFindIdentifier(id, (ele) => idSet.add(ele));
365
- const createdExpIdSet = /* @__PURE__ */ new Set();
366
- ["Identifier", "ArrowFunctionExpression", "FunctionExpression"].includes(init.type) ? createdExpIdSet.add(init) : this.collectExpressionIdentifiers(init, (id2) => createdExpIdSet.add(id2));
367
- for (const createdId of idSet) {
368
- 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]);
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
- if (left.type === "Identifier") {
415
- const { left: left2 } = node;
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, 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:
@@ -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[];
@@ -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: [...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))
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,6 +1,6 @@
1
1
  {
2
2
  "name": "js-code-detector",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.js",
6
6
  "types": "dist/cjs/index.d.ts",
@@ -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
- }