@pobammer-ts/small-rules 2.1.0 → 2.2.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/dist/index.d.ts +122 -286
- package/dist/index.js +316 -190
- package/package.json +21 -22
package/dist/index.js
CHANGED
|
@@ -7,15 +7,17 @@ import { ResolverFactory } from "oxc-resolver";
|
|
|
7
7
|
import { type } from "arktype";
|
|
8
8
|
//#region src/rules/array-type-generic.ts
|
|
9
9
|
function toGenericArrayType(typeNode, sourceCode) {
|
|
10
|
+
if (typeNode.type === "TSParenthesizedType") return toGenericArrayType(typeNode.typeAnnotation, sourceCode);
|
|
10
11
|
if (typeNode.type === "TSArrayType") return `Array<${toGenericArrayType(typeNode.elementType, sourceCode)}>`;
|
|
11
12
|
if (typeNode.type === "TSTypeOperator" && typeNode.operator === "readonly" && typeNode.typeAnnotation.type === "TSArrayType") return `ReadonlyArray<${toGenericArrayType(typeNode.typeAnnotation.elementType, sourceCode)}>`;
|
|
12
13
|
return sourceCode.getText(typeNode);
|
|
13
14
|
}
|
|
14
15
|
function isTopLevelArrayType({ parent }) {
|
|
15
|
-
|
|
16
|
+
const meaningfulParent = parent.type === "TSParenthesizedType" ? parent.parent : parent;
|
|
17
|
+
return !(meaningfulParent.type === "TSRestType" && meaningfulParent.parent.type === "TSTupleType" || meaningfulParent.type === "TSTupleType" || meaningfulParent.type === "TSArrayType" || meaningfulParent.type === "TSTypeOperator" && meaningfulParent.operator === "readonly");
|
|
16
18
|
}
|
|
17
19
|
const arrayTypeGeneric = defineRule({
|
|
18
|
-
|
|
20
|
+
createOnce(context) {
|
|
19
21
|
function reportArrayType(node) {
|
|
20
22
|
context.report({
|
|
21
23
|
fix(fixer) {
|
|
@@ -343,7 +345,7 @@ function isKeyOfNode(key) {
|
|
|
343
345
|
function isComponentName(name) {
|
|
344
346
|
return COMPONENT_NAME_PATTERN.test(name);
|
|
345
347
|
}
|
|
346
|
-
function isVariableDeclarator
|
|
348
|
+
function isVariableDeclarator(node) {
|
|
347
349
|
return node.type === "VariableDeclarator";
|
|
348
350
|
}
|
|
349
351
|
function getTypeAnnotationFromBinding(binding) {
|
|
@@ -369,7 +371,7 @@ function getImportedName({ imported }) {
|
|
|
369
371
|
function hasName(node) {
|
|
370
372
|
return node.type === "Identifier" && isStringRaw(node.name);
|
|
371
373
|
}
|
|
372
|
-
function isIdentifierName
|
|
374
|
+
function isIdentifierName(node) {
|
|
373
375
|
return node.type === "Identifier";
|
|
374
376
|
}
|
|
375
377
|
function isJsxIdentifier$1(node) {
|
|
@@ -381,7 +383,7 @@ function isJsxOpeningExpression(node) {
|
|
|
381
383
|
function isImportDeclaration(node) {
|
|
382
384
|
return node.type === "ImportDeclaration";
|
|
383
385
|
}
|
|
384
|
-
function isStringLiteral
|
|
386
|
+
function isStringLiteral(node) {
|
|
385
387
|
return node.type === "Literal" && isStringRaw(node.value);
|
|
386
388
|
}
|
|
387
389
|
function isCallExpression$1(node) {
|
|
@@ -429,7 +431,7 @@ function isImportDefaultSpecifier(node) {
|
|
|
429
431
|
function isImportNamespaceSpecifier(node) {
|
|
430
432
|
return node.type === "ImportNamespaceSpecifier";
|
|
431
433
|
}
|
|
432
|
-
function isVariableDeclaration
|
|
434
|
+
function isVariableDeclaration(node) {
|
|
433
435
|
return node.type === "VariableDeclaration";
|
|
434
436
|
}
|
|
435
437
|
function isExportNamedDeclaration(node) {
|
|
@@ -462,7 +464,7 @@ function isFunction(node) {
|
|
|
462
464
|
function isTsQualifiedName(node) {
|
|
463
465
|
return node.type === "TSQualifiedName";
|
|
464
466
|
}
|
|
465
|
-
function isNumericLiteral
|
|
467
|
+
function isNumericLiteral(node) {
|
|
466
468
|
return node.type === "Literal" && isNumberRaw(node.value);
|
|
467
469
|
}
|
|
468
470
|
function isNewExpression(node) {
|
|
@@ -498,9 +500,15 @@ function isThisExpression(node) {
|
|
|
498
500
|
function isStaticRequire(node) {
|
|
499
501
|
if (!isCallExpression$1(node) || node.optional) return false;
|
|
500
502
|
const { callee } = node;
|
|
501
|
-
if (!isIdentifierName
|
|
503
|
+
if (!isIdentifierName(callee) || callee.name !== "require" || node.arguments.length !== 1) return false;
|
|
502
504
|
const [argument] = node.arguments;
|
|
503
|
-
return argument !== void 0 && isStringLiteral
|
|
505
|
+
return argument !== void 0 && isStringLiteral(argument);
|
|
506
|
+
}
|
|
507
|
+
function isBindingIdentifier(node) {
|
|
508
|
+
return node.type === "Identifier";
|
|
509
|
+
}
|
|
510
|
+
function isExpressionNode(node) {
|
|
511
|
+
return node.type !== "PrivateIdentifier";
|
|
504
512
|
}
|
|
505
513
|
//#endregion
|
|
506
514
|
//#region src/rules/ban-react-fc.ts
|
|
@@ -519,7 +527,7 @@ function getTypeAnnotationFromId(node) {
|
|
|
519
527
|
return isTsTypeAnnotation(typeAnnotation) ? typeAnnotation : void 0;
|
|
520
528
|
}
|
|
521
529
|
const banReactFc = defineRule({
|
|
522
|
-
|
|
530
|
+
createOnce(context) {
|
|
523
531
|
return { VariableDeclarator(node) {
|
|
524
532
|
const typeAnnotation = getTypeAnnotationFromId(node);
|
|
525
533
|
if (typeAnnotation === void 0) return;
|
|
@@ -548,7 +556,6 @@ function normalizeBannedTypes(rawOptions) {
|
|
|
548
556
|
const bannedTypes = new Map(DEFAULT_BANNED_TYPES);
|
|
549
557
|
if (!(isRecord(rawOptions) && "bannedTypes" in rawOptions)) return bannedTypes;
|
|
550
558
|
const { bannedTypes: configuredBannedTypes } = rawOptions;
|
|
551
|
-
if (configuredBannedTypes === void 0) return bannedTypes;
|
|
552
559
|
if (isStringArray$1(configuredBannedTypes)) {
|
|
553
560
|
for (const typeName of configuredBannedTypes) bannedTypes.set(typeName.toLowerCase(), {
|
|
554
561
|
originalName: typeName,
|
|
@@ -1427,7 +1434,7 @@ const enforceIanitorCheckType = defineRule({
|
|
|
1427
1434
|
const { init, id } = node;
|
|
1428
1435
|
if (init?.type !== "CallExpression" || !isIanitorValidator(init)) return;
|
|
1429
1436
|
hasIanitorReference = true;
|
|
1430
|
-
if (id.type === "Identifier" && id.typeAnnotation !== void 0) return;
|
|
1437
|
+
if (id.type === "Identifier" && id.typeAnnotation !== void 0 && id.typeAnnotation !== null) return;
|
|
1431
1438
|
const complexity = calculateIanitorComplexity(init);
|
|
1432
1439
|
if (complexity < config.baseThreshold) return;
|
|
1433
1440
|
variableDeclaratorsToCheck.set(node, { complexity });
|
|
@@ -1881,7 +1888,7 @@ function getBindingTypeAnnotation(bindingName) {
|
|
|
1881
1888
|
}
|
|
1882
1889
|
function hasContextualArrayAnnotation(node, sourceCode) {
|
|
1883
1890
|
const { parent } = node;
|
|
1884
|
-
if (isVariableDeclarator
|
|
1891
|
+
if (isVariableDeclarator(parent) && parent.init === node) {
|
|
1885
1892
|
const typeAnnotation = getBindingTypeAnnotation(parent.id);
|
|
1886
1893
|
if (typeAnnotation === void 0) return false;
|
|
1887
1894
|
return extractElementTypeFromArrayAnnotation(typeAnnotation.typeAnnotation, sourceCode) !== void 0;
|
|
@@ -2050,7 +2057,7 @@ function reportLengthArrayConstructor(context, node, options, lengthExpressionTe
|
|
|
2050
2057
|
}
|
|
2051
2058
|
function getPushCollapseCandidate(sourceCode, statements, index) {
|
|
2052
2059
|
const statement = statements[index];
|
|
2053
|
-
if (statement === void 0 || !isVariableDeclaration
|
|
2060
|
+
if (statement === void 0 || !isVariableDeclaration(statement)) return void 0;
|
|
2054
2061
|
if (statement.kind !== "const" && statement.kind !== "let") return void 0;
|
|
2055
2062
|
if (statement.declarations.length !== 1) return void 0;
|
|
2056
2063
|
const [declarator] = statement.declarations;
|
|
@@ -2199,9 +2206,6 @@ const VISITOR_KEYS_TO_SKIP = new Set([
|
|
|
2199
2206
|
function isIdentifierReference$1(node) {
|
|
2200
2207
|
return node.type === "Identifier";
|
|
2201
2208
|
}
|
|
2202
|
-
function isBindingIdentifier$1(node) {
|
|
2203
|
-
return node.type === "Identifier";
|
|
2204
|
-
}
|
|
2205
2209
|
function isNode(value) {
|
|
2206
2210
|
return "type" in value && typeof value.type === "string";
|
|
2207
2211
|
}
|
|
@@ -2237,10 +2241,10 @@ function getArrayIndexAssignment(statement, arrayIdentifierName, expectedIndex)
|
|
|
2237
2241
|
const { expression } = statement;
|
|
2238
2242
|
if (!isAssignmentExpression(expression) || expression.operator !== "=") return void 0;
|
|
2239
2243
|
const { left } = expression;
|
|
2240
|
-
if (!isMemberExpression(left)
|
|
2244
|
+
if (!(isMemberExpression(left) && left.computed)) return void 0;
|
|
2241
2245
|
const { object, property } = left;
|
|
2242
2246
|
if (!isIdentifierReference$1(object) || object.name !== arrayIdentifierName) return void 0;
|
|
2243
|
-
if (!isNumericLiteral
|
|
2247
|
+
if (!isNumericLiteral(property) || property.value !== expectedIndex) return void 0;
|
|
2244
2248
|
return {
|
|
2245
2249
|
expression,
|
|
2246
2250
|
statement
|
|
@@ -2248,13 +2252,13 @@ function getArrayIndexAssignment(statement, arrayIdentifierName, expectedIndex)
|
|
|
2248
2252
|
}
|
|
2249
2253
|
function getCandidate(sourceCode, statements, index) {
|
|
2250
2254
|
const declaration = statements[index];
|
|
2251
|
-
if (declaration === void 0 || !isVariableDeclaration
|
|
2255
|
+
if (declaration === void 0 || !isVariableDeclaration(declaration) || declaration.declarations.length !== 1) return;
|
|
2252
2256
|
const [declarator] = declaration.declarations;
|
|
2253
2257
|
/* v8 ignore next -- guarded by declarations.length === 1; undefined is a parser invariant. @preserve */
|
|
2254
|
-
if (declarator === void 0 || !isVariableDeclarator
|
|
2258
|
+
if (declarator === void 0 || !isVariableDeclarator(declarator) || declarator.init === null) return;
|
|
2255
2259
|
const { init } = declarator;
|
|
2256
2260
|
if (!isNewExpression(init) || init.arguments.length > 0 || !isGlobalArrayConstructor(sourceCode, init)) return;
|
|
2257
|
-
if (!isBindingIdentifier
|
|
2261
|
+
if (!isBindingIdentifier(declarator.id)) return void 0;
|
|
2258
2262
|
const arrayIdentifierName = declarator.id.name;
|
|
2259
2263
|
const foundAssignments = new Array();
|
|
2260
2264
|
let scanIndex = index + 1;
|
|
@@ -2373,9 +2377,6 @@ function isAllowAutofixOption(value) {
|
|
|
2373
2377
|
}
|
|
2374
2378
|
//#endregion
|
|
2375
2379
|
//#region src/rules/no-array-size-assignment.ts
|
|
2376
|
-
function isExpressionNode$1(node) {
|
|
2377
|
-
return node.type !== "PrivateIdentifier";
|
|
2378
|
-
}
|
|
2379
2380
|
function areEquivalentTargets(left, right, sourceCode) {
|
|
2380
2381
|
if (left.type !== right.type) return false;
|
|
2381
2382
|
switch (left.type) {
|
|
@@ -2394,7 +2395,7 @@ function areEquivalentMembers(left, right, sourceCode) {
|
|
|
2394
2395
|
return left.computed ? areEquivalentComputedProperties(left.property, right.property, sourceCode) : areEquivalentStaticProperties(left.property, right.property);
|
|
2395
2396
|
}
|
|
2396
2397
|
function areEquivalentComputedProperties(left, right, sourceCode) {
|
|
2397
|
-
return isExpressionNode
|
|
2398
|
+
return isExpressionNode(left) && isExpressionNode(right) && areEquivalentTargets(left, right, sourceCode);
|
|
2398
2399
|
}
|
|
2399
2400
|
function areEquivalentStaticProperties(left, right) {
|
|
2400
2401
|
if (left.type === "PrivateIdentifier" || right.type === "PrivateIdentifier") return left.type === "PrivateIdentifier" && right.type === "PrivateIdentifier" && left.name === right.name;
|
|
@@ -2409,7 +2410,7 @@ function isSafeMemberAccess(node, allowLiteralRoot) {
|
|
|
2409
2410
|
if (node.optional || !isSafeMemberAccess(node.object, false)) return false;
|
|
2410
2411
|
if (node.computed)
|
|
2411
2412
|
/* v8 ignore next -- @preserve computed member properties are expressions in parser output. */
|
|
2412
|
-
return isExpressionNode
|
|
2413
|
+
return isExpressionNode(node.property) ? isSafeMemberAccess(node.property, true) : false;
|
|
2413
2414
|
return node.property.type === "Identifier" || node.property.type === "PrivateIdentifier";
|
|
2414
2415
|
default: return false;
|
|
2415
2416
|
}
|
|
@@ -2440,7 +2441,7 @@ function getAppendTarget(node, sourceCode, environment) {
|
|
|
2440
2441
|
const noArraySizeAssignment = defineRule({
|
|
2441
2442
|
create(context) {
|
|
2442
2443
|
const [options] = context.options;
|
|
2443
|
-
const allowAutofix = isAllowAutofixOption(options) && options
|
|
2444
|
+
const allowAutofix = isAllowAutofixOption(options) && options.allowAutofix;
|
|
2444
2445
|
const environment = options?.environment === "standard" ? "standard" : "roblox-ts";
|
|
2445
2446
|
const { sourceCode } = context;
|
|
2446
2447
|
return { AssignmentExpression(node) {
|
|
@@ -2595,7 +2596,8 @@ function isPromiseChainCall(node) {
|
|
|
2595
2596
|
return PROMISE_CHAIN_METHODS.has(node.callee.property.name);
|
|
2596
2597
|
}
|
|
2597
2598
|
function isAsyncIife({ callee }) {
|
|
2598
|
-
|
|
2599
|
+
const unwrapped = unwrapExpression(callee);
|
|
2600
|
+
return (unwrapped.type === "ArrowFunctionExpression" || unwrapped.type === "FunctionExpression") && unwrapped.async;
|
|
2599
2601
|
}
|
|
2600
2602
|
function getThisAsyncMethodName({ callee }, asyncMethods) {
|
|
2601
2603
|
if (callee.type !== "MemberExpression" || callee.object.type !== "ThisExpression" || callee.property.type !== "Identifier") return;
|
|
@@ -2613,6 +2615,7 @@ function getLocalVariableAssignment(node) {
|
|
|
2613
2615
|
}
|
|
2614
2616
|
function isNonIifeFunction(node) {
|
|
2615
2617
|
if (node.type !== "ArrowFunctionExpression" && node.type !== "FunctionExpression") return false;
|
|
2618
|
+
if (node.parent.type === "ParenthesizedExpression" && node.parent.parent.type === "CallExpression" && node.parent.parent.callee === node.parent) return false;
|
|
2616
2619
|
return node.parent.type !== "CallExpression" || node.parent.callee !== node;
|
|
2617
2620
|
}
|
|
2618
2621
|
function isInsideSkippedFunction(node, constructorBody) {
|
|
@@ -2740,9 +2743,6 @@ const noCascadingSetState = defineRule({
|
|
|
2740
2743
|
});
|
|
2741
2744
|
//#endregion
|
|
2742
2745
|
//#region src/rules/no-color3-constructor.ts
|
|
2743
|
-
function isNumericLiteral(node) {
|
|
2744
|
-
return node.type === "Literal" && isNumberRaw(node.value);
|
|
2745
|
-
}
|
|
2746
2746
|
function mapComponentToRgbRange(value) {
|
|
2747
2747
|
return Math.round(value > 1 ? value : value * 255);
|
|
2748
2748
|
}
|
|
@@ -3645,6 +3645,7 @@ function unwrapNode(node) {
|
|
|
3645
3645
|
/* v8 ignore next -- @preserve wrapper variants are parser-shape defensive cases. */
|
|
3646
3646
|
switch (node.type) {
|
|
3647
3647
|
case "ChainExpression":
|
|
3648
|
+
case "ParenthesizedExpression":
|
|
3648
3649
|
case "TSAsExpression":
|
|
3649
3650
|
case "TSInstantiationExpression":
|
|
3650
3651
|
case "TSNonNullExpression":
|
|
@@ -4569,7 +4570,7 @@ function isStandaloneUpdateExpression(node) {
|
|
|
4569
4570
|
const noIncrementDecrement = defineRule({
|
|
4570
4571
|
create(context) {
|
|
4571
4572
|
const [options] = context.options;
|
|
4572
|
-
const allowAutofix = isAllowAutofixOption(options) && options.allowAutofix
|
|
4573
|
+
const allowAutofix = isAllowAutofixOption(options) && options.allowAutofix;
|
|
4573
4574
|
const { sourceCode } = context;
|
|
4574
4575
|
return { UpdateExpression(node) {
|
|
4575
4576
|
if (!isStandaloneUpdateExpression(node)) return;
|
|
@@ -4705,7 +4706,6 @@ function traverseForThis(currentNode, visited) {
|
|
|
4705
4706
|
return false;
|
|
4706
4707
|
}
|
|
4707
4708
|
function childUsesThis(childValue, visited) {
|
|
4708
|
-
if (childValue === void 0) return false;
|
|
4709
4709
|
if (Array.isArray(childValue)) {
|
|
4710
4710
|
for (const item of childValue) if (isNode$1(item) && traverseForThis(item, visited)) return true;
|
|
4711
4711
|
return false;
|
|
@@ -4833,7 +4833,7 @@ const VALID_EXPRESSIONS = new Set([
|
|
|
4833
4833
|
function isExpression$1(node) {
|
|
4834
4834
|
return VALID_EXPRESSIONS.has(node.type);
|
|
4835
4835
|
}
|
|
4836
|
-
function isModuleLevelScope
|
|
4836
|
+
function isModuleLevelScope(scope) {
|
|
4837
4837
|
return scope.type === "module" || scope.type === "global";
|
|
4838
4838
|
}
|
|
4839
4839
|
function isImportBinding(scopeVariable) {
|
|
@@ -4854,7 +4854,7 @@ function getConstInitializer(definition) {
|
|
|
4854
4854
|
}
|
|
4855
4855
|
function getModuleConstInitializer(sourceCode, identifier) {
|
|
4856
4856
|
const variable = getVariableByName(sourceCode.getScope(identifier), identifier.name);
|
|
4857
|
-
if (variable === void 0 || !isModuleLevelScope
|
|
4857
|
+
if (variable === void 0 || !isModuleLevelScope(variable.scope)) return void 0;
|
|
4858
4858
|
for (const definition of variable.defs) {
|
|
4859
4859
|
const initializer = getConstInitializer(definition);
|
|
4860
4860
|
if (initializer !== void 0) return initializer;
|
|
@@ -4924,7 +4924,7 @@ function isStaticExpression(sourceCode, expression, seen, options) {
|
|
|
4924
4924
|
function isStaticIdentifier(sourceCode, identifier, seen, options) {
|
|
4925
4925
|
const variable = getVariableByName(sourceCode.getScope(identifier), identifier.name);
|
|
4926
4926
|
if (variable === void 0) return options.staticGlobalFactories.has(identifier.name);
|
|
4927
|
-
if (!isModuleLevelScope
|
|
4927
|
+
if (!isModuleLevelScope(variable.scope)) return false;
|
|
4928
4928
|
if (isImportBinding(variable)) return true;
|
|
4929
4929
|
for (const definition of variable.defs) {
|
|
4930
4930
|
const initializer = getConstInitializer(definition);
|
|
@@ -4964,9 +4964,6 @@ function getVariableInitializer(definition) {
|
|
|
4964
4964
|
if (definition.type !== "Variable" || definition.node.type !== "VariableDeclarator") return void 0;
|
|
4965
4965
|
return definition.node.init ?? void 0;
|
|
4966
4966
|
}
|
|
4967
|
-
function isModuleLevelScope(scope) {
|
|
4968
|
-
return scope.type === "module" || scope.type === "global";
|
|
4969
|
-
}
|
|
4970
4967
|
function getRootIdentifier$1(expression) {
|
|
4971
4968
|
let currentExpression = unwrapExpression(expression);
|
|
4972
4969
|
while (currentExpression.type === "MemberExpression") {
|
|
@@ -5028,6 +5025,7 @@ const noNativePropertiesSpread = defineRule({
|
|
|
5028
5025
|
const { value } = node;
|
|
5029
5026
|
if (value?.type !== "JSXExpressionContainer") return;
|
|
5030
5027
|
const { expression } = value;
|
|
5028
|
+
/* v8 ignore next -- @preserve Oxc only produces JSXEmptyExpression here for rejected parse-error cases. */
|
|
5031
5029
|
if (expression.type === "JSXEmptyExpression") return;
|
|
5032
5030
|
const objectExpression = resolveObjectExpression(sourceCode, expression, /* @__PURE__ */ new Set());
|
|
5033
5031
|
if (objectExpression === void 0) return;
|
|
@@ -5541,6 +5539,10 @@ function getFunctionComponentName(node) {
|
|
|
5541
5539
|
if (parent.type === "VariableDeclarator" && parent.id.type === "Identifier") return parent.id.name;
|
|
5542
5540
|
}
|
|
5543
5541
|
}
|
|
5542
|
+
function getArrowExpressionBody(node) {
|
|
5543
|
+
if (node.body.type === "BlockStatement") return void 0;
|
|
5544
|
+
return unwrapExpression(node.body);
|
|
5545
|
+
}
|
|
5544
5546
|
function getImportSourceFromVariable(variable) {
|
|
5545
5547
|
for (const definition of variable.defs) {
|
|
5546
5548
|
/* v8 ignore start -- @preserve imported component variables only carry import binding definitions here. */
|
|
@@ -5597,8 +5599,9 @@ const noRedundantAspectRatioConstraint = defineRule({
|
|
|
5597
5599
|
return {
|
|
5598
5600
|
ArrowFunctionExpression(node) {
|
|
5599
5601
|
const name = getFunctionComponentName(node);
|
|
5600
|
-
|
|
5601
|
-
if (
|
|
5602
|
+
const body = getArrowExpressionBody(node);
|
|
5603
|
+
if (name === void 0 || body === void 0 || body.type !== "JSXElement" && body.type !== "JSXFragment") return;
|
|
5604
|
+
if (!hasAspectRatioConstraintInSubtree(body)) return;
|
|
5602
5605
|
protectedComponents.add(name);
|
|
5603
5606
|
},
|
|
5604
5607
|
FunctionDeclaration(node) {
|
|
@@ -5702,7 +5705,15 @@ function isPropertyValueReference(node) {
|
|
|
5702
5705
|
/* v8 ignore next -- @preserve scope reference identifiers always have parents in parser-produced ASTs. */
|
|
5703
5706
|
const parent = ascendPastWrappers$1(node.parent ?? void 0);
|
|
5704
5707
|
/* v8 ignore next -- @preserve scope references always have parents in parser-produced ASTs. */
|
|
5705
|
-
return parent?.type === "Property" && parent.value === node;
|
|
5708
|
+
return parent?.type === "Property" && unwrapPropertyValue(parent.value) === node;
|
|
5709
|
+
}
|
|
5710
|
+
function unwrapPropertyValue(node) {
|
|
5711
|
+
let current = node;
|
|
5712
|
+
while (isWrapperParent(current)) current = current.expression;
|
|
5713
|
+
return current;
|
|
5714
|
+
}
|
|
5715
|
+
function isWrapperParent(node) {
|
|
5716
|
+
return WRAPPER_PARENT_TYPES$1.has(node.type);
|
|
5706
5717
|
}
|
|
5707
5718
|
function getDeclaredFunctionVariable(sourceCode, node) {
|
|
5708
5719
|
if (node.type === "FunctionDeclaration") {
|
|
@@ -5792,10 +5803,118 @@ const noRenderHelperFunctions = defineRule({
|
|
|
5792
5803
|
}
|
|
5793
5804
|
});
|
|
5794
5805
|
//#endregion
|
|
5806
|
+
//#region src/rules/no-restricted-property-assignment.ts
|
|
5807
|
+
function isRestriction(value) {
|
|
5808
|
+
if (!isRecord(value)) return false;
|
|
5809
|
+
if (!isStringRaw(value.object)) return false;
|
|
5810
|
+
if (!Array.isArray(value.properties)) return false;
|
|
5811
|
+
if (!value.properties.every((property) => isStringRaw(property))) return false;
|
|
5812
|
+
return value.message === void 0 || isStringRaw(value.message);
|
|
5813
|
+
}
|
|
5814
|
+
function isRuleOptions(value) {
|
|
5815
|
+
if (!isRecord(value)) return false;
|
|
5816
|
+
if (!Array.isArray(value.restrictions)) return false;
|
|
5817
|
+
if (!value.restrictions.every(isRestriction)) return false;
|
|
5818
|
+
return value.checkComputed === void 0 || typeof value.checkComputed === "boolean";
|
|
5819
|
+
}
|
|
5820
|
+
function isMemberExpressionTarget(node) {
|
|
5821
|
+
return node.type === "MemberExpression";
|
|
5822
|
+
}
|
|
5823
|
+
const noRestrictedPropertyAssignment = defineRule({
|
|
5824
|
+
createOnce(context) {
|
|
5825
|
+
let restrictions = [];
|
|
5826
|
+
let checkComputed = true;
|
|
5827
|
+
function reportIfRestricted(node, reportNode) {
|
|
5828
|
+
if (!isMemberExpressionTarget(node)) return;
|
|
5829
|
+
if (node.computed && !checkComputed) return;
|
|
5830
|
+
if (node.object.type !== "Identifier") return;
|
|
5831
|
+
const property = getMemberPropertyName(node);
|
|
5832
|
+
if (property === void 0) return;
|
|
5833
|
+
for (const restriction of restrictions) {
|
|
5834
|
+
if (restriction.object !== node.object.name) continue;
|
|
5835
|
+
if (restriction.properties.includes("*") || restriction.properties.includes(property)) {
|
|
5836
|
+
if (restriction.message === void 0) context.report({
|
|
5837
|
+
data: {
|
|
5838
|
+
object: node.object.name,
|
|
5839
|
+
property
|
|
5840
|
+
},
|
|
5841
|
+
messageId: "restricted",
|
|
5842
|
+
node: reportNode
|
|
5843
|
+
});
|
|
5844
|
+
else context.report({
|
|
5845
|
+
data: { message: restriction.message },
|
|
5846
|
+
messageId: "restrictedCustom",
|
|
5847
|
+
node: reportNode
|
|
5848
|
+
});
|
|
5849
|
+
return;
|
|
5850
|
+
}
|
|
5851
|
+
}
|
|
5852
|
+
}
|
|
5853
|
+
return {
|
|
5854
|
+
AssignmentExpression(node) {
|
|
5855
|
+
reportIfRestricted(node.left, node);
|
|
5856
|
+
},
|
|
5857
|
+
before() {
|
|
5858
|
+
const [options] = context.options;
|
|
5859
|
+
if (!isRuleOptions(options)) {
|
|
5860
|
+
restrictions = [];
|
|
5861
|
+
checkComputed = true;
|
|
5862
|
+
return;
|
|
5863
|
+
}
|
|
5864
|
+
const { checkComputed: nextCheckComputed, restrictions: nextRestrictions } = options;
|
|
5865
|
+
restrictions = nextRestrictions;
|
|
5866
|
+
checkComputed = nextCheckComputed ?? true;
|
|
5867
|
+
},
|
|
5868
|
+
UpdateExpression(node) {
|
|
5869
|
+
reportIfRestricted(node.argument, node);
|
|
5870
|
+
}
|
|
5871
|
+
};
|
|
5872
|
+
},
|
|
5873
|
+
meta: {
|
|
5874
|
+
docs: {
|
|
5875
|
+
description: "Disallow assignment to restricted object properties.",
|
|
5876
|
+
recommended: true
|
|
5877
|
+
},
|
|
5878
|
+
messages: {
|
|
5879
|
+
restricted: "Assignment to '{{object}}.{{property}}' is not permitted.",
|
|
5880
|
+
restrictedCustom: "{{message}}"
|
|
5881
|
+
},
|
|
5882
|
+
schema: [{
|
|
5883
|
+
additionalProperties: false,
|
|
5884
|
+
properties: {
|
|
5885
|
+
checkComputed: {
|
|
5886
|
+
default: true,
|
|
5887
|
+
type: "boolean"
|
|
5888
|
+
},
|
|
5889
|
+
restrictions: {
|
|
5890
|
+
items: {
|
|
5891
|
+
additionalProperties: false,
|
|
5892
|
+
properties: {
|
|
5893
|
+
message: { type: "string" },
|
|
5894
|
+
object: { type: "string" },
|
|
5895
|
+
properties: {
|
|
5896
|
+
items: { type: "string" },
|
|
5897
|
+
minItems: 1,
|
|
5898
|
+
type: "array"
|
|
5899
|
+
}
|
|
5900
|
+
},
|
|
5901
|
+
required: ["object", "properties"],
|
|
5902
|
+
type: "object"
|
|
5903
|
+
},
|
|
5904
|
+
type: "array"
|
|
5905
|
+
}
|
|
5906
|
+
},
|
|
5907
|
+
required: ["restrictions"],
|
|
5908
|
+
type: "object"
|
|
5909
|
+
}],
|
|
5910
|
+
type: "problem"
|
|
5911
|
+
}
|
|
5912
|
+
});
|
|
5913
|
+
//#endregion
|
|
5795
5914
|
//#region src/rules/no-spec-file-extension.ts
|
|
5796
5915
|
const SPEC_EXTENSION_PATTERN = /\.spec\.(?:ts|tsx)$/u;
|
|
5797
5916
|
const noSpecFileExtension = defineRule({
|
|
5798
|
-
|
|
5917
|
+
createOnce(context) {
|
|
5799
5918
|
return { Program(node) {
|
|
5800
5919
|
const { filename } = context;
|
|
5801
5920
|
if (!(filename && SPEC_EXTENSION_PATTERN.test(filename))) return;
|
|
@@ -5861,7 +5980,7 @@ function isStringElementName(node) {
|
|
|
5861
5980
|
}
|
|
5862
5981
|
function isStaticComponentVariable(variable, name) {
|
|
5863
5982
|
if (isImportBinding(variable)) return isComponentName(name) || name === REACT_FRAGMENT;
|
|
5864
|
-
if (!isModuleLevelScope
|
|
5983
|
+
if (!isModuleLevelScope(variable.scope)) return false;
|
|
5865
5984
|
if (!isComponentName(name) && name !== REACT_FRAGMENT) return false;
|
|
5866
5985
|
for (const definition of variable.defs) {
|
|
5867
5986
|
if (definition.type === "FunctionName" || definition.type === "ClassName") return true;
|
|
@@ -6000,7 +6119,7 @@ function isPromiseDelayAwaitCall(node) {
|
|
|
6000
6119
|
return getMemberPropertyName(delayCallee) === "delay";
|
|
6001
6120
|
}
|
|
6002
6121
|
const noTaskWait = defineRule({
|
|
6003
|
-
|
|
6122
|
+
createOnce(context) {
|
|
6004
6123
|
return { CallExpression(node) {
|
|
6005
6124
|
if (isPromiseDelayAwaitCall(node)) {
|
|
6006
6125
|
context.report({
|
|
@@ -6032,7 +6151,7 @@ const noTaskWait = defineRule({
|
|
|
6032
6151
|
//#endregion
|
|
6033
6152
|
//#region src/rules/no-underscore-react-properties.ts
|
|
6034
6153
|
const noUnderscoreReactProperties = defineRule({
|
|
6035
|
-
|
|
6154
|
+
createOnce(context) {
|
|
6036
6155
|
return { JSXAttribute(node) {
|
|
6037
6156
|
if (node.name.type !== "JSXIdentifier" || !node.name.name.startsWith("_")) return;
|
|
6038
6157
|
context.report({
|
|
@@ -6256,20 +6375,11 @@ function collectAllScopes(root) {
|
|
|
6256
6375
|
const current = stack.pop();
|
|
6257
6376
|
/* v8 ignore next -- @preserve non-empty traversal stack always yields a scope from pop. */
|
|
6258
6377
|
if (current === void 0) break;
|
|
6259
|
-
scopes[size++] = current;
|
|
6378
|
+
if (current.type !== "global") scopes[size++] = current;
|
|
6260
6379
|
for (const childScope of current.childScopes) stack.push(childScope);
|
|
6261
6380
|
}
|
|
6262
6381
|
return scopes;
|
|
6263
6382
|
}
|
|
6264
|
-
function isBindingIdentifier(node) {
|
|
6265
|
-
return node.type === "Identifier";
|
|
6266
|
-
}
|
|
6267
|
-
function isVariableDeclarator(node) {
|
|
6268
|
-
return node.type === "VariableDeclarator";
|
|
6269
|
-
}
|
|
6270
|
-
function isVariableDeclaration(node) {
|
|
6271
|
-
return node.type === "VariableDeclaration";
|
|
6272
|
-
}
|
|
6273
6383
|
function isFunctionLikeInitializer(node) {
|
|
6274
6384
|
return isCallbackFunction(node) || node.type === "ClassExpression";
|
|
6275
6385
|
}
|
|
@@ -6278,7 +6388,8 @@ function isObjectLikeInitializer(initializer, patterns, sourceCode) {
|
|
|
6278
6388
|
if (initializer.type === "JSXElement" || initializer.type === "JSXFragment") return true;
|
|
6279
6389
|
if (initializer.type !== "CallExpression" && initializer.type !== "NewExpression") return false;
|
|
6280
6390
|
const candidateText = sourceCode.getText(initializer.callee);
|
|
6281
|
-
|
|
6391
|
+
for (const pattern of patterns) if (pattern.test(candidateText)) return true;
|
|
6392
|
+
return false;
|
|
6282
6393
|
}
|
|
6283
6394
|
function isStatementContainer(node) {
|
|
6284
6395
|
return node.type === "Program" || node.type === "BlockStatement";
|
|
@@ -6365,6 +6476,11 @@ function isAutoInlineSafeInitializer(sourceCode, node) {
|
|
|
6365
6476
|
if (node.type === "Literal") return true;
|
|
6366
6477
|
return isStaticExpression(sourceCode, node, /* @__PURE__ */ new Set(), STATIC_OPTIONS$1) && hasOnlyRelocatableCalls(node, STATIC_OPTIONS$1.staticGlobalFactories);
|
|
6367
6478
|
}
|
|
6479
|
+
function getInlineInitializerText(sourceCode, initializer) {
|
|
6480
|
+
let current = initializer;
|
|
6481
|
+
while (current.type === "ParenthesizedExpression") current = current.expression;
|
|
6482
|
+
return sourceCode.getText(current);
|
|
6483
|
+
}
|
|
6368
6484
|
function areAdjacentStatements(first, second) {
|
|
6369
6485
|
const { parent } = first;
|
|
6370
6486
|
/* v8 ignore next -- @preserve VariableDeclaration parents visited by this rule are Program or BlockStatement containers. */
|
|
@@ -6471,7 +6587,6 @@ const noUselessConstants = defineRule({
|
|
|
6471
6587
|
};
|
|
6472
6588
|
}
|
|
6473
6589
|
function inspectScope(scope) {
|
|
6474
|
-
if (scope.type === "global") return;
|
|
6475
6590
|
const fixableConstants = new Array();
|
|
6476
6591
|
for (const scopeVariable of scope.variables) {
|
|
6477
6592
|
const candidate = getUselessConstantCandidate(scope, scopeVariable);
|
|
@@ -6489,7 +6604,7 @@ const noUselessConstants = defineRule({
|
|
|
6489
6604
|
}
|
|
6490
6605
|
fixableConstants.push({
|
|
6491
6606
|
declarationNode: candidate.declarationNode,
|
|
6492
|
-
initializerText: sourceCode
|
|
6607
|
+
initializerText: getInlineInitializerText(sourceCode, candidate.initializer),
|
|
6493
6608
|
name: candidate.name,
|
|
6494
6609
|
referenceIdentifier: candidate.referenceIdentifier,
|
|
6495
6610
|
reportNode: candidate.reportNode
|
|
@@ -18311,9 +18426,6 @@ function isIdentifierNamed(node, name) {
|
|
|
18311
18426
|
function isBooleanLiteral(node) {
|
|
18312
18427
|
return node.type === "Literal" && typeof node.value === "boolean";
|
|
18313
18428
|
}
|
|
18314
|
-
function isStringLiteral(node) {
|
|
18315
|
-
return node.type === "Literal" && isStringRaw(node.value);
|
|
18316
|
-
}
|
|
18317
18429
|
function getIntrinsicClassName(node) {
|
|
18318
18430
|
if (node.type !== "JSXIdentifier") return void 0;
|
|
18319
18431
|
const className = intrinsicClassNamesByTagName.get(node.name.toLowerCase());
|
|
@@ -18328,6 +18440,7 @@ function getJsxAttributeExpression(node) {
|
|
|
18328
18440
|
const { value } = node;
|
|
18329
18441
|
if (value === null) return void 0;
|
|
18330
18442
|
if (value.type === "Literal") return value;
|
|
18443
|
+
/* v8 ignore next -- @preserve Oxc only produces JSXEmptyExpression here for rejected parse-error cases. */
|
|
18331
18444
|
if (value.type !== "JSXExpressionContainer" || value.expression.type === "JSXEmptyExpression") return void 0;
|
|
18332
18445
|
return value.expression;
|
|
18333
18446
|
}
|
|
@@ -18426,7 +18539,7 @@ function matchesTuple(expected, actual) {
|
|
|
18426
18539
|
return true;
|
|
18427
18540
|
}
|
|
18428
18541
|
function extractNumberValue(node) {
|
|
18429
|
-
if (isNumericLiteral
|
|
18542
|
+
if (isNumericLiteral(node)) return node.value;
|
|
18430
18543
|
if (isMathHuge(node)) return Number.POSITIVE_INFINITY;
|
|
18431
18544
|
if (node.type !== "UnaryExpression") return void 0;
|
|
18432
18545
|
if (node.operator !== "+" && node.operator !== "-") return void 0;
|
|
@@ -18469,13 +18582,16 @@ function extractVector2Value(node) {
|
|
|
18469
18582
|
}
|
|
18470
18583
|
if (node.type !== "NewExpression" || !isIdentifierNamed(node.callee, "Vector2")) return void 0;
|
|
18471
18584
|
if (node.arguments.length === 0) return [0, 0];
|
|
18472
|
-
|
|
18585
|
+
return extractNumberPair(node.arguments);
|
|
18586
|
+
}
|
|
18587
|
+
function extractNumberPair(argumentsList) {
|
|
18588
|
+
const components = extractPair(argumentsList);
|
|
18473
18589
|
if (components === void 0) return void 0;
|
|
18474
|
-
const [
|
|
18475
|
-
const
|
|
18476
|
-
const
|
|
18477
|
-
if (
|
|
18478
|
-
return [
|
|
18590
|
+
const [firstNode, secondNode] = components;
|
|
18591
|
+
const first = extractNumberValue(firstNode);
|
|
18592
|
+
const second = extractNumberValue(secondNode);
|
|
18593
|
+
if (first === void 0 || second === void 0) return void 0;
|
|
18594
|
+
return [first, second];
|
|
18479
18595
|
}
|
|
18480
18596
|
function extractNumberTriple(argumentsList) {
|
|
18481
18597
|
const components = extractTriple(argumentsList);
|
|
@@ -18512,23 +18628,30 @@ function extractVector3Value(node) {
|
|
|
18512
18628
|
function extractUDimValue(node) {
|
|
18513
18629
|
if (node.type !== "NewExpression" || !isIdentifierNamed(node.callee, "UDim")) return void 0;
|
|
18514
18630
|
if (node.arguments.length === 0) return [0, 0];
|
|
18515
|
-
|
|
18631
|
+
return extractNumberPair(node.arguments);
|
|
18632
|
+
}
|
|
18633
|
+
function extractNumberQuadruple(argumentsList) {
|
|
18634
|
+
const components = extractQuadruple(argumentsList);
|
|
18516
18635
|
if (components === void 0) return void 0;
|
|
18517
|
-
const [
|
|
18518
|
-
const
|
|
18519
|
-
const
|
|
18520
|
-
|
|
18521
|
-
|
|
18636
|
+
const [firstNode, secondNode, thirdNode, fourthNode] = components;
|
|
18637
|
+
const first = extractNumberValue(firstNode);
|
|
18638
|
+
const second = extractNumberValue(secondNode);
|
|
18639
|
+
const third = extractNumberValue(thirdNode);
|
|
18640
|
+
const fourth = extractNumberValue(fourthNode);
|
|
18641
|
+
if (first === void 0 || second === void 0 || third === void 0 || fourth === void 0) return;
|
|
18642
|
+
return [
|
|
18643
|
+
first,
|
|
18644
|
+
second,
|
|
18645
|
+
third,
|
|
18646
|
+
fourth
|
|
18647
|
+
];
|
|
18522
18648
|
}
|
|
18523
18649
|
function extractUDim2Value(node) {
|
|
18524
18650
|
if (node.type === "CallExpression") {
|
|
18525
18651
|
const path = getMemberPath(node.callee);
|
|
18526
|
-
const components =
|
|
18652
|
+
const components = extractNumberPair(node.arguments);
|
|
18527
18653
|
if (path === void 0 || components === void 0) return void 0;
|
|
18528
|
-
const [
|
|
18529
|
-
const first = extractNumberValue(firstNode);
|
|
18530
|
-
const second = extractNumberValue(secondNode);
|
|
18531
|
-
if (first === void 0 || second === void 0) return void 0;
|
|
18654
|
+
const [first, second] = components;
|
|
18532
18655
|
if (path.length === 2 && path[0] === "UDim2" && path[1] === "fromOffset") return [
|
|
18533
18656
|
0,
|
|
18534
18657
|
first,
|
|
@@ -18550,20 +18673,7 @@ function extractUDim2Value(node) {
|
|
|
18550
18673
|
0,
|
|
18551
18674
|
0
|
|
18552
18675
|
];
|
|
18553
|
-
|
|
18554
|
-
if (components === void 0) return void 0;
|
|
18555
|
-
const [scaleXNode, offsetXNode, scaleYNode, offsetYNode] = components;
|
|
18556
|
-
const scaleX = extractNumberValue(scaleXNode);
|
|
18557
|
-
const offsetX = extractNumberValue(offsetXNode);
|
|
18558
|
-
const scaleY = extractNumberValue(scaleYNode);
|
|
18559
|
-
const offsetY = extractNumberValue(offsetYNode);
|
|
18560
|
-
if (scaleX === void 0 || offsetX === void 0 || scaleY === void 0 || offsetY === void 0) return;
|
|
18561
|
-
return [
|
|
18562
|
-
scaleX,
|
|
18563
|
-
offsetX,
|
|
18564
|
-
scaleY,
|
|
18565
|
-
offsetY
|
|
18566
|
-
];
|
|
18676
|
+
return extractNumberQuadruple(node.arguments);
|
|
18567
18677
|
}
|
|
18568
18678
|
function extractRectValue(node) {
|
|
18569
18679
|
if (node.type !== "NewExpression" || !isIdentifierNamed(node.callee, "Rect")) return void 0;
|
|
@@ -18573,20 +18683,7 @@ function extractRectValue(node) {
|
|
|
18573
18683
|
0,
|
|
18574
18684
|
0
|
|
18575
18685
|
];
|
|
18576
|
-
|
|
18577
|
-
if (components === void 0) return void 0;
|
|
18578
|
-
const [minimumXNode, minimumYNode, maximumXNode, maximumYNode] = components;
|
|
18579
|
-
const minimumX = extractNumberValue(minimumXNode);
|
|
18580
|
-
const minimumY = extractNumberValue(minimumYNode);
|
|
18581
|
-
const maximumX = extractNumberValue(maximumXNode);
|
|
18582
|
-
const maximumY = extractNumberValue(maximumYNode);
|
|
18583
|
-
if (minimumX === void 0 || minimumY === void 0 || maximumX === void 0 || maximumY === void 0) return;
|
|
18584
|
-
return [
|
|
18585
|
-
minimumX,
|
|
18586
|
-
minimumY,
|
|
18587
|
-
maximumX,
|
|
18588
|
-
maximumY
|
|
18589
|
-
];
|
|
18686
|
+
return extractNumberQuadruple(node.arguments);
|
|
18590
18687
|
}
|
|
18591
18688
|
function extractRGBFromComponents(components) {
|
|
18592
18689
|
const [redNode, greenNode, blueNode] = components;
|
|
@@ -18944,10 +19041,22 @@ function normalizeOptions$1(raw) {
|
|
|
18944
19041
|
stateHooks: new Set(isStringArray$1(raw.stateHooks) ? raw.stateHooks : DEFAULT_STATE_HOOKS)
|
|
18945
19042
|
};
|
|
18946
19043
|
}
|
|
19044
|
+
function getNamespacedCallNames(callee) {
|
|
19045
|
+
if (callee.type !== "MemberExpression" || callee.computed || callee.object.type !== "Identifier" || callee.property.type !== "Identifier") return;
|
|
19046
|
+
return {
|
|
19047
|
+
objectName: callee.object.name,
|
|
19048
|
+
propertyName: callee.property.name
|
|
19049
|
+
};
|
|
19050
|
+
}
|
|
19051
|
+
function getNonComputedCalleePropertyName(callee) {
|
|
19052
|
+
if (callee.type !== "MemberExpression" || callee.computed || callee.property.type !== "Identifier") return;
|
|
19053
|
+
return callee.property.name;
|
|
19054
|
+
}
|
|
18947
19055
|
function isHookCall$1(node, hookIdentifiers, reactNamespaces, hookNames) {
|
|
18948
19056
|
const { callee } = node;
|
|
18949
19057
|
if (callee.type === "Identifier") return hookIdentifiers.has(callee.name);
|
|
18950
|
-
|
|
19058
|
+
const memberNames = getNamespacedCallNames(callee);
|
|
19059
|
+
if (memberNames !== void 0) return reactNamespaces.has(memberNames.objectName) && hookNames.has(memberNames.propertyName);
|
|
18951
19060
|
return false;
|
|
18952
19061
|
}
|
|
18953
19062
|
function getFunctionName$1(node) {
|
|
@@ -19269,7 +19378,8 @@ function buildFunctionContext(node, propertyCallbackPrefixes, functionId, isCust
|
|
|
19269
19378
|
function isPropertyCallbackCall(callExpression, functionContext, propertyCallbackPrefixes) {
|
|
19270
19379
|
const { callee } = callExpression;
|
|
19271
19380
|
if (callee.type === "Identifier") return functionContext.propertyCallbackIdentifiers.has(callee.name);
|
|
19272
|
-
|
|
19381
|
+
const memberNames = getNamespacedCallNames(callee);
|
|
19382
|
+
if (memberNames !== void 0) return functionContext.propertyObjectName !== void 0 && memberNames.objectName === functionContext.propertyObjectName && hasPrefix(memberNames.propertyName, propertyCallbackPrefixes);
|
|
19273
19383
|
return false;
|
|
19274
19384
|
}
|
|
19275
19385
|
function hasDependencyIdentifier(callExpression, name) {
|
|
@@ -19319,7 +19429,8 @@ function collectSetterCalls(statements, stateSetterIdentifiers) {
|
|
|
19319
19429
|
function isAllowedPropertyCallbackCall(callExpression, propertyCallbackIdentifiers) {
|
|
19320
19430
|
const { callee } = callExpression;
|
|
19321
19431
|
if (callee.type === "Identifier") return propertyCallbackIdentifiers.has(callee.name);
|
|
19322
|
-
|
|
19432
|
+
const memberNames = getNamespacedCallNames(callee);
|
|
19433
|
+
return memberNames !== void 0 && propertyCallbackIdentifiers.has(memberNames.objectName);
|
|
19323
19434
|
}
|
|
19324
19435
|
function hasNonSetterSideEffect(statements, stateSetterIdentifiers, propertyCallbackIdentifiers) {
|
|
19325
19436
|
for (const statement of statements) {
|
|
@@ -19357,8 +19468,7 @@ function hasOnlyLogCalls(statements) {
|
|
|
19357
19468
|
return hasOnlyNestedStatementsMatching(statements, (statement) => {
|
|
19358
19469
|
const callExpression = getCallExpressionFromStatement(statement);
|
|
19359
19470
|
if (callExpression === void 0) return false;
|
|
19360
|
-
|
|
19361
|
-
return false;
|
|
19471
|
+
return getNamespacedCallNames(callExpression.callee)?.objectName === "console";
|
|
19362
19472
|
});
|
|
19363
19473
|
}
|
|
19364
19474
|
const SUBSCRIBE_METHODS = new Set([
|
|
@@ -19371,8 +19481,8 @@ function hasExternalStorePattern(statements) {
|
|
|
19371
19481
|
return statements.some((statement) => {
|
|
19372
19482
|
const callExpression = getCallExpressionFromStatement(statement);
|
|
19373
19483
|
if (callExpression === void 0) return false;
|
|
19374
|
-
|
|
19375
|
-
return
|
|
19484
|
+
const propertyName = getNonComputedCalleePropertyName(callExpression.callee);
|
|
19485
|
+
return propertyName !== void 0 && SUBSCRIBE_METHODS.has(propertyName);
|
|
19376
19486
|
});
|
|
19377
19487
|
}
|
|
19378
19488
|
function isRefCurrentArgument(argument, referenceIdentifiers) {
|
|
@@ -20080,7 +20190,7 @@ function objectExpressionMatches(sourceCode, expression, predicate) {
|
|
|
20080
20190
|
if (unwrapped.type === "ObjectExpression") return predicate(unwrapped);
|
|
20081
20191
|
if (unwrapped.type !== "Identifier") return false;
|
|
20082
20192
|
const variable = getVariableByName(sourceCode.getScope(unwrapped), unwrapped.name);
|
|
20083
|
-
if (variable === void 0 || !isModuleLevelScope
|
|
20193
|
+
if (variable === void 0 || !isModuleLevelScope(variable.scope) || isImportBinding(variable)) return false;
|
|
20084
20194
|
for (const definition of variable.defs) {
|
|
20085
20195
|
const initializer = getConstInitializer(definition);
|
|
20086
20196
|
if (initializer === void 0) continue;
|
|
@@ -20283,7 +20393,7 @@ const preferClassProperties = defineRule({
|
|
|
20283
20393
|
//#endregion
|
|
20284
20394
|
//#region src/rules/prefer-constant-dispatch.ts
|
|
20285
20395
|
function isModuleScopeConst(variable) {
|
|
20286
|
-
if (!isModuleLevelScope
|
|
20396
|
+
if (!isModuleLevelScope(variable.scope)) return false;
|
|
20287
20397
|
for (const definition of variable.defs) {
|
|
20288
20398
|
if (definition.type !== "Variable") continue;
|
|
20289
20399
|
const declarator = definition.node;
|
|
@@ -20302,7 +20412,7 @@ function resolvesToConstantIdentifier(sourceCode, identifier) {
|
|
|
20302
20412
|
function resolvesToModuleScopeBinding(sourceCode, identifier) {
|
|
20303
20413
|
const variable = getVariableByName(sourceCode.getScope(identifier), identifier.name);
|
|
20304
20414
|
if (variable === void 0) return false;
|
|
20305
|
-
return isImportBinding(variable) || isModuleLevelScope
|
|
20415
|
+
return isImportBinding(variable) || isModuleLevelScope(variable.scope);
|
|
20306
20416
|
}
|
|
20307
20417
|
function isConstantMemberExpression(sourceCode, memberExpression) {
|
|
20308
20418
|
let current = memberExpression;
|
|
@@ -20721,7 +20831,7 @@ function getContextStackReplacement(componentName, chain, sourceCode) {
|
|
|
20721
20831
|
const preferContextStack = defineRule({
|
|
20722
20832
|
create(context) {
|
|
20723
20833
|
const { filename, sourceCode } = context;
|
|
20724
|
-
/* v8 ignore start -- @preserve
|
|
20834
|
+
/* v8 ignore start -- @preserve rule harness/runtime filenames are present; empty filename is a defensive host guard. */
|
|
20725
20835
|
const discoveredContextStack = filename === "" ? { found: false } : discoverLocalComponent(filename, CONTEXT_STACK_COMPONENT);
|
|
20726
20836
|
/* v8 ignore stop -- @preserve */
|
|
20727
20837
|
const contextStackIdentifiers = /* @__PURE__ */ new Set();
|
|
@@ -21018,7 +21128,7 @@ function validateAssertionCall(context, assertionCall, deterministic, hasIndeter
|
|
|
21018
21128
|
return;
|
|
21019
21129
|
}
|
|
21020
21130
|
const [firstArgument] = assertionCall.arguments;
|
|
21021
|
-
if (firstArgument === void 0 || firstArgument.type === "SpreadElement" || !isNumericLiteral
|
|
21131
|
+
if (firstArgument === void 0 || firstArgument.type === "SpreadElement" || !isNumericLiteral(firstArgument)) {
|
|
21022
21132
|
context.report({
|
|
21023
21133
|
messageId: "assertionsRequiresNumberArgument",
|
|
21024
21134
|
node: assertionCall
|
|
@@ -21124,11 +21234,16 @@ function normalizeAdditionalStaticFactories(rawOptions) {
|
|
|
21124
21234
|
return new Set(additionalStaticFactories);
|
|
21125
21235
|
}
|
|
21126
21236
|
function isJavaScriptXmlElementAssignedToModuleConst(context, node) {
|
|
21127
|
-
|
|
21128
|
-
|
|
21129
|
-
|
|
21237
|
+
let current = node;
|
|
21238
|
+
let { parent } = current;
|
|
21239
|
+
while (parent.type === "ParenthesizedExpression") {
|
|
21240
|
+
current = parent;
|
|
21241
|
+
({parent} = current);
|
|
21242
|
+
}
|
|
21243
|
+
if (parent.type !== "VariableDeclarator" || parent.id.type !== "Identifier" || parent.init !== current) return false;
|
|
21244
|
+
const variable = getVariableByName(context.sourceCode.getScope(current), parent.id.name);
|
|
21130
21245
|
/* v8 ignore start -- @preserve module const declarators have a matching scope variable. */
|
|
21131
|
-
return variable === void 0 ? false : isModuleLevelScope
|
|
21246
|
+
return variable === void 0 ? false : isModuleLevelScope(variable.scope);
|
|
21132
21247
|
/* v8 ignore stop -- @preserve */
|
|
21133
21248
|
}
|
|
21134
21249
|
function isStaticAttributeValue(context, attribute, seen, staticOptions) {
|
|
@@ -21176,9 +21291,9 @@ function isInsideHoistedJsxElement(context, node) {
|
|
|
21176
21291
|
if (parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === current) {
|
|
21177
21292
|
const variable = getVariableByName(context.sourceCode.getScope(current), parent.id.name);
|
|
21178
21293
|
/* v8 ignore next -- @preserve module-level JSX declarators have scope variables in parser scopes. */
|
|
21179
|
-
if (variable !== void 0 && isModuleLevelScope
|
|
21294
|
+
if (variable !== void 0 && isModuleLevelScope(variable.scope)) return true;
|
|
21180
21295
|
}
|
|
21181
|
-
if (parent.type === "JSXElement" || parent.type === "JSXFragment") current = parent;
|
|
21296
|
+
if (parent.type === "JSXElement" || parent.type === "JSXFragment" || parent.type === "ParenthesizedExpression") current = parent;
|
|
21182
21297
|
({parent} = parent);
|
|
21183
21298
|
}
|
|
21184
21299
|
return false;
|
|
@@ -21233,6 +21348,7 @@ const STATIC_OPTIONS = { staticGlobalFactories: new Set(DEFAULT_STATIC_GLOBAL_FA
|
|
|
21233
21348
|
function getAttributeExpression(node) {
|
|
21234
21349
|
const { value } = node;
|
|
21235
21350
|
if (value?.type !== "JSXExpressionContainer") return void 0;
|
|
21351
|
+
/* v8 ignore next -- @preserve Oxc only produces JSXEmptyExpression here for rejected parse-error cases. */
|
|
21236
21352
|
if (value.expression.type === "JSXEmptyExpression") return void 0;
|
|
21237
21353
|
return value.expression;
|
|
21238
21354
|
}
|
|
@@ -21240,6 +21356,8 @@ function isJsxElementAssignedToModuleConst(context, node) {
|
|
|
21240
21356
|
let current = node;
|
|
21241
21357
|
while (true) {
|
|
21242
21358
|
const { parent } = current;
|
|
21359
|
+
/* v8 ignore next -- @preserve decorated parser ASTs keep JSX ancestors attached until traversal stops. */
|
|
21360
|
+
if (parent === null) return false;
|
|
21243
21361
|
if (parent.type === "VariableDeclarator") return isModuleConstDeclaration(context, node, parent, current);
|
|
21244
21362
|
const nextParent = getWalkableJsxParent(parent);
|
|
21245
21363
|
if (nextParent === void 0) return false;
|
|
@@ -21247,7 +21365,7 @@ function isJsxElementAssignedToModuleConst(context, node) {
|
|
|
21247
21365
|
}
|
|
21248
21366
|
}
|
|
21249
21367
|
function getWalkableJsxParent(parent) {
|
|
21250
|
-
if (parent.type === "JSXElement" || parent.type === "JSXFragment" || parent.type === "JSXExpressionContainer" || parent.type === "ArrayExpression") return parent;
|
|
21368
|
+
if (parent.type === "JSXElement" || parent.type === "JSXFragment" || parent.type === "JSXExpressionContainer" || parent.type === "ParenthesizedExpression" || parent.type === "ArrayExpression") return parent;
|
|
21251
21369
|
}
|
|
21252
21370
|
function isModuleConstDeclaration(context, node, parent, current) {
|
|
21253
21371
|
/* v8 ignore next -- @preserve non-identifier module bindings cannot be referenced as JSX constants. */
|
|
@@ -21255,7 +21373,7 @@ function isModuleConstDeclaration(context, node, parent, current) {
|
|
|
21255
21373
|
/* v8 ignore next -- @preserve walkable JSX parents are followed only through initializer positions. */
|
|
21256
21374
|
if (parent.init !== current) return false;
|
|
21257
21375
|
const variable = getVariableByName(context.sourceCode.getScope(node), parent.id.name);
|
|
21258
|
-
return variable !== void 0 && isModuleLevelScope
|
|
21376
|
+
return variable !== void 0 && isModuleLevelScope(variable.scope);
|
|
21259
21377
|
}
|
|
21260
21378
|
function reportHoistableObject(context, objectExpression) {
|
|
21261
21379
|
const objectText = context.sourceCode.getText(objectExpression);
|
|
@@ -21308,8 +21426,13 @@ const preferHoistedJsxObjectProperties = defineRule({
|
|
|
21308
21426
|
function isSimpleReceiver({ type }) {
|
|
21309
21427
|
return type === "Identifier" || type === "MemberExpression" || type === "CallExpression" || type === "NewExpression" || type === "ThisExpression";
|
|
21310
21428
|
}
|
|
21429
|
+
function stripParenthesizedExpression$1(expression) {
|
|
21430
|
+
let current = expression;
|
|
21431
|
+
while (current.type === "ParenthesizedExpression") current = current.expression;
|
|
21432
|
+
return current;
|
|
21433
|
+
}
|
|
21311
21434
|
const preferIdiv = defineRule({
|
|
21312
|
-
|
|
21435
|
+
createOnce(context) {
|
|
21313
21436
|
return { CallExpression(node) {
|
|
21314
21437
|
if (node.optional) return;
|
|
21315
21438
|
const callee = unwrapExpression(node.callee);
|
|
@@ -21321,9 +21444,9 @@ const preferIdiv = defineRule({
|
|
|
21321
21444
|
const expression = unwrapExpression(argument);
|
|
21322
21445
|
if (expression.type !== "BinaryExpression" || expression.operator !== "/") return;
|
|
21323
21446
|
const left = unwrapExpression(expression.left);
|
|
21324
|
-
const leftText = context.sourceCode.getText(expression.left);
|
|
21447
|
+
const leftText = context.sourceCode.getText(stripParenthesizedExpression$1(expression.left));
|
|
21325
21448
|
const receiverText = isSimpleReceiver(left) ? leftText : `(${leftText})`;
|
|
21326
|
-
const rightText = context.sourceCode.getText(expression.right);
|
|
21449
|
+
const rightText = context.sourceCode.getText(stripParenthesizedExpression$1(expression.right));
|
|
21327
21450
|
context.report({
|
|
21328
21451
|
fix: (fixer) => fixer.replaceText(node, `${receiverText}.idiv(${rightText})`),
|
|
21329
21452
|
messageId: "useIdiv",
|
|
@@ -21406,7 +21529,7 @@ function getPortalReplacement(componentName, node, sourceCode) {
|
|
|
21406
21529
|
const preferLocalPortalComponent = defineRule({
|
|
21407
21530
|
create(context) {
|
|
21408
21531
|
const { filename, sourceCode } = context;
|
|
21409
|
-
/* v8 ignore start -- @preserve
|
|
21532
|
+
/* v8 ignore start -- @preserve rule harness/runtime filenames are present; empty filename is a defensive host guard. */
|
|
21410
21533
|
const discoveredPortal = filename === "" ? { found: false } : discoverLocalComponent(filename, PORTAL_COMPONENT);
|
|
21411
21534
|
/* v8 ignore stop -- @preserve */
|
|
21412
21535
|
const availablePortalIdentifiers = /* @__PURE__ */ new Set();
|
|
@@ -21480,6 +21603,7 @@ function isKnownNonNumberIdentifier(sourceCode, identifier) {
|
|
|
21480
21603
|
return false;
|
|
21481
21604
|
}
|
|
21482
21605
|
function isKnownNonNumberExpression(sourceCode, expression) {
|
|
21606
|
+
if (expression.type === "ParenthesizedExpression") return isKnownNonNumberExpression(sourceCode, expression.expression);
|
|
21483
21607
|
if (expression.type === "TSAsExpression" || expression.type === "TSTypeAssertion") return !isNumberTypeAnnotation(expression.typeAnnotation);
|
|
21484
21608
|
/* v8 ignore next -- @preserve literal non-number cases are covered by direct literal tests. */
|
|
21485
21609
|
if (isKnownNonNumberLiteral(expression)) return true;
|
|
@@ -21489,9 +21613,15 @@ function isKnownNonNumberExpression(sourceCode, expression) {
|
|
|
21489
21613
|
function getComparableText(sourceCode, expression) {
|
|
21490
21614
|
return sourceCode.getText(unwrapExpression(expression));
|
|
21491
21615
|
}
|
|
21616
|
+
function stripParenthesizedExpression(expression) {
|
|
21617
|
+
let current = expression;
|
|
21618
|
+
while (current.type === "ParenthesizedExpression") current = current.expression;
|
|
21619
|
+
return current;
|
|
21620
|
+
}
|
|
21492
21621
|
function getMathArgumentText(sourceCode, expression) {
|
|
21493
|
-
|
|
21494
|
-
return sourceCode.getText(
|
|
21622
|
+
const unwrapped = stripParenthesizedExpression(expression);
|
|
21623
|
+
if (unwrapped.type === "SequenceExpression") return `(${sourceCode.getText(unwrapped)})`;
|
|
21624
|
+
return sourceCode.getText(unwrapped);
|
|
21495
21625
|
}
|
|
21496
21626
|
function getPreferredMathMethod(sourceCode, node) {
|
|
21497
21627
|
if (node.test.type !== "BinaryExpression") return void 0;
|
|
@@ -21870,7 +22000,7 @@ function getEnumMemberName(node) {
|
|
|
21870
22000
|
return IS_INTEGER.test(node.id.value) ? void 0 : node.id.value;
|
|
21871
22001
|
}
|
|
21872
22002
|
const preferPascalCaseEnums = defineRule({
|
|
21873
|
-
|
|
22003
|
+
createOnce(context) {
|
|
21874
22004
|
return {
|
|
21875
22005
|
TSEnumDeclaration(node) {
|
|
21876
22006
|
const identifier = node.id.name;
|
|
@@ -21905,7 +22035,7 @@ const preferPascalCaseEnums = defineRule({
|
|
|
21905
22035
|
//#endregion
|
|
21906
22036
|
//#region src/rules/prefer-sequence-overloads.ts
|
|
21907
22037
|
function isNumericLiteralValue(node, value) {
|
|
21908
|
-
return isNumericLiteral
|
|
22038
|
+
return isNumericLiteral(node) && node.value === value;
|
|
21909
22039
|
}
|
|
21910
22040
|
function getSequenceKeypointName(sequenceName) {
|
|
21911
22041
|
if (sequenceName === "ColorSequence") return "ColorSequenceKeypoint";
|
|
@@ -21957,7 +22087,7 @@ function getKeypointArrayReplacement(context, node, sequenceName, keypointName)
|
|
|
21957
22087
|
};
|
|
21958
22088
|
}
|
|
21959
22089
|
const preferSequenceOverloads = defineRule({
|
|
21960
|
-
|
|
22090
|
+
createOnce(context) {
|
|
21961
22091
|
return { NewExpression(node) {
|
|
21962
22092
|
if (node.callee.type !== "Identifier") return;
|
|
21963
22093
|
const sequenceName = node.callee.name;
|
|
@@ -22284,7 +22414,7 @@ function isPlural(identifier) {
|
|
|
22284
22414
|
return lastToken !== void 0 && isPluralWord(lastToken.lowercased, lastToken.original);
|
|
22285
22415
|
}
|
|
22286
22416
|
const preferSingularEnums = defineRule({
|
|
22287
|
-
|
|
22417
|
+
createOnce(context) {
|
|
22288
22418
|
return { TSEnumDeclaration({ id }) {
|
|
22289
22419
|
const { name } = id;
|
|
22290
22420
|
if (!isPlural(name)) return;
|
|
@@ -22310,9 +22440,6 @@ const preferSingularEnums = defineRule({
|
|
|
22310
22440
|
function canRender(node) {
|
|
22311
22441
|
return node.type === "JSXElement" || node.type === "JSXFragment";
|
|
22312
22442
|
}
|
|
22313
|
-
function isExpressionNode(node) {
|
|
22314
|
-
return node.type !== "PrivateIdentifier";
|
|
22315
|
-
}
|
|
22316
22443
|
function areEquivalentExpressionOrSuper(left, right, sourceCode) {
|
|
22317
22444
|
if (left.type === "Super" || right.type === "Super") return left.type === "Super" && right.type === "Super";
|
|
22318
22445
|
return areEquivalentExpression(left, right, sourceCode);
|
|
@@ -22962,7 +23089,7 @@ function countCaptureGroups(replacement) {
|
|
|
22962
23089
|
if (dollarReferences === null) return 0;
|
|
22963
23090
|
let maxGroup = 0;
|
|
22964
23091
|
for (const dollarReference of dollarReferences) {
|
|
22965
|
-
const groupNumber =
|
|
23092
|
+
const groupNumber = Math.trunc(Number(dollarReference.slice(1)));
|
|
22966
23093
|
if (groupNumber > maxGroup) maxGroup = groupNumber;
|
|
22967
23094
|
}
|
|
22968
23095
|
return maxGroup;
|
|
@@ -23372,18 +23499,18 @@ function isDefaultOrNamespaceImportName(identifier) {
|
|
|
23372
23499
|
if (isImportDefaultSpecifier(parent) && parent.local === identifier || isImportNamespaceSpecifier(parent) && parent.local === identifier) return true;
|
|
23373
23500
|
if (isImportSpecifier$1(parent) && parent.local === identifier) {
|
|
23374
23501
|
const { imported } = parent;
|
|
23375
|
-
if (isIdentifierName
|
|
23502
|
+
if (isIdentifierName(imported) && imported.name === "default") return true;
|
|
23376
23503
|
}
|
|
23377
|
-
return isVariableDeclarator
|
|
23504
|
+
return isVariableDeclarator(parent) && parent.id === identifier && parent.init !== null && isStaticRequire(parent.init);
|
|
23378
23505
|
}
|
|
23379
23506
|
function isExportedIdentifier(identifier) {
|
|
23380
23507
|
/* v8 ignore next -- parser-produced identifiers in this rule always expose a name. @preserve */
|
|
23381
23508
|
if (!hasName(identifier)) return false;
|
|
23382
23509
|
const { parent } = identifier;
|
|
23383
|
-
if (isVariableDeclarator
|
|
23510
|
+
if (isVariableDeclarator(parent) && parent.id === identifier) {
|
|
23384
23511
|
const declaration = parent.parent;
|
|
23385
23512
|
/* v8 ignore next -- variable declarator definitions are always parented by a variable declaration. @preserve */
|
|
23386
|
-
return isVariableDeclaration
|
|
23513
|
+
return isVariableDeclaration(declaration) ? isExportNamedDeclaration(declaration.parent) : false;
|
|
23387
23514
|
}
|
|
23388
23515
|
if (isFunctionDeclaration(parent) && parent.id === identifier) return isExportNamedDeclaration(parent.parent);
|
|
23389
23516
|
if (isClass(parent) && parent.id === identifier) return isExportNamedDeclaration(parent.parent);
|
|
@@ -23434,16 +23561,16 @@ function getImportSource(definition) {
|
|
|
23434
23561
|
if (definition.type === "ImportBinding") {
|
|
23435
23562
|
const { parent } = definition;
|
|
23436
23563
|
/* v8 ignore else -- parser import bindings retain their ImportDeclaration parent. @preserve */
|
|
23437
|
-
if (parent !== null && isImportDeclaration(parent) && isStringLiteral
|
|
23564
|
+
if (parent !== null && isImportDeclaration(parent) && isStringLiteral(parent.source)) return parent.source.value;
|
|
23438
23565
|
}
|
|
23439
23566
|
/* v8 ignore next -- variable import checks only reach require-backed variable definitions. @preserve */
|
|
23440
23567
|
if (definition.type === "Variable") {
|
|
23441
23568
|
const { node } = definition;
|
|
23442
23569
|
/* v8 ignore else -- callers only ask for sources from static require declarators. @preserve */
|
|
23443
|
-
if (isVariableDeclarator
|
|
23570
|
+
if (isVariableDeclarator(node) && node.init !== null && isStaticRequire(node.init)) {
|
|
23444
23571
|
const [argument] = node.init.arguments;
|
|
23445
23572
|
/* v8 ignore next -- static require recognition requires a string literal source. @preserve */
|
|
23446
|
-
if (argument !== void 0 && isStringLiteral
|
|
23573
|
+
if (argument !== void 0 && isStringLiteral(argument)) return argument.value;
|
|
23447
23574
|
}
|
|
23448
23575
|
}
|
|
23449
23576
|
}
|
|
@@ -23501,9 +23628,9 @@ function shouldSkipVariable(definition, definitionName, options) {
|
|
|
23501
23628
|
function getSpecialCaseReplacement(variable) {
|
|
23502
23629
|
if (variable.name !== "plr") return void 0;
|
|
23503
23630
|
const [definition] = variable.defs;
|
|
23504
|
-
if (definition?.type !== "Variable" || !isVariableDeclarator
|
|
23631
|
+
if (definition?.type !== "Variable" || !isVariableDeclarator(definition.node) || definition.node.init === null) return;
|
|
23505
23632
|
const { init } = definition.node;
|
|
23506
|
-
if (isMemberExpression(init) && !init.computed && isIdentifierName
|
|
23633
|
+
if (isMemberExpression(init) && !init.computed && isIdentifierName(init.object) && init.object.name === "Players" && isIdentifierName(init.property) && init.property.name === "LocalPlayer") return "localPlayer";
|
|
23507
23634
|
}
|
|
23508
23635
|
function computeSafeSamples(samples, scopes, isSafeNameForVariable, options) {
|
|
23509
23636
|
const safeSamples = new Array();
|
|
@@ -23525,7 +23652,7 @@ function computeSafeSamples(samples, scopes, isSafeNameForVariable, options) {
|
|
|
23525
23652
|
};
|
|
23526
23653
|
}
|
|
23527
23654
|
function createIsSafeNameForVariable(definition, variable, isSafeGeneratedName) {
|
|
23528
|
-
const avoidArgumentsReplacement = definition.type === "Variable" && isVariableDeclarator
|
|
23655
|
+
const avoidArgumentsReplacement = definition.type === "Variable" && isVariableDeclarator(definition.node) && definition.node.init === null;
|
|
23529
23656
|
const avoidArgumentsInArrowParameter = definition.type === "Parameter" && variable.scope.type === "function" && variable.scope.block.type === "ArrowFunctionExpression";
|
|
23530
23657
|
const shouldAvoidArguments = avoidArgumentsReplacement || avoidArgumentsInArrowParameter;
|
|
23531
23658
|
return (name, scopes) => {
|
|
@@ -23552,7 +23679,7 @@ function checkVariable(variable, options, scopeToNamesGeneratedByFixer, isSafeGe
|
|
|
23552
23679
|
if (definition === void 0) return;
|
|
23553
23680
|
const definitionName = definition.name;
|
|
23554
23681
|
/* v8 ignore next -- parser variable definitions in this rule expose identifier names. @preserve */
|
|
23555
|
-
if (!isIdentifierName
|
|
23682
|
+
if (!isIdentifierName(definitionName)) return;
|
|
23556
23683
|
if (shouldSkipVariable(definition, definitionName, options)) return;
|
|
23557
23684
|
const isSafeNameForVariable = createIsSafeNameForVariable(definition, variable, isSafeGeneratedName);
|
|
23558
23685
|
const specialCaseReplacement = getSpecialCaseReplacement(variable);
|
|
@@ -23598,7 +23725,7 @@ function checkPossiblyWeirdClassVariable(variable, variableChecker) {
|
|
|
23598
23725
|
}
|
|
23599
23726
|
const definitionName = definition.name;
|
|
23600
23727
|
/* v8 ignore next -- parser class-name definitions expose identifier names. @preserve */
|
|
23601
|
-
if (!isIdentifierName
|
|
23728
|
+
if (!isIdentifierName(definitionName)) {
|
|
23602
23729
|
variableChecker(variable);
|
|
23603
23730
|
return;
|
|
23604
23731
|
}
|
|
@@ -23649,7 +23776,7 @@ function getFixablePropertyReplacement(node, samples) {
|
|
|
23649
23776
|
if (samples?.length !== 1 || !isObjectPropertyKey(node)) return void 0;
|
|
23650
23777
|
const [replacement] = samples;
|
|
23651
23778
|
const { parent } = node;
|
|
23652
|
-
if (replacement !== void 0 && isProperty(parent) && isStringLiteral
|
|
23779
|
+
if (replacement !== void 0 && isProperty(parent) && isStringLiteral(parent.value) && isValidIdentifier(replacement)) return replacement;
|
|
23653
23780
|
}
|
|
23654
23781
|
const preventAbbreviations = defineRule({
|
|
23655
23782
|
create(context) {
|
|
@@ -25275,36 +25402,27 @@ function isAssignedJSXValue(node) {
|
|
|
25275
25402
|
if (parent.type === "AssignmentExpression") return parent.right === current;
|
|
25276
25403
|
return false;
|
|
25277
25404
|
}
|
|
25278
|
-
function
|
|
25405
|
+
function isJSXChildWrappedBy(node, wrapperType) {
|
|
25279
25406
|
let current = getParent(node);
|
|
25280
25407
|
/* v8 ignore next -- @preserve visited JSX nodes have parent links in parser-produced ASTs. */
|
|
25281
25408
|
if (current === void 0) return false;
|
|
25282
|
-
let
|
|
25283
|
-
while (current !== void 0 && (current.type ===
|
|
25284
|
-
|
|
25409
|
+
let foundWrapper = false;
|
|
25410
|
+
while (current !== void 0 && (current.type === wrapperType || WRAPPER_PARENT_TYPES.has(current.type))) {
|
|
25411
|
+
/* v8 ignore else -- @preserve current parser output keeps wrapped JSX operands attached directly to the wrapper here. */
|
|
25412
|
+
if (current.type === wrapperType) foundWrapper = true;
|
|
25285
25413
|
current = getParent(current);
|
|
25286
25414
|
}
|
|
25287
|
-
if (!
|
|
25415
|
+
if (!foundWrapper || current?.type !== "JSXExpressionContainer") return false;
|
|
25288
25416
|
const containerParent = getParent(current);
|
|
25289
25417
|
/* v8 ignore next -- @preserve parser-produced JSX expression containers are attached to a parent. */
|
|
25290
25418
|
if (containerParent === void 0) return false;
|
|
25291
25419
|
return containerParent.type === "JSXElement" || containerParent.type === "JSXFragment";
|
|
25292
25420
|
}
|
|
25421
|
+
function isTernaryJSXChild(node) {
|
|
25422
|
+
return isJSXChildWrappedBy(node, "ConditionalExpression");
|
|
25423
|
+
}
|
|
25293
25424
|
function isLogicalJSXChild(node) {
|
|
25294
|
-
|
|
25295
|
-
/* v8 ignore next -- @preserve visited JSX nodes have parent links in parser-produced ASTs. */
|
|
25296
|
-
if (current === void 0) return false;
|
|
25297
|
-
let foundLogical = false;
|
|
25298
|
-
while (current !== void 0 && (current.type === "LogicalExpression" || WRAPPER_PARENT_TYPES.has(current.type))) {
|
|
25299
|
-
/* v8 ignore else -- @preserve current parser output keeps logical JSX operands attached directly to LogicalExpression here. */
|
|
25300
|
-
if (current.type === "LogicalExpression") foundLogical = true;
|
|
25301
|
-
current = getParent(current);
|
|
25302
|
-
}
|
|
25303
|
-
if (!foundLogical || current?.type !== "JSXExpressionContainer") return false;
|
|
25304
|
-
const containerParent = getParent(current);
|
|
25305
|
-
/* v8 ignore next -- @preserve parser-produced JSX expression containers are attached to a parent. */
|
|
25306
|
-
if (containerParent === void 0) return false;
|
|
25307
|
-
return containerParent.type === "JSXElement" || containerParent.type === "JSXFragment";
|
|
25425
|
+
return isJSXChildWrappedBy(node, "LogicalExpression");
|
|
25308
25426
|
}
|
|
25309
25427
|
const requireReactComponentKeys = defineRule({
|
|
25310
25428
|
create(context) {
|
|
@@ -25613,7 +25731,7 @@ function getEnclosingFunctionName(node) {
|
|
|
25613
25731
|
}
|
|
25614
25732
|
function getAssignedName({ parent }) {
|
|
25615
25733
|
if (parent?.type === "VariableDeclarator" && parent.id.type === "Identifier") return parent.id.name;
|
|
25616
|
-
if (parent?.type === "PropertyDefinition" || parent?.type === "
|
|
25734
|
+
if (parent?.type === "PropertyDefinition" || parent?.type === "MethodDefinition") {
|
|
25617
25735
|
if (parent.key.type === "PrivateIdentifier") return `#${parent.key.name}`;
|
|
25618
25736
|
/* v8 ignore next -- @preserve class and object member keys are identifiers after private keys are handled. */
|
|
25619
25737
|
if (parent.key.type === "Identifier") return parent.key.name;
|
|
@@ -25707,7 +25825,7 @@ const requireThrowErrorCapture = defineRule({
|
|
|
25707
25825
|
create(context) {
|
|
25708
25826
|
const { sourceCode } = context;
|
|
25709
25827
|
const allowList = context.options[0]?.allow ?? [];
|
|
25710
|
-
/* v8 ignore next -- @preserve
|
|
25828
|
+
/* v8 ignore next -- @preserve the rule harness and Oxlint provide a physical filename for rule execution. */
|
|
25711
25829
|
const physicalFilename = context.physicalFilename ?? "<input>";
|
|
25712
25830
|
return { ThrowStatement(node) {
|
|
25713
25831
|
const { argument } = node;
|
|
@@ -25801,7 +25919,7 @@ function isNotSpread(node) {
|
|
|
25801
25919
|
return node.type !== "SpreadElement";
|
|
25802
25920
|
}
|
|
25803
25921
|
const requireUnicodeRegex = defineRule({
|
|
25804
|
-
|
|
25922
|
+
createOnce(context) {
|
|
25805
25923
|
return { CallExpression(node) {
|
|
25806
25924
|
if (!isIdentifierWithName(node.callee, "regex")) return;
|
|
25807
25925
|
if (node.arguments.length < 2) {
|
|
@@ -25843,9 +25961,9 @@ function reportEmptyDefaultValue(context, defaultValue) {
|
|
|
25843
25961
|
function checkParameterDefaults(context, parameters) {
|
|
25844
25962
|
for (const parameter of parameters) {
|
|
25845
25963
|
if (parameter.type === "AssignmentPattern" && parameter.left.type === "ObjectPattern") {
|
|
25964
|
+
checkObjectPatternDefaults(context, parameter.left);
|
|
25846
25965
|
/* v8 ignore next -- @preserve assignment pattern defaults are parser expression nodes. */
|
|
25847
25966
|
if (isNode$1(parameter.right)) reportEmptyDefaultValue(context, parameter.right);
|
|
25848
|
-
checkObjectPatternDefaults(context, parameter.left);
|
|
25849
25967
|
continue;
|
|
25850
25968
|
}
|
|
25851
25969
|
if (parameter.type !== "ObjectPattern") continue;
|
|
@@ -26126,8 +26244,12 @@ function getHookName(node) {
|
|
|
26126
26244
|
function getMemberExpressionDepth(node) {
|
|
26127
26245
|
let depth = 0;
|
|
26128
26246
|
let current = node;
|
|
26129
|
-
|
|
26130
|
-
|
|
26247
|
+
while (true) {
|
|
26248
|
+
if (current.type === "ChainExpression" || current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSNonNullExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion") {
|
|
26249
|
+
current = current.expression;
|
|
26250
|
+
continue;
|
|
26251
|
+
}
|
|
26252
|
+
if (current.type !== "MemberExpression") break;
|
|
26131
26253
|
depth += 1;
|
|
26132
26254
|
current = current.object;
|
|
26133
26255
|
}
|
|
@@ -26135,15 +26257,21 @@ function getMemberExpressionDepth(node) {
|
|
|
26135
26257
|
}
|
|
26136
26258
|
function getRootIdentifier(node) {
|
|
26137
26259
|
let current = node;
|
|
26138
|
-
|
|
26139
|
-
|
|
26260
|
+
while (true) {
|
|
26261
|
+
if (current.type === "ChainExpression" || current.type === "ParenthesizedExpression" || current.type === "TSAsExpression" || current.type === "TSNonNullExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSTypeAssertion") {
|
|
26262
|
+
current = current.expression;
|
|
26263
|
+
continue;
|
|
26264
|
+
}
|
|
26265
|
+
if (current.type !== "MemberExpression") break;
|
|
26266
|
+
current = current.object;
|
|
26267
|
+
}
|
|
26140
26268
|
return current.type === "Identifier" ? current : void 0;
|
|
26141
26269
|
}
|
|
26142
26270
|
function collectIdentifierNames(node) {
|
|
26143
26271
|
if (node.type === "Identifier") return [node.name];
|
|
26144
26272
|
if (node.type === "MemberExpression") return collectIdentifierNames(node.object);
|
|
26145
26273
|
if (node.type === "ChainExpression") return collectIdentifierNames(node.expression);
|
|
26146
|
-
if (node.type === "TSNonNullExpression" || node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression" || node.type === "TSTypeAssertion") return collectIdentifierNames(node.expression);
|
|
26274
|
+
if (node.type === "ParenthesizedExpression" || node.type === "TSNonNullExpression" || node.type === "TSAsExpression" || node.type === "TSSatisfiesExpression" || node.type === "TSTypeAssertion") return collectIdentifierNames(node.expression);
|
|
26147
26275
|
if (node.type === "BinaryExpression" || node.type === "LogicalExpression") return [...collectIdentifierNames(node.left), ...collectIdentifierNames(node.right)];
|
|
26148
26276
|
if (node.type === "UnaryExpression") return collectIdentifierNames(node.argument);
|
|
26149
26277
|
if (node.type === "ConditionalExpression") return [
|
|
@@ -26158,7 +26286,7 @@ function isExpression(node) {
|
|
|
26158
26286
|
}
|
|
26159
26287
|
function nodeToSafeDependencyPath(node, sourceCode) {
|
|
26160
26288
|
if (node.type === "Identifier") return node.name;
|
|
26161
|
-
if (node.type === "ChainExpression" || isExpression(node)) return nodeToSafeDependencyPath(node.expression, sourceCode);
|
|
26289
|
+
if (node.type === "ChainExpression" || node.type === "ParenthesizedExpression" || isExpression(node)) return nodeToSafeDependencyPath(node.expression, sourceCode);
|
|
26162
26290
|
/* v8 ignore next -- @preserve dependency path conversion only receives identifiers, chains, transparent TS wrappers, or member expressions. */
|
|
26163
26291
|
if (node.type === "MemberExpression") {
|
|
26164
26292
|
const objectPath = nodeToSafeDependencyPath(node.object, sourceCode);
|
|
@@ -26372,7 +26500,7 @@ function getCaptureInfo(current, name, variable, sourceCode) {
|
|
|
26372
26500
|
};
|
|
26373
26501
|
}
|
|
26374
26502
|
function isTransparentExpressionNode(node) {
|
|
26375
|
-
return node.type === "TSSatisfiesExpression" || node.type === "TSAsExpression" || node.type === "TSTypeAssertion" || node.type === "TSNonNullExpression";
|
|
26503
|
+
return node.type === "ParenthesizedExpression" || node.type === "TSSatisfiesExpression" || node.type === "TSAsExpression" || node.type === "TSTypeAssertion" || node.type === "TSNonNullExpression";
|
|
26376
26504
|
}
|
|
26377
26505
|
function visitChildNodes(current, sourceCode, visit) {
|
|
26378
26506
|
/* v8 ignore next -- @preserve parser node types visited here have registered visitor keys. */
|
|
@@ -26433,7 +26561,7 @@ function parseDependencies(node, sourceCode) {
|
|
|
26433
26561
|
for (const element of node.elements) {
|
|
26434
26562
|
if (!element) continue;
|
|
26435
26563
|
const actualNode = element.type === "SpreadElement" ? element.argument : element;
|
|
26436
|
-
const name =
|
|
26564
|
+
const name = nodeToSafeDependencyPath(actualNode, sourceCode);
|
|
26437
26565
|
const depth = getMemberExpressionDepth(actualNode);
|
|
26438
26566
|
dependencies.push({
|
|
26439
26567
|
depth,
|
|
@@ -26785,9 +26913,6 @@ function isReactHookName(name) {
|
|
|
26785
26913
|
function getOptions(value) {
|
|
26786
26914
|
return isRecord(value) ? value : {};
|
|
26787
26915
|
}
|
|
26788
|
-
function isIdentifierName(node) {
|
|
26789
|
-
return node.type === "Identifier";
|
|
26790
|
-
}
|
|
26791
26916
|
function isComponentOrHook(node) {
|
|
26792
26917
|
if ((node.type === "FunctionDeclaration" || node.type === "FunctionExpression") && node.id !== null) return isComponentName(node.id.name) || isReactHookName(node.id.name);
|
|
26793
26918
|
const { parent } = node;
|
|
@@ -26906,6 +27031,7 @@ const smallRules = definePlugin({
|
|
|
26906
27031
|
"no-recursive": noRecursive,
|
|
26907
27032
|
"no-redundant-aspect-ratio-constraint": noRedundantAspectRatioConstraint,
|
|
26908
27033
|
"no-render-helper-functions": noRenderHelperFunctions,
|
|
27034
|
+
"no-restricted-property-assignment": noRestrictedPropertyAssignment,
|
|
26909
27035
|
"no-spec-file-extension": noSpecFileExtension,
|
|
26910
27036
|
"no-static-react-create-element": noStaticReactCreateElement,
|
|
26911
27037
|
"no-table-create-map": noTableCreateMap,
|