mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-05-04 10:02:17 +00:00
Merge pull request #846 from alexcrichton/no-modules
Remove `Module` node from the backend AST
This commit is contained in:
commit
b38b9da499
@ -19,8 +19,6 @@ pub struct Program {
|
|||||||
pub structs: Vec<Struct>,
|
pub structs: Vec<Struct>,
|
||||||
/// rust consts
|
/// rust consts
|
||||||
pub consts: Vec<Const>,
|
pub consts: Vec<Const>,
|
||||||
/// rust submodules
|
|
||||||
pub modules: Vec<Module>,
|
|
||||||
/// "dictionaries", generated for WebIDL, which are basically just "typed
|
/// "dictionaries", generated for WebIDL, which are basically just "typed
|
||||||
/// objects" in the sense that they represent a JS object with a particular
|
/// objects" in the sense that they represent a JS object with a particular
|
||||||
/// shape in JIT parlance.
|
/// shape in JIT parlance.
|
||||||
@ -250,18 +248,6 @@ pub enum ConstValue {
|
|||||||
Null,
|
Null,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A rust module
|
|
||||||
///
|
|
||||||
/// This exists to give the ability to namespace js imports.
|
|
||||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub struct Module {
|
|
||||||
pub vis: syn::Visibility,
|
|
||||||
pub name: Ident,
|
|
||||||
/// js -> rust interfaces
|
|
||||||
pub imports: Vec<Import>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Dictionary {
|
pub struct Dictionary {
|
||||||
@ -284,8 +270,6 @@ impl Program {
|
|||||||
structs: self.structs.iter().map(|a| a.shared()).collect(),
|
structs: self.structs.iter().map(|a| a.shared()).collect(),
|
||||||
enums: self.enums.iter().map(|a| a.shared()).collect(),
|
enums: self.enums.iter().map(|a| a.shared()).collect(),
|
||||||
imports: self.imports.iter()
|
imports: self.imports.iter()
|
||||||
// add in imports from inside modules
|
|
||||||
.chain(self.modules.iter().flat_map(|m| m.imports.iter()))
|
|
||||||
.map(|a| a.shared())
|
.map(|a| a.shared())
|
||||||
.collect::<Result<_, Diagnostic>>()?,
|
.collect::<Result<_, Diagnostic>>()?,
|
||||||
version: shared::version(),
|
version: shared::version(),
|
||||||
|
@ -69,11 +69,6 @@ impl TryToTokens for ast::Program {
|
|||||||
for c in self.consts.iter() {
|
for c in self.consts.iter() {
|
||||||
c.to_tokens(tokens);
|
c.to_tokens(tokens);
|
||||||
}
|
}
|
||||||
for m in self.modules.iter() {
|
|
||||||
if let Err(e) = m.try_to_tokens(tokens) {
|
|
||||||
errors.push(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for d in self.dictionaries.iter() {
|
for d in self.dictionaries.iter() {
|
||||||
d.to_tokens(tokens);
|
d.to_tokens(tokens);
|
||||||
}
|
}
|
||||||
@ -1101,30 +1096,6 @@ impl ToTokens for ast::Const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryToTokens for ast::Module {
|
|
||||||
fn try_to_tokens(&self, tokens: &mut TokenStream) -> Result<(), Diagnostic> {
|
|
||||||
for import in &self.imports {
|
|
||||||
DescribeImport(&import.kind).to_tokens(tokens);
|
|
||||||
}
|
|
||||||
let vis = &self.vis;
|
|
||||||
let name = &self.name;
|
|
||||||
let mut errors = Vec::new();
|
|
||||||
let mut body = TokenStream::new();
|
|
||||||
for import in &self.imports {
|
|
||||||
if let Err(e) = import.kind.try_to_tokens(&mut body) {
|
|
||||||
errors.push(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Diagnostic::from_vec(errors)?;
|
|
||||||
(quote!{
|
|
||||||
#vis mod #name {
|
|
||||||
#body
|
|
||||||
}
|
|
||||||
}).to_tokens(tokens);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToTokens for ast::Dictionary {
|
impl ToTokens for ast::Dictionary {
|
||||||
fn to_tokens(&self, tokens: &mut TokenStream) {
|
fn to_tokens(&self, tokens: &mut TokenStream) {
|
||||||
let name = &self.name;
|
let name = &self.name;
|
||||||
|
@ -34,12 +34,13 @@ use std::env;
|
|||||||
use std::fs;
|
use std::fs;
|
||||||
use std::iter::FromIterator;
|
use std::iter::FromIterator;
|
||||||
|
|
||||||
use backend::ast;
|
|
||||||
use backend::TryToTokens;
|
use backend::TryToTokens;
|
||||||
use backend::defined::{ImportedTypeDefinitions, RemoveUndefinedImports};
|
use backend::ast;
|
||||||
use backend::defined::ImportedTypeReferences;
|
use backend::defined::ImportedTypeReferences;
|
||||||
|
use backend::defined::{ImportedTypeDefinitions, RemoveUndefinedImports};
|
||||||
use backend::util::{ident_ty, rust_ident, raw_ident, wrap_import_function};
|
use backend::util::{ident_ty, rust_ident, raw_ident, wrap_import_function};
|
||||||
use proc_macro2::{Ident, Span};
|
use proc_macro2::{Ident, Span};
|
||||||
|
use quote::ToTokens;
|
||||||
use weedle::attribute::{ExtendedAttributeList};
|
use weedle::attribute::{ExtendedAttributeList};
|
||||||
use weedle::dictionary::DictionaryMember;
|
use weedle::dictionary::DictionaryMember;
|
||||||
use weedle::interface::InterfaceMember;
|
use weedle::interface::InterfaceMember;
|
||||||
@ -51,9 +52,14 @@ use idl_type::ToIdlType;
|
|||||||
|
|
||||||
pub use error::{Error, ErrorKind, Result};
|
pub use error::{Error, ErrorKind, Result};
|
||||||
|
|
||||||
|
struct Program {
|
||||||
|
main: backend::ast::Program,
|
||||||
|
submodules: Vec<(String, backend::ast::Program)>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse a string of WebIDL source text into a wasm-bindgen AST.
|
/// Parse a string of WebIDL source text into a wasm-bindgen AST.
|
||||||
fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
||||||
-> Result<backend::ast::Program>
|
-> Result<Program>
|
||||||
{
|
{
|
||||||
let definitions = match weedle::parse(webidl_source) {
|
let definitions = match weedle::parse(webidl_source) {
|
||||||
Ok(def) => def,
|
Ok(def) => def,
|
||||||
@ -80,6 +86,7 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
|||||||
first_pass_record.builtin_idents = builtin_idents();
|
first_pass_record.builtin_idents = builtin_idents();
|
||||||
definitions.first_pass(&mut first_pass_record, ())?;
|
definitions.first_pass(&mut first_pass_record, ())?;
|
||||||
let mut program = Default::default();
|
let mut program = Default::default();
|
||||||
|
let mut submodules = Vec::new();
|
||||||
|
|
||||||
let allowed_types = allowed_types.map(|list| {
|
let allowed_types = allowed_types.map(|list| {
|
||||||
list.iter().cloned().collect::<HashSet<_>>()
|
list.iter().cloned().collect::<HashSet<_>>()
|
||||||
@ -102,7 +109,8 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (name, n) in first_pass_record.namespaces.iter() {
|
for (name, n) in first_pass_record.namespaces.iter() {
|
||||||
first_pass_record.append_ns(&mut program, name, n);
|
let prog = first_pass_record.append_ns(name, n);
|
||||||
|
submodules.push((snake_case_ident(name).to_string(), prog));
|
||||||
}
|
}
|
||||||
for (name, d) in first_pass_record.interfaces.iter() {
|
for (name, d) in first_pass_record.interfaces.iter() {
|
||||||
if filter(name) {
|
if filter(name) {
|
||||||
@ -127,7 +135,10 @@ fn parse(webidl_source: &str, allowed_types: Option<&[&str]>)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(program)
|
Ok(Program {
|
||||||
|
main: program,
|
||||||
|
submodules: submodules,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile the given WebIDL source text into Rust source text containing
|
/// Compile the given WebIDL source text into Rust source text containing
|
||||||
@ -152,7 +163,7 @@ fn builtin_idents() -> BTreeSet<Ident> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Run codegen on the AST to generate rust code.
|
/// Run codegen on the AST to generate rust code.
|
||||||
fn compile_ast(mut ast: backend::ast::Program) -> String {
|
fn compile_ast(mut ast: Program) -> String {
|
||||||
// Iteratively prune all entries from the AST which reference undefined
|
// Iteratively prune all entries from the AST which reference undefined
|
||||||
// fields. Each pass may remove definitions of types and so we need to
|
// fields. Each pass may remove definitions of types and so we need to
|
||||||
// reexecute this pass to see if we need to keep removing types until we
|
// reexecute this pass to see if we need to keep removing types until we
|
||||||
@ -162,13 +173,24 @@ fn compile_ast(mut ast: backend::ast::Program) -> String {
|
|||||||
let track = env::var_os("__WASM_BINDGEN_DUMP_FEATURES");
|
let track = env::var_os("__WASM_BINDGEN_DUMP_FEATURES");
|
||||||
loop {
|
loop {
|
||||||
let mut defined = builtin.clone();
|
let mut defined = builtin.clone();
|
||||||
ast.imported_type_definitions(&mut |id| {
|
{
|
||||||
defined.insert(id.clone());
|
let mut cb = |id: &Ident| {
|
||||||
if track.is_some() {
|
defined.insert(id.clone());
|
||||||
all_definitions.insert(id.clone());
|
if track.is_some() {
|
||||||
|
all_definitions.insert(id.clone());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ast.main.imported_type_definitions(&mut cb);
|
||||||
|
for (_, m) in ast.submodules.iter() {
|
||||||
|
m.imported_type_references(&mut cb);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
if !ast.remove_undefined_imports(&|id| defined.contains(id)) {
|
let changed =
|
||||||
|
ast.main.remove_undefined_imports(&|id| defined.contains(id)) ||
|
||||||
|
ast.submodules.iter_mut().any(|(_, m)| {
|
||||||
|
m.remove_undefined_imports(&|id| defined.contains(id))
|
||||||
|
});
|
||||||
|
if !changed {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,9 +203,21 @@ fn compile_ast(mut ast: backend::ast::Program) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut tokens = proc_macro2::TokenStream::new();
|
let mut tokens = proc_macro2::TokenStream::new();
|
||||||
if let Err(e) = ast.try_to_tokens(&mut tokens) {
|
if let Err(e) = ast.main.try_to_tokens(&mut tokens) {
|
||||||
e.panic();
|
e.panic();
|
||||||
}
|
}
|
||||||
|
for (name, m) in ast.submodules.iter() {
|
||||||
|
let mut m_tokens = proc_macro2::TokenStream::new();
|
||||||
|
if let Err(e) = m.try_to_tokens(&mut m_tokens) {
|
||||||
|
e.panic();
|
||||||
|
}
|
||||||
|
|
||||||
|
let name = Ident::new(name, Span::call_site());
|
||||||
|
|
||||||
|
(quote! {
|
||||||
|
pub mod #name { #m_tokens }
|
||||||
|
}).to_tokens(&mut tokens);
|
||||||
|
}
|
||||||
tokens.to_string()
|
tokens.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,26 +374,21 @@ impl<'src> FirstPassRecord<'src> {
|
|||||||
|
|
||||||
fn append_ns(
|
fn append_ns(
|
||||||
&'src self,
|
&'src self,
|
||||||
program: &mut backend::ast::Program,
|
|
||||||
name: &'src str,
|
name: &'src str,
|
||||||
ns: &'src first_pass::NamespaceData<'src>,
|
ns: &'src first_pass::NamespaceData<'src>,
|
||||||
) {
|
) -> backend::ast::Program {
|
||||||
let mut module = backend::ast::Module {
|
let mut ret = Default::default();
|
||||||
vis: public(),
|
|
||||||
name: rust_ident(snake_case_ident(name).as_str()),
|
|
||||||
imports: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
for (id, data) in ns.operations.iter() {
|
for (id, data) in ns.operations.iter() {
|
||||||
self.append_ns_member(&mut module, name, id, data);
|
self.append_ns_member(&mut ret, name, id, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
program.modules.push(module);
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn append_ns_member(
|
fn append_ns_member(
|
||||||
&self,
|
&self,
|
||||||
module: &mut backend::ast::Module,
|
module: &mut backend::ast::Program,
|
||||||
self_name: &'src str,
|
self_name: &'src str,
|
||||||
id: &OperationId<'src>,
|
id: &OperationId<'src>,
|
||||||
data: &OperationData<'src>,
|
data: &OperationData<'src>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user