From 11bca27c56e3934e898eeed53bd9daa26f933c7b Mon Sep 17 00:00:00 2001 From: Bishops-exe Date: Sat, 13 Jun 2026 12:40:55 +0200 Subject: [PATCH] feat(wasm): derive Tsify on all AST and block types Enables accurate TypeScript type generation from Rust types directly. Replaces manual serde_wasm_bindgen::from_value/to_value calls in build() and diagnostic_to_string() with Tsify-typed parameters. Adds FxHashSet, SmolStr, and Value TS aliases to supplement FxHashMap. --- gdsl.py | 7 ++++--- src/ast/arg.rs | 4 ++-- src/ast/asset.rs | 4 ++-- src/ast/const_expr.rs | 5 +++-- src/ast/enum_.rs | 4 ++-- src/ast/enum_variant.rs | 4 ++-- src/ast/expr.rs | 4 ++-- src/ast/func.rs | 4 ++-- src/ast/list.rs | 6 +++--- src/ast/name.rs | 4 ++-- src/ast/proc.rs | 4 ++-- src/ast/references.rs | 5 +++-- src/ast/rotation_style.rs | 3 ++- src/ast/sprite.rs | 5 +++-- src/ast/stmt.rs | 4 ++-- src/ast/struct_.rs | 4 ++-- src/ast/struct_field.rs | 4 ++-- src/ast/struct_literal_field.rs | 3 ++- src/ast/type_.rs | 4 ++-- src/ast/value.rs | 1 - src/ast/var.rs | 4 ++-- src/blocks.rs | 9 +++++---- src/lexer/token.rs | 4 ++-- src/wasm.rs | 19 ++++++++++--------- 24 files changed, 63 insertions(+), 56 deletions(-) diff --git a/gdsl.py b/gdsl.py index f8229b96..8c4159bf 100644 --- a/gdsl.py +++ b/gdsl.py @@ -186,6 +186,7 @@ def parse(): f = open("src/blocks.rs", "w") f.write(""" +use tsify::Tsify; use serde::{Deserialize, Serialize}; pub struct Menu { pub input: &'static str, @@ -194,7 +195,7 @@ def parse(): pub field: &'static str, } """) -f.write("#[derive(Debug, Copy, Clone, Serialize, Deserialize)]\npub enum UnOp {") +f.write("#[derive(Tsify, Debug, Copy, Clone, Serialize, Deserialize)]\npub enum UnOp {") for un_op in un_ops: f.write(f"{un_op},") f.write("}\n\n") @@ -232,7 +233,7 @@ def parse(): f.write("}") f.write("}") f.write("}\n\n") -f.write("#[derive(Debug, Copy, Clone, Serialize, Deserialize)]\npub enum BinOp {") +f.write("#[derive(Tsify, Debug, Copy, Clone, Serialize, Deserialize)]\npub enum BinOp {") for bin_op in bin_ops: f.write(f"{bin_op},") f.write("}\n\n") @@ -269,7 +270,7 @@ def parse(): def write_blocks(typename: str, blocks: dict[str, Block | list[Block]]): f.write( - f"#[derive(Debug, Copy, Clone, Serialize, Deserialize)]\npub enum {typename} {{" + f"#[derive(Tsify, Debug, Copy, Clone, Serialize, Deserialize)]\npub enum {typename} {{" ) for variant, block in blocks.items(): if isinstance(block, list): diff --git a/src/ast/arg.rs b/src/ast/arg.rs index a3fda59c..3ccb3154 100644 --- a/src/ast/arg.rs +++ b/src/ast/arg.rs @@ -3,14 +3,14 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::{ type_::Type, ConstExpr, }; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct Arg { pub name: SmolStr, pub span: Span, diff --git a/src/ast/asset.rs b/src/ast/asset.rs index 72512cb2..66d77bf2 100644 --- a/src/ast/asset.rs +++ b/src/ast/asset.rs @@ -5,10 +5,10 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Tsify, Debug, Serialize, Deserialize, Clone)] pub struct Asset { pub name: SmolStr, pub path: SmolStr, diff --git a/src/ast/const_expr.rs b/src/ast/const_expr.rs index 8ac4e8ca..74233224 100644 --- a/src/ast/const_expr.rs +++ b/src/ast/const_expr.rs @@ -3,6 +3,7 @@ use serde::{ Deserialize, Serialize, }; +use tsify::Tsify; use super::{ StructLiteralField, @@ -16,7 +17,7 @@ use crate::{ misc::SmolStr, }; -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Tsify, Debug, Serialize, Deserialize, Clone)] pub enum ConstExpr { Value { value: Value, @@ -35,7 +36,7 @@ pub enum ConstExpr { }, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] pub struct ConstStructLiteralField { pub name: SmolStr, pub name_span: Span, diff --git a/src/ast/enum_.rs b/src/ast/enum_.rs index 5c6bc27e..b86f7746 100644 --- a/src/ast/enum_.rs +++ b/src/ast/enum_.rs @@ -3,11 +3,11 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::enum_variant::EnumVariant; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct Enum { pub name: SmolStr, pub span: Span, diff --git a/src/ast/enum_variant.rs b/src/ast/enum_variant.rs index beaed7a2..ffcc5191 100644 --- a/src/ast/enum_variant.rs +++ b/src/ast/enum_variant.rs @@ -3,11 +3,11 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::value::Value; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct EnumVariant { pub name: SmolStr, pub span: Span, diff --git a/src/ast/expr.rs b/src/ast/expr.rs index b9d778c0..7ed12f2c 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -4,7 +4,7 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::{ value::Value, Name, @@ -19,7 +19,7 @@ use crate::{ misc::SmolStr, }; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] pub enum Expr { Value { value: Value, diff --git a/src/ast/func.rs b/src/ast/func.rs index 6c2d8aea..4d04bf11 100644 --- a/src/ast/func.rs +++ b/src/ast/func.rs @@ -3,11 +3,11 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::Type; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct Func { pub name: SmolStr, pub span: Span, diff --git a/src/ast/list.rs b/src/ast/list.rs index b0c46da7..89f3b937 100644 --- a/src/ast/list.rs +++ b/src/ast/list.rs @@ -3,14 +3,14 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::{ type_::Type, ConstExpr, }; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct List { pub name: SmolStr, pub span: Span, @@ -19,7 +19,7 @@ pub struct List { pub is_used: bool, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub enum ListDefault { Values(Vec), File { path: SmolStr, span: Span }, diff --git a/src/ast/name.rs b/src/ast/name.rs index f5f30c3d..ce546af6 100644 --- a/src/ast/name.rs +++ b/src/ast/name.rs @@ -3,10 +3,10 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use crate::misc::SmolStr; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] pub enum Name { Name { name: SmolStr, diff --git a/src/ast/proc.rs b/src/ast/proc.rs index 909cd91e..6086197b 100644 --- a/src/ast/proc.rs +++ b/src/ast/proc.rs @@ -3,10 +3,10 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct Proc { pub name: SmolStr, pub span: Span, diff --git a/src/ast/references.rs b/src/ast/references.rs index 2a877035..44bd6223 100644 --- a/src/ast/references.rs +++ b/src/ast/references.rs @@ -3,10 +3,11 @@ use serde::{ Deserialize, Serialize, }; +use tsify::Tsify; use crate::misc::SmolStr; -#[derive(Debug, Default, Serialize, Deserialize)] +#[derive(Tsify, Debug, Default, Serialize, Deserialize)] pub struct References { pub procs: FxHashSet, pub funcs: FxHashSet, @@ -16,7 +17,7 @@ pub struct References { pub args: FxHashSet, } -#[derive(Debug, Default, Serialize, Deserialize, Eq, PartialEq, Hash)] +#[derive(Tsify, Debug, Default, Serialize, Deserialize, Eq, PartialEq, Hash)] pub struct NameReference { pub name: SmolStr, pub field: Option, diff --git a/src/ast/rotation_style.rs b/src/ast/rotation_style.rs index 4e621260..88b58d59 100644 --- a/src/ast/rotation_style.rs +++ b/src/ast/rotation_style.rs @@ -4,8 +4,9 @@ use serde::{ Deserialize, Serialize, }; +use tsify::Tsify; -#[derive(Default, Debug, Serialize, Deserialize)] +#[derive(Tsify, Default, Debug, Serialize, Deserialize)] pub enum RotationStyle { LeftRight, #[default] diff --git a/src/ast/sprite.rs b/src/ast/sprite.rs index 6980bf97..ff5d9665 100644 --- a/src/ast/sprite.rs +++ b/src/ast/sprite.rs @@ -7,7 +7,7 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::*; use crate::{ diagnostic::{ @@ -17,7 +17,8 @@ use crate::{ misc::SmolStr, }; -#[derive(Debug, Default, Serialize, Deserialize)] +#[derive(Tsify, Debug, Default, Serialize, Deserialize)] +#[tsify(from_wasm_abi, into_wasm_abi)] pub struct Sprite { pub costumes: Vec, pub sounds: Vec, diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 60aa56f0..9b3484d3 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -4,7 +4,7 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::{ expr::Expr, type_::Type, @@ -19,7 +19,7 @@ use crate::{ misc::SmolStr, }; -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Tsify, Clone, Debug, Serialize, Deserialize)] pub enum Stmt { Repeat { times: Box, diff --git a/src/ast/struct_.rs b/src/ast/struct_.rs index 33051098..492f1d0d 100644 --- a/src/ast/struct_.rs +++ b/src/ast/struct_.rs @@ -3,14 +3,14 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::{ struct_field::StructField, ConstExpr, }; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct Struct { pub name: SmolStr, pub span: Span, diff --git a/src/ast/struct_field.rs b/src/ast/struct_field.rs index 456a5755..4ca35cad 100644 --- a/src/ast/struct_field.rs +++ b/src/ast/struct_field.rs @@ -3,11 +3,11 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::ConstExpr; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct StructField { pub name: SmolStr, pub span: Span, diff --git a/src/ast/struct_literal_field.rs b/src/ast/struct_literal_field.rs index 9268879a..9d51117b 100644 --- a/src/ast/struct_literal_field.rs +++ b/src/ast/struct_literal_field.rs @@ -3,11 +3,12 @@ use serde::{ Deserialize, Serialize, }; +use tsify::Tsify; use super::Expr; use crate::misc::SmolStr; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] pub struct StructLiteralField { pub name: SmolStr, pub span: Span, diff --git a/src/ast/type_.rs b/src/ast/type_.rs index 9bd5d9a4..5d5c8e98 100644 --- a/src/ast/type_.rs +++ b/src/ast/type_.rs @@ -6,10 +6,10 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use crate::misc::SmolStr; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] pub enum Type { Value, Struct { name: SmolStr, span: Span }, diff --git a/src/ast/value.rs b/src/ast/value.rs index 3f63bd5c..19e9a28e 100644 --- a/src/ast/value.rs +++ b/src/ast/value.rs @@ -6,7 +6,6 @@ use serde::{ Deserialize, Serialize, }; - use crate::misc::SmolStr; #[derive(Debug, Clone)] diff --git a/src/ast/var.rs b/src/ast/var.rs index 7f7f83a7..5391bfd0 100644 --- a/src/ast/var.rs +++ b/src/ast/var.rs @@ -3,14 +3,14 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::{ type_::Type, ConstExpr, }; use crate::misc::SmolStr; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Tsify, Debug, Serialize, Deserialize)] pub struct Var { pub name: SmolStr, pub span: Span, diff --git a/src/blocks.rs b/src/blocks.rs index 385a4a60..80bd707c 100644 --- a/src/blocks.rs +++ b/src/blocks.rs @@ -2,13 +2,14 @@ use serde::{ Deserialize, Serialize, }; +use tsify::Tsify; pub struct Menu { pub input: &'static str, pub opcode: &'static str, pub default: &'static str, pub field: &'static str, } -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Copy, Clone, Serialize, Deserialize)] pub enum UnOp { Not, Length, @@ -101,7 +102,7 @@ impl UnOp { } } -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Copy, Clone, Serialize, Deserialize)] pub enum BinOp { Add, Sub, @@ -180,7 +181,7 @@ impl BinOp { } } } -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Copy, Clone, Serialize, Deserialize)] pub enum Block { Move, TurnLeft, @@ -1097,7 +1098,7 @@ impl Block { } } } -#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +#[derive(Tsify, Debug, Copy, Clone, Serialize, Deserialize)] pub enum Repr { XPosition, YPosition, diff --git a/src/lexer/token.rs b/src/lexer/token.rs index 3fee5a0d..ddb6437a 100644 --- a/src/lexer/token.rs +++ b/src/lexer/token.rs @@ -8,11 +8,11 @@ use serde::{ Deserialize, Serialize, }; - +use tsify::Tsify; use super::literal::*; use crate::misc::SmolStr; -#[derive(Debug, Logos, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Tsify, Debug, Logos, Clone, PartialEq, Serialize, Deserialize)] #[logos(skip r"[ \r\t\f]+")] #[logos(skip r"#[^\n]*\n")] pub enum Token { diff --git a/src/wasm.rs b/src/wasm.rs index f9bab1c6..15f7c54f 100644 --- a/src/wasm.rs +++ b/src/wasm.rs @@ -37,9 +37,13 @@ export interface Span { end: number } -type Sprite = object +type FxHashMap = Map; -type FxHashMap = Map +type FxHashSet = Set; + +type SmolStr = string; + +type Value = boolean | number | string; "; #[derive(Tsify, Serialize, Deserialize)] @@ -51,22 +55,19 @@ pub struct Build { } #[wasm_bindgen] -pub fn build(fs: JsValue) -> JsValue { - let fs: MemFS = serde_wasm_bindgen::from_value(fs).unwrap(); +pub fn build(fs: MemFS) -> Build { let fs = Rc::new(RefCell::new(fs)); let mut file = Vec::new(); let sb3 = Sb3::new(Cursor::new(&mut file), fs.clone(), "project".into()); let stdlib = StandardLibrary { path: "stdlib".into(), - version: Version::new(0, 0, 0), + version: Version::new(0, 0, 0), }; let artifact = build_impl(fs, "project".into(), sb3, Some(stdlib)).unwrap(); - serde_wasm_bindgen::to_value(&Build { file, artifact }).unwrap() + Build { file, artifact } } #[wasm_bindgen] -pub fn diagnostic_to_string(diagnostic: JsValue, sprite: JsValue) -> String { - let diagnostic: Diagnostic = serde_wasm_bindgen::from_value(diagnostic).unwrap(); - let sprite: Sprite = serde_wasm_bindgen::from_value(sprite).unwrap(); +pub fn diagnostic_to_string(diagnostic: Diagnostic, sprite: Sprite) -> String { diagnostic.kind.to_string(&sprite) }