diff --git a/docs/developer-guide/code-path-analysis.md b/docs/developer-guide/code-path-analysis.md index 3507ff64142..f22eb8f3497 100644 --- a/docs/developer-guide/code-path-analysis.md +++ b/docs/developer-guide/code-path-analysis.md @@ -27,7 +27,7 @@ This has references of both the initial segment and the final segments of a code `CodePath` has the following properties: * `id` (`string`) - A unique string. Respective rules can use `id` to save additional information for each code path. -* `origin` (`string`) - The reason that the code path was started. May be `"program"`, `"function"`, or `"class-field-initializer"`. +* `origin` (`string`) - The reason that the code path was started. May be `"program"`, `"function"`, `"class-field-initializer"`, or `"class-static-block"`. * `initialSegment` (`CodePathSegment`) - The initial segment of this code path. * `finalSegments` (`CodePathSegment[]`) - The final segments which includes both returned and thrown. * `returnedSegments` (`CodePathSegment[]`) - The final segments which includes only returned. diff --git a/lib/linter/code-path-analysis/code-path-analyzer.js b/lib/linter/code-path-analysis/code-path-analyzer.js index d66c2f1be32..2dcc2734884 100644 --- a/lib/linter/code-path-analysis/code-path-analyzer.js +++ b/lib/linter/code-path-analysis/code-path-analyzer.js @@ -461,6 +461,10 @@ function processCodePathToEnter(analyzer, node) { startCodePath("function"); break; + case "StaticBlock": + startCodePath("class-static-block"); + break; + case "ChainExpression": state.pushChainContext(); break; @@ -706,7 +710,8 @@ function postprocess(analyzer, node) { case "Program": case "FunctionDeclaration": case "FunctionExpression": - case "ArrowFunctionExpression": { + case "ArrowFunctionExpression": + case "StaticBlock": { endCodePath(); break; } diff --git a/lib/linter/code-path-analysis/code-path.js b/lib/linter/code-path-analysis/code-path.js index f225c09a1d5..0e666277094 100644 --- a/lib/linter/code-path-analysis/code-path.js +++ b/lib/linter/code-path-analysis/code-path.js @@ -40,7 +40,7 @@ class CodePath { /** * The reason that this code path was started. May be "program", - * "function", or "class-field-initializer". + * "function", "class-field-initializer", or "class-static-block". * @type {string} */ this.origin = origin; diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--between-fields.js b/tests/fixtures/code-path-analysis/class-static-blocks--between-fields.js new file mode 100644 index 00000000000..9bf8edfefca --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--between-fields.js @@ -0,0 +1,65 @@ +/*expected +initial->s2_1->s2_2->s2_3; +s2_1->s2_3->final; +*/ +/*expected +initial->s3_1->s3_2->s3_3->s3_4; +s3_1->s3_4; +s3_2->s3_4->final; +*/ +/*expected +initial->s4_1->s4_2->s4_3->s4_4->s4_5; +s4_1->s4_5; +s4_2->s4_5; +s4_3->s4_5->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { bar = a || b; static { x || y || z } baz = p || q || r || s; } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="LogicalExpression:enter\nIdentifier (a)"]; + s2_2[label="Identifier (b)"]; + s2_3[label="LogicalExpression:exit"]; + initial->s2_1->s2_2->s2_3; + s2_1->s2_3->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s3_1[label="StaticBlock:enter\nExpressionStatement:enter\nLogicalExpression:enter\nLogicalExpression:enter\nIdentifier (x)"]; + s3_2[label="Identifier (y)\nLogicalExpression:exit"]; + s3_3[label="Identifier (z)"]; + s3_4[label="LogicalExpression:exit\nExpressionStatement:exit\nStaticBlock:exit"]; + initial->s3_1->s3_2->s3_3->s3_4; + s3_1->s3_4; + s3_2->s3_4->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s4_1[label="LogicalExpression:enter\nLogicalExpression:enter\nLogicalExpression:enter\nIdentifier (p)"]; + s4_2[label="Identifier (q)\nLogicalExpression:exit"]; + s4_3[label="Identifier (r)\nLogicalExpression:exit"]; + s4_4[label="Identifier (s)"]; + s4_5[label="LogicalExpression:exit"]; + initial->s4_1->s4_2->s4_3->s4_4->s4_5; + s4_1->s4_5; + s4_2->s4_5; + s4_3->s4_5->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nPropertyDefinition:enter\nIdentifier (bar)\nLogicalExpression\nPropertyDefinition:exit\nStaticBlock\nPropertyDefinition:enter\nIdentifier (baz)\nLogicalExpression\nPropertyDefinition:exit\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--between-methods.js b/tests/fixtures/code-path-analysis/class-static-blocks--between-methods.js new file mode 100644 index 00000000000..a6de6909a3f --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--between-methods.js @@ -0,0 +1,65 @@ +/*expected +initial->s2_1->s2_2->s2_3; +s2_1->s2_3->final; +*/ +/*expected +initial->s3_1->s3_2->s3_3->s3_4; +s3_1->s3_4; +s3_2->s3_4->final; +*/ +/*expected +initial->s4_1->s4_2->s4_3->s4_4->s4_5; +s4_1->s4_5; +s4_2->s4_5; +s4_3->s4_5->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { bar () { a || b } static { x || y || z } baz() { p || q || r || s } } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="FunctionExpression:enter\nBlockStatement:enter\nExpressionStatement:enter\nLogicalExpression:enter\nIdentifier (a)"]; + s2_2[label="Identifier (b)"]; + s2_3[label="LogicalExpression:exit\nExpressionStatement:exit\nBlockStatement:exit\nFunctionExpression:exit"]; + initial->s2_1->s2_2->s2_3; + s2_1->s2_3->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s3_1[label="StaticBlock:enter\nExpressionStatement:enter\nLogicalExpression:enter\nLogicalExpression:enter\nIdentifier (x)"]; + s3_2[label="Identifier (y)\nLogicalExpression:exit"]; + s3_3[label="Identifier (z)"]; + s3_4[label="LogicalExpression:exit\nExpressionStatement:exit\nStaticBlock:exit"]; + initial->s3_1->s3_2->s3_3->s3_4; + s3_1->s3_4; + s3_2->s3_4->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s4_1[label="FunctionExpression:enter\nBlockStatement:enter\nExpressionStatement:enter\nLogicalExpression:enter\nLogicalExpression:enter\nLogicalExpression:enter\nIdentifier (p)"]; + s4_2[label="Identifier (q)\nLogicalExpression:exit"]; + s4_3[label="Identifier (r)\nLogicalExpression:exit"]; + s4_4[label="Identifier (s)"]; + s4_5[label="LogicalExpression:exit\nExpressionStatement:exit\nBlockStatement:exit\nFunctionExpression:exit"]; + initial->s4_1->s4_2->s4_3->s4_4->s4_5; + s4_1->s4_5; + s4_2->s4_5; + s4_3->s4_5->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nMethodDefinition:enter\nIdentifier (bar)\nFunctionExpression\nMethodDefinition:exit\nStaticBlock\nMethodDefinition:enter\nIdentifier (baz)\nFunctionExpression\nMethodDefinition:exit\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--conditional.js b/tests/fixtures/code-path-analysis/class-static-blocks--conditional.js new file mode 100644 index 00000000000..bcdb4a7ec73 --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--conditional.js @@ -0,0 +1,29 @@ +/*expected +initial->s2_1->s2_2->s2_4; +s2_1->s2_3->s2_4->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { static { this.bar = a ? b : c; } } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="StaticBlock:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nThisExpression\nIdentifier (bar)\nMemberExpression:exit\nConditionalExpression:enter\nIdentifier (a)"]; + s2_2[label="Identifier (b)"]; + s2_4[label="ConditionalExpression:exit\nAssignmentExpression:exit\nExpressionStatement:exit\nStaticBlock:exit"]; + s2_3[label="Identifier (c)"]; + initial->s2_1->s2_2->s2_4; + s2_1->s2_3->s2_4->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nStaticBlock\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--empty.js b/tests/fixtures/code-path-analysis/class-static-blocks--empty.js new file mode 100644 index 00000000000..40a1e71ae54 --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--empty.js @@ -0,0 +1,24 @@ +/*expected +initial->s2_1->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { static {} } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="StaticBlock"]; + initial->s2_1->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nStaticBlock\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--function-inside.js b/tests/fixtures/code-path-analysis/class-static-blocks--function-inside.js new file mode 100644 index 00000000000..49df347f09a --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--function-inside.js @@ -0,0 +1,34 @@ +/*expected +initial->s3_1->final; +*/ +/*expected +initial->s2_1->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { static { (p) => {} } } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s3_1[label="ArrowFunctionExpression:enter\nIdentifier (p)\nBlockStatement\nArrowFunctionExpression:exit"]; + initial->s3_1->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="StaticBlock:enter\nExpressionStatement:enter\nArrowFunctionExpression\nExpressionStatement:exit\nStaticBlock:exit"]; + initial->s2_1->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nStaticBlock\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--if-else.js b/tests/fixtures/code-path-analysis/class-static-blocks--if-else.js new file mode 100644 index 00000000000..7b4a542bc55 --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--if-else.js @@ -0,0 +1,29 @@ +/*expected +initial->s2_1->s2_2->s2_4; +s2_1->s2_3->s2_4->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { static { if (bar) { this.baz = 1; } else { this.qux = 2; } } } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="StaticBlock:enter\nIfStatement:enter\nIdentifier (bar)"]; + s2_2[label="BlockStatement:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nThisExpression\nIdentifier (baz)\nMemberExpression:exit\nLiteral (1)\nAssignmentExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s2_4[label="IfStatement:exit\nStaticBlock:exit"]; + s2_3[label="BlockStatement:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nThisExpression\nIdentifier (qux)\nMemberExpression:exit\nLiteral (2)\nAssignmentExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + initial->s2_1->s2_2->s2_4; + s2_1->s2_3->s2_4->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nStaticBlock\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--multiple-1.js b/tests/fixtures/code-path-analysis/class-static-blocks--multiple-1.js new file mode 100644 index 00000000000..67365fb2fc8 --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--multiple-1.js @@ -0,0 +1,34 @@ +/*expected +initial->s2_1->final; +*/ +/*expected +initial->s3_1->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { static { this.bar = 1; } static { this.baz = 2; } } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="StaticBlock:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nThisExpression\nIdentifier (bar)\nMemberExpression:exit\nLiteral (1)\nAssignmentExpression:exit\nExpressionStatement:exit\nStaticBlock:exit"]; + initial->s2_1->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s3_1[label="StaticBlock:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nThisExpression\nIdentifier (baz)\nMemberExpression:exit\nLiteral (2)\nAssignmentExpression:exit\nExpressionStatement:exit\nStaticBlock:exit"]; + initial->s3_1->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nStaticBlock\nStaticBlock\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--multiple-2.js b/tests/fixtures/code-path-analysis/class-static-blocks--multiple-2.js new file mode 100644 index 00000000000..218d18a78be --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--multiple-2.js @@ -0,0 +1,45 @@ +/*expected +initial->s2_1->s2_2->s2_3->s2_4; +s2_1->s2_4; +s2_2->s2_4->final; +*/ +/*expected +initial->s3_1->s3_2->s3_3; +s3_1->s3_3->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { static { x || y || z } static { p || q } } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="StaticBlock:enter\nExpressionStatement:enter\nLogicalExpression:enter\nLogicalExpression:enter\nIdentifier (x)"]; + s2_2[label="Identifier (y)\nLogicalExpression:exit"]; + s2_3[label="Identifier (z)"]; + s2_4[label="LogicalExpression:exit\nExpressionStatement:exit\nStaticBlock:exit"]; + initial->s2_1->s2_2->s2_3->s2_4; + s2_1->s2_4; + s2_2->s2_4->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s3_1[label="StaticBlock:enter\nExpressionStatement:enter\nLogicalExpression:enter\nIdentifier (p)"]; + s3_2[label="Identifier (q)"]; + s3_3[label="LogicalExpression:exit\nExpressionStatement:exit\nStaticBlock:exit"]; + initial->s3_1->s3_2->s3_3; + s3_1->s3_3->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nStaticBlock\nStaticBlock\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/class-static-blocks--simple.js b/tests/fixtures/code-path-analysis/class-static-blocks--simple.js new file mode 100644 index 00000000000..06bb73787bf --- /dev/null +++ b/tests/fixtures/code-path-analysis/class-static-blocks--simple.js @@ -0,0 +1,24 @@ +/*expected +initial->s2_1->final; +*/ +/*expected +initial->s1_1->final; +*/ +class Foo { static { this.bar = baz; } } + +/*DOT +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s2_1[label="StaticBlock:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nThisExpression\nIdentifier (bar)\nMemberExpression:exit\nIdentifier (baz)\nAssignmentExpression:exit\nExpressionStatement:exit\nStaticBlock:exit"]; + initial->s2_1->final; +} +digraph { + node[shape=box,style="rounded,filled",fillcolor=white]; + initial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25]; + final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25]; + s1_1[label="Program:enter\nClassDeclaration:enter\nIdentifier (Foo)\nClassBody:enter\nStaticBlock\nClassBody:exit\nClassDeclaration:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/lib/linter/code-path-analysis/code-path.js b/tests/lib/linter/code-path-analysis/code-path.js index 42a63a280df..760d5b39989 100644 --- a/tests/lib/linter/code-path-analysis/code-path.js +++ b/tests/lib/linter/code-path-analysis/code-path.js @@ -106,6 +106,12 @@ describe("CodePathAnalyzer", () => { assert.strictEqual(codePath.origin, "class-field-initializer"); }); + + it("should be 'class-static-block' when code path starts inside a class static block", () => { + const codePath = parseCodePaths("class Foo { static { this.a=1; } }")[1]; + + assert.strictEqual(codePath.origin, "class-static-block"); + }); }); describe(".traverseSegments()", () => {