fix(linter): memorize visited block id in neighbors_filtered_by_edge_weight (#3407)

closes: #3396

we visit the same node too many times, I picked some result from run require-render-return rule on [timeserieseexploere.js](https://github.com/elastic/kibana/blob/main/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js)

```bash
    NodeIndex(64): 368640,
    NodeIndex(67): 737280,
    NodeIndex(70): 2949120,
    NodeIndex(73): 5971968,
    NodeIndex(76): 11943936,
    NodeIndex(43): 184320,
    NodeIndex(71): 2985984,
    NodeIndex(65): 368640,
    NodeIndex(68): 1474560,
    NodeIndex(74): 5971968,
    NodeIndex(77): 23887872,
    NodeIndex(44): 184320,
    NodeIndex(41): 73728,
    NodeIndex(35): 36864,
    NodeIndex(66): 737280,
    NodeIndex(69): 1474560,
    NodeIndex(72): 2985984,
    NodeIndex(75): 11943936,
```
This commit is contained in:
mysteryven 2024-05-26 08:11:48 +00:00
parent 3855579eb4
commit 5e06298ec2
11 changed files with 55 additions and 52 deletions

View file

@ -110,14 +110,18 @@ fn contains_return_statement<'a>(node: &AstNode<'a>, ctx: &LintContext<'a>) -> b
}
for entry in cfg.basic_block(*basic_block_id) {
if let BasicBlockElement::Assignment(to_reg, val) = entry {
if matches!(to_reg, Register::Return)
&& matches!(val, AssignmentValue::NotImplicitUndefined)
{
return (FoundReturn::Yes, STOP_WALKING_ON_THIS_PATH);
match entry {
BasicBlockElement::Assignment(to_reg, val) => {
if matches!(to_reg, Register::Return)
&& matches!(val, AssignmentValue::NotImplicitUndefined)
{
return (FoundReturn::Yes, STOP_WALKING_ON_THIS_PATH);
}
}
} else {
// We don't care about other types of instructions.
BasicBlockElement::Unreachable | BasicBlockElement::Throw(_) => {
return (FoundReturn::No, STOP_WALKING_ON_THIS_PATH);
}
BasicBlockElement::Break(_) => {}
}
}
@ -186,7 +190,31 @@ fn is_in_es6_component<'a, 'b>(node: &'b AstNode<'a>, ctx: &'b LintContext<'a>)
fn test() {
use crate::tester::Tester;
// let too_many_if_else = (1..10)
// .map(|i| {
// "
// if (a > i) {
// foo1()
// } else {
// foo2()
// }
// "
// })
// .collect::<String>();
// let too_many_if_else_case = format!(
// "
// class Hello extends React.Component {{
// render() {{
// {too_many_if_else}
// return 'div'
// }}
// }}
// ",
// );
let pass = vec![
// &too_many_if_else_case,
r"
class Hello extends React.Component {
render() {

View file

@ -801,7 +801,6 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
let after_conditional_graph_ix = self.cfg.new_basic_block();
/* cfg */
self.cfg.put_unreachable();
self.cfg.add_edge(
after_consequent_expr_graph_ix,
after_conditional_graph_ix,
@ -1078,12 +1077,7 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> {
/* cfg - bb after if statement joins consequent and alternate */
let after_if_graph_ix = self.cfg.new_basic_block();
if stmt.alternate.is_some() {
self.cfg.put_unreachable();
}
// else {
self.cfg.add_edge(after_consequent_stmt_graph_ix, after_if_graph_ix, EdgeType::Normal);
// }
self.cfg.add_edge(
before_if_stmt_graph_ix,

View file

@ -1,4 +1,5 @@
use petgraph::{visit::EdgeRef, Direction, Graph};
use rustc_hash::FxHashSet;
use crate::BasicBlockId;
@ -15,6 +16,7 @@ where
{
let mut q = vec![];
let mut final_states = vec![];
let mut visited = FxHashSet::default();
// for initial node
let (new_state, keep_walking_this_path) = visitor(&node, Default::default());
@ -27,6 +29,10 @@ where
while let Some((graph_ix, state)) = q.pop() {
let mut edges = 0;
if visited.contains(&graph_ix) {
continue;
}
visited.insert(graph_ix);
for edge in graph.edges_directed(graph_ix, Direction::Outgoing) {
if let Some(result_of_edge_filtering) = edge_filter(edge.weight()) {
final_states.push(result_of_edge_filtering);

View file

@ -9,9 +9,7 @@ digraph {
2 [ label = ""]
3 [ label = ""]
4 [ label = ""]
5 [ label = "Unreachable()"]
0 -> 1 [ ]
4 -> 5 [ ]
2 -> 4 [ ]
1 -> 2 [ ]
1 -> 3 [ ]

View file

@ -22,7 +22,3 @@ bb3: {
bb4: {
}
bb5: {
Unreachable()
}

View file

@ -8,8 +8,6 @@ digraph {
1 [ label = ""]
2 [ label = ""]
3 [ label = ""]
4 [ label = "Unreachable()"]
3 -> 4 [ ]
1 -> 3 [ ]
0 -> 1 [ ]
0 -> 2 [ ]

View file

@ -18,7 +18,3 @@ bb2: {
bb3: {
}
bb4: {
Unreachable()
}

View file

@ -14,22 +14,20 @@ digraph {
7 [ label = "$return = <value>"]
8 [ label = ""]
9 [ label = "Unreachable()"]
10 [ label = ""]
11 [ label = "Unreachable()\n$return = <value>"]
12 [ label = ""]
13 [ label = "Unreachable()"]
14 [ label = ""]
10 [ label = "$return = <value>"]
11 [ label = ""]
12 [ label = "Unreachable()"]
13 [ label = ""]
0 -> 1 [ ]
1 -> 2 [ ]
1 -> 3 [ ]
2 -> 3 [ ]
5 -> 6 [ ]
8 -> 9 [ ]
10 -> 11 [ ]
6 -> 10 [ ]
3 -> 4 [ ]
3 -> 7 [ ]
9 -> 10 [ ]
12 -> 13 [ ]
0 -> 14 [ ]
11 -> 12 [ ]
0 -> 13 [ ]
}

View file

@ -44,22 +44,17 @@ bb9: {
}
bb10: {
}
bb11: {
Unreachable()
$return = <value>
}
bb12: {
bb11: {
}
bb13: {
bb12: {
Unreachable()
}
bb14: {
bb13: {
}

View file

@ -17,9 +17,8 @@ digraph {
10 [ label = "Unreachable()"]
11 [ label = ""]
12 [ label = ""]
13 [ label = "Unreachable()"]
13 [ label = ""]
14 [ label = ""]
15 [ label = ""]
0 -> 1 [ ]
5 -> 6 [ ]
5 -> 6 [ ]
@ -29,7 +28,6 @@ digraph {
10 -> 11 [ ]
7 -> 8 [ ]
7 -> 11 [ ]
12 -> 13 [ ]
6 -> 12 [ ]
4 -> 5 [ ]
4 -> 7 [ ]
@ -37,8 +35,8 @@ digraph {
1 -> 2 [ ]
2 -> 3 [ ]
3 -> 4 [ ]
13 -> 3 [ ]
3 -> 14 [ ]
12 -> 3 [ ]
3 -> 13 [ ]
9 -> 3 [ ]
0 -> 15 [ ]
0 -> 14 [ ]
}

View file

@ -57,13 +57,9 @@ bb12: {
}
bb13: {
Unreachable()
}
bb14: {
}
bb15: {
}