auto-cr-rules 2.0.76 → 2.0.78

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.
@@ -16,10 +16,19 @@ exports.noCircularDependencies = void 0;
16
16
  var fs_1 = __importDefault(require("fs"));
17
17
  var path_1 = __importDefault(require("path"));
18
18
  var types_1 = require("../types");
19
+ /**
20
+ * 检测相对路径形成的循环依赖:
21
+ * - 仅解析 .ts/.tsx/.js/.jsx/.mjs/.cjs;
22
+ * - 从当前文件的 import 出发,沿依赖图寻找回到自身的路径;
23
+ * - 输出完整环路链路,便于定位循环发生的文件。
24
+ */
19
25
  var SUPPORTED_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
26
+ // 避免在大型仓库里构图过深或过大导致卡顿。
20
27
  var MAX_GRAPH_NODES = 2000;
21
28
  var MAX_GRAPH_DEPTH = 80;
29
+ // 跨文件缓存解析结果,减少重复 IO 与正则扫描。
22
30
  var resolvedImportCache = new Map();
31
+ // 记录已上报的环路(做规范化),避免同一环路重复报错。
23
32
  var reportedCycles = new Set();
24
33
  exports.noCircularDependencies = (0, types_1.defineRule)('no-circular-dependencies', { tag: 'base', severity: types_1.RuleSeverity.Warning }, function (_a) {
25
34
  var _b, _c;
@@ -28,7 +37,7 @@ exports.noCircularDependencies = (0, types_1.defineRule)('no-circular-dependenci
28
37
  var root = resolveProjectRoot(origin);
29
38
  var moduleStart = (_c = (_b = ast.span) === null || _b === void 0 ? void 0 : _b.start) !== null && _c !== void 0 ? _c : 0;
30
39
  var lineIndex = buildLineIndex(source);
31
- // Seed cache with SWC-collected imports for the current file.
40
+ // 先用 SWC 提供的 import 列表初始化当前文件的依赖,保证准确性与性能。
32
41
  resolvedImportCache.set(origin, resolveFromReferences(origin, helpers.imports, root));
33
42
  for (var _i = 0, _d = helpers.imports; _i < _d.length; _i++) {
34
43
  var reference = _d[_i];
@@ -39,6 +48,7 @@ exports.noCircularDependencies = (0, types_1.defineRule)('no-circular-dependenci
39
48
  if (!target) {
40
49
  continue;
41
50
  }
51
+ // 从目标模块回溯,如果能再次回到 origin,即存在环路。
42
52
  var pathToOrigin = findPathToOrigin(target, origin, root);
43
53
  if (!pathToOrigin) {
44
54
  continue;
@@ -49,6 +59,7 @@ exports.noCircularDependencies = (0, types_1.defineRule)('no-circular-dependenci
49
59
  continue;
50
60
  }
51
61
  reportedCycles.add(cycleKey);
62
+ // 统一输出相对路径,便于直接定位到仓库内文件。
52
63
  var displayChain = formatCycle(cycle, root);
53
64
  var description = messages.circularDependency({ chain: displayChain });
54
65
  var suggestions = language === 'zh'
@@ -60,6 +71,7 @@ exports.noCircularDependencies = (0, types_1.defineRule)('no-circular-dependenci
60
71
  { text: 'Split modules to avoid mutual dependencies.' },
61
72
  { text: 'Extract shared logic into a dedicated module to break the cycle.' },
62
73
  ];
74
+ // 优先使用 SWC 的 span 计算行号,作为高可信位置;失败时再用文本匹配兜底。
63
75
  var computedLine = reference.span
64
76
  ? resolveLine(lineIndex, bytePosToCharIndex(source, moduleStart, reference.span.start))
65
77
  : undefined;
@@ -74,6 +86,7 @@ exports.noCircularDependencies = (0, types_1.defineRule)('no-circular-dependenci
74
86
  }, reference.span);
75
87
  }
76
88
  });
89
+ // 选择项目根目录:优先使用当前工作目录,找不到则向上寻找最近的 package.json。
77
90
  var resolveProjectRoot = function (filePath) {
78
91
  var cwd = path_1.default.resolve(process.cwd());
79
92
  if (isWithinRoot(filePath, cwd)) {
@@ -90,10 +103,12 @@ var resolveProjectRoot = function (filePath) {
90
103
  }
91
104
  return cwd;
92
105
  };
106
+ // 防止解析路径逃逸到仓库外,避免跨项目误报。
93
107
  var isWithinRoot = function (filePath, root) {
94
108
  var relative = path_1.default.relative(root, filePath);
95
109
  return relative === '' || (!relative.startsWith('..') && !path_1.default.isAbsolute(relative));
96
110
  };
111
+ // 将当前文件的 import 列表解析为真实文件路径(只处理相对路径)。
97
112
  var resolveFromReferences = function (origin, references, root) {
98
113
  var resolved = new Set();
99
114
  for (var _i = 0, references_1 = references; _i < references_1.length; _i++) {
@@ -108,6 +123,8 @@ var resolveFromReferences = function (origin, references, root) {
108
123
  }
109
124
  return Array.from(resolved);
110
125
  };
126
+ // DFS 搜索依赖图中是否存在一条从 start 回到 origin 的路径。
127
+ // 通过节点数与深度上限,避免超大项目中搜索失控。
111
128
  var findPathToOrigin = function (start, origin, root) {
112
129
  var nodesVisited = 0;
113
130
  var visiting = new Set();
@@ -145,6 +162,8 @@ var findPathToOrigin = function (start, origin, root) {
145
162
  };
146
163
  return walk(start, 0);
147
164
  };
165
+ // 读取文件并通过简单正则抽取 import/require/export-from。
166
+ // 这里不重新解析 AST,成本低但可能漏掉非常规写法。
148
167
  var getResolvedImports = function (filePath, root) {
149
168
  var cached = resolvedImportCache.get(filePath);
150
169
  if (cached) {
@@ -179,6 +198,7 @@ var readFileSafe = function (filePath) {
179
198
  return null;
180
199
  }
181
200
  };
201
+ // 用正则匹配常见的导入写法,覆盖 import / dynamic import / require / export-from。
182
202
  var extractImportSpecifiers = function (source) {
183
203
  var results = [];
184
204
  var patterns = [
@@ -196,6 +216,8 @@ var extractImportSpecifiers = function (source) {
196
216
  }
197
217
  return results;
198
218
  };
219
+ // 解析相对路径到真实文件:支持自动补全扩展名与目录 index。
220
+ // 并确保解析结果在项目根目录内。
199
221
  var resolveImportFile = function (fromFile, specifier, root) {
200
222
  if (!specifier.startsWith('.')) {
201
223
  return null;
@@ -267,6 +289,7 @@ var resolveFromDirectory = function (basePath) {
267
289
  }
268
290
  return null;
269
291
  };
292
+ // 将环路规范化为稳定 key,避免同一环路从不同入口重复报错。
270
293
  var buildCycleKey = function (cycle) {
271
294
  if (cycle.length <= 2) {
272
295
  return cycle.join('->');
@@ -282,6 +305,7 @@ var buildCycleKey = function (cycle) {
282
305
  }
283
306
  return best;
284
307
  };
308
+ // 输出尽量相对路径,便于直接定位文件。
285
309
  var formatCycle = function (cycle, root) {
286
310
  var formatted = cycle.map(function (entry) {
287
311
  var relative = path_1.default.relative(root, entry);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auto-cr-rules",
3
- "version": "2.0.76",
3
+ "version": "2.0.78",
4
4
  "description": "Extensible static analysis rule set for the auto-cr automated code review toolkit",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/types/index.d.ts",