Skip to content

chore: add exported-function-args-maximum Deno Style Guide linter plugin #6561

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
40 changes: 40 additions & 0 deletions _tools/lint_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,5 +310,45 @@
};
},
},
// https://docs.deno.com/runtime/contributing/style_guide/#exported-functions%3A-max-2-args%2C-put-the-rest-into-an-options-object
"exported-function-args-maximum": {
create(context) {
return {
ExportNamedDeclaration(node) {
const declaration = node.declaration;
if (declaration?.type !== "FunctionDeclaration") return;
const params = declaration.params;
const id = declaration.id;
if (params.length < 3) return;
if (params.length === 3) {
const param = params.at(-1)!;

switch (param.type) {
case "Identifier":
if (param.name === "options") return;
break;
case "AssignmentPattern": {
if (param.right.type === "ObjectExpression") return;
break;
}

Check warning on line 333 in _tools/lint_plugin.ts

View check run for this annotation

Codecov / codecov/patch

_tools/lint_plugin.ts#L331-L333

Added lines #L331 - L333 were not covered by tests
}
return context.report({
node: id ?? declaration,
message:
"Third argument of export function is not an options object.",
hint:
"Export functions can have 0-2 required arguments, plus (if necessary) an options object (so max 3 total).",
});
}
context.report({
node: id ?? declaration,
message: "Exported function has more than three arguments.",
hint:
"Export functions can have 0-2 required arguments, plus (if necessary) an options object (so max 3 total).",
});
},
};
},
},
},
} satisfies Deno.lint.Plugin;
57 changes: 57 additions & 0 deletions _tools/lint_plugin_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,3 +310,60 @@ new CustomError("Can't parse input");
],
);
});

Deno.test("deno-style-guide/exported-function-args-maximum", {
ignore: !Deno.version.deno.startsWith("2"),
}, () => {
// Good
assertLintPluginDiagnostics(
`
function foo() {
}
function foo(bar: unknown) {
}
function foo(bar: unknown, baz: unknown) {
}
function foo(bar: unknown, baz: unknown, options: Record<string, unknown>) {
}
function foo(bar: unknown, baz: unknown, bat: unknown, bay: unknown) {
}
export function foo() {
}
export function foo(bar: unknown) {
}
export function foo(bar: unknown, baz: unknown) {
}
export function foo(bar: unknown, baz: unknown, options: Record<string, unknown>) {
}
`,
[],
);

// Bad
assertLintPluginDiagnostics(
`
export function foo(bar: unknown, baz: unknown, bat: unknown) {
}
export function foo(bar: unknown, baz: unknown, bat: unknown, options: Record<string, unknown>) {
}
`,
[
{
fix: [],
hint:
"Export functions can have 0-2 required arguments, plus (if necessary) an options object (so max 3 total).",
id: "deno-style-guide/exported-function-args-maximum",
message: "Third argument of export function is not an options object.",
range: [17, 20],
},
{
fix: [],
hint:
"Export functions can have 0-2 required arguments, plus (if necessary) an options object (so max 3 total).",
id: "deno-style-guide/exported-function-args-maximum",
message: "Exported function has more than three arguments.",
range: [83, 86],
},
],
);
});
1 change: 1 addition & 0 deletions assert/almost_equals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { AssertionError } from "./assertion_error.ts";
* default is one hundred thousandth of a percent of the expected value.
* @param msg The optional message to include in the error.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sidenote: bums me out a little that we don't follow this rule in @std/assert 😝

export function assertAlmostEquals(
actual: number,
expected: number,
Expand Down
1 change: 1 addition & 0 deletions assert/array_includes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export type ArrayLikeArg<T> = ArrayLike<T> & object;
* @param expected The array-like object to check for.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertArrayIncludes<T>(
actual: ArrayLikeArg<T>,
expected: ArrayLikeArg<T>,
Expand Down
1 change: 1 addition & 0 deletions assert/equals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected value to compare.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertEquals<T>(
actual: T,
expected: T,
Expand Down
1 change: 1 addition & 0 deletions assert/greater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected value to compare.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertGreater<T>(actual: T, expected: T, msg?: string) {
if (actual > expected) return;

Expand Down
1 change: 1 addition & 0 deletions assert/greater_or_equal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected value to compare.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertGreaterOrEqual<T>(
actual: T,
expected: T,
Expand Down
1 change: 1 addition & 0 deletions assert/instance_of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export type GetConstructorType<T extends AnyConstructor> = InstanceType<T>;
* @param expectedType The expected class constructor.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertInstanceOf<
// deno-lint-ignore no-explicit-any
T extends abstract new (...args: any[]) => any,
Expand Down
1 change: 1 addition & 0 deletions assert/is_error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { stripAnsiCode } from "@std/internal/styles";
* @param msgMatches The optional string or RegExp to assert in the error message.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertIsError<E extends Error = Error>(
error: unknown,
// deno-lint-ignore no-explicit-any
Expand Down
1 change: 1 addition & 0 deletions assert/less.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected value to compare.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertLess<T>(actual: T, expected: T, msg?: string) {
if (actual < expected) return;

Expand Down
1 change: 1 addition & 0 deletions assert/less_or_equal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected value to compare.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertLessOrEqual<T>(
actual: T,
expected: T,
Expand Down
1 change: 1 addition & 0 deletions assert/match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected pattern to match.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertMatch(
actual: string,
expected: RegExp,
Expand Down
1 change: 1 addition & 0 deletions assert/not_equals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { format } from "@std/internal/format";
* @param expected The expected value to compare.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertNotEquals<T>(actual: T, expected: T, msg?: string) {
if (!equal(actual, expected)) {
return;
Expand Down
1 change: 1 addition & 0 deletions assert/not_instance_of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { assertFalse } from "./false.ts";
* @param unexpectedType The class constructor to check against.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertNotInstanceOf<A, T>(
actual: A,
// deno-lint-ignore no-explicit-any
Expand Down
1 change: 1 addition & 0 deletions assert/not_match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected value to not match.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertNotMatch(
actual: string,
expected: RegExp,
Expand Down
1 change: 1 addition & 0 deletions assert/not_strict_equals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { format } from "@std/internal/format";
* @param expected The expected value to compare.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertNotStrictEquals<T>(
actual: T,
expected: T,
Expand Down
1 change: 1 addition & 0 deletions assert/object_match.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { assertEquals } from "./equals.ts";
* @param expected The expected value to match.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertObjectMatch(
// deno-lint-ignore no-explicit-any
actual: Record<PropertyKey, any>,
Expand Down
1 change: 1 addition & 0 deletions assert/rejects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export function assertRejects<E extends Error = Error>(
msgIncludes?: string,
msg?: string,
): Promise<E>;
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export async function assertRejects<E extends Error = Error>(
fn: () => PromiseLike<unknown>,
errorClassOrMsg?:
Expand Down
1 change: 1 addition & 0 deletions assert/strict_equals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected value to compare.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertStrictEquals<T>(
actual: unknown,
expected: T,
Expand Down
1 change: 1 addition & 0 deletions assert/string_includes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { AssertionError } from "./assertion_error.ts";
* @param expected The expected string to check for inclusion.
* @param msg The optional message to display if the assertion fails.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertStringIncludes(
actual: string,
expected: string,
Expand Down
1 change: 1 addition & 0 deletions assert/throws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export function assertThrows<E extends Error = Error>(
msgIncludes?: string,
msg?: string,
): E;
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function assertThrows<E extends Error = Error>(
fn: () => unknown,
errorClassOrMsg?:
Expand Down
1 change: 1 addition & 0 deletions async/_util.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2018-2025 the Deno authors. MIT license.
// This module is browser compatible.

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocker: we should have this function just accept an object.

export function exponentialBackoffWithJitter(
cap: number,
base: number,
Expand Down
1 change: 1 addition & 0 deletions async/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const ERROR_WHILE_MAPPING_MESSAGE =
* @param iteratorFn The function to call for every item of the array.
* @returns The async iterator with the transformed values.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function pooledMap<T, R>(
poolLimit: number,
array: Iterable<T> | AsyncIterable<T>,
Expand Down
1 change: 1 addition & 0 deletions bytes/copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
* Defining an offset will start copying at the specified index in the
* destination array.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function copy(src: Uint8Array, dst: Uint8Array, offset = 0): number {
offset = Math.max(0, Math.min(offset, dst.byteLength));
const dstBytesAvailable = dst.byteLength - offset;
Expand Down
1 change: 1 addition & 0 deletions bytes/includes_needle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { indexOfNeedle } from "./index_of_needle.ts";
* ```
* The search will start at the specified index in the source array.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function includesNeedle(
source: Uint8Array,
needle: Uint8Array,
Expand Down
1 change: 1 addition & 0 deletions bytes/index_of_needle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
* Defining a start index will begin the search at the specified index in the
* source array.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function indexOfNeedle(
source: Uint8Array,
needle: Uint8Array,
Expand Down
1 change: 1 addition & 0 deletions bytes/last_index_of_needle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* Defining a start index will begin the search at the specified index in the
* source array.
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function lastIndexOfNeedle(
source: Uint8Array,
needle: Uint8Array,
Expand Down
1 change: 1 addition & 0 deletions cbor/_common_encode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export function calcEncodingSize(x: CborType): number {
return size + calcHeaderSize(pairs);
}

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function encode(
input: CborType,
output: Uint8Array,
Expand Down
1 change: 1 addition & 0 deletions collections/reduce_groups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { mapValues } from "./map_values.ts";
* });
* ```
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function reduceGroups<T, A>(
record: Readonly<Record<string, ReadonlyArray<T>>>,
reducer: (accumulator: A, current: T) => A,
Expand Down
1 change: 1 addition & 0 deletions collections/running_reduce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* assertEquals(sumSteps, [1, 3, 6, 10, 15]);
* ```
*/
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function runningReduce<T, O>(
array: readonly T[],
reducer: (accumulator: O, current: T, currentIndex: number) => O,
Expand Down
4 changes: 4 additions & 0 deletions csv/_io.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export interface LineReader {
isEOF(): boolean;
}

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export async function parseRecord(
fullLine: string,
reader: LineReader,
Expand Down Expand Up @@ -201,6 +202,7 @@ export async function parseRecord(
return result;
}

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function createBareQuoteErrorMessage(
zeroBasedRecordStartLine: number,
zeroBasedLine: number,
Expand All @@ -212,6 +214,7 @@ export function createBareQuoteErrorMessage(
zeroBasedColumn + 1
}: bare " in non-quoted-field`;
}
// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function createQuoteErrorMessage(
zeroBasedRecordStartLine: number,
zeroBasedLine: number,
Expand All @@ -224,6 +227,7 @@ export function createQuoteErrorMessage(
}: extraneous or missing " in quoted-field`;
}

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function convertRowToObject(
row: readonly string[],
headers: readonly string[],
Expand Down
2 changes: 2 additions & 0 deletions encoding/_common16.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function calcSizeHex(originalSize: number): number {
return originalSize * 2;
}

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function encode(
buffer: Uint8Array_,
i: number,
Expand All @@ -43,6 +44,7 @@ export function encode(
return o;
}

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function decode(
buffer: Uint8Array_,
i: number,
Expand Down
2 changes: 2 additions & 0 deletions encoding/_common32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export function calcSizeBase32(rawSize: number): number {
return ((rawSize + 4) / 5 | 0) * 8;
}

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function encode(
buffer: Uint8Array_,
i: number,
Expand Down Expand Up @@ -128,6 +129,7 @@ export function encode(
return o;
}

// deno-lint-ignore deno-style-guide/exported-function-args-maximum
export function decode(
buffer: Uint8Array_,
i: number,
Expand Down
Loading
Loading