fixes: #8437
In semantic builder make sure `Program` reference has a lifetime of the
Arena.
---------
Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
Add `AstKind::ty` method to get `AstType` from an `AstKind`.
Works by setting the enum discriminants of `AstKind` and `AstType` to be the same, so one can be converted to the other at zero cost.
The new implementation port from [esbuild](df815ac27b/internal/js_parser/js_parser_lower.go (L355-L467)), before from `Babel`.
Babel's transform implementation for the async method is incorrect because the async method should return a rejecting promise when it throws an error. Everything is good if the errors are thrown in the async method body, but the following case will throw an error in the parameters which causes the whole program crushed not a rejecting promise. So we should move the parameters to the inner generator function when the parameters could throw an error.
Input:
```js
class Cls {
// ReferenceError: Cannot access 'b' before initialization
async method(a = b, b = 0) {}
}
```
Before output
```js
class Cls {
method(a = b, b = 0) {
return babelHelpers.asyncToGenerator(function* () {})();
}
}
```
After output:
```js
class Cls {
method() {
// ReferenceError: Cannot access 'b' before initialization
return babelHelpers.asyncToGenerator(function* (a = b, b = 0) {}).apply(this, arguments);
}
}
```
No override tests because Babel doesn't cover this case.
Update babel submodule for conformance tests to latest HEAD.
The test fixtures include a new one for a bug fix which @branchseer
intends to also apply to Oxc - https://github.com/babel/babel/pull/17050
(see #8342).
Follow-on after #8482.
Fix an edge case in arrow functions transform when inserting `_this = this` after `super()`. It is possible (though bizarre) for `super()` to contain another `super()` call. This will throw an error when evaluating the outer `super()`, but it can still be observable in some cases.
```js
let f;
class S {}
class C extends S {
constructor(x) {
super(super(), this.x = x, f = async () => this);
}
}
try { new C(123) } catch {}
const c = await f();
assert(c.x === 123);
```
So, before bailing out from searching for more `super()`s in class constructor, visit the `super()` call's arguments.
Some of Babel's exec tests contain a return statement at top level, in order to return a Promise.
e.g. ad572fd1a1/packages/babel-plugin-transform-private-methods/test/fixtures/private-method-loose/async/exec.js
These test files could not be parsed due to illegal position of `return`, and the tests were silently excluded.
This PR:
1. Includes those tests by passing `allow_return_outside_function: true` option to parser for exec tests.
2. Includes a "transform error" message in snapshot for any exec tests which produce errors in parser/transformer.
Found a bunch of failed tests related to we don't use
`classPrivateSetter` and `classPrivateGetter` to transform private
getter and private setter. The simplest way is to add alternative helper
functions for these two. The reason we don't use I have explained in
#8132
```shell
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-add.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitand.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «0») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitor.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «15») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitxor.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «257») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-div.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «0.5») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1000») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-lshift.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «96») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-mod.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-mult.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «6») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-rshift.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-srshift.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-sub.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
```
I did a few things in this PR,
1. Remove `names` which store the declarations name used for checking re-declaration. (We can use SymbolTable to do it now.)
2. Correct semantic data for namespace transform
3. Simplify code
close: #8385
This PR is to solve the missing `super` transform in the async arrow function, and `_this = this` inserts to an incorrect place. These problems are all about the async arrow function, which is a part of the init of class property. Learn more at #8387.
The output matches Babel's output except for static prop as Babel transforms incorrectly.
Compresses `new Int8Array(0)` into `new Int8Array()`. (then will be compress into `new Int8Array`).
Partial quote from the [spec](https://tc39.es/ecma262/multipage/indexed-collections.html#sec-typedarray):
> 5. If numberOfArgs = 0, then
> a. Return ? AllocateTypedArray(constructorName, NewTarget, proto, 0).
> 6. Else,
> c. Else,
> ii. Let elementLength be ? ToIndex(firstArgument).
> iii. Return ? AllocateTypedArray(constructorName, NewTarget, proto, elementLength).
Fix implementations of `ContentEq` and `ContentHash` for literal AST types:
* `NullLiteral::content_hash` is a no-op, same as other types which only contain a `Span`.
* `NumericLiteral::content_eq` and `content_hash` ignore `base` field.
* `NumericLiteral::content_hash` works around `0.0 == -0.0`.
* `BigIntLiteral::content_eq` and `content_hash` ignore `base` field.
* `StringLiteral::content_hash` ignore `raw` field.
* `RegExpLiteral::content_eq` and `content_hash` consider 2 `RegExp`s to be equal if they are printed the same (regardless of whether they were parsed by `oxc_regular_expression` or not).
Additionally, implement `StringLiteral::content_eq` manually to avoid "special case" logic in `oxc_ast_tools`.
We use `content_eq` in the minifier, where raw value can become `None`.
`raw` cannot be removed from other literals, they will always be equal otherwise.
This `super.value` belongs to the nested class, we shouldn't transform it.
```js
class Outer {
async method() {
class Inner extends Outer {
normal() {
// `super.value` should not be transformed, because it is not in an async method
super.value
}
}
}
}
```
Missing error that super property inside plain function.
```js
class C {
constructor() {
function g() {
// * It is a Syntax Error if PropName of MethodDefinition is not "constructor" and HasDirectSuper of MethodDefinition is true.
super();
}
}
method() {
function func() {
// It is a Syntax Error if FunctionBody Contains SuperProperty is true.
super.good();
}
}
}
```
I am not sure why test262 doesn't cover tests like that
The simplified version of the evaluation of `a = a || b` is:
> AssignmentExpression : LeftHandSideExpression = LogicalORExpression || LogicalANDExpression
> 1. Let lRef be ? Evaluation of LeftHandSideExpression.
> 2. Let llRef be ? Evaluation of LogicalORExpression.
> 3. Let llVal be ? GetValue(llRef).
> 4. If ToBoolean(llVal) is true
> a. Perform ? PutValue(lRef, llVal).
> b. return llVal.
> 5. Let lrRef be ? Evaluation of LogicalANDExpression.
> 6. Let rRef be ? GetValue(lrRef).
> 7. Let rVal be ? GetValue(rRef). [Note GetValue(rRef) returns rRef itself]
> 8. Perform ? PutValue(lRef, rVal).
> 9. Return rVal.
The simplified version of the evaluation of `a ||= b` is:
> AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
> 1. Let lRef be ? Evaluation of LeftHandSideExpression.
> 2. Let lVal be ? GetValue(lRef).
> 3. If ToBoolean(lVal) is true, return lVal.
> 4. Let rRef be ? Evaluation of AssignmentExpression.
> 5. Let rVal be ? GetValue(rRef).
> 6. Perform ? PutValue(lRef, rVal).
> 7. Return rVal.
The difference of these is that
- the evaluation of `a` is done twice for `a = a || b`, one with `1. Let lRef be ? Evaluation of LeftHandSideExpression` and one with `2. Let llRef be ? Evaluation of LogicalORExpression.`. This is same with #8366, #8367.
- `PutValue(lRef, llVal)` is performed when `ToBoolean(lVal)` is `true`.
So `x = x || 1` can be compressed to `x ||= 1` when the conditions written in #8366 are met and `PutValue(lRef, llVal)` does not have a side effect. When `a` is a non-global identifier (and not a reference created by a `with` statement), these conditions are met.
**References**
- [Spec of `||`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-binary-logical-operators-runtime-semantics-evaluation)
- [Spec of `=` / `||=`](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-binary-logical-operators-runtime-semantics-evaluation)