Skip to content

Commit

Permalink
feat: support semver aware WIT
Browse files Browse the repository at this point in the history
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
  • Loading branch information
vados-cosmonic committed Jul 31, 2024
1 parent 3946278 commit 3d4c926
Show file tree
Hide file tree
Showing 17 changed files with 642 additions and 109 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ strip = true
anyhow = "1.0.86"
base64 = "0.22.1"
heck = "0.5.0"
log = "0.4.22"
semver = "1.0.23"
js-component-bindgen = { path = "./crates/js-component-bindgen" }
structopt = "0.3.26"
wasm-encoder = "0.212.0"
Expand All @@ -55,4 +57,4 @@ wit-parser = "0.212.0"
xshell = "0.2.6"

[dev-dependencies]
anyhow = { workspace = true }
anyhow = { workspace = true }
14 changes: 14 additions & 0 deletions crates/js-component-bindgen-component/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ impl Guest for JsComponentBindgenComponent {
opts: TypeGenerationOptions,
) -> Result<Vec<(String, Vec<u8>)>, String> {
let mut resolve = Resolve::default();

// Add features if specified
match opts.features {
Some(EnabledFeatureSet::List(ref features)) => {
for f in features.into_iter() {
resolve.features.insert(f.to_string());
}
}
Some(EnabledFeatureSet::All) => {
resolve.all_features = true;
}
_ => {}
}

let ids = match opts.wit {
Wit::Source(source) => resolve
.push_str(format!("{name}.wit"), &source)
Expand Down
10 changes: 10 additions & 0 deletions crates/js-component-bindgen-component/wit/js-component-bindgen.wit
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ world js-component-bindgen {
path(string),
}

/// Enumerate enabled features
variant enabled-feature-set {
/// Enable only the given list of features
%list(list<string>),
/// Enable all features
all,
}

record type-generation-options {
/// wit to generate typing from
wit: wit,
Expand All @@ -81,6 +89,8 @@ world js-component-bindgen {
tla-compat: option<bool>,
instantiation: option<instantiation-mode>,
map: option<maps>,
/// Features that should be enabled as part of feature gating
features: option<enabled-feature-set>,
}

enum export-type {
Expand Down
6 changes: 4 additions & 2 deletions crates/js-component-bindgen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ transpile-bindgen = []

[dependencies]
anyhow = { workspace = true }
base64 = { workspace = true }
heck = { workspace = true }
log = { workspace = true }
semver = { workspace = true }
wasm-encoder = { workspace = true }
wasmparser = { workspace = true }
wasmtime-environ = { workspace = true, features = ['component-model'] }
wit-bindgen-core = { workspace = true }
wit-component = { workspace = true }
wit-parser = { workspace = true }
base64 = { workspace = true }
wasm-encoder = { workspace = true }
36 changes: 34 additions & 2 deletions crates/js-component-bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ pub use transpile_bindgen::{BindingsMode, InstantiationMode, TranspileOpts};
use anyhow::Result;
use transpile_bindgen::transpile_bindgen;

use anyhow::{bail, Context};
use anyhow::{bail, ensure, Context};
use wasmtime_environ::component::{ComponentTypesBuilder, Export, StaticModuleIndex};
use wasmtime_environ::wasmparser::Validator;
use wasmtime_environ::{PrimaryMap, ScopeVec, Tunables};
use wit_component::DecodedWasm;

use ts_bindgen::ts_bindgen;
use wit_parser::{Resolve, Type, TypeDefKind, TypeId, WorldId};
use wit_parser::{Package, Resolve, Stability, Type, TypeDefKind, TypeId, WorldId};

/// Calls [`write!`] with the passed arguments and unwraps the result.
///
Expand Down Expand Up @@ -172,3 +172,35 @@ pub fn dealias(resolve: &Resolve, mut id: TypeId) -> TypeId {
}
}
}

/// Check if an item (usually some form of [`WorldItem`]) should be allowed through the feature gate
/// of a given package.
fn feature_gate_allowed(
resolve: &Resolve,
package: &Package,
stability: &Stability,
) -> Result<bool> {
let Some(package_version) = package.name.version.as_ref() else {
// If the package version is missing (we're likely dealing with an unresolved package)
// and we can't really check much.
return Ok(true);
};

Ok(match stability {
Stability::Unknown => true,
Stability::Stable { since, .. } => {
ensure!(
package_version >= since,
"feature gates cannot refer to unreleased (future) package versions"
);

// Stabilization (@since annotation) overrides features and deprecation
true
}
Stability::Unstable { feature } => {
// If a @unstable feature is present but the related feature was not enabled
// or all features was not selected, exclude
resolve.all_features || resolve.features.contains(feature)
}
})
}
Loading

0 comments on commit 3d4c926

Please sign in to comment.