@blumintinc/eslint-plugin-blumint 1.19.4 → 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 +53 -1
- package/package.json +1 -1
- package/release-manifest.json +28 -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.
|
|
@@ -102,7 +139,14 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
|
|
|
102
139
|
for (const member of node.body.body) {
|
|
103
140
|
if (member.type === utils_1.AST_NODE_TYPES.MethodDefinition ||
|
|
104
141
|
member.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition) {
|
|
105
|
-
|
|
142
|
+
// Only genuine methods (`kind: 'method'`) are invoked directly as
|
|
143
|
+
// `this.x(args)`. A `get`/`set` accessor is also a MethodDefinition,
|
|
144
|
+
// but `this.accessor(args)` evaluates the accessor with zero arguments
|
|
145
|
+
// and then calls its RETURN VALUE — so when that value is an
|
|
146
|
+
// externally-supplied function it legitimately needs instance state
|
|
147
|
+
// threaded in, and flagging it is a false positive (issue #1308). The
|
|
148
|
+
// constructor is likewise never called as `this.constructor(...)`.
|
|
149
|
+
if (member.kind !== 'method') {
|
|
106
150
|
continue;
|
|
107
151
|
}
|
|
108
152
|
const methodName = getNameFromPropertyName(member.key);
|
|
@@ -113,6 +157,7 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
|
|
|
113
157
|
params: getMethodParams(member),
|
|
114
158
|
isStatic: Boolean(member.static),
|
|
115
159
|
isAbstract: member.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition,
|
|
160
|
+
externallyReachable: computeExternallyReachable(methodName, member.accessibility),
|
|
116
161
|
});
|
|
117
162
|
}
|
|
118
163
|
else if (member.type === utils_1.AST_NODE_TYPES.PropertyDefinition) {
|
|
@@ -130,6 +175,7 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
|
|
|
130
175
|
params,
|
|
131
176
|
isStatic: false,
|
|
132
177
|
isAbstract: false,
|
|
178
|
+
externallyReachable: computeExternallyReachable(methodName, member.accessibility),
|
|
133
179
|
});
|
|
134
180
|
}
|
|
135
181
|
}
|
|
@@ -425,6 +471,12 @@ exports.noRedundantThisParams = (0, createRule_1.createRule)({
|
|
|
425
471
|
for (const [, propStats] of argProperties) {
|
|
426
472
|
if (propStats.callsWithProperty === methodStats.totalCalls) {
|
|
427
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
|
+
}
|
|
428
480
|
reportAccess(methodName, violation.methodMeta, argIndex, violation.access);
|
|
429
481
|
}
|
|
430
482
|
}
|
package/package.json
CHANGED
package/release-manifest.json
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
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
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"version": "1.19.5",
|
|
18
|
+
"date": "2026-07-15T15:24:16.132Z",
|
|
19
|
+
"rules": [
|
|
20
|
+
{
|
|
21
|
+
"name": "no-redundant-this-params",
|
|
22
|
+
"changeType": "fix",
|
|
23
|
+
"issues": [
|
|
24
|
+
1308
|
|
25
|
+
],
|
|
26
|
+
"summary": "skip get/set accessors when resolving callees (closes #1308)"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
},
|
|
2
30
|
{
|
|
3
31
|
"version": "1.19.4",
|
|
4
32
|
"date": "2026-07-14T18:24:36.895Z",
|