diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 2c3c9661b..cfdc23675 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -42,6 +42,7 @@ pub enum ImportKind { Static(ImportStatic), Type(ImportType), Enum(ImportEnum), + Const(Const), } #[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] @@ -174,6 +175,24 @@ pub struct TypeAlias { pub src: syn::Type, } +#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] +pub struct Const { + pub vis: syn::Visibility, + pub name: Ident, + pub interface_name: Ident, + pub ty: syn::Type, + pub value: ConstValue, +} + +#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] +/// same as webidl::ast::ConstValue +pub enum ConstValue { + BooleanLiteral(bool), + FloatLiteral(f64), + IntegerLiteral(i64), + Null, +} + impl Program { pub(crate) fn shared(&self) -> shared::Program { shared::Program { @@ -293,6 +312,7 @@ impl ImportKind { ImportKind::Static(_) => false, ImportKind::Type(_) => false, ImportKind::Enum(_) => false, + ImportKind::Const(_) => false, } } @@ -302,6 +322,7 @@ impl ImportKind { ImportKind::Static(ref f) => shared::ImportKind::Static(f.shared()), ImportKind::Type(ref f) => shared::ImportKind::Type(f.shared()), ImportKind::Enum(ref f) => shared::ImportKind::Enum(f.shared()), + ImportKind::Const(ref f) => shared::ImportKind::Const(f.shared()), } } } @@ -404,3 +425,9 @@ impl StructField { } } } + +impl Const { + fn shared(&self) -> shared::Const { + shared::Const {} + } +} diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 1e3e69af7..a83d19239 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -501,6 +501,7 @@ impl ToTokens for ast::ImportKind { ast::ImportKind::Static(ref s) => s.to_tokens(tokens), ast::ImportKind::Type(ref t) => t.to_tokens(tokens), ast::ImportKind::Enum(ref e) => e.to_tokens(tokens), + ast::ImportKind::Const(ref c) => c.to_tokens(tokens), } } } @@ -842,6 +843,7 @@ impl<'a> ToTokens for DescribeImport<'a> { ast::ImportKind::Static(_) => return, ast::ImportKind::Type(_) => return, ast::ImportKind::Enum(_) => return, + ast::ImportKind::Const(_) => return, }; let describe_name = format!("__wbindgen_describe_{}", f.shim); let describe_name = Ident::new(&describe_name, Span::call_site()); @@ -958,3 +960,41 @@ impl ToTokens for ast::TypeAlias { }).to_tokens(into); } } + +impl ToTokens for ast::Const { + fn to_tokens(&self, tokens: &mut TokenStream) { + use ast::ConstValue::*; + + let vis = &self.vis; + let name = &self.name; + let interface_name = &self.interface_name; + let ty = &self.ty; + + let value: TokenStream = match self.value { + BooleanLiteral(false) => quote!(false), + BooleanLiteral(true) => quote!(true), + // the actual type is unknown because of typedefs + // so we cannot use std::fxx::INFINITY + // but we can use type inference + FloatLiteral(f) if f.is_infinite() && f.is_sign_positive() => quote!(1.0 / 0.0), + FloatLiteral(f) if f.is_infinite() && f.is_sign_negative() => quote!(-1.0 / 0.0), + FloatLiteral(f) if f.is_nan() => quote!(0.0 / 0.0), + // again no suffix + // panics on +-inf, nan + FloatLiteral(f) => { + let f = Literal::f64_unsuffixed(f); + quote!(#f) + }, + IntegerLiteral(i) => { + let i = Literal::i64_unsuffixed(i); + quote!(#i) + }, + Null => unimplemented!(), + }; + (quote! { + impl #interface_name { + #vis const #name: #ty = #value; + } + }).to_tokens(tokens); + } +} diff --git a/crates/backend/src/defined.rs b/crates/backend/src/defined.rs index d775cb02f..84eabe505 100644 --- a/crates/backend/src/defined.rs +++ b/crates/backend/src/defined.rs @@ -106,6 +106,7 @@ impl ImportedTypes for ast::ImportKind { ast::ImportKind::Function(fun) => fun.imported_types(f), ast::ImportKind::Type(ty) => ty.imported_types(f), ast::ImportKind::Enum(enm) => enm.imported_types(f), + ast::ImportKind::Const(c) => c.imported_types(f), } } } @@ -229,6 +230,15 @@ impl ImportedTypes for ast::TypeAlias { } } +impl ImportedTypes for ast::Const { + fn imported_types(&self, f: &mut F) + where + F: FnMut(&Ident, ImportedTypeKind), + { + self.ty.imported_types(f); + } +} + /// Remove any methods, statics, &c, that reference types that are *not* /// defined. pub trait RemoveUndefinedImports { diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index ef47aa55b..b23fe2646 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1757,6 +1757,7 @@ impl<'a, 'b> SubContext<'a, 'b> { } shared::ImportKind::Type(_) => {} shared::ImportKind::Enum(_) => {} + shared::ImportKind::Const(_) => {} } Ok(()) } diff --git a/crates/shared/src/lib.rs b/crates/shared/src/lib.rs index 8df1e5344..8985733dc 100644 --- a/crates/shared/src/lib.rs +++ b/crates/shared/src/lib.rs @@ -34,6 +34,7 @@ pub enum ImportKind { Static(ImportStatic), Type(ImportType), Enum(ImportEnum), + Const(Const) } #[derive(Deserialize, Serialize)] @@ -124,6 +125,9 @@ pub struct StructField { pub comments: Vec, } +#[derive(Deserialize, Serialize)] +pub struct Const {} + pub fn new_function(struct_name: &str) -> String { let mut name = format!("__wbg_"); name.extend(struct_name.chars().flat_map(|s| s.to_lowercase()));