Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions webapi_gen/emit/interface_emitter.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,45 @@ pub impl Emitter for InterfaceEmitter with emit(
interface_methods.push(trait_method)
continue rest
}
[Attribute(attr), .. rest] if attr.static_ =>
// Static attributes are not yet handled
[Attribute(attr), .. rest] if attr.static_ => {
if attr.is_readonly && !attr.is_inherit {
// only static readonly attributes are supported for now
// TODO: log this
continue rest
}
let (attr_type, attr_emits) = arg_mbt_type(
attr.type_,
interface.name,
attr.name,
"",
self.type_registry,
)
emits.push_iter(attr_emits.iter())
if attr_type is ArgMbtType::Union(union_type_name, has_undefined) {
emits
..push(Emit::External(union_type_name))
..push(Emit::IntoMethod(union_type_name))
if has_undefined {
emits.push(Emit::IsUndefinedMethod(union_type_name))
}
emits.push(
Emit::UnionArgTraitImpl(
TypeName(union_type_name),
TraitName("T\{union_type_name}"),
),
)
}
emits.push_iter(attr_emits.iter())

// Static Attribute Get method
let static_attr_getter_method = StaticAttributeGetMethodEmit::{
interface_name: interface.name,
original_name: attr.name,
return_type: attr_type.name(),
}
interface_methods.push(static_attr_getter_method)
continue rest
}
[Attribute(attr), .. rest] => {
let (attr_type, attr_emits) = arg_mbt_type(
attr.type_,
Expand Down
42 changes: 42 additions & 0 deletions webapi_gen/emit/interface_method_emit.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,48 @@ impl InterfaceMethodEmit for AttributeSetMethodEmit with impl_emit(
Code(code.to_string())
}

//============================ Attribute Set Method Emit ======================

///|
struct StaticAttributeGetMethodEmit {
interface_name : String // Name of the interface this method belongs to, eg. Document
original_name : String // Original attribute name from IDL, eg "title"
return_type : String
} derive(Show, ToJson)

///|
impl InterfaceMethodEmit for StaticAttributeGetMethodEmit with decl_emit(
_self : StaticAttributeGetMethodEmit,
) -> Code {
Code("") // Static attributes are not included in trait declarations
}

///|
impl InterfaceMethodEmit for StaticAttributeGetMethodEmit with impl_emit(
self : StaticAttributeGetMethodEmit,
) -> Code {
// Emit FFI function
let ret_type_str = self.return_type
let trait_name = self.interface_name
let ffi_name = "\{snake_case(trait_name)}_\{snake_case(self.original_name)}_ffi"
let code = StringBuilder::new()
code
..write_string(
"extern \"js\" fn \{ffi_name}() -> \{ret_type_str} = \"() => \{trait_name}.\{self.original_name}\"",
)
..write_string("\n\n")

// Emit static attribute getter implementation
let method_name = safe_identifier(self.original_name)
code
..write_string(
"pub fn \{trait_name}::\{method_name}() -> \{ret_type_str} {\n",
)
..write_string(" \{ffi_name}()\n")
..write_string("}")
Code(code.to_string())
}

//============================ Method Emit Helpers ============================

///|
Expand Down
Loading