use crate::intrinsic::Intrinsic;
use crate::wit::AdapterId;
use std::borrow::Cow;
use std::collections::{BTreeMap, HashMap, HashSet};
use std::path::PathBuf;
use walrus::TypedCustomSectionId;
#[derive(Default, Debug)]
pub struct WasmBindgenAux {
pub extra_typescript: Vec<String>,
pub local_modules: HashMap<String, String>,
pub snippets: BTreeMap<String, Vec<String>>,
pub package_jsons: HashSet<PathBuf>,
pub export_map: HashMap<AdapterId, AuxExport>,
pub import_map: HashMap<AdapterId, AuxImport>,
pub reexports: BTreeMap<String, (JsImport, bool)>,
pub imports_with_catch: HashSet<AdapterId>,
pub imports_with_variadic: HashSet<AdapterId>,
pub imports_with_assert_no_shim: HashSet<AdapterId>,
pub enums: HashMap<String, AuxEnum>,
pub string_enums: HashMap<String, AuxStringEnum>,
pub structs: Vec<AuxStruct>,
pub externref_table: Option<walrus::TableId>,
pub function_table: Option<walrus::TableId>,
pub externref_alloc: Option<walrus::FunctionId>,
pub externref_drop: Option<walrus::FunctionId>,
pub externref_drop_slice: Option<walrus::FunctionId>,
pub exn_store: Option<walrus::FunctionId>,
pub destroy_closure: Option<walrus::FunctionId>,
pub stack_pointer: Option<walrus::GlobalId>,
pub thread_destroy: Option<walrus::FunctionId>,
pub js_tag: Option<walrus::TagId>,
pub wrapped_js_tag: Option<walrus::TagId>,
pub uses_reinit: bool,
}
pub type WasmBindgenAuxId = TypedCustomSectionId<WasmBindgenAux>;
#[derive(Debug)]
pub struct AuxExport {
pub debug_name: String,
pub comments: String,
pub args: Option<Vec<AuxFunctionArgumentData>>,
pub asyncness: bool,
pub kind: AuxExportKind,
pub js_namespace: Option<Vec<String>>,
pub generate_typescript: bool,
pub generate_jsdoc: bool,
pub variadic: bool,
pub fn_ret_ty_override: Option<String>,
pub fn_ret_desc: Option<String>,
}
#[derive(Debug, Clone)]
pub struct AuxFunctionArgumentData {
pub name: String,
pub ty_override: Option<String>,
pub optional: bool,
pub desc: Option<String>,
}
#[derive(Debug)]
pub enum AuxExportKind {
Function(String),
FunctionThis(String),
Constructor(String),
Method {
class: String,
name: String,
receiver: AuxReceiverKind,
kind: AuxExportedMethodKind,
},
}
#[derive(Debug, Clone, Copy)]
pub enum AuxExportedMethodKind {
Method,
Getter,
Setter,
}
#[derive(Debug, Clone, Copy)]
pub enum AuxReceiverKind {
None,
Borrowed,
Owned,
}
impl AuxReceiverKind {
pub fn is_static(self) -> bool {
matches!(self, Self::None)
}
}
#[derive(Debug)]
pub struct AuxEnum {
pub name: String,
pub comments: String,
pub variants: Vec<(String, i64, String)>,
pub generate_typescript: bool,
pub private: bool,
pub js_namespace: Option<Vec<String>>,
}
#[derive(Debug)]
pub struct AuxStringEnum {
pub name: String,
pub comments: String,
pub variant_values: Vec<String>,
pub generate_typescript: bool,
#[allow(dead_code)]
pub js_namespace: Option<Vec<String>>,
}
#[derive(Debug)]
pub struct AuxStruct {
pub name: String,
pub rust_name: String,
pub qualified_name: String,
pub comments: String,
pub is_inspectable: bool,
pub generate_typescript: bool,
pub private: bool,
pub js_namespace: Option<Vec<String>>,
}
#[derive(Debug)]
pub enum AuxImport {
Value(AuxValue),
ValueWithThis(JsImport, String),
Instanceof(JsImport),
Static { js: JsImport, optional: bool },
String(String),
Cast { sig_comment: String },
StructuralMethod(String),
StructuralGetter(String),
StructuralClassGetter(JsImport, String),
StructuralSetter(String),
StructuralClassSetter(JsImport, String),
IndexingGetterOfClass(JsImport),
IndexingGetterOfObject,
IndexingSetterOfClass(JsImport),
IndexingSetterOfObject,
IndexingDeleterOfClass(JsImport),
IndexingDeleterOfObject,
WrapInExportedClass(String),
Intrinsic(Intrinsic),
LinkTo(String, Option<String>),
UnwrapExportedClass(String),
}
#[derive(Debug)]
pub enum AuxValue {
Bare(JsImport),
Getter(JsImport, String),
ClassGetter(JsImport, String),
Setter(JsImport, String),
ClassSetter(JsImport, String),
}
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
pub struct JsImport {
pub name: JsImportName,
pub fields: Vec<String>,
}
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
pub enum JsImportName {
Global { name: String },
Module { module: String, name: String },
LocalModule { module: String, name: String },
InlineJs {
unique_crate_identifier: String,
snippet_idx_in_crate: usize,
name: String,
},
VendorPrefixed { name: String, prefixes: Vec<String> },
}
impl walrus::CustomSection for WasmBindgenAux {
fn name(&self) -> &str {
"wasm-bindgen custom section"
}
fn data(&self, _: &walrus::IdsToIndices) -> Cow<'_, [u8]> {
panic!("shouldn't emit custom sections just yet");
}
fn add_gc_roots(&self, roots: &mut walrus::passes::Roots) {
if let Some(id) = self.externref_table {
roots.push_table(id);
}
if let Some(id) = self.function_table {
roots.push_table(id);
}
if let Some(id) = self.externref_alloc {
roots.push_func(id);
}
if let Some(id) = self.externref_drop_slice {
roots.push_func(id);
}
if let Some(id) = self.exn_store {
roots.push_func(id);
}
if let Some(id) = self.destroy_closure {
roots.push_func(id);
}
if let Some(id) = self.stack_pointer {
roots.push_global(id);
}
if let Some(id) = self.thread_destroy {
roots.push_func(id);
}
if let Some(id) = self.js_tag {
roots.push_tag(id);
}
}
}