Skip to content

Commit

Permalink
fix(codegen): print TSNonNullExpression (#4869)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen committed Aug 13, 2024
1 parent 3da33d3 commit a226962
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 49 deletions.
98 changes: 60 additions & 38 deletions crates/oxc_codegen/src/gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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),
}
}
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down
12 changes: 12 additions & 0 deletions crates/oxc_codegen/tests/integration/snapshots/ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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;
24 changes: 14 additions & 10 deletions crates/oxc_codegen/tests/integration/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down Expand Up @@ -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| {
Expand All @@ -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
}
3 changes: 2 additions & 1 deletion tasks/coverage/transformer_typescript.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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"

0 comments on commit a226962

Please sign in to comment.