From 58abd9311900a8af5a3c0963daaf64675bdd8383 Mon Sep 17 00:00:00 2001 From: Milos Djermanovic Date: Mon, 31 Aug 2020 23:30:12 +0200 Subject: [PATCH] Update: support logical assignments in code path analysis (refs #13569) (#13612) * Update: support logical assignment in code path analysis (refs #13569) * Fix minor formatting issues --- .../code-path-analysis/code-path-analyzer.js | 38 +++++++++++++++++++ .../code-path-analysis/code-path-state.js | 4 +- .../assignment--do-while-and.js | 21 ++++++++++ .../assignment--do-while-or.js | 21 ++++++++++ .../assignment--do-while-qq.js | 23 +++++++++++ .../assignment--for-and-1.js | 23 +++++++++++ .../assignment--for-and-2.js | 22 +++++++++++ .../assignment--for-or-1.js | 23 +++++++++++ .../assignment--for-or-2.js | 22 +++++++++++ .../assignment--for-qq-1.js | 25 ++++++++++++ .../assignment--for-qq-2.js | 24 ++++++++++++ .../assignment--if-and-1.js | 23 +++++++++++ .../assignment--if-and-2.js | 28 ++++++++++++++ .../assignment--if-and-3.js | 36 ++++++++++++++++++ .../code-path-analysis/assignment--if-or-1.js | 23 +++++++++++ .../code-path-analysis/assignment--if-or-2.js | 26 +++++++++++++ .../code-path-analysis/assignment--if-or-3.js | 36 ++++++++++++++++++ .../code-path-analysis/assignment--if-qq-1.js | 25 ++++++++++++ .../code-path-analysis/assignment--if-qq-2.js | 30 +++++++++++++++ .../assignment--logical-and-1.js | 21 ++++++++++ .../assignment--logical-and-2.js | 21 ++++++++++ .../assignment--logical-and-3.js | 21 ++++++++++ .../assignment--logical-or-1.js | 21 ++++++++++ .../assignment--logical-or-2.js | 21 ++++++++++ .../assignment--logical-or-3.js | 21 ++++++++++ .../assignment--logical-qq-1.js | 21 ++++++++++ .../assignment--logical-qq-2.js | 21 ++++++++++ .../assignment--logical-qq-3.js | 21 ++++++++++ .../code-path-analysis/assignment--multi-1.js | 21 ++++++++++ .../assignment--multi-10.js | 28 ++++++++++++++ .../code-path-analysis/assignment--multi-2.js | 21 ++++++++++ .../code-path-analysis/assignment--multi-3.js | 21 ++++++++++ .../code-path-analysis/assignment--multi-4.js | 21 ++++++++++ .../code-path-analysis/assignment--multi-5.js | 21 ++++++++++ .../code-path-analysis/assignment--multi-6.js | 21 ++++++++++ .../code-path-analysis/assignment--multi-7.js | 24 ++++++++++++ .../code-path-analysis/assignment--multi-8.js | 14 +++++++ .../code-path-analysis/assignment--multi-9.js | 24 ++++++++++++ .../assignment--nested-and-1.js | 21 ++++++++++ .../assignment--nested-and-2.js | 21 ++++++++++ .../assignment--nested-and-3.js | 21 ++++++++++ .../assignment--nested-or-1.js | 21 ++++++++++ .../assignment--nested-or-2.js | 21 ++++++++++ .../assignment--nested-or-3.js | 21 ++++++++++ .../assignment--nested-qq-1.js | 23 +++++++++++ .../assignment--nested-qq-2.js | 23 +++++++++++ .../assignment--nested-qq-3.js | 21 ++++++++++ .../assignment--simple-and-1.js | 18 +++++++++ .../assignment--simple-and-2.js | 25 ++++++++++++ .../assignment--simple-and-3.js | 21 ++++++++++ .../assignment--simple-bitand.js | 14 +++++++ .../assignment--simple-eq.js | 14 +++++++ .../assignment--simple-or-1.js | 18 +++++++++ .../assignment--simple-or-2.js | 25 ++++++++++++ .../assignment--simple-or-3.js | 21 ++++++++++ .../assignment--simple-plus.js | 14 +++++++ .../assignment--simple-qq-1.js | 18 +++++++++ .../assignment--simple-qq-2.js | 25 ++++++++++++ .../assignment--simple-qq-3.js | 21 ++++++++++ .../assignment--while-and.js | 22 +++++++++++ .../assignment--while-or.js | 22 +++++++++++ .../assignment--while-qq.js | 24 ++++++++++++ .../code-path-analysis/code-path-analyzer.js | 2 +- tests/lib/rules/no-this-before-super.js | 19 ++++++++++ 64 files changed, 1391 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/code-path-analysis/assignment--do-while-and.js create mode 100644 tests/fixtures/code-path-analysis/assignment--do-while-or.js create mode 100644 tests/fixtures/code-path-analysis/assignment--do-while-qq.js create mode 100644 tests/fixtures/code-path-analysis/assignment--for-and-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--for-and-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--for-or-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--for-or-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--for-qq-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--for-qq-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--if-and-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--if-and-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--if-and-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--if-or-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--if-or-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--if-or-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--if-qq-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--if-qq-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-and-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-and-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-and-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-or-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-or-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-or-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-qq-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-qq-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--logical-qq-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-10.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-4.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-5.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-6.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-7.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-8.js create mode 100644 tests/fixtures/code-path-analysis/assignment--multi-9.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-and-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-and-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-and-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-or-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-or-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-or-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-qq-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-qq-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--nested-qq-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-and-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-and-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-and-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-bitand.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-eq.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-or-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-or-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-or-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-plus.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-qq-1.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-qq-2.js create mode 100644 tests/fixtures/code-path-analysis/assignment--simple-qq-3.js create mode 100644 tests/fixtures/code-path-analysis/assignment--while-and.js create mode 100644 tests/fixtures/code-path-analysis/assignment--while-or.js create mode 100644 tests/fixtures/code-path-analysis/assignment--while-qq.js diff --git a/lib/linter/code-path-analysis/code-path-analyzer.js b/lib/linter/code-path-analysis/code-path-analyzer.js index 3a0cda51118..47427c11a3d 100644 --- a/lib/linter/code-path-analysis/code-path-analyzer.js +++ b/lib/linter/code-path-analysis/code-path-analyzer.js @@ -39,6 +39,17 @@ function isHandledLogicalOperator(operator) { return operator === "&&" || operator === "||" || operator === "??"; } +/** + * Checks whether the given assignment operator is a logical assignment operator. + * Logical assignments are taken into account for the code path analysis + * because of their short-circuiting semantics. + * @param {string} operator The operator found in the AssignmentExpression node + * @returns {boolean} `true` if the operator is "&&=" or "||=" or "??=" + */ +function isLogicalAssignmentOperator(operator) { + return operator === "&&=" || operator === "||=" || operator === "??="; +} + /** * Gets the label if the parent node of a given node is a LabeledStatement. * @param {ASTNode} node A node to get. @@ -71,6 +82,9 @@ function isForkingByTrueOrFalse(node) { case "LogicalExpression": return isHandledLogicalOperator(parent.operator); + case "AssignmentExpression": + return isLogicalAssignmentOperator(parent.operator); + default: return false; } @@ -266,6 +280,15 @@ function preprocess(analyzer, node) { } break; + case "AssignmentExpression": + if ( + parent.right === node && + isLogicalAssignmentOperator(parent.operator) + ) { + state.makeLogicalRight(); + } + break; + case "ConditionalExpression": case "IfStatement": @@ -413,6 +436,15 @@ function processCodePathToEnter(analyzer, node) { } break; + case "AssignmentExpression": + if (isLogicalAssignmentOperator(node.operator)) { + state.pushChoiceContext( + node.operator.slice(0, -1), // removes `=` from the end + isForkingByTrueOrFalse(node) + ); + } + break; + case "ConditionalExpression": case "IfStatement": state.pushChoiceContext("test", false); @@ -491,6 +523,12 @@ function processCodePathToExit(analyzer, node) { } break; + case "AssignmentExpression": + if (isLogicalAssignmentOperator(node.operator)) { + state.popChoiceContext(); + } + break; + case "SwitchStatement": state.popSwitchContext(); break; diff --git a/lib/linter/code-path-analysis/code-path-state.js b/lib/linter/code-path-analysis/code-path-state.js index f2b16d07e0d..f75e60e28a8 100644 --- a/lib/linter/code-path-analysis/code-path-state.js +++ b/lib/linter/code-path-analysis/code-path-state.js @@ -317,7 +317,7 @@ class CodePathState { //-------------------------------------------------------------------------- /** - * Creates a context for ConditionalExpression, LogicalExpression, + * Creates a context for ConditionalExpression, LogicalExpression, AssignmentExpression (logical assignments only), * IfStatement, WhileStatement, DoWhileStatement, or ForStatement. * * LogicalExpressions have cases that it goes different paths between the @@ -339,7 +339,7 @@ class CodePathState { * a -> b -> foo(); * a -> b -> bar(); * @param {string} kind A kind string. - * If the new context is LogicalExpression's, this is `"&&"` or `"||"`. + * If the new context is LogicalExpression's or AssignmentExpression's, this is `"&&"` or `"||"` or `"??"`. * If it's IfStatement's or ConditionalExpression's, this is `"test"`. * Otherwise, this is `"loop"`. * @param {boolean} isForkingAsResult A flag that shows that goes different diff --git a/tests/fixtures/code-path-analysis/assignment--do-while-and.js b/tests/fixtures/code-path-analysis/assignment--do-while-and.js new file mode 100644 index 00000000000..35452116a72 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--do-while-and.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_2->s1_4; +s1_3->s1_4->final; +*/ +do { + foo(); +} while (a &&= b); + +/*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]; + s1_1[label="Program:enter\nDoWhileStatement:enter"]; + s1_2[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="DoWhileStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_2->s1_4; + s1_3->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--do-while-or.js b/tests/fixtures/code-path-analysis/assignment--do-while-or.js new file mode 100644 index 00000000000..6762c6922af --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--do-while-or.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_2->s1_2; +s1_3->s1_4->final; +*/ +do { + foo(); +} while (a ||= b); + +/*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]; + s1_1[label="Program:enter\nDoWhileStatement:enter"]; + s1_2[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="DoWhileStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_2->s1_2; + s1_3->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--do-while-qq.js b/tests/fixtures/code-path-analysis/assignment--do-while-qq.js new file mode 100644 index 00000000000..f35b62056d9 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--do-while-qq.js @@ -0,0 +1,23 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_2->s1_2; +s1_3->s1_4; +s1_2->s1_4->final; +*/ +do { + foo(); +} while (a ??= b); + +/*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]; + s1_1[label="Program:enter\nDoWhileStatement:enter"]; + s1_2[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="DoWhileStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_2->s1_2; + s1_3->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--for-and-1.js b/tests/fixtures/code-path-analysis/assignment--for-and-1.js new file mode 100644 index 00000000000..d135f6f0d09 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--for-and-1.js @@ -0,0 +1,23 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_2->s1_6; +s1_3->s1_6->final; +*/ +for (init; a &&= b; update) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nForStatement:enter\nIdentifier (init)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="Identifier (update)"]; + s1_6[label="ForStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_2->s1_6; + s1_3->s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--for-and-2.js b/tests/fixtures/code-path-analysis/assignment--for-and-2.js new file mode 100644 index 00000000000..7f373b072eb --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--for-and-2.js @@ -0,0 +1,22 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_5; +s1_3->s1_5->final; +*/ +for (init; a &&= b;) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nForStatement:enter\nIdentifier (init)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="ForStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_5; + s1_3->s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--for-or-1.js b/tests/fixtures/code-path-analysis/assignment--for-or-1.js new file mode 100644 index 00000000000..e04977a7346 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--for-or-1.js @@ -0,0 +1,23 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_2->s1_4; +s1_3->s1_6->final; +*/ +for (init; a ||= b; update) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nForStatement:enter\nIdentifier (init)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="Identifier (update)"]; + s1_6[label="ForStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_2->s1_4; + s1_3->s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--for-or-2.js b/tests/fixtures/code-path-analysis/assignment--for-or-2.js new file mode 100644 index 00000000000..58648a4e3a6 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--for-or-2.js @@ -0,0 +1,22 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4; +s1_3->s1_5->final; +*/ +for (init; a ||= b;) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nForStatement:enter\nIdentifier (init)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="ForStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4; + s1_3->s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--for-qq-1.js b/tests/fixtures/code-path-analysis/assignment--for-qq-1.js new file mode 100644 index 00000000000..85efdc36a20 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--for-qq-1.js @@ -0,0 +1,25 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_2->s1_4; +s1_3->s1_6; +s1_2->s1_6->final; +*/ +for (init; a ??= b; update) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nForStatement:enter\nIdentifier (init)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="Identifier (update)"]; + s1_6[label="ForStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_2->s1_4; + s1_3->s1_6; + s1_2->s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--for-qq-2.js b/tests/fixtures/code-path-analysis/assignment--for-qq-2.js new file mode 100644 index 00000000000..cf5d31f0814 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--for-qq-2.js @@ -0,0 +1,24 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4; +s1_3->s1_5; +s1_2->s1_5->final; +*/ +for (init; a ??= b;) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nForStatement:enter\nIdentifier (init)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="ForStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4; + s1_3->s1_5; + s1_2->s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--if-and-1.js b/tests/fixtures/code-path-analysis/assignment--if-and-1.js new file mode 100644 index 00000000000..d16b407ac9d --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--if-and-1.js @@ -0,0 +1,23 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +if (a &&= b) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nIfStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_4[label="IfStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--if-and-2.js b/tests/fixtures/code-path-analysis/assignment--if-and-2.js new file mode 100644 index 00000000000..cbf18927916 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--if-and-2.js @@ -0,0 +1,28 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_5; +s1_1->s1_4->s1_5; +s1_2->s1_4; +s1_5->final; +*/ +if (a &&= b) { + foo(); +} else { + bar(); +} + +/*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]; + s1_1[label="Program:enter\nIfStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="IfStatement:exit\nProgram:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + initial->s1_1->s1_2->s1_3->s1_5; + s1_1->s1_4->s1_5; + s1_2->s1_4; + s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--if-and-3.js b/tests/fixtures/code-path-analysis/assignment--if-and-3.js new file mode 100644 index 00000000000..ad6c18790d9 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--if-and-3.js @@ -0,0 +1,36 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_7->s1_9; +s1_1->s1_8->s1_9; +s1_2->s1_8; +s1_3->s1_8; +s1_4->s1_6->s1_7; +s1_9->final; +*/ +if ((a &&= b) && c) { + d ? foo() : bar(); +} else { + 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]; + s1_1[label="Program:enter\nIfStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nConditionalExpression:enter\nIdentifier (d)"]; + s1_5[label="CallExpression:enter\nIdentifier (foo)\nCallExpression:exit"]; + s1_7[label="ConditionalExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_9[label="IfStatement:exit\nProgram:exit"]; + s1_8[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (baz)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_6[label="CallExpression:enter\nIdentifier (bar)\nCallExpression:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_7->s1_9; + s1_1->s1_8->s1_9; + s1_2->s1_8; + s1_3->s1_8; + s1_4->s1_6->s1_7; + s1_9->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--if-or-1.js b/tests/fixtures/code-path-analysis/assignment--if-or-1.js new file mode 100644 index 00000000000..1a2bd7df3b1 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--if-or-1.js @@ -0,0 +1,23 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_3; +s1_2->s1_4->final; +*/ +if (a ||= b) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nIfStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_4[label="IfStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_3; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--if-or-2.js b/tests/fixtures/code-path-analysis/assignment--if-or-2.js new file mode 100644 index 00000000000..628ef60a5d9 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--if-or-2.js @@ -0,0 +1,26 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_5; +s1_1->s1_3; +s1_2->s1_4->s1_5->final; +*/ +if (a ||= b) { + foo(); +} else { + bar(); +} + +/*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]; + s1_1[label="Program:enter\nIfStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="IfStatement:exit\nProgram:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + initial->s1_1->s1_2->s1_3->s1_5; + s1_1->s1_3; + s1_2->s1_4->s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--if-or-3.js b/tests/fixtures/code-path-analysis/assignment--if-or-3.js new file mode 100644 index 00000000000..cfef916f799 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--if-or-3.js @@ -0,0 +1,36 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_7->s1_9; +s1_1->s1_4; +s1_2->s1_4; +s1_3->s1_8->s1_9; +s1_4->s1_6->s1_7; +s1_9->final; +*/ +if ((a ||= b) || c) { + d ? foo() : bar(); +} else { + 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]; + s1_1[label="Program:enter\nIfStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nConditionalExpression:enter\nIdentifier (d)"]; + s1_5[label="CallExpression:enter\nIdentifier (foo)\nCallExpression:exit"]; + s1_7[label="ConditionalExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_9[label="IfStatement:exit\nProgram:exit"]; + s1_8[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (baz)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_6[label="CallExpression:enter\nIdentifier (bar)\nCallExpression:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_5->s1_7->s1_9; + s1_1->s1_4; + s1_2->s1_4; + s1_3->s1_8->s1_9; + s1_4->s1_6->s1_7; + s1_9->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--if-qq-1.js b/tests/fixtures/code-path-analysis/assignment--if-qq-1.js new file mode 100644 index 00000000000..847ea79c579 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--if-qq-1.js @@ -0,0 +1,25 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_3; +s1_2->s1_4; +s1_1->s1_4->final; +*/ +if (a ??= b) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nIfStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_4[label="IfStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_3; + s1_2->s1_4; + s1_1->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--if-qq-2.js b/tests/fixtures/code-path-analysis/assignment--if-qq-2.js new file mode 100644 index 00000000000..50b2fdbd639 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--if-qq-2.js @@ -0,0 +1,30 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_5; +s1_1->s1_3; +s1_2->s1_4->s1_5; +s1_1->s1_4; +s1_5->final; +*/ +if (a ??= b) { + foo(); +} else { + bar(); +} + +/*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]; + s1_1[label="Program:enter\nIfStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="IfStatement:exit\nProgram:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (bar)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + initial->s1_1->s1_2->s1_3->s1_5; + s1_1->s1_3; + s1_2->s1_4->s1_5; + s1_1->s1_4; + s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-and-1.js b/tests/fixtures/code-path-analysis/assignment--logical-and-1.js new file mode 100644 index 00000000000..f8d4b448cb6 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-and-1.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-and-2.js b/tests/fixtures/code-path-analysis/assignment--logical-and-2.js new file mode 100644 index 00000000000..2ad1da1437d --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-and-2.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-and-3.js b/tests/fixtures/code-path-analysis/assignment--logical-and-3.js new file mode 100644 index 00000000000..ff80195c88b --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-and-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-or-1.js b/tests/fixtures/code-path-analysis/assignment--logical-or-1.js new file mode 100644 index 00000000000..8f51a6ed95d --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-or-1.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-or-2.js b/tests/fixtures/code-path-analysis/assignment--logical-or-2.js new file mode 100644 index 00000000000..7878072176d --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-or-2.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-or-3.js b/tests/fixtures/code-path-analysis/assignment--logical-or-3.js new file mode 100644 index 00000000000..52498d17a07 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-or-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-qq-1.js b/tests/fixtures/code-path-analysis/assignment--logical-qq-1.js new file mode 100644 index 00000000000..8b2873c1e6f --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-qq-1.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-qq-2.js b/tests/fixtures/code-path-analysis/assignment--logical-qq-2.js new file mode 100644 index 00000000000..dc17fb4a36f --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-qq-2.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--logical-qq-3.js b/tests/fixtures/code-path-analysis/assignment--logical-qq-3.js new file mode 100644 index 00000000000..6baaeecfbd4 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--logical-qq-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="LogicalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nLogicalExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-1.js b/tests/fixtures/code-path-analysis/assignment--multi-1.js new file mode 100644 index 00000000000..fd7300d9995 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-1.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nAssignmentExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-10.js b/tests/fixtures/code-path-analysis/assignment--multi-10.js new file mode 100644 index 00000000000..dc4785c7e42 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-10.js @@ -0,0 +1,28 @@ +/*expected +initial->s1_1->s1_2->s1_4->s1_5->s1_6->s1_8->s1_9; +s1_1->s1_3->s1_4->s1_9; +s1_5->s1_7->s1_8; +s1_9->final; +*/ +a[b ? c : d] ||= e[f ? g : h] = i; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nIdentifier (a)\nConditionalExpression:enter\nIdentifier (b)"]; + s1_2[label="Identifier (c)"]; + s1_4[label="ConditionalExpression:exit\nMemberExpression:exit"]; + s1_5[label="AssignmentExpression:enter\nMemberExpression:enter\nIdentifier (e)\nConditionalExpression:enter\nIdentifier (f)"]; + s1_6[label="Identifier (g)"]; + s1_8[label="ConditionalExpression:exit\nMemberExpression:exit\nIdentifier (i)\nAssignmentExpression:exit"]; + s1_9[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + s1_3[label="Identifier (d)"]; + s1_7[label="Identifier (h)"]; + initial->s1_1->s1_2->s1_4->s1_5->s1_6->s1_8->s1_9; + s1_1->s1_3->s1_4->s1_9; + s1_5->s1_7->s1_8; + s1_9->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-2.js b/tests/fixtures/code-path-analysis/assignment--multi-2.js new file mode 100644 index 00000000000..4267d065ca6 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-2.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nAssignmentExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-3.js b/tests/fixtures/code-path-analysis/assignment--multi-3.js new file mode 100644 index 00000000000..00befa172a6 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nAssignmentExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-4.js b/tests/fixtures/code-path-analysis/assignment--multi-4.js new file mode 100644 index 00000000000..ef6e42937a1 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-4.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nAssignmentExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-5.js b/tests/fixtures/code-path-analysis/assignment--multi-5.js new file mode 100644 index 00000000000..084fd01528b --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-5.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nAssignmentExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-6.js b/tests/fixtures/code-path-analysis/assignment--multi-6.js new file mode 100644 index 00000000000..b8841865097 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-6.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)\nAssignmentExpression:exit"]; + s1_4[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-7.js b/tests/fixtures/code-path-analysis/assignment--multi-7.js new file mode 100644 index 00000000000..1deb49c7168 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-7.js @@ -0,0 +1,24 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_5; +s1_1->s1_5; +s1_2->s1_5; +s1_3->s1_5->final; +*/ +a ??= b ||= c &&= d; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (b)"]; + s1_3[label="AssignmentExpression:enter\nIdentifier (c)"]; + s1_4[label="Identifier (d)\nAssignmentExpression:exit\nAssignmentExpression:exit"]; + s1_5[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_5; + s1_1->s1_5; + s1_2->s1_5; + s1_3->s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-8.js b/tests/fixtures/code-path-analysis/assignment--multi-8.js new file mode 100644 index 00000000000..6dad336f512 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-8.js @@ -0,0 +1,14 @@ +/*expected +initial->s1_1->final; +*/ +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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)\nAssignmentExpression:enter\nIdentifier (b)\nIdentifier (c)\nAssignmentExpression:exit\nAssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--multi-9.js b/tests/fixtures/code-path-analysis/assignment--multi-9.js new file mode 100644 index 00000000000..679eeccbc68 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--multi-9.js @@ -0,0 +1,24 @@ +/*expected +initial->s1_1->s1_2->s1_4->s1_5->s1_7->s1_8->s1_9; +s1_1->s1_3->s1_4->s1_6->s1_7->s1_9->final; +*/ +a[b ? c : d] = e[f ? g : h] ||= i; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nIdentifier (a)\nConditionalExpression:enter\nIdentifier (b)"]; + s1_2[label="Identifier (c)"]; + s1_4[label="ConditionalExpression:exit\nMemberExpression:exit\nAssignmentExpression:enter\nMemberExpression:enter\nIdentifier (e)\nConditionalExpression:enter\nIdentifier (f)"]; + s1_5[label="Identifier (g)"]; + s1_7[label="ConditionalExpression:exit\nMemberExpression:exit"]; + s1_8[label="Identifier (i)"]; + s1_9[label="AssignmentExpression:exit\nAssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + s1_3[label="Identifier (d)"]; + s1_6[label="Identifier (h)"]; + initial->s1_1->s1_2->s1_4->s1_5->s1_7->s1_8->s1_9; + s1_1->s1_3->s1_4->s1_6->s1_7->s1_9->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-and-1.js b/tests/fixtures/code-path-analysis/assignment--nested-and-1.js new file mode 100644 index 00000000000..c80d582ea74 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-and-1.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-and-2.js b/tests/fixtures/code-path-analysis/assignment--nested-and-2.js new file mode 100644 index 00000000000..2cfdcc356ac --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-and-2.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_3; +s1_2->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_3; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-and-3.js b/tests/fixtures/code-path-analysis/assignment--nested-and-3.js new file mode 100644 index 00000000000..8bb52f02239 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-and-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-or-1.js b/tests/fixtures/code-path-analysis/assignment--nested-or-1.js new file mode 100644 index 00000000000..e0ec2e8e851 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-or-1.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_3; +s1_2->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_3; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-or-2.js b/tests/fixtures/code-path-analysis/assignment--nested-or-2.js new file mode 100644 index 00000000000..83983520152 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-or-2.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-or-3.js b/tests/fixtures/code-path-analysis/assignment--nested-or-3.js new file mode 100644 index 00000000000..a5cb26c95ee --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-or-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-qq-1.js b/tests/fixtures/code-path-analysis/assignment--nested-qq-1.js new file mode 100644 index 00000000000..65d178b0800 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-qq-1.js @@ -0,0 +1,23 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_3; +s1_2->s1_4; +s1_1->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_3; + s1_2->s1_4; + s1_1->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-qq-2.js b/tests/fixtures/code-path-analysis/assignment--nested-qq-2.js new file mode 100644 index 00000000000..1e8eeac13e7 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-qq-2.js @@ -0,0 +1,23 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_3; +s1_2->s1_4; +s1_1->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_3; + s1_2->s1_4; + s1_1->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--nested-qq-3.js b/tests/fixtures/code-path-analysis/assignment--nested-qq-3.js new file mode 100644 index 00000000000..ab94d6b0481 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--nested-qq-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4; +s1_1->s1_4; +s1_2->s1_4->final; +*/ +(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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nLogicalExpression:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_3[label="Identifier (c)"]; + s1_4[label="LogicalExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4; + s1_1->s1_4; + s1_2->s1_4->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-and-1.js b/tests/fixtures/code-path-analysis/assignment--simple-and-1.js new file mode 100644 index 00000000000..90e49db5a22 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-and-1.js @@ -0,0 +1,18 @@ +/*expected +initial->s1_1->s1_2->s1_3; +s1_1->s1_3->final; +*/ +a &&= b; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)"]; + s1_3[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3; + s1_1->s1_3->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-and-2.js b/tests/fixtures/code-path-analysis/assignment--simple-and-2.js new file mode 100644 index 00000000000..046559a6ff1 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-and-2.js @@ -0,0 +1,25 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_5->s1_6; +s1_1->s1_6; +s1_2->s1_4->s1_5; +s1_6->final; +*/ +a &&= b ? c : d; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="ConditionalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)"]; + s1_5[label="ConditionalExpression:exit"]; + s1_6[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + s1_4[label="Identifier (d)"]; + initial->s1_1->s1_2->s1_3->s1_5->s1_6; + s1_1->s1_6; + s1_2->s1_4->s1_5; + s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-and-3.js b/tests/fixtures/code-path-analysis/assignment--simple-and-3.js new file mode 100644 index 00000000000..cd3d0ec43ca --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-and-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_4->s1_5->s1_6; +s1_1->s1_3->s1_4->s1_6->final; +*/ +a[b ? c : d] &&= e; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nIdentifier (a)\nConditionalExpression:enter\nIdentifier (b)"]; + s1_2[label="Identifier (c)"]; + s1_4[label="ConditionalExpression:exit\nMemberExpression:exit"]; + s1_5[label="Identifier (e)"]; + s1_6[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + s1_3[label="Identifier (d)"]; + initial->s1_1->s1_2->s1_4->s1_5->s1_6; + s1_1->s1_3->s1_4->s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-bitand.js b/tests/fixtures/code-path-analysis/assignment--simple-bitand.js new file mode 100644 index 00000000000..e769969e12a --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-bitand.js @@ -0,0 +1,14 @@ +/*expected +initial->s1_1->final; +*/ +a &= b; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)\nIdentifier (b)\nAssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-eq.js b/tests/fixtures/code-path-analysis/assignment--simple-eq.js new file mode 100644 index 00000000000..0022ada6ef7 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-eq.js @@ -0,0 +1,14 @@ +/*expected +initial->s1_1->final; +*/ +a = b; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)\nIdentifier (b)\nAssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-or-1.js b/tests/fixtures/code-path-analysis/assignment--simple-or-1.js new file mode 100644 index 00000000000..8737eaa20c3 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-or-1.js @@ -0,0 +1,18 @@ +/*expected +initial->s1_1->s1_2->s1_3; +s1_1->s1_3->final; +*/ +a ||= b; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)"]; + s1_3[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3; + s1_1->s1_3->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-or-2.js b/tests/fixtures/code-path-analysis/assignment--simple-or-2.js new file mode 100644 index 00000000000..57f2702e84a --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-or-2.js @@ -0,0 +1,25 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_5->s1_6; +s1_1->s1_6; +s1_2->s1_4->s1_5; +s1_6->final; +*/ +a ||= b ? c : d; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="ConditionalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)"]; + s1_5[label="ConditionalExpression:exit"]; + s1_6[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + s1_4[label="Identifier (d)"]; + initial->s1_1->s1_2->s1_3->s1_5->s1_6; + s1_1->s1_6; + s1_2->s1_4->s1_5; + s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-or-3.js b/tests/fixtures/code-path-analysis/assignment--simple-or-3.js new file mode 100644 index 00000000000..9ccc0dea885 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-or-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_4->s1_5->s1_6; +s1_1->s1_3->s1_4->s1_6->final; +*/ +a[b ? c : d] ||= e; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nIdentifier (a)\nConditionalExpression:enter\nIdentifier (b)"]; + s1_2[label="Identifier (c)"]; + s1_4[label="ConditionalExpression:exit\nMemberExpression:exit"]; + s1_5[label="Identifier (e)"]; + s1_6[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + s1_3[label="Identifier (d)"]; + initial->s1_1->s1_2->s1_4->s1_5->s1_6; + s1_1->s1_3->s1_4->s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-plus.js b/tests/fixtures/code-path-analysis/assignment--simple-plus.js new file mode 100644 index 00000000000..1237039b903 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-plus.js @@ -0,0 +1,14 @@ +/*expected +initial->s1_1->final; +*/ +a += b; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)\nIdentifier (b)\nAssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-qq-1.js b/tests/fixtures/code-path-analysis/assignment--simple-qq-1.js new file mode 100644 index 00000000000..8ceede31172 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-qq-1.js @@ -0,0 +1,18 @@ +/*expected +initial->s1_1->s1_2->s1_3; +s1_1->s1_3->final; +*/ +a ??= b; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="Identifier (b)"]; + s1_3[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3; + s1_1->s1_3->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-qq-2.js b/tests/fixtures/code-path-analysis/assignment--simple-qq-2.js new file mode 100644 index 00000000000..be5276ab563 --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-qq-2.js @@ -0,0 +1,25 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_5->s1_6; +s1_1->s1_6; +s1_2->s1_4->s1_5; +s1_6->final; +*/ +a ??= b ? c : d; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nIdentifier (a)"]; + s1_2[label="ConditionalExpression:enter\nIdentifier (b)"]; + s1_3[label="Identifier (c)"]; + s1_5[label="ConditionalExpression:exit"]; + s1_6[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + s1_4[label="Identifier (d)"]; + initial->s1_1->s1_2->s1_3->s1_5->s1_6; + s1_1->s1_6; + s1_2->s1_4->s1_5; + s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--simple-qq-3.js b/tests/fixtures/code-path-analysis/assignment--simple-qq-3.js new file mode 100644 index 00000000000..bdf7fd8780a --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--simple-qq-3.js @@ -0,0 +1,21 @@ +/*expected +initial->s1_1->s1_2->s1_4->s1_5->s1_6; +s1_1->s1_3->s1_4->s1_6->final; +*/ +a[b ? c : d] ??= e; + +/*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]; + s1_1[label="Program:enter\nExpressionStatement:enter\nAssignmentExpression:enter\nMemberExpression:enter\nIdentifier (a)\nConditionalExpression:enter\nIdentifier (b)"]; + s1_2[label="Identifier (c)"]; + s1_4[label="ConditionalExpression:exit\nMemberExpression:exit"]; + s1_5[label="Identifier (e)"]; + s1_6[label="AssignmentExpression:exit\nExpressionStatement:exit\nProgram:exit"]; + s1_3[label="Identifier (d)"]; + initial->s1_1->s1_2->s1_4->s1_5->s1_6; + s1_1->s1_3->s1_4->s1_6->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--while-and.js b/tests/fixtures/code-path-analysis/assignment--while-and.js new file mode 100644 index 00000000000..8cc5e45031a --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--while-and.js @@ -0,0 +1,22 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_5; +s1_3->s1_5->final; +*/ +while (a &&= b) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nWhileStatement:enter"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="WhileStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_5; + s1_3->s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--while-or.js b/tests/fixtures/code-path-analysis/assignment--while-or.js new file mode 100644 index 00000000000..cde21d5ae8c --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--while-or.js @@ -0,0 +1,22 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4; +s1_3->s1_5->final; +*/ +while (a ||= b) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nWhileStatement:enter"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="WhileStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4; + s1_3->s1_5->final; +} +*/ diff --git a/tests/fixtures/code-path-analysis/assignment--while-qq.js b/tests/fixtures/code-path-analysis/assignment--while-qq.js new file mode 100644 index 00000000000..39f3184246e --- /dev/null +++ b/tests/fixtures/code-path-analysis/assignment--while-qq.js @@ -0,0 +1,24 @@ +/*expected +initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4; +s1_3->s1_5; +s1_2->s1_5->final; +*/ +while (a ??= b) { + foo(); +} + +/*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]; + s1_1[label="Program:enter\nWhileStatement:enter"]; + s1_2[label="AssignmentExpression:enter\nIdentifier (a)"]; + s1_3[label="Identifier (b)\nAssignmentExpression:exit"]; + s1_4[label="BlockStatement:enter\nExpressionStatement:enter\nCallExpression:enter\nIdentifier (foo)\nCallExpression:exit\nExpressionStatement:exit\nBlockStatement:exit"]; + s1_5[label="WhileStatement:exit\nProgram:exit"]; + initial->s1_1->s1_2->s1_3->s1_4->s1_2->s1_4; + s1_3->s1_5; + s1_2->s1_5->final; +} +*/ diff --git a/tests/lib/linter/code-path-analysis/code-path-analyzer.js b/tests/lib/linter/code-path-analysis/code-path-analyzer.js index ec516c54a02..c5d0ecf267f 100644 --- a/tests/lib/linter/code-path-analysis/code-path-analyzer.js +++ b/tests/lib/linter/code-path-analysis/code-path-analyzer.js @@ -557,7 +557,7 @@ describe("CodePathAnalyzer", () => { } })); const messages = linter.verify(source, { - parserOptions: { ecmaVersion: 2020 }, + parserOptions: { ecmaVersion: 2021 }, rules: { test: 2 } }); diff --git a/tests/lib/rules/no-this-before-super.js b/tests/lib/rules/no-this-before-super.js index c41b8c9c179..7a947c00b1c 100644 --- a/tests/lib/rules/no-this-before-super.js +++ b/tests/lib/rules/no-this-before-super.js @@ -39,6 +39,10 @@ ruleTester.run("no-this-before-super", rule, { "class A extends B { constructor() { super(); this.c(); } }", "class A extends B { constructor() { super(); super.c(); } }", "class A extends B { constructor() { if (true) { super(); } else { super(); } this.c(); } }", + "class A extends B { constructor() { foo = super(); this.c(); } }", + "class A extends B { constructor() { foo += super().a; this.c(); } }", + "class A extends B { constructor() { foo |= super().a; this.c(); } }", + "class A extends B { constructor() { foo &= super().a; this.c(); } }", // allows `this`/`super` in nested executable scopes, even if before `super()`. "class A extends B { constructor() { class B extends C { constructor() { super(); this.d = 0; } } super(); } }", @@ -161,6 +165,21 @@ ruleTester.run("no-this-before-super", rule, { { code: "class A extends B { constructor() { try { super(); } catch (err) { } this.a; } }", errors: [{ messageId: "noBeforeSuper", data: { kind: "this" }, type: "ThisExpression" }] + }, + { + code: "class A extends B { constructor() { foo &&= super().a; this.c(); } }", + parserOptions: { ecmaVersion: 2021 }, + errors: [{ messageId: "noBeforeSuper", data: { kind: "this" }, type: "ThisExpression" }] + }, + { + code: "class A extends B { constructor() { foo ||= super().a; this.c(); } }", + parserOptions: { ecmaVersion: 2021 }, + errors: [{ messageId: "noBeforeSuper", data: { kind: "this" }, type: "ThisExpression" }] + }, + { + code: "class A extends B { constructor() { foo ??= super().a; this.c(); } }", + parserOptions: { ecmaVersion: 2021 }, + errors: [{ messageId: "noBeforeSuper", data: { kind: "this" }, type: "ThisExpression" }] } ] });