0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-01 12:16:11 -05:00
This commit is contained in:
Marvin Hagemeister 2025-01-09 19:00:23 +01:00
parent 3f16eec700
commit aed3d16ff8
3 changed files with 113 additions and 14 deletions

View file

@ -61,7 +61,9 @@ use deno_ast::swc::ast::TsFnParam;
use deno_ast::swc::ast::TsIndexSignature;
use deno_ast::swc::ast::TsLit;
use deno_ast::swc::ast::TsLitType;
use deno_ast::swc::ast::TsModuleName;
use deno_ast::swc::ast::TsModuleRef;
use deno_ast::swc::ast::TsNamespaceBody;
use deno_ast::swc::ast::TsParamPropParam;
use deno_ast::swc::ast::TsThisTypeOrIdent;
use deno_ast::swc::ast::TsType;
@ -965,8 +967,10 @@ fn serialize_expr(ctx: &mut TsEsTreeBuilder, expr: &Expr) -> NodeRef {
Expr::TsConstAssertion(node) => {
let expr = serialize_expr(ctx, node.expr.as_ref());
// TODO(@marvinhagemeister): type_ann
ctx.write_ts_as_expr(&node.span, expr, NodeRef(0))
let type_name = ctx.write_identifier(&node.span, "const", false, None);
let type_ann = ctx.write_ts_type_ref(&node.span, type_name, None);
ctx.write_ts_as_expr(&node.span, expr, type_ann)
}
Expr::TsNonNull(node) => {
let expr = serialize_expr(ctx, node.expr.as_ref());
@ -1278,8 +1282,6 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
.decls
.iter()
.map(|decl| {
// TODO(@marvinhagemeister): Definite?
let ident = serialize_pat(ctx, &decl.name);
let init = decl
.init
@ -1309,8 +1311,6 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
.decls
.iter()
.map(|decl| {
// TODO(@marvinhagemeister): Definite?
let ident = serialize_pat(ctx, &decl.name);
let init = decl
.init
@ -1397,8 +1397,30 @@ fn serialize_decl(ctx: &mut TsEsTreeBuilder, decl: &Decl) -> NodeRef {
let body = ctx.write_ts_enum_body(&node.span, members);
ctx.write_ts_enum(&node.span, node.declare, node.is_const, id, body)
}
Decl::TsModule(_) => {
todo!()
Decl::TsModule(node) => {
let ident = match node.id {
TsModuleName::Ident(ident) => serialize_ident(ctx, &ident),
TsModuleName::Str(str_lit) => {
serialize_lit(ctx, &Lit::Str(str_lit.clone()))
}
};
let body = node.body.as_ref().map(|body| match body {
TsNamespaceBody::TsModuleBlock(mod_block) => {
let items = mod_block.body;
// TODO
ctx.write_ts_module_block(&mod_block.span, items)
}
TsNamespaceBody::TsNamespaceDecl(ts_namespace_decl) => todo!(),
});
ctx.write_ts_module_decl(
&node.span,
node.declare,
node.global,
ident,
body,
)
}
}
}

View file

@ -33,6 +33,8 @@ pub enum AstNode {
TSNamespaceExportDeclaration,
TSImportEqualsDeclaration,
TSExternalModuleReference,
TSModuleDeclaration,
TSModuleBlock,
// Decls
ClassDeclaration,
@ -257,6 +259,7 @@ pub enum AstProp {
Finalizer,
Flags,
Generator,
Global,
Handler,
Id,
In,
@ -327,8 +330,6 @@ pub enum AstProp {
Value, // Last value is used for max value
}
// TODO: Feels like there should be an easier way to iterater over an
// enum in Rust and lowercase the first letter.
impl Display for AstProp {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let s = match self {
@ -382,6 +383,7 @@ impl Display for AstProp {
AstProp::Finalizer => "finalizer",
AstProp::Flags => "flags",
AstProp::Generator => "generator",
AstProp::Global => "global",
AstProp::Handler => "handler",
AstProp::Id => "id",
AstProp::In => "in",
@ -472,8 +474,6 @@ impl AstBufSerializer for TsEsTreeBuilder {
}
}
// TODO: Add a builder API to make it easier to convert from different source
// ast formats.
impl TsEsTreeBuilder {
pub fn new() -> Self {
// Max values
@ -670,7 +670,7 @@ impl TsEsTreeBuilder {
let id = self
.ctx
.append_node(AstNode::TSExternalModuleReference, span);
self.ctx.write_str(AstProp::Expression, expr);
self.ctx.write_ref(AstProp::Expression, &id, expr);
self.ctx.commit_node(id)
}
@ -1856,6 +1856,33 @@ impl TsEsTreeBuilder {
self.ctx.commit_node(id)
}
pub fn write_ts_module_decl(
&mut self,
span: &Span,
is_declare: bool,
is_global: bool,
ident: NodeRef,
body: Option<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSModuleDeclaration, span);
self.ctx.write_bool(AstProp::Declare, is_declare);
self.ctx.write_bool(AstProp::Global, is_global);
self.ctx.write_ref(AstProp::Id, &id, ident);
self.ctx.write_maybe_ref(AstProp::Body, &id, body);
self.ctx.commit_node(id)
}
pub fn write_ts_module_block(
&mut self,
span: &Span,
body: Vec<NodeRef>,
) -> NodeRef {
let id = self.ctx.append_node(AstNode::TSModuleBlock, span);
self.ctx.write_ref_vec(AstProp::Body, &id, body);
self.ctx.commit_node(id)
}
pub fn write_ts_class_implements(
&mut self,
span: &Span,

View file

@ -721,7 +721,24 @@ Deno.test("Plugin - Literal", async (t) => {
await testSnapshot(t, "/foo/g", "Literal");
});
Deno.test("Plugin - TS Interface", async (t) => {
Deno.test("Plugin - TSAsExpression", async (t) => {
await testSnapshot(t, "a as any", "TSAsExpression");
await testSnapshot(t, '"foo" as const', "TSAsExpression");
});
Deno.test("Plugin - TSEnumDeclaration", async (t) => {
await testSnapshot(t, "enum Foo {}", "TSEnumDeclaration");
await testSnapshot(t, "const enum Foo {}", "TSEnumDeclaration");
await testSnapshot(t, "enum Foo { A, B }", "TSEnumDeclaration");
await testSnapshot(t, 'enum Foo { "a-b" }', "TSEnumDeclaration");
await testSnapshot(
t,
"enum Foo { A = 1, B = 2, C = A | B }",
"TSEnumDeclaration",
);
});
Deno.test("Plugin - TSInterface", async (t) => {
await testSnapshot(t, "interface A {}", "TSInterface");
await testSnapshot(t, "interface A<T> {}", "TSInterface");
await testSnapshot(t, "interface A extends Foo<T>, Bar<T> {}", "TSInterface");
@ -736,4 +753,37 @@ Deno.test("Plugin - TS Interface", async (t) => {
await testSnapshot(t, "interface A { <T>(a: T): T }", "TSInterface");
await testSnapshot(t, "interface A { new <T>(a: T): T }", "TSInterface");
await testSnapshot(t, "interface A { a: new <T>(a: T) => T }", "TSInterface");
await testSnapshot(t, "interface A { get a(): string }", "TSInterface");
await testSnapshot(t, "interface A { set a(v: string) }", "TSInterface");
});
Deno.test("Plugin - TSSatisfiesExpression", async (t) => {
await testSnapshot(t, "{} satisfies A", "TSSatisfiesExpression");
});
Deno.test("Plugin - TSTypeAliasDeclaration", async (t) => {
await testSnapshot(t, "type A = any", "TSTypeAliasDeclaration");
await testSnapshot(t, "type A<T> = any", "TSTypeAliasDeclaration");
await testSnapshot(t, "declare type A<T> = any", "TSTypeAliasDeclaration");
});
Deno.test("Plugin - TSNonNullExpression", async (t) => {
await testSnapshot(t, "a!", "TSNonNullExpression");
});
Deno.test("Plugin - TSUnionType", async (t) => {
await testSnapshot(t, "type A = B | C", "TSUnionType");
});
Deno.test("Plugin - TSIntersectionType", async (t) => {
await testSnapshot(t, "type A = B & C", "TSIntersectionType");
});
Deno.test("Plugin - TSModuleDeclaration", async (t) => {
await testSnapshot(t, "module A;", "TSModuleDeclaration");
await testSnapshot(
t,
"declare module A { export function A(): void }",
"TSModuleDeclaration",
);
});