From d6e37703502b9f028038de59ade197973abef2d0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 5 Mar 2019 14:53:14 -0800 Subject: [PATCH] Scope snippets within a crate Use the same crate identifier for manually included snippets as well as inline snippets to help with debugging. --- crates/backend/src/encode.rs | 7 ++++- crates/cli-support/src/js/mod.rs | 48 ++++++++++++++++++++++---------- crates/cli-support/src/lib.rs | 21 ++++++++++---- crates/shared/src/lib.rs | 1 + 4 files changed, 56 insertions(+), 21 deletions(-) diff --git a/crates/backend/src/encode.rs b/crates/backend/src/encode.rs index 2cec95f5..791adb48 100644 --- a/crates/backend/src/encode.rs +++ b/crates/backend/src/encode.rs @@ -78,7 +78,7 @@ impl Interner { // Generate a unique ID which is somewhat readable as well, so mix in // the crate name, hash to make it unique, and then the original path. - let new_identifier = format!("{}-{}{}", self.crate_name, ShortHash(0), id); + let new_identifier = format!("{}{}", self.unique_crate_identifier(), id); let file = LocalFile { path, definition: span, @@ -88,6 +88,10 @@ impl Interner { drop(files); self.resolve_import_module(id, span) } + + fn unique_crate_identifier(&self) -> String { + format!("{}-{}", self.crate_name, ShortHash(0)) + } } fn shared_program<'a>( @@ -139,6 +143,7 @@ fn shared_program<'a>( .iter() .map(|js| intern.intern_str(js)) .collect(), + unique_crate_identifier: intern.intern_str(&intern.unique_crate_identifier()), }) } diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 89a2f158..ec0c10d8 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -58,9 +58,11 @@ pub struct Context<'a> { /// known as to their actual JS contents. pub local_modules: HashMap<&'a str, &'a str>, - /// An integer offset of where to start assigning indexes to `inline_js` - /// snippets. This is incremented each time a `Program` is processed. - pub snippet_offset: usize, + /// A map of how many snippets we've seen from each unique crate identifier, + /// used to number snippets correctly when writing them to the filesystem + /// when there's multiple snippets within one crate that aren't all part of + /// the same `Program`. + pub snippet_offsets: HashMap<&'a str, usize>, pub anyref: wasm_bindgen_anyref_xform::Context, } @@ -118,7 +120,8 @@ enum Import<'a> { }, /// Same as `Module`, except we're importing from an `inline_js` attribute InlineJs { - idx: usize, + unique_crate_identifier: &'a str, + snippet_idx_in_crate: usize, name: &'a str, field: Option<&'a str>, }, @@ -2133,9 +2136,14 @@ impl<'a> Context<'a> { let path = match import { Import::Module { module, .. } => module.to_string(), Import::LocalModule { module, .. } => format!("./snippets/{}", module), - Import::InlineJs { idx, .. } => { - format!("./snippets/wbg-inline{}.js", idx) - } + Import::InlineJs { + unique_crate_identifier, + snippet_idx_in_crate, + .. + } => format!( + "./snippets/{}/inline{}.js", + unique_crate_identifier, snippet_idx_in_crate + ), _ => unreachable!(), }; if use_node_require { @@ -2918,11 +2926,19 @@ impl<'a, 'b> SubContext<'a, 'b> { name, field, }, - decode::ImportModule::Inline(idx) => Import::InlineJs { - idx: idx as usize + self.cx.snippet_offset, - name, - field, - }, + decode::ImportModule::Inline(idx) => { + let offset = *self + .cx + .snippet_offsets + .get(self.program.unique_crate_identifier) + .unwrap_or(&0); + Import::InlineJs { + unique_crate_identifier: self.program.unique_crate_identifier, + snippet_idx_in_crate: idx as usize + offset, + name, + field, + } + } decode::ImportModule::None => Import::Global { name, field }, }) } @@ -2936,7 +2952,7 @@ impl<'a, 'b> SubContext<'a, 'b> { #[derive(Hash, Eq, PartialEq)] pub enum ImportModule<'a> { Named(&'a str), - Inline(usize), + Inline(&'a str, usize), None, } @@ -2946,7 +2962,11 @@ impl<'a> Import<'a> { Import::Module { module, .. } | Import::LocalModule { module, .. } => { ImportModule::Named(module) } - Import::InlineJs { idx, .. } => ImportModule::Inline(*idx), + Import::InlineJs { + unique_crate_identifier, + snippet_idx_in_crate, + .. + } => ImportModule::Inline(unique_crate_identifier, *snippet_idx_in_crate), Import::Global { .. } | Import::VendorPrefixed { .. } => ImportModule::None, } } diff --git a/crates/cli-support/src/lib.rs b/crates/cli-support/src/lib.rs index 9856880a..6bd78e7c 100755 --- a/crates/cli-support/src/lib.rs +++ b/crates/cli-support/src/lib.rs @@ -304,7 +304,7 @@ impl Bindgen { local_modules: Default::default(), start: None, anyref: Default::default(), - snippet_offset: 0, + snippet_offsets: Default::default(), }; cx.anyref.enabled = self.anyref; cx.anyref.prepare(cx.module)?; @@ -316,14 +316,21 @@ impl Bindgen { } .generate()?; - for (i, js) in program.inline_js.iter().enumerate() { - let name = format!("wbg-inline{}.js", i + cx.snippet_offset); - let path = out_dir.join("snippets").join(name); + let offset = cx + .snippet_offsets + .entry(program.unique_crate_identifier) + .or_insert(0); + for js in program.inline_js.iter() { + let name = format!("inline{}.js", *offset); + *offset += 1; + let path = out_dir + .join("snippets") + .join(program.unique_crate_identifier) + .join(name); fs::create_dir_all(path.parent().unwrap())?; fs::write(&path, js) .with_context(|_| format!("failed to write `{}`", path.display()))?; } - cx.snippet_offset += program.inline_js.len(); } // Write out all local JS snippets to the final destination now that @@ -630,7 +637,9 @@ fn demangle(module: &mut Module) { impl OutputMode { fn nodejs_experimental_modules(&self) -> bool { match self { - OutputMode::Node { experimental_modules } => *experimental_modules, + OutputMode::Node { + experimental_modules, + } => *experimental_modules, _ => false, } } diff --git a/crates/shared/src/lib.rs b/crates/shared/src/lib.rs index 40084daf..c32f4c14 100644 --- a/crates/shared/src/lib.rs +++ b/crates/shared/src/lib.rs @@ -16,6 +16,7 @@ macro_rules! shared_api { typescript_custom_sections: Vec<&'a str>, local_modules: Vec>, inline_js: Vec<&'a str>, + unique_crate_identifier: &'a str, } struct Import<'a> {