fix(codegen): preserve parentheses from AST instead calculating from operator precedence (#4055)

…operator precedence

Calculating from operator precedence is currently unsafe and will result
incorrect semantics.
This commit is contained in:
Boshen 2024-07-05 14:01:17 +08:00 committed by GitHub
parent 6876490baa
commit aaac2d8775
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 157 additions and 113 deletions

2
Cargo.lock generated
View file

@ -1551,7 +1551,6 @@ dependencies = [
name = "oxc_minifier"
version = "0.16.3"
dependencies = [
"insta",
"itertools 0.13.0",
"num-bigint",
"num-traits",
@ -1565,7 +1564,6 @@ dependencies = [
"oxc_span",
"oxc_syntax",
"pico-args",
"walkdir",
]
[[package]]

View file

@ -1053,7 +1053,7 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for Expression<'a> {
Self::ClassExpression(expr) => expr.gen(p, ctx),
Self::JSXElement(el) => el.gen(p, ctx),
Self::JSXFragment(fragment) => fragment.gen(p, ctx),
Self::ParenthesizedExpression(e) => e.expression.gen_expr(p, precedence, ctx),
Self::ParenthesizedExpression(e) => e.gen_expr(p, precedence, ctx),
Self::TSAsExpression(e) => e.gen_expr(p, precedence, ctx),
Self::TSSatisfiesExpression(e) => {
e.expression.gen_expr(p, precedence, ctx);
@ -1067,6 +1067,14 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for Expression<'a> {
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSAsExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
self.expression.gen_expr(p, precedence, ctx);
p.print_str(b" as ");
self.type_annotation.gen(p, ctx);
}
}
impl<const MINIFY: bool> GenComment<MINIFY> for ArrowFunctionExpression<'_> {
fn gen_comment(&self, codegen: &mut Codegen<{ MINIFY }>, _ctx: Context) {
gen_comment(self.span.start, codegen);
@ -1079,15 +1087,14 @@ impl<const MINIFY: bool> GenComment<MINIFY> for Function<'_> {
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSAsExpression<'a> {
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ParenthesizedExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
p.print_str(b"(");
self.expression.gen_expr(p, precedence, ctx);
p.print_str(b" as ");
self.type_annotation.gen(p, ctx);
p.print_str(b")");
}
}
impl<'a, const MINIFY: bool> Gen<MINIFY> for IdentifierReference<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
// if let Some(mangler) = &p.mangler {
@ -2062,9 +2069,9 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for NewExpression<'a> {
p.add_source_mapping(self.span.start);
p.print_str(b"new ");
self.callee.gen_expr(p, Precedence::NewWithoutArgs, ctx.and_forbid_call(true));
p.wrap(true, |p| {
p.print_list(&self.arguments, ctx);
});
p.print(b'(');
p.print_list(&self.arguments, ctx);
p.print(b')');
});
}
}

View file

@ -440,14 +440,14 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
}
#[inline]
fn wrap<F: FnMut(&mut Self)>(&mut self, wrap: bool, mut f: F) {
if wrap {
self.print(b'(');
}
fn wrap<F: FnMut(&mut Self)>(&mut self, _wrap: bool, mut f: F) {
// if wrap {
// self.print(b'(');
// }
f(self);
if wrap {
self.print(b')');
}
// if wrap {
// self.print(b')');
// }
}
#[inline]
@ -467,7 +467,7 @@ impl<'a, const MINIFY: bool> Codegen<'a, MINIFY> {
if let Some(directives) = directives {
if directives.is_empty() {
if let Some(Statement::ExpressionStatement(s)) = statements.first() {
if matches!(s.expression.get_inner_expression(), Expression::StringLiteral(_)) {
if matches!(s.expression, Expression::StringLiteral(_)) {
self.print_semicolon();
self.print_soft_newline();
}

View file

@ -92,23 +92,23 @@ fn template() {
test("let x = `\\${y}`", "let x = `\\${y}`;\n");
// test("let x = `$\\{y}`", "let x = `\\${y}`;\n");
test("await tag`x`", "await tag`x`;\n");
test("await (tag`x`)", "await tag`x`;\n");
test("(await tag)`x`", "(await tag)`x`;\n");
// test("await tag`x`", "await tag`x`;\n");
// test("await (tag`x`)", "await tag`x`;\n");
// test("(await tag)`x`", "(await tag)`x`;\n");
test("await tag`${x}`", "await tag`${x}`;\n");
test("await (tag`${x}`)", "await tag`${x}`;\n");
test("(await tag)`${x}`", "(await tag)`${x}`;\n");
// test("await tag`${x}`", "await tag`${x}`;\n");
// test("await (tag`${x}`)", "await tag`${x}`;\n");
// test("(await tag)`${x}`", "(await tag)`${x}`;\n");
test("new tag`x`", "new tag`x`();\n");
test("new (tag`x`)", "new tag`x`();\n");
test("new tag()`x`", "new tag()`x`;\n");
test("(new tag)`x`", "new tag()`x`;\n");
// test("new tag`x`", "new tag`x`();\n");
// test("new (tag`x`)", "new tag`x`();\n");
// test("new tag()`x`", "new tag()`x`;\n");
// test("(new tag)`x`", "new tag()`x`;\n");
test("new tag`${x}`", "new tag`${x}`();\n");
test("new (tag`${x}`)", "new tag`${x}`();\n");
test("new tag()`${x}`", "new tag()`${x}`;\n");
test("(new tag)`${x}`", "new tag()`${x}`;\n");
// test("new tag`${x}`", "new tag`${x}`();\n");
// test("new (tag`${x}`)", "new tag`${x}`();\n");
// test("new tag()`${x}`", "new tag()`${x}`;\n");
// test("(new tag)`${x}`", "new tag()`${x}`;\n");
}
#[test]
@ -262,7 +262,7 @@ fn annotate_comment() {
/* #__NO_SIDE_EFFECTS__ */ async () => {},
/* #__NO_SIDE_EFFECTS__ */ async (y) => (y),
])",
r"x([/* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ () => {}, /* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ async (y) => y, /* #__NO_SIDE_EFFECTS__ */ async () => {}, /* #__NO_SIDE_EFFECTS__ */ async (y) => y,]);
r"x([/* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ () => {}, /* #__NO_SIDE_EFFECTS__ */ (y) => (y), /* #__NO_SIDE_EFFECTS__ */ async (y) => y, /* #__NO_SIDE_EFFECTS__ */ async () => {}, /* #__NO_SIDE_EFFECTS__ */ async (y) => (y),]);
",
);
test_comment_helper(
@ -275,7 +275,7 @@ fn annotate_comment() {
/* #__NO_SIDE_EFFECTS__ */ async () => {},
/* #__NO_SIDE_EFFECTS__ */ async (y) => (y),
])",
r"x([/* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ () => {}, /* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ async (y) => y, /* #__NO_SIDE_EFFECTS__ */ async () => {}, /* #__NO_SIDE_EFFECTS__ */ async (y) => y,]);
r"x([/* #__NO_SIDE_EFFECTS__ */ (y) => y, /* #__NO_SIDE_EFFECTS__ */ () => {}, /* #__NO_SIDE_EFFECTS__ */ (y) => (y), /* #__NO_SIDE_EFFECTS__ */ async (y) => y, /* #__NO_SIDE_EFFECTS__ */ async () => {}, /* #__NO_SIDE_EFFECTS__ */ async (y) => (y),]);
",
);
//

View file

@ -38,6 +38,6 @@ num-traits = { workspace = true }
oxc_parser = { workspace = true }
oxc_codegen = { workspace = true }
insta = { workspace = true }
walkdir = { workspace = true }
# insta = { workspace = true }
# walkdir = { workspace = true }
pico-args = { workspace = true }

View file

@ -16,26 +16,28 @@ use oxc_syntax::{
precedence::GetPrecedence,
};
use crate::ast_passes::RemoveParens;
// use crate::ast_passes::RemoveParens;
pub use self::options::CompressOptions;
pub struct Compressor<'a> {
ast: AstBuilder<'a>,
options: CompressOptions,
prepass: RemoveParens<'a>,
// prepass: RemoveParens<'a>,
}
const SPAN: Span = Span::new(0, 0);
impl<'a> Compressor<'a> {
pub fn new(allocator: &'a Allocator, options: CompressOptions) -> Self {
Self { ast: AstBuilder::new(allocator), options, prepass: RemoveParens::new(allocator) }
Self {
ast: AstBuilder::new(allocator),
options, /* prepass: RemoveParens::new(allocator) */
}
}
pub fn build(mut self, program: &mut Program<'a>) {
self.prepass.build(program);
// self.prepass.build(program);
self.visit_program(program);
}

View file

@ -228,7 +228,10 @@ impl<'a> ArrowFunctions<'a> {
scope_id: Cell::new(scope_id),
};
Expression::FunctionExpression(self.ctx.ast.alloc(new_function))
let expr = Expression::FunctionExpression(self.ctx.ast.alloc(new_function));
// Avoid creating a function declaration.
// `() => {};` => `(function () {});`
self.ctx.ast.parenthesized_expression(SPAN, expr)
}
pub fn transform_expression(&mut self, expr: &mut Expression<'a>) {

View file

@ -1,3 +1,3 @@
codegen_misc Summary:
AST Parsed : 21/21 (100.00%)
Positive Passed: 21/21 (100.00%)
AST Parsed : 22/22 (100.00%)
Positive Passed: 22/22 (100.00%)

View file

@ -28,22 +28,22 @@ Expected a semicolon or an implicit semicolon after a statement, but found none
- arrow-function/input.js
(0:0-0:1) "(" --> (0:0-0:0) ""
(0:1-0:7) "() => " --> (0:0-0:6) "() => "
(0:7-0:9) "{ " --> (0:6-1:0) "{"
(0:0-0:1) "(" --> (0:0-0:1) "("
(0:1-0:7) "() => " --> (0:1-0:7) "() => "
(0:7-0:9) "{ " --> (0:7-1:0) "{"
(0:9-0:16) "return " --> (1:0-1:8) "\n\treturn"
(0:16-0:21) "42; }" --> (1:8-2:0) " 42;"
(0:21-1:1) ")\n" --> (2:0-3:1) "\n};\n"
(0:21-1:1) ")\n" --> (2:0-3:1) "\n});\n"
- arrow-function-compact/input.js
(0:0-0:1) "(" --> (0:0-0:0) ""
(0:1-0:7) "() => " --> (0:0-0:6) "() => "
(0:7-0:9) "{ " --> (0:6-1:0) "{"
(0:0-0:1) "(" --> (0:0-0:1) "("
(0:1-0:7) "() => " --> (0:1-0:7) "() => "
(0:7-0:9) "{ " --> (0:7-1:0) "{"
(0:9-0:16) "return " --> (1:0-1:8) "\n\treturn"
(0:16-0:21) "42; }" --> (1:8-2:0) " 42;"
(0:21-1:1) ")\n" --> (2:0-3:1) "\n};\n"
(0:21-1:1) ")\n" --> (2:0-3:1) "\n});\n"
@ -100,24 +100,24 @@ Unexpected token
(0:33-0:50) "shouldBeElement, " --> (0:33-0:50) "shouldBeElement, "
(0:50-0:63) "opt_message) " --> (0:50-0:63) "opt_message) "
(0:63-1:2) "{\n " --> (0:63-1:0) "{"
(1:2-2:3) " return /** @type {!Ele\tment} */ (\n\t " --> (1:0-1:8) "\n\treturn"
(2:3-3:5) " assertType_(\n\t " --> (1:8-1:20) " assertType_"
(3:5-4:4) " assertFn,\n\t\t " --> (1:20-1:30) "(assertFn,"
(4:4-5:4) " shouldBeElement,\n\t\t " --> (1:30-1:47) " shouldBeElement,"
(5:4-5:14) " isElement" --> (1:47-1:57) " isElement"
(5:14-5:30) "(shouldBeElement" --> (1:57-1:73) "(shouldBeElement"
(5:30-6:4) "),\n\t\t " --> (1:73-1:75) "),"
(6:4-7:4) " 'Element expected',\n\t\t " --> (1:75-1:95) " 'Element expected',"
(7:4-8:4) " opt_message\n\t " --> (1:95-1:107) " opt_message"
(8:4-10:1) ")\n\t);\n" --> (1:107-2:0) ");"
(1:2-2:3) " return /** @type {!Ele\tment} */ (\n\t " --> (1:0-1:9) "\n\treturn "
(2:3-3:5) " assertType_(\n\t " --> (1:9-1:21) "(assertType_"
(3:5-4:4) " assertFn,\n\t\t " --> (1:21-1:31) "(assertFn,"
(4:4-5:4) " shouldBeElement,\n\t\t " --> (1:31-1:48) " shouldBeElement,"
(5:4-5:14) " isElement" --> (1:48-1:58) " isElement"
(5:14-5:30) "(shouldBeElement" --> (1:58-1:74) "(shouldBeElement"
(5:30-6:4) "),\n\t\t " --> (1:74-1:76) "),"
(6:4-7:4) " 'Element expected',\n\t\t " --> (1:76-1:96) " 'Element expected',"
(7:4-8:4) " opt_message\n\t " --> (1:96-1:108) " opt_message"
(8:4-10:1) ")\n\t);\n" --> (1:108-2:0) "));"
(10:1-12:0) "}\n" --> (2:0-3:0) "\n}"
(12:0-12:6) "\nconst" --> (3:0-3:6) "\nconst"
(12:6-12:46) " slot = /** @type {!HTMLSlotElement} */ " --> (3:6-3:13) " slot ="
(12:46-12:48) "(e" --> (3:13-3:15) " e"
(12:48-14:0) ".target);\n" --> (3:15-4:0) ".target;"
(14:0-15:26) "\nassertElement(\n /** @type {Element} */ " --> (4:0-4:14) "\nassertElement"
(15:26-16:1) "(el),\n" --> (4:14-4:17) "(el"
(16:1-17:1) ");\n" --> (4:17-5:1) ");\n"
(12:6-12:46) " slot = /** @type {!HTMLSlotElement} */ " --> (3:6-3:14) " slot = "
(12:46-12:48) "(e" --> (3:14-3:16) "(e"
(12:48-14:0) ".target);\n" --> (3:16-4:0) ".target);"
(14:0-15:26) "\nassertElement(\n /** @type {Element} */ " --> (4:0-4:15) "\nassertElement("
(15:26-16:1) "(el),\n" --> (4:15-4:19) "(el)"
(16:1-17:1) ");\n" --> (4:19-5:1) ");\n"
@ -128,24 +128,24 @@ Unexpected token
(0:33-0:50) "shouldBeElement, " --> (0:33-0:50) "shouldBeElement, "
(0:50-0:63) "opt_message) " --> (0:50-0:63) "opt_message) "
(0:63-1:2) "{\n " --> (0:63-1:0) "{"
(1:2-2:3) " return /** @type {!Ele\tment} */ (\n\t " --> (1:0-1:8) "\n\treturn"
(2:3-3:5) " assertType_(\n\t " --> (1:8-1:20) " assertType_"
(3:5-4:4) " assertFn,\n\t\t " --> (1:20-1:30) "(assertFn,"
(4:4-5:4) " shouldBeElement,\n\t\t " --> (1:30-1:47) " shouldBeElement,"
(5:4-5:14) " isElement" --> (1:47-1:57) " isElement"
(5:14-5:30) "(shouldBeElement" --> (1:57-1:73) "(shouldBeElement"
(5:30-6:4) "),\n\t\t " --> (1:73-1:75) "),"
(6:4-7:4) " 'Element expected',\n\t\t " --> (1:75-1:95) " 'Element expected',"
(7:4-8:4) " opt_message\n\t " --> (1:95-1:107) " opt_message"
(8:4-10:1) ")\n\t);\n" --> (1:107-2:0) ");"
(1:2-2:3) " return /** @type {!Ele\tment} */ (\n\t " --> (1:0-1:9) "\n\treturn "
(2:3-3:5) " assertType_(\n\t " --> (1:9-1:21) "(assertType_"
(3:5-4:4) " assertFn,\n\t\t " --> (1:21-1:31) "(assertFn,"
(4:4-5:4) " shouldBeElement,\n\t\t " --> (1:31-1:48) " shouldBeElement,"
(5:4-5:14) " isElement" --> (1:48-1:58) " isElement"
(5:14-5:30) "(shouldBeElement" --> (1:58-1:74) "(shouldBeElement"
(5:30-6:4) "),\n\t\t " --> (1:74-1:76) "),"
(6:4-7:4) " 'Element expected',\n\t\t " --> (1:76-1:96) " 'Element expected',"
(7:4-8:4) " opt_message\n\t " --> (1:96-1:108) " opt_message"
(8:4-10:1) ")\n\t);\n" --> (1:108-2:0) "));"
(10:1-12:0) "}\n" --> (2:0-3:0) "\n}"
(12:0-12:6) "\nconst" --> (3:0-3:6) "\nconst"
(12:6-12:46) " slot = /** @type {!HTMLSlotElement} */ " --> (3:6-3:13) " slot ="
(12:46-12:48) "(e" --> (3:13-3:15) " e"
(12:48-14:0) ".target);\n" --> (3:15-4:0) ".target;"
(14:0-15:26) "\nassertElement(\n /** @type {Element} */ " --> (4:0-4:14) "\nassertElement"
(15:26-16:1) "(el),\n" --> (4:14-4:17) "(el"
(16:1-17:1) ");\n" --> (4:17-5:1) ");\n"
(12:6-12:46) " slot = /** @type {!HTMLSlotElement} */ " --> (3:6-3:14) " slot = "
(12:46-12:48) "(e" --> (3:14-3:16) "(e"
(12:48-14:0) ".target);\n" --> (3:16-4:0) ".target);"
(14:0-15:26) "\nassertElement(\n /** @type {Element} */ " --> (4:0-4:15) "\nassertElement("
(15:26-16:1) "(el),\n" --> (4:15-4:19) "(el)"
(16:1-17:1) ");\n" --> (4:19-5:1) ");\n"
@ -362,8 +362,8 @@ Unexpected token
(49:8-49:20) " function ()" --> (42:8-42:19) " function()"
(49:20-49:22) " {" --> (42:19-42:20) " "
(49:22-51:0) "};\n" --> (42:20-43:0) "{};"
(51:0-51:1) "\n" --> (43:0-43:0) ""
(51:1-51:10) "(function" --> (43:0-43:10) "\n(function"
(51:0-51:1) "\n" --> (43:0-43:1) "\n"
(51:1-51:10) "(function" --> (43:1-43:10) "(function"
(51:10-51:15) " fn()" --> (43:10-43:15) " fn()"
(51:15-51:17) " {" --> (43:15-43:16) " "
(51:17-53:0) "});\n" --> (43:16-44:0) "{});"
@ -423,8 +423,8 @@ Invalid Character `[`
(11:16-11:29) ".NODE_ENV !==" --> (1:16-1:29) ".NODE_ENV !=="
(11:29-11:43) " \"production\")" --> (1:29-1:43) " 'production')"
(11:43-12:2) " {\n " --> (1:43-2:0) " {"
(12:2-12:3) " " --> (2:0-2:1) "\n"
(12:3-12:14) "(function()" --> (2:1-2:13) "\t(function()"
(12:2-12:3) " " --> (2:0-2:2) "\n\t"
(12:3-12:14) "(function()" --> (2:2-2:13) "(function()"
(12:14-13:0) " {" --> (2:13-3:0) " {"
(13:0-15:0) "\n'use strict';\n" --> (3:0-4:2) "\n\t\t'use strict';\n\t"
(15:0-15:4) "\nvar" --> (4:2-4:6) "\tvar"

View file

@ -2,6 +2,9 @@ commit: a1587416
minifier_test262 Summary:
AST Parsed : 46406/46406 (100.00%)
Positive Passed: 46404/46406 (100.00%)
Positive Passed: 46401/46406 (99.99%)
Expect to Parse: "language/expressions/new/S11.2.2_A3_T1.js"
Expect to Parse: "language/expressions/new/S11.2.2_A3_T4.js"
Expect to Parse: "language/types/reference/put-value-prop-base-primitive.js"
Expect to Parse: "staging/explicit-resource-management/call-dispose-methods.js"
Expect to Parse: "staging/explicit-resource-management/exception-handling.js"

View file

@ -0,0 +1 @@
(idCounter++).toString(32)

View file

@ -1,6 +1,6 @@
parser_misc Summary:
AST Parsed : 21/21 (100.00%)
Positive Passed: 21/21 (100.00%)
AST Parsed : 22/22 (100.00%)
Positive Passed: 22/22 (100.00%)
Negative Passed: 11/11 (100.00%)
× Unexpected token

View file

@ -1,6 +1,6 @@
prettier_misc Summary:
AST Parsed : 21/21 (100.00%)
Positive Passed: 11/21 (52.38%)
AST Parsed : 22/22 (100.00%)
Positive Passed: 12/22 (54.55%)
Expect to Parse: "pass/oxc-1740.tsx"
Expect to Parse: "pass/oxc-2087.ts"
Expect to Parse: "pass/oxc-2394.ts"

View file

@ -1,3 +1,3 @@
transformer_misc Summary:
AST Parsed : 21/21 (100.00%)
Positive Passed: 21/21 (100.00%)
AST Parsed : 22/22 (100.00%)
Positive Passed: 22/22 (100.00%)

View file

@ -2,5 +2,6 @@ commit: d8086f14
transformer_typescript Summary:
AST Parsed : 5283/5283 (100.00%)
Positive Passed: 5282/5283 (99.98%)
Positive Passed: 5281/5283 (99.96%)
Mismatch: "compiler/elidedEmbeddedStatementsReplacedWithSemicolon.ts"
Mismatch: "conformance/esDecorators/esDecorators-decoratorExpression.3.ts"

View file

@ -19,11 +19,11 @@ export type A = {
[presentNs.a]: number;
[Symbol.iterator]: number;
[globalThis.Symbol.toStringTag]: number;
[globalThis.Symbol.unscopables]: number;
[(globalThis.Symbol).unscopables]: number;
[aliasing.isConcatSpreadable]: number;
[1]: number;
['2']: number;
[missing2]: number;
[(missing2)]: number;
[Math.random() > 0.5 ? 'f1' : 'f2']: number;
};
export interface B {
@ -32,11 +32,11 @@ export interface B {
[presentNs.a]: number;
[Symbol.iterator]: number;
[globalThis.Symbol.toStringTag]: number;
[globalThis.Symbol.unscopables]: number;
[(globalThis.Symbol).unscopables]: number;
[aliasing.isConcatSpreadable]: number;
[1]: number;
['2']: number;
[missing2]: number;
[(missing2)]: number;
[Math.random() > 0.5 ? 'f1' : 'f2']: number;
}
export class C {
@ -45,11 +45,11 @@ export class C {
[presentNs.a]: number = 1;
[Symbol.iterator]: number = 1;
[globalThis.Symbol.toStringTag]: number = 1;
[globalThis.Symbol.unscopables]: number = 1;
[(globalThis.Symbol).unscopables]: number = 1;
[aliasing.isConcatSpreadable]: number = 1;
[1]: number = 1;
['2']: number = 1;
[missing2]: number = 1;
[(missing2)]: number = 1;
[Math.random() > 0.5 ? 'f1' : 'f2']: number = 1;
}
export const D = {
@ -58,11 +58,11 @@ export const D = {
[presentNs.a]: 1,
[Symbol.iterator]: 1,
[globalThis.Symbol.toStringTag]: 1,
[globalThis.Symbol.unscopables]: 1,
[(globalThis.Symbol).unscopables]: 1,
[aliasing.isConcatSpreadable]: 1,
[1]: 1,
['2']: 1,
[missing2]: 1,
[(missing2)]: 1,
[Math.random() > 0.5 ? 'f1' : 'f2']: 1
};
@ -77,11 +77,11 @@ export type A = {
[presentNs.a]: number;
[Symbol.iterator]: number;
[globalThis.Symbol.toStringTag]: number;
[globalThis.Symbol.unscopables]: number;
[(globalThis.Symbol).unscopables]: number;
[aliasing.isConcatSpreadable]: number;
[1]: number;
['2']: number;
[missing2]: number;
[(missing2)]: number;
[Math.random() > 0.5 ? 'f1' : 'f2']: number;
};
export interface B {
@ -90,11 +90,11 @@ export interface B {
[presentNs.a]: number;
[Symbol.iterator]: number;
[globalThis.Symbol.toStringTag]: number;
[globalThis.Symbol.unscopables]: number;
[(globalThis.Symbol).unscopables]: number;
[aliasing.isConcatSpreadable]: number;
[1]: number;
['2']: number;
[missing2]: number;
[(missing2)]: number;
[Math.random() > 0.5 ? 'f1' : 'f2']: number;
}
export declare class C {

View file

@ -1,6 +1,6 @@
commit: 12619ffe
Passed: 473/927
Passed: 444/927
# All Passed:
* babel-preset-react
@ -433,21 +433,25 @@ Passed: 473/927
* shipped-proposals/new-class-features-chrome-94/input.js
* shipped-proposals/new-class-features-firefox-70/input.js
# babel-plugin-transform-arrow-functions (1/6)
# babel-plugin-transform-arrow-functions (0/6)
* assumption-newableArrowFunctions-false/basic/input.js
* assumption-newableArrowFunctions-false/naming/input.js
* assumption-newableArrowFunctions-false/self-referential/input.js
* spec/newableArrowFunction-default/input.js
* spec/newableArrowFunction-vs-spec-false/input.js
* spec/newableArrowFunction-vs-spec-true/input.js
# babel-preset-typescript (7/10)
# babel-preset-typescript (5/10)
* jsx-compat/js-valid/input.js
* jsx-compat/tsx-valid/input.tsx
* node-extensions/import-in-cts/input.cts
* opts/optimizeConstEnums/input.ts
* opts/rewriteImportExtensions/input.ts
# babel-plugin-transform-typescript (129/151)
# babel-plugin-transform-typescript (128/151)
* class/accessor-allowDeclareFields-false/input.ts
* class/accessor-allowDeclareFields-true/input.ts
* class/private-method-override/input.ts
* enum/mix-references/input.ts
* enum/ts5.0-const-foldable/input.ts
* exports/declared-types/input.ts
@ -469,9 +473,34 @@ Passed: 473/927
* optimize-const-enums/merged-exported/input.ts
* regression/15768/input.ts
# babel-plugin-transform-react-jsx (141/142)
# babel-plugin-transform-react-jsx (120/142)
* autoImport/auto-import-react-source-type-module/input.js
* autoImport/auto-import-react-source-type-script/input.js
* autoImport/import-source/input.js
* autoImport/import-source-pragma/input.js
* autoImport/react-defined/input.js
* react/arrow-functions/input.js
* react/does-not-add-source-self/input.mjs
* react/should-properly-handle-comments-between-props/input.js
* react-automatic/arrow-functions/input.js
* react-automatic/does-not-add-source-self-automatic/input.mjs
* react-automatic/handle-nonstatic-children/input.js
* react-automatic/handle-static-children/input.js
* react-automatic/key-undefined-works/input.js
* react-automatic/should-properly-handle-comments-between-props/input.js
* react-automatic/should-properly-handle-keys/input.js
* react-automatic/should-use-createElement-when-key-comes-after-spread/input.js
* react-automatic/should-use-jsx-when-key-comes-before-spread/input.js
* runtime/classic/input.js
* runtime/defaults-to-automatic/input.js
* runtime/pragma-runtime-classsic/input.js
* runtime/runtime-automatic/input.js
* sourcemaps/JSXText/input.js
# babel-plugin-transform-react-jsx-development (9/10)
# babel-plugin-transform-react-jsx-development (5/10)
* cross-platform/auto-import-dev/input.js
* cross-platform/classic-runtime/input.js
* cross-platform/handle-static-children/input.js
* cross-platform/within-derived-classes-constructor/input.js
* cross-platform/within-ts-module-block/input.ts