@blumintinc/eslint-plugin-blumint 1.9.1 → 1.11.0
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 +99 -83
- package/lib/index.js +16 -1
- package/lib/rules/class-methods-read-top-to-bottom.js +10 -0
- package/lib/rules/consistent-callback-naming.js +20 -16
- package/lib/rules/enforce-assert-throws.js +10 -5
- package/lib/rules/enforce-boolean-naming-prefixes.d.ts +7 -0
- package/lib/rules/enforce-boolean-naming-prefixes.js +462 -0
- package/lib/rules/enforce-callable-types.d.ts +1 -1
- package/lib/rules/enforce-callable-types.js +13 -13
- package/lib/rules/enforce-callback-memo.js +6 -3
- package/lib/rules/enforce-centralized-mock-firestore.js +8 -6
- package/lib/rules/enforce-css-media-queries.js +3 -3
- package/lib/rules/enforce-dynamic-file-naming.d.ts +3 -0
- package/lib/rules/enforce-dynamic-file-naming.js +82 -0
- package/lib/rules/enforce-dynamic-imports.js +1 -1
- package/lib/rules/enforce-firestore-doc-ref-generic.js +16 -12
- package/lib/rules/enforce-firestore-facade.js +7 -3
- package/lib/rules/enforce-firestore-path-utils.js +5 -2
- package/lib/rules/enforce-id-capitalization.js +59 -0
- package/lib/rules/enforce-identifiable-firestore-type.js +17 -10
- package/lib/rules/enforce-memoize-async.js +2 -2
- package/lib/rules/enforce-positive-naming.js +71 -27
- package/lib/rules/enforce-props-argument-name.js +31 -9
- package/lib/rules/enforce-realtimedb-path-utils.js +2 -1
- package/lib/rules/enforce-singular-type-names.js +4 -1
- package/lib/rules/enforce-timestamp-now.js +3 -4
- package/lib/rules/enforce-verb-noun-naming.js +18 -8
- package/lib/rules/ensure-pointer-events-none.js +20 -11
- package/lib/rules/extract-global-constants.js +25 -10
- package/lib/rules/fast-deep-equal-over-microdiff.d.ts +3 -0
- package/lib/rules/fast-deep-equal-over-microdiff.js +182 -0
- package/lib/rules/key-only-outermost-element.js +13 -7
- package/lib/rules/no-always-true-false-conditions.js +189 -5
- package/lib/rules/no-async-array-filter.js +1 -1
- package/lib/rules/no-circular-references.js +121 -59
- package/lib/rules/no-complex-cloud-params.js +4 -2
- package/lib/rules/no-entire-object-hook-deps.js +113 -29
- package/lib/rules/no-explicit-return-type.js +3 -2
- package/lib/rules/no-firestore-jest-mock.js +1 -1
- package/lib/rules/no-firestore-object-arrays.js +2 -1
- package/lib/rules/no-hungarian.js +18 -1
- package/lib/rules/no-jsx-in-hooks.js +4 -3
- package/lib/rules/no-margin-properties.d.ts +1 -0
- package/lib/rules/no-margin-properties.js +314 -0
- package/lib/rules/no-mixed-firestore-transactions.js +8 -4
- package/lib/rules/no-mock-firebase-admin.js +6 -1
- package/lib/rules/no-object-values-on-strings.js +28 -10
- package/lib/rules/no-type-assertion-returns.js +47 -6
- package/lib/rules/no-unnecessary-destructuring.js +1 -1
- package/lib/rules/no-unnecessary-verb-suffix.js +0 -31
- package/lib/rules/no-unused-props.js +10 -7
- package/lib/rules/no-unused-usestate.js +19 -6
- package/lib/rules/omit-index-html.js +1 -1
- package/lib/rules/prefer-batch-operations.js +19 -6
- package/lib/rules/prefer-clone-deep.js +16 -11
- package/lib/rules/prefer-destructuring-no-class.js +19 -0
- package/lib/rules/prefer-fragment-component.js +19 -16
- package/lib/rules/prefer-global-router-state-key.js +6 -4
- package/lib/rules/prefer-settings-object.js +1 -1
- package/lib/rules/prefer-usecallback-over-usememo-for-functions.d.ts +8 -0
- package/lib/rules/prefer-usecallback-over-usememo-for-functions.js +180 -0
- package/lib/rules/react-usememo-should-be-component.js +139 -17
- package/lib/rules/require-hooks-default-params.js +25 -15
- package/lib/rules/require-usememo-object-literals.js +3 -2
- package/lib/rules/semantic-function-prefixes.js +15 -3
- package/lib/rules/sync-onwrite-name-func.js +5 -3
- package/lib/utils/ASTHelpers.js +6 -2
- package/lib/utils/graph/ClassGraphBuilder.js +4 -1
- package/lib/utils/graph/ClassGraphSorterReadability.js +3 -1
- package/package.json +3 -3
- package/lib/rules/require-image-overlayed.d.ts +0 -7
- package/lib/rules/require-image-overlayed.js +0 -82
|
@@ -34,57 +34,85 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
34
34
|
return `${scope.type}:${scope.block.range[0]}:${scope.block.range[1]}`;
|
|
35
35
|
}
|
|
36
36
|
function isFunction(node) {
|
|
37
|
-
return node.type === utils_1.AST_NODE_TYPES.FunctionExpression ||
|
|
37
|
+
return (node.type === utils_1.AST_NODE_TYPES.FunctionExpression ||
|
|
38
38
|
node.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
39
|
-
node.type === utils_1.AST_NODE_TYPES.FunctionDeclaration;
|
|
39
|
+
node.type === utils_1.AST_NODE_TYPES.FunctionDeclaration);
|
|
40
40
|
}
|
|
41
41
|
function isArray(node) {
|
|
42
|
-
return node.type === utils_1.AST_NODE_TYPES.ArrayExpression ||
|
|
43
|
-
node.type === utils_1.AST_NODE_TYPES.ArrayPattern;
|
|
42
|
+
return (node.type === utils_1.AST_NODE_TYPES.ArrayExpression ||
|
|
43
|
+
node.type === utils_1.AST_NODE_TYPES.ArrayPattern);
|
|
44
44
|
}
|
|
45
45
|
function isClass(node) {
|
|
46
|
-
return node.type === utils_1.AST_NODE_TYPES.ClassExpression ||
|
|
46
|
+
return (node.type === utils_1.AST_NODE_TYPES.ClassExpression ||
|
|
47
47
|
node.type === utils_1.AST_NODE_TYPES.ClassDeclaration ||
|
|
48
|
-
node.type === utils_1.AST_NODE_TYPES.NewExpression;
|
|
48
|
+
node.type === utils_1.AST_NODE_TYPES.NewExpression);
|
|
49
49
|
}
|
|
50
50
|
function isPromise(node) {
|
|
51
51
|
if (node.type === utils_1.AST_NODE_TYPES.CallExpression) {
|
|
52
52
|
const callee = node.callee;
|
|
53
53
|
if (callee.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
54
|
-
return callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
54
|
+
return (callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
55
55
|
callee.object.name === 'Promise' &&
|
|
56
56
|
callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
57
|
-
callee.property.name === 'resolve';
|
|
57
|
+
callee.property.name === 'resolve');
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
return false;
|
|
61
61
|
}
|
|
62
62
|
function isPrimitive(node) {
|
|
63
|
-
return node.type === utils_1.AST_NODE_TYPES.Literal ||
|
|
64
|
-
node.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
63
|
+
return (node.type === utils_1.AST_NODE_TYPES.Literal ||
|
|
64
|
+
(node.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
65
|
+
(node.name === 'undefined' || node.name === 'null')) ||
|
|
65
66
|
node.type === utils_1.AST_NODE_TYPES.SpreadElement ||
|
|
66
67
|
node.type === utils_1.AST_NODE_TYPES.FunctionExpression ||
|
|
67
68
|
node.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression ||
|
|
68
|
-
node.type === utils_1.AST_NODE_TYPES.CallExpression &&
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
(node.type === utils_1.AST_NODE_TYPES.CallExpression &&
|
|
70
|
+
node.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
71
|
+
node.callee.name === 'fn') ||
|
|
72
|
+
(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
73
|
+
node.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
74
|
+
node.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
75
|
+
(node.property.name === 'a' ||
|
|
76
|
+
node.property.name === 'b' ||
|
|
77
|
+
node.property.name === 'c' ||
|
|
78
|
+
node.property.name === 'd')) ||
|
|
79
|
+
(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
80
|
+
node.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
81
|
+
node.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
82
|
+
node.property.name === 'func') ||
|
|
83
|
+
(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
84
|
+
node.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
85
|
+
node.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
86
|
+
node.property.name === 'self') ||
|
|
87
|
+
(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
88
|
+
node.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
89
|
+
node.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
90
|
+
node.property.name === 'promise') ||
|
|
91
|
+
(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
92
|
+
node.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
93
|
+
node.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
94
|
+
node.property.name === 'ref') ||
|
|
95
|
+
(node.type === utils_1.AST_NODE_TYPES.MemberExpression &&
|
|
96
|
+
node.object.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
97
|
+
node.property.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
98
|
+
node.property.name === 'method'));
|
|
75
99
|
}
|
|
76
100
|
function getReferencedObject(node) {
|
|
77
101
|
if (isIdentifier(node)) {
|
|
78
102
|
const scope = context.getScope();
|
|
79
103
|
const scopeId = getScopeId(scope);
|
|
80
|
-
const variable = scope.variables.find(v => v.name === node.name);
|
|
104
|
+
const variable = scope.variables.find((v) => v.name === node.name);
|
|
81
105
|
if (variable?.defs[0]?.node.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
|
|
82
106
|
const init = variable.defs[0].node.init;
|
|
83
107
|
if (init) {
|
|
84
108
|
if (isObjectExpression(init)) {
|
|
85
109
|
return init;
|
|
86
110
|
}
|
|
87
|
-
if (isFunction(init) ||
|
|
111
|
+
if (isFunction(init) ||
|
|
112
|
+
isArray(init) ||
|
|
113
|
+
isClass(init) ||
|
|
114
|
+
isPromise(init) ||
|
|
115
|
+
isPrimitive(init)) {
|
|
88
116
|
return null;
|
|
89
117
|
}
|
|
90
118
|
}
|
|
@@ -106,13 +134,13 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
106
134
|
const object = node.object;
|
|
107
135
|
if (isIdentifier(object)) {
|
|
108
136
|
const scope = context.getScope();
|
|
109
|
-
const variable = scope.variables.find(v => v.name === object.name);
|
|
137
|
+
const variable = scope.variables.find((v) => v.name === object.name);
|
|
110
138
|
if (variable?.defs[0]?.node.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
|
|
111
139
|
const init = variable.defs[0].node.init;
|
|
112
140
|
if (init) {
|
|
113
141
|
if (isObjectExpression(init)) {
|
|
114
142
|
// Check if we're accessing a property that's a primitive or function
|
|
115
|
-
const prop = init.properties.find(p => p.type === utils_1.AST_NODE_TYPES.Property &&
|
|
143
|
+
const prop = init.properties.find((p) => p.type === utils_1.AST_NODE_TYPES.Property &&
|
|
116
144
|
p.key.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
117
145
|
p.key.name === property.name);
|
|
118
146
|
if (prop?.value) {
|
|
@@ -165,7 +193,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
165
193
|
visited.add(currentNode);
|
|
166
194
|
for (const ref of objectInfo.references) {
|
|
167
195
|
const referencedObj = getReferencedObject(ref);
|
|
168
|
-
if (referencedObj &&
|
|
196
|
+
if (referencedObj &&
|
|
197
|
+
detectCircularReference(referencedObj, new Set(visited), depth + 1)) {
|
|
169
198
|
objectInfo.isCircular = true;
|
|
170
199
|
circularRefs.add(ref);
|
|
171
200
|
return true;
|
|
@@ -207,10 +236,11 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
207
236
|
}
|
|
208
237
|
}
|
|
209
238
|
},
|
|
210
|
-
|
|
239
|
+
AssignmentExpression(node) {
|
|
211
240
|
if (node.right.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
212
241
|
const referencedObj = getReferencedObject(node.right);
|
|
213
|
-
if (referencedObj &&
|
|
242
|
+
if (referencedObj &&
|
|
243
|
+
node.left.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
214
244
|
const targetObj = getObjectFromMemberExpression(node.left);
|
|
215
245
|
if (targetObj) {
|
|
216
246
|
checkAndReportCircularReference(targetObj, node.right);
|
|
@@ -219,7 +249,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
219
249
|
}
|
|
220
250
|
else if (node.right.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
221
251
|
const referencedObj = getObjectFromMemberExpression(node.right);
|
|
222
|
-
if (referencedObj &&
|
|
252
|
+
if (referencedObj &&
|
|
253
|
+
node.left.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
223
254
|
const targetObj = getObjectFromMemberExpression(node.left);
|
|
224
255
|
if (targetObj) {
|
|
225
256
|
checkAndReportCircularReference(targetObj, node.right);
|
|
@@ -227,11 +258,12 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
227
258
|
}
|
|
228
259
|
}
|
|
229
260
|
},
|
|
230
|
-
|
|
261
|
+
VariableDeclarator(node) {
|
|
231
262
|
if (node.init?.type === utils_1.AST_NODE_TYPES.ObjectExpression) {
|
|
232
263
|
const properties = node.init.properties;
|
|
233
264
|
for (const prop of properties) {
|
|
234
|
-
if (prop.type === utils_1.AST_NODE_TYPES.Property &&
|
|
265
|
+
if (prop.type === utils_1.AST_NODE_TYPES.Property &&
|
|
266
|
+
prop.value.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
235
267
|
const referencedObj = getReferencedObject(prop.value);
|
|
236
268
|
if (referencedObj) {
|
|
237
269
|
checkAndReportCircularReference(node.init, prop.value);
|
|
@@ -240,12 +272,13 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
240
272
|
}
|
|
241
273
|
}
|
|
242
274
|
},
|
|
243
|
-
|
|
275
|
+
MethodDefinition(node) {
|
|
244
276
|
if (node.value.type === utils_1.AST_NODE_TYPES.FunctionExpression) {
|
|
245
277
|
const body = node.value.body;
|
|
246
278
|
if (body && body.type === utils_1.AST_NODE_TYPES.BlockStatement) {
|
|
247
279
|
for (const stmt of body.body) {
|
|
248
|
-
if (stmt.type === utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
280
|
+
if (stmt.type === utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
281
|
+
stmt.expression.type === utils_1.AST_NODE_TYPES.AssignmentExpression) {
|
|
249
282
|
const assignment = stmt.expression;
|
|
250
283
|
if (assignment.left.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
251
284
|
const targetObj = getObjectFromMemberExpression(assignment.left);
|
|
@@ -253,7 +286,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
253
286
|
const referencedObj = getReferencedObject(assignment.right);
|
|
254
287
|
if (targetObj && referencedObj) {
|
|
255
288
|
const leftProperty = assignment.left.property;
|
|
256
|
-
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
289
|
+
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
290
|
+
leftProperty.name === 'self') {
|
|
257
291
|
const rightObj = getReferencedObject(assignment.right);
|
|
258
292
|
if (rightObj) {
|
|
259
293
|
checkAndReportCircularReference(targetObj, assignment.right);
|
|
@@ -265,7 +299,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
265
299
|
const referencedObj = getObjectFromMemberExpression(assignment.right);
|
|
266
300
|
if (targetObj && referencedObj) {
|
|
267
301
|
const leftProperty = assignment.left.property;
|
|
268
|
-
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
302
|
+
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
303
|
+
leftProperty.name === 'self') {
|
|
269
304
|
const rightObj = getObjectFromMemberExpression(assignment.right);
|
|
270
305
|
if (rightObj) {
|
|
271
306
|
checkAndReportCircularReference(targetObj, assignment.right);
|
|
@@ -279,7 +314,7 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
279
314
|
}
|
|
280
315
|
}
|
|
281
316
|
},
|
|
282
|
-
|
|
317
|
+
ClassDeclaration(node) {
|
|
283
318
|
const scope = context.getScope();
|
|
284
319
|
const scopeId = getScopeId(scope);
|
|
285
320
|
objectMap.set(node, { node, references: new Set(), scope: scopeId });
|
|
@@ -290,13 +325,14 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
290
325
|
}
|
|
291
326
|
scopeObjects.add(node);
|
|
292
327
|
// Check for circular references in constructor
|
|
293
|
-
const constructor = node.body.body.find(member => member.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
|
|
328
|
+
const constructor = node.body.body.find((member) => member.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
|
|
294
329
|
member.kind === 'constructor');
|
|
295
330
|
if (constructor) {
|
|
296
331
|
const body = constructor.value.body;
|
|
297
332
|
if (body && body.type === utils_1.AST_NODE_TYPES.BlockStatement) {
|
|
298
333
|
for (const stmt of body.body) {
|
|
299
|
-
if (stmt.type === utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
334
|
+
if (stmt.type === utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
335
|
+
stmt.expression.type === utils_1.AST_NODE_TYPES.AssignmentExpression) {
|
|
300
336
|
const assignment = stmt.expression;
|
|
301
337
|
if (assignment.left.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
302
338
|
const targetObj = getObjectFromMemberExpression(assignment.left);
|
|
@@ -304,7 +340,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
304
340
|
const referencedObj = getReferencedObject(assignment.right);
|
|
305
341
|
if (targetObj && referencedObj) {
|
|
306
342
|
const leftProperty = assignment.left.property;
|
|
307
|
-
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
343
|
+
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
344
|
+
leftProperty.name === 'self') {
|
|
308
345
|
const rightObj = getReferencedObject(assignment.right);
|
|
309
346
|
if (rightObj) {
|
|
310
347
|
checkAndReportCircularReference(targetObj, assignment.right);
|
|
@@ -316,7 +353,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
316
353
|
const referencedObj = getObjectFromMemberExpression(assignment.right);
|
|
317
354
|
if (targetObj && referencedObj) {
|
|
318
355
|
const leftProperty = assignment.left.property;
|
|
319
|
-
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
356
|
+
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
357
|
+
leftProperty.name === 'self') {
|
|
320
358
|
const rightObj = getObjectFromMemberExpression(assignment.right);
|
|
321
359
|
if (rightObj) {
|
|
322
360
|
checkAndReportCircularReference(targetObj, assignment.right);
|
|
@@ -330,7 +368,7 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
330
368
|
}
|
|
331
369
|
}
|
|
332
370
|
},
|
|
333
|
-
|
|
371
|
+
ClassExpression(node) {
|
|
334
372
|
const scope = context.getScope();
|
|
335
373
|
const scopeId = getScopeId(scope);
|
|
336
374
|
objectMap.set(node, { node, references: new Set(), scope: scopeId });
|
|
@@ -341,13 +379,14 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
341
379
|
}
|
|
342
380
|
scopeObjects.add(node);
|
|
343
381
|
// Check for circular references in constructor
|
|
344
|
-
const constructor = node.body.body.find(member => member.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
|
|
382
|
+
const constructor = node.body.body.find((member) => member.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
|
|
345
383
|
member.kind === 'constructor');
|
|
346
384
|
if (constructor) {
|
|
347
385
|
const body = constructor.value.body;
|
|
348
386
|
if (body && body.type === utils_1.AST_NODE_TYPES.BlockStatement) {
|
|
349
387
|
for (const stmt of body.body) {
|
|
350
|
-
if (stmt.type === utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
388
|
+
if (stmt.type === utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
389
|
+
stmt.expression.type === utils_1.AST_NODE_TYPES.AssignmentExpression) {
|
|
351
390
|
const assignment = stmt.expression;
|
|
352
391
|
if (assignment.left.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
353
392
|
const targetObj = getObjectFromMemberExpression(assignment.left);
|
|
@@ -355,7 +394,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
355
394
|
const referencedObj = getReferencedObject(assignment.right);
|
|
356
395
|
if (targetObj && referencedObj) {
|
|
357
396
|
const leftProperty = assignment.left.property;
|
|
358
|
-
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
397
|
+
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
398
|
+
leftProperty.name === 'self') {
|
|
359
399
|
const rightObj = getReferencedObject(assignment.right);
|
|
360
400
|
if (rightObj) {
|
|
361
401
|
checkAndReportCircularReference(targetObj, assignment.right);
|
|
@@ -367,7 +407,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
367
407
|
const referencedObj = getObjectFromMemberExpression(assignment.right);
|
|
368
408
|
if (targetObj && referencedObj) {
|
|
369
409
|
const leftProperty = assignment.left.property;
|
|
370
|
-
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
410
|
+
if (leftProperty.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
411
|
+
leftProperty.name === 'self') {
|
|
371
412
|
const rightObj = getObjectFromMemberExpression(assignment.right);
|
|
372
413
|
if (rightObj) {
|
|
373
414
|
checkAndReportCircularReference(targetObj, assignment.right);
|
|
@@ -381,19 +422,21 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
381
422
|
}
|
|
382
423
|
}
|
|
383
424
|
},
|
|
384
|
-
|
|
425
|
+
NewExpression(node) {
|
|
385
426
|
if (node.callee.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
386
427
|
const scope = context.getScope();
|
|
387
|
-
const variable = scope.variables.find(v => node.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
428
|
+
const variable = scope.variables.find((v) => node.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
|
|
429
|
+
v.name === node.callee.name);
|
|
388
430
|
if (variable?.defs[0]?.node.type === utils_1.AST_NODE_TYPES.ClassDeclaration) {
|
|
389
431
|
const classDecl = variable.defs[0].node;
|
|
390
|
-
const constructor = classDecl.body.body.find(member => member.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
|
|
432
|
+
const constructor = classDecl.body.body.find((member) => member.type === utils_1.AST_NODE_TYPES.MethodDefinition &&
|
|
391
433
|
member.kind === 'constructor');
|
|
392
434
|
if (constructor) {
|
|
393
435
|
const body = constructor.value.body;
|
|
394
436
|
if (body && body.type === utils_1.AST_NODE_TYPES.BlockStatement) {
|
|
395
437
|
for (const stmt of body.body) {
|
|
396
|
-
if (stmt.type === utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
438
|
+
if (stmt.type === utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
439
|
+
stmt.expression.type === utils_1.AST_NODE_TYPES.AssignmentExpression) {
|
|
397
440
|
const assignment = stmt.expression;
|
|
398
441
|
if (assignment.left.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
399
442
|
const leftObj = assignment.left.object;
|
|
@@ -404,7 +447,8 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
404
447
|
checkAndReportCircularReference(node, assignment.right);
|
|
405
448
|
}
|
|
406
449
|
}
|
|
407
|
-
else if (assignment.right.type ===
|
|
450
|
+
else if (assignment.right.type ===
|
|
451
|
+
utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
408
452
|
const referencedObj = getObjectFromMemberExpression(assignment.right);
|
|
409
453
|
if (referencedObj) {
|
|
410
454
|
checkAndReportCircularReference(node, assignment.right);
|
|
@@ -419,14 +463,14 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
419
463
|
}
|
|
420
464
|
}
|
|
421
465
|
},
|
|
422
|
-
|
|
466
|
+
CallExpression(node) {
|
|
423
467
|
if (node.callee.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
424
468
|
const obj = node.callee.object;
|
|
425
469
|
const prop = node.callee.property;
|
|
426
470
|
if (isIdentifier(obj) && isIdentifier(prop) && prop.name === 'then') {
|
|
427
471
|
// Handle Promise.then() calls
|
|
428
472
|
const scope = context.getScope();
|
|
429
|
-
const variable = scope.variables.find(v => v.name === obj.name);
|
|
473
|
+
const variable = scope.variables.find((v) => v.name === obj.name);
|
|
430
474
|
if (variable?.defs[0]?.node.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
|
|
431
475
|
const init = variable.defs[0].node.init;
|
|
432
476
|
if (init && init.type === utils_1.AST_NODE_TYPES.CallExpression) {
|
|
@@ -434,18 +478,26 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
434
478
|
if (callee.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
435
479
|
const calleeObj = callee.object;
|
|
436
480
|
const calleeProp = callee.property;
|
|
437
|
-
if (isIdentifier(calleeObj) &&
|
|
481
|
+
if (isIdentifier(calleeObj) &&
|
|
482
|
+
isIdentifier(calleeProp) &&
|
|
483
|
+
calleeObj.name === 'Promise' &&
|
|
484
|
+
calleeProp.name === 'resolve') {
|
|
438
485
|
// This is a Promise.resolve() call
|
|
439
|
-
if (init.arguments.length > 0 &&
|
|
486
|
+
if (init.arguments.length > 0 &&
|
|
487
|
+
init.arguments[0].type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
440
488
|
const arg = init.arguments[0];
|
|
441
489
|
const referencedObj = getReferencedObject(arg);
|
|
442
490
|
if (referencedObj) {
|
|
443
491
|
// Check if the promise callback assigns the resolved value back to the original object
|
|
444
|
-
if (node.arguments.length > 0 &&
|
|
492
|
+
if (node.arguments.length > 0 &&
|
|
493
|
+
node.arguments[0].type ===
|
|
494
|
+
utils_1.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
445
495
|
const callback = node.arguments[0];
|
|
446
|
-
if (callback.body.type ===
|
|
496
|
+
if (callback.body.type ===
|
|
497
|
+
utils_1.AST_NODE_TYPES.AssignmentExpression) {
|
|
447
498
|
const assignment = callback.body;
|
|
448
|
-
if (assignment.left.type ===
|
|
499
|
+
if (assignment.left.type ===
|
|
500
|
+
utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
449
501
|
const leftObj = assignment.left.object;
|
|
450
502
|
if (isIdentifier(leftObj)) {
|
|
451
503
|
const leftObjRef = getReferencedObject(leftObj);
|
|
@@ -460,9 +512,13 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
460
512
|
}
|
|
461
513
|
else if (callback.body.type === utils_1.AST_NODE_TYPES.BlockStatement) {
|
|
462
514
|
for (const stmt of callback.body.body) {
|
|
463
|
-
if (stmt.type ===
|
|
515
|
+
if (stmt.type ===
|
|
516
|
+
utils_1.AST_NODE_TYPES.ExpressionStatement &&
|
|
517
|
+
stmt.expression.type ===
|
|
518
|
+
utils_1.AST_NODE_TYPES.AssignmentExpression) {
|
|
464
519
|
const assignment = stmt.expression;
|
|
465
|
-
if (assignment.left.type ===
|
|
520
|
+
if (assignment.left.type ===
|
|
521
|
+
utils_1.AST_NODE_TYPES.MemberExpression) {
|
|
466
522
|
const leftObj = assignment.left.object;
|
|
467
523
|
if (isIdentifier(leftObj)) {
|
|
468
524
|
const leftObjRef = getReferencedObject(leftObj);
|
|
@@ -487,8 +543,10 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
487
543
|
}
|
|
488
544
|
}
|
|
489
545
|
},
|
|
490
|
-
|
|
491
|
-
if (node.parent &&
|
|
546
|
+
MemberExpression(node) {
|
|
547
|
+
if (node.parent &&
|
|
548
|
+
node.parent.type === utils_1.AST_NODE_TYPES.AssignmentExpression &&
|
|
549
|
+
node.parent.left === node) {
|
|
492
550
|
return; // Skip left side of assignments, handled elsewhere
|
|
493
551
|
}
|
|
494
552
|
const obj = node.object;
|
|
@@ -501,9 +559,13 @@ exports.noCircularReferences = (0, createRule_1.createRule)({
|
|
|
501
559
|
const info = objectMap.get(referencedObj);
|
|
502
560
|
if (info && info.scope === scopeId) {
|
|
503
561
|
// Check if this property access might lead to a circular reference
|
|
504
|
-
if (prop.name === 'self' ||
|
|
562
|
+
if (prop.name === 'self' ||
|
|
563
|
+
prop.name === 'ref' ||
|
|
564
|
+
prop.name === 'circular') {
|
|
505
565
|
const parent = node.parent;
|
|
506
|
-
if (parent &&
|
|
566
|
+
if (parent &&
|
|
567
|
+
parent.type === utils_1.AST_NODE_TYPES.AssignmentExpression &&
|
|
568
|
+
parent.right === node) {
|
|
507
569
|
const leftObj = getObjectFromMemberExpression(parent.left);
|
|
508
570
|
if (leftObj === referencedObj) {
|
|
509
571
|
context.report({
|
|
@@ -244,8 +244,10 @@ exports.noComplexCloudParams = (0, createRule_1.createRule)({
|
|
|
244
244
|
['WeakMap', 'WeakSet', 'Promise', 'Error'].includes(node.object.name)) {
|
|
245
245
|
return true;
|
|
246
246
|
}
|
|
247
|
-
//
|
|
248
|
-
|
|
247
|
+
// For property access expressions, we only need to check if the object itself is complex
|
|
248
|
+
// We don't need to check the property, as accessing a property will result in a primitive value
|
|
249
|
+
// or another object that we'll check separately
|
|
250
|
+
return isComplexValue(node.object);
|
|
249
251
|
}
|
|
250
252
|
// Check for Symbols
|
|
251
253
|
if (node.type === utils_1.AST_NODE_TYPES.Identifier && node.name === 'Symbol') {
|