pasika 0.10.91 → 0.10.93
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 +86 -17
- package/package.json +1 -1
|
@@ -6418,13 +6418,17 @@ function canGroupSource(source) {
|
|
|
6418
6418
|
function isGroupedUsageSource(source) {
|
|
6419
6419
|
return source.type === "Identifier" || source.type === "ThisExpression";
|
|
6420
6420
|
}
|
|
6421
|
+
function supportsSinglePropertySource(source) {
|
|
6422
|
+
if (isGroupedUsageSource(source) || source.type === "CallExpression") return true;
|
|
6423
|
+
return source.type === "MemberExpression" && !source.computed && !source.optional && source.property.type === "Identifier" && supportsSinglePropertySource(source.object);
|
|
6424
|
+
}
|
|
6421
6425
|
function rootIdentifierName(node) {
|
|
6422
6426
|
if (node.type === "Identifier") return node.name;
|
|
6423
6427
|
if (node.type !== "MemberExpression" || node.object.type === "Super") return void 0;
|
|
6424
6428
|
return rootIdentifierName(node.object);
|
|
6425
6429
|
}
|
|
6426
6430
|
function isCompliantLocalName(propertyName5) {
|
|
6427
|
-
return !propertyName5.includes("_");
|
|
6431
|
+
return !propertyName5.includes("_") || /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$/u.test(propertyName5);
|
|
6428
6432
|
}
|
|
6429
6433
|
function propertyNameOf(node) {
|
|
6430
6434
|
if (node.type !== "Property" || node.computed) return void 0;
|
|
@@ -6485,6 +6489,27 @@ function enumValueResolver(context) {
|
|
|
6485
6489
|
return typeSymbol ? isEnumSymbol(typeSymbol) : localEnumBinding(context, node);
|
|
6486
6490
|
};
|
|
6487
6491
|
}
|
|
6492
|
+
function detachableCallResolver(context) {
|
|
6493
|
+
const services = typedParserServices(context.sourceCode.parserServices);
|
|
6494
|
+
if (!services) return () => false;
|
|
6495
|
+
const checker = services.program.getTypeChecker();
|
|
6496
|
+
const { esTreeNodeToTSNodeMap: nodeMap } = services;
|
|
6497
|
+
const isUnboundFunctionType = (type) => ts9.isFunctionTypeNode(type) && !type.parameters.some((parameter) => ts9.isIdentifier(parameter.name) && parameter.name.text === "this");
|
|
6498
|
+
return (member) => {
|
|
6499
|
+
const node = nodeMap.get(member);
|
|
6500
|
+
if (!node || !ts9.isPropertyAccessExpression(node)) return false;
|
|
6501
|
+
const symbol = checker.getSymbolAtLocation(node.name);
|
|
6502
|
+
const declarations = symbol?.declarations;
|
|
6503
|
+
if (!declarations?.length) return false;
|
|
6504
|
+
return declarations.every((declaration) => {
|
|
6505
|
+
if (ts9.isPropertySignature(declaration) || ts9.isPropertyDeclaration(declaration)) {
|
|
6506
|
+
return declaration.type !== void 0 && isUnboundFunctionType(declaration.type) || ts9.isPropertyDeclaration(declaration) && declaration.initializer !== void 0 && ts9.isArrowFunction(declaration.initializer);
|
|
6507
|
+
}
|
|
6508
|
+
if (ts9.isPropertyAssignment(declaration)) return ts9.isArrowFunction(declaration.initializer);
|
|
6509
|
+
return false;
|
|
6510
|
+
});
|
|
6511
|
+
};
|
|
6512
|
+
}
|
|
6488
6513
|
function directMappingRequiresQualifiedAccess(context, ownershipResolver, member) {
|
|
6489
6514
|
const mapping = renamedDirectMapping(context, member);
|
|
6490
6515
|
if (!mapping || !ownershipResolver) return false;
|
|
@@ -6503,14 +6528,15 @@ function objectUsage(scope, sourceText) {
|
|
|
6503
6528
|
}
|
|
6504
6529
|
return usage;
|
|
6505
6530
|
}
|
|
6506
|
-
function memberIsRead(context, member) {
|
|
6531
|
+
function memberIsRead(context, member, detachableCall) {
|
|
6507
6532
|
const parent = context.sourceCode.getAncestors(member).at(-1);
|
|
6508
6533
|
if (!parent) return true;
|
|
6509
6534
|
if (parent.type === "AssignmentExpression" && parent.left === member) return false;
|
|
6510
6535
|
if (parent.type === "UpdateExpression" && parent.argument === member) return false;
|
|
6511
6536
|
if (parent.type === "UnaryExpression" && parent.operator === "delete" && parent.argument === member) return false;
|
|
6512
6537
|
if ((parent.type === "ForInStatement" || parent.type === "ForOfStatement") && parent.left === member) return false;
|
|
6513
|
-
if (
|
|
6538
|
+
if (parent.type === "CallExpression" && parent.callee === member) return detachableCall(member);
|
|
6539
|
+
if (parent.type === "NewExpression" && parent.callee === member) return false;
|
|
6514
6540
|
if (parent.type === "TaggedTemplateExpression" && parent.tag === member) return false;
|
|
6515
6541
|
return true;
|
|
6516
6542
|
}
|
|
@@ -6518,10 +6544,10 @@ function memberIsDirectVariableInitializer(context, member) {
|
|
|
6518
6544
|
const parent = context.sourceCode.getAncestors(member).at(-1);
|
|
6519
6545
|
return parent?.type === "VariableDeclarator" && parent.init === member;
|
|
6520
6546
|
}
|
|
6521
|
-
function recordMemberUsage(context, scope, ownershipResolver, member, isEnumValue) {
|
|
6547
|
+
function recordMemberUsage(context, scope, ownershipResolver, member, isEnumValue, detachableCall) {
|
|
6522
6548
|
if (!scope || member.computed || member.optional || member.property.type !== "Identifier") return;
|
|
6523
6549
|
if (!memberCanBeDestructured(context, ownershipResolver, member, isEnumValue)) return;
|
|
6524
|
-
if (!isGroupedUsageSource(member.object) || !memberIsRead(context, member)) return;
|
|
6550
|
+
if (!isGroupedUsageSource(member.object) || !memberIsRead(context, member, detachableCall)) return;
|
|
6525
6551
|
const sourceText = context.sourceCode.getText(member.object);
|
|
6526
6552
|
const usage = objectUsage(scope, sourceText);
|
|
6527
6553
|
const propertyName5 = member.property.name;
|
|
@@ -6667,8 +6693,8 @@ function groupedDestructuringSelections(context, first, isEnumValue) {
|
|
|
6667
6693
|
function declarationTerminator(context, declaration) {
|
|
6668
6694
|
return context.sourceCode.getText(declaration).trimEnd().endsWith(";") ? ";" : "";
|
|
6669
6695
|
}
|
|
6670
|
-
function
|
|
6671
|
-
return `"${binding.
|
|
6696
|
+
function singlePropertyMessage(binding) {
|
|
6697
|
+
return `"${binding.propertyName}" is the only property bound from "${binding.sourceText}". Read "${binding.sourceText}.${binding.propertyName}" directly instead of creating a local binding. ${DOC5}`;
|
|
6672
6698
|
}
|
|
6673
6699
|
function groupMessage(bindings) {
|
|
6674
6700
|
const firstBinding = bindings[0];
|
|
@@ -6688,17 +6714,18 @@ var preferObjectDestructuringRule = {
|
|
|
6688
6714
|
type: "problem",
|
|
6689
6715
|
fixable: "code",
|
|
6690
6716
|
docs: {
|
|
6691
|
-
description: "
|
|
6717
|
+
description: "Prefer direct access for one property and shared destructuring for related property reads."
|
|
6692
6718
|
}
|
|
6693
6719
|
},
|
|
6694
6720
|
create(context) {
|
|
6695
6721
|
const ownershipResolver = contractOwnershipResolver(context);
|
|
6696
6722
|
const isEnumValue = enumValueResolver(context);
|
|
6723
|
+
const detachableCall = detachableCallResolver(context);
|
|
6697
6724
|
const grouped = /* @__PURE__ */ new Set();
|
|
6698
6725
|
const usageScopes = [];
|
|
6699
6726
|
const currentUsageScope = () => usageScopes.at(-1);
|
|
6700
6727
|
const enterUsageScope = (node) => {
|
|
6701
|
-
usageScopes.push({ node, objects: /* @__PURE__ */ new Map() });
|
|
6728
|
+
usageScopes.push({ node, objects: /* @__PURE__ */ new Map(), singleProperties: [] });
|
|
6702
6729
|
};
|
|
6703
6730
|
const enterUsageBarrier = () => {
|
|
6704
6731
|
usageScopes.push(void 0);
|
|
@@ -6722,6 +6749,12 @@ var preferObjectDestructuringRule = {
|
|
|
6722
6749
|
node: firstDirectMember,
|
|
6723
6750
|
message: scopeUsageMessage(sourceText, usage.propertyNames),
|
|
6724
6751
|
fix(fixer) {
|
|
6752
|
+
if (usage.directMembers.some(({ member }) => {
|
|
6753
|
+
const parent = context.sourceCode.getAncestors(member).at(-1);
|
|
6754
|
+
return parent?.type === "CallExpression" && parent.callee === member;
|
|
6755
|
+
})) {
|
|
6756
|
+
return null;
|
|
6757
|
+
}
|
|
6725
6758
|
const memberFixes = usage.directMembers.map(
|
|
6726
6759
|
({ member, propertyName: propertyName5 }) => fixer.replaceText(member, propertyName5)
|
|
6727
6760
|
);
|
|
@@ -6745,6 +6778,31 @@ ${indentation}`;
|
|
|
6745
6778
|
}
|
|
6746
6779
|
});
|
|
6747
6780
|
}
|
|
6781
|
+
for (const binding of scope.singleProperties) {
|
|
6782
|
+
const fromSameSource = scope.singleProperties.filter(({ sourceText }) => sourceText === binding.sourceText);
|
|
6783
|
+
if (fromSameSource[0] !== binding) continue;
|
|
6784
|
+
const usage = scope.objects.get(binding.sourceText);
|
|
6785
|
+
const usedProperties = usage?.propertyNames;
|
|
6786
|
+
if (usedProperties && usedProperties.size > 1 && usage.directMembers.length > 0) {
|
|
6787
|
+
if (scope.singleProperties.some(
|
|
6788
|
+
(item) => item.node.type === "ObjectPattern" && item.sourceText === binding.sourceText
|
|
6789
|
+
)) {
|
|
6790
|
+
continue;
|
|
6791
|
+
}
|
|
6792
|
+
}
|
|
6793
|
+
if (usedProperties && usedProperties.size > 1) {
|
|
6794
|
+
context.report({ node: binding.node, message: scopeUsageMessage(binding.sourceText, usedProperties) });
|
|
6795
|
+
continue;
|
|
6796
|
+
}
|
|
6797
|
+
if (fromSameSource.length > 1) {
|
|
6798
|
+
const names = new Set(fromSameSource.map(({ propertyName: propertyName5 }) => propertyName5));
|
|
6799
|
+
if (names.size > 1) {
|
|
6800
|
+
context.report({ node: binding.node, message: scopeUsageMessage(binding.sourceText, names) });
|
|
6801
|
+
continue;
|
|
6802
|
+
}
|
|
6803
|
+
}
|
|
6804
|
+
context.report({ node: binding.node, message: singlePropertyMessage(binding) });
|
|
6805
|
+
}
|
|
6748
6806
|
};
|
|
6749
6807
|
return {
|
|
6750
6808
|
Program: enterUsageScope,
|
|
@@ -6758,7 +6816,7 @@ ${indentation}`;
|
|
|
6758
6816
|
ArrowFunctionExpression: enterUsageBarrier,
|
|
6759
6817
|
"ArrowFunctionExpression:exit": exitUsageScope,
|
|
6760
6818
|
MemberExpression(node) {
|
|
6761
|
-
recordMemberUsage(context, currentUsageScope(), ownershipResolver, node, isEnumValue);
|
|
6819
|
+
recordMemberUsage(context, currentUsageScope(), ownershipResolver, node, isEnumValue, detachableCall);
|
|
6762
6820
|
},
|
|
6763
6821
|
VariableDeclaration(node) {
|
|
6764
6822
|
for (const declarator of node.declarations) {
|
|
@@ -6774,7 +6832,20 @@ ${indentation}`;
|
|
|
6774
6832
|
const selection = destructuringSelection(context, node, isEnumValue);
|
|
6775
6833
|
if (selection) {
|
|
6776
6834
|
const group = groupedDestructuringSelections(context, selection, isEnumValue);
|
|
6777
|
-
if (group.length <= 1)
|
|
6835
|
+
if (group.length <= 1) {
|
|
6836
|
+
if (node.kind === "const" && selection.propertyNames.length === 1 && supportsSinglePropertySource(selection.source)) {
|
|
6837
|
+
const declarator = node.declarations[0];
|
|
6838
|
+
const propertyName5 = selection.propertyNames[0];
|
|
6839
|
+
if (declarator && propertyName5) {
|
|
6840
|
+
currentUsageScope()?.singleProperties.push({
|
|
6841
|
+
node: declarator.id,
|
|
6842
|
+
sourceText: selection.sourceText,
|
|
6843
|
+
propertyName: propertyName5
|
|
6844
|
+
});
|
|
6845
|
+
}
|
|
6846
|
+
}
|
|
6847
|
+
return;
|
|
6848
|
+
}
|
|
6778
6849
|
for (const item of group.slice(1)) grouped.add(item.declaration);
|
|
6779
6850
|
const lastDeclaration = group.at(-1)?.declaration;
|
|
6780
6851
|
if (!lastDeclaration) return;
|
|
@@ -6841,13 +6912,11 @@ ${indentation}`;
|
|
|
6841
6912
|
}
|
|
6842
6913
|
}
|
|
6843
6914
|
for (const binding of bindings) {
|
|
6844
|
-
if (!
|
|
6845
|
-
|
|
6915
|
+
if (node.kind !== "const" || !supportsSinglePropertySource(binding.source)) continue;
|
|
6916
|
+
currentUsageScope()?.singleProperties.push({
|
|
6846
6917
|
node: binding.declarator,
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
return fixer.replaceText(binding.declarator, `{ ${binding.bindingText} } = ${binding.sourceText}`);
|
|
6850
|
-
}
|
|
6918
|
+
sourceText: binding.sourceText,
|
|
6919
|
+
propertyName: binding.propertyName
|
|
6851
6920
|
});
|
|
6852
6921
|
}
|
|
6853
6922
|
}
|