eslint-plugin-th-rules 3.6.0 → 3.6.1
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/plugin.d.ts
CHANGED
|
@@ -11,10 +11,9 @@ export declare const rules: {
|
|
|
11
11
|
'no-default-export': import("@typescript-eslint/utils/ts-eslint").RuleModule<"unnamed", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
12
12
|
name: string;
|
|
13
13
|
};
|
|
14
|
-
'no-destructuring': import("@typescript-eslint/utils/ts-eslint").RuleModule<"tooDeep" | "tooMany" | "tooLong" | "tooManyCumulative"
|
|
14
|
+
'no-destructuring': import("@typescript-eslint/utils/ts-eslint").RuleModule<"tooDeep" | "tooMany" | "tooLong" | "tooManyCumulative", [{
|
|
15
15
|
maximumDestructuredVariables?: number;
|
|
16
16
|
maximumLineLength?: number;
|
|
17
|
-
directAccessIdentifiers?: string[];
|
|
18
17
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
19
18
|
name: string;
|
|
20
19
|
};
|
|
@@ -64,10 +63,9 @@ declare const plugin: {
|
|
|
64
63
|
'no-default-export': import("@typescript-eslint/utils/ts-eslint").RuleModule<"unnamed", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
65
64
|
name: string;
|
|
66
65
|
};
|
|
67
|
-
'no-destructuring': import("@typescript-eslint/utils/ts-eslint").RuleModule<"tooDeep" | "tooMany" | "tooLong" | "tooManyCumulative"
|
|
66
|
+
'no-destructuring': import("@typescript-eslint/utils/ts-eslint").RuleModule<"tooDeep" | "tooMany" | "tooLong" | "tooManyCumulative", [{
|
|
68
67
|
maximumDestructuredVariables?: number;
|
|
69
68
|
maximumLineLength?: number;
|
|
70
|
-
directAccessIdentifiers?: string[];
|
|
71
69
|
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
72
70
|
name: string;
|
|
73
71
|
};
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,KAAK
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAajB,CAAC;AAEF,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAY,CAAC;AACzB,eAAe,MAAM,CAAC"}
|
|
@@ -3,10 +3,9 @@ type Options = [
|
|
|
3
3
|
{
|
|
4
4
|
maximumDestructuredVariables?: number;
|
|
5
5
|
maximumLineLength?: number;
|
|
6
|
-
directAccessIdentifiers?: string[];
|
|
7
6
|
}
|
|
8
7
|
];
|
|
9
|
-
type MessageIds = 'tooDeep' | 'tooMany' | 'tooLong' | 'tooManyCumulative'
|
|
8
|
+
type MessageIds = 'tooDeep' | 'tooMany' | 'tooLong' | 'tooManyCumulative';
|
|
10
9
|
declare const noDestructuring: ESLintUtils.RuleModule<MessageIds, Options, unknown, ESLintUtils.RuleListener> & {
|
|
11
10
|
name: string;
|
|
12
11
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-destructuring.d.ts","sourceRoot":"","sources":["../../src/rules/no-destructuring.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAItF,KAAK,OAAO,GAAG;IACd;QACC,4BAA4B,CAAC,EAAE,MAAM,CAAC;QACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"no-destructuring.d.ts","sourceRoot":"","sources":["../../src/rules/no-destructuring.ts"],"names":[],"mappings":"AAGA,OAAO,EAAkB,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAItF,KAAK,OAAO,GAAG;IACd;QACC,4BAA4B,CAAC,EAAE,MAAM,CAAC;QACtC,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC3B;CACD,CAAC;AAEF,KAAK,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,mBAAmB,CAAC;AAE1E,QAAA,MAAM,eAAe;;CA+NnB,CAAC;AAEH,eAAe,eAAe,CAAC"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/* eslint-disable new-cap */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
3
|
import _ from 'lodash';
|
|
3
4
|
import { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';
|
|
4
|
-
const
|
|
5
|
+
const MAX_TAB_COUNT = 3;
|
|
5
6
|
const noDestructuring = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh2001/eslint-plugin-th-rules/blob/main/docs/rules/no-destructuring.md')({
|
|
6
7
|
name: 'no-destructuring',
|
|
7
8
|
meta: {
|
|
@@ -15,51 +16,48 @@ const noDestructuring = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh
|
|
|
15
16
|
properties: {
|
|
16
17
|
maximumDestructuredVariables: { type: 'integer', minimum: 0 },
|
|
17
18
|
maximumLineLength: { type: 'integer', minimum: 0 },
|
|
18
|
-
directAccessIdentifiers: {
|
|
19
|
-
type: 'array',
|
|
20
|
-
items: { type: 'string', minLength: 1 },
|
|
21
|
-
},
|
|
22
19
|
},
|
|
23
20
|
additionalProperties: false,
|
|
24
21
|
},
|
|
25
22
|
],
|
|
26
23
|
messages: {
|
|
27
|
-
tooDeep: 'Destructuring at
|
|
24
|
+
tooDeep: 'Destructuring at a nesting level above {{max}} is not allowed; found {{actual}} levels of nesting.',
|
|
28
25
|
tooMany: 'Destructuring of more than {{max}} variables is not allowed.',
|
|
29
26
|
tooLong: 'Destructuring spanning a line exceeding {{max}} characters is not allowed.',
|
|
30
|
-
tooManyCumulative: '
|
|
31
|
-
directAccessRequired: 'Do not destructure from "{{identifier}}". Use direct member access, for example {{identifier}}.onChangeText.',
|
|
27
|
+
tooManyCumulative: 'Destructuring of more than {{max}} variables from "{{source}}" in the same scope is not allowed; found {{total}}.',
|
|
32
28
|
},
|
|
33
29
|
},
|
|
34
30
|
defaultOptions: [
|
|
35
31
|
{
|
|
36
32
|
maximumDestructuredVariables: 2,
|
|
37
33
|
maximumLineLength: 100,
|
|
38
|
-
directAccessIdentifiers: ['properties'],
|
|
39
34
|
},
|
|
40
35
|
],
|
|
41
36
|
create(context, [options]) {
|
|
42
37
|
const maxVariables = options.maximumDestructuredVariables ?? 2;
|
|
43
38
|
const maxLineLength = options.maximumLineLength ?? 100;
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Tracks total destructured properties per initializer expression text per scope node.
|
|
41
|
+
* WeakMap is used so scopes can be GC'ed and we do not leak memory across files.
|
|
42
|
+
*/
|
|
43
|
+
const totalsByScope = new WeakMap();
|
|
46
44
|
function getLineText(lineNumber) {
|
|
47
45
|
return context.sourceCode.lines[lineNumber - 1] ?? '';
|
|
48
46
|
}
|
|
49
|
-
function getIndentSpacesForLine(lineNumber) {
|
|
50
|
-
const lineText = getLineText(lineNumber);
|
|
51
|
-
return lineText.search(/\S|$/);
|
|
52
|
-
}
|
|
53
47
|
function getMaxSpannedLineLength(startLine, endLine) {
|
|
54
48
|
let max = 0;
|
|
55
49
|
for (let i = startLine; i <= endLine; i++) {
|
|
56
|
-
const
|
|
57
|
-
if (
|
|
58
|
-
max =
|
|
50
|
+
const line = getLineText(i);
|
|
51
|
+
if (line.length > max) {
|
|
52
|
+
max = line.length;
|
|
59
53
|
}
|
|
60
54
|
}
|
|
61
55
|
return max;
|
|
62
56
|
}
|
|
57
|
+
function getIndentCountForLine(lineNumber) {
|
|
58
|
+
const lineText = getLineText(lineNumber);
|
|
59
|
+
return lineText.search(/\S|$/);
|
|
60
|
+
}
|
|
63
61
|
function getScopeNode(node) {
|
|
64
62
|
const ancestors = context.sourceCode.getAncestors(node);
|
|
65
63
|
for (let i = ancestors.length - 1; i >= 0; i--) {
|
|
@@ -74,78 +72,52 @@ const noDestructuring = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh
|
|
|
74
72
|
}
|
|
75
73
|
return context.sourceCode.ast;
|
|
76
74
|
}
|
|
77
|
-
function
|
|
78
|
-
const existing =
|
|
75
|
+
function getScopeMap(scopeNode) {
|
|
76
|
+
const existing = totalsByScope.get(scopeNode);
|
|
79
77
|
if (!_.isNil(existing)) {
|
|
80
78
|
return existing;
|
|
81
79
|
}
|
|
82
80
|
const created = new Map();
|
|
83
|
-
|
|
81
|
+
totalsByScope.set(scopeNode, created);
|
|
84
82
|
return created;
|
|
85
83
|
}
|
|
86
|
-
function
|
|
87
|
-
if (_.isNil(init)) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
return init.type === AST_NODE_TYPES.Identifier && directAccessIdentifiers.has(init.name);
|
|
91
|
-
}
|
|
92
|
-
function reportIfNeeded(patternNode, reportNode, initExpression) {
|
|
84
|
+
function reportIfNeeded(patternNode, reportNode = patternNode) {
|
|
93
85
|
if (patternNode?.type !== AST_NODE_TYPES.ObjectPattern || _.isNil(patternNode.loc)) {
|
|
94
86
|
return;
|
|
95
87
|
}
|
|
96
|
-
if (isDirectAccessForbiddenInitializer(initExpression)) {
|
|
97
|
-
context.report({
|
|
98
|
-
node: reportNode,
|
|
99
|
-
messageId: 'directAccessRequired',
|
|
100
|
-
data: { identifier: initExpression.name },
|
|
101
|
-
});
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
88
|
const startLine = patternNode.loc.start.line;
|
|
105
89
|
const endLine = patternNode.loc.end.line;
|
|
106
|
-
const
|
|
90
|
+
const indentCount = getIndentCountForLine(startLine);
|
|
107
91
|
const propertyCount = patternNode.properties?.length ?? 0;
|
|
108
92
|
const maxSpannedLineLength = getMaxSpannedLineLength(startLine, endLine);
|
|
109
|
-
if (
|
|
93
|
+
if (indentCount > MAX_TAB_COUNT) {
|
|
110
94
|
context.report({
|
|
111
95
|
node: reportNode,
|
|
112
96
|
messageId: 'tooDeep',
|
|
113
|
-
data: {
|
|
97
|
+
data: {
|
|
98
|
+
max: MAX_TAB_COUNT,
|
|
99
|
+
actual: indentCount,
|
|
100
|
+
},
|
|
114
101
|
});
|
|
115
102
|
}
|
|
116
103
|
if (propertyCount > maxVariables) {
|
|
117
104
|
context.report({
|
|
118
105
|
node: reportNode,
|
|
119
106
|
messageId: 'tooMany',
|
|
120
|
-
data: {
|
|
107
|
+
data: {
|
|
108
|
+
max: maxVariables,
|
|
109
|
+
},
|
|
121
110
|
});
|
|
122
111
|
}
|
|
123
112
|
if (maxSpannedLineLength > maxLineLength) {
|
|
124
113
|
context.report({
|
|
125
114
|
node: reportNode,
|
|
126
115
|
messageId: 'tooLong',
|
|
127
|
-
data: {
|
|
116
|
+
data: {
|
|
117
|
+
max: maxLineLength,
|
|
118
|
+
},
|
|
128
119
|
});
|
|
129
120
|
}
|
|
130
|
-
if (!_.isNil(initExpression)) {
|
|
131
|
-
const scopeNode = getScopeNode(reportNode);
|
|
132
|
-
const scopeMap = getOrCreateScopeMap(scopeNode);
|
|
133
|
-
const sourceText = context.sourceCode.getText(initExpression);
|
|
134
|
-
const previousTotal = scopeMap.get(sourceText) ?? 0;
|
|
135
|
-
const newTotal = previousTotal + propertyCount;
|
|
136
|
-
scopeMap.set(sourceText, newTotal);
|
|
137
|
-
if (newTotal > maxVariables) {
|
|
138
|
-
context.report({
|
|
139
|
-
node: reportNode,
|
|
140
|
-
messageId: 'tooManyCumulative',
|
|
141
|
-
data: {
|
|
142
|
-
source: sourceText,
|
|
143
|
-
max: maxVariables,
|
|
144
|
-
total: newTotal,
|
|
145
|
-
},
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
121
|
}
|
|
150
122
|
function checkParameters(parameters) {
|
|
151
123
|
for (const p of parameters || []) {
|
|
@@ -153,15 +125,45 @@ const noDestructuring = ESLintUtils.RuleCreator(() => 'https://github.com/tomerh
|
|
|
153
125
|
continue;
|
|
154
126
|
}
|
|
155
127
|
if (p.type === AST_NODE_TYPES.AssignmentPattern) {
|
|
156
|
-
reportIfNeeded(p.left, p
|
|
128
|
+
reportIfNeeded(p.left, p);
|
|
157
129
|
continue;
|
|
158
130
|
}
|
|
159
|
-
reportIfNeeded(p, p
|
|
131
|
+
reportIfNeeded(p, p);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function checkCumulativeVariableDeclarator(node) {
|
|
135
|
+
if (node.id.type !== AST_NODE_TYPES.ObjectPattern) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (_.isNil(node.init)) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const propertyCount = node.id.properties?.length ?? 0;
|
|
142
|
+
if (propertyCount > maxVariables) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
const scopeNode = getScopeNode(node);
|
|
146
|
+
const scopeMap = getScopeMap(scopeNode);
|
|
147
|
+
const sourceText = context.sourceCode.getText(node.init);
|
|
148
|
+
const previousTotal = scopeMap.get(sourceText) ?? 0;
|
|
149
|
+
const newTotal = previousTotal + propertyCount;
|
|
150
|
+
scopeMap.set(sourceText, newTotal);
|
|
151
|
+
if (previousTotal > 0 && newTotal > maxVariables) {
|
|
152
|
+
context.report({
|
|
153
|
+
node,
|
|
154
|
+
messageId: 'tooManyCumulative',
|
|
155
|
+
data: {
|
|
156
|
+
source: sourceText,
|
|
157
|
+
max: maxVariables,
|
|
158
|
+
total: newTotal,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
160
161
|
}
|
|
161
162
|
}
|
|
162
163
|
return {
|
|
163
164
|
VariableDeclarator(node) {
|
|
164
|
-
reportIfNeeded(node.id, node
|
|
165
|
+
reportIfNeeded(node.id, node);
|
|
166
|
+
checkCumulativeVariableDeclarator(node);
|
|
165
167
|
},
|
|
166
168
|
FunctionDeclaration(node) {
|
|
167
169
|
checkParameters(node.params);
|