@blumintinc/eslint-plugin-blumint 1.19.5 → 1.19.6
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/lib/index.js +1 -1
- package/lib/rules/no-redundant-this-params.js +45 -0
- package/package.json +1 -1
- package/release-manifest.json +14 -0
package/lib/index.js
CHANGED
|
@@ -77,8 +77,45 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
|
|
|
77
77
|
}
|
|
78
78
|
return [];
|
|
79
79
|
}
|
|
80
|
+
function isExportedClass(node) {
|
|
81
|
+
const parent = node.parent;
|
|
82
|
+
if (!parent) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if (parent.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration ||
|
|
86
|
+
parent.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
// `export const Foo = class { ... }` exposes the class expression to other
|
|
90
|
+
// files just as an exported declaration does.
|
|
91
|
+
if (node.type === utils_1.AST_NODE_TYPES.ClassExpression &&
|
|
92
|
+
parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator) {
|
|
93
|
+
const declaration = parent.parent;
|
|
94
|
+
const exportNode = declaration?.parent;
|
|
95
|
+
return (exportNode?.type === utils_1.AST_NODE_TYPES.ExportNamedDeclaration ||
|
|
96
|
+
exportNode?.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration);
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
80
100
|
function collectClassInfo(node) {
|
|
81
101
|
const methods = new Map();
|
|
102
|
+
// A method's `this.method(...)` call sites are confined to this file only
|
|
103
|
+
// when the class cannot be extended from another file. An `abstract` class
|
|
104
|
+
// exists to be subclassed, and an exported class can be subclassed
|
|
105
|
+
// anywhere; either way subclasses may call an inherited non-private method
|
|
106
|
+
// with a different `this.<member>`, so those methods are externally
|
|
107
|
+
// reachable and must not be reported. See issue #1309.
|
|
108
|
+
const classIsExtensible = Boolean(node.abstract) ||
|
|
109
|
+
isExportedClass(node);
|
|
110
|
+
function computeExternallyReachable(methodName, accessibility) {
|
|
111
|
+
if (!classIsExtensible) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
// `private` (TS) and `#name` (ECMAScript) methods are never inherited,
|
|
115
|
+
// so all of their call sites live in the declaring class body.
|
|
116
|
+
const isPrivate = accessibility === 'private' || methodName.startsWith('#');
|
|
117
|
+
return !isPrivate;
|
|
118
|
+
}
|
|
82
119
|
function setMethod(methodName, meta) {
|
|
83
120
|
/**
|
|
84
121
|
* Prefer instance methods over static methods when names collide.
|
|
@@ -120,6 +157,7 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
|
|
|
120
157
|
params: getMethodParams(member),
|
|
121
158
|
isStatic: Boolean(member.static),
|
|
122
159
|
isAbstract: member.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition,
|
|
160
|
+
externallyReachable: computeExternallyReachable(methodName, member.accessibility),
|
|
123
161
|
});
|
|
124
162
|
}
|
|
125
163
|
else if (member.type === utils_1.AST_NODE_TYPES.PropertyDefinition) {
|
|
@@ -137,6 +175,7 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
|
|
|
137
175
|
params,
|
|
138
176
|
isStatic: false,
|
|
139
177
|
isAbstract: false,
|
|
178
|
+
externallyReachable: computeExternallyReachable(methodName, member.accessibility),
|
|
140
179
|
});
|
|
141
180
|
}
|
|
142
181
|
}
|
|
@@ -432,6 +471,12 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
|
|
|
432
471
|
for (const [, propStats] of argProperties) {
|
|
433
472
|
if (propStats.callsWithProperty === methodStats.totalCalls) {
|
|
434
473
|
for (const violation of propStats.violations) {
|
|
474
|
+
// Skip methods whose call sites are not provably confined to
|
|
475
|
+
// this file: a subclass elsewhere may thread a different
|
|
476
|
+
// `this.<member>` through the same parameter (issue #1309).
|
|
477
|
+
if (violation.methodMeta.externallyReachable) {
|
|
478
|
+
continue;
|
|
479
|
+
}
|
|
435
480
|
reportAccess(methodName, violation.methodMeta, argIndex, violation.access);
|
|
436
481
|
}
|
|
437
482
|
}
|
package/package.json
CHANGED
package/release-manifest.json
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.19.6",
|
|
4
|
+
"date": "2026-07-16T01:27:07.130Z",
|
|
5
|
+
"rules": [
|
|
6
|
+
{
|
|
7
|
+
"name": "no-redundant-this-params",
|
|
8
|
+
"changeType": "fix",
|
|
9
|
+
"issues": [
|
|
10
|
+
1309
|
|
11
|
+
],
|
|
12
|
+
"summary": "skip externally-reachable methods (closes #1309)"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
},
|
|
2
16
|
{
|
|
3
17
|
"version": "1.19.5",
|
|
4
18
|
"date": "2026-07-15T15:24:16.132Z",
|