mm_eslint 1.4.5 → 1.4.6

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.
@@ -0,0 +1,286 @@
1
+ const { Name } = require('./name.js');
2
+
3
+ /**
4
+ * 变量名检测器类
5
+ * 负责检测变量名是否符合命名规范
6
+ */
7
+ class VariableName 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
+ VariableName.prototype.VariableDeclaration = function (node) {
19
+ // 检测变量声明(let 和 var)
20
+ if (node.kind === 'let' || node.kind === 'var') {
21
+ for (let i = 0; i < node.declarations.length; i++) {
22
+ let decl = node.declarations[i];
23
+ if (decl.id && decl.id.type === 'Identifier') {
24
+ // 排除对象字面量(ObjectExpression)
25
+ if (decl.init && decl.init.type === 'ObjectExpression') {
26
+ continue;
27
+ }
28
+
29
+ // 排除数组字面量(ArrayExpression)
30
+ if (decl.init && decl.init.type === 'ArrayExpression') {
31
+ continue;
32
+ }
33
+
34
+ // 排除类实例:如果右边是 new 表达式,则不是变量
35
+ if (decl.init && decl.init.type === 'NewExpression') {
36
+ continue;
37
+ }
38
+
39
+ // 排除正则表达式字面量(RegExp实例)
40
+ if (decl.init && decl.init.type === 'Literal' && decl.init.regex) {
41
+ continue;
42
+ }
43
+
44
+ // 排除函数:如果右边是函数表达式或箭头函数,则不是变量
45
+ if (decl.init && (decl.init.type === 'FunctionExpression' || decl.init.type === 'ArrowFunctionExpression')) {
46
+ continue;
47
+ }
48
+
49
+ // 排除类:如果右边是类表达式,则不是变量
50
+ if (decl.init && decl.init.type === 'ClassExpression') {
51
+ continue;
52
+ }
53
+
54
+ // 检测变量名
55
+ let name = decl.id.name;
56
+
57
+ // 使用精确的类型识别逻辑
58
+ let original_type = this._getOriginalType(decl, 'VariableDeclaration');
59
+
60
+ // 只有当确实是变量时才进行变量命名规则检测
61
+ if (original_type === 'variable' || original_type === 'unknown') {
62
+ let error = this.check(node, name, original_type);
63
+
64
+ // 如果检测到错误,报告错误
65
+ if (error) {
66
+ this.report(node, error, original_type);
67
+ return error;
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ // /**
76
+ // * 标识符引用节点检测函数(变量引用)
77
+ // * @param {Object} node - 标识符节点
78
+ // * @returns {Object|undefined} - 检测结果对象或undefined
79
+ // */
80
+ // VariableName.prototype.Identifier = function (node) {
81
+ // // 检测标识符引用(如表达式中的 Name、Age)
82
+ // if (node.type === 'Identifier') {
83
+ // let name = node.name;
84
+
85
+ // // 使用精确的类型识别逻辑
86
+ // let original_type = this._getOriginalType(node, 'Identifier');
87
+
88
+ // // 只有当确实是变量引用时才进行变量命名规则检测
89
+ // if (original_type === 'variable' || original_type === 'unknown') {
90
+ // let error = this.check(node, name, original_type);
91
+
92
+ // // 如果检测到错误,报告错误
93
+ // if (error) {
94
+ // this.report(node, error, original_type);
95
+ // return error;
96
+ // }
97
+ // }
98
+ // }
99
+ // };
100
+
101
+ /**
102
+ * 属性节点检测函数(变量属性)
103
+ * @param {Object} node - 属性节点
104
+ * @returns {Object|undefined} - 检测结果对象或undefined
105
+ */
106
+ VariableName.prototype.Property = function (node) {
107
+ // 判断右边是否为变量值
108
+ if (node.key && node.key.type === 'Identifier') {
109
+ // 排除类实例:如果右边是 new 表达式,则不是变量属性
110
+ if (node.value && node.value.type === 'NewExpression') {
111
+ return;
112
+ }
113
+
114
+ // 排除函数:如果右边是函数表达式或箭头函数,则不是变量属性
115
+ if (node.value && (node.value.type === 'FunctionExpression' || node.value.type === 'ArrowFunctionExpression')) {
116
+ return;
117
+ }
118
+
119
+ // 排除类:如果右边是类表达式,则不是变量属性
120
+ if (node.value && node.value.type === 'ClassExpression') {
121
+ return;
122
+ }
123
+
124
+ // 排除对象字面量(ObjectExpression)
125
+ if (node.value && node.value.type === 'ObjectExpression') {
126
+ return;
127
+ }
128
+
129
+ // 排除数组字面量(ArrayExpression)
130
+ if (node.value && node.value.type === 'ArrayExpression') {
131
+ return;
132
+ }
133
+
134
+ // 排除正则表达式字面量(RegExp实例)
135
+ if (node.value && node.value.type === 'Literal' && node.value.regex) {
136
+ return;
137
+ }
138
+
139
+ // 对于对象字面量的属性简写(property shorthand),使用属性命名风格规则
140
+ // 例如:{ firstName, lastName } 中的 firstName 和 lastName
141
+ if (node.shorthand && node.value && node.value.type === 'Identifier') {
142
+ // 属性简写应该使用属性命名风格规则
143
+ let name = node.key.name;
144
+ let error = this.check(node, name, 'property');
145
+ this.report(node, error, 'property');
146
+ return error;
147
+ }
148
+
149
+ // 使用 _getOriginalType 方法判断属性值的类型
150
+ // 只有当属性值是变量时,才检测属性名
151
+ let original_type = this._getOriginalType(node, 'Property');
152
+
153
+ // 检查属性是否在常量对象中,如果是则跳过变量检测
154
+ if (this._isInConstantObject(node)) {
155
+ return;
156
+ }
157
+
158
+ if (original_type === 'variable') {
159
+ let name = node.key.name;
160
+ let error = this.check(node, name, 'property-variable');
161
+ this.report(node, error, 'property-variable');
162
+ return error;
163
+ }
164
+ return;
165
+ }
166
+ }
167
+
168
+ /**
169
+ * 属性定义节点检测函数(类属性)
170
+ * @param {Object} node - 属性定义节点
171
+ * @returns {Object|undefined} - 检测结果对象或undefined
172
+ */
173
+ VariableName.prototype.PropertyDefinition = function (node) {
174
+ // 排除类实例、函数、类表达式
175
+ if (node.value && (node.value.type === 'NewExpression' || node.value.type === 'FunctionExpression' || node.value.type === 'ArrowFunctionExpression' || node.value.type === 'ClassExpression' || node.value.type === 'ObjectExpression' || node.value.type === 'ArrayExpression' || node.value.regex)) {
176
+ return;
177
+ }
178
+
179
+ // 检测属性定义(类属性)
180
+ if (node.key && node.key.type === 'Identifier') {
181
+ let name = node.key.name;
182
+ let type = this._getOriginalType(node, 'PropertyDefinition');
183
+ if (type === 'variable') {
184
+ let original_type = 'property-variable';
185
+ if (node.static) {
186
+ original_type = 'static-variable';
187
+ }
188
+ else if (node.key.type === 'PrivateIdentifier') {
189
+ original_type = 'private-variable';
190
+ }
191
+ else if (name.startsWith('_')) {
192
+ original_type = 'internal-variable';
193
+ }
194
+ let error = this.check(node, name, original_type);
195
+ this.report(node, error, original_type);
196
+ return error;
197
+ }
198
+ }
199
+ }
200
+
201
+
202
+ /**
203
+ * 方法定义节点检测函数(getter/setter访问器)
204
+ * @param {Object} node - 方法定义节点
205
+ * @returns {Object|undefined} - 检测结果对象或undefined
206
+ */
207
+ VariableName.prototype.MethodDefinition = function (node) {
208
+ // 处理getter和setter访问器(都应该按照属性处理)
209
+ if ((node.kind === 'get' || node.kind === 'set') && node.key && node.key.type === 'Identifier') {
210
+ let name = node.key.name;
211
+ let original_type = 'property-variable';
212
+ if (node.static) {
213
+ original_type = 'static-variable';
214
+ }
215
+ else if (node.key.type === 'PrivateIdentifier') {
216
+ original_type = 'private-variable';
217
+ }
218
+ else if (name.startsWith('_')) {
219
+ original_type = 'internal-variable';
220
+ }
221
+ let error = this.check(node, name, original_type);
222
+ this.report(node, error, original_type);
223
+ return error;
224
+ }
225
+ }
226
+
227
+ /**
228
+ * 默认导出节点检测函数(变量导出)
229
+ * @param {Object} node - 默认导出节点
230
+ * @returns {Object|undefined} - 检测结果对象或undefined
231
+ */
232
+ VariableName.prototype.ExportDefaultDeclaration = function (node) {
233
+ // 检测导出的对象名
234
+ if (node.declaration && node.declaration.type === 'Identifier') {
235
+ let type = this._getOriginalType(node.declaration, 'ExportDefaultDeclaration');
236
+ if (type === 'variable') {
237
+ let name = node.declaration.name;
238
+ let original_type = 'export-variable';
239
+ let error = this.check(node.declaration, name, original_type);
240
+ this.report(node.declaration, error, original_type);
241
+ return error;
242
+ }
243
+ }
244
+ }
245
+
246
+ /**
247
+ * 命名导出节点检测函数(变量导出)
248
+ * @param {Object} node - 命名导出节点
249
+ * @returns {Object|undefined} - 检测结果对象或undefined
250
+ */
251
+ VariableName.prototype.ExportNamedDeclaration = function (node) {
252
+ // 检测命名导出的函数引用
253
+ if (node.specifiers && node.specifiers.length > 0) {
254
+ for (let i = 0; i < node.specifiers.length; i++) {
255
+ let specifier = node.specifiers[i];
256
+
257
+ // 检测导出的标识符(避免重复检测)
258
+ // 优先检测 exported 属性,如果存在则使用它,否则使用 local 属性
259
+ let identifier_to_check = null;
260
+ let identifier_name = '';
261
+
262
+ if (specifier.exported && specifier.exported.type === 'Identifier') {
263
+ identifier_to_check = specifier.exported;
264
+ identifier_name = specifier.exported.name;
265
+ } else if (specifier.local && specifier.local.type === 'Identifier') {
266
+ identifier_to_check = specifier.local;
267
+ identifier_name = specifier.local.name;
268
+ }
269
+
270
+ // 只有当找到有效标识符时才进行检测
271
+ if (identifier_to_check) {
272
+ let original_type = this._getOriginalType(specifier, 'ExportSpecifier');
273
+
274
+ // 只有当导出的是变量时才检测
275
+ if (original_type === 'variable') {
276
+ let error = this.check(identifier_to_check, identifier_name, 'export-variable');
277
+ this.report(identifier_to_check, error, 'export-variable');
278
+ }
279
+ }
280
+ }
281
+ }
282
+ }
283
+
284
+ module.exports = {
285
+ VariableName
286
+ };
@@ -0,0 +1,83 @@
1
+ /**
2
+ * 类相关修复函数
3
+ * 负责处理类声明、类表达式等AST节点的修复逻辑
4
+ */
5
+ class ClassFix {
6
+ /**
7
+ * 构造函数
8
+ * @param {object} config 配置对象
9
+ */
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+
14
+ /**
15
+ * 创建类声明修复函数
16
+ * @param {object} context ESLint上下文
17
+ * @param {object} node AST节点
18
+ * @param {object} error 错误信息
19
+ * @returns {function} 修复函数
20
+ */
21
+ createClassFixFunction(context, node, error) {
22
+ var old_name = error.name;
23
+ var new_name = error.fix_suggestion;
24
+
25
+ if (!old_name || !new_name) {
26
+ return function(fixer) {
27
+ return [];
28
+ };
29
+ }
30
+
31
+ return function(fixer) {
32
+ // 类声明特殊处理:直接查找类名标识符
33
+ if (node.type === 'ClassDeclaration' && node.id && node.id.type === 'Identifier' && node.id.name === old_name) {
34
+ return fixer.replaceText(node.id, new_name);
35
+ }
36
+
37
+ // 类表达式特殊处理
38
+ if (node.type === 'ClassExpression' && node.id && node.id.type === 'Identifier' && node.id.name === old_name) {
39
+ return fixer.replaceText(node.id, new_name);
40
+ }
41
+
42
+ // 继承的父类名处理
43
+ if (node.type === 'ClassDeclaration' && node.superClass && node.superClass.type === 'Identifier' && node.superClass.name === old_name) {
44
+ return fixer.replaceText(node.superClass, new_name);
45
+ }
46
+
47
+ // 通用查找作为备用方案
48
+ var identifier_node = this._findIdentifierNode(node, old_name);
49
+ if (identifier_node) {
50
+ return fixer.replaceText(identifier_node, new_name);
51
+ }
52
+
53
+ return [];
54
+ }.bind(this);
55
+ }
56
+
57
+ /**
58
+ * 查找标识符节点
59
+ * @param {object} node AST节点
60
+ * @param {string} name 名称
61
+ * @returns {object|null} 标识符节点
62
+ */
63
+ _findIdentifierNode(node, name) {
64
+ // 如果是标识符节点且名称匹配
65
+ if (node.type === 'Identifier' && node.name === name) {
66
+ return node;
67
+ }
68
+
69
+ // 如果是类声明,检查类名标识符
70
+ if (node.type === 'ClassDeclaration' && node.id && node.id.type === 'Identifier' && node.id.name === name) {
71
+ return node.id;
72
+ }
73
+
74
+ // 如果是类表达式,检查类名标识符
75
+ if (node.type === 'ClassExpression' && node.id && node.id.type === 'Identifier' && node.id.name === name) {
76
+ return node.id;
77
+ }
78
+
79
+ return null;
80
+ }
81
+ }
82
+
83
+ module.exports = { ClassFix };
@@ -0,0 +1,169 @@
1
+ /**
2
+ * 导出相关修复函数
3
+ * 负责处理导出语句中的引用修复逻辑
4
+ */
5
+ class ExportFix {
6
+ /**
7
+ * 构造函数
8
+ * @param {object} config 配置对象
9
+ */
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+
14
+ /**
15
+ * 修复导出语句中的引用
16
+ * @param {object} context ESLint上下文
17
+ * @param {string} old_name 旧名称
18
+ * @param {string} new_name 新名称
19
+ * @param {object} node AST节点
20
+ * @param {object} fixer 修复器
21
+ * @returns {array} 修复数组
22
+ */
23
+ fixExportReferences(context, old_name, new_name, node, fixer) {
24
+ var fixes = [];
25
+
26
+ // 获取当前文件的完整AST
27
+ var source_code = context.getSourceCode();
28
+ var ast = source_code.ast;
29
+
30
+ // 遍历AST查找导出语句
31
+ this._traverseAST(ast, function(child_node) {
32
+ // 处理 ES6 export { name } 形式的导出
33
+ if (child_node.type === 'ExportNamedDeclaration' &&
34
+ child_node.specifiers && child_node.specifiers.length > 0) {
35
+
36
+ for (var i = 0; i < child_node.specifiers.length; i++) {
37
+ var specifier = child_node.specifiers[i];
38
+
39
+ // 处理普通导出(如 export { className })
40
+ if (specifier.local && specifier.local.type === 'Identifier' &&
41
+ specifier.local.name === old_name) {
42
+ fixes.push(fixer.replaceText(specifier.local, new_name));
43
+ }
44
+
45
+ // 处理重命名导出(如 export { className as ClassName })
46
+ if (specifier.exported && specifier.exported.type === 'Identifier' &&
47
+ specifier.exported.name === old_name) {
48
+ fixes.push(fixer.replaceText(specifier.exported, new_name));
49
+ }
50
+ }
51
+ }
52
+
53
+ // 处理 ES6 export default name 形式的导出
54
+ if (child_node.type === 'ExportDefaultDeclaration' &&
55
+ child_node.declaration && child_node.declaration.type === 'Identifier' &&
56
+ child_node.declaration.name === old_name) {
57
+
58
+ fixes.push(fixer.replaceText(child_node.declaration, new_name));
59
+ }
60
+
61
+ // 处理 ES6 export const name = ... 形式的导出
62
+ if (child_node.type === 'ExportNamedDeclaration' &&
63
+ child_node.declaration && child_node.declaration.type === 'VariableDeclaration') {
64
+
65
+ for (var i = 0; i < child_node.declaration.declarations.length; i++) {
66
+ var declaration = child_node.declaration.declarations[i];
67
+ if (declaration.id && declaration.id.type === 'Identifier' &&
68
+ declaration.id.name === old_name) {
69
+ fixes.push(fixer.replaceText(declaration.id, new_name));
70
+ }
71
+ }
72
+ }
73
+
74
+ // 处理 module.exports = { ... } 形式的导出
75
+ if (child_node.type === 'AssignmentExpression' &&
76
+ child_node.left &&
77
+ child_node.left.type === 'MemberExpression' &&
78
+ child_node.left.object &&
79
+ child_node.left.object.type === 'Identifier' &&
80
+ child_node.left.object.name === 'module' &&
81
+ child_node.left.property &&
82
+ child_node.left.property.type === 'Identifier' &&
83
+ child_node.left.property.name === 'exports' &&
84
+ child_node.right &&
85
+ child_node.right.type === 'ObjectExpression') {
86
+
87
+ // 检查对象字面量中的属性
88
+ for (var i = 0; i < child_node.right.properties.length; i++) {
89
+ var property = child_node.right.properties[i];
90
+
91
+ // 处理简写属性(如 { AdminManager })
92
+ if (property.shorthand && property.key && property.key.type === 'Identifier' && property.key.name === old_name) {
93
+ fixes.push(fixer.replaceText(property.key, new_name));
94
+ }
95
+
96
+ // 处理普通属性(如 { AdminManager: AdminManager })
97
+ if (!property.shorthand && property.key && property.key.type === 'Identifier' && property.key.name === old_name) {
98
+ fixes.push(fixer.replaceText(property.key, new_name));
99
+ }
100
+ }
101
+ }
102
+
103
+ // 处理 exports.XXX = ... 形式的导出
104
+ if (child_node.type === 'AssignmentExpression' &&
105
+ child_node.left &&
106
+ child_node.left.type === 'MemberExpression' &&
107
+ child_node.left.object &&
108
+ child_node.left.object.type === 'Identifier' &&
109
+ child_node.left.object.name === 'exports' &&
110
+ child_node.left.property &&
111
+ child_node.left.property.type === 'Identifier' &&
112
+ child_node.left.property.name === old_name) {
113
+
114
+ fixes.push(fixer.replaceText(child_node.left.property, new_name));
115
+ }
116
+
117
+ // 处理 module.exports.XXX = ... 形式的导出
118
+ if (child_node.type === 'AssignmentExpression' &&
119
+ child_node.left &&
120
+ child_node.left.type === 'MemberExpression' &&
121
+ child_node.left.object &&
122
+ child_node.left.object.type === 'MemberExpression' &&
123
+ child_node.left.object.object &&
124
+ child_node.left.object.object.type === 'Identifier' &&
125
+ child_node.left.object.object.name === 'module' &&
126
+ child_node.left.object.property &&
127
+ child_node.left.object.property.type === 'Identifier' &&
128
+ child_node.left.object.property.name === 'exports' &&
129
+ child_node.left.property &&
130
+ child_node.left.property.type === 'Identifier' &&
131
+ child_node.left.property.name === old_name) {
132
+
133
+ fixes.push(fixer.replaceText(child_node.left.property, new_name));
134
+ }
135
+ });
136
+
137
+ return fixes;
138
+ }
139
+
140
+ /**
141
+ * 遍历AST节点
142
+ * @param {object} node AST节点
143
+ * @param {function} callback 回调函数
144
+ */
145
+ _traverseAST(node, callback) {
146
+ if (!node || typeof node !== 'object') {
147
+ return;
148
+ }
149
+
150
+ // 调用回调函数处理当前节点
151
+ callback(node);
152
+
153
+ // 递归遍历子节点
154
+ for (var k in node) {
155
+ if (node.hasOwnProperty(k)) {
156
+ var child = node[k];
157
+ if (Array.isArray(child)) {
158
+ for (var i = 0; i < child.length; i++) {
159
+ this._traverseAST(child[i], callback);
160
+ }
161
+ } else if (typeof child === 'object' && child !== null) {
162
+ this._traverseAST(child, callback);
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+
169
+ module.exports = { ExportFix };
@@ -0,0 +1,85 @@
1
+ /**
2
+ * 函数相关修复函数
3
+ * 负责处理函数声明、函数表达式、箭头函数等AST节点的修复逻辑
4
+ */
5
+ class FunctionFix {
6
+ /**
7
+ * 构造函数
8
+ * @param {object} config 配置对象
9
+ */
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+
14
+ /**
15
+ * 创建函数修复函数
16
+ * @param {object} context ESLint上下文
17
+ * @param {object} node AST节点
18
+ * @param {object} error 错误信息
19
+ * @returns {function} 修复函数
20
+ */
21
+ createFunctionFixFunction(context, node, error) {
22
+ var old_name = error.name;
23
+ var new_name = error.fix_suggestion;
24
+
25
+ if (!old_name || !new_name) {
26
+ return function(fixer) {
27
+ return [];
28
+ };
29
+ }
30
+
31
+ return function(fixer) {
32
+ // 函数声明特殊处理
33
+ if (node.type === 'FunctionDeclaration' && node.id && node.id.type === 'Identifier' && node.id.name === old_name) {
34
+ return fixer.replaceText(node.id, new_name);
35
+ }
36
+
37
+ // 函数表达式特殊处理
38
+ if (node.type === 'FunctionExpression' && node.id && node.id.type === 'Identifier' && node.id.name === old_name) {
39
+ return fixer.replaceText(node.id, new_name);
40
+ }
41
+
42
+ // 箭头函数处理(通过父节点查找变量名)
43
+ if (node.type === 'ArrowFunctionExpression' && node.parent && node.parent.type === 'VariableDeclarator' &&
44
+ node.parent.id && node.parent.id.type === 'Identifier' && node.parent.id.name === old_name) {
45
+ return fixer.replaceText(node.parent.id, new_name);
46
+ }
47
+
48
+ // 函数调用处理
49
+ if (node.type === 'CallExpression' && node.callee && node.callee.type === 'Identifier' && node.callee.name === old_name) {
50
+ return fixer.replaceText(node.callee, new_name);
51
+ }
52
+
53
+ // 通用查找作为备用方案
54
+ var identifier_node = this._findIdentifierNode(node, old_name);
55
+ if (identifier_node) {
56
+ return fixer.replaceText(identifier_node, new_name);
57
+ }
58
+
59
+ return [];
60
+ }.bind(this);
61
+ }
62
+
63
+ /**
64
+ * 查找标识符节点
65
+ * @param {object} node AST节点
66
+ * @param {string} name 名称
67
+ * @returns {object|null} 标识符节点
68
+ */
69
+ _findIdentifierNode(node, name) {
70
+ // 如果是标识符节点且名称匹配
71
+ if (node.type === 'Identifier' && node.name === name) {
72
+ return node;
73
+ }
74
+
75
+ // 如果是函数声明,检查函数名标识符
76
+ if ((node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') &&
77
+ node.id && node.id.type === 'Identifier' && node.id.name === name) {
78
+ return node.id;
79
+ }
80
+
81
+ return null;
82
+ }
83
+ }
84
+
85
+ module.exports = { FunctionFix };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * 修复模块索引文件
3
+ * 统一导出所有修复类
4
+ */
5
+ const { ClassFix } = require('./class_fix.js');
6
+ const { VariableFix } = require('./variable_fix.js');
7
+ const { FunctionFix } = require('./function_fix.js');
8
+ const { PropertyFix } = require('./property_fix.js');
9
+ const { MethodFix } = require('./method_fix.js');
10
+ const { ParamFix } = require('./param_fix.js');
11
+ const { ExportFix } = require('./export_fix.js');
12
+
13
+ module.exports = {
14
+ ClassFix,
15
+ VariableFix,
16
+ FunctionFix,
17
+ PropertyFix,
18
+ MethodFix,
19
+ ParamFix,
20
+ ExportFix
21
+ };