Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support webidl namespaces. #678

Merged
merged 13 commits into from
Aug 13, 2018
15 changes: 15 additions & 0 deletions crates/backend/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ pub struct Program {
pub structs: Vec<Struct>,
/// rust consts
pub consts: Vec<Const>,
/// rust submodules
pub modules: Vec<Module>,
}

/// A rust module
///
/// This exists to give the ability to namespace js imports.
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
pub struct Module {
/// module name
pub name: String,
/// js -> rust interfaces
pub imports: Vec<Import>,
}

/// A rust to js interface. Allows interaction with rust objects/functions
Expand Down Expand Up @@ -227,6 +240,8 @@ impl Program {
structs: self.structs.iter().map(|a| a.shared()).collect(),
enums: self.enums.iter().map(|a| a.shared()).collect(),
imports: self.imports.iter()
// add in imports from inside modules
.chain(self.modules.iter().flat_map(|m| m.imports.iter()))
.map(|a| a.shared())
.collect::<Result<_, Diagnostic>>()?,
version: shared::version(),
Expand Down
31 changes: 31 additions & 0 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ impl TryToTokens for ast::Program {
for i in self.imports.iter() {
DescribeImport(&i.kind).to_tokens(tokens);

// If there is a js namespace, check that name isn't a type. If it is,
// this import might be a method on that type.
if let Some(ns) = &i.js_namespace {
if types.contains(ns) && i.kind.fits_on_impl() {
let kind = match i.kind.try_to_token_stream() {
Expand All @@ -61,6 +63,11 @@ impl TryToTokens for ast::Program {
errors.push(e);
}
}
for m in self.modules.iter() {
if let Err(e) = m.try_to_tokens(tokens) {
errors.push(e);
}
}
for e in self.enums.iter() {
e.to_tokens(tokens);
}
Expand All @@ -87,6 +94,7 @@ impl TryToTokens for ast::Program {
// Each JSON blob is prepended with the length of the JSON blob so when
// all these sections are concatenated in the final wasm file we know
// how to extract all the JSON pieces, so insert the byte length here.
// The value is little-endian.
let generated_static_length = description.len() + 4;
let mut bytes = vec![
(description.len() >> 0) as u8,
Expand Down Expand Up @@ -1103,6 +1111,29 @@ impl ToTokens for ast::Const {
}
}

impl TryToTokens for ast::Module {
fn try_to_tokens(&self, tokens: &mut TokenStream) -> Result<(), Diagnostic> {
let mut errors = Vec::new();
for i in self.imports.iter() {
DescribeImport(&i.kind).to_tokens(tokens);
}
let name = &self.name;
let mut body = TokenStream::new();
for i in self.imports.iter() {
if let Err(e) = i.kind.try_to_tokens(&mut body) {
errors.push(e);
}
}
Diagnostic::from_vec(errors)?;
(quote!{
pub mod #name {
#body
}
}).to_tokens(tokens);
Ok(())
}
}

/// Emits the necessary glue tokens for "descriptor", generating an appropriate
/// symbol name as well as attributes around the descriptor function itself.
struct Descriptor<'a, T>(&'a Ident, T);
Expand Down