diff --git a/docs/rules/indent.md b/docs/rules/indent.md index 2a626604e01..74fb0e7e2ac 100644 --- a/docs/rules/indent.md +++ b/docs/rules/indent.md @@ -79,6 +79,8 @@ This rule has an object option: * `"FunctionExpression"` takes an object to define rules for function expressions. * `parameters` (default: 1) enforces indentation level for parameters in a function expression. This can either be a number indicating indentation level, or the string `"first"` indicating that all parameters of the expression must be aligned with the first parameter. This can also be set to `"off"` to disable checking for FunctionExpression parameters. * `body` (default: 1) enforces indentation level for the body of a function expression. +* `"StaticBlock"` takes an object to define rules for class static blocks. + * `body` (default: 1) enforces indentation level for the body of a class static block. * `"CallExpression"` takes an object to define rules for function call expressions. * `arguments` (default: 1) enforces indentation level for arguments in a call expression. This can either be a number indicating indentation level, or the string `"first"` indicating that all arguments of the expression must be aligned with the first argument. This can also be set to `"off"` to disable checking for CallExpression arguments. * `"ArrayExpression"` (default: 1) enforces indentation level for elements in arrays. It can also be set to the string `"first"`, indicating that all the elements in the array should be aligned with the first element. This can also be set to `"off"` to disable checking for array elements. @@ -484,6 +486,56 @@ var foo = function(bar, baz, } ``` +### StaticBlock + +Examples of **incorrect** code for this rule with the `2, { "StaticBlock": {"body": 1} }` option: + +```js +/*eslint indent: ["error", 2, { "StaticBlock": {"body": 1} }]*/ + +class C { + static { + foo(); + } +} +``` + +Examples of **correct** code for this rule with the `2, { "StaticBlock": {"body": 1} }` option: + +```js +/*eslint indent: ["error", 2, { "StaticBlock": {"body": 1} }]*/ + +class C { + static { + foo(); + } +} +``` + +Examples of **incorrect** code for this rule with the `2, { "StaticBlock": {"body": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "StaticBlock": {"body": 2} }]*/ + +class C { + static { + foo(); + } +} +``` + +Examples of **correct** code for this rule with the `2, { "StaticBlock": {"body": 2} }` option: + +```js +/*eslint indent: ["error", 2, { "StaticBlock": {"body": 2} }]*/ + +class C { + static { + foo(); + } +} +``` + ### CallExpression Examples of **incorrect** code for this rule with the `2, { "CallExpression": {"arguments": 1} }` option: diff --git a/lib/rules/indent.js b/lib/rules/indent.js index 7b17e3e5402..f4dbfff27b4 100644 --- a/lib/rules/indent.js +++ b/lib/rules/indent.js @@ -68,6 +68,7 @@ const KNOWN_NODES = new Set([ "ReturnStatement", "SequenceExpression", "SpreadElement", + "StaticBlock", "Super", "SwitchCase", "SwitchStatement", @@ -583,6 +584,16 @@ module.exports = { }, additionalProperties: false }, + StaticBlock: { + type: "object", + properties: { + body: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + }, CallExpression: { type: "object", properties: { @@ -646,6 +657,9 @@ module.exports = { parameters: DEFAULT_PARAMETER_INDENT, body: DEFAULT_FUNCTION_BODY_INDENT }, + StaticBlock: { + body: DEFAULT_FUNCTION_BODY_INDENT + }, CallExpression: { arguments: DEFAULT_PARAMETER_INDENT }, @@ -1397,6 +1411,13 @@ module.exports = { } }, + StaticBlock(node) { + const openingCurly = sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token + const closingCurly = sourceCode.getLastToken(node); + + addElementListIndent(node.body, openingCurly, closingCurly, options.StaticBlock.body); + }, + SwitchStatement(node) { const openingCurly = sourceCode.getTokenAfter(node.discriminant, astUtils.isOpeningBraceToken); const closingCurly = sourceCode.getLastToken(node); diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js index 03086ce139e..39476791420 100644 --- a/tests/lib/rules/indent.js +++ b/tests/lib/rules/indent.js @@ -5847,6 +5847,241 @@ ruleTester.run("indent", rule, { ar2){} `, options: [2, { FunctionDeclaration: { parameters: "first" }, FunctionExpression: { parameters: "first" } }] + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [2], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [4, { StaticBlock: { body: 2 } }], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [4, { StaticBlock: { body: 0 } }], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + \tstatic { + \t\tfoo(); + \t\tbar(); + \t} + } + `, + options: ["tab"], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + \tstatic { + \t\t\tfoo(); + \t\t\tbar(); + \t} + } + `, + options: ["tab", { StaticBlock: { body: 2 } }], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static + { + foo(); + bar(); + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static { + var x, + y; + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static + { + var x, + y; + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static { + if (foo) { + bar; + } + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static { + { + bar; + } + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + static {} + + static { + } + + static + { + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + + static { + foo; + } + + static { + bar; + } + + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + + x = 1; + + static { + foo; + } + + y = 2; + + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + + method1(param) { + foo; + } + + static { + bar; + } + + method2(param) { + foo; + } + + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + function f() { + class C { + static { + foo(); + bar(); + } + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 } + }, + { + code: unIndent` + class C { + method() { + foo; + } + static { + bar; + } + } + `, + options: [4, { FunctionExpression: { body: 2 }, StaticBlock: { body: 2 } }], + parserOptions: { ecmaVersion: 2022 } } ], @@ -11814,6 +12049,580 @@ ruleTester.run("indent", rule, { [4, 8, 0, "Keyword"], [5, 4, 0, "Punctuator"] ]) + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [2], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 2, 0, "Keyword"], + [3, 4, 0, "Identifier"], + [4, 4, 0, "Identifier"], + [5, 2, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 8, 0, "Identifier"], + [4, 8, 0, "Identifier"], + [5, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 8, "Keyword"], + [3, 8, 4, "Identifier"], + [4, 8, 0, "Identifier"], + [5, 4, 8, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [4, { StaticBlock: { body: 2 } }], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 12, 0, "Identifier"], + [4, 12, 0, "Identifier"], + [5, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + options: [4, { StaticBlock: { body: 0 } }], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 4, 0, "Identifier"], + [4, 4, 0, "Identifier"], + [5, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + \tstatic { + \t\tfoo(); + \t\tbar(); + \t} + } + `, + options: ["tab"], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors("tab", [ + [2, 1, 0, "Keyword"], + [3, 2, 0, "Identifier"], + [4, 2, 0, "Identifier"], + [5, 1, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + \tstatic { + \t\t\tfoo(); + \t\t\tbar(); + \t} + } + `, + options: ["tab", { StaticBlock: { body: 2 } }], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors("tab", [ + [2, 1, 0, "Keyword"], + [3, 3, 0, "Identifier"], + [4, 3, 0, "Identifier"], + [5, 1, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static + { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + static + { + foo(); + bar(); + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 4, 0, "Punctuator"], + [4, 8, 0, "Identifier"], + [5, 8, 0, "Identifier"], + [6, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static + { + foo(); + bar(); + } + } + `, + output: unIndent` + class C { + static + { + foo(); + bar(); + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [3, 4, 8, "Punctuator"], + [6, 4, 8, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + var x, + y; + } + } + `, + output: unIndent` + class C { + static { + var x, + y; + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 8, 0, "Keyword"], + [4, 12, 0, "Identifier"], + [5, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static + { + var x, + y; + } + } + `, + output: unIndent` + class C { + static + { + var x, + y; + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 4, 0, "Punctuator"], + [4, 8, 0, "Keyword"], + [5, 12, 0, "Identifier"], + [6, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + if (foo) { + bar; + } + } + } + `, + output: unIndent` + class C { + static { + if (foo) { + bar; + } + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 8, 0, "Keyword"], + [4, 12, 0, "Identifier"], + [5, 8, 0, "Punctuator"], + [6, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static { + { + bar; + } + } + } + `, + output: unIndent` + class C { + static { + { + bar; + } + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 8, 0, "Punctuator"], + [4, 12, 0, "Identifier"], + [5, 8, 0, "Punctuator"], + [6, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + static {} + + static { + } + + static + { + } + } + `, + output: unIndent` + class C { + static {} + + static { + } + + static + { + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [4, 4, 0, "Keyword"], + [5, 4, 0, "Punctuator"], + [7, 4, 0, "Keyword"], + [8, 4, 0, "Punctuator"], + [9, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + + static { + foo; + } + + static { + bar; + } + + } + `, + output: unIndent` + class C { + + static { + foo; + } + + static { + bar; + } + + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [3, 4, 0, "Keyword"], + [4, 8, 4, "Identifier"], + [5, 4, 0, "Punctuator"], + [7, 4, 0, "Keyword"], + [8, 8, 4, "Identifier"], + [9, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + + x = 1; + + static { + foo; + } + + y = 2; + + } + `, + output: unIndent` + class C { + + x = 1; + + static { + foo; + } + + y = 2; + + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [3, 4, 0, "Identifier"], + [5, 4, 0, "Keyword"], + [6, 8, 4, "Identifier"], + [7, 4, 0, "Punctuator"], + [9, 4, 0, "Identifier"] + ]) + }, + { + code: unIndent` + class C { + + method1(param) { + foo; + } + + static { + bar; + } + + method2(param) { + foo; + } + + } + `, + output: unIndent` + class C { + + method1(param) { + foo; + } + + static { + bar; + } + + method2(param) { + foo; + } + + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [3, 4, 0, "Identifier"], + [4, 8, 4, "Identifier"], + [5, 4, 0, "Punctuator"], + [7, 4, 0, "Keyword"], + [8, 8, 4, "Identifier"], + [9, 4, 0, "Punctuator"], + [11, 4, 0, "Identifier"], + [12, 8, 4, "Identifier"], + [13, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + function f() { + class C { + static { + foo(); + bar(); + } + } + } + `, + output: unIndent` + function f() { + class C { + static { + foo(); + bar(); + } + } + } + `, + options: [4], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Keyword"], + [3, 8, 0, "Keyword"], + [4, 12, 0, "Identifier"], + [5, 12, 0, "Identifier"], + [6, 8, 0, "Punctuator"], + [7, 4, 0, "Punctuator"] + ]) + }, + { + code: unIndent` + class C { + method() { + foo; + } + static { + bar; + } + } + `, + output: unIndent` + class C { + method() { + foo; + } + static { + bar; + } + } + `, + options: [4, { FunctionExpression: { body: 2 }, StaticBlock: { body: 2 } }], + parserOptions: { ecmaVersion: 2022 }, + errors: expectedErrors([ + [2, 4, 0, "Identifier"], + [3, 12, 0, "Identifier"], + [4, 4, 0, "Punctuator"], + [5, 4, 0, "Keyword"], + [6, 12, 0, "Identifier"], + [7, 4, 0, "Punctuator"] + ]) } ] });