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)
This PR aims to provide a more accurate error/finalization flow, I've nuked the old error path approach and rewrote it with more versatility in mind.
We used to visit the finalizer block twice and create 2 sets of AstNodes/Basic Blocks for them, This was there to differentiate between the error path finalizer and success path one. There is no longer a need for having 2 separate sets of nodes to do this differentiation.
As for the error path now we have 2 kinds of them, Everything is attached to an error block - even if it is not in a try-catch statement - this results in a lot of extra edges to keep track of these "Implicit" error blocks but I believe in future it can help us to track cross block error paths, For example, we can dynamically attach and cache the implicit error block of a function to its call site error path (either implicit or explicit).
close: #3620
In `Babel`, the expected output is:
```ts
var x = 10;
var Foo = function(Foo) {
Foo[Foo['a'] = 10] = 'a';
Foo[Foo['b'] = 10] = 'b';
Foo[Foo['c'] = 30] = 'c';
return Foo;
}(Foo || {});
```
IMO, `Foo.b + x` is enough, because `x` is not a const variable. The
output same as with `typescript`
I've just created example using `oxc_semantic`.
> https://gist.github.com/leaysgur/bcb748daa665d1615eabda6967366d05
But it could not be compiled due to:
```
error: to use a constant of type `CtxFlags` in a pattern, `CtxFlags` must be annotated with `#[derive(PartialEq, Eq)]`
```
- 0.14.0: 🆖
- ...
- 0.13.0: 🆖
- 0.12.5: 🆗
This change seems to fix this.
Change arrow function transform to use UIDs for `_this` vars, which can't clash with an existing binding.
I believe there are some problems with our current implementation, but have struggled to fix them due to weird interactions with TS transforms. Have added "TODO" comments, so we can return to this and fix them later on, once scopes in TS transforms are correct.
My failed attempt at fixing is on this branch: https://github.com/oxc-project/oxc/tree/transform-arrow-functions
Correct the `#[visited_node]` attr on `ArrowFunctionExpression` to recognise strict mode functions.
This change has no effect at present as `Traverse` codegen currently ignores `strict_if`. But useful for it to be correct for if we codegen `Visit` / `VisitMut` later on (#3392).
Replace recursion with loop in
`JSXMemberExpression::get_object_identifier`.
Also add a mutable version
`JSXMemberExpression::get_object_identifier_mut`.
Re-use existing `Atom`s in React Display Name transform rather than writing duplicate strings into the arena.
Also add comments for where our implementation diverges from Babel's (in my opinion, ours is an improvement).
Fix column number in JSX source transform, and add tests.
It was correct in all cases, except for when a Unicode character with code point above `0xFFFF` appears earlier on the line.
Such characters are:
* 4 bytes in UTF-8.
* 2 characters in UTF-16.
* 1 `char` in Rust.
Babel (which we're trying to match) uses count of UTF-16 characters for column number, whereas we were using count of Rust `char`s.
React JSX Source transform generates a top-level variable `_jsxFileName` containing file path.
Previously this var name was hard-coded. Generate a UID instead to avoid clash with existing var called `_jsxFileName`. Add this binding to scopes.