eslint-plugin-lube 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +95 -0
- package/README.md +17 -4
- package/docs/closures-last.md +34 -0
- package/docs/indent.md +102 -0
- package/docs/no-ambiguous-start.md +23 -0
- package/docs/no-loose-types.md +25 -0
- package/docs/no-typedef.md +24 -0
- package/docs/pretty-jsdoc-lines.md +30 -0
- package/docs/pretty-parens.md +59 -0
- package/docs/require-returns.md +21 -0
- package/docs/svelte-naming-convention.md +5 -6
- package/package.json +2 -7
- package/src/index.js +78 -19
- package/src/rules/ascii-order.js +113 -127
- package/src/rules/closures-last.js +323 -0
- package/src/rules/indent.js +84 -0
- package/src/rules/no-ambiguous-start.js +42 -0
- package/src/rules/no-loose-types.js +127 -0
- package/src/rules/no-typedef.js +44 -0
- package/src/rules/prefer-param-tag.js +35 -35
- package/src/rules/prefer-type-tag.js +29 -29
- package/src/rules/pretty-imports.js +23 -23
- package/src/rules/pretty-jsdoc-casting.js +39 -39
- package/src/rules/pretty-jsdoc-lines.js +104 -0
- package/src/rules/pretty-parens.js +280 -0
- package/src/rules/pretty-sequence.js +79 -95
- package/src/rules/pretty-ternary.js +27 -31
- package/src/rules/require-returns.js +190 -0
- package/src/rules/svelte-naming-convention.js +457 -546
- package/src/utils/accept_cr_eol.js +36 -0
- package/src/utils/indent_model.js +1596 -0
- package/src/utils/jsdoc_tags.js +30 -0
- package/src/utils/order_compare.js +17 -0
- package/src/utils/rule_options.js +30 -0
- package/src/utils/skip_unchanged_fixes.js +3 -3
- package/src/utils/source_text.js +80 -255
- package/src/utils/split_declarations.js +35 -14
- package/src/utils/trim_fixes.js +108 -0
- package/types/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,100 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.0
|
|
4
|
+
|
|
5
|
+
### Breaking
|
|
6
|
+
|
|
7
|
+
- **The strict and recommended configs use `lube/indent` instead of `@stylistic/indent`**: options and disable
|
|
8
|
+
comments for `@stylistic/indent` no longer apply to them, so set the indentation with `lube/indent`. The plugin's
|
|
9
|
+
`@stylistic/indent` is `@stylistic/eslint-plugin`'s own rule again, no longer wrapped. `recommended` now indents a
|
|
10
|
+
line that starts with an operator (`&&`, `||`, `+`) one level deeper than the line its expression starts on, also
|
|
11
|
+
when the expression starts its own line after `(`, `[` or `=`, every such line of one expression at that same
|
|
12
|
+
level; the `*` lines of a block comment align under its `/*`; and a line inside a Svelte template expression is
|
|
13
|
+
indented as JavaScript from the indent of the line that holds the expression's `{`, while markup lines and `$:`
|
|
14
|
+
statements stay as they are. A bracket opened in the middle of a line, as in `} of f(`, `); i < bar(` or
|
|
15
|
+
`|| b).catch(`, indents its contents one level deeper than that line, where `@stylistic/indent` indented them from
|
|
16
|
+
the line their expression starts on, and its closer goes back to that line's indent; the body of a statement (`if`,
|
|
17
|
+
`for`, `while`, `switch`, a function or a class) still indents from the statement's first line, wherever its `{`
|
|
18
|
+
lands.
|
|
19
|
+
A line that starts with a comment followed by code, such as a JSDoc cast, is indented like that code. Run
|
|
20
|
+
`eslint --fix` once to re-indent existing code.
|
|
21
|
+
- **The strict config moves nested function declarations below the last statement of their function** with the new
|
|
22
|
+
`closures-last`: a function declaration inside a function body goes below the `return`, or to the bottom of the
|
|
23
|
+
body when there is none. The moved functions come in `ascii-order`'s order when that rule checks declarations for
|
|
24
|
+
the file, and keep their source order otherwise. It has a fix, so run `eslint --fix` once; a moved function whose
|
|
25
|
+
parameter or local has the name of a variable of the enclosing function is then reported by `no-shadow`, so rename
|
|
26
|
+
it by hand.
|
|
27
|
+
- **The strict and recommended configs write a JSDoc block of one tag on one line** with the new
|
|
28
|
+
`pretty-jsdoc-lines`: a block of several lines holding one tag and no description becomes `/** @returns {void} */`,
|
|
29
|
+
and a one-line block of two or more tags is split, one tag a line. A tag whose type spans lines and a block with a
|
|
30
|
+
description, a blank line or an `@example` stay as they are. It has a fix, so run `eslint --fix` once.
|
|
31
|
+
- **The strict config requires a `@returns` tag** with the new `require-returns`, on every function declaration and
|
|
32
|
+
every function held by a `const`. Its fix adds `@returns {void}` (`Promise<void>` for an async function) to a
|
|
33
|
+
function that returns no value; write the type of the others by hand.
|
|
34
|
+
- **The strict config forbids loose types** with the new `no-loose-types`: `any`, `*`, `object` and `Object` in the
|
|
35
|
+
type of a JSDoc tag or a TypeScript annotation are reported, while a property or parameter of that name is not. It
|
|
36
|
+
has no fix; write the real type, or `unknown` for a value that is really arbitrary.
|
|
37
|
+
- **The strict config forbids `@typedef` and `@callback`** with the new `no-typedef`: both JSDoc tags are reported.
|
|
38
|
+
It has no fix; declare the type in a `.d.ts` file and name it with `import("./types.js").Name`.
|
|
39
|
+
- **The strict config forbids a statement that starts with `(`, `[` or a template literal** with the new
|
|
40
|
+
`no-ambiguous-start`, also behind a leading JSDoc cast, since without semicolons it joins the line above. It has no
|
|
41
|
+
fix; assign the value to a `const` first.
|
|
42
|
+
|
|
43
|
+
### Changed
|
|
44
|
+
|
|
45
|
+
- **The strict config's fixes settle in fewer passes**: a fix of a `lube` or `@stylistic` rule covers only the text it
|
|
46
|
+
changes, so it no longer blocks the fixes of other rules next to it within the same `eslint --fix` pass.
|
|
47
|
+
- **`closures-last` fixes bodies with a line that starts with a guarding `;`**: a statement after `"use strict"\n;` or
|
|
48
|
+
`;[ a ].map(f)` moves like any other, and a moved statement keeps its `;` where the code needs it.
|
|
49
|
+
- **`closures-last` fixes a body where a statement starting with `(`, `[`, `` ` ``, `+`, `-`, `/` or `<` follows a
|
|
50
|
+
function declaration**: when moving the function would let that statement continue the one before it, the fix puts
|
|
51
|
+
a `;` at its start, as in `var x = 1\n;(x)`. The strict config, whose `@stylistic/no-extra-semi` removes the `;`
|
|
52
|
+
written after a function declaration, no longer ends with a `closures-last` report it cannot fix there.
|
|
53
|
+
- **The strict config indents a line that starts with a binary or logical operator** (`||`, `&&`, `??`, `+`,
|
|
54
|
+
`===`, ...): at the indent of its expression when the expression starts a line of its own, as in `if (\n\ta\n\t&& b\n)`,
|
|
55
|
+
and one level deeper than the line the expression starts on otherwise, as in `return a\n\t|| b`. The lines of the
|
|
56
|
+
operand after it, a call `pretty-sequence` splits there among them, move with it in the same pass. Run
|
|
57
|
+
`eslint --fix` once to re-indent existing code.
|
|
58
|
+
|
|
59
|
+
### Added
|
|
60
|
+
|
|
61
|
+
- `pretty-parens`, in the strict and recommended configs: a grouping parenthesis, the parentheses of `if`, `while`,
|
|
62
|
+
`do ... while`, `for`, `switch`, `catch` and `with`, and the `${ }` of a template literal that hold an expression
|
|
63
|
+
spanning lines are written either as `(a\n\tb)`, the closing bracket right after the last token, or as
|
|
64
|
+
`(\n\ta\n\tb\n)`, the closing bracket on its own line when the opening bracket ends its line. Mixed forms are fixed
|
|
65
|
+
to the form the opening bracket starts; when a line comment ends the content, the fix breaks after the opening
|
|
66
|
+
bracket instead. JSDoc casts stay with `pretty-jsdoc-casting`, and the brackets of calls, parameters, arrays and
|
|
67
|
+
objects with `pretty-sequence`.
|
|
68
|
+
- `lube/indent`, in the strict and recommended configs: reports and fixes the indentation of every line, computed
|
|
69
|
+
from the syntax tree. The first option is `"tab"` or a number of spaces; the second sets `SwitchCase` and
|
|
70
|
+
`binaryOperator`, both `1` by default and `SwitchCase: 0` in the configs.
|
|
71
|
+
- `closures-last`, in the strict config: reports a function declaration that has another statement after it in the
|
|
72
|
+
body of a function, a function expression or an arrow function, and fixes it by moving the declarations to the end
|
|
73
|
+
of the body in their source order, each with the comments above it and the comment after it on its line, and its
|
|
74
|
+
overload signatures. The top level of a file, nested blocks and functions assigned to variables stay. A body that
|
|
75
|
+
shares a line with its statements, or a statement that would move up while starting with `(`, `[`, `` ` ``, `+`,
|
|
76
|
+
`-`, `/` or `<`, is reported without a fix.
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
|
|
80
|
+
- `eslint --fix` with the strict config finishes in one run on files that need many renames: it used to stop
|
|
81
|
+
after its 10 passes with renames and formatting left. `svelte-naming-convention` now renames every fixable name of a
|
|
82
|
+
file, with its declarations, usages and export specifiers, in one fix, whatever `fixSameNames` is, which only
|
|
83
|
+
decides whether usages are reported too. A name with a usage on a line turned off by `eslint-disable` is reported
|
|
84
|
+
without a fix, like one with a declaration there.
|
|
85
|
+
- `max-statements-per-line` in the strict config puts every declaration of a line like
|
|
86
|
+
`var a; var b; var c` on its own line in one pass instead of one per pass.
|
|
87
|
+
- In a file whose line breaks are CR alone, `eol-last` counts a final CR as the line break at the end of the file:
|
|
88
|
+
`eslint --fix` with the recommended config used to stop with circular fixes there, and now ends the file with
|
|
89
|
+
exactly one CR; the strict config now removes the final CR as it removes a final LF or CRLF.
|
|
90
|
+
|
|
91
|
+
## 0.8.1
|
|
92
|
+
|
|
93
|
+
### Fixed
|
|
94
|
+
|
|
95
|
+
- `svelte-naming-convention` no longer reports or renames an ambient TypeScript declaration (`declare function`, `declare const`, `declare let`, `declare var`, `declare class`, and anything inside `declare global { }` or `declare module "m" { }`) or its usages, since the name belongs to the host that injects it.
|
|
96
|
+
- `svelte-naming-convention` renames every overload signature and the implementation of a function together with its calls, instead of only the calls.
|
|
97
|
+
|
|
3
98
|
## 0.8.0
|
|
4
99
|
|
|
5
100
|
### Breaking
|
package/README.md
CHANGED
|
@@ -82,7 +82,8 @@ Both configs are flat config objects with `plugins` and `rules`, and differ in h
|
|
|
82
82
|
|
|
83
83
|
**`configs.recommended`** only formats and orders, and every rule in it has a fix, so it suits format on save.
|
|
84
84
|
- The `@stylistic` formatting rules: tab indentation, double quotes, no semicolons, spacing and line breaks.
|
|
85
|
-
- `pretty-imports`, `pretty-jsdoc-casting`, `pretty-sequence` and `pretty-ternary`, with items on one line up to 80 characters.
|
|
85
|
+
- `pretty-imports`, `pretty-jsdoc-casting`, `pretty-parens`, `pretty-sequence` and `pretty-ternary`, with items on one line up to 80 characters.
|
|
86
|
+
- `pretty-jsdoc-lines`, which writes a JSDoc block of one tag on one line and a block of several tags one tag a line.
|
|
86
87
|
- `ascii-order` for the names inside import and export braces only.
|
|
87
88
|
- A line break at the end of a file and at most one blank line, as editors write them.
|
|
88
89
|
- It never renames an identifier, never moves an import, key, function or test, and reports nothing about what the code does.
|
|
@@ -91,9 +92,13 @@ Both configs are flat config objects with `plugins` and `rules`, and differ in h
|
|
|
91
92
|
- `svelte-naming-convention`, which renames declarations to snake_case.
|
|
92
93
|
- `prefer-param-tag`, which moves the inline `/** @type {T} */` comments of a function declaration's parameters into `@param` tags on the declaration ([prefer-param-tag](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/prefer-param-tag.md)).
|
|
93
94
|
- `prefer-type-tag`, which moves the cast of a declaration's value into a `@type` tag on the declaration, in a project linted with type information ([prefer-type-tag](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/prefer-type-tag.md) shows the parser options).
|
|
95
|
+
- `closures-last`, which moves the function declarations inside a function body below its other statements ([closures-last](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/closures-last.md)).
|
|
96
|
+
- `require-returns`, which asks for a `@returns` tag on every function declaration and every function held by a `const`, and adds `@returns {void}` to one that returns no value ([require-returns](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/require-returns.md)).
|
|
97
|
+
- `no-loose-types`, `no-typedef` and `no-ambiguous-start`, which report `any`, `*`, `object` and `Object` in types, the tags `@typedef` and `@callback`, and a statement starting with `(`, `[` or a template literal ([no-loose-types](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/no-loose-types.md), [no-typedef](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/no-typedef.md), [no-ambiguous-start](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/no-ambiguous-start.md)).
|
|
94
98
|
- `ascii-order` for import statements, object keys, function declarations and test cases too (see below).
|
|
95
99
|
- `pretty-sequence` and `pretty-imports` at 30 characters.
|
|
96
100
|
- No blank lines, no line break at the end of a file and one statement per line.
|
|
101
|
+
- A line that starts with `||`, `&&`, `+` or another binary operator indented under its expression, one level deeper than the line the expression starts on (the `binaryOperator` option of `lube/indent`, which `recommended` sets too).
|
|
97
102
|
- `curly` (braces on every block) and core rules such as `func-style` (declarations), `no-shadow`, `prefer-const`, `one-var` (never) and `no-console`.
|
|
98
103
|
|
|
99
104
|
In `strict`, `ascii-order` fixes import order assuming modules can run in any order, and key order assuming nothing reads it: sorted keys change `Object.keys`, `JSON.stringify` and `for...in`.
|
|
@@ -101,9 +106,9 @@ In `strict`, `ascii-order` fixes import order assuming modules can run in any or
|
|
|
101
106
|
- Disable the rule where key or import order matters; [ascii-order](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/ascii-order.md) lists what it does not fix.
|
|
102
107
|
|
|
103
108
|
### Changing a rule
|
|
104
|
-
Override a rule after the spread: `rules: { ...lube.configs.recommended.rules, "
|
|
105
|
-
- Formatting rules go by their `@stylistic/` name
|
|
106
|
-
- An indentation of your own also goes to the `indent` option of `pretty-imports`, `pretty-sequence` and `pretty-ternary`, or those rules and
|
|
109
|
+
Override a rule after the spread: `rules: { ...lube.configs.recommended.rules, "lube/indent": ["error", 4] }`.
|
|
110
|
+
- Formatting rules go by their `@stylistic/` name, except indentation, which is `lube/indent`.
|
|
111
|
+
- An indentation of your own also goes to the `indent` option of `pretty-imports`, `pretty-parens`, `pretty-sequence` and `pretty-ternary`, or those rules and `lube/indent` keep rewriting each other's fixes.
|
|
107
112
|
- `pretty-sequence` writes the items of an array, object or call one per line once they are longer than its `maxLength` together, 80 in `recommended` and 30 in `strict`: `"lube/pretty-sequence": ["error", { maxLength: 100 }]`.
|
|
108
113
|
- Every option of a rule is checked, so a misspelled option is a configuration error.
|
|
109
114
|
|
|
@@ -111,13 +116,21 @@ Override a rule after the spread: `rules: { ...lube.configs.recommended.rules, "
|
|
|
111
116
|
| Rule | Enforces | `recommended` |
|
|
112
117
|
| --- | --- | --- |
|
|
113
118
|
| [ascii-order](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/ascii-order.md) | ASCII order of import statements, import and export names, object keys, function declarations and test cases | names only |
|
|
119
|
+
| [closures-last](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/closures-last.md) | Function declarations inside a function body below its other statements, since they are hoisted | no |
|
|
114
120
|
| [curly](https://eslint.org/docs/latest/rules/curly) | Braces around the bodies of `if`, `else`, `for`, `while` and `do`, as ESLint's own rule does, with a fix that keeps a comment in front of the body, such as a JSDoc cast, inside the braces | no |
|
|
121
|
+
| [indent](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/indent.md) | Indentation of every line computed from the syntax tree, including lines that start with an operator, the `*` lines of block comments and the template expressions of `.svelte` files | yes |
|
|
122
|
+
| [no-ambiguous-start](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/no-ambiguous-start.md) | No statement starting with `(`, `[` or a template literal, which joins the line above without semicolons | no |
|
|
123
|
+
| [no-loose-types](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/no-loose-types.md) | No `any`, `*`, `object` or `Object` in JSDoc tag types and TypeScript annotations | no |
|
|
124
|
+
| [no-typedef](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/no-typedef.md) | No `@typedef` or `@callback` JSDoc tags | no |
|
|
115
125
|
| [prefer-param-tag](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/prefer-param-tag.md) | JSDoc `@param` tags on a function declaration instead of inline `/** @type {T} */` comments in its parameter list | no |
|
|
116
126
|
| [prefer-type-tag](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/prefer-type-tag.md) | A JSDoc `@type` tag on a declaration instead of a cast of its value, wherever the tag would type check (needs type information) | no |
|
|
117
127
|
| [pretty-imports](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-imports.md) | Import and export names on one line when they fit, or one per line | yes |
|
|
118
128
|
| [pretty-jsdoc-casting](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-jsdoc-casting.md) | JSDoc type casts written as `/** @type {T} */(value)/**/` | yes |
|
|
129
|
+
| [pretty-jsdoc-lines](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-jsdoc-lines.md) | A JSDoc block of one tag on one line, and a block of several tags one tag a line | yes |
|
|
130
|
+
| [pretty-parens](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-parens.md) | Parentheses, statement headers and `${ }` that hold a multi-line expression closed right after the last token, or on their own line when the opener ends its line | yes |
|
|
119
131
|
| [pretty-sequence](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-sequence.md) | Items of arrays, objects, calls and parameters on one line when they fit, or one per line | yes |
|
|
120
132
|
| [pretty-ternary](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/pretty-ternary.md) | Nested and long ternaries broken before `?` and `:`, one indent deeper per level | yes |
|
|
133
|
+
| [require-returns](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/require-returns.md) | A JSDoc `@returns` tag on every function declaration and every function held by a `const` | no |
|
|
121
134
|
| [svelte-naming-convention](https://github.com/artxe/lube-series/blob/master/packages/eslint-plugin-lube/docs/svelte-naming-convention.md) | snake_case declarations, following the Svelte code conventions | no |
|
|
122
135
|
|
|
123
136
|
## What it is not
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# closures-last
|
|
2
|
+
Enforces the function declarations inside a function body below all its other statements: below the `return`, or at the bottom of the body when there is none. A function declaration is hoisted, so moving it never changes what the code does.
|
|
3
|
+
|
|
4
|
+
- Checked are the statements directly in the body of a function declaration, a function expression or an arrow function.
|
|
5
|
+
- Not checked: the top level of a file, blocks inside a body (`if`, loops, `static` blocks, TypeScript namespaces), and arrow functions or function expressions assigned to variables, which are not hoisted.
|
|
6
|
+
- TypeScript overload signatures move with their implementation.
|
|
7
|
+
- The fix moves the declarations to the end of the body, keeping the comments above each one (JSDoc, `eslint-disable-next-line`, `@ts-expect-error`) and the comment after it on its line. The file's own line breaks are kept.
|
|
8
|
+
- A body whose statements share a line, `function f() { function a() {} return a }`, is reported without a fix.
|
|
9
|
+
- A statement starting with `(`, `[`, a template literal or an operator that moving a function would join to the statement before it, as a semicolon-free file reads them as one expression, gets a `;` at its start: `var x = 1\nfunction a() {}\n(x)` becomes `var x = 1\n;(x)\nfunction a() {}`. One after a statement ending with `;` or with the brace of a block, such as `if (x) {}`, stays as it is.
|
|
10
|
+
- With `ascii-order` enabled for the file and `checkDeclarations` on, the fix emits the moved declarations in `ascii-order`'s order (overloads of one name stay together), so that rule has nothing left to reorder; otherwise they keep their source order.
|
|
11
|
+
|
|
12
|
+
## options
|
|
13
|
+
None.
|
|
14
|
+
|
|
15
|
+
## Valid
|
|
16
|
+
```js
|
|
17
|
+
function outer() {
|
|
18
|
+
return inner
|
|
19
|
+
function inner() {}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function other() {
|
|
23
|
+
const handler = () => 1
|
|
24
|
+
return handler
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Invalid
|
|
29
|
+
```js
|
|
30
|
+
function outer() {
|
|
31
|
+
function inner() {}
|
|
32
|
+
return inner
|
|
33
|
+
}
|
|
34
|
+
```
|
package/docs/indent.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# indent
|
|
2
|
+
Enforces the indentation of every line, computed from the syntax tree, and fixes it.
|
|
3
|
+
|
|
4
|
+
- A line is indented one level deeper than the line its enclosing block, bracket pair or expression starts on.
|
|
5
|
+
- A line that starts with a binary or logical operator (`&&`, `||`, `??`, `+`, ...) is indented `binaryOperator` levels deeper than the line its expression starts on.
|
|
6
|
+
- The `*` lines of a block comment align under the `/*` that opens it.
|
|
7
|
+
- In a `.svelte` file, a line inside a template expression is indented as JavaScript from the indent of the line that holds the expression's `{`. Markup lines and `$:` statements are left as they are.
|
|
8
|
+
|
|
9
|
+
## options
|
|
10
|
+
```js
|
|
11
|
+
schema: [
|
|
12
|
+
{
|
|
13
|
+
additionalProperties: false,
|
|
14
|
+
anyOf: [
|
|
15
|
+
{ enum: ["tab"] },
|
|
16
|
+
{ minimum: 0, type: "integer" }
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
additionalProperties: false,
|
|
21
|
+
properties: {
|
|
22
|
+
SwitchCase: { minimum: 0, type: "integer" },
|
|
23
|
+
binaryOperator: { minimum: 0, type: "integer" }
|
|
24
|
+
},
|
|
25
|
+
type: "object"
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
```
|
|
29
|
+
The first option is `"tab"` or the number of spaces of one level. The second is an object.
|
|
30
|
+
### SwitchCase
|
|
31
|
+
The levels a `case` is indented past its `switch`. The default is `1`; the `strict` and `recommended` configs set `0`.
|
|
32
|
+
### binaryOperator
|
|
33
|
+
The levels a line that starts with an operator is indented past the line its expression starts on. The default is `1`; with `0` such a line stays at the indent of its expression.
|
|
34
|
+
|
|
35
|
+
## Valid
|
|
36
|
+
```js
|
|
37
|
+
function f() {
|
|
38
|
+
return 1
|
|
39
|
+
}
|
|
40
|
+
const a = b
|
|
41
|
+
|| c
|
|
42
|
+
f(
|
|
43
|
+
a
|
|
44
|
+
|| b
|
|
45
|
+
)
|
|
46
|
+
switch (a) {
|
|
47
|
+
case 1:
|
|
48
|
+
b()
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* @param {number} a
|
|
52
|
+
*/
|
|
53
|
+
function g(a) {}
|
|
54
|
+
```
|
|
55
|
+
`switch` with `["error", "tab", { SwitchCase: 0 }]`. With `["error", "tab", { binaryOperator: 0 }]`, `const a = b\n|| c` is valid.
|
|
56
|
+
```svelte
|
|
57
|
+
<div>
|
|
58
|
+
{a.map(b => {
|
|
59
|
+
return b
|
|
60
|
+
})}
|
|
61
|
+
{#if a
|
|
62
|
+
&& b}
|
|
63
|
+
<p />
|
|
64
|
+
{/if}
|
|
65
|
+
</div>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Invalid
|
|
69
|
+
```js
|
|
70
|
+
function f() {
|
|
71
|
+
return 1
|
|
72
|
+
}
|
|
73
|
+
const a = b
|
|
74
|
+
|| c
|
|
75
|
+
f(
|
|
76
|
+
a
|
|
77
|
+
|| b
|
|
78
|
+
)
|
|
79
|
+
if (a) {
|
|
80
|
+
/**
|
|
81
|
+
* b
|
|
82
|
+
*/
|
|
83
|
+
b()
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
```svelte
|
|
87
|
+
<div>
|
|
88
|
+
{a.map(b => {
|
|
89
|
+
return b
|
|
90
|
+
})}
|
|
91
|
+
</div>
|
|
92
|
+
{#if a
|
|
93
|
+
&& b}
|
|
94
|
+
<p />
|
|
95
|
+
{/if}
|
|
96
|
+
{#snippet a(
|
|
97
|
+
b,
|
|
98
|
+
c
|
|
99
|
+
)}
|
|
100
|
+
<p />
|
|
101
|
+
{/snippet}
|
|
102
|
+
```
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# no-ambiguous-start
|
|
2
|
+
Disallows an expression statement that starts with `(`, `[` or a template literal.
|
|
3
|
+
|
|
4
|
+
- Without semicolons such a statement joins the line above and becomes a call, an index or a tagged template of it.
|
|
5
|
+
- A JSDoc cast in front is not a token, so `/** @type {T} */(x).y = 1` counts too.
|
|
6
|
+
- Assign the value to a `const` first, or write the statement another way.
|
|
7
|
+
- It has no fix.
|
|
8
|
+
|
|
9
|
+
## options
|
|
10
|
+
None.
|
|
11
|
+
|
|
12
|
+
## Valid
|
|
13
|
+
```js
|
|
14
|
+
const result = (a || b).run()
|
|
15
|
+
foo()
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Invalid
|
|
19
|
+
```js
|
|
20
|
+
(a || b).run()
|
|
21
|
+
;[a, b] = [b, a]
|
|
22
|
+
`x`.trim()
|
|
23
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# no-loose-types
|
|
2
|
+
Disallows `any`, `*`, `object` and `Object` in the type of a JSDoc tag (`@type`, `@param`, `@returns`, `@template`, ...) and in TypeScript type annotations.
|
|
3
|
+
|
|
4
|
+
- Use `unknown` where the value is really arbitrary, or its real type.
|
|
5
|
+
- A property or parameter named `any` or `object`, a member such as `obj.any` and text inside a string are not types and stay valid.
|
|
6
|
+
- It has no fix, since the type is yours to write.
|
|
7
|
+
|
|
8
|
+
## options
|
|
9
|
+
None.
|
|
10
|
+
|
|
11
|
+
## Valid
|
|
12
|
+
```js
|
|
13
|
+
/** @type {Record<string, unknown>} */
|
|
14
|
+
const bag = {}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Invalid
|
|
18
|
+
```js
|
|
19
|
+
/** @type {any} */
|
|
20
|
+
let a
|
|
21
|
+
/** @param {*} value */
|
|
22
|
+
function f(value) {}
|
|
23
|
+
/** @returns {Promise<object>} */
|
|
24
|
+
async function g() {}
|
|
25
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# no-typedef
|
|
2
|
+
Disallows the JSDoc tags `@typedef` and `@callback`.
|
|
3
|
+
|
|
4
|
+
- Declare the type in a `.d.ts` file and use it through `import("./types.js").Name` or a `/** @import */` tag.
|
|
5
|
+
- A tag inside a `/* */` comment that is not JSDoc, a `//` comment or a string is not checked.
|
|
6
|
+
- It has no fix, since the type moves to another file.
|
|
7
|
+
|
|
8
|
+
## options
|
|
9
|
+
None.
|
|
10
|
+
|
|
11
|
+
## Valid
|
|
12
|
+
```js
|
|
13
|
+
/** @type {import("./types.js").Name} */
|
|
14
|
+
let name
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Invalid
|
|
18
|
+
```js
|
|
19
|
+
/** @typedef {string} Name */
|
|
20
|
+
/**
|
|
21
|
+
* @callback Run
|
|
22
|
+
* @returns {void}
|
|
23
|
+
*/
|
|
24
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# pretty-jsdoc-lines
|
|
2
|
+
Enforces a JSDoc block of one tag on one line, and a block of two or more tags with one tag a line.
|
|
3
|
+
|
|
4
|
+
- A block of several lines that holds one tag and no description is joined into one line: `/** @returns {void} */`. A tag whose type spans lines, such as `@param {{\n * a: number\n * }} total`, is left alone, because the line breaks separate the members of a type literal. A block with a description, a blank line or an `@example` is left alone.
|
|
5
|
+
- A one-line block that holds two or more tags is split, one tag a line, a description first. A block that does not start its line is reported without a fix.
|
|
6
|
+
- Braces keep `{@link A}` and the types of the tags from being read as tags.
|
|
7
|
+
|
|
8
|
+
## options
|
|
9
|
+
None.
|
|
10
|
+
|
|
11
|
+
## Valid
|
|
12
|
+
```js
|
|
13
|
+
/** @returns {void} */
|
|
14
|
+
function f() {}
|
|
15
|
+
/**
|
|
16
|
+
* @param {number} count
|
|
17
|
+
* @returns {void}
|
|
18
|
+
*/
|
|
19
|
+
function g(count) {}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Invalid
|
|
23
|
+
```js
|
|
24
|
+
/**
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
function f() {}
|
|
28
|
+
/** @param {number} count @returns {void} */
|
|
29
|
+
function g(count) {}
|
|
30
|
+
```
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# pretty-parens
|
|
2
|
+
Writes a bracket that holds an expression spanning lines in one of two forms: the closing bracket right after the last token when the opening bracket is followed by content, or on a line of its own when the opening bracket ends its line.
|
|
3
|
+
|
|
4
|
+
- It checks the grouping parentheses of an expression, the parentheses of `if`, `while`, `do ... while`, `for`, `for ... in`, `for ... of`, `switch`, `catch` and `with`, and the `${ }` of a template literal.
|
|
5
|
+
- A bracket whose content sits on one line is left alone. The arguments of calls, function parameters, arrays, objects and imports belong to `pretty-sequence`.
|
|
6
|
+
- If the opening bracket is followed by content on its line, the line break before the closing bracket is removed. If the opening bracket ends its line, a line break and the indent of the opening bracket's line are put before the closing bracket. A line comment right after the opening bracket counts as ending its line.
|
|
7
|
+
- When a line comment ends the content, the closing bracket cannot move up, so the fix breaks after the opening bracket instead.
|
|
8
|
+
- The parentheses of a JSDoc cast, `/** @type {T} */(value)/**/`, are left to `pretty-jsdoc-casting`, which writes them without white space inside.
|
|
9
|
+
- Only the white space next to the bracket changes, so the content keeps its text and comments.
|
|
10
|
+
|
|
11
|
+
## options
|
|
12
|
+
```js
|
|
13
|
+
schema: [
|
|
14
|
+
{
|
|
15
|
+
additionalProperties: false,
|
|
16
|
+
properties: {
|
|
17
|
+
indent: { default: "\t", type: "string" }
|
|
18
|
+
},
|
|
19
|
+
type: "object"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
```
|
|
23
|
+
### indent
|
|
24
|
+
The string of one indentation level, used when the fix breaks after an opening bracket. Match it to `lube/indent`, or the two rules keep rewriting each other's fixes.
|
|
25
|
+
|
|
26
|
+
## Valid
|
|
27
|
+
```js
|
|
28
|
+
var value = (a
|
|
29
|
+
|| b)
|
|
30
|
+
var value = (
|
|
31
|
+
a
|
|
32
|
+
|| b
|
|
33
|
+
)
|
|
34
|
+
if (a
|
|
35
|
+
|| b) {
|
|
36
|
+
}
|
|
37
|
+
if (
|
|
38
|
+
a
|
|
39
|
+
|| b
|
|
40
|
+
) {
|
|
41
|
+
}
|
|
42
|
+
var text = `${a
|
|
43
|
+
? b
|
|
44
|
+
: c}`
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Invalid
|
|
48
|
+
```js
|
|
49
|
+
var value = (a
|
|
50
|
+
|| b
|
|
51
|
+
)
|
|
52
|
+
var value = (
|
|
53
|
+
a
|
|
54
|
+
|| b)
|
|
55
|
+
if (a
|
|
56
|
+
|| b
|
|
57
|
+
) {
|
|
58
|
+
}
|
|
59
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# require-returns
|
|
2
|
+
Requires a `@returns` tag in the JSDoc of every function declaration and every function held by a `const`.
|
|
3
|
+
|
|
4
|
+
- Methods, object members, callbacks and functions held by `let` or `var` are not checked.
|
|
5
|
+
- The fix adds `@returns {void}` (`@returns {Promise<void>}` for an async function), creating the block when there is none, only when the function returns no value. A function that returns a value, a generator, and one whose declaration or JSDoc does not start its line are reported without a fix, since the type is yours to write.
|
|
6
|
+
- `@return` counts as a tag too.
|
|
7
|
+
|
|
8
|
+
## options
|
|
9
|
+
None.
|
|
10
|
+
|
|
11
|
+
## Valid
|
|
12
|
+
```js
|
|
13
|
+
/** @returns {number} */
|
|
14
|
+
const count = () => 1
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Invalid
|
|
18
|
+
```js
|
|
19
|
+
function run() {}
|
|
20
|
+
const count = () => 1
|
|
21
|
+
```
|
|
@@ -4,12 +4,13 @@ The strict config turns it on and the recommended config leaves it off, since it
|
|
|
4
4
|
|
|
5
5
|
- Declarations such as variables, parameters, catch clauses, array patterns and non-shorthand object patterns, `const { key: camelCase } = value`, are reported. A shorthand property, `const { camelCase } = value`, and a shorthand import, `import { camelCase } from "m"`, are not, because the name is the key or the export it reads; write `const { camelCase: camel_case } = value` or `import { camelCase as camel_case }` to rename it.
|
|
6
6
|
- The message names the expected name, `Rename 'camelCase' to 'camel_case'`, or, for a name without a snake_case form such as `NO_SNAKE__CASE`, asks for snake_case, UPPER_SNAKE_CASE or PascalCase.
|
|
7
|
-
- Usages such as assignments, function bodies, `extends` clauses, JSX and TypeScript expressions are only renamed along with their declaration; `fixSameNames` sets
|
|
7
|
+
- Usages such as assignments, function bodies, `extends` clauses, JSX and TypeScript expressions are only renamed along with their declaration; `fixSameNames` sets whether they are reported.
|
|
8
8
|
- Usages are matched to declarations by scope, so a global, an import or an exported camelCase function of the same name is left as it is.
|
|
9
|
+
- An ambient TypeScript declaration, `declare function acquireVsCodeApi(): Api`, `declare const`, `declare class`, or anything inside `declare global { }` or `declare module "m" { }`, names a binding the code does not own: it is neither reported nor renamed, and neither are its usages.
|
|
9
10
|
- A declaration exported with `export { camelCase }` is renamed together with the export specifier, `export { camel_case as camelCase }`.
|
|
10
11
|
- The JSDoc of a renamed parameter follows it: `@param {T} [camelCase]`, `{camelCase is T}` and `{typeof camelCase}`.
|
|
11
12
|
- In a `.svelte` file, the store subscriptions of a renamed store are renamed with it, `$camelCase` into `$camel_case`, in the same fix, and so are the usages in the markup: mustache tags, attributes, directives and the expression of `{#if}`, `{#each}`, `{#await}` and `{#key}`. A shorthand attribute is written out, `{camelCase}` into `camelCase={camel_case}`, so the name of the property stays. Names the markup declares, the context of `{#each}`, the value of `{#await}` and a `let:` property, are not reported.
|
|
12
|
-
- A name is reported without a fix when it has no snake_case form, such as `NO_SNAKE__CASE`, when the snake_case name would shadow or capture another variable, when it is also declared where the rule does not rename, such as a TypeScript namespace merged with a function or `export var camelCase`, when a declaration of it is turned off with an `eslint-disable` comment, when it is used as a JSX or Svelte component tag, `<Camel_Case />`, which a lowercase name would turn into an HTML tag, when it also appears where the rule cannot tell a reference from a type or a property, such as `let a: camelCase` or markup of a Svelte parser, or when it is read as a store, `$camelCase`, outside a `.svelte` file, where `$camelCase` is a name of its own.
|
|
13
|
+
- A name is reported without a fix when it has no snake_case form, such as `NO_SNAKE__CASE`, when the snake_case name would shadow or capture another variable, when it is also declared where the rule does not rename, such as a TypeScript namespace merged with a function or `export var camelCase`, when a declaration or a usage of it is turned off with an `eslint-disable` comment, when it is used as a JSX or Svelte component tag, `<Camel_Case />`, which a lowercase name would turn into an HTML tag, when it also appears where the rule cannot tell a reference from a type or a property, such as `let a: camelCase` or markup of a Svelte parser, or when it is read as a store, `$camelCase`, outside a `.svelte` file, where `$camelCase` is a name of its own.
|
|
13
14
|
|
|
14
15
|
## options
|
|
15
16
|
```js
|
|
@@ -24,10 +25,8 @@ schema: [
|
|
|
24
25
|
]
|
|
25
26
|
```
|
|
26
27
|
### fixSameNames
|
|
27
|
-
If it is `true`, every usage of a reported declaration is reported
|
|
28
|
-
|
|
29
|
-
The declaration and its usages are renamed in one fix instead when the snake_case name is already declared in the file or a variable of the same name is declared in a nested scope, so a half-renamed usage never resolves to another variable.
|
|
30
|
-
If it is `false`, only the declaration is reported, and its fix renames the declaration and every usage at once.
|
|
28
|
+
If it is `true`, every usage of a reported declaration is reported too; if it is `false`, only the declaration is.
|
|
29
|
+
Either way, one fix renames every fixable name of the file with all its declarations, usages, assignments, `export { }` specifiers and `export default`, so `eslint --fix` finishes the renames in one pass, a half-renamed usage never resolves to another variable, and no other rule sees a variable apart from its writes: `prefer-const` never turns `let lastBid = 1` into a `const` without its `lastBid += 1`.
|
|
31
30
|
```js
|
|
32
31
|
myFunction() // Only in the case that fixSameNames is true, an error occurs.
|
|
33
32
|
|
package/package.json
CHANGED
|
@@ -7,11 +7,6 @@
|
|
|
7
7
|
"@stylistic/eslint-plugin": "^5.10.0"
|
|
8
8
|
},
|
|
9
9
|
"description": "Fixable ESLint rules that format code without Prettier",
|
|
10
|
-
"devDependencies": {
|
|
11
|
-
"@types/estree": "^1.0.9",
|
|
12
|
-
"@typescript/native": "npm:typescript@^7.0.2",
|
|
13
|
-
"eslint": "^10.12.0"
|
|
14
|
-
},
|
|
15
10
|
"engines": {
|
|
16
11
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
|
17
12
|
},
|
|
@@ -53,10 +48,10 @@
|
|
|
53
48
|
},
|
|
54
49
|
"type": "module",
|
|
55
50
|
"types": "types/index.d.ts",
|
|
56
|
-
"version": "0.
|
|
51
|
+
"version": "0.9.0",
|
|
57
52
|
"scripts": {
|
|
58
53
|
"dts": "node ../../scripts/tsc_with_clean.js eslint-plugin-lube",
|
|
59
54
|
"lint": "pnpm -w lint",
|
|
60
|
-
"test": "pnpm -w exec vitest run
|
|
55
|
+
"test": "pnpm -w exec vitest run test/eslint-plugin-lube"
|
|
61
56
|
}
|
|
62
57
|
}
|