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