mm_eslint 1.5.0 → 1.5.2

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.
@@ -10,6 +10,23 @@ class ConstName extends Name {
10
10
  }
11
11
  }
12
12
 
13
+ /**
14
+ * 判断节点是否在for...of或for...in循环中
15
+ * @param {Object} node - AST节点
16
+ * @returns {boolean} 是否在for...of或for...in循环中
17
+ */
18
+ ConstName.prototype._isInForOfLoop = function (node) {
19
+ let current_node = node;
20
+ while (current_node.parent) {
21
+ // 检查父节点是否为ForOfStatement或ForInStatement
22
+ if (current_node.parent.type === 'ForOfStatement' || current_node.parent.type === 'ForInStatement') {
23
+ return true;
24
+ }
25
+ current_node = current_node.parent;
26
+ }
27
+ return false;
28
+ }
29
+
13
30
  /**
14
31
  * 变量声明节点检测函数(常量声明)
15
32
  * @param {Object} node - 变量声明节点
@@ -46,6 +63,11 @@ ConstName.prototype.VariableDeclaration = function (node) {
46
63
  continue;
47
64
  }
48
65
 
66
+ // 排除for...of和for...in循环中的const声明
67
+ if (this._isInForOfLoop(node)) {
68
+ continue;
69
+ }
70
+
49
71
  // 判断是否为常量(包括 Object.freeze() 等情况)
50
72
  if (this._isConstantValue(decl.init)) {
51
73
  // 检测常量名
@@ -200,6 +222,11 @@ ConstName.prototype._isConstantValue = function (value_node) {
200
222
  return false; // 其他函数调用不是常量
201
223
  }
202
224
 
225
+ // 排除await表达式
226
+ if (value_node.type === 'AwaitExpression') {
227
+ return false; // await表达式的结果通常是可变的,不是常量
228
+ }
229
+
203
230
  // 默认情况下,如果不是排除的类型,就认为是常量
204
231
  return true;
205
232
  }
@@ -500,10 +527,28 @@ ConstName.prototype.ExportNamedDeclaration = function (node) {
500
527
  for (let i = 0; i < node.declaration.declarations.length; i++) {
501
528
  let declaration = node.declaration.declarations[i];
502
529
  if (declaration.id && declaration.id.type === 'Identifier') {
503
- let name = declaration.id.name;
504
- let error = this.check(node, name, 'export-constant');
505
- this.report(node, error, 'export-constant');
506
- return error;
530
+ // 排除函数:如果右边是函数表达式或箭头函数,则不是常量
531
+ if (declaration.init && (declaration.init.type === 'FunctionExpression' || declaration.init.type === 'ArrowFunctionExpression')) {
532
+ return;
533
+ }
534
+
535
+ // 排除类:如果右边是类表达式,则不是常量
536
+ if (declaration.init && declaration.init.type === 'ClassExpression') {
537
+ return;
538
+ }
539
+
540
+ // 排除类实例:如果右边是 new 表达式,则不是常量
541
+ if (declaration.init && declaration.init.type === 'NewExpression') {
542
+ return;
543
+ }
544
+
545
+ // 判断是否为常量(包括 Object.freeze() 等情况)
546
+ if (this._isConstantValue(declaration.init)) {
547
+ let name = declaration.id.name;
548
+ let error = this.check(node, name, 'export-constant');
549
+ this.report(node, error, 'export-constant');
550
+ return error;
551
+ }
507
552
  }
508
553
  }
509
554
  }
@@ -79,25 +79,9 @@ VariableName.prototype.VariableDeclaration = function (node) {
79
79
  // 检测变量名
80
80
  let name = decl.id.name;
81
81
 
82
- // 对于const声明,只处理右边是CallExpression的情况
83
- if (decl.init && decl.init.type === 'CallExpression') {
84
- // 排除require()调用,因为导入的模块类型无法确定
85
- if (decl.init.callee && decl.init.callee.type === 'Identifier' && decl.init.callee.name === 'require') {
86
- return; // 跳过require()调用
87
- }
88
-
89
- // 排除Object.freeze()等常量函数调用
90
- if (decl.init.callee && decl.init.callee.type === 'MemberExpression' &&
91
- decl.init.callee.object && decl.init.callee.object.type === 'Identifier' &&
92
- decl.init.callee.object.name === 'Object' && decl.init.callee.property &&
93
- decl.init.callee.property.type === 'Identifier' && (
94
- decl.init.callee.property.name === 'freeze' ||
95
- decl.init.callee.property.name === 'seal' ||
96
- decl.init.callee.property.name === 'preventExtensions'
97
- )) {
98
- return; // 跳过常量函数调用
99
- }
100
-
82
+ // 检查是否在for...of循环中
83
+ if (this._isInForLoop(node)) {
84
+ // 在for...of循环中的const声明应该使用let
101
85
  let error = {
102
86
  message: `变量'${name}'应该使用let标签声明而不是const标签声明`,
103
87
  fix: function(fixer) {
@@ -107,6 +91,50 @@ VariableName.prototype.VariableDeclaration = function (node) {
107
91
  this.report(node, error, 'variable');
108
92
  return error;
109
93
  }
94
+
95
+ // 对于const声明,处理右边是CallExpression或AwaitExpression的情况
96
+ if (decl.init) {
97
+ // 对于AwaitExpression,直接处理
98
+ if (decl.init.type === 'AwaitExpression') {
99
+ let error = {
100
+ message: `变量'${name}'应该使用let标签声明而不是const标签声明`,
101
+ fix: function(fixer) {
102
+ return fixer.replaceTextRange([node.range[0], node.range[0] + 5], 'let');
103
+ }
104
+ };
105
+ this.report(node, error, 'variable');
106
+ return error;
107
+ }
108
+
109
+ // 对于CallExpression,进行详细排除检查
110
+ else if (decl.init.type === 'CallExpression') {
111
+ // 排除require()调用,因为导入的模块类型无法确定
112
+ if (decl.init.callee && decl.init.callee.type === 'Identifier' && decl.init.callee.name === 'require') {
113
+ return; // 跳过require()调用
114
+ }
115
+
116
+ // 排除Object.freeze()等常量函数调用
117
+ if (decl.init.callee && decl.init.callee.type === 'MemberExpression' &&
118
+ decl.init.callee.object && decl.init.callee.object.type === 'Identifier' &&
119
+ decl.init.callee.object.name === 'Object' && decl.init.callee.property &&
120
+ decl.init.callee.property.type === 'Identifier' && (
121
+ decl.init.callee.property.name === 'freeze' ||
122
+ decl.init.callee.property.name === 'seal' ||
123
+ decl.init.callee.property.name === 'preventExtensions'
124
+ )) {
125
+ return; // 跳过常量函数调用
126
+ }
127
+
128
+ let error = {
129
+ message: `变量'${name}'应该使用let标签声明而不是const标签声明`,
130
+ fix: function(fixer) {
131
+ return fixer.replaceTextRange([node.range[0], node.range[0] + 5], 'let');
132
+ }
133
+ };
134
+ this.report(node, error, 'variable');
135
+ return error;
136
+ }
137
+ }
110
138
  // 对于const声明的其他情况,跳过变量规则检测(由常量规则处理)
111
139
  return;
112
140
  }
@@ -114,32 +142,6 @@ VariableName.prototype.VariableDeclaration = function (node) {
114
142
  }
115
143
  }
116
144
 
117
- // /**
118
- // * 标识符引用节点检测函数(变量引用)
119
- // * @param {Object} node - 标识符节点
120
- // * @returns {Object|undefined} - 检测结果对象或undefined
121
- // */
122
- // VariableName.prototype.Identifier = function (node) {
123
- // // 检测标识符引用(如表达式中的 Name、Age)
124
- // if (node.type === 'Identifier') {
125
- // let name = node.name;
126
-
127
- // // 使用精确的类型识别逻辑
128
- // let original_type = this._getOriginalType(node, 'Identifier');
129
-
130
- // // 只有当确实是变量引用时才进行变量命名规则检测
131
- // if (original_type === 'variable' || original_type === 'unknown') {
132
- // let error = this.check(node, name, original_type);
133
-
134
- // // 如果检测到错误,报告错误
135
- // if (error) {
136
- // this.report(node, error, original_type);
137
- // return error;
138
- // }
139
- // }
140
- // }
141
- // };
142
-
143
145
  /**
144
146
  * 属性节点检测函数(变量属性)
145
147
  * @param {Object} node - 属性节点
@@ -323,6 +325,23 @@ VariableName.prototype.ExportNamedDeclaration = function (node) {
323
325
  }
324
326
  }
325
327
 
328
+ /**
329
+ * 判断节点是否在for...of或for...in循环中
330
+ * @param {Object} node - AST节点
331
+ * @returns {boolean} 是否在for...of或for...in循环中
332
+ */
333
+ VariableName.prototype._isInForLoop = function (node) {
334
+ let current_node = node;
335
+ while (current_node.parent) {
336
+ // 检查父节点是否为ForOfStatement或ForInStatement
337
+ if (current_node.parent.type === 'ForOfStatement' || current_node.parent.type === 'ForInStatement') {
338
+ return true;
339
+ }
340
+ current_node = current_node.parent;
341
+ }
342
+ return false;
343
+ }
344
+
326
345
  module.exports = {
327
346
  VariableName
328
347
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mm_eslint",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "ESLint plugin for personal naming conventions - supports PascalCase, camelCase, snake_case, and UPPER_SNAKE_CASE naming rules with intelligent recommendations",
5
5
  "main": "index.js",
6
6
  "keywords": [