@pobammer-ts/small-rules 2.3.0 → 2.4.1
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/dist/index.js +260 -231
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { definePlugin, defineRule } from "oxlint-plugin-utilities";
|
|
2
2
|
import ignore from "ignore";
|
|
3
|
-
import path, { basename, dirname, extname, join, relative } from "node:path";
|
|
3
|
+
import path, { basename, dirname, extname, isAbsolute, join, relative } from "node:path";
|
|
4
4
|
import { parseSync } from "oxc-parser";
|
|
5
5
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
6
6
|
import { ResolverFactory } from "oxc-resolver";
|
|
7
7
|
import { type } from "arktype";
|
|
8
|
-
import { minimatch } from "minimatch";
|
|
8
|
+
import { Minimatch, minimatch } from "minimatch";
|
|
9
9
|
//#region src/rules/array-type-generic.ts
|
|
10
10
|
function toGenericArrayType(typeNode, sourceCode) {
|
|
11
11
|
if (typeNode.type === "TSParenthesizedType") return toGenericArrayType(typeNode.typeAnnotation, sourceCode);
|
|
@@ -113,6 +113,197 @@ function hasShadowedBinding(sourceCode, node, name) {
|
|
|
113
113
|
return false;
|
|
114
114
|
}
|
|
115
115
|
//#endregion
|
|
116
|
+
//#region src/utilities/oxc-utilities.ts
|
|
117
|
+
const COMPONENT_NAME_PATTERN = /^[A-Z]/v;
|
|
118
|
+
const KEY_OF_NODE = new Set([
|
|
119
|
+
"end",
|
|
120
|
+
"loc",
|
|
121
|
+
"parent",
|
|
122
|
+
"range",
|
|
123
|
+
"start",
|
|
124
|
+
"type"
|
|
125
|
+
]);
|
|
126
|
+
function isNode$1(value) {
|
|
127
|
+
return isRecord(value) && isStringRaw(value.type);
|
|
128
|
+
}
|
|
129
|
+
function isKeyOfNode(key) {
|
|
130
|
+
return KEY_OF_NODE.has(key);
|
|
131
|
+
}
|
|
132
|
+
function isComponentName(name) {
|
|
133
|
+
return COMPONENT_NAME_PATTERN.test(name);
|
|
134
|
+
}
|
|
135
|
+
function isVariableDeclarator(node) {
|
|
136
|
+
return node.type === "VariableDeclarator";
|
|
137
|
+
}
|
|
138
|
+
function getTypeAnnotationFromBinding(binding) {
|
|
139
|
+
return isTsTypeAnnotation(binding.typeAnnotation) ? binding.typeAnnotation : void 0;
|
|
140
|
+
}
|
|
141
|
+
function isTsTypeAnnotation(value) {
|
|
142
|
+
return isRecord(value) && "type" in value && value.type === "TSTypeAnnotation";
|
|
143
|
+
}
|
|
144
|
+
function isIdentifierNamed$1(node, name) {
|
|
145
|
+
return node.type === "Identifier" && node.name === name;
|
|
146
|
+
}
|
|
147
|
+
function isReactNamedCall(node, identifiers, reactNamespaces, name) {
|
|
148
|
+
if (node.callee.type === "Identifier") return identifiers.has(node.callee.name);
|
|
149
|
+
if (node.callee.type !== "MemberExpression" || node.callee.object.type !== "Identifier") return false;
|
|
150
|
+
return reactNamespaces.has(node.callee.object.name) && getMemberPropertyName(node.callee) === name;
|
|
151
|
+
}
|
|
152
|
+
function isUseMemoCall(node, memoIdentifiers, reactNamespaces) {
|
|
153
|
+
return isReactNamedCall(node, memoIdentifiers, reactNamespaces, "useMemo");
|
|
154
|
+
}
|
|
155
|
+
function getImportedName({ imported }) {
|
|
156
|
+
return imported.type === "Identifier" ? imported.name : imported.value;
|
|
157
|
+
}
|
|
158
|
+
function hasName(node) {
|
|
159
|
+
return node.type === "Identifier" && isStringRaw(node.name);
|
|
160
|
+
}
|
|
161
|
+
function isIdentifierName(node) {
|
|
162
|
+
return node.type === "Identifier";
|
|
163
|
+
}
|
|
164
|
+
function isJsxIdentifier$1(node) {
|
|
165
|
+
return node.type === "JSXIdentifier" && "name" in node;
|
|
166
|
+
}
|
|
167
|
+
function isJsxOpeningExpression(node) {
|
|
168
|
+
return node.type === "JSXOpeningElement";
|
|
169
|
+
}
|
|
170
|
+
function isImportDeclaration(node) {
|
|
171
|
+
return node.type === "ImportDeclaration";
|
|
172
|
+
}
|
|
173
|
+
function isStringLiteral(node) {
|
|
174
|
+
return node.type === "Literal" && isStringRaw(node.value);
|
|
175
|
+
}
|
|
176
|
+
function isCallExpression$1(node) {
|
|
177
|
+
return node.type === "CallExpression";
|
|
178
|
+
}
|
|
179
|
+
function isImportSpecifier$1(node) {
|
|
180
|
+
return node.type === "ImportSpecifier";
|
|
181
|
+
}
|
|
182
|
+
function isExportSpecifier(node) {
|
|
183
|
+
return node.type === "ExportSpecifier";
|
|
184
|
+
}
|
|
185
|
+
function isProperty(node) {
|
|
186
|
+
return node.type === "Property";
|
|
187
|
+
}
|
|
188
|
+
function isMemberExpression(node) {
|
|
189
|
+
return node.type === "MemberExpression";
|
|
190
|
+
}
|
|
191
|
+
function isAssignmentExpression(node) {
|
|
192
|
+
return node.type === "AssignmentExpression";
|
|
193
|
+
}
|
|
194
|
+
function isUnaryExpression(node) {
|
|
195
|
+
return node.type === "UnaryExpression";
|
|
196
|
+
}
|
|
197
|
+
function isBinaryExpression(node) {
|
|
198
|
+
return node.type === "BinaryExpression";
|
|
199
|
+
}
|
|
200
|
+
function isLogicalExpression(node) {
|
|
201
|
+
return node.type === "LogicalExpression";
|
|
202
|
+
}
|
|
203
|
+
function isConditionalExpression(node) {
|
|
204
|
+
return node.type === "ConditionalExpression";
|
|
205
|
+
}
|
|
206
|
+
function isSequenceExpression(node) {
|
|
207
|
+
return node.type === "SequenceExpression";
|
|
208
|
+
}
|
|
209
|
+
function isMethodDefinition(node) {
|
|
210
|
+
return node.type === "MethodDefinition" || node.type === "TSAbstractMethodDefinition";
|
|
211
|
+
}
|
|
212
|
+
function isPropertyDefinition(node) {
|
|
213
|
+
return node.type === "PropertyDefinition" || node.type === "TSAbstractPropertyDefinition";
|
|
214
|
+
}
|
|
215
|
+
function isImportDefaultSpecifier(node) {
|
|
216
|
+
return node.type === "ImportDefaultSpecifier";
|
|
217
|
+
}
|
|
218
|
+
function isImportNamespaceSpecifier(node) {
|
|
219
|
+
return node.type === "ImportNamespaceSpecifier";
|
|
220
|
+
}
|
|
221
|
+
function isVariableDeclaration(node) {
|
|
222
|
+
return node.type === "VariableDeclaration";
|
|
223
|
+
}
|
|
224
|
+
function isExportNamedDeclaration(node) {
|
|
225
|
+
return node.type === "ExportNamedDeclaration";
|
|
226
|
+
}
|
|
227
|
+
function isFunctionDeclaration(node) {
|
|
228
|
+
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
|
|
229
|
+
}
|
|
230
|
+
function isCallbackFunction(node) {
|
|
231
|
+
return node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression";
|
|
232
|
+
}
|
|
233
|
+
function isAnyFunction(node) {
|
|
234
|
+
return node.type === "ArrowFunctionExpression" || node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
|
|
235
|
+
}
|
|
236
|
+
function isNamedGlobalCall(node, name) {
|
|
237
|
+
return isIdentifierNamed$1(node.callee, name);
|
|
238
|
+
}
|
|
239
|
+
function isClass(node) {
|
|
240
|
+
return node.type === "ClassDeclaration" || node.type === "ClassExpression";
|
|
241
|
+
}
|
|
242
|
+
function isTsTypeAliasDeclaration(node) {
|
|
243
|
+
return node.type === "TSTypeAliasDeclaration";
|
|
244
|
+
}
|
|
245
|
+
function isTsPropertySignature(node) {
|
|
246
|
+
return node.type === "TSPropertySignature";
|
|
247
|
+
}
|
|
248
|
+
function isLiteral(node) {
|
|
249
|
+
return node.type === "Literal";
|
|
250
|
+
}
|
|
251
|
+
function isArrowFunctionExpression(node) {
|
|
252
|
+
return node.type === "ArrowFunctionExpression";
|
|
253
|
+
}
|
|
254
|
+
function isFunction(node) {
|
|
255
|
+
return isFunctionDeclaration(node) || isArrowFunctionExpression(node);
|
|
256
|
+
}
|
|
257
|
+
function isTsQualifiedName(node) {
|
|
258
|
+
return node.type === "TSQualifiedName";
|
|
259
|
+
}
|
|
260
|
+
function isNumericLiteral(node) {
|
|
261
|
+
return node.type === "Literal" && isNumberRaw(node.value);
|
|
262
|
+
}
|
|
263
|
+
function isNewExpression(node) {
|
|
264
|
+
return node.type === "NewExpression";
|
|
265
|
+
}
|
|
266
|
+
function isArrayExpression(node) {
|
|
267
|
+
return node.type === "ArrayExpression";
|
|
268
|
+
}
|
|
269
|
+
function isObjectExpression(node) {
|
|
270
|
+
return node.type === "ObjectExpression";
|
|
271
|
+
}
|
|
272
|
+
function isObjectPattern(node) {
|
|
273
|
+
return node.type === "ObjectPattern";
|
|
274
|
+
}
|
|
275
|
+
function isTemplateLiteral(node) {
|
|
276
|
+
return node.type === "TemplateLiteral";
|
|
277
|
+
}
|
|
278
|
+
function isExpressionStatement(node) {
|
|
279
|
+
return node.type === "ExpressionStatement";
|
|
280
|
+
}
|
|
281
|
+
function isTsTypeAssertion(node) {
|
|
282
|
+
return node.type === "TSTypeAssertion";
|
|
283
|
+
}
|
|
284
|
+
function isTsAsExpression(node) {
|
|
285
|
+
return node.type === "TSAsExpression";
|
|
286
|
+
}
|
|
287
|
+
function isAssignmentPattern(node) {
|
|
288
|
+
return node.type === "AssignmentPattern";
|
|
289
|
+
}
|
|
290
|
+
function isThisExpression(node) {
|
|
291
|
+
return node.type === "ThisExpression";
|
|
292
|
+
}
|
|
293
|
+
function isStaticRequire(node) {
|
|
294
|
+
if (!isCallExpression$1(node) || node.optional) return false;
|
|
295
|
+
const { callee } = node;
|
|
296
|
+
if (!isIdentifierName(callee) || callee.name !== "require" || node.arguments.length !== 1) return false;
|
|
297
|
+
const [argument] = node.arguments;
|
|
298
|
+
return argument !== void 0 && isStringLiteral(argument);
|
|
299
|
+
}
|
|
300
|
+
function isBindingIdentifier(node) {
|
|
301
|
+
return node.type === "Identifier";
|
|
302
|
+
}
|
|
303
|
+
function isExpressionNode(node) {
|
|
304
|
+
return node.type !== "PrivateIdentifier";
|
|
305
|
+
}
|
|
306
|
+
//#endregion
|
|
116
307
|
//#region src/rules/ban-instances.ts
|
|
117
308
|
function getJsxAttributeName$2(name) {
|
|
118
309
|
return name.type === "JSXIdentifier" ? name.name : name.name.name;
|
|
@@ -163,7 +354,7 @@ function getEnclosingFunctionScope(scope) {
|
|
|
163
354
|
return currentScope;
|
|
164
355
|
}
|
|
165
356
|
function getInstanceClassName(node) {
|
|
166
|
-
if (node
|
|
357
|
+
if (!isNamedGlobalCall(node, "Instance")) return void 0;
|
|
167
358
|
const [firstArgument] = node.arguments;
|
|
168
359
|
if (firstArgument?.type !== "Literal" || !isStringRaw(firstArgument.value)) return void 0;
|
|
169
360
|
return firstArgument.value;
|
|
@@ -327,191 +518,6 @@ const banInstances = defineRule({
|
|
|
327
518
|
}
|
|
328
519
|
});
|
|
329
520
|
//#endregion
|
|
330
|
-
//#region src/utilities/oxc-utilities.ts
|
|
331
|
-
const COMPONENT_NAME_PATTERN = /^[A-Z]/v;
|
|
332
|
-
const KEY_OF_NODE = new Set([
|
|
333
|
-
"end",
|
|
334
|
-
"loc",
|
|
335
|
-
"parent",
|
|
336
|
-
"range",
|
|
337
|
-
"start",
|
|
338
|
-
"type"
|
|
339
|
-
]);
|
|
340
|
-
function isNode$1(value) {
|
|
341
|
-
return isRecord(value) && isStringRaw(value.type);
|
|
342
|
-
}
|
|
343
|
-
function isKeyOfNode(key) {
|
|
344
|
-
return KEY_OF_NODE.has(key);
|
|
345
|
-
}
|
|
346
|
-
function isComponentName(name) {
|
|
347
|
-
return COMPONENT_NAME_PATTERN.test(name);
|
|
348
|
-
}
|
|
349
|
-
function isVariableDeclarator(node) {
|
|
350
|
-
return node.type === "VariableDeclarator";
|
|
351
|
-
}
|
|
352
|
-
function getTypeAnnotationFromBinding(binding) {
|
|
353
|
-
return isTsTypeAnnotation(binding.typeAnnotation) ? binding.typeAnnotation : void 0;
|
|
354
|
-
}
|
|
355
|
-
function isTsTypeAnnotation(value) {
|
|
356
|
-
return isRecord(value) && "type" in value && value.type === "TSTypeAnnotation";
|
|
357
|
-
}
|
|
358
|
-
function isIdentifierNamed$1(node, name) {
|
|
359
|
-
return node.type === "Identifier" && node.name === name;
|
|
360
|
-
}
|
|
361
|
-
function isReactNamedCall(node, identifiers, reactNamespaces, name) {
|
|
362
|
-
if (node.callee.type === "Identifier") return identifiers.has(node.callee.name);
|
|
363
|
-
if (node.callee.type !== "MemberExpression" || node.callee.object.type !== "Identifier") return false;
|
|
364
|
-
return reactNamespaces.has(node.callee.object.name) && getMemberPropertyName(node.callee) === name;
|
|
365
|
-
}
|
|
366
|
-
function isUseMemoCall(node, memoIdentifiers, reactNamespaces) {
|
|
367
|
-
return isReactNamedCall(node, memoIdentifiers, reactNamespaces, "useMemo");
|
|
368
|
-
}
|
|
369
|
-
function getImportedName({ imported }) {
|
|
370
|
-
return imported.type === "Identifier" ? imported.name : imported.value;
|
|
371
|
-
}
|
|
372
|
-
function hasName(node) {
|
|
373
|
-
return node.type === "Identifier" && isStringRaw(node.name);
|
|
374
|
-
}
|
|
375
|
-
function isIdentifierName(node) {
|
|
376
|
-
return node.type === "Identifier";
|
|
377
|
-
}
|
|
378
|
-
function isJsxIdentifier$1(node) {
|
|
379
|
-
return node.type === "JSXIdentifier" && "name" in node;
|
|
380
|
-
}
|
|
381
|
-
function isJsxOpeningExpression(node) {
|
|
382
|
-
return node.type === "JSXOpeningElement";
|
|
383
|
-
}
|
|
384
|
-
function isImportDeclaration(node) {
|
|
385
|
-
return node.type === "ImportDeclaration";
|
|
386
|
-
}
|
|
387
|
-
function isStringLiteral(node) {
|
|
388
|
-
return node.type === "Literal" && isStringRaw(node.value);
|
|
389
|
-
}
|
|
390
|
-
function isCallExpression$1(node) {
|
|
391
|
-
return node.type === "CallExpression";
|
|
392
|
-
}
|
|
393
|
-
function isImportSpecifier$1(node) {
|
|
394
|
-
return node.type === "ImportSpecifier";
|
|
395
|
-
}
|
|
396
|
-
function isExportSpecifier(node) {
|
|
397
|
-
return node.type === "ExportSpecifier";
|
|
398
|
-
}
|
|
399
|
-
function isProperty(node) {
|
|
400
|
-
return node.type === "Property";
|
|
401
|
-
}
|
|
402
|
-
function isMemberExpression(node) {
|
|
403
|
-
return node.type === "MemberExpression";
|
|
404
|
-
}
|
|
405
|
-
function isAssignmentExpression(node) {
|
|
406
|
-
return node.type === "AssignmentExpression";
|
|
407
|
-
}
|
|
408
|
-
function isUnaryExpression(node) {
|
|
409
|
-
return node.type === "UnaryExpression";
|
|
410
|
-
}
|
|
411
|
-
function isBinaryExpression(node) {
|
|
412
|
-
return node.type === "BinaryExpression";
|
|
413
|
-
}
|
|
414
|
-
function isLogicalExpression(node) {
|
|
415
|
-
return node.type === "LogicalExpression";
|
|
416
|
-
}
|
|
417
|
-
function isConditionalExpression(node) {
|
|
418
|
-
return node.type === "ConditionalExpression";
|
|
419
|
-
}
|
|
420
|
-
function isSequenceExpression(node) {
|
|
421
|
-
return node.type === "SequenceExpression";
|
|
422
|
-
}
|
|
423
|
-
function isMethodDefinition(node) {
|
|
424
|
-
return node.type === "MethodDefinition" || node.type === "TSAbstractMethodDefinition";
|
|
425
|
-
}
|
|
426
|
-
function isPropertyDefinition(node) {
|
|
427
|
-
return node.type === "PropertyDefinition" || node.type === "TSAbstractPropertyDefinition";
|
|
428
|
-
}
|
|
429
|
-
function isImportDefaultSpecifier(node) {
|
|
430
|
-
return node.type === "ImportDefaultSpecifier";
|
|
431
|
-
}
|
|
432
|
-
function isImportNamespaceSpecifier(node) {
|
|
433
|
-
return node.type === "ImportNamespaceSpecifier";
|
|
434
|
-
}
|
|
435
|
-
function isVariableDeclaration(node) {
|
|
436
|
-
return node.type === "VariableDeclaration";
|
|
437
|
-
}
|
|
438
|
-
function isExportNamedDeclaration(node) {
|
|
439
|
-
return node.type === "ExportNamedDeclaration";
|
|
440
|
-
}
|
|
441
|
-
function isFunctionDeclaration(node) {
|
|
442
|
-
return node.type === "FunctionDeclaration" || node.type === "FunctionExpression";
|
|
443
|
-
}
|
|
444
|
-
function isCallbackFunction(node) {
|
|
445
|
-
return node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression";
|
|
446
|
-
}
|
|
447
|
-
function isClass(node) {
|
|
448
|
-
return node.type === "ClassDeclaration" || node.type === "ClassExpression";
|
|
449
|
-
}
|
|
450
|
-
function isTsTypeAliasDeclaration(node) {
|
|
451
|
-
return node.type === "TSTypeAliasDeclaration";
|
|
452
|
-
}
|
|
453
|
-
function isTsPropertySignature(node) {
|
|
454
|
-
return node.type === "TSPropertySignature";
|
|
455
|
-
}
|
|
456
|
-
function isLiteral(node) {
|
|
457
|
-
return node.type === "Literal";
|
|
458
|
-
}
|
|
459
|
-
function isArrowFunctionExpression(node) {
|
|
460
|
-
return node.type === "ArrowFunctionExpression";
|
|
461
|
-
}
|
|
462
|
-
function isFunction(node) {
|
|
463
|
-
return isFunctionDeclaration(node) || isArrowFunctionExpression(node);
|
|
464
|
-
}
|
|
465
|
-
function isTsQualifiedName(node) {
|
|
466
|
-
return node.type === "TSQualifiedName";
|
|
467
|
-
}
|
|
468
|
-
function isNumericLiteral(node) {
|
|
469
|
-
return node.type === "Literal" && isNumberRaw(node.value);
|
|
470
|
-
}
|
|
471
|
-
function isNewExpression(node) {
|
|
472
|
-
return node.type === "NewExpression";
|
|
473
|
-
}
|
|
474
|
-
function isArrayExpression(node) {
|
|
475
|
-
return node.type === "ArrayExpression";
|
|
476
|
-
}
|
|
477
|
-
function isObjectExpression(node) {
|
|
478
|
-
return node.type === "ObjectExpression";
|
|
479
|
-
}
|
|
480
|
-
function isObjectPattern(node) {
|
|
481
|
-
return node.type === "ObjectPattern";
|
|
482
|
-
}
|
|
483
|
-
function isTemplateLiteral(node) {
|
|
484
|
-
return node.type === "TemplateLiteral";
|
|
485
|
-
}
|
|
486
|
-
function isExpressionStatement(node) {
|
|
487
|
-
return node.type === "ExpressionStatement";
|
|
488
|
-
}
|
|
489
|
-
function isTsTypeAssertion(node) {
|
|
490
|
-
return node.type === "TSTypeAssertion";
|
|
491
|
-
}
|
|
492
|
-
function isTsAsExpression(node) {
|
|
493
|
-
return node.type === "TSAsExpression";
|
|
494
|
-
}
|
|
495
|
-
function isAssignmentPattern(node) {
|
|
496
|
-
return node.type === "AssignmentPattern";
|
|
497
|
-
}
|
|
498
|
-
function isThisExpression(node) {
|
|
499
|
-
return node.type === "ThisExpression";
|
|
500
|
-
}
|
|
501
|
-
function isStaticRequire(node) {
|
|
502
|
-
if (!isCallExpression$1(node) || node.optional) return false;
|
|
503
|
-
const { callee } = node;
|
|
504
|
-
if (!isIdentifierName(callee) || callee.name !== "require" || node.arguments.length !== 1) return false;
|
|
505
|
-
const [argument] = node.arguments;
|
|
506
|
-
return argument !== void 0 && isStringLiteral(argument);
|
|
507
|
-
}
|
|
508
|
-
function isBindingIdentifier(node) {
|
|
509
|
-
return node.type === "Identifier";
|
|
510
|
-
}
|
|
511
|
-
function isExpressionNode(node) {
|
|
512
|
-
return node.type !== "PrivateIdentifier";
|
|
513
|
-
}
|
|
514
|
-
//#endregion
|
|
515
521
|
//#region src/rules/ban-react-fc.ts
|
|
516
522
|
const BANNED_FC_NAMES = new Set([
|
|
517
523
|
"FC",
|
|
@@ -2598,7 +2604,7 @@ function isPromiseChainCall(node) {
|
|
|
2598
2604
|
}
|
|
2599
2605
|
function isAsyncIife({ callee }) {
|
|
2600
2606
|
const unwrapped = unwrapExpression(callee);
|
|
2601
|
-
return (unwrapped
|
|
2607
|
+
return isCallbackFunction(unwrapped) && unwrapped.async;
|
|
2602
2608
|
}
|
|
2603
2609
|
function getThisAsyncMethodName({ callee }, asyncMethods) {
|
|
2604
2610
|
if (callee.type !== "MemberExpression" || callee.object.type !== "ThisExpression" || callee.property.type !== "Identifier") return;
|
|
@@ -2615,7 +2621,7 @@ function getLocalVariableAssignment(node) {
|
|
|
2615
2621
|
return parent.id.type === "Identifier" ? parent.id.name : void 0;
|
|
2616
2622
|
}
|
|
2617
2623
|
function isNonIifeFunction(node) {
|
|
2618
|
-
if (node
|
|
2624
|
+
if (!isCallbackFunction(node)) return false;
|
|
2619
2625
|
if (node.parent.type === "ParenthesizedExpression" && node.parent.parent.type === "CallExpression" && node.parent.parent.callee === node.parent) return false;
|
|
2620
2626
|
return node.parent.type !== "CallExpression" || node.parent.callee !== node;
|
|
2621
2627
|
}
|
|
@@ -2766,7 +2772,7 @@ const noColor3Constructor = defineRule({
|
|
|
2766
2772
|
create(context) {
|
|
2767
2773
|
const options = normalizeOptions$4(context.options[0]);
|
|
2768
2774
|
return { NewExpression(node) {
|
|
2769
|
-
if (node
|
|
2775
|
+
if (!isNamedGlobalCall(node, "Color3")) return;
|
|
2770
2776
|
const parameters = node.arguments;
|
|
2771
2777
|
if (parameters.length === 0) return;
|
|
2772
2778
|
const collected = collectNumericComponents(parameters);
|
|
@@ -3446,14 +3452,6 @@ const LOOP_TYPES = new Set([
|
|
|
3446
3452
|
function isLoopNode(node) {
|
|
3447
3453
|
return LOOP_TYPES.has(node.type);
|
|
3448
3454
|
}
|
|
3449
|
-
const FUNCTION_BOUNDARY_TYPES$1 = new Set([
|
|
3450
|
-
"ArrowFunctionExpression",
|
|
3451
|
-
"FunctionDeclaration",
|
|
3452
|
-
"FunctionExpression"
|
|
3453
|
-
]);
|
|
3454
|
-
function isFunctionBoundary(node) {
|
|
3455
|
-
return FUNCTION_BOUNDARY_TYPES$1.has(node.type);
|
|
3456
|
-
}
|
|
3457
3455
|
function findLabeledStatementBody$1(labelName, startingNode) {
|
|
3458
3456
|
let current = startingNode;
|
|
3459
3457
|
while (current !== null) {
|
|
@@ -3467,7 +3465,7 @@ function breaksTargetLoop(statement, loopNode) {
|
|
|
3467
3465
|
if (statement.label) return findLabeledStatementBody$1(statement.label.name, statement.parent) === loopNode;
|
|
3468
3466
|
let current = statement.parent;
|
|
3469
3467
|
while (current !== null) {
|
|
3470
|
-
if (current.type === "Program" ||
|
|
3468
|
+
if (current.type === "Program" || isAnyFunction(current) || current.type === "SwitchStatement") return false;
|
|
3471
3469
|
if (isLoopNode(current)) return current === loopNode;
|
|
3472
3470
|
current = current.parent;
|
|
3473
3471
|
}
|
|
@@ -5534,7 +5532,7 @@ function hasAspectRatioConstraintInSubtree(node) {
|
|
|
5534
5532
|
function getFunctionComponentName(node) {
|
|
5535
5533
|
if (node.type === "FunctionDeclaration") return node.id?.name;
|
|
5536
5534
|
/* v8 ignore next -- @preserve only named declarations and assigned function expressions are inspected as components. */
|
|
5537
|
-
if (node
|
|
5535
|
+
if (isCallbackFunction(node)) {
|
|
5538
5536
|
const { parent } = node;
|
|
5539
5537
|
/* v8 ignore next -- @preserve assigned function components have identifier variable declarator parents. */
|
|
5540
5538
|
if (parent.type === "VariableDeclarator" && parent.id.type === "Identifier") return parent.id.name;
|
|
@@ -5815,7 +5813,46 @@ const isRuleOptions = type({
|
|
|
5815
5813
|
"checkComputed?": "boolean | undefined",
|
|
5816
5814
|
restrictions: isRestriction.array().readonly()
|
|
5817
5815
|
}).readonly();
|
|
5818
|
-
const
|
|
5816
|
+
const FILE_MATCH_OPTIONS = { matchBase: true };
|
|
5817
|
+
const NAME_MATCH_OPTIONS = {
|
|
5818
|
+
dot: true,
|
|
5819
|
+
magicalBraces: true
|
|
5820
|
+
};
|
|
5821
|
+
function normalizePath(value) {
|
|
5822
|
+
return value.replaceAll("\\", "/");
|
|
5823
|
+
}
|
|
5824
|
+
function createFileCandidates(filename) {
|
|
5825
|
+
const normalizedFilename = normalizePath(filename);
|
|
5826
|
+
if (!isAbsolute(filename)) return [normalizedFilename];
|
|
5827
|
+
const relativeFilename = normalizePath(relative(process.cwd(), filename));
|
|
5828
|
+
if (relativeFilename === "" || relativeFilename.startsWith("..")) return [normalizedFilename];
|
|
5829
|
+
return [normalizedFilename, relativeFilename];
|
|
5830
|
+
}
|
|
5831
|
+
function compileMatcher(pattern, options) {
|
|
5832
|
+
const matcher = new Minimatch(pattern, options);
|
|
5833
|
+
const hasMagic = matcher.hasMagic();
|
|
5834
|
+
return {
|
|
5835
|
+
hasMagic,
|
|
5836
|
+
matches: hasMagic ? (value) => matcher.match(value) : (value) => value === pattern
|
|
5837
|
+
};
|
|
5838
|
+
}
|
|
5839
|
+
function createPropertyMatcher(patterns) {
|
|
5840
|
+
const literalPatterns = /* @__PURE__ */ new Set();
|
|
5841
|
+
const globMatchers = [];
|
|
5842
|
+
for (const pattern of patterns) {
|
|
5843
|
+
const matcher = compileMatcher(pattern, NAME_MATCH_OPTIONS);
|
|
5844
|
+
if (matcher.hasMagic) globMatchers.push(matcher.matches);
|
|
5845
|
+
else literalPatterns.add(pattern);
|
|
5846
|
+
}
|
|
5847
|
+
return (property) => literalPatterns.has(property) || globMatchers.some((matcher) => matcher(property));
|
|
5848
|
+
}
|
|
5849
|
+
function compileRestriction(restriction) {
|
|
5850
|
+
return {
|
|
5851
|
+
matchesObject: compileMatcher(restriction.object, NAME_MATCH_OPTIONS).matches,
|
|
5852
|
+
matchesProperty: createPropertyMatcher(restriction.properties),
|
|
5853
|
+
message: restriction.message
|
|
5854
|
+
};
|
|
5855
|
+
}
|
|
5819
5856
|
function getEffectiveOptions(context) {
|
|
5820
5857
|
const [options] = context.options;
|
|
5821
5858
|
if (!isRuleOptions.allows(options)) return {
|
|
@@ -5824,11 +5861,12 @@ function getEffectiveOptions(context) {
|
|
|
5824
5861
|
restrictions: []
|
|
5825
5862
|
};
|
|
5826
5863
|
const { allowFiles, checkComputed, restrictions } = options;
|
|
5827
|
-
const
|
|
5864
|
+
const fileCandidates = createFileCandidates(context.filename);
|
|
5865
|
+
const isAllowedFile = allowFiles?.some((pattern) => fileCandidates.some((filename) => minimatch(filename, pattern, FILE_MATCH_OPTIONS))) ?? false;
|
|
5828
5866
|
return {
|
|
5829
5867
|
checkComputed: checkComputed ?? true,
|
|
5830
5868
|
isAllowedFile,
|
|
5831
|
-
restrictions
|
|
5869
|
+
restrictions: restrictions.map(compileRestriction)
|
|
5832
5870
|
};
|
|
5833
5871
|
}
|
|
5834
5872
|
const noRestrictedPropertyAssignment = defineRule({
|
|
@@ -5840,8 +5878,8 @@ const noRestrictedPropertyAssignment = defineRule({
|
|
|
5840
5878
|
const property = getMemberPropertyName(node);
|
|
5841
5879
|
if (property === void 0) return;
|
|
5842
5880
|
for (const restriction of restrictions) {
|
|
5843
|
-
if (restriction.
|
|
5844
|
-
if (restriction.
|
|
5881
|
+
if (!restriction.matchesObject(node.object.name)) continue;
|
|
5882
|
+
if (restriction.matchesProperty(property)) {
|
|
5845
5883
|
if (restriction.message === void 0) context.report({
|
|
5846
5884
|
data: {
|
|
5847
5885
|
object: node.object.name,
|
|
@@ -5992,7 +6030,7 @@ function isStaticComponentVariable(variable, name) {
|
|
|
5992
6030
|
if (definition.node.type !== "VariableDeclarator") continue;
|
|
5993
6031
|
const initializer = definition.node.init ?? void 0;
|
|
5994
6032
|
if (initializer === void 0) continue;
|
|
5995
|
-
if (initializer
|
|
6033
|
+
if (isCallbackFunction(initializer) || initializer.type === "ClassExpression") return true;
|
|
5996
6034
|
}
|
|
5997
6035
|
return false;
|
|
5998
6036
|
}
|
|
@@ -6385,9 +6423,14 @@ function collectAllScopes(root) {
|
|
|
6385
6423
|
function isFunctionLikeInitializer(node) {
|
|
6386
6424
|
return isCallbackFunction(node) || node.type === "ClassExpression";
|
|
6387
6425
|
}
|
|
6426
|
+
const OBJECT_LIKE_INITIALIZER_TYPES = new Set([
|
|
6427
|
+
"ArrayExpression",
|
|
6428
|
+
"ObjectExpression",
|
|
6429
|
+
"JSXElement",
|
|
6430
|
+
"JSXFragment"
|
|
6431
|
+
]);
|
|
6388
6432
|
function isObjectLikeInitializer(initializer, patterns, sourceCode) {
|
|
6389
|
-
if (
|
|
6390
|
-
if (initializer.type === "JSXElement" || initializer.type === "JSXFragment") return true;
|
|
6433
|
+
if (OBJECT_LIKE_INITIALIZER_TYPES.has(initializer.type)) return true;
|
|
6391
6434
|
if (initializer.type !== "CallExpression" && initializer.type !== "NewExpression") return false;
|
|
6392
6435
|
const candidateText = sourceCode.getText(initializer.callee);
|
|
6393
6436
|
for (const pattern of patterns) if (pattern.test(candidateText)) return true;
|
|
@@ -22045,7 +22088,7 @@ function getSequenceKeypointName(sequenceName) {
|
|
|
22045
22088
|
}
|
|
22046
22089
|
function getKeypointValue(node, keypointName, time) {
|
|
22047
22090
|
if (node.type !== "NewExpression") return void 0;
|
|
22048
|
-
if (node
|
|
22091
|
+
if (!isNamedGlobalCall(node, keypointName)) return void 0;
|
|
22049
22092
|
if (node.arguments.length !== 2) return void 0;
|
|
22050
22093
|
const [timeArgument, valueArgument] = node.arguments;
|
|
22051
22094
|
/* v8 ignore next -- @preserve length was checked above; this only guards malformed AST tuples. */
|
|
@@ -22704,7 +22747,7 @@ function collectArguments(parameters) {
|
|
|
22704
22747
|
const preferUDim2Shorthand = defineRule({
|
|
22705
22748
|
create(context) {
|
|
22706
22749
|
return { NewExpression(node) {
|
|
22707
|
-
if (node
|
|
22750
|
+
if (!isNamedGlobalCall(node, "UDim2")) return;
|
|
22708
22751
|
const collected = collectArguments(node.arguments);
|
|
22709
22752
|
if (collected === void 0) return;
|
|
22710
22753
|
const [scaleXNode, offsetXNode, scaleYNode, offsetYNode] = node.arguments;
|
|
@@ -25200,7 +25243,6 @@ const EMPTY_CALLBACK_USAGE = {
|
|
|
25200
25243
|
memoization: false
|
|
25201
25244
|
};
|
|
25202
25245
|
const SHOULD_ASCEND_TYPES = new Set(["ConditionalExpression", "LogicalExpression"]);
|
|
25203
|
-
const IS_FUNCTION_EXPRESSION = new Set(["ArrowFunctionExpression", "FunctionExpression"]);
|
|
25204
25246
|
const CONTROL_FLOW_TYPES = new Set([
|
|
25205
25247
|
"BlockStatement",
|
|
25206
25248
|
"CatchClause",
|
|
@@ -25225,13 +25267,10 @@ function ascendPastWrappers(node) {
|
|
|
25225
25267
|
while (current !== void 0 && WRAPPER_PARENT_TYPES.has(current.type)) current = getParent(current);
|
|
25226
25268
|
return current;
|
|
25227
25269
|
}
|
|
25228
|
-
function isFunctionLikeNode(node) {
|
|
25229
|
-
return node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression" || node.type === "FunctionDeclaration";
|
|
25230
|
-
}
|
|
25231
25270
|
function getEnclosingFunctionLike(node) {
|
|
25232
25271
|
let current = getParent(node);
|
|
25233
25272
|
while (current !== void 0) {
|
|
25234
|
-
if (
|
|
25273
|
+
if (isAnyFunction(current)) return current;
|
|
25235
25274
|
current = getParent(current);
|
|
25236
25275
|
}
|
|
25237
25276
|
}
|
|
@@ -25338,7 +25377,7 @@ function isFunctionReturnStatement(parent) {
|
|
|
25338
25377
|
while (currentNode !== void 0 && CONTROL_FLOW_TYPES.has(currentNode.type)) currentNode = ascendPastWrappers(getParent(currentNode));
|
|
25339
25378
|
/* v8 ignore next -- @preserve return statements that contain JSX are parser-nested inside a function body. */
|
|
25340
25379
|
if (currentNode === void 0) return false;
|
|
25341
|
-
return
|
|
25380
|
+
return isAnyFunction(currentNode);
|
|
25342
25381
|
}
|
|
25343
25382
|
function isTopLevelReturn(node) {
|
|
25344
25383
|
if (!isTopLevelFunctionReturn(node)) return false;
|
|
@@ -26118,11 +26157,6 @@ const strictComponentBoundaries = defineRule({
|
|
|
26118
26157
|
});
|
|
26119
26158
|
//#endregion
|
|
26120
26159
|
//#region src/rules/use-exhaustive-dependencies.ts
|
|
26121
|
-
const FUNCTION_DECLARATIONS = new Set([
|
|
26122
|
-
"ArrowFunctionExpression",
|
|
26123
|
-
"FunctionDeclaration",
|
|
26124
|
-
"FunctionExpression"
|
|
26125
|
-
]);
|
|
26126
26160
|
const UNSTABLE_VALUES = new Set([
|
|
26127
26161
|
"ArrayExpression",
|
|
26128
26162
|
"ArrowFunctionExpression",
|
|
@@ -26431,7 +26465,7 @@ function isDeclaredInComponentBody(variable, closureNode) {
|
|
|
26431
26465
|
/* v8 ignore next -- @preserve hook closure nodes are nested inside their containing component function. */
|
|
26432
26466
|
let parent = closureNode.parent ?? void 0;
|
|
26433
26467
|
while (parent) {
|
|
26434
|
-
if (
|
|
26468
|
+
if (isAnyFunction(parent)) {
|
|
26435
26469
|
const functionParent = parent;
|
|
26436
26470
|
if (variable.defs.some((definition) => {
|
|
26437
26471
|
if (definition.type !== "Parameter") return false;
|
|
@@ -26627,7 +26661,7 @@ function reportUnnecessaryDependency(context, dependencies, dependency, dependen
|
|
|
26627
26661
|
});
|
|
26628
26662
|
}
|
|
26629
26663
|
function isCallbackFunctionNode(node) {
|
|
26630
|
-
return node
|
|
26664
|
+
return node !== void 0 && isAnyFunction(node);
|
|
26631
26665
|
}
|
|
26632
26666
|
function getRequiredCaptures(captures, stableHooks) {
|
|
26633
26667
|
return captures.filter((capture) => capture.forceDependency || !isStableValue(capture.variable, capture.name, stableHooks));
|
|
@@ -26794,7 +26828,7 @@ const useExhaustiveDependencies = defineRule({
|
|
|
26794
26828
|
}
|
|
26795
26829
|
function resolveClosureFunction(closureArgument, callExpression) {
|
|
26796
26830
|
if (closureArgument.type === "ArrowFunctionExpression") return closureArgument;
|
|
26797
|
-
if (!(
|
|
26831
|
+
if (!(isAnyFunction(closureArgument) || closureArgument.type === "Identifier")) return void 0;
|
|
26798
26832
|
const resolved = resolveFunctionReference(closureArgument, getScope(callExpression));
|
|
26799
26833
|
return isCallbackFunctionNode(resolved) ? resolved : void 0;
|
|
26800
26834
|
}
|
|
@@ -26927,17 +26961,12 @@ function isHookCall(node) {
|
|
|
26927
26961
|
const hookName = getHookName$1(node);
|
|
26928
26962
|
return hookName !== void 0 && isReactHookName(hookName);
|
|
26929
26963
|
}
|
|
26930
|
-
const FUNCTION_BOUNDARIES = new Set([
|
|
26931
|
-
"ArrowFunctionExpression",
|
|
26932
|
-
"FunctionDeclaration",
|
|
26933
|
-
"FunctionExpression"
|
|
26934
|
-
]);
|
|
26935
26964
|
function isInFinallyBlock(node) {
|
|
26936
26965
|
let current = node.parent;
|
|
26937
26966
|
const maxDepth = 20;
|
|
26938
26967
|
let inFinallyBlock = false;
|
|
26939
26968
|
for (let depth = 0; depth < maxDepth && current !== null; depth += 1) {
|
|
26940
|
-
if (
|
|
26969
|
+
if (isAnyFunction(current)) break;
|
|
26941
26970
|
if (current.type === "TryStatement") {
|
|
26942
26971
|
let checkNode = node;
|
|
26943
26972
|
while (checkNode !== null && checkNode !== current) {
|