Skip to content

Commit

Permalink
feat: update padding-line-between-statements for class static blocks (#…
Browse files Browse the repository at this point in the history
…15318)

Updates the `padding-line-between-statements` rule to apply to the top level of class static blocks.

Refs #15016
  • Loading branch information
mdjermanovic committed Nov 17, 2021
1 parent 6b85426 commit 9b666e0
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 1 deletion.
16 changes: 16 additions & 0 deletions docs/rules/padding-line-between-statements.md
Expand Up @@ -147,6 +147,13 @@ function foo() {
const a = 0;
bar();
}

class C {
static {
let a = 0;
bar();
}
}
```

Examples of **correct** code for the `[{ blankLine: "always", prev: ["const", "let", "var"], next: "*"}, { blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"]}]` configuration:
Expand Down Expand Up @@ -178,6 +185,15 @@ function foo() {

bar();
}

class C {
static {
let a = 0;
let b = 0;

bar();
}
}
```

----
Expand Down
2 changes: 2 additions & 0 deletions lib/rules/padding-line-between-statements.js
Expand Up @@ -618,9 +618,11 @@ module.exports = {
Program: enterScope,
BlockStatement: enterScope,
SwitchStatement: enterScope,
StaticBlock: enterScope,
"Program:exit": exitScope,
"BlockStatement:exit": exitScope,
"SwitchStatement:exit": exitScope,
"StaticBlock:exit": exitScope,

":statement": verify,

Expand Down
2 changes: 1 addition & 1 deletion lib/rules/utils/ast-utils.js
Expand Up @@ -35,7 +35,7 @@ const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|g
const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);

// A set of node types that can contain a list of statements
const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]);
const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "StaticBlock", "SwitchCase"]);

const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u;

Expand Down
219 changes: 219 additions & 0 deletions tests/lib/rules/padding-line-between-statements.js
Expand Up @@ -2626,6 +2626,114 @@ ruleTester.run("padding-line-between-statements", rule, {
options: [
{ blankLine: "always", prev: "block-like", next: "block-like" }
]
},

// class static blocks
{
code: "class C {\n static {\n let x;\n\n foo();\n }\n }",
options: [
{ blankLine: "always", prev: "let", next: "expression" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C {\n static {\n let x;\n foo();\n }\n }",
options: [
{ blankLine: "never", prev: "let", next: "expression" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C {\n static {\n let x;\n foo();\n\n const y = 1;\n }\n }",
options: [
{ blankLine: "always", prev: "expression", next: "const" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C {\n static {\n let x;\n foo();\n const y = 1;\n }\n }",
options: [
{ blankLine: "never", prev: "expression", next: "const" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C {\n static {\n let x;\n foo();\n\n const y = 1;\n const z = 1;\n }\n }",
options: [
{ blankLine: "always", prev: "expression", next: "const" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C {\n static {\n let x;\n foo();\n const y = 1;\n const z = 1;\n }\n }",
options: [
{ blankLine: "never", prev: "expression", next: "const" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C {\n static {\n let a = 0;\n let b =0;\n\n bar();\n }\n }",
options: [
{ blankLine: "always", prev: ["const", "let", "var"], next: "*" },
{ blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"] }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static { let x; { let y; } let z; } }",
options: [
{ blankLine: "always", prev: "let", next: "let" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { method() { let x; } static { let y; } }",
options: [
{ blankLine: "always", prev: "let", next: "let" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static { let y; } method() { let x; } }",
options: [
{ blankLine: "always", prev: "let", next: "let" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static { let x; } static { let y; } }",
options: [
{ blankLine: "always", prev: "let", next: "let" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "let x; class C { static { let y; } }",
options: [
{ blankLine: "always", prev: "let", next: "let" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static { let x; } } let y;",
options: [
{ blankLine: "always", prev: "let", next: "let" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static { let x; } }",
options: [
{ blankLine: "always", prev: "class", next: "let" }
],
parserOptions: { ecmaVersion: 2022 }
},
{
code: "class C { static { 'use strict'; let x; } }", // 'use strict'; is "espression", because class static blocks don't have directives
options: [
{ blankLine: "always", prev: "directive", next: "let" }
],
parserOptions: { ecmaVersion: 2022 }
}
],
invalid: [
Expand Down Expand Up @@ -4976,6 +5084,117 @@ ruleTester.run("padding-line-between-statements", rule, {
{ messageId: "expectedBlankLine" },
{ messageId: "expectedBlankLine" }
]
},

// class static blocks
{
code: "class C {\n static {\n let x;\n foo();\n }\n }",
output: "class C {\n static {\n let x;\n\n foo();\n }\n }",
options: [
{ blankLine: "always", prev: "let", next: "expression" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
},
{
code: "class C {\n static {\n let x;\n\n foo();\n }\n }",
output: "class C {\n static {\n let x;\n foo();\n }\n }",
options: [
{ blankLine: "never", prev: "let", next: "expression" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "unexpectedBlankLine" }]
},
{
code: "class C {\n static {\n let x;\n foo();\n const y = 1;\n }\n }",
output: "class C {\n static {\n let x;\n foo();\n\n const y = 1;\n }\n }",
options: [
{ blankLine: "always", prev: "expression", next: "const" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
},
{
code: "class C {\n static {\n let x;\n foo();\n\n const y = 1;\n }\n }",
output: "class C {\n static {\n let x;\n foo();\n const y = 1;\n }\n }",
options: [
{ blankLine: "never", prev: "expression", next: "const" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "unexpectedBlankLine" }]
},
{
code: "class C {\n static {\n let x;\n foo();\n const y = 1;\n const z = 1;\n }\n }",
output: "class C {\n static {\n let x;\n foo();\n\n const y = 1;\n const z = 1;\n }\n }",
options: [
{ blankLine: "always", prev: "expression", next: "const" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
},
{
code: "class C {\n static {\n let x;\n foo();\n\n const y = 1;\n const z = 1;\n }\n }",
output: "class C {\n static {\n let x;\n foo();\n const y = 1;\n const z = 1;\n }\n }",
options: [
{ blankLine: "never", prev: "expression", next: "const" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "unexpectedBlankLine" }]
},
{
code: "class C {\n static {\n let a = 0;\n bar();\n }\n }",
output: "class C {\n static {\n let a = 0;\n\n bar();\n }\n }",
options: [
{ blankLine: "always", prev: ["const", "let", "var"], next: "*" },
{ blankLine: "any", prev: ["const", "let", "var"], next: ["const", "let", "var"] }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
},
{
code: "class C { static { let x; { let y; let z; } let q; } }",
output: "class C { static { let x; { let y;\n\n let z; } let q; } }",
options: [
{ blankLine: "always", prev: "let", next: "let" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
},
{
code: "class C { static { { let x; } let y; let z; } }",
output: "class C { static { { let x; } let y;\n\n let z; } }",
options: [
{ blankLine: "always", prev: "let", next: "let" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
},
{
code: "class C { static { foo(); if (bar) {} } }",
output: "class C { static { foo();\n\n if (bar) {} } }",
options: [
{ blankLine: "always", prev: "expression", next: "block-like" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
},
{
code: "class C { static { let x; } } let y;",
output: "class C { static { let x; } }\n\n let y;",
options: [
{ blankLine: "always", prev: "class", next: "let" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
},
{
code: "class C { static { 'use strict'; let x; } }", // 'use strict'; is "espression", because class static blocks don't have directives
output: "class C { static { 'use strict';\n\n let x; } }",
options: [
{ blankLine: "always", prev: "expression", next: "let" }
],
parserOptions: { ecmaVersion: 2022 },
errors: [{ messageId: "expectedBlankLine" }]
}
]
});

0 comments on commit 9b666e0

Please sign in to comment.