@@ -9,9 +9,13 @@ import { deepmerge } from "deepmerge-ts";
9
9
import {
10
10
type IgnoreIdentifierPatternOption ,
11
11
type IgnorePrefixSelectorOption ,
12
+ type OverridableOptions ,
13
+ type RawOverridableOptions ,
14
+ getCoreOptions ,
12
15
ignoreIdentifierPatternOptionSchema ,
13
16
ignorePrefixSelectorOptionSchema ,
14
17
shouldIgnorePattern ,
18
+ upgradeRawOverridableOptions ,
15
19
} from "#/options" ;
16
20
import { ruleNameScope } from "#/utils/misc" ;
17
21
import type { ESFunction } from "#/utils/node-types" ;
@@ -21,7 +25,9 @@ import {
21
25
type RuleResult ,
22
26
createRuleUsingFunction ,
23
27
} from "#/utils/rule" ;
28
+ import { overridableOptionsSchema } from "#/utils/schemas" ;
24
29
import {
30
+ getEnclosingFunction ,
25
31
isArgument ,
26
32
isGetter ,
27
33
isIIFE ,
@@ -46,83 +52,82 @@ export const fullName: `${typeof ruleNameScope}/${typeof name}` = `${ruleNameSco
46
52
*/
47
53
type ParameterCountOptions = "atLeastOne" | "exactlyOne" ;
48
54
55
+ type CoreOptions = IgnoreIdentifierPatternOption &
56
+ IgnorePrefixSelectorOption & {
57
+ allowRestParameter : boolean ;
58
+ allowArgumentsKeyword : boolean ;
59
+ enforceParameterCount :
60
+ | ParameterCountOptions
61
+ | false
62
+ | {
63
+ count : ParameterCountOptions ;
64
+ ignoreLambdaExpression : boolean ;
65
+ ignoreIIFE : boolean ;
66
+ ignoreGettersAndSetters : boolean ;
67
+ } ;
68
+ } ;
69
+
49
70
/**
50
71
* The options this rule can take.
51
72
*/
52
- type Options = [
53
- IgnoreIdentifierPatternOption &
54
- IgnorePrefixSelectorOption & {
55
- allowRestParameter : boolean ;
56
- allowArgumentsKeyword : boolean ;
57
- enforceParameterCount :
58
- | ParameterCountOptions
59
- | false
60
- | {
61
- count : ParameterCountOptions ;
62
- ignoreLambdaExpression : boolean ;
63
- ignoreIIFE : boolean ;
64
- ignoreGettersAndSetters : boolean ;
65
- } ;
66
- } ,
67
- ] ;
73
+ type RawOptions = [ RawOverridableOptions < CoreOptions > ] ;
74
+ type Options = OverridableOptions < CoreOptions > ;
68
75
69
- /**
70
- * The schema for the rule options.
71
- */
72
- const schema : JSONSchema4 [ ] = [
76
+ const coreOptionsPropertiesSchema = deepmerge (
77
+ ignoreIdentifierPatternOptionSchema ,
78
+ ignorePrefixSelectorOptionSchema ,
73
79
{
74
- type : "object" ,
75
- properties : deepmerge (
76
- ignoreIdentifierPatternOptionSchema ,
77
- ignorePrefixSelectorOptionSchema ,
78
- {
79
- allowRestParameter : {
80
+ allowRestParameter : {
81
+ type : "boolean" ,
82
+ } ,
83
+ allowArgumentsKeyword : {
84
+ type : "boolean" ,
85
+ } ,
86
+ enforceParameterCount : {
87
+ oneOf : [
88
+ {
80
89
type : "boolean" ,
90
+ enum : [ false ] ,
81
91
} ,
82
- allowArgumentsKeyword : {
83
- type : "boolean" ,
92
+ {
93
+ type : "string" ,
94
+ enum : [ "atLeastOne" , "exactlyOne" ] ,
84
95
} ,
85
- enforceParameterCount : {
86
- oneOf : [
87
- {
88
- type : "boolean" ,
89
- enum : [ false ] ,
90
- } ,
91
- {
96
+ {
97
+ type : "object" ,
98
+ properties : {
99
+ count : {
92
100
type : "string" ,
93
101
enum : [ "atLeastOne" , "exactlyOne" ] ,
94
102
} ,
95
- {
96
- type : "object" ,
97
- properties : {
98
- count : {
99
- type : "string" ,
100
- enum : [ "atLeastOne" , "exactlyOne" ] ,
101
- } ,
102
- ignoreGettersAndSetters : {
103
- type : "boolean" ,
104
- } ,
105
- ignoreLambdaExpression : {
106
- type : "boolean" ,
107
- } ,
108
- ignoreIIFE : {
109
- type : "boolean" ,
110
- } ,
111
- } ,
112
- additionalProperties : false ,
103
+ ignoreGettersAndSetters : {
104
+ type : "boolean" ,
105
+ } ,
106
+ ignoreLambdaExpression : {
107
+ type : "boolean" ,
108
+ } ,
109
+ ignoreIIFE : {
110
+ type : "boolean" ,
113
111
} ,
114
- ] ,
112
+ } ,
113
+ additionalProperties : false ,
115
114
} ,
116
- } satisfies JSONSchema4ObjectSchema [ "properties" ] ,
117
- ) ,
118
- additionalProperties : false ,
115
+ ] ,
116
+ } ,
119
117
} ,
118
+ ) as NonNullable < JSONSchema4ObjectSchema [ "properties" ] > ;
119
+
120
+ /**
121
+ * The schema for the rule options.
122
+ */
123
+ const schema : JSONSchema4 [ ] = [
124
+ overridableOptionsSchema ( coreOptionsPropertiesSchema ) ,
120
125
] ;
121
126
122
127
/**
123
128
* The default options for the rule.
124
129
*/
125
- const defaultOptions : Options = [
130
+ const defaultOptions : RawOptions = [
126
131
{
127
132
allowRestParameter : false ,
128
133
allowArgumentsKeyword : false ,
@@ -157,7 +162,7 @@ const meta: NamedCreateRuleCustomMeta<keyof typeof errorMessages> = {
157
162
description : "Enforce functional parameters." ,
158
163
recommended : "recommended" ,
159
164
recommendedSeverity : "error" ,
160
- requiresTypeChecking : false ,
165
+ requiresTypeChecking : true ,
161
166
} ,
162
167
messages : errorMessages ,
163
168
schema,
@@ -167,9 +172,9 @@ const meta: NamedCreateRuleCustomMeta<keyof typeof errorMessages> = {
167
172
* Get the rest parameter violations.
168
173
*/
169
174
function getRestParamViolations (
170
- [ { allowRestParameter } ] : Readonly < Options > ,
175
+ { allowRestParameter } : Readonly < CoreOptions > ,
171
176
node : ESFunction ,
172
- ) : RuleResult < keyof typeof errorMessages , Options > [ "descriptors" ] {
177
+ ) : RuleResult < keyof typeof errorMessages , RawOptions > [ "descriptors" ] {
173
178
return ! allowRestParameter &&
174
179
node . params . length > 0 &&
175
180
isRestElement ( node . params . at ( - 1 ) )
@@ -186,9 +191,9 @@ function getRestParamViolations(
186
191
* Get the parameter count violations.
187
192
*/
188
193
function getParamCountViolations (
189
- [ { enforceParameterCount } ] : Readonly < Options > ,
194
+ { enforceParameterCount } : Readonly < CoreOptions > ,
190
195
node : ESFunction ,
191
- ) : RuleResult < keyof typeof errorMessages , Options > [ "descriptors" ] {
196
+ ) : RuleResult < keyof typeof errorMessages , RawOptions > [ "descriptors" ] {
192
197
if (
193
198
enforceParameterCount === false ||
194
199
( node . params . length === 0 &&
@@ -234,11 +239,24 @@ function getParamCountViolations(
234
239
*/
235
240
function checkFunction (
236
241
node : ESFunction ,
237
- context : Readonly < RuleContext < keyof typeof errorMessages , Options > > ,
238
- options : Readonly < Options > ,
239
- ) : RuleResult < keyof typeof errorMessages , Options > {
240
- const [ optionsObject ] = options ;
241
- const { ignoreIdentifierPattern } = optionsObject ;
242
+ context : Readonly < RuleContext < keyof typeof errorMessages , RawOptions > > ,
243
+ rawOptions : Readonly < RawOptions > ,
244
+ ) : RuleResult < keyof typeof errorMessages , RawOptions > {
245
+ const options = upgradeRawOverridableOptions ( rawOptions [ 0 ] ) ;
246
+ const optionsToUse = getCoreOptions < CoreOptions , Options > (
247
+ node ,
248
+ context ,
249
+ options ,
250
+ ) ;
251
+
252
+ if ( optionsToUse === null ) {
253
+ return {
254
+ context,
255
+ descriptors : [ ] ,
256
+ } ;
257
+ }
258
+
259
+ const { ignoreIdentifierPattern } = optionsToUse ;
242
260
243
261
if ( shouldIgnorePattern ( node , context , ignoreIdentifierPattern ) ) {
244
262
return {
@@ -250,8 +268,8 @@ function checkFunction(
250
268
return {
251
269
context,
252
270
descriptors : [
253
- ...getRestParamViolations ( options , node ) ,
254
- ...getParamCountViolations ( options , node ) ,
271
+ ...getRestParamViolations ( optionsToUse , node ) ,
272
+ ...getParamCountViolations ( optionsToUse , node ) ,
255
273
] ,
256
274
} ;
257
275
}
@@ -261,11 +279,31 @@ function checkFunction(
261
279
*/
262
280
function checkIdentifier (
263
281
node : TSESTree . Identifier ,
264
- context : Readonly < RuleContext < keyof typeof errorMessages , Options > > ,
265
- options : Readonly < Options > ,
266
- ) : RuleResult < keyof typeof errorMessages , Options > {
267
- const [ optionsObject ] = options ;
268
- const { ignoreIdentifierPattern } = optionsObject ;
282
+ context : Readonly < RuleContext < keyof typeof errorMessages , RawOptions > > ,
283
+ rawOptions : Readonly < RawOptions > ,
284
+ ) : RuleResult < keyof typeof errorMessages , RawOptions > {
285
+ if ( node . name !== "arguments" ) {
286
+ return {
287
+ context,
288
+ descriptors : [ ] ,
289
+ } ;
290
+ }
291
+
292
+ const functionNode = getEnclosingFunction ( node ) ;
293
+ const options = upgradeRawOverridableOptions ( rawOptions [ 0 ] ) ;
294
+ const optionsToUse =
295
+ functionNode === null
296
+ ? options
297
+ : getCoreOptions < CoreOptions , Options > ( functionNode , context , options ) ;
298
+
299
+ if ( optionsToUse === null ) {
300
+ return {
301
+ context,
302
+ descriptors : [ ] ,
303
+ } ;
304
+ }
305
+
306
+ const { ignoreIdentifierPattern } = optionsToUse ;
269
307
270
308
if ( shouldIgnorePattern ( node , context , ignoreIdentifierPattern ) ) {
271
309
return {
@@ -274,15 +312,12 @@ function checkIdentifier(
274
312
} ;
275
313
}
276
314
277
- const { allowArgumentsKeyword } = optionsObject ;
315
+ const { allowArgumentsKeyword } = optionsToUse ;
278
316
279
317
return {
280
318
context,
281
319
descriptors :
282
- ! allowArgumentsKeyword &&
283
- node . name === "arguments" &&
284
- ! isPropertyName ( node ) &&
285
- ! isPropertyAccess ( node )
320
+ ! allowArgumentsKeyword && ! isPropertyName ( node ) && ! isPropertyAccess ( node )
286
321
? [
287
322
{
288
323
node,
@@ -294,8 +329,8 @@ function checkIdentifier(
294
329
}
295
330
296
331
// Create the rule.
297
- export const rule : Rule < keyof typeof errorMessages , Options > =
298
- createRuleUsingFunction < keyof typeof errorMessages , Options > (
332
+ export const rule : Rule < keyof typeof errorMessages , RawOptions > =
333
+ createRuleUsingFunction < keyof typeof errorMessages , RawOptions > (
299
334
name ,
300
335
meta ,
301
336
defaultOptions ,
0 commit comments