oxc/crates
rzvxa 046ff3fdfb feat(linter/eslint): add no_unreachable rule. (#3238)
closes #621
[no-unreachable](069aa680c7/lib/rules/no-unreachable.js (L196))

[oxlint-echosystem-ci result](https://github.com/rzvxa/oxlint-ecosystem-ci/actions/runs/9406195143/job/25909079029)

This rule is done but since it is running for every possible statement and does quite a bit of work on them to determine whether it is 100% reachable or not; The performance in my opinion is kind of abysmal.

I'll try to work it out, I know Biome does 2 types of checks to simplify the rule for some nodes, However, they have a lot more false negatives than our implementation.

##### Here is one example of those [false negatives](https://biomejs.dev/playground/?code=ZgB1AG4AYwB0AGkAbwBuACAAeAAoACkAIAB7ACAAZABvACAAewAgAGEAKAApADsAIAB9ACAAdwBoAGkAbABlACgAdAByAHUAZQApADsAIABiACgAKQA7ACAAfQA%3D)

-------------

### Update 1:

I've benchmarked this rule using only the simplified reachability checks and it was around 5% faster, To be honest, it isn't much improvement especially considering that we can only use this check for a small portion of nodes and even that is accompanied by newly introduced checks which would lessen the amount of performance gain further.

Most of the performance regression is because of allocations during our depth first search since we have to store both the visited and finished nodes which results in a bunch of rapid-fire allocations back to back. Currently, At the moment I don't have a great idea of how to improve it, We may have to implement our own graph to use arenas underneath.

Given that this rule is the most extensive use case of control flow (It doesn't come with a limited scope similar to property and constructor rules already implemented) this performance drop might be reasonable to some extent.

------------

### Update 2:

I reworked my approach in 2 senses, First I used @Boshen's suggestion inspired by TypeScript and kept some of the reachability information in the basic block structure instead of calculating it on the fly. It is done by propagating the `Unreachable` edge and `Unreachable` instruction throughout subgraphs.

This for sure helped with the performance but the next part is what never failed to amaze me, Going from something near `O(n!)` in the worst-case scenario to `O(n^2)` (in the worst-case scenario). By changing the approach instead of checking the reachability of each statement we do it in 3 paths; First, we do a path on the entire CFG and query all reachable but suspicious cases, and then we do another path on each of these suspicions subgraphs to determine the reachability with higher confidence. Finally, we iterate all of the appropriate nodes and check their reachability status according to the information collected in 2 previous paths.

With these 2 this rule went from `-24%` to `~-2%`.

This performance gain doesn't come for free though; It increases the likelihood of false positives/negatives, But as long as we are passing our `ecosystem-ci` it should be fine. We can always sacrifice some performance to check for edge cases if there are any.

[new oxlint-echosystem-ci result](https://github.com/rzvxa/oxlint-ecosystem-ci/actions/runs/9490791181)
2024-06-13 09:37:45 +00:00
..
oxc Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_allocator feat(linter): add eslint/no-useless-constructor (#3594) 2024-06-13 13:12:18 +08:00
oxc_ast feat(linter/eslint): add no_unreachable rule. (#3238) 2024-06-13 09:37:45 +00:00
oxc_ast_macros Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_codegen Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_diagnostics Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_index Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_js_regex chore: crates should only publish src and examples directory 2024-06-08 16:35:16 +08:00
oxc_language_server feat!(ast): make Trivias clonable by adding Arc (#3638) 2024-06-12 13:16:10 +08:00
oxc_linter feat(linter/eslint): add no_unreachable rule. (#3238) 2024-06-13 09:37:45 +00:00
oxc_macros chore: crates should only publish src and examples directory 2024-06-08 16:35:16 +08:00
oxc_minifier Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_module_lexer Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_parser chore: change all usages of static_assertions to dev-dependencies (#3654) 2024-06-13 13:18:53 +08:00
oxc_prettier feat!(ast): make Trivias clonable by adding Arc (#3638) 2024-06-12 13:16:10 +08:00
oxc_semantic feat(linter/eslint): add no_unreachable rule. (#3238) 2024-06-13 09:37:45 +00:00
oxc_sourcemap Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_span Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_syntax Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_transformer fix(transformer): do not rename accessible identifier references (#3623) 2024-06-13 15:26:38 +08:00
oxc_traverse Release crates v0.14.0 (#3643) 2024-06-12 17:52:41 +08:00
oxc_wasm fix!(codegen): remove the unecessary 4th argument from Codegen::new (#3640) 2024-06-12 07:58:54 +00:00