aver-lang 0.19.0

VM and transpiler for Aver, a statically-typed language designed for AI-assisted development
Documentation
//! WIT emission for the component artifact.
//!
//! Per the component contract (`docs/wasip2.md` point 5), every
//! `.component.wasm` we emit ships a sibling `.wit` whose contents
//! are the human-readable view of the import / export surface.
//!
//! Phase 1.2a transitional: emits an empty world in the `aver:user`
//! package. The wasm-gc core's `_start` and any internal exports
//! become private to the component (not surfaced through the world).
//! Phase 1.2b switches the body to `include wasi:cli/command@0.2.4;`
//! once the wasm-gc backend exports a matching `wasi:cli/run`. The
//! WASI WIT bundle that backs the include is already vendored under
//! `wit/wasi-0.2.4/` and loaded by `wasi_bundle::push_wasi_packages`.
//!
//! WIT emission is by inline `format!` while the surface is small
//! and template-shaped. Add `wit-encoder` (structured builder) only
//! if per-effect imports beyond the standard WASI worlds need it.

use super::wrap::Wasip2World;

/// Emit the WIT source that pairs with the component bytes. The
/// emitted source is also parsed by `wrap.rs` to build the
/// `component-type:<world>` metadata custom section, so this is the
/// single source of truth for what the component declares.
///
/// Phase 1 keeps the world body empty: Aver's effects do not yet
/// flow into WIT imports here. The wrap pipeline still validates
/// end-to-end on the empty world (component is a valid WASI 0.2
/// artifact, just with no public surface). Phase 1.2 turns this
/// into a meaningful world declaration.
pub fn emit_world_wit(world: Wasip2World, needs_http: bool) -> String {
    let local_name = world.local_name();
    let (header_note, body) = match world {
        // `wasi:cli/command` is the canonical CLI shape from the
        // upstream `wasi-0.2.4` bundle: every cli/io/clocks/random/
        // filesystem/sockets import that the imports-only world
        // declares, PLUS the required `wasi:cli/run.run` export.
        // The wasm-gc emitter exports `wasi:cli/run@0.2.4#run`
        // (canonical-ABI mangled name) when `target == Wasip2`, so
        // the contract is satisfiable at this commit.
        //
        // `wasi:cli/command` does not transitively include
        // `wasi:http/*`. When the user program reaches an `Http.*`
        // effect, the wasm-gc backend emits canonical-ABI imports
        // of `wasi:http/outgoing-handler@0.2.4` (and types via the
        // implicit transitive package); the world has to declare
        // that import explicitly so `wit-component::ComponentEncoder`
        // matches it against the host. `needs_http` is derived in
        // `wrap.rs` by scanning the core module's imports — single
        // source of truth, no risk of drift between codegen and
        // world declaration.
        Wasip2World::CliCommand => {
            let header =
                "// Phase 1.2b1.3 — wasm-gc emits `wasi:cli/run@0.2.4#run` to satisfy this world.";
            let body = if needs_http {
                "  include wasi:cli/command@0.2.4;\n  \n  // Phase 2 / 0.19 — Http.* effects on `--target wasip2` lower\n  // directly to `wasi:http/outgoing-handler.handle` plus the\n  // future-incoming-response / incoming-response choreography.\n  // WASI 0.3 collapses this into native `future<T>` / `stream<u8>`\n  // types and three imports; a `Wasip3World` variant lands when\n  // the spec stabilises.\n  import wasi:http/outgoing-handler@0.2.4;".to_string()
            } else {
                "  include wasi:cli/command@0.2.4;".to_string()
            };
            (header, body)
        }
        // Phase 3 / 0.19 — HttpServer.listen. Component exports
        // `wasi:http/incoming-handler.handle`, host (e.g.
        // `wasmtime serve --http=:N`) calls into our handler per
        // request. `include wasi:http/proxy@0.2.4` brings the export
        // requirement plus every wasi:http/types / wasi:io/streams /
        // wasi:clocks import the request/response choreography
        // consumes — single declaration covers both directions.
        Wasip2World::HttpProxy => (
            "// Phase 3 / 0.19 — HttpServer.listen on `--target wasip2`.",
            "  include wasi:http/proxy@0.2.4;".to_string(),
        ),
    };
    format!(
        "// Generated by `aver compile --target wasip2`.\n\
         // Direct WIT lowering: this is the source of truth for the\n\
         // component's import / export surface. Component metadata is\n\
         // encoded from this same WIT and embedded into the core\n\
         // module. See docs/wasip2.md for the contract.\n\
         //\n\
         {header_note}\n\n\
         package aver:user;\n\n\
         world {local_name} {{\n\
         {body}\n\
         }}\n"
    )
}