@@ -9,6 +9,8 @@ import { deepmerge } from "deepmerge-ts";
9
9
import {
10
10
type IgnoreIdentifierPatternOption ,
11
11
type IgnorePrefixSelectorOption ,
12
+ type OverridableOptions ,
13
+ getCoreOptions ,
12
14
ignoreIdentifierPatternOptionSchema ,
13
15
ignorePrefixSelectorOptionSchema ,
14
16
shouldIgnorePattern ,
@@ -20,7 +22,9 @@ import {
20
22
type RuleResult ,
21
23
createRuleUsingFunction ,
22
24
} from "#eslint-plugin-functional/utils/rule" ;
25
+ import { overridableOptionsSchema } from "#eslint-plugin-functional/utils/schemas" ;
23
26
import {
27
+ getEnclosingFunction ,
24
28
isArgument ,
25
29
isGetter ,
26
30
isIIFE ,
@@ -45,77 +49,75 @@ export const fullName = `${ruleNameScope}/${name}`;
45
49
*/
46
50
type ParameterCountOptions = "atLeastOne" | "exactlyOne" ;
47
51
52
+ type CoreOptions = 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
+
48
67
/**
49
68
* The options this rule can take.
50
69
*/
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
- ] ;
70
+ type Options = [ OverridableOptions < CoreOptions > ] ;
67
71
68
- /**
69
- * The schema for the rule options.
70
- */
71
- const schema : JSONSchema4 [ ] = [
72
+ const coreOptionsPropertiesSchema = deepmerge (
73
+ ignoreIdentifierPatternOptionSchema ,
74
+ ignorePrefixSelectorOptionSchema ,
72
75
{
73
- type : "object" ,
74
- properties : deepmerge (
75
- ignoreIdentifierPatternOptionSchema ,
76
- ignorePrefixSelectorOptionSchema ,
77
- {
78
- allowRestParameter : {
76
+ allowRestParameter : {
77
+ type : "boolean" ,
78
+ } ,
79
+ allowArgumentsKeyword : {
80
+ type : "boolean" ,
81
+ } ,
82
+ enforceParameterCount : {
83
+ oneOf : [
84
+ {
79
85
type : "boolean" ,
86
+ enum : [ false ] ,
80
87
} ,
81
- allowArgumentsKeyword : {
82
- type : "boolean" ,
88
+ {
89
+ type : "string" ,
90
+ enum : [ "atLeastOne" , "exactlyOne" ] ,
83
91
} ,
84
- enforceParameterCount : {
85
- oneOf : [
86
- {
87
- type : "boolean" ,
88
- enum : [ false ] ,
89
- } ,
90
- {
92
+ {
93
+ type : "object" ,
94
+ properties : {
95
+ count : {
91
96
type : "string" ,
92
97
enum : [ "atLeastOne" , "exactlyOne" ] ,
93
98
} ,
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 ,
99
+ ignoreGettersAndSetters : {
100
+ type : "boolean" ,
101
+ } ,
102
+ ignoreLambdaExpression : {
103
+ type : "boolean" ,
112
104
} ,
113
- ] ,
105
+ ignoreIIFE : {
106
+ type : "boolean" ,
107
+ } ,
108
+ } ,
109
+ additionalProperties : false ,
114
110
} ,
115
- } satisfies JSONSchema4ObjectSchema [ "properties" ] ,
116
- ) ,
117
- additionalProperties : false ,
111
+ ] ,
112
+ } ,
118
113
} ,
114
+ ) as NonNullable < JSONSchema4ObjectSchema [ "properties" ] > ;
115
+
116
+ /**
117
+ * The schema for the rule options.
118
+ */
119
+ const schema : JSONSchema4 [ ] = [
120
+ overridableOptionsSchema ( coreOptionsPropertiesSchema ) ,
119
121
] ;
120
122
121
123
/**
@@ -156,6 +158,7 @@ const meta: NamedCreateRuleCustomMeta<keyof typeof errorMessages, Options> = {
156
158
description : "Enforce functional parameters." ,
157
159
recommended : "recommended" ,
158
160
recommendedSeverity : "error" ,
161
+ requiresTypeChecking : true ,
159
162
} ,
160
163
messages : errorMessages ,
161
164
schema,
@@ -165,7 +168,7 @@ const meta: NamedCreateRuleCustomMeta<keyof typeof errorMessages, Options> = {
165
168
* Get the rest parameter violations.
166
169
*/
167
170
function getRestParamViolations (
168
- [ { allowRestParameter } ] : Readonly < Options > ,
171
+ { allowRestParameter } : Readonly < CoreOptions > ,
169
172
node : ESFunction ,
170
173
) : RuleResult < keyof typeof errorMessages , Options > [ "descriptors" ] {
171
174
return ! allowRestParameter &&
@@ -184,7 +187,7 @@ function getRestParamViolations(
184
187
* Get the parameter count violations.
185
188
*/
186
189
function getParamCountViolations (
187
- [ { enforceParameterCount } ] : Readonly < Options > ,
190
+ { enforceParameterCount } : Readonly < CoreOptions > ,
188
191
node : ESFunction ,
189
192
) : RuleResult < keyof typeof errorMessages , Options > [ "descriptors" ] {
190
193
if (
@@ -235,8 +238,20 @@ function checkFunction(
235
238
context : Readonly < RuleContext < keyof typeof errorMessages , Options > > ,
236
239
options : Readonly < Options > ,
237
240
) : RuleResult < keyof typeof errorMessages , Options > {
238
- const [ optionsObject ] = options ;
239
- const { ignoreIdentifierPattern } = optionsObject ;
241
+ const optionsToUse = getCoreOptions < CoreOptions , Options > (
242
+ node ,
243
+ context ,
244
+ options ,
245
+ ) ;
246
+
247
+ if ( optionsToUse === null ) {
248
+ return {
249
+ context,
250
+ descriptors : [ ] ,
251
+ } ;
252
+ }
253
+
254
+ const { ignoreIdentifierPattern } = optionsToUse ;
240
255
241
256
if ( shouldIgnorePattern ( node , context , ignoreIdentifierPattern ) ) {
242
257
return {
@@ -248,8 +263,8 @@ function checkFunction(
248
263
return {
249
264
context,
250
265
descriptors : [
251
- ...getRestParamViolations ( options , node ) ,
252
- ...getParamCountViolations ( options , node ) ,
266
+ ...getRestParamViolations ( optionsToUse , node ) ,
267
+ ...getParamCountViolations ( optionsToUse , node ) ,
253
268
] ,
254
269
} ;
255
270
}
@@ -262,8 +277,27 @@ function checkIdentifier(
262
277
context : Readonly < RuleContext < keyof typeof errorMessages , Options > > ,
263
278
options : Readonly < Options > ,
264
279
) : RuleResult < keyof typeof errorMessages , Options > {
265
- const [ optionsObject ] = options ;
266
- const { ignoreIdentifierPattern } = optionsObject ;
280
+ if ( node . name !== "arguments" ) {
281
+ return {
282
+ context,
283
+ descriptors : [ ] ,
284
+ } ;
285
+ }
286
+
287
+ const functionNode = getEnclosingFunction ( node ) ;
288
+ const optionsToUse =
289
+ functionNode === null
290
+ ? options [ 0 ]
291
+ : getCoreOptions < CoreOptions , Options > ( functionNode , context , options ) ;
292
+
293
+ if ( optionsToUse === null ) {
294
+ return {
295
+ context,
296
+ descriptors : [ ] ,
297
+ } ;
298
+ }
299
+
300
+ const { ignoreIdentifierPattern } = optionsToUse ;
267
301
268
302
if ( shouldIgnorePattern ( node , context , ignoreIdentifierPattern ) ) {
269
303
return {
@@ -272,15 +306,12 @@ function checkIdentifier(
272
306
} ;
273
307
}
274
308
275
- const { allowArgumentsKeyword } = optionsObject ;
309
+ const { allowArgumentsKeyword } = optionsToUse ;
276
310
277
311
return {
278
312
context,
279
313
descriptors :
280
- ! allowArgumentsKeyword &&
281
- node . name === "arguments" &&
282
- ! isPropertyName ( node ) &&
283
- ! isPropertyAccess ( node )
314
+ ! allowArgumentsKeyword && ! isPropertyName ( node ) && ! isPropertyAccess ( node )
284
315
? [
285
316
{
286
317
node,
0 commit comments