Skip to content

Commit

Permalink
feat(functional-parameters): add option to ignore lambda function exp…
Browse files Browse the repository at this point in the history
…ressions
  • Loading branch information
RebeccaStevens committed Jan 28, 2023
1 parent c0a8699 commit 044e54b
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 3 deletions.
17 changes: 17 additions & 0 deletions docs/rules/functional-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ type Options = {
allowArgumentsKeyword: boolean;
enforceParameterCount: "atLeastOne" | "exactlyOne" | false | {
count: "atLeastOne" | "exactlyOne";
ignoreLambdaExpression: boolean,
ignoreIIFE: boolean;
};
ignorePattern?: string[] | string;
Expand All @@ -68,13 +69,24 @@ const defaults = {
allowArgumentsKeyword: false,
enforceParameterCount: {
count: "atLeastOne",
ignoreLambdaExpression: false,
ignoreIIFE: true
}
}
```

### Preset Overrides

#### `recommended`

```ts
const recommendedOptions = {
enforceParameterCount: {
ignoreLambdaExpression: true,
},
}
```

#### `lite`

```ts
Expand Down Expand Up @@ -133,6 +145,11 @@ See [Currying](https://en.wikipedia.org/wiki/Currying) and [Higher-order functio

See [enforceParameterCount](#enforceparametercount).

### `enforceParameterCount.ignoreLambdaExpression`

If true, this option allows for the use of lambda function expressions that do not have any parameters.
Here, a lambda function expression refers to any function being defined in place as passed directly as an argument to another function.

#### `enforceParameterCount.ignoreIIFE`

If true, this option allows for the use of [IIFEs](https://developer.mozilla.org/en-US/docs/Glossary/IIFE) that do not have any parameters.
Expand Down
7 changes: 7 additions & 0 deletions src/configs/recommended.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { deepmerge } from "deepmerge-ts";
import type { Linter } from "eslint";
import { Immutability } from "is-immutable-type";

import * as functionalParameters from "~/rules/functional-parameters";
import * as noConditionalStatement from "~/rules/no-conditional-statement";
import * as noLet from "~/rules/no-let";
import * as noThrowStatement from "~/rules/no-throw-statement";
Expand All @@ -13,6 +14,12 @@ import strict from "./strict";

const overrides: Linter.Config = {
rules: {
[`functional/${functionalParameters.name}`]: [
"error",
{
enforceParameterCount: { ignoreLambdaExpression: true },
},
],
[`functional/${noConditionalStatement.name}`]: [
"error",
{
Expand Down
16 changes: 13 additions & 3 deletions src/rules/functional-parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ import {
import type { ESFunction } from "~/src/util/node-types";
import type { RuleResult } from "~/util/rule";
import { createRuleUsingFunction } from "~/util/rule";
import { isIIFE, isPropertyAccess, isPropertyName } from "~/util/tree";
import {
isArgument,
isIIFE,
isPropertyAccess,
isPropertyName,
} from "~/util/tree";
import { isRestElement } from "~/util/typeguard";

/**
Expand All @@ -42,6 +47,7 @@ type Options = readonly [
| false
| Readonly<{
count: ParameterCountOptions;
ignoreLambdaExpression: boolean;
ignoreIIFE: boolean;
}>;
}>
Expand Down Expand Up @@ -80,6 +86,9 @@ const schema: JSONSchema4 = [
type: "string",
enum: ["atLeastOne", "exactlyOne"],
},
ignoreLambdaExpression: {
type: "boolean",
},
ignoreIIFE: {
type: "boolean",
},
Expand All @@ -103,6 +112,7 @@ const defaultOptions: Options = [
allowArgumentsKeyword: false,
enforceParameterCount: {
count: "atLeastOne",
ignoreLambdaExpression: false,
ignoreIIFE: true,
},
},
Expand Down Expand Up @@ -163,8 +173,8 @@ function getParamCountViolations(
enforceParameterCount === false ||
(node.params.length === 0 &&
typeof enforceParameterCount === "object" &&
enforceParameterCount.ignoreIIFE &&
isIIFE(node))
((enforceParameterCount.ignoreIIFE && isIIFE(node)) ||
(enforceParameterCount.ignoreLambdaExpression && isArgument(node))))
) {
return [];
}
Expand Down
12 changes: 12 additions & 0 deletions src/util/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ export function isIIFE(node: ReadonlyDeep<TSESTree.Node>): boolean {
);
}

/**
* Is the given node being passed as an argument?
*/
export function isArgument(node: ReadonlyDeep<TSESTree.Node>): boolean {
return (
node.parent !== undefined &&
isCallExpression(node.parent) &&
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any
node.parent.arguments.includes(node as any)
);
}

/**
* Get the key the given node is assigned to in its parent ObjectExpression.
*/
Expand Down
15 changes: 15 additions & 0 deletions tests/rules/functional-parameters/es3/invalid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,21 @@ const tests: ReadonlyArray<InvalidTestCase> = [
},
],
},
{
code: dedent`
function foo(param) {}
foo(function () {});
`,
optionsSet: [[]],
errors: [
{
messageId: "paramCountAtLeastOne",
type: "FunctionExpression",
line: 2,
column: 5,
},
],
},
];

export default tests;
7 changes: 7 additions & 0 deletions tests/rules/functional-parameters/es3/valid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ const tests: ReadonlyArray<ValidTestCase> = [
],
],
},
{
code: dedent`
function foo(param) {}
foo(function () {});
`,
optionsSet: [[{ enforceParameterCount: { ignoreLambdaExpression: true } }]],
},
];

export default tests;
15 changes: 15 additions & 0 deletions tests/rules/functional-parameters/es6/invalid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ const tests: ReadonlyArray<InvalidTestCase> = [
},
],
},
{
code: dedent`
function foo(param) {}
foo(() => 1);
`,
optionsSet: [[]],
errors: [
{
messageId: "paramCountAtLeastOne",
type: "ArrowFunctionExpression",
line: 2,
column: 5,
},
],
},
];

export default tests;
7 changes: 7 additions & 0 deletions tests/rules/functional-parameters/es6/valid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ const tests: ReadonlyArray<ValidTestCase> = [
],
],
},
{
code: dedent`
function foo(param) {}
foo(() => 1);
`,
optionsSet: [[{ enforceParameterCount: { ignoreLambdaExpression: true } }]],
},
];

export default tests;

0 comments on commit 044e54b

Please sign in to comment.