mm_eslint 1.4.5 → 1.4.7
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/README.md +26 -0
- package/README_EN.md +27 -1
- package/index.js +153 -297
- package/{config.js → lib/config.js} +59 -32
- package/lib/detector/class_instance_name.js +246 -0
- package/lib/detector/class_name.js +261 -0
- package/lib/detector/const_name.js +529 -0
- package/lib/detector/function_name.js +318 -0
- package/lib/detector/index.js +18 -0
- package/lib/detector/name.js +626 -0
- package/lib/detector/object_name.js +245 -0
- package/lib/detector/param_name.js +247 -0
- package/lib/detector/variable_name.js +286 -0
- package/lib/fix/class_fix.js +83 -0
- package/lib/fix/export_fix.js +169 -0
- package/lib/fix/function_fix.js +85 -0
- package/lib/fix/index.js +21 -0
- package/lib/fix/method_fix.js +82 -0
- package/lib/fix/param_fix.js +63 -0
- package/lib/fix/property_fix.js +93 -0
- package/lib/fix/variable_fix.js +134 -0
- package/lib/fix.js +160 -0
- package/{util.js → lib/util.js} +8 -0
- package/{validator.js → lib/validator.js} +3 -3
- package/package.json +10 -13
- package/detector.js +0 -1291
- package/eslint.config.js +0 -25
- package/fix.js +0 -441
- package/handler.js +0 -993
- /package/{corrector.js → lib/corrector.js} +0 -0
- /package/{tip.js → lib/tip.js} +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
const { Name } = require('./name.js');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 变量名检测器类
|
|
5
|
+
* 负责检测变量名是否符合命名规范
|
|
6
|
+
*/
|
|
7
|
+
class ObjectName extends Name {
|
|
8
|
+
constructor(context, config) {
|
|
9
|
+
super(context, config);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 对象声明节点检测函数
|
|
15
|
+
* @param {Object} node - 对象声明节点
|
|
16
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
17
|
+
*/
|
|
18
|
+
ObjectName.prototype.VariableDeclaration = function (node) {
|
|
19
|
+
// 检测变量声明(let 和 var)
|
|
20
|
+
if (node.kind === 'let' || node.kind === 'var') {
|
|
21
|
+
// 如果右边是对象或数组字面量(ObjectExpression),则是对象
|
|
22
|
+
if (node.type === 'ObjectExpression' || node.type === 'ArrayExpression') {
|
|
23
|
+
// 检测变量名
|
|
24
|
+
let name = node.id.name;
|
|
25
|
+
let original_type = 'object';
|
|
26
|
+
let error = this.check(node.id, name, original_type);
|
|
27
|
+
this.report(node.id, error, original_type);
|
|
28
|
+
|
|
29
|
+
if (error) {
|
|
30
|
+
return error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
for (let i = 0; i < node.declarations.length; i++) {
|
|
35
|
+
let decl = node.declarations[i];
|
|
36
|
+
if (decl.id && decl.id.type === 'Identifier') {
|
|
37
|
+
// 排除类实例:如果右边是 new 表达式,则不是变量
|
|
38
|
+
if (decl.init && decl.init.type === 'NewExpression') {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 排除正则表达式字面量(RegExp实例)
|
|
43
|
+
if (decl.init && decl.init.type === 'Literal' && decl.init.regex) {
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 排除函数:如果右边是函数表达式或箭头函数,则不是变量
|
|
48
|
+
if (decl.init && (decl.init.type === 'FunctionExpression' || decl.init.type === 'ArrowFunctionExpression')) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 排除类:如果右边是类表达式,则不是变量
|
|
53
|
+
if (decl.init && decl.init.type === 'ClassExpression') {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// 排除基本类型字面量:布尔值、数字、字符串等
|
|
58
|
+
if (decl.init && decl.init.type === 'Literal') {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 检测变量名(仅处理真正的对象类型)
|
|
63
|
+
let name = decl.id.name;
|
|
64
|
+
let original_type = 'object';
|
|
65
|
+
let error = this.check(decl.id, name, original_type);
|
|
66
|
+
this.report(decl.id, error, original_type);
|
|
67
|
+
|
|
68
|
+
if (error) {
|
|
69
|
+
return error;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 属性节点检测函数(对象属性)
|
|
78
|
+
* @param {Object} node - 属性节点
|
|
79
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
80
|
+
*/
|
|
81
|
+
ObjectName.prototype.Property = function (node) {
|
|
82
|
+
// 判断右边是否为对象值
|
|
83
|
+
if (node.key && node.key.type === 'Identifier') {
|
|
84
|
+
// 排除类实例:如果右边是 new 表达式,则不是对象属性
|
|
85
|
+
if (node.value && node.value.type === 'NewExpression') {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 排除函数:如果右边是函数表达式或箭头函数,则不是对象属性
|
|
90
|
+
if (node.value && (node.value.type === 'FunctionExpression' || node.value.type === 'ArrowFunctionExpression')) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 排除类:如果右边是类表达式,则不是对象属性
|
|
95
|
+
if (node.value && node.value.type === 'ClassExpression') {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// 排除正则表达式字面量(RegExp实例)
|
|
100
|
+
if (node.value && node.value.type === 'Literal' && node.value.regex) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 如果右边是对象字面量(ObjectExpression)或数组字面量(ArrayExpression),则是对象
|
|
105
|
+
if (node.value && (node.value.type === 'ObjectExpression' || node.value.type === 'ArrayExpression')) {
|
|
106
|
+
// 检查属性是否在常量对象中,如果是则跳过对象检测(由常量检测器处理)
|
|
107
|
+
if (this._isInConstantObject(node)) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let name = node.key.name;
|
|
112
|
+
let error = this.check(node, name, 'property-object');
|
|
113
|
+
this.report(node, error, 'property-object');
|
|
114
|
+
return error;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// 使用 _getOriginalType 方法判断属性值的类型
|
|
118
|
+
// 只有当属性值是变量时,才检测属性名
|
|
119
|
+
let original_type = this._getOriginalType(node, 'Property');
|
|
120
|
+
if (original_type === 'object') {
|
|
121
|
+
let name = node.key.name;
|
|
122
|
+
let error = this.check(node, name, 'property-object');
|
|
123
|
+
this.report(node, error, 'property-object');
|
|
124
|
+
return error;
|
|
125
|
+
}
|
|
126
|
+
else if (original_type === 'unknown') {
|
|
127
|
+
let name = node.key.name;
|
|
128
|
+
let error = this.check(node, name, 'property');
|
|
129
|
+
this.report(node, error, 'property');
|
|
130
|
+
return error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* 属性定义节点检测函数(类属性)
|
|
139
|
+
* @param {Object} node - 属性定义节点
|
|
140
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
141
|
+
*/
|
|
142
|
+
ObjectName.prototype.PropertyDefinition = function (node) {
|
|
143
|
+
// 如果右边是对象或数组字面量(ObjectExpression),则是对象属性
|
|
144
|
+
if (node.value && (node.value.type === 'ObjectExpression' || node.value.type === 'ArrayExpression')) {
|
|
145
|
+
let name = node.key.name;
|
|
146
|
+
let error = this.check(node, name, 'property-object');
|
|
147
|
+
this.report(node, error, 'property-object');
|
|
148
|
+
return error;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 排除类实例、函数、类表达式
|
|
152
|
+
if (node.value && (node.value.type === 'NewExpression' || node.value.type === 'FunctionExpression' || node.value.type === 'ArrowFunctionExpression' || node.value.type === 'ClassExpression')) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// 检测属性定义(类属性)
|
|
157
|
+
if (node.key && node.key.type === 'Identifier') {
|
|
158
|
+
let name = node.key.name;
|
|
159
|
+
let type = this._getOriginalType(node, 'PropertyDefinition');
|
|
160
|
+
if (type === 'object') {
|
|
161
|
+
let original_type = 'property-object';
|
|
162
|
+
if (node.static) {
|
|
163
|
+
original_type = 'static-object';
|
|
164
|
+
}
|
|
165
|
+
else if (node.key.type === 'PrivateIdentifier') {
|
|
166
|
+
original_type = 'private-object';
|
|
167
|
+
}
|
|
168
|
+
else if (name.startsWith('_')) {
|
|
169
|
+
original_type = 'internal-object';
|
|
170
|
+
}
|
|
171
|
+
let error = this.check(node, name, original_type);
|
|
172
|
+
this.report(node, error, original_type);
|
|
173
|
+
return error;
|
|
174
|
+
}
|
|
175
|
+
else if (type === 'unknown') {
|
|
176
|
+
let name = node.key.name;
|
|
177
|
+
let error = this.check(node, name, 'property');
|
|
178
|
+
this.report(node, error, 'property');
|
|
179
|
+
return error;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* 默认导出节点检测函数(对象导出)
|
|
188
|
+
* @param {Object} node - 默认导出节点
|
|
189
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
190
|
+
*/
|
|
191
|
+
ObjectName.prototype.ExportDefaultDeclaration = function (node) {
|
|
192
|
+
// 检测导出的对象名
|
|
193
|
+
if (node.declaration && node.declaration.type === 'Identifier') {
|
|
194
|
+
let type = this._getOriginalType(node.declaration, 'ExportDefaultDeclaration');
|
|
195
|
+
if (type === 'object') {
|
|
196
|
+
let name = node.declaration.name;
|
|
197
|
+
let original_type = 'export-object';
|
|
198
|
+
let error = this.check(node.declaration, name, original_type);
|
|
199
|
+
this.report(node.declaration, error, original_type);
|
|
200
|
+
return error;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* 命名导出节点检测函数(对象导出)
|
|
207
|
+
* @param {Object} node - 命名导出节点
|
|
208
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
209
|
+
*/
|
|
210
|
+
ObjectName.prototype.ExportNamedDeclaration = function (node) {
|
|
211
|
+
// 检测命名导出的函数引用
|
|
212
|
+
if (node.specifiers && node.specifiers.length > 0) {
|
|
213
|
+
for (let i = 0; i < node.specifiers.length; i++) {
|
|
214
|
+
let specifier = node.specifiers[i];
|
|
215
|
+
|
|
216
|
+
// 检测导出的标识符(避免重复检测)
|
|
217
|
+
// 优先检测 exported 属性,如果存在则使用它,否则使用 local 属性
|
|
218
|
+
let identifier_to_check = null;
|
|
219
|
+
let identifier_name = '';
|
|
220
|
+
|
|
221
|
+
if (specifier.exported && specifier.exported.type === 'Identifier') {
|
|
222
|
+
identifier_to_check = specifier.exported;
|
|
223
|
+
identifier_name = specifier.exported.name;
|
|
224
|
+
} else if (specifier.local && specifier.local.type === 'Identifier') {
|
|
225
|
+
identifier_to_check = specifier.local;
|
|
226
|
+
identifier_name = specifier.local.name;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 只有当找到有效标识符时才进行检测
|
|
230
|
+
if (identifier_to_check) {
|
|
231
|
+
let original_type = this._getOriginalType(specifier, 'ExportSpecifier');
|
|
232
|
+
|
|
233
|
+
// 只有当导出的是对象时才检测
|
|
234
|
+
if (original_type === 'object') {
|
|
235
|
+
let error = this.check(identifier_to_check, identifier_name, 'export-object');
|
|
236
|
+
this.report(identifier_to_check, error, 'export-object');
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
module.exports = {
|
|
244
|
+
ObjectName
|
|
245
|
+
};
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
const { Name } = require('./name.js');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 参数名检测器类
|
|
5
|
+
* 负责检测参数名是否符合命名规范
|
|
6
|
+
*/
|
|
7
|
+
class ParamName extends Name {
|
|
8
|
+
constructor(context, config) {
|
|
9
|
+
super(context, config);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 函数声明节点检测函数(参数检测)
|
|
15
|
+
* @param {Object} node - 函数声明节点
|
|
16
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
17
|
+
*/
|
|
18
|
+
ParamName.prototype.FunctionDeclaration = function (node) {
|
|
19
|
+
// 检测函数参数
|
|
20
|
+
if (node.params && node.params.length > 0) {
|
|
21
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
22
|
+
let param = node.params[i];
|
|
23
|
+
if (param.type === 'Identifier') {
|
|
24
|
+
let name = param.name;
|
|
25
|
+
// 根据函数体内的使用方式判断参数类型
|
|
26
|
+
let original_type = this._getParameterType(node, param);
|
|
27
|
+
if (original_type === 'unknown') {
|
|
28
|
+
original_type = 'param';
|
|
29
|
+
}
|
|
30
|
+
let error = this.check(param, name, original_type);
|
|
31
|
+
this.report(param, error, original_type);
|
|
32
|
+
|
|
33
|
+
if (error) {
|
|
34
|
+
return error;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* 函数表达式节点检测函数(参数检测)
|
|
43
|
+
* @param {Object} node - 函数表达式节点
|
|
44
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
45
|
+
*/
|
|
46
|
+
ParamName.prototype.FunctionExpression = function (node) {
|
|
47
|
+
// 检测函数参数
|
|
48
|
+
if (node.params && node.params.length > 0) {
|
|
49
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
50
|
+
let param = node.params[i];
|
|
51
|
+
if (param.type === 'Identifier') {
|
|
52
|
+
let name = param.name;
|
|
53
|
+
// 根据函数体内的使用方式判断参数类型
|
|
54
|
+
let original_type = this._getParameterType(node, param);
|
|
55
|
+
if (original_type === 'unknown') {
|
|
56
|
+
original_type = 'param';
|
|
57
|
+
}
|
|
58
|
+
let error = this.check(param, name, original_type);
|
|
59
|
+
this.report(param, error, original_type);
|
|
60
|
+
|
|
61
|
+
if (error) {
|
|
62
|
+
return error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* 箭头函数表达式节点检测函数(参数检测)
|
|
71
|
+
* @param {Object} node - 箭头函数表达式节点
|
|
72
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
73
|
+
*/
|
|
74
|
+
ParamName.prototype.ArrowFunctionExpression = function (node) {
|
|
75
|
+
// 检测箭头函数参数
|
|
76
|
+
if (node.params && node.params.length > 0) {
|
|
77
|
+
for (let i = 0; i < node.params.length; i++) {
|
|
78
|
+
let param = node.params[i];
|
|
79
|
+
if (param.type === 'Identifier') {
|
|
80
|
+
let name = param.name;
|
|
81
|
+
// 根据函数体内的使用方式判断参数类型
|
|
82
|
+
let original_type = this._getParameterType(node, param);
|
|
83
|
+
if (original_type === 'unknown') {
|
|
84
|
+
original_type = 'param';
|
|
85
|
+
}
|
|
86
|
+
let error = this.check(param, name, original_type);
|
|
87
|
+
this.report(param, error, original_type);
|
|
88
|
+
|
|
89
|
+
if (error) {
|
|
90
|
+
return error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* 方法定义节点检测函数(参数检测)
|
|
99
|
+
* @param {Object} node - 方法定义节点
|
|
100
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
101
|
+
*/
|
|
102
|
+
ParamName.prototype.MethodDefinition = function (node) {
|
|
103
|
+
// 检测类方法参数
|
|
104
|
+
if (node.value && node.value.params && node.value.params.length > 0) {
|
|
105
|
+
for (let i = 0; i < node.value.params.length; i++) {
|
|
106
|
+
let param = node.value.params[i];
|
|
107
|
+
if (param.type === 'Identifier') {
|
|
108
|
+
let name = param.name;
|
|
109
|
+
// 根据函数体内的使用方式判断参数类型
|
|
110
|
+
let original_type = this._getParameterType(node.value, param);
|
|
111
|
+
if (original_type === 'unknown') {
|
|
112
|
+
original_type = 'param';
|
|
113
|
+
}
|
|
114
|
+
let error = this.check(node, name, original_type);
|
|
115
|
+
this.report(node, error, original_type);
|
|
116
|
+
|
|
117
|
+
if (error) {
|
|
118
|
+
return error;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* 新表达式节点检测函数(参数检测)
|
|
127
|
+
* @param {Object} node - 新表达式节点
|
|
128
|
+
* @returns {Object|undefined} - 检测结果对象或undefined
|
|
129
|
+
*/
|
|
130
|
+
ParamName.prototype.NewExpression = function (node) {
|
|
131
|
+
// 检测新表达式中的参数
|
|
132
|
+
if (node.arguments && node.arguments.length > 0) {
|
|
133
|
+
for (let i = 0; i < node.arguments.length; i++) {
|
|
134
|
+
let arg = node.arguments[i];
|
|
135
|
+
if (arg.type === 'Identifier') {
|
|
136
|
+
let name = arg.name;
|
|
137
|
+
let original_type = 'param';
|
|
138
|
+
let error = this.check(node, name, original_type);
|
|
139
|
+
this.report(node, error, original_type);
|
|
140
|
+
|
|
141
|
+
if (error) {
|
|
142
|
+
return error;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* 根据函数体内的使用方式判断参数类型
|
|
151
|
+
* @param {Object} node - 函数节点
|
|
152
|
+
* @param {Object} param - 参数节点
|
|
153
|
+
* @returns {string} 参数类型
|
|
154
|
+
*/
|
|
155
|
+
ParamName.prototype._getParameterType = function (node, param) {
|
|
156
|
+
const param_name = param.name;
|
|
157
|
+
|
|
158
|
+
// 如果没有函数体,默认返回基本参数类型
|
|
159
|
+
if (!node.body || !node.body.body) {
|
|
160
|
+
return 'param';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 遍历函数体内的语句,分析参数的使用方式
|
|
164
|
+
const statements = node.body.body;
|
|
165
|
+
let is_function = false;
|
|
166
|
+
let is_class = false;
|
|
167
|
+
let is_class_instance = false;
|
|
168
|
+
let is_object = false;
|
|
169
|
+
|
|
170
|
+
// 如果statements不是数组,直接返回基本参数类型
|
|
171
|
+
if (!Array.isArray(statements)) {
|
|
172
|
+
return 'param';
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// 使用Set来避免循环引用
|
|
176
|
+
const visited = new Set();
|
|
177
|
+
|
|
178
|
+
// 递归遍历AST节点
|
|
179
|
+
const traverse = (ast_node) => {
|
|
180
|
+
if (!ast_node || visited.has(ast_node)) return;
|
|
181
|
+
visited.add(ast_node);
|
|
182
|
+
|
|
183
|
+
// 检查是否作为函数调用
|
|
184
|
+
if (ast_node.type === 'CallExpression' &&
|
|
185
|
+
ast_node.callee &&
|
|
186
|
+
ast_node.callee.type === 'Identifier' &&
|
|
187
|
+
ast_node.callee.name === param_name) {
|
|
188
|
+
is_function = true;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// 检查是否作为类实例化
|
|
193
|
+
if (ast_node.type === 'NewExpression' &&
|
|
194
|
+
ast_node.callee &&
|
|
195
|
+
ast_node.callee.type === 'Identifier' &&
|
|
196
|
+
ast_node.callee.name === param_name) {
|
|
197
|
+
is_class = true;
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// 检查是否作为对象使用(访问属性)
|
|
202
|
+
if (ast_node.type === 'MemberExpression' &&
|
|
203
|
+
ast_node.object &&
|
|
204
|
+
ast_node.object.type === 'Identifier' &&
|
|
205
|
+
ast_node.object.name === param_name) {
|
|
206
|
+
is_object = true;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// 递归遍历子节点,只遍历特定的属性
|
|
210
|
+
const keys_to_traverse = ['body', 'expression', 'declaration', 'declarations', 'init', 'test', 'consequent', 'alternate', 'argument', 'arguments', 'object', 'property', 'left', 'right', 'elements', 'properties', 'key', 'value', 'id', 'params', 'param', 'specifiers', 'exported', 'local', 'block', 'handler', 'finalizer', 'cases', 'discriminant', 'quasi', 'expressions', 'tag', 'quasis', 'cooked', 'raw', 'regex', 'flags', 'pattern', 'extra', 'rawValue', 'comments', 'leadingComments', 'trailingComments', 'innerComments'];
|
|
211
|
+
|
|
212
|
+
for (let key of keys_to_traverse) {
|
|
213
|
+
try {
|
|
214
|
+
if (ast_node[key] && typeof ast_node[key] === 'object') {
|
|
215
|
+
if (Array.isArray(ast_node[key])) {
|
|
216
|
+
ast_node[key].forEach(traverse);
|
|
217
|
+
} else {
|
|
218
|
+
traverse(ast_node[key]);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
} catch (error) {
|
|
222
|
+
// 忽略访问受限属性的错误
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
// 遍历函数体内的所有语句
|
|
229
|
+
statements.forEach(traverse);
|
|
230
|
+
|
|
231
|
+
// 根据使用方式确定参数类型
|
|
232
|
+
if (is_class) {
|
|
233
|
+
return 'param-class';
|
|
234
|
+
} else if (is_function) {
|
|
235
|
+
return 'param-function';
|
|
236
|
+
} else if (is_class_instance) {
|
|
237
|
+
return 'param-class-instance';
|
|
238
|
+
} else if (is_object) {
|
|
239
|
+
return 'param-object';
|
|
240
|
+
} else {
|
|
241
|
+
return 'param';
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
module.exports = {
|
|
246
|
+
ParamName
|
|
247
|
+
};
|