fix(codegen): print TSNonNullExpression (#4869)

This commit is contained in:
Boshen 2024-08-13 08:47:07 +00:00
parent 3da33d3647
commit a2269625cc
4 changed files with 88 additions and 49 deletions

View file

@ -1072,30 +1072,14 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for Expression<'a> {
Self::JSXFragment(fragment) => fragment.gen(p, 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);
p.print_str(" satisfies ");
e.type_annotation.gen(p, ctx);
}
Self::TSSatisfiesExpression(e) => e.gen_expr(p, precedence, ctx),
Self::TSTypeAssertion(e) => e.gen_expr(p, precedence, ctx),
Self::TSNonNullExpression(e) => e.expression.gen_expr(p, precedence, ctx),
Self::TSInstantiationExpression(e) => e.expression.gen_expr(p, precedence, ctx),
Self::TSNonNullExpression(e) => e.gen_expr(p, precedence, ctx),
Self::TSInstantiationExpression(e) => e.gen_expr(p, precedence, ctx),
}
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSAsExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
p.print_char(b'(');
p.print_char(b'(');
self.expression.gen_expr(p, precedence, ctx);
p.print_char(b')');
p.print_str(" as ");
self.type_annotation.gen(p, ctx);
p.print_char(b')');
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for ParenthesizedExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
self.expression.gen_expr(p, precedence, ctx);
@ -1887,10 +1871,10 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for SimpleAssignmentTarget<'a> {
self.to_member_expression().gen_expr(p, precedence, ctx);
}
Self::TSAsExpression(e) => e.gen_expr(p, precedence, ctx),
Self::TSSatisfiesExpression(e) => e.expression.gen_expr(p, precedence, ctx),
Self::TSNonNullExpression(e) => e.expression.gen_expr(p, precedence, ctx),
Self::TSSatisfiesExpression(e) => e.gen_expr(p, precedence, ctx),
Self::TSNonNullExpression(e) => e.gen_expr(p, precedence, ctx),
Self::TSTypeAssertion(e) => e.gen_expr(p, precedence, ctx),
Self::TSInstantiationExpression(e) => e.expression.gen_expr(p, precedence, ctx),
Self::TSInstantiationExpression(e) => e.gen_expr(p, precedence, ctx),
}
}
}
@ -2127,6 +2111,60 @@ impl<'a, const MINIFY: bool> GenExpr<MINIFY> for NewExpression<'a> {
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSAsExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
p.print_char(b'(');
p.print_char(b'(');
self.expression.gen_expr(p, precedence, ctx);
p.print_char(b')');
p.print_str(" as ");
self.type_annotation.gen(p, ctx);
p.print_char(b')');
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSSatisfiesExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
// TODO: print properly
self.expression.gen_expr(p, precedence, ctx);
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSNonNullExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
p.wrap(matches!(self.expression, Expression::ParenthesizedExpression(_)), |p| {
self.expression.gen_expr(p, precedence, ctx);
});
p.print_char(b'!');
if MINIFY {
p.print_hard_space();
}
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSInstantiationExpression<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
// TODO: print properly
self.expression.gen_expr(p, precedence, ctx);
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSTypeAssertion<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
p.wrap(precedence >= self.precedence(), |p| {
p.print_str("<");
// var r = < <T>(x: T) => T > ((x) => { return null; });
// ^ make sure space is printed here.
if matches!(self.type_annotation, TSType::TSFunctionType(_)) {
p.print_hard_space();
}
self.type_annotation.gen(p, ctx);
p.print_str(">");
self.expression.gen_expr(p, Precedence::Member, ctx);
});
}
}
impl<'a, const MINIFY: bool> Gen<MINIFY> for MetaProperty<'a> {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) {
p.add_source_mapping(self.span.start);
@ -3599,22 +3637,6 @@ impl<'a, const MINIFY: bool> Gen<MINIFY> for TSModuleReference<'a> {
}
}
impl<'a, const MINIFY: bool> GenExpr<MINIFY> for TSTypeAssertion<'a> {
fn gen_expr(&self, p: &mut Codegen<{ MINIFY }>, precedence: Precedence, ctx: Context) {
p.wrap(precedence >= self.precedence(), |p| {
p.print_str("<");
// var r = < <T>(x: T) => T > ((x) => { return null; });
// ^ make sure space is printed here.
if matches!(self.type_annotation, TSType::TSFunctionType(_)) {
p.print_hard_space();
}
self.type_annotation.gen(p, ctx);
p.print_str(">");
self.expression.gen_expr(p, Precedence::Member, ctx);
});
}
}
impl<const MINIFY: bool> Gen<MINIFY> for TSAccessibility {
fn gen(&self, p: &mut Codegen<{ MINIFY }>, _ctx: Context) {
match self {

View file

@ -94,3 +94,15 @@ abstract class A {private abstract static readonly prop: string}
abstract class A {
private abstract static readonly prop: string;
}
a = x!;
a = x!;
b = (x as y);
b = ((x) as y);
c = foo<string>;
c = foo;
d = x satisfies y;
d = x;

View file

@ -5,6 +5,16 @@ use oxc_codegen::{CodeGenerator, CodegenOptions};
use oxc_parser::Parser;
use oxc_span::SourceType;
fn codegen(source_text: &str) -> String {
let allocator = Allocator::default();
let source_type = SourceType::default().with_typescript(true).with_module(true);
let ret = Parser::new(&allocator, source_text, source_type).parse();
CodeGenerator::new()
.with_options(CodegenOptions { single_quote: true })
.build(&ret.program)
.source_text
}
#[test]
fn ts() {
let cases = [
@ -36,6 +46,10 @@ fn ts() {
"class A {constructor(public readonly a: number) {}}",
"abstract class A {private abstract static m() {}}",
"abstract class A {private abstract static readonly prop: string}",
"a = x!;",
"b = (x as y);",
"c = foo<string>;",
"d = x satisfies y;",
];
let snapshot = cases.into_iter().fold(String::new(), |mut w, case| {
@ -47,13 +61,3 @@ fn ts() {
insta::assert_snapshot!("ts", snapshot);
});
}
fn codegen(source_text: &str) -> String {
let allocator = Allocator::default();
let source_type = SourceType::default().with_typescript(true).with_module(true);
let ret = Parser::new(&allocator, source_text, source_type).parse();
CodeGenerator::new()
.with_options(CodegenOptions { single_quote: true })
.build(&ret.program)
.source_text
}

View file

@ -2,7 +2,8 @@ commit: d8086f14
transformer_typescript Summary:
AST Parsed : 6456/6456 (100.00%)
Positive Passed: 6453/6456 (99.95%)
Positive Passed: 6452/6456 (99.94%)
Mismatch: "compiler/constEnumNamespaceReferenceCausesNoImport2.ts"
Mismatch: "compiler/incrementOnNullAssertion.ts"
Mismatch: "conformance/externalModules/typeOnly/exportDeclaration.ts"
Mismatch: "conformance/jsx/inline/inlineJsxAndJsxFragPragmaOverridesCompilerOptions.tsx"