pasika 0.10.107 → 0.10.108
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/eslint/pasika/index.js +104 -34
- package/package.json +1 -1
|
@@ -9143,7 +9143,7 @@ function isHookUsage(node, hook) {
|
|
|
9143
9143
|
}
|
|
9144
9144
|
if (ts15.isIdentifier(node) && node.text === hook.value) {
|
|
9145
9145
|
const parent = node.parent;
|
|
9146
|
-
if (ts15.isBindingElement(parent) || ts15.isPropertyAccessExpression(parent) || ts15.
|
|
9146
|
+
if (ts15.isBindingElement(parent) && parent.name === node || ts15.isVariableDeclaration(parent) && parent.name === node || ts15.isParameter(parent) && parent.name === node || ts15.isPropertyAccessExpression(parent) && parent.name === node || ts15.isPropertyAssignment(parent) && parent.name === node) {
|
|
9147
9147
|
return void 0;
|
|
9148
9148
|
}
|
|
9149
9149
|
return "value";
|
|
@@ -9168,19 +9168,77 @@ function topLevelJsxChildren(initial) {
|
|
|
9168
9168
|
}
|
|
9169
9169
|
return void 0;
|
|
9170
9170
|
}
|
|
9171
|
-
function
|
|
9172
|
-
|
|
9171
|
+
function isSimpleDerivedExpression(node) {
|
|
9172
|
+
if (ts15.isNewExpression(node) || ts15.isAwaitExpression(node) || ts15.isYieldExpression(node) || ts15.isDeleteExpression(node) || ts15.isTaggedTemplateExpression(node) || ts15.isBlock(node)) {
|
|
9173
|
+
return false;
|
|
9174
|
+
}
|
|
9175
|
+
if (ts15.isCallExpression(node)) {
|
|
9176
|
+
const callee = node.expression;
|
|
9177
|
+
if (!ts15.isPropertyAccessExpression(callee) || !(/* @__PURE__ */ new Set(["filter", "map", "find", "findIndex", "some", "every", "slice", "includes"])).has(callee.name.text)) {
|
|
9178
|
+
return false;
|
|
9179
|
+
}
|
|
9180
|
+
}
|
|
9181
|
+
if (ts15.isArrowFunction(node) && ts15.isBlock(node.body)) return false;
|
|
9182
|
+
if (ts15.isBinaryExpression(node)) {
|
|
9183
|
+
const operator = node.operatorToken.kind;
|
|
9184
|
+
if (operator >= ts15.SyntaxKind.FirstAssignment && operator <= ts15.SyntaxKind.LastAssignment) return false;
|
|
9185
|
+
}
|
|
9186
|
+
if ((ts15.isPrefixUnaryExpression(node) || ts15.isPostfixUnaryExpression(node)) && (node.operator === ts15.SyntaxKind.PlusPlusToken || node.operator === ts15.SyntaxKind.MinusMinusToken)) {
|
|
9187
|
+
return false;
|
|
9188
|
+
}
|
|
9189
|
+
let safe = true;
|
|
9190
|
+
ts15.forEachChild(node, (child) => {
|
|
9191
|
+
if (!isSimpleDerivedExpression(child)) safe = false;
|
|
9192
|
+
});
|
|
9193
|
+
return safe;
|
|
9194
|
+
}
|
|
9195
|
+
function isIdentifierRead(node, names) {
|
|
9196
|
+
if (!ts15.isIdentifier(node) || !names.has(node.text)) return false;
|
|
9197
|
+
const parent = node.parent;
|
|
9198
|
+
return !(ts15.isBindingElement(parent) && parent.name === node || ts15.isVariableDeclaration(parent) && parent.name === node || ts15.isParameter(parent) && parent.name === node || ts15.isPropertyAccessExpression(parent) && parent.name === node || ts15.isPropertyAssignment(parent) && parent.name === node);
|
|
9199
|
+
}
|
|
9200
|
+
function containsNamedRead(node, names) {
|
|
9201
|
+
if (isIdentifierRead(node, names)) return true;
|
|
9202
|
+
return ts15.forEachChild(node, (child) => containsNamedRead(child, names)) ?? false;
|
|
9203
|
+
}
|
|
9204
|
+
function findDerivedState(body, hook) {
|
|
9205
|
+
const names = /* @__PURE__ */ new Set([hook.value]);
|
|
9206
|
+
const allowedInitializers = /* @__PURE__ */ new Set();
|
|
9207
|
+
for (const statement of body.statements) {
|
|
9208
|
+
if (!ts15.isVariableStatement(statement) || statement.declarationList.flags !== ts15.NodeFlags.Const) continue;
|
|
9209
|
+
for (const declaration of statement.declarationList.declarations) {
|
|
9210
|
+
if (!ts15.isIdentifier(declaration.name) || !declaration.initializer) continue;
|
|
9211
|
+
if (!containsNamedRead(declaration.initializer, names)) continue;
|
|
9212
|
+
if (!isSimpleDerivedExpression(declaration.initializer)) continue;
|
|
9213
|
+
names.add(declaration.name.text);
|
|
9214
|
+
allowedInitializers.add(declaration.initializer);
|
|
9215
|
+
}
|
|
9216
|
+
}
|
|
9217
|
+
return { names, allowedInitializers };
|
|
9218
|
+
}
|
|
9219
|
+
function isTrackedUse(node, hook, names) {
|
|
9220
|
+
return isHookUsage(node, hook) !== void 0 || isIdentifierRead(node, names);
|
|
9221
|
+
}
|
|
9222
|
+
function countUsesIn(child, hook, names) {
|
|
9173
9223
|
let count = 0;
|
|
9174
9224
|
const visit = (node) => {
|
|
9175
|
-
if (
|
|
9176
|
-
positions.push(node);
|
|
9177
|
-
count += 1;
|
|
9178
|
-
}
|
|
9225
|
+
if (isTrackedUse(node, hook, names)) count += 1;
|
|
9179
9226
|
if (ts15.isFunctionDeclaration(node) || ts15.isClassDeclaration(node)) return;
|
|
9180
9227
|
ts15.forEachChild(node, visit);
|
|
9181
9228
|
};
|
|
9182
9229
|
visit(child);
|
|
9183
|
-
return
|
|
9230
|
+
return count;
|
|
9231
|
+
}
|
|
9232
|
+
function jsxChildren(node) {
|
|
9233
|
+
if (ts15.isJsxElement(node) || ts15.isJsxFragment(node)) {
|
|
9234
|
+
return [...node.children].filter((child) => !ts15.isJsxText(child));
|
|
9235
|
+
}
|
|
9236
|
+
return void 0;
|
|
9237
|
+
}
|
|
9238
|
+
function isDecorativeSeparator(node) {
|
|
9239
|
+
if (!ts15.isJsxSelfClosingElement(node) && !ts15.isJsxElement(node)) return false;
|
|
9240
|
+
const tagName2 = ts15.isJsxElement(node) ? node.openingElement.tagName : node.tagName;
|
|
9241
|
+
return /(?:Divider|Separator)$/.test(tagName2.getText());
|
|
9184
9242
|
}
|
|
9185
9243
|
var soleStateOwnerRule = {
|
|
9186
9244
|
meta: {
|
|
@@ -9226,42 +9284,54 @@ function analyzeSoleOwner(declaration, hook) {
|
|
|
9226
9284
|
};
|
|
9227
9285
|
visit(body);
|
|
9228
9286
|
if (returns.length !== 1) return void 0;
|
|
9229
|
-
const
|
|
9230
|
-
if (!
|
|
9231
|
-
const
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
const
|
|
9236
|
-
|
|
9237
|
-
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9287
|
+
const expression = returns[0]?.expression;
|
|
9288
|
+
if (!expression || !ts15.isExpression(expression)) return void 0;
|
|
9289
|
+
const root = topLevelJsxChildren(expression);
|
|
9290
|
+
if (!root) return void 0;
|
|
9291
|
+
const derived = findDerivedState(body, hook);
|
|
9292
|
+
if (usesOutsideJsx(declaration, hook, derived, root.children)) return void 0;
|
|
9293
|
+
const totalUses = countUsesIn(root.root, hook, derived.names);
|
|
9294
|
+
if (totalUses === 0) return void 0;
|
|
9295
|
+
const analyzeSection = (node) => {
|
|
9296
|
+
const children = jsxChildren(node);
|
|
9297
|
+
if (!children || children.length === 0) return void 0;
|
|
9298
|
+
for (const child of children) {
|
|
9299
|
+
if (ts15.isJsxElement(child) || ts15.isJsxFragment(child)) {
|
|
9300
|
+
const inner = analyzeSection(child);
|
|
9301
|
+
if (inner) return inner;
|
|
9302
|
+
}
|
|
9303
|
+
}
|
|
9304
|
+
const counts = children.map((child) => countUsesIn(child, hook, derived.names));
|
|
9305
|
+
if (counts.reduce((sum, count) => sum + count, 0) !== totalUses) return void 0;
|
|
9306
|
+
const firstUsed = counts.findIndex((count) => count > 0);
|
|
9307
|
+
const lastUsed = counts.map((count) => count > 0).lastIndexOf(true);
|
|
9308
|
+
if (firstUsed === -1 || lastUsed === -1) return void 0;
|
|
9309
|
+
for (let index = firstUsed; index <= lastUsed; index += 1) {
|
|
9310
|
+
const child = children[index];
|
|
9311
|
+
if ((counts[index] ?? 0) === 0 && (child === void 0 || !isDecorativeSeparator(child))) return void 0;
|
|
9312
|
+
}
|
|
9313
|
+
const hasOutside = firstUsed > 0 || lastUsed < children.length - 1;
|
|
9314
|
+
if (!hasOutside) return void 0;
|
|
9315
|
+
return { run: lastUsed - firstUsed + 1, totalTopLevel: children.length };
|
|
9316
|
+
};
|
|
9317
|
+
return analyzeSection(root.root);
|
|
9318
|
+
}
|
|
9319
|
+
function usesOutsideJsx(declaration, hook, derived, children) {
|
|
9250
9320
|
let outside = false;
|
|
9251
9321
|
const visit = (node) => {
|
|
9252
9322
|
if (outside) return;
|
|
9253
9323
|
if (node !== declaration && (ts15.isFunctionDeclaration(node) || ts15.isClassDeclaration(node))) return;
|
|
9254
|
-
if (
|
|
9324
|
+
if (isTrackedUse(node, hook, derived.names)) {
|
|
9255
9325
|
let current = node;
|
|
9256
|
-
let
|
|
9326
|
+
let allowed = false;
|
|
9257
9327
|
while (!ts15.isSourceFile(current)) {
|
|
9258
|
-
if (children.includes(current)) {
|
|
9259
|
-
|
|
9328
|
+
if (children.includes(current) || derived.allowedInitializers.has(current)) {
|
|
9329
|
+
allowed = true;
|
|
9260
9330
|
break;
|
|
9261
9331
|
}
|
|
9262
9332
|
current = current.parent;
|
|
9263
9333
|
}
|
|
9264
|
-
if (!
|
|
9334
|
+
if (!allowed) outside = true;
|
|
9265
9335
|
}
|
|
9266
9336
|
ts15.forEachChild(node, visit);
|
|
9267
9337
|
};
|