From a636906ed590336a49bce8e372cc5ea1ecef11ce Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 25 May 2023 14:01:53 -0500 Subject: [PATCH] Update Component and WIT import/export syntax (#1027) * Implement basic support for new import/export names * Remove the old URL fields. * Change the binary format, updating the major version, to have a discriminator byte. * Implement validation of ID names including parsing and uniqueness. * Update existing tests for new changes. * Add text-parsing support * Add text-printing support * Add encoding support * Support new WIT syntax in `wit-parser` This commit implements the changes outlined in WebAssembly/component-model#193 for the `wit-parser` crate. Namely this updates all parsing, lexing, and resolution of a WIT package. The largest change is that the concept of a "document" has been removed. Additionally most tests needed an update to have a `package foo` header. Intra-package resolution is also a bit trickier now and required a restructuring of the AST resolution pass, but nothing too too radical for what it's doing. * Update the wit-component crate This is a very large commit which gets the wit-component crate's tests working again. The main changes this accounts for are: * URLs are removed. * Documents are removed and instead interfaces/worlds are directly in a package. * The encoding structure of a package was slightly updated to reflect this. * A few minor bugs were fixed now that the ID format is more expressive than the prior format. * Update the wasm-compose crate This is mostly dealing with the fallout of removing URLs. * Update the wasm-tools CLI This removed a few now-obsolete options to `wasm-tools component wit` (yay!) as they're contextually no longer needed given the new structure of WIT. * Update the wit-smith crates * Require namespaces in WIT IDs * Add Ord/PartialOrd for PackageName * Review comments * Merge import/export names These may get split again in the future, but for now they're the same. * rustfmt * Improve world selection Add support for syntax to select any world within the `Resolve`, avoiding the need for the `WorldId` to be defined within the package specified. * Support full semver Add support for full semver versions on interface strings --- Cargo.toml | 1 + crates/wasm-compose/src/composer.rs | 6 +- crates/wasm-compose/src/encoding.rs | 129 +-- crates/wasm-compose/src/graph.rs | 79 +- crates/wasm-compose/tests/compose.rs | 2 +- .../tests/compositions/url-mismatch/b.wat | 3 - .../tests/compositions/url-mismatch/error.txt | 1 - .../tests/compositions/url-mismatch/root.wat | 4 - crates/wasm-encoder/src/component.rs | 2 +- crates/wasm-encoder/src/component/exports.rs | 16 +- crates/wasm-encoder/src/component/imports.rs | 58 +- .../wasm-encoder/src/component/instances.rs | 9 +- crates/wasm-encoder/src/component/types.rs | 18 +- crates/wasm-encoder/src/lib.rs | 2 +- crates/wasm-smith/src/component/encode.rs | 15 +- crates/wasmparser/Cargo.toml | 2 +- crates/wasmparser/src/parser.rs | 10 +- .../src/readers/component/exports.rs | 9 +- .../src/readers/component/imports.rs | 35 +- .../src/readers/component/instances.rs | 1 - .../wasmparser/src/readers/component/types.rs | 17 +- crates/wasmparser/src/validator.rs | 7 +- crates/wasmparser/src/validator/component.rs | 300 +++--- crates/wasmparser/src/validator/names.rs | 302 ++++-- crates/wasmparser/src/validator/types.rs | 64 +- crates/wasmprinter/src/lib.rs | 40 +- crates/wast/src/component/binary.rs | 32 +- crates/wast/src/component/expand.rs | 19 +- crates/wast/src/component/export.rs | 40 +- crates/wast/src/component/import.rs | 69 +- crates/wast/src/component/types.rs | 12 +- crates/wast/src/lib.rs | 1 + crates/wit-component/Cargo.toml | 1 - crates/wit-component/src/builder.rs | 7 +- crates/wit-component/src/decoding.rs | 738 ++++++++------- crates/wit-component/src/dummy.rs | 4 +- crates/wit-component/src/encoding.rs | 74 +- crates/wit-component/src/encoding/types.rs | 6 +- crates/wit-component/src/encoding/wit.rs | 111 +-- crates/wit-component/src/encoding/world.rs | 53 +- crates/wit-component/src/metadata.rs | 47 +- crates/wit-component/src/printing.rs | 117 +-- crates/wit-component/src/validation.rs | 81 +- crates/wit-component/tests/components.rs | 39 +- .../adapt-empty-interface/adapt-old.wit | 2 +- .../adapt-empty-interface/component.wit | 2 - .../adapt-empty-interface/component.wit.print | 4 + .../adapt-empty-interface/module.wit | 3 +- .../adapt-export-default/adapt-old.wit | 2 +- .../adapt-export-default/component.wit | 3 - .../adapt-export-default/component.wit.print | 5 + .../adapt-export-default/module.wit | 3 +- .../adapt-export-namespaced/adapt-old.wat | 2 +- .../adapt-export-namespaced/adapt-old.wit | 4 +- .../adapt-export-namespaced/component.wat | 6 +- .../adapt-export-namespaced/component.wit | 7 - .../component.wit.print | 5 + .../adapt-export-namespaced/module.wit | 4 +- .../adapt-export-reallocs/adapt-old.wit | 2 +- .../adapt-export-reallocs/component.wit | 8 - .../adapt-export-reallocs/component.wit.print | 8 + .../adapt-export-reallocs/module.wit | 4 +- .../adapt-export-save-args/adapt-old.wit | 2 +- .../{component.wit => component.wit.print} | 4 +- .../adapt-export-save-args/module.wit | 3 +- .../adapt-old.wat | 4 +- .../adapt-old.wit | 4 +- .../component.wat | 10 +- .../component.wit | 7 - .../component.wit.print | 5 + .../adapt-export-with-post-return/module.wit | 4 +- .../adapt-unused.wat | 2 +- .../adapt-unused.wit | 4 +- .../component.wat | 10 +- .../component.wit | 10 - .../component.wit.print | 8 + .../module.wit | 4 +- .../adapt-old.wit | 2 +- .../component.wit | 7 - .../component.wit.print | 7 + .../module.wit | 3 +- .../adapt-old.wit | 2 +- .../component.wit | 7 - .../component.wit.print | 7 + .../module.wit | 4 +- .../adapt-old.wit | 2 +- .../component.wit | 7 - .../component.wit.print | 7 + .../module.wit | 4 +- .../adapt-old.wit | 2 +- .../component.wit | 7 - .../component.wit.print | 7 + .../module.wit | 3 +- .../adapt-inject-stack/adapt-old.wit | 2 +- .../adapt-inject-stack/component.wit | 7 - .../adapt-inject-stack/component.wit.print | 7 + .../components/adapt-inject-stack/module.wit | 3 +- .../adapt-list-return/adapt-old.wit | 2 +- .../adapt-list-return/component.wit | 7 - .../adapt-list-return/component.wit.print | 7 + .../components/adapt-list-return/module.wit | 4 +- .../adapt-memory-simple/adapt-old.wit | 2 +- .../adapt-memory-simple/component.wit | 7 - .../adapt-memory-simple/component.wit.print | 7 + .../components/adapt-memory-simple/module.wit | 3 +- .../adapt-missing-memory/module.wit | 1 - .../components/adapt-multiple/adapt-foo.wit | 2 +- .../components/adapt-multiple/component.wit | 12 - .../adapt-multiple/component.wit.print | 10 + .../components/adapt-multiple/module.wit | 3 +- .../adapt-wasi-snapshot-preview1.wat | 2 +- .../adapt-wasi-snapshot-preview1.wit | 4 +- .../components/adapt-preview1/component.wat | 6 +- .../components/adapt-preview1/component.wit | 12 - .../adapt-preview1/component.wit.print | 8 + .../components/adapt-preview1/module.wit | 4 +- .../components/adapt-unused/adapt-old.wit | 2 +- .../components/adapt-unused/component.wit | 2 - .../adapt-unused/component.wit.print | 4 + .../tests/components/adapt-unused/module.wit | 3 +- .../{component.wit => component.wit.print} | 4 +- .../tests/components/bare-funcs/module.wit | 3 +- .../components/empty-module-import/module.wit | 1 - .../tests/components/empty/component.wit | 2 - .../components/empty/component.wit.print | 4 + .../tests/components/empty/module.wit | 3 +- .../ensure-default-type-exports/component.wat | 6 +- .../ensure-default-type-exports/component.wit | 14 - .../component.wit.print | 6 + .../ensure-default-type-exports/module.wat | 2 +- .../ensure-default-type-exports/module.wit | 6 +- .../adapt-old.wat | 0 .../adapt-old.wit | 2 +- .../error.txt | 0 .../module.wat | 0 .../error-adapt-missing-memory/module.wit | 2 + .../error.txt | 0 .../module.wat | 0 .../module.wit | 4 +- .../error.txt | 0 .../module.wat | 0 .../error-empty-module-import/module.wit | 2 + .../error.txt | 0 .../module.wat | 0 .../module.wit | 4 +- .../error.txt | 0 .../module.wat | 0 .../module.wit | 4 +- .../error.txt | 0 .../module.wat | 0 .../error-invalid-module-import/module.wit | 2 + .../error.txt | 0 .../module.wat | 0 .../error-missing-default-export/module.wit | 4 + .../error.txt | 0 .../module.wat | 0 .../module.wit | 4 +- .../error.txt | 0 .../module.wat | 0 .../error-missing-import-func/module.wit | 9 + .../components/error-missing-import/error.txt | 1 + .../module.wat | 0 .../error-missing-import/module.wit | 2 + .../component.wat | 2 +- .../component.wit | 18 - .../component.wit.print | 8 + .../export-interface-using-import/module.wit | 6 +- .../export-name-shuffling/component.wat | 2 +- .../export-name-shuffling/component.wit | 15 - .../export-name-shuffling/component.wit.print | 9 + .../export-name-shuffling/module.wit | 9 +- .../export-type-name-conflict/component.wat | 2 +- .../export-type-name-conflict/component.wit | 15 - .../component.wit.print | 9 + .../export-type-name-conflict/module.wit | 6 +- .../export-with-type-alias/component.wat | 6 +- .../export-with-type-alias/component.wit | 11 - .../component.wit.print | 5 + .../export-with-type-alias/module.wat | 2 +- .../export-with-type-alias/module.wit | 6 +- .../tests/components/exports/component.wit | 31 - .../components/exports/component.wit.print | 29 + .../tests/components/exports/module.wit | 4 +- .../components/import-conflict/component.wat | 26 +- .../components/import-conflict/component.wit | 17 - .../import-conflict/component.wit.print | 7 + .../components/import-conflict/module.wat | 8 +- .../components/import-conflict/module.wit | 10 +- .../import-empty-interface/component.wit | 2 - .../component.wit.print | 4 + .../import-empty-interface/module.wit | 4 +- .../component.wat | 59 ++ .../component.wit.print | 7 + .../deps/dep/foo.wit | 5 + .../import-export-same-iface-name/module.wat | 5 + .../import-export-same-iface-name/module.wit | 11 + .../components/import-export/component.wit | 15 - .../import-export/component.wit.print | 13 + .../tests/components/import-export/module.wit | 4 +- .../adapt-old.wat | 10 +- .../adapt-old.wit | 6 +- .../component.wat | 40 +- .../component.wit | 35 - .../component.wit.print | 14 + .../deps/shared-dependency/doc.wit | 4 +- .../deps/shared-dependency/types.wit | 2 +- .../module.wat | 8 +- .../module.wit | 8 +- .../tests/components/imports/component.wit | 33 - .../components/imports/component.wit.print | 29 + .../tests/components/imports/module.wit | 4 +- .../invalid-module-import/module.wit | 1 - .../components/lift-options/component.wat | 82 +- .../components/lift-options/component.wit | 53 -- .../lift-options/component.wit.print | 5 + .../tests/components/lift-options/module.wat | 40 +- .../tests/components/lift-options/module.wit | 6 +- .../components/lower-options/component.wat | 80 +- .../components/lower-options/component.wit | 53 -- .../lower-options/component.wit.print | 5 + .../tests/components/lower-options/module.wat | 34 +- .../tests/components/lower-options/module.wit | 6 +- .../components/many-same-names/component.wat | 55 ++ .../many-same-names/component.wit.print | 10 + .../components/many-same-names/module.wat | 3 + .../components/many-same-names/module.wit | 19 + .../missing-default-export/module.wit | 3 - .../components/missing-import-func/error.txt | 4 - .../components/missing-import-func/module.wit | 7 - .../components/missing-import/module.wit | 1 - .../no-realloc-required/component.wit | 7 - .../no-realloc-required/component.wit.print | 7 + .../components/no-realloc-required/module.wit | 4 +- .../components/post-return/component.wit | 3 - .../post-return/component.wit.print | 5 + .../tests/components/post-return/module.wit | 4 +- .../rename-import-interface/component.wat | 6 +- .../rename-import-interface/component.wit | 7 - .../component.wit.print | 5 + .../rename-import-interface/module.wat | 2 +- .../rename-import-interface/module.wit | 6 +- .../components/rename-interface/component.wat | 2 +- .../components/rename-interface/component.wit | 15 - .../rename-interface/component.wit.print | 9 + .../components/rename-interface/module.wit | 8 +- .../{component.wit => component.wit.print} | 4 +- .../tests/components/simple/module.wit | 4 +- .../components/tricky-order/component.wat | 4 +- .../components/tricky-order/component.wit | 20 - .../tricky-order/component.wit.print | 10 + .../tests/components/tricky-order/module.wit | 16 +- .../components/unused-import/component.wat | 6 +- .../components/unused-import/component.wit | 7 - .../unused-import/component.wit.print | 5 + .../tests/components/unused-import/module.wat | 2 +- .../tests/components/unused-import/module.wit | 8 +- .../worlds-with-type-renamings/component.wat | 12 +- .../worlds-with-type-renamings/component.wit | 19 - .../component.wit.print | 7 + .../worlds-with-type-renamings/module.wat | 4 +- .../worlds-with-type-renamings/module.wit | 10 +- .../{component.wit => component.wit.print} | 4 +- .../components/worlds-with-types/module.wit | 4 +- crates/wit-component/tests/interfaces.rs | 45 +- .../tests/interfaces/console.wat | 4 +- .../tests/interfaces/console.wit | 2 + .../tests/interfaces/console.wit.print | 2 + .../tests/interfaces/diamond-disambiguate.wat | 26 +- .../diamond-disambiguate/foo.wit.print | 22 + .../interfaces/diamond-disambiguate/join.wit | 8 +- .../diamond-disambiguate/join.wit.print | 10 - .../diamond-disambiguate/shared1.wit | 2 +- .../diamond-disambiguate/shared1.wit.print | 5 - .../diamond-disambiguate/shared2.wit | 2 +- .../diamond-disambiguate/shared2.wit.print | 5 - .../tests/interfaces/diamond.wat | 34 +- .../tests/interfaces/diamond.wit | 12 +- .../tests/interfaces/diamond.wit.print | 30 +- .../wit-component/tests/interfaces/empty.wat | 20 +- .../wit-component/tests/interfaces/empty.wit | 8 +- .../tests/interfaces/empty.wit.print | 10 +- .../export-other-packages-interface.wat | 6 +- .../deps/the-dep/the-doc.wit | 4 +- .../deps/the-dep/the-doc.wit.print | 5 - .../export-other-packages-interface/foo.wit | 4 +- .../foo.wit.print | 4 +- .../tests/interfaces/exports.wat | 8 +- .../tests/interfaces/exports.wit | 4 +- .../tests/interfaces/exports.wit.print | 4 +- .../wit-component/tests/interfaces/flags.wat | 8 +- .../wit-component/tests/interfaces/flags.wit | 4 +- .../tests/interfaces/flags.wit.print | 4 +- .../wit-component/tests/interfaces/floats.wat | 8 +- .../wit-component/tests/interfaces/floats.wit | 4 +- .../tests/interfaces/floats.wit.print | 4 +- .../tests/interfaces/foreign-use-chain.wat | 8 +- .../foreign-use-chain/deps/bar/bar.wit | 6 +- .../foreign-use-chain/deps/bar/bar.wit.print | 9 - .../interfaces/foreign-use-chain/foo.wit | 6 +- .../foreign-use-chain/foo.wit.print | 6 +- .../tests/interfaces/import-and-export.wat | 12 +- .../tests/interfaces/import-and-export.wit | 6 +- .../interfaces/import-and-export.wit.print | 6 +- .../tests/interfaces/integers.wat | 8 +- .../tests/interfaces/integers.wit | 4 +- .../tests/interfaces/integers.wit.print | 4 +- .../wit-component/tests/interfaces/lists.wat | 8 +- .../wit-component/tests/interfaces/lists.wit | 4 +- .../tests/interfaces/lists.wit.print | 4 +- .../tests/interfaces/multi-doc.wat | 36 +- .../tests/interfaces/multi-doc/a.wit | 10 +- .../tests/interfaces/multi-doc/a.wit.print | 8 - .../tests/interfaces/multi-doc/b.wit | 4 +- .../tests/interfaces/multi-doc/b.wit.print | 10 - .../tests/interfaces/multi-doc/foo.wit.print | 20 + .../tests/interfaces/multiple-use.wat | 8 +- .../tests/interfaces/multiple-use.wit | 8 +- .../tests/interfaces/multiple-use.wit.print | 8 +- .../tests/interfaces/pkg-use-chain.wat | 30 +- .../interfaces/pkg-use-chain/chain.wit.print | 20 + .../tests/interfaces/pkg-use-chain/def.wit | 6 +- .../interfaces/pkg-use-chain/def.wit.print | 14 - .../interfaces/pkg-use-chain/the-use.wit | 4 +- .../pkg-use-chain/the-use.wit.print | 4 - .../tests/interfaces/pkg-use-chain2.wat | 30 +- .../tests/interfaces/pkg-use-chain2/bar.wit | 4 +- .../interfaces/pkg-use-chain2/bar.wit.print | 15 - .../tests/interfaces/pkg-use-chain2/foo.wit | 4 +- .../interfaces/pkg-use-chain2/foo.wit.print | 19 +- .../interfaces/preserve-dep-type-order.wat | 10 +- .../preserve-dep-type-order/deps/dep/foo.wit | 4 +- .../deps/dep/foo.wit.print | 10 - .../preserve-dep-type-order/foo.wit | 6 +- .../preserve-dep-type-order/foo.wit.print | 6 +- .../interfaces/preserve-foreign-reexport.wat | 6 +- .../deps/my-dep/my-doc.wit | 4 +- .../deps/my-dep/my-doc.wit.print | 8 - .../preserve-foreign-reexport/foo.wit | 4 +- .../preserve-foreign-reexport/foo.wit.print | 4 +- .../tests/interfaces/print-keyword.wat | 4 +- .../tests/interfaces/print-keyword.wit | 2 + .../tests/interfaces/print-keyword.wit.print | 2 + .../tests/interfaces/records.wat | 10 +- .../tests/interfaces/records.wit | 6 +- .../tests/interfaces/records.wit.print | 6 +- .../interfaces/reference-out-of-order.wat | 8 +- .../interfaces/reference-out-of-order.wit | 4 +- .../reference-out-of-order.wit.print | 4 +- .../tests/interfaces/simple-deps.wat | 6 +- .../simple-deps/deps/some-dep/types.wit | 4 +- .../simple-deps/deps/some-dep/types.wit.print | 5 - .../tests/interfaces/simple-deps/foo.wit | 3 +- .../interfaces/simple-deps/foo.wit.print | 4 +- .../tests/interfaces/simple-multi.wat | 13 +- .../interfaces/simple-multi/bar.wit.print | 3 - .../tests/interfaces/simple-multi/foo.wit | 2 + .../interfaces/simple-multi/foo.wit.print | 5 + .../tests/interfaces/simple-use.wat | 6 +- .../tests/interfaces/simple-use.wit | 4 +- .../tests/interfaces/simple-use.wit.print | 4 +- .../tests/interfaces/simple-world.wat | 8 +- .../tests/interfaces/simple-world.wit | 4 +- .../tests/interfaces/simple-world.wit.print | 4 +- .../tests/interfaces/single-named-result.wat | 4 +- .../tests/interfaces/single-named-result.wit | 2 + .../interfaces/single-named-result.wit.print | 2 + .../tests/interfaces/type-alias.wat | 10 +- .../tests/interfaces/type-alias.wit | 6 +- .../tests/interfaces/type-alias.wit.print | 6 +- .../tests/interfaces/type-alias2.wat | 8 +- .../tests/interfaces/type-alias2.wit | 4 +- .../tests/interfaces/type-alias2.wit.print | 4 +- .../interfaces/upstream-deps-same-name.wat | 8 +- .../deps/a/the-name.wit | 3 +- .../deps/a/the-name.wit.print | 5 - .../deps/b/the-name.wit | 3 +- .../deps/b/the-name.wit.print | 5 - .../upstream-deps-same-name/foo.wit | 6 +- .../upstream-deps-same-name/foo.wit.print | 6 +- .../tests/interfaces/use-chain.wat | 8 +- .../tests/interfaces/use-chain.wit | 6 +- .../tests/interfaces/use-chain.wit.print | 6 +- .../tests/interfaces/use-for-type.wat | 8 +- .../tests/interfaces/use-for-type.wit | 6 +- .../tests/interfaces/use-for-type.wit.print | 4 +- .../tests/interfaces/variants.wat | 8 +- .../tests/interfaces/variants.wit | 4 +- .../tests/interfaces/variants.wit.print | 4 +- .../tests/interfaces/wasi-http.wat | 181 +--- .../interfaces/wasi-http/deps/io/streams.wit | 6 +- .../wasi-http/deps/io/streams.wit.print | 41 - .../wasi-http/deps/logging/handler.wit | 4 +- .../wasi-http/deps/logging/handler.wit.print | 12 - .../interfaces/wasi-http/deps/poll/poll.wit | 4 +- .../wasi-http/deps/poll/poll.wit.print | 8 - .../wasi-http/deps/random/random.wit | 4 +- .../wasi-http/deps/random/random.wit.print | 8 - .../{types.wit.print => http.wit.print} | 25 +- .../interfaces/wasi-http/incoming-handler.wit | 4 +- .../wasi-http/incoming-handler.wit.print | 5 - .../interfaces/wasi-http/outgoing-handler.wit | 4 +- .../wasi-http/outgoing-handler.wit.print | 5 - .../tests/interfaces/wasi-http/proxy.wit | 10 +- .../interfaces/wasi-http/proxy.wit.print | 9 - .../tests/interfaces/wasi-http/types.wit | 10 +- .../interfaces/world-inline-interface.wat | 4 +- .../interfaces/world-inline-interface.wit | 2 + .../world-inline-interface.wit.print | 2 + .../tests/interfaces/world-pkg-conflict.wat | 20 +- .../interfaces/world-pkg-conflict/bar.wit | 2 +- .../world-pkg-conflict/bar.wit.print | 5 - .../interfaces/world-pkg-conflict/foo.wit | 6 +- .../world-pkg-conflict/foo.wit.print | 11 +- .../tests/interfaces/world-top-level.wat | 32 +- .../tests/interfaces/world-top-level.wit | 2 + .../interfaces/world-top-level.wit.print | 14 +- .../tests/interfaces/worlds-with-types.wat | 30 +- .../tests/interfaces/worlds-with-types.wit | 4 +- .../interfaces/worlds-with-types.wit.print | 14 +- crates/wit-component/tests/merge.rs | 70 +- .../tests/merge/bad-interface1/error.txt | 7 +- .../tests/merge/bad-interface1/from/a.wit | 4 +- .../merge/bad-interface1/from/deps/foo/a.wit | 5 +- .../tests/merge/bad-interface1/into/a.wit | 4 +- .../merge/bad-interface1/into/deps/foo/a.wit | 4 +- .../tests/merge/bad-interface2/error.txt | 7 +- .../tests/merge/bad-interface2/from/a.wit | 4 +- .../merge/bad-interface2/from/deps/foo/a.wit | 4 +- .../tests/merge/bad-interface2/into/a.wit | 4 +- .../merge/bad-interface2/into/deps/foo/a.wit | 4 +- .../tests/merge/bad-world1/error.txt | 7 +- .../tests/merge/bad-world1/from/a.wit | 3 +- .../merge/bad-world1/from/deps/foo/a.wit | 8 +- .../tests/merge/bad-world1/into/a.wit | 3 +- .../merge/bad-world1/into/deps/foo/a.wit | 6 +- .../tests/merge/bad-world2/error.txt | 7 +- .../tests/merge/bad-world2/from/a.wit | 4 +- .../merge/bad-world2/from/deps/foo/a.wit | 4 +- .../tests/merge/bad-world2/into/a.wit | 4 +- .../merge/bad-world2/into/deps/foo/a.wit | 6 +- .../tests/merge/bad-world3/error.txt | 7 +- .../tests/merge/bad-world3/from/a.wit | 4 +- .../merge/bad-world3/from/deps/foo/a.wit | 4 +- .../tests/merge/bad-world3/into/a.wit | 4 +- .../merge/bad-world3/into/deps/foo/a.wit | 6 +- .../tests/merge/bad-world4/error.txt | 7 +- .../tests/merge/bad-world4/from/a.wit | 4 +- .../merge/bad-world4/from/deps/foo/a.wit | 8 +- .../tests/merge/bad-world4/into/a.wit | 4 +- .../merge/bad-world4/into/deps/foo/a.wit | 6 +- .../tests/merge/bad-world5/error.txt | 8 +- .../tests/merge/bad-world5/from/a.wit | 4 +- .../merge/bad-world5/from/deps/foo/a.wit | 4 +- .../tests/merge/bad-world5/into/a.wit | 4 +- .../merge/bad-world5/into/deps/foo/a.wit | 6 +- .../tests/merge/success/from/a.wit | 4 +- .../merge/success/from/deps/foo/shared.wit | 10 +- .../success/from/deps/only-from-dep/a.wit | 4 +- .../tests/merge/success/into/b.wit | 4 +- .../merge/success/into/deps/foo/shared.wit | 8 +- .../success/merge/{foo/shared.wit => foo.wit} | 30 +- .../merge/success/merge/foo/only-from.wit | 7 - .../merge/success/merge/foo/only-into.wit | 7 - .../tests/merge/success/merge/from.wit | 7 + .../tests/merge/success/merge/from/a.wit | 5 - .../tests/merge/success/merge/into.wit | 7 + .../tests/merge/success/merge/into/b.wit | 5 - .../merge/success/merge/only-from-dep.wit | 7 + .../merge/success/merge/only-from-dep/a.wit | 5 - crates/wit-parser/Cargo.toml | 1 + crates/wit-parser/src/ast.rs | 394 +++++--- crates/wit-parser/src/ast/lex.rs | 49 +- crates/wit-parser/src/ast/resolve.rs | 794 ++++++++-------- crates/wit-parser/src/lib.rs | 149 +-- crates/wit-parser/src/live.rs | 14 +- crates/wit-parser/src/resolve.rs | 889 +++++++----------- crates/wit-parser/tests/all.rs | 2 +- crates/wit-parser/tests/ui/comments.wit | 2 + .../tests/ui/diamond1/deps/dep1/types.wit | 2 + .../tests/ui/diamond1/deps/dep2/types.wit | 2 + crates/wit-parser/tests/ui/diamond1/join.wit | 6 + .../tests/ui/disambiguate-diamond/shared1.wit | 2 +- .../tests/ui/disambiguate-diamond/shared2.wit | 2 +- .../tests/ui/disambiguate-diamond/world.wit | 10 +- crates/wit-parser/tests/ui/embedded.wit.md | 2 + crates/wit-parser/tests/ui/empty.wit | 1 + .../deps/another-pkg/other-doc.wit | 2 + .../tests/ui/foreign-deps/deps/corp/saas.wit | 4 +- .../deps/different-pkg/the-doc.wit | 3 +- .../foreign-deps/deps/foreign-pkg/the-doc.wit | 4 +- .../foreign-deps/deps/some-pkg/some-doc.wit | 4 +- .../ui/foreign-deps/deps/wasi/clocks.wit | 4 +- .../ui/foreign-deps/deps/wasi/filesystem.wit | 4 +- .../wit-parser/tests/ui/foreign-deps/root.wit | 41 +- crates/wit-parser/tests/ui/functions.wit | 2 + crates/wit-parser/tests/ui/many-names/a.wit | 2 + crates/wit-parser/tests/ui/many-names/b.wit | 5 + crates/wit-parser/tests/ui/multi-file/bar.wit | 10 +- .../tests/ui/multi-file/cycle-a.wit | 7 + .../tests/ui/multi-file/cycle-b.wit | 3 + crates/wit-parser/tests/ui/multi-file/foo.wit | 28 +- .../wit-parser/tests/ui/package-syntax1.wit | 1 + .../wit-parser/tests/ui/package-syntax3.wit | 1 + .../wit-parser/tests/ui/package-syntax4.wit | 1 + .../ui/parse-fail/alias-no-type.wit.result | 6 +- .../ui/parse-fail/bad-diamond.wit.result | 8 - .../tests/ui/parse-fail/bad-diamond/a.wit | 9 - .../tests/ui/parse-fail/bad-diamond/b.wit | 9 - .../tests/ui/parse-fail/bad-diamond/join.wit | 4 - .../tests/ui/parse-fail/bad-function.wit | 2 + .../ui/parse-fail/bad-function.wit.result | 4 +- .../tests/ui/parse-fail/bad-function2.wit | 2 + .../ui/parse-fail/bad-function2.wit.result | 4 +- .../tests/ui/parse-fail/bad-pkg1.wit.result | 13 +- .../tests/ui/parse-fail/bad-pkg1/root.wit | 4 +- .../tests/ui/parse-fail/bad-pkg2.wit.result | 8 +- .../ui/parse-fail/bad-pkg2/deps/bar/empty.wit | 1 + .../tests/ui/parse-fail/bad-pkg2/root.wit | 4 +- .../tests/ui/parse-fail/bad-pkg3.wit.result | 8 +- .../ui/parse-fail/bad-pkg3/deps/bar/baz.wit | 2 + .../tests/ui/parse-fail/bad-pkg3/root.wit | 4 +- .../tests/ui/parse-fail/bad-pkg4.wit.result | 8 +- .../ui/parse-fail/bad-pkg4/deps/bar/baz.wit | 3 +- .../tests/ui/parse-fail/bad-pkg4/root.wit | 3 +- .../tests/ui/parse-fail/bad-pkg5.wit.result | 8 +- .../ui/parse-fail/bad-pkg5/deps/bar/baz.wit | 3 +- .../tests/ui/parse-fail/bad-pkg5/root.wit | 3 +- .../tests/ui/parse-fail/bad-pkg6.wit.result | 8 +- .../ui/parse-fail/bad-pkg6/deps/bar/baz.wit | 4 + .../tests/ui/parse-fail/bad-pkg6/root.wit | 3 +- .../tests/ui/parse-fail/bad-world-type1.wit | 1 + .../ui/parse-fail/bad-world-type1.wit.result | 4 +- .../ui/parse-fail/bad-world-type2.wit.result | 5 - .../parse-fail/conflicting-package.wit.result | 8 + .../ui/parse-fail/conflicting-package/a.wit | 1 + .../ui/parse-fail/conflicting-package/b.wit | 1 + .../wit-parser/tests/ui/parse-fail/cycle.wit | 1 + .../tests/ui/parse-fail/cycle.wit.result | 4 +- .../wit-parser/tests/ui/parse-fail/cycle2.wit | 1 + .../tests/ui/parse-fail/cycle2.wit.result | 4 +- .../wit-parser/tests/ui/parse-fail/cycle3.wit | 1 + .../tests/ui/parse-fail/cycle3.wit.result | 4 +- .../wit-parser/tests/ui/parse-fail/cycle4.wit | 1 + .../tests/ui/parse-fail/cycle4.wit.result | 4 +- .../wit-parser/tests/ui/parse-fail/cycle5.wit | 1 + .../tests/ui/parse-fail/cycle5.wit.result | 4 +- .../ui/parse-fail/default-interface1.wit | 3 - .../parse-fail/default-interface1.wit.result | 5 - .../tests/ui/parse-fail/default-world1.wit | 3 - .../ui/parse-fail/default-world1.wit.result | 5 - .../ui/parse-fail/duplicate-functions.wit | 2 + .../parse-fail/duplicate-functions.wit.result | 4 +- .../ui/parse-fail/duplicate-interface.wit | 2 + .../parse-fail/duplicate-interface.wit.result | 6 +- .../duplicate-interface2.wit.result | 8 + .../parse-fail/duplicate-interface2/foo.wit | 3 + .../parse-fail/duplicate-interface2/foo2.wit | 3 + .../tests/ui/parse-fail/duplicate-type.wit | 1 + .../ui/parse-fail/duplicate-type.wit.result | 4 +- .../tests/ui/parse-fail/empty-enum.wit | 1 + .../tests/ui/parse-fail/empty-enum.wit.result | 4 +- .../tests/ui/parse-fail/empty-union.wit | 1 + .../ui/parse-fail/empty-union.wit.result | 4 +- .../tests/ui/parse-fail/empty-variant1.wit | 1 + .../ui/parse-fail/empty-variant1.wit.result | 4 +- .../tests/ui/parse-fail/export-twice.wit | 8 + .../ui/parse-fail/export-twice.wit.result | 5 + .../ui/parse-fail/import-export-overlap1.wit | 1 + .../import-export-overlap1.wit.result | 4 +- .../ui/parse-fail/import-export-overlap2.wit | 1 + .../import-export-overlap2.wit.result | 4 +- .../ui/parse-fail/import-export-overlap3.wit | 11 - .../import-export-overlap3.wit.result | 6 - .../tests/ui/parse-fail/import-twice.wit | 8 + .../ui/parse-fail/import-twice.wit.result | 5 + .../tests/ui/parse-fail/invalid-md.wit.result | 2 +- .../ui/parse-fail/invalid-type-reference.wit | 2 + .../invalid-type-reference.wit.result | 4 +- .../ui/parse-fail/invalid-type-reference2.wit | 2 + .../invalid-type-reference2.wit.result | 4 +- .../tests/ui/parse-fail/invalid@filename.wit | 0 .../ui/parse-fail/invalid@filename.wit.result | 4 - .../deps/bar/.gitkeep => missing-package.wit} | 0 .../ui/parse-fail/missing-package.wit.result | 1 + .../no-access-to-sibling-use.wit.result | 8 + .../no-access-to-sibling-use/bar.wit | 1 + .../no-access-to-sibling-use/foo.wit | 5 + .../tests/ui/parse-fail/pkg-cycle.wit.result | 6 +- .../ui/parse-fail/pkg-cycle/deps/a1/root.wit | 3 +- .../tests/ui/parse-fail/pkg-cycle/root.wit | 3 +- .../tests/ui/parse-fail/pkg-cycle2.wit.result | 6 +- .../ui/parse-fail/pkg-cycle2/deps/a1/root.wit | 3 +- .../ui/parse-fail/pkg-cycle2/deps/a2/root.wit | 3 +- .../tests/ui/parse-fail/pkg-cycle2/root.wit | 3 +- .../tests/ui/parse-fail/undefined-typed.wit | 1 + .../ui/parse-fail/undefined-typed.wit.result | 4 +- .../tests/ui/parse-fail/unknown-interface.wit | 4 +- .../parse-fail/unknown-interface.wit.result | 8 +- .../ui/parse-fail/unresolved-interface1.wit | 4 +- .../unresolved-interface1.wit.result | 6 +- .../ui/parse-fail/unresolved-interface2.wit | 4 +- .../unresolved-interface2.wit.result | 8 +- .../ui/parse-fail/unresolved-interface3.wit | 6 +- .../unresolved-interface3.wit.result | 8 +- .../ui/parse-fail/unresolved-interface4.wit | 4 +- .../unresolved-interface4.wit.result | 8 +- .../ui/parse-fail/unresolved-interface5.wit | 5 - .../unresolved-interface5.wit.result | 5 - .../tests/ui/parse-fail/unresolved-use1.wit | 4 +- .../ui/parse-fail/unresolved-use1.wit.result | 8 +- .../ui/parse-fail/unresolved-use10.wit.result | 8 +- .../ui/parse-fail/unresolved-use10/bar.wit | 4 +- .../ui/parse-fail/unresolved-use11.wit.result | 8 - .../ui/parse-fail/unresolved-use11/bar.wit | 3 - .../ui/parse-fail/unresolved-use11/foo.wit | 2 - .../tests/ui/parse-fail/unresolved-use2.wit | 4 +- .../ui/parse-fail/unresolved-use2.wit.result | 6 +- .../tests/ui/parse-fail/unresolved-use3.wit | 4 +- .../ui/parse-fail/unresolved-use3.wit.result | 6 +- .../tests/ui/parse-fail/unresolved-use4.wit | 5 - .../ui/parse-fail/unresolved-use4.wit.result | 5 - .../tests/ui/parse-fail/unresolved-use5.wit | 6 - .../ui/parse-fail/unresolved-use5.wit.result | 5 - .../tests/ui/parse-fail/unresolved-use6.wit | 5 - .../ui/parse-fail/unresolved-use6.wit.result | 5 - .../tests/ui/parse-fail/unresolved-use7.wit | 4 +- .../ui/parse-fail/unresolved-use7.wit.result | 6 +- .../tests/ui/parse-fail/unresolved-use8.wit | 4 +- .../ui/parse-fail/unresolved-use8.wit.result | 6 +- .../tests/ui/parse-fail/unresolved-use9.wit | 4 +- .../ui/parse-fail/unresolved-use9.wit.result | 8 +- .../tests/ui/parse-fail/use-conflict.wit | 4 +- .../ui/parse-fail/use-conflict.wit.result | 6 +- .../tests/ui/parse-fail/use-conflict2.wit | 4 +- .../ui/parse-fail/use-conflict2.wit.result | 4 +- .../tests/ui/parse-fail/use-conflict3.wit | 4 +- .../ui/parse-fail/use-conflict3.wit.result | 4 +- .../tests/ui/parse-fail/use-cycle1.wit | 4 +- .../tests/ui/parse-fail/use-cycle1.wit.result | 6 +- .../tests/ui/parse-fail/use-cycle2.wit | 5 - .../tests/ui/parse-fail/use-cycle2.wit.result | 5 - .../tests/ui/parse-fail/use-cycle3.wit | 6 - .../tests/ui/parse-fail/use-cycle3.wit.result | 5 - .../tests/ui/parse-fail/use-cycle4.wit | 5 +- .../tests/ui/parse-fail/use-cycle4.wit.result | 6 +- .../ui/parse-fail/use-from-package-world.wit | 8 - .../use-from-package-world.wit.result | 5 - .../use-from-package-world2.wit.result | 8 - .../use-from-package-world2/bar.wit | 3 - .../use-from-package-world2/foo.wit | 2 - .../tests/ui/parse-fail/use-shadow1.wit | 7 + .../ui/parse-fail/use-shadow1.wit.result | 5 + .../world-implicit-import1.wit.result | 6 - .../world-implicit-import2.wit.result | 5 - .../world-implicit-import3.wit.result | 5 - .../ui/parse-fail/world-interface-clash.wit | 1 + .../world-interface-clash.wit.result | 6 +- .../tests/ui/parse-fail/world-same-fields.wit | 9 - .../parse-fail/world-same-fields.wit.result | 5 - .../ui/parse-fail/world-same-fields2.wit | 2 + .../parse-fail/world-same-fields2.wit.result | 4 +- .../ui/parse-fail/world-same-fields3.wit | 2 + .../parse-fail/world-same-fields3.wit.result | 4 +- .../parse-fail/world-same-fields4.wit.result | 8 - .../tests/ui/parse-fail/world-same-import.wit | 6 - .../parse-fail/world-same-import.wit.result | 5 - .../ui/parse-fail/world-top-level-func.wit | 1 + .../world-top-level-func.wit.result | 4 +- .../ui/parse-fail/world-top-level-func2.wit | 1 + .../world-top-level-func2.wit.result | 4 +- .../parse-fail/worlds-same-fields5.wit.result | 9 - crates/wit-parser/tests/ui/shared-types.wit | 2 + crates/wit-parser/tests/ui/type-then-eof.wit | 2 + crates/wit-parser/tests/ui/types.wit | 2 + crates/wit-parser/tests/ui/use-chain.wit | 11 + crates/wit-parser/tests/ui/use.wit | 17 +- .../tests/ui/versions/deps/a1/foo.wit | 5 + .../tests/ui/versions/deps/a2/foo.wit | 5 + crates/wit-parser/tests/ui/versions/foo.wit | 7 + crates/wit-parser/tests/ui/wasi.wit | 2 + crates/wit-parser/tests/ui/world-diamond.wit | 10 +- ...d-type2.wit => world-iface-no-collide.wit} | 4 +- .../world-implicit-import1.wit | 4 +- .../world-implicit-import2.wit | 4 +- .../world-implicit-import3.wit | 4 +- .../{parse-fail => }/world-same-fields4.wit | 4 +- .../tests/ui/world-top-level-funcs.wit | 2 + .../{parse-fail => }/worlds-same-fields5.wit | 9 +- .../wit-parser/tests/ui/worlds-with-types.wit | 6 +- crates/wit-parser/tests/ui/worlds.wit | 29 +- crates/wit-smith/Cargo.toml | 2 + crates/wit-smith/src/config.rs | 16 +- crates/wit-smith/src/generate.rs | 446 ++++++--- crates/wit-smith/src/lib.rs | 20 +- fuzz/fuzz_targets/roundtrip-wit.rs | 24 +- src/bin/wasm-tools/component.rs | 121 +-- tests/cli/dump/alias.wat.stdout | 12 +- tests/cli/dump/alias2.wat.stdout | 263 +++--- tests/cli/dump/bundled.wat.stdout | 26 +- .../dump/component-expand-bundle.wat.stdout | 4 +- .../dump/component-expand-bundle2.wat.stdout | 54 +- .../component-inline-export-import.wat.stdout | 12 +- .../cli/dump/component-inline-type.wat.stdout | 12 +- .../dump/component-instance-type.wat.stdout | 16 +- tests/cli/dump/component-linking.wat.stdout | 38 +- .../cli/dump/component-outer-alias.wat.stdout | 16 +- tests/cli/dump/import-modules.wat.stdout | 6 +- tests/cli/dump/instance-expand.wat.stdout | 8 +- tests/cli/dump/instance-type.wat.stdout | 8 +- tests/cli/dump/instance-type2.wat.stdout | 8 +- tests/cli/dump/instantiate.wat.stdout | 8 +- tests/cli/dump/instantiate2.wat.stdout | 10 +- tests/cli/dump/module-types.wat.stdout | 6 +- tests/cli/dump/nested-component.wat.stdout | 44 +- tests/cli/print-core-wasm-wit.wit | 6 +- tests/cli/print-core-wasm-wit.wit.stdout | 4 +- tests/local/component-model/export.wast | 22 +- tests/local/component-model/import.wast | 82 +- .../local/component-model/instance-type.wast | 2 +- tests/local/component-model/instantiate.wast | 2 +- tests/local/component-model/naming.wast | 27 +- tests/local/component-model/resources.wast | 21 +- tests/local/component-model/start.wast | 14 +- tests/local/component-model/types.wast | 6 +- tests/local/component-model/very-nested.wast | 2 +- .../local/component-model/export.wast/7.print | 2 +- .../local/component-model/export.wast/8.print | 4 +- .../component-model/import.wast/14.print | 20 +- .../component-model/import.wast/15.print | 4 - .../local/component-model/naming.wast/0.print | 9 + .../component-model/resources.wast/105.print | 7 + 731 files changed, 5589 insertions(+), 5311 deletions(-) delete mode 100644 crates/wasm-compose/tests/compositions/url-mismatch/b.wat delete mode 100644 crates/wasm-compose/tests/compositions/url-mismatch/error.txt delete mode 100644 crates/wasm-compose/tests/compositions/url-mismatch/root.wat delete mode 100644 crates/wit-component/tests/components/adapt-empty-interface/component.wit create mode 100644 crates/wit-component/tests/components/adapt-empty-interface/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-export-default/component.wit create mode 100644 crates/wit-component/tests/components/adapt-export-default/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-export-namespaced/component.wit create mode 100644 crates/wit-component/tests/components/adapt-export-namespaced/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-export-reallocs/component.wit create mode 100644 crates/wit-component/tests/components/adapt-export-reallocs/component.wit.print rename crates/wit-component/tests/components/adapt-export-save-args/{component.wit => component.wit.print} (51%) delete mode 100644 crates/wit-component/tests/components/adapt-export-with-post-return/component.wit create mode 100644 crates/wit-component/tests/components/adapt-export-with-post-return/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wit create mode 100644 crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wit create mode 100644 crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wit create mode 100644 crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wit create mode 100644 crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wit create mode 100644 crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-inject-stack/component.wit create mode 100644 crates/wit-component/tests/components/adapt-inject-stack/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-list-return/component.wit create mode 100644 crates/wit-component/tests/components/adapt-list-return/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-memory-simple/component.wit create mode 100644 crates/wit-component/tests/components/adapt-memory-simple/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-missing-memory/module.wit delete mode 100644 crates/wit-component/tests/components/adapt-multiple/component.wit create mode 100644 crates/wit-component/tests/components/adapt-multiple/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-preview1/component.wit create mode 100644 crates/wit-component/tests/components/adapt-preview1/component.wit.print delete mode 100644 crates/wit-component/tests/components/adapt-unused/component.wit create mode 100644 crates/wit-component/tests/components/adapt-unused/component.wit.print rename crates/wit-component/tests/components/bare-funcs/{component.wit => component.wit.print} (77%) delete mode 100644 crates/wit-component/tests/components/empty-module-import/module.wit delete mode 100644 crates/wit-component/tests/components/empty/component.wit create mode 100644 crates/wit-component/tests/components/empty/component.wit.print delete mode 100644 crates/wit-component/tests/components/ensure-default-type-exports/component.wit create mode 100644 crates/wit-component/tests/components/ensure-default-type-exports/component.wit.print rename crates/wit-component/tests/components/{adapt-missing-memory => error-adapt-missing-memory}/adapt-old.wat (100%) rename crates/wit-component/tests/components/{adapt-missing-memory => error-adapt-missing-memory}/adapt-old.wit (64%) rename crates/wit-component/tests/components/{adapt-missing-memory => error-adapt-missing-memory}/error.txt (100%) rename crates/wit-component/tests/components/{adapt-missing-memory => error-adapt-missing-memory}/module.wat (100%) create mode 100644 crates/wit-component/tests/components/error-adapt-missing-memory/module.wit rename crates/wit-component/tests/components/{default-export-sig-mismatch => error-default-export-sig-mismatch}/error.txt (100%) rename crates/wit-component/tests/components/{default-export-sig-mismatch => error-default-export-sig-mismatch}/module.wat (100%) rename crates/wit-component/tests/components/{default-export-sig-mismatch => error-default-export-sig-mismatch}/module.wit (55%) rename crates/wit-component/tests/components/{empty-module-import => error-empty-module-import}/error.txt (100%) rename crates/wit-component/tests/components/{empty-module-import => error-empty-module-import}/module.wat (100%) create mode 100644 crates/wit-component/tests/components/error-empty-module-import/module.wit rename crates/wit-component/tests/components/{export-sig-mismatch => error-export-sig-mismatch}/error.txt (100%) rename crates/wit-component/tests/components/{export-sig-mismatch => error-export-sig-mismatch}/module.wat (100%) rename crates/wit-component/tests/components/{export-sig-mismatch => error-export-sig-mismatch}/module.wit (67%) rename crates/wit-component/tests/components/{import-sig-mismatch => error-import-sig-mismatch}/error.txt (100%) rename crates/wit-component/tests/components/{import-sig-mismatch => error-import-sig-mismatch}/module.wat (100%) rename crates/wit-component/tests/components/{import-sig-mismatch => error-import-sig-mismatch}/module.wit (64%) rename crates/wit-component/tests/components/{invalid-module-import => error-invalid-module-import}/error.txt (100%) rename crates/wit-component/tests/components/{invalid-module-import => error-invalid-module-import}/module.wat (100%) create mode 100644 crates/wit-component/tests/components/error-invalid-module-import/module.wit rename crates/wit-component/tests/components/{missing-default-export => error-missing-default-export}/error.txt (100%) rename crates/wit-component/tests/components/{missing-default-export => error-missing-default-export}/module.wat (100%) create mode 100644 crates/wit-component/tests/components/error-missing-default-export/module.wit rename crates/wit-component/tests/components/{missing-export => error-missing-export}/error.txt (100%) rename crates/wit-component/tests/components/{missing-export => error-missing-export}/module.wat (100%) rename crates/wit-component/tests/components/{missing-export => error-missing-export}/module.wit (58%) rename crates/wit-component/tests/components/{missing-import => error-missing-import-func}/error.txt (100%) rename crates/wit-component/tests/components/{missing-import-func => error-missing-import-func}/module.wat (100%) create mode 100644 crates/wit-component/tests/components/error-missing-import-func/module.wit create mode 100644 crates/wit-component/tests/components/error-missing-import/error.txt rename crates/wit-component/tests/components/{missing-import => error-missing-import}/module.wat (100%) create mode 100644 crates/wit-component/tests/components/error-missing-import/module.wit delete mode 100644 crates/wit-component/tests/components/export-interface-using-import/component.wit create mode 100644 crates/wit-component/tests/components/export-interface-using-import/component.wit.print delete mode 100644 crates/wit-component/tests/components/export-name-shuffling/component.wit create mode 100644 crates/wit-component/tests/components/export-name-shuffling/component.wit.print delete mode 100644 crates/wit-component/tests/components/export-type-name-conflict/component.wit create mode 100644 crates/wit-component/tests/components/export-type-name-conflict/component.wit.print delete mode 100644 crates/wit-component/tests/components/export-with-type-alias/component.wit create mode 100644 crates/wit-component/tests/components/export-with-type-alias/component.wit.print delete mode 100644 crates/wit-component/tests/components/exports/component.wit create mode 100644 crates/wit-component/tests/components/exports/component.wit.print delete mode 100644 crates/wit-component/tests/components/import-conflict/component.wit create mode 100644 crates/wit-component/tests/components/import-conflict/component.wit.print delete mode 100644 crates/wit-component/tests/components/import-empty-interface/component.wit create mode 100644 crates/wit-component/tests/components/import-empty-interface/component.wit.print create mode 100644 crates/wit-component/tests/components/import-export-same-iface-name/component.wat create mode 100644 crates/wit-component/tests/components/import-export-same-iface-name/component.wit.print create mode 100644 crates/wit-component/tests/components/import-export-same-iface-name/deps/dep/foo.wit create mode 100644 crates/wit-component/tests/components/import-export-same-iface-name/module.wat create mode 100644 crates/wit-component/tests/components/import-export-same-iface-name/module.wit delete mode 100644 crates/wit-component/tests/components/import-export/component.wit create mode 100644 crates/wit-component/tests/components/import-export/component.wit.print delete mode 100644 crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wit create mode 100644 crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wit.print delete mode 100644 crates/wit-component/tests/components/imports/component.wit create mode 100644 crates/wit-component/tests/components/imports/component.wit.print delete mode 100644 crates/wit-component/tests/components/invalid-module-import/module.wit delete mode 100644 crates/wit-component/tests/components/lift-options/component.wit create mode 100644 crates/wit-component/tests/components/lift-options/component.wit.print delete mode 100644 crates/wit-component/tests/components/lower-options/component.wit create mode 100644 crates/wit-component/tests/components/lower-options/component.wit.print create mode 100644 crates/wit-component/tests/components/many-same-names/component.wat create mode 100644 crates/wit-component/tests/components/many-same-names/component.wit.print create mode 100644 crates/wit-component/tests/components/many-same-names/module.wat create mode 100644 crates/wit-component/tests/components/many-same-names/module.wit delete mode 100644 crates/wit-component/tests/components/missing-default-export/module.wit delete mode 100644 crates/wit-component/tests/components/missing-import-func/error.txt delete mode 100644 crates/wit-component/tests/components/missing-import-func/module.wit delete mode 100644 crates/wit-component/tests/components/missing-import/module.wit delete mode 100644 crates/wit-component/tests/components/no-realloc-required/component.wit create mode 100644 crates/wit-component/tests/components/no-realloc-required/component.wit.print delete mode 100644 crates/wit-component/tests/components/post-return/component.wit create mode 100644 crates/wit-component/tests/components/post-return/component.wit.print delete mode 100644 crates/wit-component/tests/components/rename-import-interface/component.wit create mode 100644 crates/wit-component/tests/components/rename-import-interface/component.wit.print delete mode 100644 crates/wit-component/tests/components/rename-interface/component.wit create mode 100644 crates/wit-component/tests/components/rename-interface/component.wit.print rename crates/wit-component/tests/components/simple/{component.wit => component.wit.print} (70%) delete mode 100644 crates/wit-component/tests/components/tricky-order/component.wit create mode 100644 crates/wit-component/tests/components/tricky-order/component.wit.print delete mode 100644 crates/wit-component/tests/components/unused-import/component.wit create mode 100644 crates/wit-component/tests/components/unused-import/component.wit.print delete mode 100644 crates/wit-component/tests/components/worlds-with-type-renamings/component.wit create mode 100644 crates/wit-component/tests/components/worlds-with-type-renamings/component.wit.print rename crates/wit-component/tests/components/worlds-with-types/{component.wit => component.wit.print} (66%) create mode 100644 crates/wit-component/tests/interfaces/diamond-disambiguate/foo.wit.print delete mode 100644 crates/wit-component/tests/interfaces/diamond-disambiguate/join.wit.print delete mode 100644 crates/wit-component/tests/interfaces/diamond-disambiguate/shared1.wit.print delete mode 100644 crates/wit-component/tests/interfaces/diamond-disambiguate/shared2.wit.print delete mode 100644 crates/wit-component/tests/interfaces/export-other-packages-interface/deps/the-dep/the-doc.wit.print delete mode 100644 crates/wit-component/tests/interfaces/foreign-use-chain/deps/bar/bar.wit.print delete mode 100644 crates/wit-component/tests/interfaces/multi-doc/a.wit.print delete mode 100644 crates/wit-component/tests/interfaces/multi-doc/b.wit.print create mode 100644 crates/wit-component/tests/interfaces/multi-doc/foo.wit.print create mode 100644 crates/wit-component/tests/interfaces/pkg-use-chain/chain.wit.print delete mode 100644 crates/wit-component/tests/interfaces/pkg-use-chain/def.wit.print delete mode 100644 crates/wit-component/tests/interfaces/pkg-use-chain/the-use.wit.print delete mode 100644 crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit.print delete mode 100644 crates/wit-component/tests/interfaces/preserve-dep-type-order/deps/dep/foo.wit.print delete mode 100644 crates/wit-component/tests/interfaces/preserve-foreign-reexport/deps/my-dep/my-doc.wit.print delete mode 100644 crates/wit-component/tests/interfaces/simple-deps/deps/some-dep/types.wit.print delete mode 100644 crates/wit-component/tests/interfaces/simple-multi/bar.wit.print delete mode 100644 crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/a/the-name.wit.print delete mode 100644 crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/b/the-name.wit.print delete mode 100644 crates/wit-component/tests/interfaces/wasi-http/deps/io/streams.wit.print delete mode 100644 crates/wit-component/tests/interfaces/wasi-http/deps/logging/handler.wit.print delete mode 100644 crates/wit-component/tests/interfaces/wasi-http/deps/poll/poll.wit.print delete mode 100644 crates/wit-component/tests/interfaces/wasi-http/deps/random/random.wit.print rename crates/wit-component/tests/interfaces/wasi-http/{types.wit.print => http.wit.print} (83%) delete mode 100644 crates/wit-component/tests/interfaces/wasi-http/incoming-handler.wit.print delete mode 100644 crates/wit-component/tests/interfaces/wasi-http/outgoing-handler.wit.print delete mode 100644 crates/wit-component/tests/interfaces/wasi-http/proxy.wit.print delete mode 100644 crates/wit-component/tests/interfaces/world-pkg-conflict/bar.wit.print rename crates/wit-component/tests/merge/success/merge/{foo/shared.wit => foo.wit} (53%) delete mode 100644 crates/wit-component/tests/merge/success/merge/foo/only-from.wit delete mode 100644 crates/wit-component/tests/merge/success/merge/foo/only-into.wit create mode 100644 crates/wit-component/tests/merge/success/merge/from.wit delete mode 100644 crates/wit-component/tests/merge/success/merge/from/a.wit create mode 100644 crates/wit-component/tests/merge/success/merge/into.wit delete mode 100644 crates/wit-component/tests/merge/success/merge/into/b.wit create mode 100644 crates/wit-component/tests/merge/success/merge/only-from-dep.wit delete mode 100644 crates/wit-component/tests/merge/success/merge/only-from-dep/a.wit create mode 100644 crates/wit-parser/tests/ui/diamond1/deps/dep1/types.wit create mode 100644 crates/wit-parser/tests/ui/diamond1/deps/dep2/types.wit create mode 100644 crates/wit-parser/tests/ui/diamond1/join.wit create mode 100644 crates/wit-parser/tests/ui/many-names/a.wit create mode 100644 crates/wit-parser/tests/ui/many-names/b.wit create mode 100644 crates/wit-parser/tests/ui/multi-file/cycle-a.wit create mode 100644 crates/wit-parser/tests/ui/multi-file/cycle-b.wit create mode 100644 crates/wit-parser/tests/ui/package-syntax1.wit create mode 100644 crates/wit-parser/tests/ui/package-syntax3.wit create mode 100644 crates/wit-parser/tests/ui/package-syntax4.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/bad-diamond.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/bad-diamond/a.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/bad-diamond/b.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/bad-diamond/join.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/bad-pkg2/deps/bar/empty.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/bad-world-type2.wit.result create mode 100644 crates/wit-parser/tests/ui/parse-fail/conflicting-package.wit.result create mode 100644 crates/wit-parser/tests/ui/parse-fail/conflicting-package/a.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/conflicting-package/b.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/default-interface1.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/default-interface1.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/default-world1.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/default-world1.wit.result create mode 100644 crates/wit-parser/tests/ui/parse-fail/duplicate-interface2.wit.result create mode 100644 crates/wit-parser/tests/ui/parse-fail/duplicate-interface2/foo.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/duplicate-interface2/foo2.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/export-twice.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/export-twice.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/import-export-overlap3.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/import-export-overlap3.wit.result create mode 100644 crates/wit-parser/tests/ui/parse-fail/import-twice.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/import-twice.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/invalid@filename.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/invalid@filename.wit.result rename crates/wit-parser/tests/ui/parse-fail/{bad-pkg2/deps/bar/.gitkeep => missing-package.wit} (100%) create mode 100644 crates/wit-parser/tests/ui/parse-fail/missing-package.wit.result create mode 100644 crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use.wit.result create mode 100644 crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use/bar.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use/foo.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-interface5.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-interface5.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use11.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use11/bar.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use11/foo.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use4.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use4.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use5.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use5.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use6.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/unresolved-use6.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-cycle2.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-cycle2.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-cycle3.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-cycle3.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-from-package-world.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-from-package-world.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-from-package-world2.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-from-package-world2/bar.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/use-from-package-world2/foo.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/use-shadow1.wit create mode 100644 crates/wit-parser/tests/ui/parse-fail/use-shadow1.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/world-implicit-import1.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/world-implicit-import2.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/world-implicit-import3.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/world-same-fields.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/world-same-fields.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/world-same-fields4.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/world-same-import.wit delete mode 100644 crates/wit-parser/tests/ui/parse-fail/world-same-import.wit.result delete mode 100644 crates/wit-parser/tests/ui/parse-fail/worlds-same-fields5.wit.result create mode 100644 crates/wit-parser/tests/ui/use-chain.wit create mode 100644 crates/wit-parser/tests/ui/versions/deps/a1/foo.wit create mode 100644 crates/wit-parser/tests/ui/versions/deps/a2/foo.wit create mode 100644 crates/wit-parser/tests/ui/versions/foo.wit rename crates/wit-parser/tests/ui/{parse-fail/bad-world-type2.wit => world-iface-no-collide.wit} (69%) rename crates/wit-parser/tests/ui/{parse-fail => }/world-implicit-import1.wit (77%) rename crates/wit-parser/tests/ui/{parse-fail => }/world-implicit-import2.wit (70%) rename crates/wit-parser/tests/ui/{parse-fail => }/world-implicit-import3.wit (70%) rename crates/wit-parser/tests/ui/{parse-fail => }/world-same-fields4.wit (76%) rename crates/wit-parser/tests/ui/{parse-fail => }/worlds-same-fields5.wit (58%) delete mode 100644 tests/snapshots/local/component-model/import.wast/15.print create mode 100644 tests/snapshots/local/component-model/naming.wast/0.print create mode 100644 tests/snapshots/local/component-model/resources.wast/105.print diff --git a/Cargo.toml b/Cargo.toml index b129040b70..bf08d10919 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ serde = { version = "1.0.137", features = ["derive"] } wasmtime = { version = "3.0.0", default-features = false, features = ['cranelift'] } url = "2.0.0" pretty_assertions = "1.3.0" +semver = "1.0.0" wasm-encoder = { version = "0.28.0", path = "crates/wasm-encoder"} wasm-compose = { version = "0.2.16", path = "crates/wasm-compose"} diff --git a/crates/wasm-compose/src/composer.rs b/crates/wasm-compose/src/composer.rs index 9fcbfbe9d8..81fd32f221 100644 --- a/crates/wasm-compose/src/composer.rs +++ b/crates/wasm-compose/src/composer.rs @@ -210,7 +210,7 @@ impl<'a> CompositionGraphBuilder<'a> { let (_, instance_id) = self.instances.get_index(instance).unwrap(); let (_, component) = self.graph.get_component_of_instance(*instance_id).unwrap(); match component.export_by_name(export) { - Some((export_index, _, kind, index)) if kind == ComponentExternalKind::Instance => { + Some((export_index, kind, index)) if kind == ComponentExternalKind::Instance => { let export_ty = component.types.component_instance_at(index).unwrap(); if !ComponentEntityType::is_subtype_of( &ComponentEntityType::Instance(export_ty), @@ -236,7 +236,7 @@ impl<'a> CompositionGraphBuilder<'a> { /// Resolves an import instance reference. fn resolve_import_ref(&self, r: InstanceImportRef) -> (&Component, &str, TypeId) { let component = self.graph.get_component(r.component).unwrap(); - let (name, _, ty) = component.import(r.import).unwrap(); + let (name, ty) = component.import(r.import).unwrap(); match ty { ComponentTypeRef::Instance(index) => ( component, @@ -307,7 +307,7 @@ impl<'a> CompositionGraphBuilder<'a> { let count = queue.len(); // Push a dependency for every instance import - for (import, name, _, ty) in component.imports() { + for (import, name, ty) in component.imports() { match ty { ComponentTypeRef::Instance(_) => {} _ => bail!( diff --git a/crates/wasm-compose/src/encoding.rs b/crates/wasm-compose/src/encoding.rs index 07bbb311f6..85ef94b97e 100644 --- a/crates/wasm-compose/src/encoding.rs +++ b/crates/wasm-compose/src/encoding.rs @@ -132,20 +132,20 @@ impl<'a> TypeEncoder<'a> { pub fn component(&self, imports: I, exports: E) -> ComponentType where - I: IntoIterator, - E: IntoIterator, + I: IntoIterator, + E: IntoIterator, { let mut encoded = ComponentType::new(); let mut types = TypeMap::new(); - for (name, url, ty) in imports { + for (name, ty) in imports { let ty = self.component_entity_type(&mut encoded, &mut types, ty); - encoded.import(name, url, ty); + encoded.import(name, ty); } - for (name, url, ty) in exports { + for (name, ty) in exports { let export = self.export(ty, &mut encoded, &mut types); - encoded.export(name, url, export); + encoded.export(name, export); } encoded @@ -153,14 +153,14 @@ impl<'a> TypeEncoder<'a> { pub fn instance(&self, exports: E) -> InstanceType where - E: IntoIterator, + E: IntoIterator, { let mut encoded = InstanceType::new(); let mut types = TypeMap::new(); - for (name, url, ty) in exports { + for (name, ty) in exports { let export = self.export(ty, &mut encoded, &mut types); - encoded.export(name, url, export); + encoded.export(name, export); } encoded @@ -372,9 +372,7 @@ impl<'a> TypeEncoder<'a> { Entry::Occupied(e) => *e.get(), Entry::Vacant(e) => { let ty = ty.as_component_instance_type().unwrap(); - let instance = self.instance(ty.exports.iter().map(|(n, (u, t))| { - (n.as_str(), u.as_ref().map(|u| u.as_str()).unwrap_or(""), *t) - })); + let instance = self.instance(ty.exports.iter().map(|(n, t)| (n.as_str(), *t))); let index = encodable.type_count(); encodable.ty().instance(&instance); *e.insert(index) @@ -395,12 +393,8 @@ impl<'a> TypeEncoder<'a> { let ty = ty.as_component_type().unwrap(); let component = self.component( - ty.imports.iter().map(|(n, (u, t))| { - (n.as_str(), u.as_ref().map(|u| u.as_str()).unwrap_or(""), *t) - }), - ty.exports.iter().map(|(n, (u, t))| { - (n.as_str(), u.as_ref().map(|u| u.as_str()).unwrap_or(""), *t) - }), + ty.imports.iter().map(|(n, t)| (n.as_str(), *t)), + ty.exports.iter().map(|(n, t)| (n.as_str(), *t)), ); let index = encodable.type_count(); @@ -721,24 +715,13 @@ enum ArgumentImportKind<'a> { /// Instances are unioned together to form a single instance to /// import that will satisfy all instantiation arguments that /// reference the import. - Instance( - IndexMap< - &'a str, - ( - &'a str, - &'a crate::graph::Component<'a>, - ComponentEntityType, - ), - >, - ), + Instance(IndexMap<&'a str, (&'a crate::graph::Component<'a>, ComponentEntityType)>), } /// Represents an import for an instantiation argument. struct ArgumentImport<'a> { // The name of the import. name: &'a str, - /// The URL of the import. - url: &'a str, /// The kind of import. kind: ArgumentImportKind<'a>, /// The instances that will use the import for an argument. @@ -763,15 +746,8 @@ impl ArgumentImport<'_> { .iter(); let mut map = IndexMap::with_capacity(exports.len()); - for (name, (url, ty)) in exports { - map.insert( - name.as_str(), - ( - url.as_ref().map(|u| u.as_str()).unwrap_or(""), - *component, - *ty, - ), - ); + for (name, ty) in exports { + map.insert(name.as_str(), (*component, *ty)); } self.kind = ArgumentImportKind::Instance(map); @@ -787,16 +763,7 @@ impl ArgumentImport<'_> { ArgumentImportKind::Instance(exports), ArgumentImportKind::Item(new_component, ComponentEntityType::Instance(id)), ) => { - if arg.url != self.url { - bail!( - "cannot import instance with name `{name}` because import URL `{url}` conflicts with `{other}`", - name = self.name, - url = self.url, - other = arg.url, - ); - } - - for (name, (url, new_type)) in new_component + for (name, new_type) in new_component .types .type_from_id(id) .unwrap() @@ -807,7 +774,7 @@ impl ArgumentImport<'_> { { match exports.entry(name.as_str()) { indexmap::map::Entry::Occupied(mut e) => { - let (_, existing_component, existing_type) = e.get_mut(); + let (existing_component, existing_type) = e.get_mut(); match Self::compatible_type( existing_component, *existing_type, @@ -827,11 +794,7 @@ impl ArgumentImport<'_> { } } indexmap::map::Entry::Vacant(e) => { - e.insert(( - url.as_ref().map(|u| u.as_str()).unwrap_or(""), - new_component, - *new_type, - )); + e.insert((new_component, *new_type)); } } } @@ -857,16 +820,6 @@ impl ArgumentImport<'_> { new_type, ) { Some((c, ty)) => { - if arg.url != self.url { - bail!( - "cannot import {ty} with name `{name}` because import URL `{url}` conflicts with `{other}`", - ty = type_desc(new_type), - name = self.name, - url = self.url, - other = arg.url - ); - } - *existing_component = c; *existing_type = ty; } @@ -968,16 +921,15 @@ impl<'a> ImportMap<'a> { let instance_index = InstanceIndex(instance_index); // Import any unconnected instantiation arguments for the instance - for (import_index, name, _, _) in entry.component.imports() { + for (import_index, name, _) in entry.component.imports() { if instance.connected.contains(&import_index) { continue; } - let (_, url, ty) = entry.component.import_entity_type(import_index).unwrap(); + let (_, ty) = entry.component.import_entity_type(import_index).unwrap(); let arg = ArgumentImport { name, - url, kind: ArgumentImportKind::Item(&entry.component, ty), instances: smallvec::smallvec![(instance_index, import_index)], }; @@ -1095,7 +1047,7 @@ impl<'a> CompositionGraphEncoder<'a> { for (name, entry) in imports.0 { match entry { ImportMapEntry::Component(component) => { - self.encode_component_import(encoded, name.as_ref(), "", component); + self.encode_component_import(encoded, name.as_ref(), component); } ImportMapEntry::Argument(arg) => { let index = match arg.kind { @@ -1103,12 +1055,11 @@ impl<'a> CompositionGraphEncoder<'a> { encoded, &mut type_map, name.as_ref(), - arg.url, component, ty, ), ArgumentImportKind::Instance(exports) => { - self.encode_instance_import(encoded, name.as_ref(), arg.url, exports) + self.encode_instance_import(encoded, name.as_ref(), exports) } }; @@ -1125,11 +1076,10 @@ impl<'a> CompositionGraphEncoder<'a> { &mut self, encoded: &mut Component, name: &str, - url: &str, component: &'a crate::graph::Component, ) -> u32 { let type_index = self.define_component_type(encoded, component); - let index = self.import(encoded, name, url, ComponentTypeRef::Component(type_index)); + let index = self.import(encoded, name, ComponentTypeRef::Component(type_index)); assert!(self .encoded_components @@ -1144,7 +1094,6 @@ impl<'a> CompositionGraphEncoder<'a> { encoded: &mut Component, type_map: &mut TypeMap<'a>, name: &str, - url: &str, component: &'a crate::graph::Component, ty: ComponentEntityType, ) -> u32 { @@ -1169,22 +1118,21 @@ impl<'a> CompositionGraphEncoder<'a> { self.types += type_section.len(); } - self.import(encoded, name, url, ty) + self.import(encoded, name, ty) } fn encode_instance_import( &mut self, encoded: &mut Component, name: &str, - url: &str, - exports: IndexMap<&'a str, (&'a str, &'a crate::graph::Component, ComponentEntityType)>, + exports: IndexMap<&'a str, (&'a crate::graph::Component, ComponentEntityType)>, ) -> u32 { let mut instance_type = InstanceType::new(); let mut types = TypeMap::new(); - for (name, (url, component, ty)) in exports { + for (name, (component, ty)) in exports { let encoder = TypeEncoder::new(&component.types); let export = encoder.export(ty, &mut instance_type, &mut types); - instance_type.export(name, url, export); + instance_type.export(name, export); } let index = self.types; @@ -1193,7 +1141,7 @@ impl<'a> CompositionGraphEncoder<'a> { encoded.section(&type_section); self.types += 1; - self.import(encoded, name, url, ComponentTypeRef::Instance(index)) + self.import(encoded, name, ComponentTypeRef::Instance(index)) } fn encode_instantiations(&mut self, encoded: &mut Component) -> Result<()> { @@ -1227,7 +1175,7 @@ impl<'a> CompositionGraphEncoder<'a> { let mut alias_section = ComponentAliasSection::new(); let mut export_section = ComponentExportSection::new(); - for (export_index, export_name, export_url, kind, _) in entry.component.exports() { + for (export_index, export_name, kind, _) in entry.component.exports() { let kind = match kind { ComponentExternalKind::Module => ComponentExportKind::Module, ComponentExternalKind::Func => ComponentExportKind::Func, @@ -1251,7 +1199,7 @@ impl<'a> CompositionGraphEncoder<'a> { } }; - export_section.export(export_name, export_url, kind, index, None); + export_section.export(export_name, kind, index, None); } if !alias_section.is_empty() { @@ -1376,11 +1324,10 @@ impl<'a> CompositionGraphEncoder<'a> { for (import_index, export_index) in map { // Check to see if we need to alias the item from the source instance - let (name, _, ty) = component.import(*import_index).unwrap(); + let (name, ty) = component.import(*import_index).unwrap(); let index = match export_index { Some(export_index) => { - let (export_name, _, _, _) = - source_component.export(*export_index).unwrap(); + let (export_name, _, _) = source_component.export(*export_index).unwrap(); match self.aliases.get(&(source_id, *export_index)) { Some(index) => *index, None => { @@ -1402,7 +1349,7 @@ impl<'a> CompositionGraphEncoder<'a> { } // Finally, add any instantiation arguments that are being imported - for (i, (name, (_, ty))) in component.imports.iter().enumerate() { + for (i, (name, ty)) in component.imports.iter().enumerate() { let import_index = ImportIndex(i); if instance.connected.contains(&import_index) { continue; @@ -1415,13 +1362,7 @@ impl<'a> CompositionGraphEncoder<'a> { args } - fn import( - &mut self, - encoded: &mut Component, - name: &str, - url: &str, - ty: ComponentTypeRef, - ) -> u32 { + fn import(&mut self, encoded: &mut Component, name: &str, ty: ComponentTypeRef) -> u32 { let (desc, count) = match ty { ComponentTypeRef::Module(_) => ("module", &mut self.modules), ComponentTypeRef::Func(_) => ("function", &mut self.funcs), @@ -1434,7 +1375,7 @@ impl<'a> CompositionGraphEncoder<'a> { log::debug!("importing {desc} with `{name}` (encoded index {count}) in composed component"); let mut import_section = ComponentImportSection::new(); - import_section.import(name, url, ty); + import_section.import(name, ty); encoded.section(&import_section); let index = *count; diff --git a/crates/wasm-compose/src/graph.rs b/crates/wasm-compose/src/graph.rs index 2c605e6a9b..93212d0685 100644 --- a/crates/wasm-compose/src/graph.rs +++ b/crates/wasm-compose/src/graph.rs @@ -37,9 +37,9 @@ pub struct Component<'a> { /// The type information of the component. pub(crate) types: Types, /// The import map of the component. - pub(crate) imports: IndexMap, + pub(crate) imports: IndexMap, /// The export map of the component. - pub(crate) exports: IndexMap, + pub(crate) exports: IndexMap, } impl<'a> Component<'a> { @@ -122,19 +122,25 @@ impl<'a> Component<'a> { Payload::ComponentImportSection(s) => { for import in s { let import = import?; - imports.insert( - import.name.to_string(), - (import.url.to_string(), import.ty), - ); + let name = match import.name { + wasmparser::ComponentExternName::Kebab(s) + | wasmparser::ComponentExternName::Interface(s) => { + s.to_string() + } + }; + imports.insert(name, import.ty); } } Payload::ComponentExportSection(s) => { for export in s { let export = export?; - exports.insert( - export.name.to_string(), - (export.url.to_string(), export.kind, export.index), - ); + let name = match export.name { + wasmparser::ComponentExternName::Kebab(s) + | wasmparser::ComponentExternName::Interface(s) => { + s.to_string() + } + }; + exports.insert(name, (export.kind, export.index)); } } _ => {} @@ -193,58 +199,51 @@ impl<'a> Component<'a> { pub fn export( &self, index: impl Into, - ) -> Option<(&str, &str, ComponentExternalKind, u32)> { + ) -> Option<(&str, ComponentExternalKind, u32)> { let index = index.into(); self.exports .get_index(index.0) - .map(|(name, (url, kind, index))| (name.as_str(), url.as_str(), *kind, *index)) + .map(|(name, (kind, index))| (name.as_str(), *kind, *index)) } /// Gets an export from the component for the given export name. - pub fn export_by_name( - &self, - name: &str, - ) -> Option<(ExportIndex, &str, ComponentExternalKind, u32)> { + pub fn export_by_name(&self, name: &str) -> Option<(ExportIndex, ComponentExternalKind, u32)> { self.exports .get_full(name) - .map(|(i, _, (url, kind, index))| (ExportIndex(i), url.as_str(), *kind, *index)) + .map(|(i, _, (kind, index))| (ExportIndex(i), *kind, *index)) } /// Gets an iterator over the component's exports. pub fn exports( &self, - ) -> impl ExactSizeIterator { + ) -> impl ExactSizeIterator { self.exports .iter() .enumerate() - .map(|(i, (name, (url, kind, index)))| { - (ExportIndex(i), name.as_str(), url.as_str(), *kind, *index) - }) + .map(|(i, (name, (kind, index)))| (ExportIndex(i), name.as_str(), *kind, *index)) } /// Gets an import from the component for the given import index. - pub fn import(&self, index: impl Into) -> Option<(&str, &str, ComponentTypeRef)> { + pub fn import(&self, index: impl Into) -> Option<(&str, ComponentTypeRef)> { let index = index.into(); self.imports .get_index(index.0) - .map(|(name, (url, ty))| (name.as_str(), url.as_str(), *ty)) + .map(|(name, ty)| (name.as_str(), *ty)) } /// Gets an import from the component for the given import name. - pub fn import_by_name(&self, name: &str) -> Option<(ImportIndex, &str, ComponentTypeRef)> { + pub fn import_by_name(&self, name: &str) -> Option<(ImportIndex, ComponentTypeRef)> { self.imports .get_full(name) - .map(|(i, _, (url, ty))| (ImportIndex(i), url.as_str(), *ty)) + .map(|(i, _, ty)| (ImportIndex(i), *ty)) } /// Gets an iterator over the component's imports. - pub fn imports( - &self, - ) -> impl ExactSizeIterator { + pub fn imports(&self) -> impl ExactSizeIterator { self.imports .iter() .enumerate() - .map(|(i, (name, (url, ty)))| (ImportIndex(i), name.as_str(), url.as_str(), *ty)) + .map(|(i, (name, ty))| (ImportIndex(i), name.as_str(), *ty)) } pub(crate) fn ty(&self) -> wasm_encoder::ComponentType { @@ -261,17 +260,17 @@ impl<'a> Component<'a> { pub(crate) fn export_entity_type( &self, index: ExportIndex, - ) -> Option<(&str, &str, ComponentEntityType)> { - let (name, url, _kind, _index) = self.export(index)?; - Some((name, url, self.types.component_entity_type_of_extern(name)?)) + ) -> Option<(&str, ComponentEntityType)> { + let (name, _kind, _index) = self.export(index)?; + Some((name, self.types.component_entity_type_of_export(name)?)) } pub(crate) fn import_entity_type( &self, index: ImportIndex, - ) -> Option<(&str, &str, ComponentEntityType)> { - let (name, url, _ty) = self.import(index)?; - Some((name, url, self.types.component_entity_type_of_extern(name)?)) + ) -> Option<(&str, ComponentEntityType)> { + let (name, _ty) = self.import(index)?; + Some((name, self.types.component_entity_type_of_import(name)?)) } /// Finds a compatible instance export on the component for the given instance type. @@ -282,7 +281,7 @@ impl<'a> Component<'a> { ) -> Option { self.exports .iter() - .position(|(_, (_, kind, index))| { + .position(|(_, (kind, index))| { if *kind != ComponentExternalKind::Instance { return false; } @@ -309,10 +308,10 @@ impl<'a> Component<'a> { .exports .iter(); - for (k, (_, b)) in exports { + for (k, b) in exports { match self.exports.get_full(k.as_str()) { Some((ai, _, _)) => { - let (_, _, a) = self.export_entity_type(ExportIndex(ai)).unwrap(); + let (_, a) = self.export_entity_type(ExportIndex(ai)).unwrap(); if !ComponentEntityType::is_subtype_of(&a, self.types.as_ref(), b, types) { return false; } @@ -735,7 +734,7 @@ impl<'a> CompositionGraph<'a> { .ok_or_else(|| anyhow!("the target instance does not exist in the graph"))?; let target_component = &self.components[&target_instance.component].component; - let (import_name, _, import_ty) = target_component + let (import_name, import_ty) = target_component .import_entity_type(target_import) .ok_or_else(|| anyhow!("the target import index is invalid"))?; @@ -747,7 +746,7 @@ impl<'a> CompositionGraph<'a> { } if let Some(export_index) = source_export { - let (export_name, _, export_ty) = source_component + let (export_name, export_ty) = source_component .export_entity_type(export_index) .ok_or_else(|| anyhow!("the source export index is invalid"))?; diff --git a/crates/wasm-compose/tests/compose.rs b/crates/wasm-compose/tests/compose.rs index 831d0b1b28..b2e4195808 100644 --- a/crates/wasm-compose/tests/compose.rs +++ b/crates/wasm-compose/tests/compose.rs @@ -75,7 +75,7 @@ fn component_composing() -> Result<()> { ) })?; - wit_component::decode("component", &bytes).with_context(|| { + wit_component::decode(&bytes).with_context(|| { format!( "failed to decode WIT from component bytes for test case `{}`", test_case diff --git a/crates/wasm-compose/tests/compositions/url-mismatch/b.wat b/crates/wasm-compose/tests/compositions/url-mismatch/b.wat deleted file mode 100644 index 9018fcc7bd..0000000000 --- a/crates/wasm-compose/tests/compositions/url-mismatch/b.wat +++ /dev/null @@ -1,3 +0,0 @@ -(component - (import "a" "http://example.com/bar" (instance)) -) diff --git a/crates/wasm-compose/tests/compositions/url-mismatch/error.txt b/crates/wasm-compose/tests/compositions/url-mismatch/error.txt deleted file mode 100644 index 956919f9b3..0000000000 --- a/crates/wasm-compose/tests/compositions/url-mismatch/error.txt +++ /dev/null @@ -1 +0,0 @@ -cannot import instance with name `a` because import URL `http://example.com/foo` conflicts with `http://example.com/bar` diff --git a/crates/wasm-compose/tests/compositions/url-mismatch/root.wat b/crates/wasm-compose/tests/compositions/url-mismatch/root.wat deleted file mode 100644 index 0c1f4c1121..0000000000 --- a/crates/wasm-compose/tests/compositions/url-mismatch/root.wat +++ /dev/null @@ -1,4 +0,0 @@ -(component - (import "a" "http://example.com/foo" (instance)) - (import "b" (instance)) -) diff --git a/crates/wasm-encoder/src/component.rs b/crates/wasm-encoder/src/component.rs index 5f92a91f77..68ee1b6448 100644 --- a/crates/wasm-encoder/src/component.rs +++ b/crates/wasm-encoder/src/component.rs @@ -113,7 +113,7 @@ impl Component { // Magic 0x00, 0x61, 0x73, 0x6D, // Version - 0x0c, 0x00, 0x01, 0x00, + 0x0d, 0x00, 0x01, 0x00, ]; /// Begin writing a new `Component`. diff --git a/crates/wasm-encoder/src/component/exports.rs b/crates/wasm-encoder/src/component/exports.rs index 9720d51b02..09f9e2514a 100644 --- a/crates/wasm-encoder/src/component/exports.rs +++ b/crates/wasm-encoder/src/component/exports.rs @@ -2,7 +2,10 @@ use super::{ COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, FUNCTION_SORT, INSTANCE_SORT, TYPE_SORT, VALUE_SORT, }; -use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentTypeRef, Encode}; +use crate::{ + encode_section, AsComponentExternName, ComponentSection, ComponentSectionId, ComponentTypeRef, + Encode, +}; /// Represents the kind of an export from a WebAssembly component. #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -52,11 +55,12 @@ impl Encode for ComponentExportKind { /// # Example /// /// ```rust -/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind}; +/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind, ComponentExternName}; /// /// // This exports a function named "foo" /// let mut exports = ComponentExportSection::new(); -/// exports.export("foo", "", ComponentExportKind::Func, 0, None); +/// let name = ComponentExternName::Kebab("foo"); +/// exports.export(name, ComponentExportKind::Func, 0, None); /// /// let mut component = Component::new(); /// component.section(&exports); @@ -88,14 +92,12 @@ impl ComponentExportSection { /// Define an export in the export section. pub fn export( &mut self, - name: &str, - url: &str, + name: impl AsComponentExternName, kind: ComponentExportKind, index: u32, ty: Option, ) -> &mut Self { - name.encode(&mut self.bytes); - url.encode(&mut self.bytes); + name.as_component_extern_name().encode(&mut self.bytes); kind.encode(&mut self.bytes); index.encode(&mut self.bytes); match ty { diff --git a/crates/wasm-encoder/src/component/imports.rs b/crates/wasm-encoder/src/component/imports.rs index 548a213712..fe611a015d 100644 --- a/crates/wasm-encoder/src/component/imports.rs +++ b/crates/wasm-encoder/src/component/imports.rs @@ -82,7 +82,7 @@ impl Encode for ComponentTypeRef { /// # Example /// /// ```rust -/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType, ComponentImportSection, ComponentTypeRef}; +/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType, ComponentImportSection, ComponentTypeRef, ComponentExternName}; /// /// let mut types = ComponentTypeSection::new(); /// @@ -99,7 +99,8 @@ impl Encode for ComponentTypeRef { /// /// // This imports a function named `f` with the type defined above /// let mut imports = ComponentImportSection::new(); -/// imports.import("f", "", ComponentTypeRef::Func(0)); +/// let name = ComponentExternName::Kebab("f"); +/// imports.import(name, ComponentTypeRef::Func(0)); /// /// let mut component = Component::new(); /// component.section(&types); @@ -130,9 +131,8 @@ impl ComponentImportSection { } /// Define an import in the component import section. - pub fn import(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> &mut Self { - name.encode(&mut self.bytes); - url.encode(&mut self.bytes); + pub fn import(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self { + name.as_component_extern_name().encode(&mut self.bytes); ty.encode(&mut self.bytes); self.num_added += 1; self @@ -150,3 +150,51 @@ impl ComponentSection for ComponentImportSection { ComponentSectionId::Import.into() } } + +/// The different names that can be assigned to component imports +#[derive(Debug, Copy, Clone)] +pub enum ComponentExternName<'a> { + /// This is a "kebab name" along the lines of "a-foo-bar" + Kebab(&'a str), + /// This is an ID along the lines of "wasi:http/types@2.0" + Interface(&'a str), +} + +impl Encode for ComponentExternName<'_> { + fn encode(&self, sink: &mut Vec) { + match self { + ComponentExternName::Kebab(name) => { + sink.push(0x00); + name.encode(sink); + } + ComponentExternName::Interface(name) => { + sink.push(0x01); + name.encode(sink); + } + } + } +} + +/// Helper trait to convert into a `ComponentExternName` either from that type +/// or from a string. +pub trait AsComponentExternName { + /// Converts this receiver into a `ComponentExternName`. + fn as_component_extern_name(&self) -> ComponentExternName<'_>; +} + +impl AsComponentExternName for ComponentExternName<'_> { + fn as_component_extern_name(&self) -> ComponentExternName<'_> { + *self + } +} + +impl> AsComponentExternName for S { + fn as_component_extern_name(&self) -> ComponentExternName<'_> { + let s = self.as_ref(); + if s.contains("/") { + ComponentExternName::Interface(s) + } else { + ComponentExternName::Kebab(s) + } + } +} diff --git a/crates/wasm-encoder/src/component/instances.rs b/crates/wasm-encoder/src/component/instances.rs index 5f2c97dec3..d2a8e4e777 100644 --- a/crates/wasm-encoder/src/component/instances.rs +++ b/crates/wasm-encoder/src/component/instances.rs @@ -1,6 +1,7 @@ use super::CORE_INSTANCE_SORT; use crate::{ - encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind, + encode_section, ComponentExportKind, ComponentExternName, ComponentSection, ComponentSectionId, + Encode, ExportKind, }; /// Represents an argument to a module instantiation. @@ -114,10 +115,10 @@ impl ComponentSection for InstanceSection { /// # Example /// /// ```rust -/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind}; +/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind, ComponentExternName}; /// /// let mut instances = ComponentInstanceSection::new(); -/// instances.export_items([("foo", ComponentExportKind::Func, 0)]); +/// instances.export_items([(ComponentExternName::Kebab("foo"), ComponentExportKind::Func, 0)]); /// instances.instantiate(1, [("foo", ComponentExportKind::Instance, 0)]); /// /// let mut component = Component::new(); @@ -170,7 +171,7 @@ impl ComponentInstanceSection { /// Define an instance by exporting items. pub fn export_items<'a, E>(&mut self, exports: E) -> &mut Self where - E: IntoIterator, + E: IntoIterator, ComponentExportKind, u32)>, E::IntoIter: ExactSizeIterator, { let exports = exports.into_iter(); diff --git a/crates/wasm-encoder/src/component/types.rs b/crates/wasm-encoder/src/component/types.rs index 6b0b9ed0bc..417b10f7d9 100644 --- a/crates/wasm-encoder/src/component/types.rs +++ b/crates/wasm-encoder/src/component/types.rs @@ -1,7 +1,7 @@ use super::CORE_TYPE_SORT; use crate::{ - encode_section, Alias, ComponentExportKind, ComponentOuterAliasKind, ComponentSection, - ComponentSectionId, ComponentTypeRef, Encode, EntityType, ValType, + encode_section, Alias, AsComponentExternName, ComponentExportKind, ComponentOuterAliasKind, + ComponentSection, ComponentSectionId, ComponentTypeRef, Encode, EntityType, ValType, }; /// Represents the type of a core module. @@ -245,10 +245,9 @@ impl ComponentType { } /// Defines an import in this component type. - pub fn import(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> &mut Self { + pub fn import(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self { self.bytes.push(0x03); - name.encode(&mut self.bytes); - url.encode(&mut self.bytes); + name.as_component_extern_name().encode(&mut self.bytes); ty.encode(&mut self.bytes); self.num_added += 1; match ty { @@ -259,10 +258,9 @@ impl ComponentType { } /// Defines an export in this component type. - pub fn export(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> &mut Self { + pub fn export(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self { self.bytes.push(0x04); - name.encode(&mut self.bytes); - url.encode(&mut self.bytes); + name.as_component_extern_name().encode(&mut self.bytes); ty.encode(&mut self.bytes); self.num_added += 1; match ty { @@ -324,8 +322,8 @@ impl InstanceType { } /// Defines an export in this instance type. - pub fn export(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> &mut Self { - self.0.export(name, url, ty); + pub fn export(&mut self, name: impl AsComponentExternName, ty: ComponentTypeRef) -> &mut Self { + self.0.export(name, ty); self } diff --git a/crates/wasm-encoder/src/lib.rs b/crates/wasm-encoder/src/lib.rs index c182c709ee..930c63ec9d 100644 --- a/crates/wasm-encoder/src/lib.rs +++ b/crates/wasm-encoder/src/lib.rs @@ -210,6 +210,6 @@ mod test { #[test] fn it_encodes_an_empty_component() { let bytes = Component::new().finish(); - assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0c, 0x00, 0x01, 0x00]); + assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0d, 0x00, 0x01, 0x00]); } } diff --git a/crates/wasm-smith/src/component/encode.rs b/crates/wasm-smith/src/component/encode.rs index f98d477eb7..c5b6571203 100644 --- a/crates/wasm-smith/src/component/encode.rs +++ b/crates/wasm-smith/src/component/encode.rs @@ -73,7 +73,7 @@ impl ImportSection { fn encode(&self, component: &mut wasm_encoder::Component) { let mut sec = wasm_encoder::ComponentImportSection::new(); for imp in &self.imports { - sec.import(&imp.name, imp.url.as_deref().unwrap_or(""), imp.ty); + sec.import(wasm_encoder::ComponentExternName::Kebab(&imp.name), imp.ty); } component.section(&sec); } @@ -180,7 +180,10 @@ impl Type { for def in &comp_ty.defs { match def { ComponentTypeDef::Import(imp) => { - enc_comp_ty.import(&imp.name, imp.url.as_deref().unwrap_or(""), imp.ty); + enc_comp_ty.import( + wasm_encoder::ComponentExternName::Kebab(&imp.name), + imp.ty, + ); } ComponentTypeDef::CoreType(ty) => { ty.encode(enc_comp_ty.core_type()); @@ -188,8 +191,8 @@ impl Type { ComponentTypeDef::Type(ty) => { ty.encode(enc_comp_ty.ty()); } - ComponentTypeDef::Export { name, url, ty } => { - enc_comp_ty.export(name, url.as_deref().unwrap_or(""), *ty); + ComponentTypeDef::Export { name, url: _, ty } => { + enc_comp_ty.export(wasm_encoder::ComponentExternName::Kebab(name), *ty); } ComponentTypeDef::Alias(a) => { enc_comp_ty.alias(translate_alias(a)); @@ -208,8 +211,8 @@ impl Type { InstanceTypeDecl::Type(ty) => { ty.encode(enc_inst_ty.ty()); } - InstanceTypeDecl::Export { name, url, ty } => { - enc_inst_ty.export(name, url.as_deref().unwrap_or(""), *ty); + InstanceTypeDecl::Export { name, url: _, ty } => { + enc_inst_ty.export(wasm_encoder::ComponentExternName::Kebab(name), *ty); } InstanceTypeDecl::Alias(a) => { enc_inst_ty.alias(translate_alias(a)); diff --git a/crates/wasmparser/Cargo.toml b/crates/wasmparser/Cargo.toml index 2d4e355e0a..45202aa267 100644 --- a/crates/wasmparser/Cargo.toml +++ b/crates/wasmparser/Cargo.toml @@ -14,7 +14,7 @@ exclude = ["benches/*.wasm"] [dependencies] indexmap = { workspace = true } -url = { workspace = true } +semver = { workspace = true } [dev-dependencies] anyhow = { workspace = true } diff --git a/crates/wasmparser/src/parser.rs b/crates/wasmparser/src/parser.rs index fa29501bd4..87c47f2356 100644 --- a/crates/wasmparser/src/parser.rs +++ b/crates/wasmparser/src/parser.rs @@ -19,9 +19,11 @@ pub(crate) const WASM_MODULE_VERSION: u16 = 0x1; // the component model is stabilized this will become 0x1. The changes here are: // // * [????-??-??] 0xa - original version -// * [2022-01-05] 0xb - `export` introduces an alias -// * [2022-02-06] 0xc - `export` has an optional type ascribed to it -pub(crate) const WASM_COMPONENT_VERSION: u16 = 0xc; +// * [2023-01-05] 0xb - `export` introduces an alias +// * [2023-02-06] 0xc - `export` has an optional type ascribed to it +// * [2023-05-10] 0xd - imports/exports drop URLs, new discriminator byte which +// allows for `(import (interface "...") ...)` syntax. +pub(crate) const WASM_COMPONENT_VERSION: u16 = 0xd; const KIND_MODULE: u16 = 0x00; const KIND_COMPONENT: u16 = 0x01; @@ -1204,7 +1206,7 @@ mod tests { fn parser_after_component_header() -> Parser { let mut p = Parser::default(); assert_matches!( - p.parse(b"\0asm\x0c\0\x01\0", false), + p.parse(b"\0asm\x0d\0\x01\0", false), Ok(Chunk::Parsed { consumed: 8, payload: Payload::Version { diff --git a/crates/wasmparser/src/readers/component/exports.rs b/crates/wasmparser/src/readers/component/exports.rs index ca973bf430..35c5439405 100644 --- a/crates/wasmparser/src/readers/component/exports.rs +++ b/crates/wasmparser/src/readers/component/exports.rs @@ -1,4 +1,6 @@ -use crate::{BinaryReader, ComponentTypeRef, FromReader, Result, SectionLimited}; +use crate::{ + BinaryReader, ComponentExternName, ComponentTypeRef, FromReader, Result, SectionLimited, +}; /// Represents the kind of an external items of a WebAssembly component. #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -67,9 +69,7 @@ impl ComponentExternalKind { #[derive(Debug, Clone)] pub struct ComponentExport<'a> { /// The name of the exported item. - pub name: &'a str, - /// The optional URL of the exported item. - pub url: &'a str, + pub name: ComponentExternName<'a>, /// The kind of the export. pub kind: ComponentExternalKind, /// The index of the exported item. @@ -85,7 +85,6 @@ impl<'a> FromReader<'a> for ComponentExport<'a> { fn from_reader(reader: &mut BinaryReader<'a>) -> Result { Ok(ComponentExport { name: reader.read()?, - url: reader.read()?, kind: reader.read()?, index: reader.read()?, ty: match reader.read_u8()? { diff --git a/crates/wasmparser/src/readers/component/imports.rs b/crates/wasmparser/src/readers/component/imports.rs index b51de945da..d5e09cbc8f 100644 --- a/crates/wasmparser/src/readers/component/imports.rs +++ b/crates/wasmparser/src/readers/component/imports.rs @@ -79,9 +79,7 @@ impl<'a> FromReader<'a> for ComponentTypeRef { #[derive(Debug, Copy, Clone)] pub struct ComponentImport<'a> { /// The name of the imported item. - pub name: &'a str, - /// The optional URL of the imported item. - pub url: &'a str, + pub name: ComponentExternName<'a>, /// The type reference for the import. pub ty: ComponentTypeRef, } @@ -90,7 +88,6 @@ impl<'a> FromReader<'a> for ComponentImport<'a> { fn from_reader(reader: &mut BinaryReader<'a>) -> Result { Ok(ComponentImport { name: reader.read()?, - url: reader.read()?, ty: reader.read()?, }) } @@ -102,7 +99,7 @@ impl<'a> FromReader<'a> for ComponentImport<'a> { /// /// ``` /// use wasmparser::ComponentImportSectionReader; -/// let data: &[u8] = &[0x01, 0x01, 0x41, 0x00, 0x01, 0x66]; +/// let data: &[u8] = &[0x01, 0x00, 0x01, 0x41, 0x01, 0x66]; /// let reader = ComponentImportSectionReader::new(data, 0).unwrap(); /// for import in reader { /// let import = import.expect("import"); @@ -110,3 +107,31 @@ impl<'a> FromReader<'a> for ComponentImport<'a> { /// } /// ``` pub type ComponentImportSectionReader<'a> = SectionLimited<'a, ComponentImport<'a>>; + +/// Represents the name of a component import. +#[derive(Debug, Copy, Clone)] +#[allow(missing_docs)] +pub enum ComponentExternName<'a> { + Kebab(&'a str), + Interface(&'a str), +} + +impl<'a> ComponentExternName<'a> { + /// Returns the underlying string representing this name. + pub fn as_str(&self) -> &'a str { + match self { + ComponentExternName::Kebab(name) => name, + ComponentExternName::Interface(name) => name, + } + } +} + +impl<'a> FromReader<'a> for ComponentExternName<'a> { + fn from_reader(reader: &mut BinaryReader<'a>) -> Result { + Ok(match reader.read_u8()? { + 0x00 => ComponentExternName::Kebab(reader.read()?), + 0x01 => ComponentExternName::Interface(reader.read()?), + x => return reader.invalid_leading_byte(x, "import name"), + }) + } +} diff --git a/crates/wasmparser/src/readers/component/instances.rs b/crates/wasmparser/src/readers/component/instances.rs index 8166395edc..a33762c420 100644 --- a/crates/wasmparser/src/readers/component/instances.rs +++ b/crates/wasmparser/src/readers/component/instances.rs @@ -141,7 +141,6 @@ impl<'a> FromReader<'a> for ComponentInstance<'a> { .map(|_| { Ok(ComponentExport { name: reader.read()?, - url: "", kind: reader.read()?, index: reader.read()?, ty: None, diff --git a/crates/wasmparser/src/readers/component/types.rs b/crates/wasmparser/src/readers/component/types.rs index 3ce67db922..73171568c5 100644 --- a/crates/wasmparser/src/readers/component/types.rs +++ b/crates/wasmparser/src/readers/component/types.rs @@ -1,7 +1,7 @@ use crate::limits::*; use crate::{ - BinaryReader, ComponentAlias, ComponentImport, ComponentTypeRef, FromReader, FuncType, Import, - Result, SectionLimited, Type, TypeRef, ValType, + BinaryReader, ComponentAlias, ComponentExternName, ComponentImport, ComponentTypeRef, + FromReader, FuncType, Import, Result, SectionLimited, Type, TypeRef, ValType, }; use std::fmt; @@ -296,9 +296,7 @@ pub enum ComponentTypeDeclaration<'a> { /// The component type declaration is for an export. Export { /// The name of the export. - name: &'a str, - /// The optional URL of the export. - url: &'a str, + name: ComponentExternName<'a>, /// The type reference for the export. ty: ComponentTypeRef, }, @@ -320,8 +318,8 @@ impl<'a> FromReader<'a> for ComponentTypeDeclaration<'a> { InstanceTypeDeclaration::CoreType(t) => ComponentTypeDeclaration::CoreType(t), InstanceTypeDeclaration::Type(t) => ComponentTypeDeclaration::Type(t), InstanceTypeDeclaration::Alias(a) => ComponentTypeDeclaration::Alias(a), - InstanceTypeDeclaration::Export { name, url, ty } => { - ComponentTypeDeclaration::Export { name, url, ty } + InstanceTypeDeclaration::Export { name, ty } => { + ComponentTypeDeclaration::Export { name, ty } } }) } @@ -339,9 +337,7 @@ pub enum InstanceTypeDeclaration<'a> { /// The instance type declaration is for an export. Export { /// The name of the export. - name: &'a str, - /// The URL for the export. - url: &'a str, + name: ComponentExternName<'a>, /// The type reference for the export. ty: ComponentTypeRef, }, @@ -355,7 +351,6 @@ impl<'a> FromReader<'a> for InstanceTypeDeclaration<'a> { 0x02 => InstanceTypeDeclaration::Alias(reader.read()?), 0x04 => InstanceTypeDeclaration::Export { name: reader.read()?, - url: reader.read()?, ty: reader.read()?, }, x => return reader.invalid_leading_byte(x, "component or instance type declaration"), diff --git a/crates/wasmparser/src/validator.rs b/crates/wasmparser/src/validator.rs index 6b89fae760..254cfce98b 100644 --- a/crates/wasmparser/src/validator.rs +++ b/crates/wasmparser/src/validator.rs @@ -1219,13 +1219,13 @@ impl Validator { |components, _, count, offset| { let current = components.last_mut().unwrap(); check_max( - current.externs.len(), + current.exports.len(), count, MAX_WASM_EXPORTS, - "imports and exports", + "exports", offset, )?; - current.externs.reserve(count as usize); + current.exports.reserve(count as usize); Ok(()) }, |components, types, _, export, offset| { @@ -1233,7 +1233,6 @@ impl Validator { let ty = current.export_to_entity_type(&export, types, offset)?; current.add_export( export.name, - export.url, ty, types, offset, diff --git a/crates/wasmparser/src/validator/component.rs b/crates/wasmparser/src/validator/component.rs index c88467768b..3b9acb08a9 100644 --- a/crates/wasmparser/src/validator/component.rs +++ b/crates/wasmparser/src/validator/component.rs @@ -16,14 +16,13 @@ use crate::{ ComponentDefinedType, ComponentEntityType, Context, InstanceTypeKind, LoweringInfo, Remap, SubtypeCx, TupleType, UnionType, VariantType, }, - BinaryReaderError, CanonicalOption, ComponentExternalKind, ComponentOuterAliasKind, - ComponentTypeRef, ExternalKind, FuncType, GlobalType, InstantiationArgKind, MemoryType, Result, - TableType, TypeBounds, ValType, WasmFeatures, + BinaryReaderError, CanonicalOption, ComponentExternName, ComponentExternalKind, + ComponentOuterAliasKind, ComponentTypeRef, ExternalKind, FuncType, GlobalType, + InstantiationArgKind, MemoryType, Result, TableType, TypeBounds, ValType, WasmFeatures, }; use indexmap::{map::Entry, IndexMap, IndexSet}; use std::collections::{HashMap, HashSet}; use std::mem; -use url::Url; fn to_kebab_str<'a>(s: &'a str, desc: &str, offset: usize) -> Result<&'a KebabStr> { match KebabStr::new(s) { @@ -38,16 +37,6 @@ fn to_kebab_str<'a>(s: &'a str, desc: &str, offset: usize) -> Result<&'a KebabSt } } -fn parse_url(url: &str, offset: usize) -> Result> { - if url.is_empty() { - return Ok(None); - } - - Url::parse(url) - .map(Some) - .map_err(|e| BinaryReaderError::new(e.to_string(), offset)) -} - pub(crate) struct ComponentState { /// Whether this state is a concrete component, an instance type, or a /// component type. @@ -70,15 +59,9 @@ pub(crate) struct ComponentState { pub instances: Vec, pub components: Vec, - /// A set of all imports and exports since they share the same namespace. - pub externs: IndexMap, ComponentEntityType, ExternKind)>, - next_import_index: usize, - next_export_index: usize, - - // Note: URL validation requires unique URLs by byte comparison, so - // strings are used here and the URLs are not normalized. - import_urls: HashSet, - export_urls: HashSet, + pub imports: IndexMap, + pub exports: IndexMap, + pub kebab_named_externs: IndexSet, has_start: bool, type_size: u32, @@ -238,16 +221,14 @@ impl ComponentState { values: Default::default(), instances: Default::default(), components: Default::default(), - externs: Default::default(), - import_urls: Default::default(), - export_urls: Default::default(), + imports: Default::default(), + exports: Default::default(), + kebab_named_externs: Default::default(), has_start: Default::default(), type_size: 1, imported_resources: Default::default(), defined_resources: Default::default(), explicit_resources: Default::default(), - next_import_index: 0, - next_export_index: 0, exported_types: Default::default(), imported_types: Default::default(), toplevel_exported_resources: Default::default(), @@ -430,66 +411,23 @@ impl ComponentState { let mut entity = self.check_type_ref(&import.ty, types, offset)?; self.add_entity( &mut entity, - Some((import.name, ExternKind::Import)), + Some((import.name.as_str(), ExternKind::Import)), types, offset, )?; - let name = self.parse_kebab_name( + self.toplevel_imported_resources.validate_extern( import.name, "import", &entity, - Some(&self.toplevel_imported_resources), types, offset, + &mut self.kebab_named_externs, + &mut self.imports, + &mut self.type_size, )?; - - match self.externs.entry(name) { - Entry::Occupied(e) => { - bail!( - offset, - "import name `{name}` conflicts with previous {desc} name `{prev}`", - name = import.name, - prev = e.key(), - desc = e.get().2.desc(), - ); - } - Entry::Vacant(e) => { - let url = parse_url(import.url, offset)?; - if let Some(url) = url.as_ref() { - if !self.import_urls.insert(url.to_string()) { - bail!(offset, "duplicate import URL `{url}`"); - } - } - - self.type_size = combine_type_sizes(self.type_size, entity.type_size(), offset)?; - e.insert((url, entity, ExternKind::Import)); - self.next_import_index += 1; - } - } - Ok(()) } - fn parse_kebab_name( - &self, - name: &str, - desc: &str, - ty: &ComponentEntityType, - cx: Option<&KebabNameContext>, - types: &TypeAlloc, - offset: usize, - ) -> Result { - let name = match KebabName::new(name.to_string()) { - Some(name) => name, - None => bail!(offset, "{desc} name `{name}` is not in kebab case"), - }; - if let Some(cx) = cx { - cx.validate(&name, ty, types, offset) - .with_context(|| format!("{desc} name `{name}` is not valid"))?; - } - Ok(name) - } - fn add_entity( &mut self, ty: &mut ComponentEntityType, @@ -548,8 +486,7 @@ impl ComponentState { // resource is injected with a fresh new identifier // into our state. if created == referenced { - self.imported_resources - .insert(id, vec![self.next_import_index]); + self.imported_resources.insert(id, vec![self.imports.len()]); } } @@ -570,8 +507,7 @@ impl ComponentState { // update the `explicit_resources` list. A new // export path is about to be created for this // resource and this keeps track of that. - self.explicit_resources - .insert(id, vec![self.next_export_index]); + self.explicit_resources.insert(id, vec![self.exports.len()]); } None => {} @@ -685,7 +621,7 @@ impl ComponentState { let ty = types[*i].as_component_instance_type().unwrap(); ty.exports .values() - .all(|(_url, ty)| self.validate_and_register_named_types(None, kind, ty, types)) + .all(|ty| self.validate_and_register_named_types(None, kind, ty, types)) } // All types referred to by a function must be named. @@ -768,7 +704,7 @@ impl ComponentState { .all(|ty| types.type_named_valtype(ty, set)), // Instances must recursively have all referenced types named. - Type::ComponentInstance(ty) => ty.exports.values().all(|(_url, ty)| { + Type::ComponentInstance(ty) => ty.exports.values().all(|ty| { let id = match ty { ComponentEntityType::Module(id) | ComponentEntityType::Func(id) @@ -836,14 +772,14 @@ impl ComponentState { let prev = mapping.resources.insert(*old, *new); assert!(prev.is_none()); - let mut base = vec![self.next_import_index]; + let mut base = vec![self.imports.len()]; base.extend(ty.explicit_resources[old].iter().copied()); self.imported_resources.insert(*new, base); } // Using the old-to-new resource mapping perform a substitution on // the `exports` and `explicit_resources` fields of `new_ty` - for (_, ty) in new_ty.exports.values_mut() { + for ty in new_ty.exports.values_mut() { types.remap_component_entity(ty, &mut mapping); } for (id, path) in mem::take(&mut new_ty.explicit_resources) { @@ -897,7 +833,7 @@ impl ComponentState { mapping.resources.insert(old, new); self.defined_resources.insert(new, None); } - for (_, ty) in new_ty.exports.values_mut() { + for ty in new_ty.exports.values_mut() { types.remap_component_entity(ty, &mut mapping); } for (id, path) in mem::take(&mut new_ty.explicit_resources) { @@ -916,7 +852,7 @@ impl ComponentState { // generated. let ty = types[*id].as_component_instance_type().unwrap(); for (id, path) in ty.explicit_resources.iter() { - let mut new_path = vec![self.next_export_index]; + let mut new_path = vec![self.exports.len()]; new_path.extend(path); self.explicit_resources.insert(*id, new_path); } @@ -924,55 +860,31 @@ impl ComponentState { pub fn add_export( &mut self, - name: &str, - url: &str, + name: ComponentExternName<'_>, mut ty: ComponentEntityType, types: &mut TypeAlloc, offset: usize, check_limit: bool, ) -> Result<()> { if check_limit { - check_max( - self.externs.len(), - 1, - MAX_WASM_EXPORTS, - "imports and exports", - offset, - )?; + check_max(self.exports.len(), 1, MAX_WASM_EXPORTS, "exports", offset)?; } - self.add_entity(&mut ty, Some((name, ExternKind::Export)), types, offset)?; - let kebab_name = self.parse_kebab_name( - name, + self.add_entity( + &mut ty, + Some((name.as_str(), ExternKind::Export)), + types, + offset, + )?; + self.toplevel_exported_resources.validate_extern( + name.into(), "export", &ty, - Some(&self.toplevel_exported_resources), types, offset, + &mut self.kebab_named_externs, + &mut self.exports, + &mut self.type_size, )?; - - match self.externs.entry(kebab_name) { - Entry::Occupied(e) => { - bail!( - offset, - "export name `{name}` conflicts with previous {desc} name `{prev}`", - prev = e.key(), - desc = e.get().2.desc(), - ); - } - Entry::Vacant(e) => { - let url = parse_url(url, offset)?; - if let Some(url) = url.as_ref() { - if !self.export_urls.insert(url.to_string()) { - bail!(offset, "duplicate export URL `{url}`"); - } - } - - self.type_size = combine_type_sizes(self.type_size, ty.type_size(), offset)?; - e.insert((url, ty, ExternKind::Export)); - self.next_export_index += 1; - } - } - Ok(()) } @@ -1546,10 +1458,10 @@ impl ComponentState { crate::ComponentTypeDeclaration::Type(ty) => { Self::add_type(components, ty, features, types, offset, true)?; } - crate::ComponentTypeDeclaration::Export { name, url, ty } => { + crate::ComponentTypeDeclaration::Export { name, ty } => { let current = components.last_mut().unwrap(); let ty = current.check_type_ref(&ty, types, offset)?; - current.add_export(name, url, ty, types, offset, true)?; + current.add_export(name, ty, types, offset, true)?; } crate::ComponentTypeDeclaration::Import(import) => { components @@ -1583,10 +1495,10 @@ impl ComponentState { crate::InstanceTypeDeclaration::Type(ty) => { Self::add_type(components, ty, features, types, offset, true)?; } - crate::InstanceTypeDeclaration::Export { name, url, ty } => { + crate::InstanceTypeDeclaration::Export { name, ty } => { let current = components.last_mut().unwrap(); let ty = current.check_type_ref(&ty, types, offset)?; - current.add_export(name, url, ty, types, offset, true)?; + current.add_export(name, ty, types, offset, true)?; } crate::InstanceTypeDeclaration::Alias(alias) => { Self::add_alias(components, alias, types, offset)?; @@ -1622,16 +1534,7 @@ impl ComponentState { // they're exported is plumbed through as-is. explicit_resources: mem::take(&mut state.explicit_resources), - // Transform the fused list of imports and exports into just exports - // since instance types can only declare exports. - exports: state - .externs - .into_iter() - .map(|(name, (url, ty, kind))| match kind { - ExternKind::Export => (name, (url, ty)), - ExternKind::Import => unreachable!(), - }) - .collect(), + exports: mem::take(&mut state.exports), }) } @@ -1814,15 +1717,7 @@ impl ComponentState { } } }; - let name = self.parse_kebab_name( - component_arg.name, - "instantiation argument", - &ty, - None, - types, - offset, - )?; - match args.entry(name) { + match args.entry(component_arg.name.to_string()) { Entry::Occupied(e) => { bail!( offset, @@ -1921,7 +1816,7 @@ impl ComponentState { let type_size = component_type .exports .iter() - .fold(1, |acc, (_, (_, ty))| acc + ty.type_size()); + .fold(1, |acc, (_, ty)| acc + ty.type_size()); // Perform the subtype check that `args` matches the imports of // `component_type_id`. The result of this subtype check is the @@ -1981,7 +1876,7 @@ impl ComponentState { // variables provided by imports and additionally ensuring that all // references to the component's defined resources are rebound to the // fresh ones introduced just above. - for (_, entity) in exports.values_mut() { + for entity in exports.values_mut() { types.remap_component_entity(entity, &mut mapping); } let component_type = types[component_type_id].as_component_type().unwrap(); @@ -2017,7 +1912,7 @@ impl ComponentState { // In debug mode, however, do a sanity check. if cfg!(debug_assertions) { let mut free = IndexSet::new(); - for (_, ty) in exports.values() { + for ty in exports.values() { types.free_variables_component_entity(ty, &mut free); } assert!(fresh_defined_resources.is_subset(&free)); @@ -2063,6 +1958,7 @@ impl ComponentState { let mut type_size = 1; let mut inst_exports = IndexMap::new(); let mut explicit_resources = IndexMap::new(); + let mut kebab_names = IndexSet::new(); // NB: It's intentional that this context is empty since no indices are // introduced in the bag-of-exports construct which means there's no @@ -2126,26 +2022,16 @@ impl ComponentState { } }; - let name = self.parse_kebab_name( - export.name, + names.validate_extern( + export.name.into(), "instance export", &ty, - Some(&names), types, offset, + &mut kebab_names, + &mut inst_exports, + &mut type_size, )?; - match inst_exports.entry(name) { - Entry::Occupied(e) => bail!( - offset, - "instance export name `{name}` conflicts with previous export name `{prev}`", - prev = e.key(), - name = export.name, - ), - Entry::Vacant(e) => { - type_size = combine_type_sizes(type_size, ty.type_size(), offset)?; - e.insert((None, ty)); - } - } } let ty = Type::ComponentInstance(Box::new(ComponentInstanceType { @@ -2342,17 +2228,13 @@ impl ComponentState { types: &mut TypeAlloc, offset: usize, ) -> Result<()> { - let name = match KebabName::new(name.to_string()) { - Some(name) => name, - None => bail!(offset, "alias export name `{name}` is not in kebab case"), - }; let mut ty = match types[self.instance_at(instance_index, offset)?] .as_component_instance_type() .unwrap() .exports - .get(&name) + .get(name) { - Some((_, ty)) => *ty, + Some(ty) => *ty, None => bail!( offset, "instance {instance_index} has no export named `{name}`" @@ -2893,23 +2775,11 @@ impl ComponentState { /// `ComponentType` which is suitable to use to describe the type of this /// component. pub fn finish(&mut self, types: &TypeAlloc, offset: usize) -> Result { - // Partition `self.externs` into `imports` and `exports. - let mut imports = IndexMap::with_capacity(self.next_import_index); - let mut exports = IndexMap::with_capacity(self.next_export_index); - for (name, (url, t, kind)) in self.externs.iter() { - let map = match kind { - ExternKind::Import => &mut imports, - ExternKind::Export => &mut exports, - }; - let prev = map.insert(name.clone(), (url.clone(), *t)); - assert!(prev.is_none()); - } - let mut ty = ComponentType { // Inherit some fields based on translation of the component. type_size: self.type_size, - imports, - exports, + imports: self.imports.clone(), + exports: self.exports.clone(), // This is filled in as a subset of `self.defined_resources` // depending on what's actually used by the exports. See the @@ -2929,7 +2799,7 @@ impl ComponentState { // be used as part of the exports. This set is then used to reject any // of `self.defined_resources` which show up. let mut free = IndexSet::default(); - for (_, ty) in ty.imports.values() { + for ty in ty.imports.values() { types.free_variables_component_entity(ty, &mut free); } for (resource, _path) in self.defined_resources.iter() { @@ -2968,7 +2838,7 @@ impl ComponentState { // necessary, but it's left here for completeness and out of an // abundance of caution. free.clear(); - for (_, ty) in ty.exports.values() { + for ty in ty.exports.values() { types.free_variables_component_entity(ty, &mut free); } for (id, _rep) in mem::take(&mut self.defined_resources) { @@ -3007,6 +2877,60 @@ impl KebabNameContext { self.all_resource_names.insert(name.to_string()); } + fn validate_extern( + &self, + name: ComponentExternName<'_>, + desc: &str, + ty: &ComponentEntityType, + types: &TypeAlloc, + offset: usize, + kebab_names: &mut IndexSet, + items: &mut IndexMap, + type_size: &mut u32, + ) -> Result<()> { + // First validate that `name` is even a valid kebab name, meaning it's + // in kebab-case, is an ID, etc. + let kebab = KebabName::new(name, offset).with_context(|| { + format!("{desc} name `{}` is not a valid extern name", name.as_str()) + })?; + + // Validate that the kebab name, if it has structure such as + // `[method]a.b`, is indeed valid with respect to known resources. + self.validate(&kebab, ty, types, offset) + .with_context(|| format!("{desc} name `{kebab}` is not valid"))?; + + // Top-level kebab-names must all be unique, even between both imports + // and exports ot a component. For those names consult the `kebab_names` + // set. + if let ComponentExternName::Kebab(_) = name { + if let Some(prev) = kebab_names.replace(kebab.clone()) { + bail!( + offset, + "{desc} name `{kebab}` conflicts with previous name `{prev}`", + ); + } + } + + // Otherwise all strings must be unique, regardless of their name, so + // consult the `items` set to ensure that we're not for example + // importing the same interface ID twice. + match items.entry(kebab.into()) { + Entry::Occupied(e) => { + bail!( + offset, + "{desc} name `{name}` conflicts with previous name `{prev}`", + name = name.as_str(), + prev = e.key(), + ); + } + Entry::Vacant(e) => { + e.insert(*ty); + *type_size = combine_type_sizes(*type_size, ty.type_size(), offset)?; + } + } + Ok(()) + } + /// Validates that the `name` provided is allowed to have the type `ty`. fn validate( &self, @@ -3023,8 +2947,8 @@ impl KebabNameContext { Ok(types[id].as_component_func_type().unwrap()) }; match name.kind() { - // Normal kebab name? No validation necessary. - KebabNameKind::Normal(_) => {} + // Normal kebab name or id? No validation necessary. + KebabNameKind::Normal(_) | KebabNameKind::Id { .. } => {} // Constructors must return `(own $resource)` and the `$resource` // must be named within this context to match `rname` diff --git a/crates/wasmparser/src/validator/names.rs b/crates/wasmparser/src/validator/names.rs index d60ca013ac..0c3263b35a 100644 --- a/crates/wasmparser/src/validator/names.rs +++ b/crates/wasmparser/src/validator/names.rs @@ -1,6 +1,8 @@ //! Definitions of name-related helpers and newtypes, primarily for the //! component model. +use crate::{ComponentExternName, Result}; +use semver::Version; use std::borrow::Borrow; use std::fmt; use std::hash::{Hash, Hasher}; @@ -214,14 +216,31 @@ impl From for String { /// Note that this type the `Method` and `Static` variants are considered equal /// and hash to the same value. This enables disallowing clashes between the two /// where method name overlap cannot happen. +#[derive(Clone)] +pub struct KebabName { + raw: String, + parsed: ParsedKebabName, +} + #[derive(Copy, Clone)] -pub struct KebabName { - raw: T, - dot: Option, +enum ParsedKebabName { + Normal, + Constructor, + Method { + dot: u32, + }, + Static { + dot: u32, + }, + Id { + colon: u32, + slash: u32, + at: Option, + }, } /// Created via [`KebabName::kind`] and classifies a name. -#[derive(Debug, Copy, Clone)] +#[derive(Debug, Clone)] pub enum KebabNameKind<'a> { /// `a-b-c` Normal(&'a KebabStr), @@ -239,99 +258,153 @@ pub enum KebabNameKind<'a> { resource: &'a KebabStr, name: &'a KebabStr, }, + /// `wasi:http/types@2.0` + #[allow(missing_docs)] + Id { + namespace: &'a KebabStr, + package: &'a KebabStr, + interface: &'a KebabStr, + version: Option, + }, } -impl KebabName -where - T: AsRef, -{ +const CONSTRUCTOR: &str = "[constructor]"; +const METHOD: &str = "[method]"; +const STATIC: &str = "[static]"; + +impl KebabName { /// Attempts to parse `name` as a kebab name, returning `None` if it's not /// valid. - pub fn new(name: T) -> Option> { - let s = name.as_ref(); - let dot = if let Some(s) = s.strip_prefix("[constructor]") { - KebabStr::new(s)?; - None - } else if let Some(s) = s.strip_prefix("[method]") { - let dot = s.find('.')?; - KebabStr::new(&s[..dot])?; - KebabStr::new(&s[dot + 1..])?; - Some(u32::try_from(dot).ok()?) - } else if let Some(s) = s.strip_prefix("[static]") { - let dot = s.find('.')?; - KebabStr::new(&s[..dot])?; - KebabStr::new(&s[dot + 1..])?; - Some(u32::try_from(dot).ok()?) - } else { - KebabStr::new(s)?; - None + pub fn new(name: ComponentExternName<'_>, offset: usize) -> Result { + let validate_kebab = |s: &str| { + if KebabStr::new(s).is_none() { + bail!(offset, "`{s}` is not in kebab case") + } else { + Ok(()) + } }; - Some(KebabName { raw: name, dot }) + let find = |s: &str, c: char| match s.find(c) { + Some(i) => Ok(i), + None => bail!(offset, "failed to find `{c}` character"), + }; + let parsed = match name { + ComponentExternName::Kebab(s) => { + if let Some(s) = s.strip_prefix(CONSTRUCTOR) { + validate_kebab(s)?; + ParsedKebabName::Constructor + } else if let Some(s) = s.strip_prefix(METHOD) { + let dot = find(s, '.')?; + validate_kebab(&s[..dot])?; + validate_kebab(&s[dot + 1..])?; + ParsedKebabName::Method { dot: dot as u32 } + } else if let Some(s) = s.strip_prefix(STATIC) { + let dot = find(s, '.')?; + validate_kebab(&s[..dot])?; + validate_kebab(&s[dot + 1..])?; + ParsedKebabName::Static { dot: dot as u32 } + } else { + validate_kebab(s)?; + ParsedKebabName::Normal + } + } + ComponentExternName::Interface(s) => { + let colon = find(s, ':')?; + validate_kebab(&s[..colon])?; + let slash = find(s, '/')?; + let at = s[slash..].find('@').map(|i| i + slash); + validate_kebab(&s[colon + 1..slash])?; + validate_kebab(&s[slash + 1..at.unwrap_or(s.len())])?; + if let Some(at) = at { + let version = &s[at + 1..]; + if let Err(e) = version.parse::() { + bail!(offset, "failed to parse version: {e}") + } + } + ParsedKebabName::Id { + colon: colon as u32, + slash: slash as u32, + at: at.map(|i| i as u32), + } + } + }; + Ok(KebabName { + raw: name.as_str().to_string(), + parsed, + }) } /// Returns the [`KebabNameKind`] corresponding to this name. pub fn kind(&self) -> KebabNameKind<'_> { - let s = self.raw.as_ref(); - if !s.starts_with('[') { - KebabNameKind::Normal(KebabStr::new_unchecked(s)) - } else if s.as_bytes()[1] == b'c' { - let prefix = "[constructor]"; - KebabNameKind::Constructor(KebabStr::new_unchecked(&s[prefix.len()..])) - } else { - let prefix1 = "[method]"; - let prefix2 = "[static]"; - let dot = self.dot.unwrap() as usize; - assert_eq!(prefix1.len(), prefix2.len()); - let rest = &s[prefix1.len()..]; - let resource = KebabStr::new_unchecked(&rest[..dot]); - let name = KebabStr::new_unchecked(&rest[dot + 1..]); - if s.as_bytes()[1] == b'm' { + match self.parsed { + ParsedKebabName::Normal => KebabNameKind::Normal(KebabStr::new_unchecked(&self.raw)), + ParsedKebabName::Constructor => { + let kebab = &self.raw[CONSTRUCTOR.len()..]; + KebabNameKind::Constructor(KebabStr::new_unchecked(kebab)) + } + ParsedKebabName::Method { dot } => { + let dotted = &self.raw[METHOD.len()..]; + let resource = KebabStr::new_unchecked(&dotted[..dot as usize]); + let name = KebabStr::new_unchecked(&dotted[dot as usize + 1..]); KebabNameKind::Method { resource, name } - } else { + } + ParsedKebabName::Static { dot } => { + let dotted = &self.raw[METHOD.len()..]; + let resource = KebabStr::new_unchecked(&dotted[..dot as usize]); + let name = KebabStr::new_unchecked(&dotted[dot as usize + 1..]); KebabNameKind::Static { resource, name } } + ParsedKebabName::Id { colon, slash, at } => { + let colon = colon as usize; + let slash = slash as usize; + let at = at.map(|i| i as usize); + let namespace = KebabStr::new_unchecked(&self.raw[..colon]); + let package = KebabStr::new_unchecked(&self.raw[colon + 1..slash]); + let interface = + KebabStr::new_unchecked(&self.raw[slash + 1..at.unwrap_or(self.raw.len())]); + let version = at.map(|i| Version::parse(&self.raw[i + 1..]).unwrap()); + KebabNameKind::Id { + namespace, + package, + interface, + version, + } + } } } /// Returns the raw underlying name as a string. pub fn as_str(&self) -> &str { - self.raw.as_ref() + &self.raw } } -impl Hash for KebabName -where - T: AsRef, -{ +impl From for String { + fn from(name: KebabName) -> String { + name.raw + } +} + +impl Hash for KebabName { fn hash(&self, hasher: &mut H) { self.kind().hash(hasher) } } -impl PartialEq for KebabName -where - T: AsRef, -{ - fn eq(&self, other: &KebabName) -> bool { +impl PartialEq for KebabName { + fn eq(&self, other: &KebabName) -> bool { self.kind().eq(&other.kind()) } } -impl Eq for KebabName where T: AsRef {} +impl Eq for KebabName {} -impl fmt::Display for KebabName -where - T: fmt::Display, -{ +impl fmt::Display for KebabName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.raw.fmt(f) } } -impl fmt::Debug for KebabName -where - T: fmt::Debug, -{ +impl fmt::Debug for KebabName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.raw.fmt(f) } @@ -354,6 +427,18 @@ impl Hash for KebabNameKind<'_> { resource.hash(hasher); name.hash(hasher); } + KebabNameKind::Id { + namespace, + package, + interface, + version, + } => { + hasher.write_u8(3); + namespace.hash(hasher); + package.hash(hasher); + interface.hash(hasher); + version.hash(hasher); + } } } } @@ -411,6 +496,22 @@ impl PartialEq for KebabNameKind<'_> { (KebabNameKind::Method { .. }, _) => false, (KebabNameKind::Static { .. }, _) => false, + + ( + KebabNameKind::Id { + namespace: an, + package: ap, + interface: ai, + version: av, + }, + KebabNameKind::Id { + namespace: bn, + package: bp, + interface: bi, + version: bv, + }, + ) => an == bn && ap == bp && ai == bi && av == bv, + (KebabNameKind::Id { .. }, _) => false, } } } @@ -422,6 +523,10 @@ mod tests { use super::*; use std::collections::HashSet; + fn parse_kebab_name(s: &str) -> Option { + KebabName::new(ComponentExternName::Kebab(s), 0).ok() + } + #[test] fn kebab_smoke() { assert!(KebabStr::new("").is_none()); @@ -438,43 +543,64 @@ mod tests { #[test] fn name_smoke() { - assert!(KebabName::new("a").is_some()); - assert!(KebabName::new("[foo]a").is_none()); - assert!(KebabName::new("[constructor]a").is_some()); - assert!(KebabName::new("[method]a").is_none()); - assert!(KebabName::new("[method]a.b").is_some()); - assert!(KebabName::new("[method]a.b.c").is_none()); - assert!(KebabName::new("[static]a.b").is_some()); - assert!(KebabName::new("[static]a").is_none()); + assert!(parse_kebab_name("a").is_some()); + assert!(parse_kebab_name("[foo]a").is_none()); + assert!(parse_kebab_name("[constructor]a").is_some()); + assert!(parse_kebab_name("[method]a").is_none()); + assert!(parse_kebab_name("[method]a.b").is_some()); + assert!(parse_kebab_name("[method]a.b.c").is_none()); + assert!(parse_kebab_name("[static]a.b").is_some()); + assert!(parse_kebab_name("[static]a").is_none()); } #[test] fn name_equality() { - assert_eq!(KebabName::new("a"), KebabName::new("a")); - assert_ne!(KebabName::new("a"), KebabName::new("b")); + assert_eq!(parse_kebab_name("a"), parse_kebab_name("a")); + assert_ne!(parse_kebab_name("a"), parse_kebab_name("b")); + assert_eq!( + parse_kebab_name("[constructor]a"), + parse_kebab_name("[constructor]a") + ); + assert_ne!( + parse_kebab_name("[constructor]a"), + parse_kebab_name("[constructor]b") + ); + assert_eq!( + parse_kebab_name("[method]a.b"), + parse_kebab_name("[method]a.b") + ); + assert_ne!( + parse_kebab_name("[method]a.b"), + parse_kebab_name("[method]b.b") + ); assert_eq!( - KebabName::new("[constructor]a"), - KebabName::new("[constructor]a") + parse_kebab_name("[static]a.b"), + parse_kebab_name("[static]a.b") ); assert_ne!( - KebabName::new("[constructor]a"), - KebabName::new("[constructor]b") + parse_kebab_name("[static]a.b"), + parse_kebab_name("[static]b.b") ); - assert_eq!(KebabName::new("[method]a.b"), KebabName::new("[method]a.b")); - assert_ne!(KebabName::new("[method]a.b"), KebabName::new("[method]b.b")); - assert_eq!(KebabName::new("[static]a.b"), KebabName::new("[static]a.b")); - assert_ne!(KebabName::new("[static]a.b"), KebabName::new("[static]b.b")); - assert_eq!(KebabName::new("[static]a.b"), KebabName::new("[method]a.b")); - assert_eq!(KebabName::new("[method]a.b"), KebabName::new("[static]a.b")); + assert_eq!( + parse_kebab_name("[static]a.b"), + parse_kebab_name("[method]a.b") + ); + assert_eq!( + parse_kebab_name("[method]a.b"), + parse_kebab_name("[static]a.b") + ); - assert_ne!(KebabName::new("[method]b.b"), KebabName::new("[static]a.b")); + assert_ne!( + parse_kebab_name("[method]b.b"), + parse_kebab_name("[static]a.b") + ); let mut s = HashSet::new(); - assert!(s.insert(KebabName::new("a"))); - assert!(s.insert(KebabName::new("[constructor]a"))); - assert!(s.insert(KebabName::new("[method]a.b"))); - assert!(!s.insert(KebabName::new("[static]a.b"))); - assert!(s.insert(KebabName::new("[static]b.b"))); + assert!(s.insert(parse_kebab_name("a"))); + assert!(s.insert(parse_kebab_name("[constructor]a"))); + assert!(s.insert(parse_kebab_name("[method]a.b"))); + assert!(!s.insert(parse_kebab_name("[static]a.b"))); + assert!(s.insert(parse_kebab_name("[static]b.b"))); } } diff --git a/crates/wasmparser/src/validator/types.rs b/crates/wasmparser/src/validator/types.rs index 9710b10694..ee4886be24 100644 --- a/crates/wasmparser/src/validator/types.rs +++ b/crates/wasmparser/src/validator/types.rs @@ -4,7 +4,7 @@ use super::{ component::{ComponentState, ExternKind}, core::Module, }; -use crate::validator::names::{KebabName, KebabString}; +use crate::validator::names::KebabString; use crate::{ ArrayType, BinaryReaderError, Export, ExternalKind, FuncType, GlobalType, Import, MemoryType, PrimitiveValType, RefType, Result, TableType, TypeRef, ValType, @@ -21,7 +21,6 @@ use std::{ ops::{Deref, DerefMut}, sync::Arc, }; -use url::Url; /// The maximum number of parameters in the canonical ABI that can be passed by value. /// @@ -533,13 +532,13 @@ pub struct ComponentType { /// /// Each import has its own kebab-name and an optional URL listed. Note that /// the set of import names is disjoint with the set of export names. - pub imports: IndexMap, ComponentEntityType)>, + pub imports: IndexMap, /// The exports of the component type. /// /// Each export has its own kebab-name and an optional URL listed. Note that /// the set of export names is disjoint with the set of import names. - pub exports: IndexMap, ComponentEntityType)>, + pub exports: IndexMap, /// Universally quantified resources required to be provided when /// instantiating this component type. @@ -588,7 +587,7 @@ pub struct ComponentInstanceType { /// The list of exports, keyed by name, that this instance has. /// /// An optional URL and type of each export is provided as well. - pub exports: IndexMap, ComponentEntityType)>, + pub exports: IndexMap, /// The list of "defined resources" or those which are closed over in /// this instance type. @@ -1245,13 +1244,18 @@ impl<'a> TypesRef<'a> { } /// Gets the component entity type for the given component import. - pub fn component_entity_type_of_extern(&self, name: &str) -> Option { + pub fn component_entity_type_of_import(&self, name: &str) -> Option { match &self.kind { TypesRefKind::Module(_) => None, - TypesRefKind::Component(component) => { - let key = KebabName::new(name.to_string())?; - Some(component.externs.get(&key)?.1) - } + TypesRefKind::Component(component) => Some(*component.imports.get(name)?), + } + } + + /// Gets the component entity type for the given component export. + pub fn component_entity_type_of_export(&self, name: &str) -> Option { + match &self.kind { + TypesRefKind::Module(_) => None, + TypesRefKind::Component(component) => Some(*component.exports.get(name)?), } } } @@ -1513,10 +1517,14 @@ impl Types { self.as_ref().entity_type_from_export(export) } - /// Gets the component entity type for the given component import or export - /// name. - pub fn component_entity_type_of_extern(&self, name: &str) -> Option { - self.as_ref().component_entity_type_of_extern(name) + /// Gets the component entity type for the given component import name. + pub fn component_entity_type_of_import(&self, name: &str) -> Option { + self.as_ref().component_entity_type_of_import(name) + } + + /// Gets the component entity type for the given component export name. + pub fn component_entity_type_of_export(&self, name: &str) -> Option { + self.as_ref().component_entity_type_of_export(name) } /// Attempts to lookup the type id that `ty` is an alias of. @@ -1802,7 +1810,7 @@ impl TypeAlloc { // defined resources, so doing this all in one go should be // equivalent. Type::Component(i) => { - for (_, ty) in i.imports.values().chain(i.exports.values()) { + for ty in i.imports.values().chain(i.exports.values()) { self.free_variables_component_entity(ty, set); } for (id, _path) in i.imported_resources.iter().chain(&i.defined_resources) { @@ -1814,7 +1822,7 @@ impl TypeAlloc { // types but then remove those defined by this component instance // itself. Type::ComponentInstance(i) => { - for (_, ty) in i.exports.values() { + for ty in i.exports.values() { self.free_variables_component_entity(ty, set); } for id in i.defined_resources.iter() { @@ -2014,7 +2022,7 @@ pub(crate) trait Remap: Index { Type::Component(i) => { let mut tmp = i.clone(); - for (_, ty) in tmp.imports.values_mut().chain(tmp.exports.values_mut()) { + for ty in tmp.imports.values_mut().chain(tmp.exports.values_mut()) { if self.remap_component_entity(ty, map) { any_changed = true; } @@ -2035,7 +2043,7 @@ pub(crate) trait Remap: Index { Type::ComponentInstance(i) => { let mut tmp = i.clone(); - for (_, ty) in tmp.exports.values_mut() { + for ty in tmp.exports.values_mut() { if self.remap_component_entity(ty, map) { any_changed = true; } @@ -2397,9 +2405,9 @@ impl<'a> SubtypeCx<'a> { let b = self.b[*b_id].as_component_instance_type().unwrap(); let mut exports = Vec::with_capacity(b.exports.len()); - for (k, (_, b)) in b.exports.iter() { + for (k, b) in b.exports.iter() { match a.exports.get(k) { - Some((_, a)) => exports.push((*a, *b)), + Some(a) => exports.push((*a, *b)), None => bail!(offset, "missing expected export `{k}`"), } } @@ -2483,7 +2491,7 @@ impl<'a> SubtypeCx<'a> { .unwrap() .imports .iter() - .map(|(name, (_url, ty))| (name.clone(), ty.clone())) + .map(|(name, ty)| (name.clone(), ty.clone())) .collect(); self.swap(); let mut import_mapping = @@ -2495,7 +2503,7 @@ impl<'a> SubtypeCx<'a> { .unwrap() .exports .iter() - .map(|(name, (_url, ty))| (name.clone(), ty.clone())) + .map(|(name, ty)| (name.clone(), ty.clone())) .collect::>(); for ty in a_exports.values_mut() { this.a.remap_component_entity(ty, &mut import_mapping); @@ -2533,7 +2541,7 @@ impl<'a> SubtypeCx<'a> { /// `ExternKind::Import` or all defined resources for `ExternKind::Export`). pub fn open_instance_type( &mut self, - a: &IndexMap, + a: &IndexMap, b: TypeId, kind: ExternKind, offset: usize, @@ -2580,7 +2588,8 @@ impl<'a> SubtypeCx<'a> { 'outer: for (resource, path) in resources.iter() { // Lookup the first path item in `imports` and the corresponding // entry in `args` by name. - let (name, (_url, mut ty)) = entities.get_index(path[0]).unwrap(); + let (name, ty) = entities.get_index(path[0]).unwrap(); + let mut ty = *ty; let mut arg = a.get(name); // Lookup all the subsequent `path` entries, if any, by index in @@ -2591,7 +2600,7 @@ impl<'a> SubtypeCx<'a> { ComponentEntityType::Instance(id) => id, _ => unreachable!(), }; - let (name, (_url, next_ty)) = self.b[id] + let (name, next_ty) = self.b[id] .as_component_instance_type() .unwrap() .exports @@ -2603,8 +2612,7 @@ impl<'a> SubtypeCx<'a> { .as_component_instance_type() .unwrap() .exports - .get(name) - .map(|(_url, ty)| ty), + .get(name), _ => continue 'outer, }; } @@ -2644,7 +2652,7 @@ impl<'a> SubtypeCx<'a> { // values from `a` to expected items in `b`. Once the list is created // the substitution check is performed on each element. let mut to_typecheck = Vec::new(); - for (name, (_, expected)) in entities.iter() { + for (name, expected) in entities.iter() { match a.get(name) { Some(arg) => to_typecheck.push((arg.clone(), expected.clone())), None => bail!(offset, "missing {} named `{name}`", kind.desc()), diff --git a/crates/wasmprinter/src/lib.rs b/crates/wasmprinter/src/lib.rs index bdf678a38a..f36e70f169 100644 --- a/crates/wasmprinter/src/lib.rs +++ b/crates/wasmprinter/src/lib.rs @@ -1613,14 +1613,10 @@ impl Printer { ComponentTypeDeclaration::Alias(alias) => { self.print_component_alias(states, alias)?; } - ComponentTypeDeclaration::Export { name, url, ty } => { + ComponentTypeDeclaration::Export { name, ty } => { self.start_group("export "); self.print_component_kind_name(states.last_mut().unwrap(), ty.kind())?; - self.print_str(name)?; - if !url.is_empty() { - self.result.push(' '); - self.print_str(url)?; - } + self.print_component_import_name(name.into())?; self.result.push(' '); self.print_component_import_ty(states.last_mut().unwrap(), &ty, false)?; self.end_group(); @@ -1651,14 +1647,10 @@ impl Printer { InstanceTypeDeclaration::Alias(alias) => { self.print_component_alias(states, alias)?; } - InstanceTypeDeclaration::Export { name, url, ty } => { + InstanceTypeDeclaration::Export { name, ty } => { self.start_group("export "); self.print_component_kind_name(states.last_mut().unwrap(), ty.kind())?; - self.print_str(name)?; - if !url.is_empty() { - self.result.push(' '); - self.print_str(url)?; - } + self.print_component_import_name(name.into())?; self.result.push(' '); self.print_component_import_ty(states.last_mut().unwrap(), &ty, false)?; self.end_group(); @@ -1822,17 +1814,25 @@ impl Printer { index: bool, ) -> Result<()> { self.start_group("import "); - self.print_str(import.name)?; - if !import.url.is_empty() { - self.result.push(' '); - self.print_str(import.url)?; - } + self.print_component_import_name(import.name)?; self.result.push(' '); self.print_component_import_ty(state, &import.ty, index)?; self.end_group(); Ok(()) } + fn print_component_import_name(&mut self, name: ComponentExternName<'_>) -> Result<()> { + match name { + ComponentExternName::Kebab(s) => self.print_str(s), + ComponentExternName::Interface(s) => { + self.start_group("interface "); + self.print_str(s)?; + self.end_group(); + Ok(()) + } + } + } + fn print_component_import_ty( &mut self, state: &mut State, @@ -1941,11 +1941,7 @@ impl Printer { if named { self.print_component_kind_name(state, export.kind)?; } - self.print_str(export.name)?; - if !export.url.is_empty() { - self.result.push(' '); - self.print_str(export.url)?; - } + self.print_component_import_name(export.name.into())?; self.result.push(' '); self.print_component_external_kind(state, export.kind, export.index)?; if let Some(ty) = &export.ty { diff --git a/crates/wast/src/component/binary.rs b/crates/wast/src/component/binary.rs index d58b9e62be..8572892dfc 100644 --- a/crates/wast/src/component/binary.rs +++ b/crates/wast/src/component/binary.rs @@ -262,7 +262,7 @@ impl<'a> Encoder<'a> { InstanceKind::BundleOfExports(exports) => { self.instances.export_items(exports.iter().map(|e| { let (kind, index) = (&e.kind).into(); - (e.name, kind, index) + (e.name.into(), kind, index) })); } } @@ -342,8 +342,7 @@ impl<'a> Encoder<'a> { let name = get_name(&import.item.id, &import.item.name); self.names_for_item_kind(&import.item.kind).push(name); self.imports.import( - import.name, - import.url.unwrap_or(""), + wasm_encoder::ComponentExternName::from(import.name), (&import.item.kind).into(), ); self.flush(Some(self.imports.id())); @@ -353,8 +352,7 @@ impl<'a> Encoder<'a> { let name = get_name(&export.id, &export.debug_name); let (kind, index) = (&export.kind).into(); self.exports.export( - export.name, - export.url.unwrap_or(""), + wasm_encoder::ComponentExternName::from(export.name), kind, index, export.ty.as_ref().map(|ty| (&ty.0.kind).into()), @@ -820,10 +818,16 @@ impl From<&ComponentType<'_>> for wasm_encoder::ComponentType { encoded.alias((&a.target).into()); } ComponentTypeDecl::Import(i) => { - encoded.import(i.name, i.url.unwrap_or(""), (&i.item.kind).into()); + encoded.import( + wasm_encoder::ComponentExternName::from(i.name), + (&i.item.kind).into(), + ); } ComponentTypeDecl::Export(e) => { - encoded.export(e.name, e.url.unwrap_or(""), (&e.item.kind).into()); + encoded.export( + wasm_encoder::ComponentExternName::from(e.name), + (&e.item.kind).into(), + ); } } } @@ -848,7 +852,10 @@ impl From<&InstanceType<'_>> for wasm_encoder::InstanceType { encoded.alias((&a.target).into()); } InstanceTypeDecl::Export(e) => { - encoded.export(e.name, e.url.unwrap_or(""), (&e.item.kind).into()); + encoded.export( + wasm_encoder::ComponentExternName::from(e.name), + (&e.item.kind).into(), + ); } } } @@ -991,3 +998,12 @@ impl<'a> From<&AliasTarget<'a>> for wasm_encoder::Alias<'a> { } } } + +impl<'a> From> for wasm_encoder::ComponentExternName<'a> { + fn from(name: ComponentExternName<'a>) -> Self { + match name { + ComponentExternName::Kebab(name) => Self::Kebab(name), + ComponentExternName::Interface(name) => Self::Interface(name), + } + } +} diff --git a/crates/wast/src/component/expand.rs b/crates/wast/src/component/expand.rs index a35104127a..54c77ded83 100644 --- a/crates/wast/src/component/expand.rs +++ b/crates/wast/src/component/expand.rs @@ -136,7 +136,7 @@ impl<'a> Expander<'a> { } fn expand_core_module(&mut self, module: &mut CoreModule<'a>) -> Option> { - for (name, url) in module.exports.names.drain(..) { + for name in module.exports.names.drain(..) { let id = gensym::fill(module.span, &mut module.id); self.component_fields_to_append .push(ComponentField::Export(ComponentExport { @@ -144,7 +144,6 @@ impl<'a> Expander<'a> { id: None, debug_name: None, name, - url, kind: ComponentExportKind::module(module.span, id), ty: None, })); @@ -157,7 +156,6 @@ impl<'a> Expander<'a> { Some(ComponentField::Import(ComponentImport { span: module.span, name: import.name, - url: import.url, item: ItemSig { span: module.span, id: module.id, @@ -184,7 +182,7 @@ impl<'a> Expander<'a> { &mut self, component: &mut NestedComponent<'a>, ) -> Option> { - for (name, url) in component.exports.names.drain(..) { + for name in component.exports.names.drain(..) { let id = gensym::fill(component.span, &mut component.id); self.component_fields_to_append .push(ComponentField::Export(ComponentExport { @@ -192,7 +190,6 @@ impl<'a> Expander<'a> { id: None, debug_name: None, name, - url, kind: ComponentExportKind::component(component.span, id), ty: None, })); @@ -207,7 +204,6 @@ impl<'a> Expander<'a> { Some(ComponentField::Import(ComponentImport { span: component.span, name: import.name, - url: import.url, item: ItemSig { span: component.span, id: component.id, @@ -220,7 +216,7 @@ impl<'a> Expander<'a> { } fn expand_instance(&mut self, instance: &mut Instance<'a>) -> Option> { - for (name, url) in instance.exports.names.drain(..) { + for name in instance.exports.names.drain(..) { let id = gensym::fill(instance.span, &mut instance.id); self.component_fields_to_append .push(ComponentField::Export(ComponentExport { @@ -228,7 +224,6 @@ impl<'a> Expander<'a> { id: None, debug_name: None, name, - url, kind: ComponentExportKind::instance(instance.span, id), ty: None, })); @@ -239,7 +234,6 @@ impl<'a> Expander<'a> { Some(ComponentField::Import(ComponentImport { span: instance.span, name: import.name, - url: import.url, item: ItemSig { span: instance.span, id: instance.id, @@ -316,7 +310,7 @@ impl<'a> Expander<'a> { } fn expand_func(&mut self, func: &mut Func<'a>) -> Option> { - for (name, url) in func.exports.names.drain(..) { + for name in func.exports.names.drain(..) { let id = gensym::fill(func.span, &mut func.id); self.component_fields_to_append .push(ComponentField::Export(ComponentExport { @@ -324,7 +318,6 @@ impl<'a> Expander<'a> { id: None, debug_name: None, name, - url, kind: ComponentExportKind::func(func.span, id), ty: None, })); @@ -335,7 +328,6 @@ impl<'a> Expander<'a> { Some(ComponentField::Import(ComponentImport { span: func.span, name: import.name, - url: import.url, item: ItemSig { span: func.span, id: func.id, @@ -401,14 +393,13 @@ impl<'a> Expander<'a> { TypeDef::Instance(t) => t.key().insert(self, index), TypeDef::Resource(_) => {} } - for (name, url) in field.exports.names.drain(..) { + for name in field.exports.names.drain(..) { self.component_fields_to_append .push(ComponentField::Export(ComponentExport { span: field.span, id: None, debug_name: None, name, - url, kind: ComponentExportKind::ty(field.span, id), ty: None, })); diff --git a/crates/wast/src/component/export.rs b/crates/wast/src/component/export.rs index ce9baaf453..a83ec522e7 100644 --- a/crates/wast/src/component/export.rs +++ b/crates/wast/src/component/export.rs @@ -1,4 +1,4 @@ -use super::{ItemRef, ItemSigNoName}; +use super::{ComponentExternName, ItemRef, ItemSigNoName}; use crate::kw; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; use crate::token::{Id, Index, NameAnnotation, Span}; @@ -13,9 +13,7 @@ pub struct ComponentExport<'a> { /// An optional name for this instance stored in the custom `name` section. pub debug_name: Option>, /// The name of this export from the component. - pub name: &'a str, - /// The URL of the export. - pub url: Option<&'a str>, + pub name: ComponentExternName<'a>, /// The kind of export. pub kind: ComponentExportKind<'a>, /// The kind of export. @@ -28,7 +26,6 @@ impl<'a> Parse<'a> for ComponentExport<'a> { let id = parser.parse()?; let debug_name = parser.parse()?; let name = parser.parse()?; - let url = parser.parse()?; let kind = parser.parse()?; let ty = if !parser.is_empty() { Some(parser.parens(|p| p.parse())?) @@ -40,7 +37,6 @@ impl<'a> Parse<'a> for ComponentExport<'a> { id, debug_name, name, - url, kind, ty, }) @@ -177,7 +173,7 @@ impl Peek for ComponentExportKind<'_> { #[derive(Debug, Default)] pub struct InlineExport<'a> { /// The extra names to export an item as, if any. - pub names: Vec<(&'a str, Option<&'a str>)>, + pub names: Vec>, } impl<'a> Parse<'a> for InlineExport<'a> { @@ -186,7 +182,7 @@ impl<'a> Parse<'a> for InlineExport<'a> { while parser.peek::() { names.push(parser.parens(|p| { p.parse::()?; - Ok((p.parse()?, p.parse()?)) + p.parse() })?); } Ok(InlineExport { names }) @@ -203,15 +199,29 @@ impl Peek for InlineExport<'_> { Some(("export", cursor)) => cursor, _ => return false, }; - // Name - let mut cursor = match cursor.string() { - Some((_, cursor)) => cursor, + + // (export "foo") + if let Some((_, cursor)) = cursor.string() { + return cursor.rparen().is_some(); + } + + // (export (interface "foo")) + let cursor = match cursor.lparen() { + Some(cursor) => cursor, None => return false, }; - // Optional URL - if let Some((_, c)) = cursor.string() { - cursor = c; - } + let cursor = match cursor.keyword() { + Some(("interface", cursor)) => cursor, + _ => return false, + }; + let cursor = match cursor.string() { + Some((_, cursor)) => cursor, + _ => return false, + }; + let cursor = match cursor.rparen() { + Some(cursor) => cursor, + _ => return false, + }; cursor.rparen().is_some() } diff --git a/crates/wast/src/component/import.rs b/crates/wast/src/component/import.rs index c8bed1cdfd..dad83166c7 100644 --- a/crates/wast/src/component/import.rs +++ b/crates/wast/src/component/import.rs @@ -1,18 +1,15 @@ use crate::component::*; use crate::kw; use crate::parser::{Cursor, Parse, Parser, Peek, Result}; -use crate::token::Index; -use crate::token::{Id, NameAnnotation, Span}; +use crate::token::{Id, Index, LParen, NameAnnotation, Span}; /// An `import` statement and entry in a WebAssembly component. #[derive(Debug)] pub struct ComponentImport<'a> { /// Where this `import` was defined pub span: Span, - /// The name of the item to import. - pub name: &'a str, - /// The optional URL of the import. - pub url: Option<&'a str>, + /// The name of the item being imported. + pub name: ComponentExternName<'a>, /// The item that's being imported. pub item: ItemSig<'a>, } @@ -21,14 +18,30 @@ impl<'a> Parse<'a> for ComponentImport<'a> { fn parse(parser: Parser<'a>) -> Result { let span = parser.parse::()?.0; let name = parser.parse()?; - let url = parser.parse()?; let item = parser.parens(|p| p.parse())?; - Ok(ComponentImport { - span, - name, - url, - item, - }) + Ok(ComponentImport { span, name, item }) + } +} + +/// The different ways an import can be named. +#[derive(Debug, Copy, Clone)] +pub enum ComponentExternName<'a> { + /// This is a kebab-named import where a top-level name is assigned. + Kebab(&'a str), + /// This is an interface import where the string is an ID. + Interface(&'a str), +} + +impl<'a> Parse<'a> for ComponentExternName<'a> { + fn parse(parser: Parser<'a>) -> Result { + if parser.peek::() { + Ok(ComponentExternName::Interface(parser.parens(|p| { + p.parse::()?; + p.parse() + })?)) + } else { + Ok(ComponentExternName::Kebab(parser.parse()?)) + } } } @@ -146,19 +159,14 @@ impl<'a> Parse<'a> for TypeBounds<'a> { #[derive(Debug, Clone)] pub struct InlineImport<'a> { /// The name of the item being imported. - pub name: &'a str, - /// The optional URL of the item being imported. - pub url: Option<&'a str>, + pub name: ComponentExternName<'a>, } impl<'a> Parse<'a> for InlineImport<'a> { fn parse(parser: Parser<'a>) -> Result { parser.parens(|p| { p.parse::()?; - Ok(InlineImport { - name: p.parse()?, - url: p.parse()?, - }) + Ok(InlineImport { name: p.parse()? }) }) } } @@ -173,9 +181,28 @@ impl Peek for InlineImport<'_> { Some(("import", cursor)) => cursor, _ => return false, }; + + // (import "foo") + if let Some((_, cursor)) = cursor.string() { + return cursor.rparen().is_some(); + } + + // (import (interface "foo")) + let cursor = match cursor.lparen() { + Some(cursor) => cursor, + None => return false, + }; + let cursor = match cursor.keyword() { + Some(("interface", cursor)) => cursor, + _ => return false, + }; let cursor = match cursor.string() { Some((_, cursor)) => cursor, - None => return false, + _ => return false, + }; + let cursor = match cursor.rparen() { + Some(cursor) => cursor, + _ => return false, }; cursor.rparen().is_some() } diff --git a/crates/wast/src/component/types.rs b/crates/wast/src/component/types.rs index 8c8698b2ca..9e40ef7049 100644 --- a/crates/wast/src/component/types.rs +++ b/crates/wast/src/component/types.rs @@ -768,9 +768,7 @@ pub struct ComponentExportType<'a> { /// Where this export was defined. pub span: Span, /// The name of this export. - pub name: &'a str, - /// The optional URL of this export. - pub url: Option<&'a str>, + pub name: ComponentExternName<'a>, /// The signature of the item. pub item: ItemSig<'a>, } @@ -781,19 +779,13 @@ impl<'a> Parse<'a> for ComponentExportType<'a> { let id = parser.parse()?; let debug_name = parser.parse()?; let name = parser.parse()?; - let url = parser.parse()?; let item = parser.parens(|p| { let mut item = p.parse::>()?.0; item.id = id; item.name = debug_name; Ok(item) })?; - Ok(Self { - span, - name, - url, - item, - }) + Ok(Self { span, name, item }) } } diff --git a/crates/wast/src/lib.rs b/crates/wast/src/lib.rs index 045ea96b36..b1079b83ad 100644 --- a/crates/wast/src/lib.rs +++ b/crates/wast/src/lib.rs @@ -432,6 +432,7 @@ pub mod kw { custom_keyword!(import); custom_keyword!(instance); custom_keyword!(instantiate); + custom_keyword!(interface); custom_keyword!(invoke); custom_keyword!(item); custom_keyword!(last); diff --git a/crates/wit-component/Cargo.toml b/crates/wit-component/Cargo.toml index 3394b152b7..1ddca87c75 100644 --- a/crates/wit-component/Cargo.toml +++ b/crates/wit-component/Cargo.toml @@ -21,7 +21,6 @@ anyhow = { workspace = true } log = "0.4.17" bitflags = "1.3.2" indexmap = { workspace = true } -url = { workspace = true } wat = { workspace = true, optional = true } [dev-dependencies] diff --git a/crates/wit-component/src/builder.rs b/crates/wit-component/src/builder.rs index 45e429af2e..ce7a96c425 100644 --- a/crates/wit-component/src/builder.rs +++ b/crates/wit-component/src/builder.rs @@ -124,12 +124,11 @@ impl ComponentBuilder { pub fn export( &mut self, name: &str, - url: &str, kind: ComponentExportKind, idx: u32, ty: Option, ) -> u32 { - self.exports().export(name, url, kind, idx, ty); + self.exports().export(name, kind, idx, ty); match kind { ComponentExportKind::Type => inc(&mut self.types), ComponentExportKind::Func => inc(&mut self.funcs), @@ -139,14 +138,14 @@ impl ComponentBuilder { } } - pub fn import(&mut self, name: &str, url: &str, ty: ComponentTypeRef) -> u32 { + pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> u32 { let ret = match &ty { ComponentTypeRef::Instance(_) => inc(&mut self.instances), ComponentTypeRef::Func(_) => inc(&mut self.funcs), ComponentTypeRef::Type(..) => inc(&mut self.types), _ => unimplemented!(), }; - self.imports().import(name, url, ty); + self.imports().import(name, ty); ret } diff --git a/crates/wit-component/src/decoding.rs b/crates/wit-component/src/decoding.rs index 00037bff68..109b19cb5b 100644 --- a/crates/wit-component/src/decoding.rs +++ b/crates/wit-component/src/decoding.rs @@ -2,10 +2,10 @@ use anyhow::{anyhow, bail, Context, Result}; use indexmap::{IndexMap, IndexSet}; use std::collections::HashMap; use std::mem; -use url::Url; use wasmparser::{ - types, ComponentExport, ComponentExternalKind, ComponentImport, Parser, Payload, - PrimitiveValType, ValidPayload, Validator, WasmFeatures, + names::{KebabName, KebabNameKind}, + types, ComponentExport, ComponentExternName, ComponentExternalKind, ComponentImport, Parser, + Payload, PrimitiveValType, ValidPayload, Validator, WasmFeatures, }; use wit_parser::*; @@ -15,7 +15,7 @@ struct ComponentInfo<'a> { /// validated. types: types::Types, /// List of all imports and exports from this component. - externs: Vec<(&'a str, Extern<'a>)>, + externs: Vec<(ComponentExternName<'a>, Extern<'a>)>, } enum Extern<'a> { @@ -58,7 +58,7 @@ impl<'a> ComponentInfo<'a> { Payload::ComponentExportSection(s) if depth == 1 => { for export in s { let export = export?; - externs.push((export.name, Extern::Export(export))); + externs.push((export.name.into(), Extern::Export(export))); } } _ => {} @@ -89,19 +89,20 @@ impl<'a> ComponentInfo<'a> { }) } - fn decode_wit_package(&self, name: &str) -> Result<(Resolve, PackageId)> { + fn decode_wit_package(&self) -> Result<(Resolve, PackageId)> { assert!(self.is_wit_package()); let resolve = Resolve::default(); let mut decoder = WitPackageDecoder { resolve, info: self, - url_to_package: IndexMap::default(), type_map: HashMap::new(), - url_to_interface: HashMap::new(), + foreign_packages: Default::default(), + iface_to_package_index: Default::default(), + named_interfaces: Default::default(), }; - let mut docs = Vec::new(); - for (doc, item) in self.externs.iter() { + let mut pkg = None; + for (name, item) in self.externs.iter() { let export = match item { Extern::Export(e) => e, _ => unreachable!(), @@ -110,159 +111,69 @@ impl<'a> ComponentInfo<'a> { Some(types::Type::Component(ty)) => ty, _ => unreachable!(), }; - let id = decoder - .decode_document(doc, ty) - .with_context(|| format!("failed to decode document `{doc}`"))?; - docs.push((doc, id)); + if pkg.is_some() { + bail!("more than one top-level exported component type found"); + } + let name = KebabName::new(*name, 0).unwrap(); + pkg = Some( + decoder + .decode_package(&name, ty) + .with_context(|| format!("failed to decode document `{name}`"))?, + ); } - let (resolve, package) = decoder.finish(Package { - name: name.to_string(), - documents: docs - .iter() - .map(|(name, d)| (name.to_string(), *d)) - .collect(), - url: None, - }); - + let pkg = pkg.ok_or_else(|| anyhow!("no exported component type found"))?; + let (resolve, package) = decoder.finish(pkg); Ok((resolve, package)) } - fn decode_component(&self, name: &str) -> Result<(Resolve, WorldId)> { + fn decode_component(&self) -> Result<(Resolve, WorldId)> { assert!(!self.is_wit_package()); let mut resolve = Resolve::default(); - let doc = resolve.documents.alloc(Document { - name: "root".to_string(), - interfaces: Default::default(), - worlds: Default::default(), - default_interface: None, - default_world: None, - package: None, - }); + // Note that this name is arbitrarily chosen. We may one day perhaps + // want to encode this in the component binary format itself, but for + // now it shouldn't be an issue to have a defaulted name here. + let world_name = "root"; let world = resolve.worlds.alloc(World { - name: name.to_string(), + name: world_name.to_string(), docs: Default::default(), imports: Default::default(), exports: Default::default(), - document: doc, + package: None, }); - resolve.documents[doc] - .worlds - .insert(name.to_string(), world); - resolve.documents[doc].default_world = Some(world); let mut decoder = WitPackageDecoder { resolve, info: self, - url_to_package: IndexMap::default(), type_map: HashMap::new(), - url_to_interface: HashMap::new(), + foreign_packages: Default::default(), + iface_to_package_index: Default::default(), + named_interfaces: Default::default(), + }; + let mut package = Package { + // Similar to `world_name` above this is arbitrarily chosen as it's + // not otherwise encoded in a binary component. This theoretically + // shouldn't cause issues, however. + name: PackageName { + namespace: "root".to_string(), + version: None, + name: "component".to_string(), + }, + worlds: [(world_name.to_string(), world)].into_iter().collect(), + interfaces: Default::default(), }; - for (name, item) in self.externs.iter() { + for (_name, item) in self.externs.iter() { match item { Extern::Import(import) => { - let ty = self - .types - .component_entity_type_of_extern(import.name) - .unwrap(); - let item = match ty { - types::ComponentEntityType::Instance(i) => { - let ty = match self.types.type_from_id(i) { - Some(types::Type::ComponentInstance(ty)) => ty, - _ => unreachable!(), - }; - let id = decoder - .register_interface(doc, Some(name), ty) - .with_context(|| { - format!("failed to decode WIT from import `{name}`") - })?; - decoder.resolve.documents[doc] - .interfaces - .insert(name.to_string(), id); - WorldItem::Interface(id) - } - types::ComponentEntityType::Func(i) => { - let ty = match self.types.type_from_id(i) { - Some(types::Type::ComponentFunc(ty)) => ty, - _ => unreachable!(), - }; - let func = decoder.convert_function(name, ty).with_context(|| { - format!("failed to decode function from import `{name}`") - })?; - WorldItem::Function(func) - } - types::ComponentEntityType::Type { - referenced, - created, - } => { - let id = decoder - .register_type_export( - name, - TypeOwner::World(world), - referenced, - created, - ) - .with_context(|| { - format!("failed to decode type from export `{name}`") - })?; - WorldItem::Type(id) - } - // All other imports do not form part of the component's world - _ => continue, - }; - decoder.resolve.worlds[world] - .imports - .insert(name.to_string(), item); + decoder.decode_component_import(import, world, &mut package)? } - Extern::Export(export) => { - let ty = self - .types - .component_entity_type_of_extern(export.name) - .unwrap(); - let item = match ty { - types::ComponentEntityType::Func(i) => { - let ty = match self.types.type_from_id(i) { - Some(types::Type::ComponentFunc(ty)) => ty, - _ => unreachable!(), - }; - let func = decoder.convert_function(name, ty).with_context(|| { - format!("failed to decode function from export `{name}`") - })?; - - WorldItem::Function(func) - } - types::ComponentEntityType::Instance(i) => { - let ty = match self.types.type_from_id(i) { - Some(types::Type::ComponentInstance(ty)) => ty, - _ => unreachable!(), - }; - let id = decoder - .register_interface(doc, Some(name), ty) - .with_context(|| { - format!("failed to decode WIT from export `{name}`") - })?; - decoder.resolve.documents[doc] - .interfaces - .insert(name.to_string(), id); - WorldItem::Interface(id) - } - _ => { - bail!("component export `{name}` was not a function or instance") - } - }; - decoder.resolve.worlds[world] - .exports - .insert(name.to_string(), item); + decoder.decode_component_export(export, world, &mut package)? } } } - let (resolve, _) = decoder.finish(Package { - name: name.to_string(), - documents: [("root".to_string(), doc)].into_iter().collect(), - url: None, - }); + let (resolve, _) = decoder.finish(package); Ok((resolve, world)) } } @@ -294,10 +205,7 @@ impl DecodedWasm { pub fn package(&self) -> PackageId { match self { DecodedWasm::WitPackage(_, id) => *id, - DecodedWasm::Component(resolve, world) => { - let doc = resolve.worlds[*world].document; - resolve.documents[doc].package.unwrap() - } + DecodedWasm::Component(resolve, world) => resolve.worlds[*world].package.unwrap(), } } } @@ -308,14 +216,14 @@ impl DecodedWasm { /// The WebAssembly binary provided here can either be a /// WIT-package-encoded-as-binary or an actual component itself. A [`Resolve`] /// is always created and the return value indicates which was detected. -pub fn decode(name: &str, bytes: &[u8]) -> Result { +pub fn decode(bytes: &[u8]) -> Result { let info = ComponentInfo::new(bytes)?; if info.is_wit_package() { - let (resolve, pkg) = info.decode_wit_package(name)?; + let (resolve, pkg) = info.decode_wit_package()?; Ok(DecodedWasm::WitPackage(resolve, pkg)) } else { - let (resolve, world) = info.decode_component(name)?; + let (resolve, world) = info.decode_component()?; Ok(DecodedWasm::Component(resolve, world)) } } @@ -323,24 +231,19 @@ pub fn decode(name: &str, bytes: &[u8]) -> Result { struct WitPackageDecoder<'a> { resolve: Resolve, info: &'a ComponentInfo<'a>, - url_to_package: IndexMap, - url_to_interface: HashMap, + foreign_packages: IndexMap, + iface_to_package_index: HashMap, + named_interfaces: HashMap, /// A map from a type id to what it's been translated to. type_map: HashMap, } impl WitPackageDecoder<'_> { - fn decode_document(&mut self, name: &str, ty: &types::ComponentType) -> Result { - // Process all imports for this document first, where imports are either - // importing interfaces from previously defined documents or from remote - // packages. Note that the URL must be specified here for these - // reconstruction purposes. - for (name, (url, ty)) in ty.imports.iter() { - let url = match url { - Some(url) => url, - None => bail!("no url specified for import `{name}`"), - }; + fn decode_package(&mut self, name: &KebabName, ty: &types::ComponentType) -> Result { + // Process all imports for this package first, where imports are + // importing from remote packages. + for (name, ty) in ty.imports.iter() { let ty = match ty { types::ComponentEntityType::Instance(idx) => { match self.info.types.type_from_id(*idx) { @@ -350,69 +253,171 @@ impl WitPackageDecoder<'_> { } _ => bail!("import `{name}` is not an instance"), }; - self.register_import(url, ty) + self.register_import(name, ty) .with_context(|| format!("failed to process import `{name}`"))?; } - let doc = self.resolve.documents.alloc(Document { - name: name.to_string(), - interfaces: IndexMap::new(), - worlds: IndexMap::new(), - default_interface: None, - default_world: None, - package: None, - }); + let mut package = Package { + // The name encoded for packages must be of the form `foo:bar/wit` + // where "wit" is just a placeholder for now. The package name in + // this case would be `foo:bar`. + name: match name.kind() { + KebabNameKind::Id { + namespace, + package, + version, + interface, + } if interface.as_str() == "wit" => PackageName { + namespace: namespace.to_string(), + name: package.to_string(), + version, + }, + _ => bail!("package name is not a valid id: {name}"), + }, + interfaces: Default::default(), + worlds: Default::default(), + }; - for (name, (url, ty)) in ty.exports.iter() { + for (name, ty) in ty.exports.iter() { match ty { types::ComponentEntityType::Instance(idx) => { let ty = match self.info.types.type_from_id(*idx) { Some(types::Type::ComponentInstance(ty)) => ty, _ => unreachable!(), }; - let id = self - .register_interface(doc, Some(name.as_str()), ty) + self.register_interface(name.as_str(), ty, &mut package) .with_context(|| format!("failed to process export `{name}`"))?; - let prev = self.resolve.documents[doc] - .interfaces - .insert(name.to_string(), id); - assert!(prev.is_none()); - if let Some(url) = url { - let prev = self.url_to_interface.insert(url.clone(), id); - assert!(prev.is_none()); - } } types::ComponentEntityType::Component(idx) => { let ty = match self.info.types.type_from_id(*idx) { Some(types::Type::Component(ty)) => ty, _ => unreachable!(), }; - let id = self - .register_world(doc, name.as_str(), ty) + self.register_world(name.as_str(), ty, &mut package) .with_context(|| format!("failed to process export `{name}`"))?; - let prev = self.resolve.documents[doc] - .worlds - .insert(name.to_string(), id); - assert!(prev.is_none()); } _ => bail!("component export `{name}` is not an instance or component"), } } - Ok(doc) + Ok(package) + } + + fn decode_component_import( + &mut self, + import: &ComponentImport<'_>, + world: WorldId, + package: &mut Package, + ) -> Result<()> { + let name = import.name.as_str(); + let ty = self + .info + .types + .component_entity_type_of_import(import.name.as_str()) + .unwrap(); + let (name, item) = match ty { + types::ComponentEntityType::Instance(i) => { + let ty = match self.info.types.type_from_id(i) { + Some(types::Type::ComponentInstance(ty)) => ty, + _ => unreachable!(), + }; + let (name, id) = if name.contains('/') { + let id = self.register_import(name, ty)?; + (WorldKey::Interface(id), id) + } else { + self.register_interface(name, ty, package) + .with_context(|| format!("failed to decode WIT from import `{name}`"))? + }; + (name, WorldItem::Interface(id)) + } + types::ComponentEntityType::Func(i) => { + let ty = match self.info.types.type_from_id(i) { + Some(types::Type::ComponentFunc(ty)) => ty, + _ => unreachable!(), + }; + let func = self + .convert_function(name, ty) + .with_context(|| format!("failed to decode function from import `{name}`"))?; + (WorldKey::Name(name.to_string()), WorldItem::Function(func)) + } + types::ComponentEntityType::Type { + referenced, + created, + } => { + let id = self + .register_type_export(name, TypeOwner::World(world), referenced, created) + .with_context(|| format!("failed to decode type from export `{name}`"))?; + (WorldKey::Name(name.to_string()), WorldItem::Type(id)) + } + // All other imports do not form part of the component's world + _ => return Ok(()), + }; + self.resolve.worlds[world].imports.insert(name, item); + Ok(()) + } + + fn decode_component_export( + &mut self, + export: &ComponentExport<'_>, + world: WorldId, + package: &mut Package, + ) -> Result<()> { + let name = export.name.as_str(); + let types = &self.info.types; + let ty = types.component_entity_type_of_export(name).unwrap(); + let (name, item) = match ty { + types::ComponentEntityType::Func(i) => { + let ty = match types.type_from_id(i) { + Some(types::Type::ComponentFunc(ty)) => ty, + _ => unreachable!(), + }; + let func = self + .convert_function(name, ty) + .with_context(|| format!("failed to decode function from export `{name}`"))?; + + (WorldKey::Name(name.to_string()), WorldItem::Function(func)) + } + types::ComponentEntityType::Instance(i) => { + let ty = match types.type_from_id(i) { + Some(types::Type::ComponentInstance(ty)) => ty, + _ => unreachable!(), + }; + let (name, id) = if name.contains('/') { + let id = self.register_import(name, ty)?; + (WorldKey::Interface(id), id) + } else { + self.register_interface(name, ty, package) + .with_context(|| format!("failed to decode WIT from export `{name}`"))? + }; + (name, WorldItem::Interface(id)) + } + _ => { + bail!("component export `{name}` was not a function or instance") + } + }; + self.resolve.worlds[world].exports.insert(name, item); + Ok(()) } + /// Registers that the `name` provided is either imported interface from a + /// foreign package or referencing a previously defined interface in this + /// package. + /// + /// This function will internally ensure that `name` is well-structured and + /// will fill in any information as necesary. For example with a foreign + /// dependency the foreign package structure, types, etc, all need to be + /// created. For a local dependency it's instead ensured that all the types + /// line up with the previous definitions. fn register_import( &mut self, - url: &Url, + name: &str, ty: &types::ComponentInstanceType, ) -> Result { - let interface = self.extract_url_interface(url)?; - - for (name, (export_url, ty)) in ty.exports.iter() { - if export_url.is_some() { - bail!("instance type export `{name}` should not have a url") - } + let (is_local, interface) = match self.named_interfaces.get(name) { + Some(id) => (true, *id), + None => (false, self.extract_dep_interface(name)?), + }; + for (name, ty) in ty.exports.iter() { match *ty { types::ComponentEntityType::Type { referenced, @@ -465,7 +470,7 @@ impl WitPackageDecoder<'_> { // slice needed for this resolve, which is what's // intended. None => { - if url.scheme() == "pkg" { + if is_local { bail!("instance type export `{name}` not defined in interface"); } let id = self.register_type_export( @@ -498,7 +503,7 @@ impl WitPackageDecoder<'_> { // match. continue; } - if url.scheme() == "pkg" { + if is_local { bail!("instance function export `{name}` not defined in interface"); } let func = self.convert_function(name.as_str(), def)?; @@ -534,69 +539,39 @@ impl WitPackageDecoder<'_> { prev } - fn extract_url_interface(&mut self, url: &Url) -> Result { - Ok(if url.scheme() == "pkg" { - self.url_to_interface - .get(url) - .copied() - .ok_or_else(|| anyhow!("no previously defined interface with url: {url}"))? + /// This will parse the `name_string` as a component model ID string and + /// ensure that there's an `InterfaceId` corresponding to its components. + fn extract_dep_interface(&mut self, name_string: &str) -> Result { + let import_name = if name_string.contains('/') { + ComponentExternName::Interface(name_string) } else { - self.extract_dep_interface(url) - .with_context(|| format!("failed to parse url: {url}"))? - }) - } - - /// TODO: Ideally this function should not need to exist. - /// - /// This function parses the `url` provided and requires it to have a - /// particular structure. That's not really great, however, since otherwise - /// there's no need to impose structure on the url field of imports/exports. - /// - /// Note that this is only used for foreign dependencies of which the binary - /// encoding does not currently reflect the package/document/interface - /// organization. Instead foreign dependencies simply have their interfaces - /// imported, and from this interface import we need to somehow translate - /// back into a package/document structure as well. - /// - /// Resolving this may require changing the binary format for components, or - /// otherwise encoding more pieces into the binary encoding of a WIT - /// document. In any case this is "good enough" for now hopefully. - fn extract_dep_interface(&mut self, url: &Url) -> Result { - // Extract the interface and the document from the url - let mut segments = url.path_segments().ok_or_else(|| anyhow!("invalid url"))?; - let interface = segments.next_back().ok_or_else(|| anyhow!("invalid url"))?; - let document = segments.next_back().ok_or_else(|| anyhow!("invalid url"))?; - let package_name = segments.next_back().ok_or_else(|| anyhow!("invalid url"))?; - - // Then drop the two path segments from the url as a key to lookup the - // dependency package by url. - let mut url = url.clone(); - url.path_segments_mut().unwrap().pop().pop(); - - // Lazily create a `Package` as necessary, along with the document and - // interface. + ComponentExternName::Kebab(name_string) + }; + let name = KebabName::new(import_name, 0).unwrap(); + let (namespace, name, version, interface) = match name.kind() { + KebabNameKind::Id { + namespace, + package, + version, + interface, + } => (namespace, package, version, interface), + _ => bail!("package name is not a valid id: {name_string}"), + }; + let package_name = PackageName { + name: name.to_string(), + namespace: namespace.to_string(), + version, + }; + // Lazily create a `Package` as necessary, along with the interface. let package = self - .url_to_package - .entry(url.clone()) + .foreign_packages + .entry(package_name.to_string()) .or_insert_with(|| Package { - name: package_name.to_string(), - documents: Default::default(), - url: Some(url.to_string()), + name: package_name.clone(), + interfaces: Default::default(), + worlds: Default::default(), }); - let doc = *package - .documents - .entry(document.to_string()) - .or_insert_with(|| { - self.resolve.documents.alloc(Document { - name: document.to_string(), - interfaces: IndexMap::new(), - worlds: IndexMap::new(), - default_interface: None, - default_world: None, - package: None, - }) - }); - let interface = *self.resolve.documents[doc] + let interface = *package .interfaces .entry(interface.to_string()) .or_insert_with(|| { @@ -605,31 +580,64 @@ impl WitPackageDecoder<'_> { docs: Default::default(), types: IndexMap::default(), functions: IndexMap::new(), - document: doc, + package: None, }) }); + + // Record a mapping of which foreign package this interface belongs to + self.iface_to_package_index.insert( + interface, + self.foreign_packages + .get_full(&package_name.to_string()) + .unwrap() + .0, + ); Ok(interface) } + /// A general-purpose helper function to translate a component instance + /// into a WIT interface. + /// + /// This is one of the main workhorses of this module. This handles + /// interfaces both at the type level, for concrete components, and + /// internally within worlds as well. + /// + /// The `name` provided is the contextual ID or name of the interface. This + /// could be a kebab-name in the case of a world import or export or it can + /// also be an ID. This is used to guide insertion into various maps. + /// + /// The `ty` provided is the actual component type being decoded. + /// + /// The `package` is where to insert the final interface if `name` is an ID + /// meaning it's registered as a named standalone item within the package. fn register_interface( &mut self, - doc: DocumentId, - name: Option<&str>, + name: &str, ty: &types::ComponentInstanceType, - ) -> Result { + package: &mut Package, + ) -> Result<(WorldKey, InterfaceId)> { + // If this interface's name is already known then that means this is an + // interface that's both imported and exported. Use `register_import` + // to draw connections between types and this interface's types. + if self.named_interfaces.contains_key(name) { + let id = self.register_import(name, ty)?; + return Ok((WorldKey::Interface(id), id)); + } + + // If this is a bare kebab-name for an interface then the interface's + // listed name is `None` and the name goes out through the key. + // Otherwise this name is extracted from `name` interpreted as an ID. + let interface_name = self.extract_interface_name_from_kebab_name(name)?; + let mut interface = Interface { - name: name.map(|n| n.to_string()), + name: interface_name.clone(), docs: Default::default(), types: IndexMap::default(), functions: IndexMap::new(), - document: doc, + package: None, }; - for (name, (export_url, ty)) in ty.exports.iter() { - if export_url.is_some() { - bail!("instance type export `{name}` should not have a url") - } - + for (name, ty) in ty.exports.iter() { match *ty { types::ComponentEntityType::Type { referenced, @@ -661,7 +669,38 @@ impl WitPackageDecoder<'_> { _ => bail!("instance type export `{name}` is not a type or function"), }; } - Ok(self.resolve.interfaces.alloc(interface)) + let id = self.resolve.interfaces.alloc(interface); + let key = match interface_name { + // If this interface is named then it's part of the package, so + // insert it. Additionally register it in `named_interfaces` so + // further use comes back to this original definition. + Some(interface_name) => { + let prev = package.interfaces.insert(interface_name, id); + assert!(prev.is_none(), "duplicate interface added for {name:?}"); + let prev = self.named_interfaces.insert(name.to_string(), id); + assert!(prev.is_none()); + WorldKey::Interface(id) + } + + // If this interface isn't named then its key is always a + // kebab-name. + None => WorldKey::Name(name.to_string()), + }; + Ok((key, id)) + } + + fn extract_interface_name_from_kebab_name(&self, name: &str) -> Result> { + let import_name = if name.contains('/') { + ComponentExternName::Interface(name) + } else { + ComponentExternName::Kebab(name) + }; + let kebab_name = KebabName::new(import_name, 0); + match kebab_name.as_ref().map(|k| k.kind()) { + Ok(KebabNameKind::Id { interface, .. }) => Ok(Some(interface.to_string())), + Ok(KebabNameKind::Normal(_name)) => Ok(None), + _ => bail!("cannot extract item name from: {name}"), + } } fn register_type_export( @@ -701,38 +740,42 @@ impl WitPackageDecoder<'_> { fn register_world( &mut self, - document: DocumentId, name: &str, ty: &types::ComponentType, + package: &mut Package, ) -> Result { + let name = self + .extract_interface_name_from_kebab_name(name)? + .context("expected world name to have an ID form")?; let mut world = World { - name: name.to_string(), + name: name.clone(), docs: Default::default(), imports: Default::default(), exports: Default::default(), - document, + package: None, }; - for (name, (url, ty)) in ty.imports.iter() { - let item = match ty { + for (name, ty) in ty.imports.iter() { + let (name, item) = match ty { types::ComponentEntityType::Instance(idx) => { let ty = match self.info.types.type_from_id(*idx) { Some(types::Type::ComponentInstance(ty)) => ty, _ => unreachable!(), }; - let id = match url { - // If a URL is specified then the import is either to a - // package-local or foreign interface, and both + let (name, id) = if name.contains("/") { + // If a name is an interface import then it is either to + // a package-local or foreign interface, and both // situations are handled in `register_import`. - Some(url) => self.register_import(url, ty)?, - - // Without a URL this indicates an inline interface that + let id = self.register_import(name, ty)?; + (WorldKey::Interface(id), id) + } else { + // A plain kebab-name indicates an inline interface that // wasn't declared explicitly elsewhere with a name, and // `register_interface` will create a new `Interface` // with no name. - None => self.register_interface(document, None, ty)?, + self.register_interface(name, ty, package)? }; - WorldItem::Interface(id) + (name, WorldItem::Interface(id)) } types::ComponentEntityType::Type { created, @@ -744,7 +787,7 @@ impl WitPackageDecoder<'_> { *referenced, *created, )?; - WorldItem::Type(ty) + (WorldKey::Name(name.to_string()), WorldItem::Type(ty)) } types::ComponentEntityType::Func(idx) => { let ty = match self.info.types.type_from_id(*idx) { @@ -752,31 +795,33 @@ impl WitPackageDecoder<'_> { _ => unreachable!(), }; let func = self.convert_function(name.as_str(), ty)?; - WorldItem::Function(func) + (WorldKey::Name(name.to_string()), WorldItem::Function(func)) } _ => bail!("component import `{name}` is not an instance, func, or type"), }; - world.imports.insert(name.to_string(), item); + world.imports.insert(name, item); } - for (name, (url, ty)) in ty.exports.iter() { - let item = match ty { + for (name, ty) in ty.exports.iter() { + let (name, item) = match ty { types::ComponentEntityType::Instance(idx) => { let ty = match self.info.types.type_from_id(*idx) { Some(types::Type::ComponentInstance(ty)) => ty, _ => unreachable!(), }; - let id = match url { + let (name, id) = if name.contains("/") { // Note that despite this being an export this is // calling `register_import`. With a URL this interface // must have been previously defined so this will // trigger the logic of either filling in a remotely // defined interface or connecting items to local // definitions of our own interface. - Some(url) => self.register_import(url, ty)?, - None => self.register_interface(document, None, ty)?, + let id = self.register_import(name, ty)?; + (WorldKey::Interface(id), id) + } else { + self.register_interface(name, ty, package)? }; - WorldItem::Interface(id) + (name, WorldItem::Interface(id)) } types::ComponentEntityType::Func(idx) => { @@ -785,14 +830,17 @@ impl WitPackageDecoder<'_> { _ => unreachable!(), }; let func = self.convert_function(name.as_str(), ty)?; - WorldItem::Function(func) + (WorldKey::Name(name.to_string()), WorldItem::Function(func)) } _ => bail!("component export `{name}` is not an instance or function"), }; - world.exports.insert(name.to_string(), item); + world.exports.insert(name, item); } - Ok(self.resolve.worlds.alloc(world)) + let id = self.resolve.worlds.alloc(world); + let prev = package.worlds.insert(name.to_string(), id); + assert!(prev.is_none()); + Ok(id) } fn convert_function(&mut self, name: &str, ty: &types::ComponentFuncType) -> Result { @@ -1032,32 +1080,22 @@ impl WitPackageDecoder<'_> { /// /// Takes the root package as an argument to insert. fn finish(mut self, package: Package) -> (Resolve, PackageId) { - // First build a map from all documents to what index their package - // resides at in the `url_to_package` array. - let mut doc_to_package_index = HashMap::new(); - for (i, (_url, pkg)) in self.url_to_package.iter().enumerate() { - for (_, doc) in pkg.documents.iter() { - let prev = doc_to_package_index.insert(*doc, i); - assert!(prev.is_none()); - } - } - - // Using the above map a topological ordering is then calculated by - // visiting all the transitive dependencies of packages. + // Build a topological ordering is then calculated by visiting all the + // transitive dependencies of packages. let mut order = IndexSet::new(); - for i in 0..self.url_to_package.len() { - self.visit_package(&doc_to_package_index, i, &mut order); + for i in 0..self.foreign_packages.len() { + self.visit_package(i, &mut order); } // Using the topological ordering create a temporary map from - // index-in-`url_to_package` to index-in-`order` - let mut idx_to_pos = vec![0; self.url_to_package.len()]; + // index-in-`foreign_packages` to index-in-`order` + let mut idx_to_pos = vec![0; self.foreign_packages.len()]; for (pos, idx) in order.iter().enumerate() { idx_to_pos[*idx] = pos; } - // .. and then using `idx_to_pos` sort the `url_to_package` array based + // .. and then using `idx_to_pos` sort the `foreign_packages` array based // on the position it's at in the topological ordering - let mut deps = mem::take(&mut self.url_to_package) + let mut deps = mem::take(&mut self.foreign_packages) .into_iter() .enumerate() .collect::>(); @@ -1070,58 +1108,68 @@ impl WitPackageDecoder<'_> { } let id = self.insert_package(package); + assert!(self.resolve.worlds.iter().all(|(_, w)| w.package.is_some())); + assert!(self + .resolve + .interfaces + .iter() + .all(|(_, i)| i.package.is_some())); (self.resolve, id) } fn insert_package(&mut self, package: Package) -> PackageId { + let name = package.name.clone(); let id = self.resolve.packages.alloc(package); - for (_, doc) in self.resolve.packages[id].documents.iter() { - self.resolve.documents[*doc].package = Some(id); + let prev = self.resolve.package_names.insert(name, id); + assert!(prev.is_none()); + for (_, iface) in self.resolve.packages[id].interfaces.iter() { + self.resolve.interfaces[*iface].package = Some(id); + } + for (_, world) in self.resolve.packages[id].worlds.iter() { + self.resolve.worlds[*world].package = Some(id); + let world = &self.resolve.worlds[*world]; + for (name, item) in world.imports.iter().chain(world.exports.iter()) { + if let WorldKey::Name(_) = name { + if let WorldItem::Interface(iface) = item { + self.resolve.interfaces[*iface].package = Some(id); + } + } + } } id } - fn visit_package( - &self, - doc_to_package_index: &HashMap, - idx: usize, - order: &mut IndexSet, - ) { + fn visit_package(&self, idx: usize, order: &mut IndexSet) { if order.contains(&idx) { return; } - let (_url, pkg) = self.url_to_package.get_index(idx).unwrap(); - for (_, id) in pkg.documents.iter() { - let doc = &self.resolve.documents[*id]; - - let interfaces = doc.interfaces.values().copied().chain( - doc.worlds - .values() - .flat_map(|w| { - let world = &self.resolve.worlds[*w]; - world.imports.values().chain(world.exports.values()) - }) - .filter_map(|item| match item { - WorldItem::Interface(id) => Some(*id), - WorldItem::Function(_) | WorldItem::Type(_) => None, - }), - ); - for iface in interfaces { - for ty in self.resolve.interfaces[iface].types.values() { - let id = match self.resolve.types[*ty].kind { - TypeDefKind::Type(Type::Id(id)) => id, - _ => continue, - }; - let owner = match self.resolve.types[id].owner { - TypeOwner::Interface(i) => i, - _ => continue, - }; - let doc = self.resolve.interfaces[owner].document; - let owner_idx = doc_to_package_index[&doc]; - if owner_idx != idx { - self.visit_package(doc_to_package_index, owner_idx, order); - } + let (_name, pkg) = self.foreign_packages.get_index(idx).unwrap(); + let interfaces = pkg.interfaces.values().copied().chain( + pkg.worlds + .values() + .flat_map(|w| { + let world = &self.resolve.worlds[*w]; + world.imports.values().chain(world.exports.values()) + }) + .filter_map(|item| match item { + WorldItem::Interface(id) => Some(*id), + WorldItem::Function(_) | WorldItem::Type(_) => None, + }), + ); + for iface in interfaces { + for ty in self.resolve.interfaces[iface].types.values() { + let id = match self.resolve.types[*ty].kind { + TypeDefKind::Type(Type::Id(id)) => id, + _ => continue, + }; + let owner = match self.resolve.types[id].owner { + TypeOwner::Interface(i) => i, + _ => continue, + }; + let owner_idx = self.iface_to_package_index[&owner]; + if owner_idx != idx { + self.visit_package(owner_idx, order); } } } diff --git a/crates/wit-component/src/dummy.rs b/crates/wit-component/src/dummy.rs index bcc9ae6cab..bb88d1fa54 100644 --- a/crates/wit-component/src/dummy.rs +++ b/crates/wit-component/src/dummy.rs @@ -20,6 +20,7 @@ pub fn dummy_module(resolve: &Resolve, world: WorldId) -> Vec { for (_, func) in resolve.interfaces[*import].functions.iter() { let sig = resolve.wasm_signature(AbiVariant::GuestImport, func); + let name = resolve.name_world_key(name); wat.push_str(&format!("(import \"{name}\" \"{}\" (func", func.name)); push_tys(&mut wat, "param", &sig.params); push_tys(&mut wat, "result", &sig.results); @@ -36,8 +37,9 @@ pub fn dummy_module(resolve: &Resolve, world: WorldId) -> Vec { push_func(&mut wat, &func.name, resolve, func); } WorldItem::Interface(export) => { + let name = resolve.name_world_key(name); for (_, func) in resolve.interfaces[*export].functions.iter() { - let name = func.core_export_name(Some(name)); + let name = func.core_export_name(Some(&name)); push_func(&mut wat, &name, resolve, func); } } diff --git a/crates/wit-component/src/encoding.rs b/crates/wit-component/src/encoding.rs index 422411ba20..654023f47b 100644 --- a/crates/wit-component/src/encoding.rs +++ b/crates/wit-component/src/encoding.rs @@ -84,6 +84,7 @@ use wasmparser::{Validator, WasmFeatures}; use wit_parser::{ abi::{AbiVariant, WasmSignature, WasmType}, Function, InterfaceId, LiveTypes, Resolve, Type, TypeDefKind, TypeId, TypeOwner, WorldItem, + WorldKey, }; const INDIRECT_TABLE_NAME: &str = "$imports"; @@ -352,7 +353,7 @@ pub struct EncodingState<'a> { /// Imported instances and what index they were imported as. imported_instances: IndexMap, - imported_funcs: IndexMap<&'a str, u32>, + imported_funcs: IndexMap, exported_instances: IndexMap, /// Map of types defined within the component's root index space. @@ -432,7 +433,7 @@ impl<'a> EncodingState<'a> { fn encode_interface_import(&mut self, name: &str, info: &ImportedInterface) -> Result<()> { let resolve = &self.info.encoder.metadata.resolve; - let (interface_id, url) = info.interface.as_ref().unwrap(); + let interface_id = info.interface.as_ref().unwrap(); let interface_id = *interface_id; let interface = &resolve.interfaces[interface_id]; log::trace!("encoding imports for `{name}` as {:?}", interface_id); @@ -447,9 +448,7 @@ impl<'a> EncodingState<'a> { log::trace!("encoding function type for `{}`", func.name); let idx = encoder.encode_func_type(resolve, func)?; - encoder - .ty - .export(&func.name, "", ComponentTypeRef::Func(idx)); + encoder.ty.export(&func.name, ComponentTypeRef::Func(idx)); } // If there were any live types from this instance which weren't @@ -472,9 +471,9 @@ impl<'a> EncodingState<'a> { return Ok(()); } let instance_type_idx = self.component.instance_type(&ty); - let instance_idx = - self.component - .import(name, url, ComponentTypeRef::Instance(instance_type_idx)); + let instance_idx = self + .component + .import(name, ComponentTypeRef::Instance(instance_type_idx)); let prev = self.imported_instances.insert(interface_id, instance_idx); assert!(prev.is_none()); Ok(()) @@ -488,13 +487,14 @@ impl<'a> EncodingState<'a> { WorldItem::Function(f) => f, WorldItem::Interface(_) | WorldItem::Type(_) => continue, }; + let name = resolve.name_world_key(name); if !info.required.contains(name.as_str()) { continue; } log::trace!("encoding function type for `{}`", func.name); let mut encoder = self.root_type_encoder(None); let idx = encoder.encode_func_type(resolve, func)?; - let func_idx = self.component.import(name, "", ComponentTypeRef::Func(idx)); + let func_idx = self.component.import(&name, ComponentTypeRef::Func(idx)); let prev = self.imported_funcs.insert(name, func_idx); assert!(prev.is_none()); } @@ -593,7 +593,7 @@ impl<'a> EncodingState<'a> { let interface = if core_wasm_name == BARE_FUNC_MODULE_NAME { None } else { - Some(core_wasm_name) + Some(core_wasm_name.to_string()) }; let import = &self.info.import_map[&interface]; let required_imports = match for_module { @@ -617,7 +617,7 @@ impl<'a> EncodingState<'a> { .expect("shim should be instantiated"), ExportKind::Func, &shims.shim_names[&ShimKind::IndirectLowering { - interface, + interface: interface.clone(), indirect_index: i, realloc: for_module, encoding, @@ -633,7 +633,7 @@ impl<'a> EncodingState<'a> { continue; } let func_index = match &import.interface { - Some((interface, _url)) => { + Some(interface) => { let instance_index = self.imported_instances[interface]; self.component.alias_func(instance_index, lowering.name) } @@ -654,6 +654,7 @@ impl<'a> EncodingState<'a> { }; let world = &resolve.worlds[self.info.encoder.metadata.world]; for export_name in exports { + let export_string = resolve.name_world_key(export_name); match &world.exports[export_name] { WorldItem::Function(func) => { let mut enc = self.root_type_encoder(None); @@ -661,10 +662,10 @@ impl<'a> EncodingState<'a> { let core_name = func.core_export_name(None); let idx = self.encode_lift(module, &core_name, func, ty)?; self.component - .export(export_name, "", ComponentExportKind::Func, idx, None); + .export(&export_string, ComponentExportKind::Func, idx, None); } WorldItem::Interface(export) => { - self.encode_interface_export(export_name, module, *export)?; + self.encode_interface_export(&export_string, module, *export)?; } WorldItem::Type(_) => unreachable!(), } @@ -751,7 +752,6 @@ impl<'a> EncodingState<'a> { let ty = nested.encode_func_type(resolve, func)?; nested.component.import( &format!("import-func-{}", func.name), - "", ComponentTypeRef::Func(ty), ); } @@ -791,7 +791,6 @@ impl<'a> EncodingState<'a> { let ty = nested.encode_func_type(resolve, func)?; nested.component.export( &func.name, - "", ComponentExportKind::Func, i as u32, Some(ComponentTypeRef::Func(ty)), @@ -814,10 +813,8 @@ impl<'a> EncodingState<'a> { let instance_index = self .component .instantiate_component(component_index, imports); - let url = resolve.url_of(export).unwrap_or(String::new()); let idx = self.component.export( export_name, - &url, ComponentExportKind::Instance, instance_index, None, @@ -847,7 +844,7 @@ impl<'a> EncodingState<'a> { if self.export_types { Some( self.component - .export(name, "", ComponentExportKind::Type, idx, None), + .export(name, ComponentExportKind::Type, idx, None), ) } else { let base = format!("import-type-{name}"); @@ -857,11 +854,9 @@ impl<'a> EncodingState<'a> { name = format!("{name}{n}"); n += 1; } - let ret = self.component.import( - &name, - "", - ComponentTypeRef::Type(TypeBounds::Eq(idx)), - ); + let ret = self + .component + .import(&name, ComponentTypeRef::Type(TypeBounds::Eq(idx))); self.imports.insert(name, ret); Some(ret) } @@ -940,7 +935,7 @@ impl<'a> EncodingState<'a> { let import_name = if *core_wasm_name == BARE_FUNC_MODULE_NAME { None } else { - Some(*core_wasm_name) + Some(core_wasm_name.to_string()) }; let import = &self.info.import_map[&import_name]; ret.append_indirect( @@ -958,7 +953,7 @@ impl<'a> EncodingState<'a> { // interface imported into the shim module itself. for (adapter, (info, _wasm)) in self.info.adapters.iter() { for (name, required) in info.required_imports.iter() { - let import = &self.info.import_map[&Some(*name)]; + let import = &self.info.import_map[&Some(name.clone())]; ret.append_indirect( name, CustomModule::Adapter(adapter), @@ -997,7 +992,7 @@ impl<'a> EncodingState<'a> { } for shim in ret.list.iter() { - let prev = ret.shim_names.insert(shim.kind, shim.name.clone()); + let prev = ret.shim_names.insert(shim.kind.clone(), shim.name.clone()); assert!(prev.is_none()); } @@ -1153,7 +1148,7 @@ impl<'a> EncodingState<'a> { let interface = &self.info.import_map[interface]; let name = interface.indirect[*indirect_index].name; let func_index = match &interface.interface { - Some((interface_id, _url)) => { + Some(interface_id) => { let instance_index = self.imported_instances[interface_id]; self.component.alias_func(instance_index, name) } @@ -1342,14 +1337,14 @@ struct Shim<'a> { kind: ShimKind<'a>, } -#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +#[derive(Debug, Clone, Hash, Eq, PartialEq)] enum ShimKind<'a> { /// This shim is a late indirect lowering of an imported function in a /// component which is only possible after prior core wasm modules are /// instantiated so their memories and functions are available. IndirectLowering { /// The name of the interface that's being lowered. - interface: Option<&'a str>, + interface: Option, /// The index within the `indirect` array of the function being lowered. indirect_index: usize, /// Which instance to pull the `realloc` function from, if necessary. @@ -1401,7 +1396,7 @@ impl<'a> Shims<'a> { let interface = if core_wasm_module == BARE_FUNC_MODULE_NAME { None } else { - Some(core_wasm_module) + Some(core_wasm_module.to_string()) }; for (indirect_index, lowering) in import.indirect.iter().enumerate() { if !required.contains(&lowering.name) { @@ -1420,7 +1415,7 @@ impl<'a> Shims<'a> { debug_name: format!("indirect-{core_wasm_module}-{}", lowering.name), options: lowering.options, kind: ShimKind::IndirectLowering { - interface, + interface: interface.clone(), indirect_index, realloc: for_module, encoding, @@ -1436,7 +1431,7 @@ pub struct ComponentEncoder { module: Vec, metadata: Bindgen, validate: bool, - main_module_exports: IndexSet, + main_module_exports: IndexSet, // This is a map from the name of the adapter to a pair of: // @@ -1446,7 +1441,7 @@ pub struct ComponentEncoder { // imports. // * The set of exports from the final world which are defined by this // adapter. - adapters: IndexMap, ModuleMetadata, IndexSet)>, + adapters: IndexMap, ModuleMetadata, IndexSet)>, } impl ComponentEncoder { @@ -1457,15 +1452,12 @@ impl ComponentEncoder { /// core module. pub fn module(mut self, module: &[u8]) -> Result { let (wasm, metadata) = metadata::decode(module)?; - self.main_module_exports.extend( - metadata.resolve.worlds[metadata.world] - .exports - .keys() - .cloned(), - ); - self.metadata + let world = self + .metadata .merge(metadata) .context("failed merge WIT package sets together")?; + self.main_module_exports + .extend(self.metadata.resolve.worlds[world].exports.keys().cloned()); self.module = if let Some(producers) = &self.metadata.producers { producers.add_to_wasm(&wasm)? } else { diff --git a/crates/wit-component/src/encoding/types.rs b/crates/wit-component/src/encoding/types.rs index 392454d251..1fd03115d0 100644 --- a/crates/wit-component/src/encoding/types.rs +++ b/crates/wit-component/src/encoding/types.rs @@ -327,11 +327,11 @@ impl<'a> ValtypeEncoder<'a> for RootTypeEncoder<'_, 'a> { Some(if self.import_types { self.state .component - .import(name, "", ComponentTypeRef::Type(TypeBounds::Eq(idx))) + .import(name, ComponentTypeRef::Type(TypeBounds::Eq(idx))) } else { self.state .component - .export(name, "", ComponentExportKind::Type, idx, None) + .export(name, ComponentExportKind::Type, idx, None) }) } else { assert!(!self.import_types); @@ -375,7 +375,7 @@ impl<'a> ValtypeEncoder<'a> for InstanceTypeEncoder<'_, 'a> { fn export_type(&mut self, idx: u32, name: &str) -> Option { let ret = self.ty.type_count(); self.ty - .export(name, "", ComponentTypeRef::Type(TypeBounds::Eq(idx))); + .export(name, ComponentTypeRef::Type(TypeBounds::Eq(idx))); Some(ret) } fn type_map(&mut self) -> &mut HashMap { diff --git a/crates/wit-component/src/encoding/wit.rs b/crates/wit-component/src/encoding/wit.rs index 99a8e8c6b5..8a3ecd6aad 100644 --- a/crates/wit-component/src/encoding/wit.rs +++ b/crates/wit-component/src/encoding/wit.rs @@ -4,7 +4,6 @@ use anyhow::Result; use indexmap::IndexSet; use std::collections::HashMap; use std::mem; -use url::Url; use wasm_encoder::*; use wit_parser::*; @@ -50,16 +49,6 @@ struct Encoder<'a> { impl Encoder<'_> { fn run(&mut self) -> Result<()> { - for (name, doc) in self.resolve.packages[self.package].documents.iter() { - let ty = self.encode_document(*doc)?; - let url = format!("pkg:/{name}"); - self.component - .export(name, &url, ComponentExportKind::Type, ty, None); - } - Ok(()) - } - - fn encode_document(&mut self, doc: DocumentId) -> Result { // Build a set of interfaces reachable from this document, including the // interfaces in the document itself. This is used to import instances // into the component type we're encoding. Note that entire interfaces @@ -69,7 +58,7 @@ impl Encoder<'_> { // notably on the order that types are defined in to assist with // roundtripping. let mut interfaces = IndexSet::new(); - for (_, id) in self.resolve.documents[doc].interfaces.iter() { + for (_, id) in self.resolve.packages[self.package].interfaces.iter() { self.add_live_interfaces(&mut interfaces, *id); } @@ -79,12 +68,12 @@ impl Encoder<'_> { let mut used_names = IndexSet::new(); for id in interfaces.iter() { let iface = &self.resolve.interfaces[*id]; - if iface.document == doc { + if iface.package == Some(self.package) { let first = used_names.insert(iface.name.as_ref().unwrap().clone()); assert!(first); } } - for (name, _world) in self.resolve.documents[doc].worlds.iter() { + for (name, _world) in self.resolve.packages[self.package].worlds.iter() { let first = used_names.insert(name.clone()); assert!(first); } @@ -97,13 +86,11 @@ impl Encoder<'_> { for interface in interfaces { encoder.interface = Some(interface); let iface = &self.resolve.interfaces[interface]; - let name = iface.name.as_ref().unwrap(); - if iface.document == doc { + let name = self.resolve.id_of(interface).unwrap(); + log::trace!("encoding interface {name}"); + if iface.package == Some(self.package) { let idx = encoder.encode_instance(interface)?; - let url = format!("pkg:/{}/{name}", self.resolve.documents[doc].name); - encoder - .outer - .export(name, &url, ComponentTypeRef::Instance(idx)); + encoder.outer.export(&name, ComponentTypeRef::Instance(idx)); } else { encoder.push_instance(); for (_, id) in iface.types.iter() { @@ -114,44 +101,29 @@ impl Encoder<'_> { encoder.outer.ty().instance(&instance); encoder.import_map.insert(interface, encoder.instances); encoder.instances += 1; - - let import_name = if used_names.insert(name.clone()) { - name.clone() - } else { - let mut i = 2; - loop { - let name = format!("{name}{i}"); - if used_names.insert(name.clone()) { - break name; - } - i += 1; - } - }; - - let url = self.url_of(interface); - encoder - .outer - .import(&import_name, &url, ComponentTypeRef::Instance(idx)); + encoder.outer.import(&name, ComponentTypeRef::Instance(idx)); } } encoder.interface = None; - let doc = &self.resolve.documents[doc]; - for (name, world) in doc.worlds.iter() { + for (name, world) in self.resolve.packages[self.package].worlds.iter() { let world = &self.resolve.worlds[*world]; let mut component = InterfaceEncoder::new(self.resolve); + log::trace!("encoding world {}", world.name); for (name, import) in world.imports.iter() { - let (url, ty) = match import { + let name = self.resolve.name_world_key(name); + log::trace!("encoding import {name}"); + let ty = match import { WorldItem::Interface(i) => { component.interface = Some(*i); let idx = component.encode_instance(*i)?; - (self.url_of(*i), ComponentTypeRef::Instance(idx)) + ComponentTypeRef::Instance(idx) } WorldItem::Function(f) => { component.interface = None; let idx = component.encode_func_type(self.resolve, f)?; - (String::new(), ComponentTypeRef::Func(idx)) + ComponentTypeRef::Func(idx) } WorldItem::Type(t) => { component.interface = None; @@ -161,34 +133,38 @@ impl Encoder<'_> { continue; } }; - component.outer.import(name, &url, ty); + component.outer.import(&name, ty); } for (name, export) in world.exports.iter() { - let (url, ty) = match export { + let name = self.resolve.name_world_key(name); + log::trace!("encoding export {name}"); + let ty = match export { WorldItem::Interface(i) => { component.interface = Some(*i); let idx = component.encode_instance(*i)?; - (self.url_of(*i), ComponentTypeRef::Instance(idx)) + ComponentTypeRef::Instance(idx) } WorldItem::Function(f) => { component.interface = None; let idx = component.encode_func_type(self.resolve, f)?; - (String::new(), ComponentTypeRef::Func(idx)) + ComponentTypeRef::Func(idx) } WorldItem::Type(_) => unreachable!(), }; - component.outer.export(name, &url, ty); + component.outer.export(&name, ty); } let idx = encoder.outer.type_count(); encoder.outer.ty().component(&component.outer); - let url = format!("pkg:/{}/{name}", doc.name); - encoder - .outer - .export(&name, &url, ComponentTypeRef::Component(idx)); + let id = self.resolve.packages[self.package].name.interface_id(&name); + encoder.outer.export(&id, ComponentTypeRef::Component(idx)); } - Ok(self.component.component_type(&encoder.outer)) + let ty = self.component.component_type(&encoder.outer); + let id = self.resolve.packages[self.package].name.interface_id("wit"); + self.component + .export(&id, ComponentExportKind::Type, ty, None); + Ok(()) } /// Recursively add all live interfaces reachable from `id` into the @@ -217,27 +193,6 @@ impl Encoder<'_> { } assert!(interfaces.insert(id)); } - - fn url_of(&self, interface: InterfaceId) -> String { - let iface = &self.resolve.interfaces[interface]; - let iface_name = match &iface.name { - Some(name) => name, - None => return String::new(), - }; - let doc = &self.resolve.documents[iface.document]; - let pkg = doc.package.unwrap(); - let mut base = if pkg == self.package { - Url::parse("pkg:/").unwrap() - } else { - let pkg = &self.resolve.packages[pkg]; - Url::parse(pkg.url.as_ref().unwrap()).unwrap() - }; - let mut segments = base.path_segments_mut().unwrap(); - segments.push(&doc.name); - segments.push(iface_name); - drop(segments); - base.to_string() - } } struct InterfaceEncoder<'a> { @@ -282,7 +237,7 @@ impl InterfaceEncoder<'_> { self.ty .as_mut() .unwrap() - .export(name, "", ComponentTypeRef::Func(ty)); + .export(name, ComponentTypeRef::Func(ty)); } let instance = self.pop_instance(); let idx = self.outer.type_count(); @@ -328,17 +283,17 @@ impl<'a> ValtypeEncoder<'a> for InterfaceEncoder<'a> { Some(ty) => { assert!(!self.import_types); let ret = ty.type_count(); - ty.export(name, "", ComponentTypeRef::Type(TypeBounds::Eq(index))); + ty.export(name, ComponentTypeRef::Type(TypeBounds::Eq(index))); Some(ret) } None => { let ret = self.outer.type_count(); if self.import_types { self.outer - .import(name, "", ComponentTypeRef::Type(TypeBounds::Eq(index))); + .import(name, ComponentTypeRef::Type(TypeBounds::Eq(index))); } else { self.outer - .export(name, "", ComponentTypeRef::Type(TypeBounds::Eq(index))); + .export(name, ComponentTypeRef::Type(TypeBounds::Eq(index))); } Some(ret) } diff --git a/crates/wit-component/src/encoding/world.rs b/crates/wit-component/src/encoding/world.rs index 8b89b2ac0c..7c57d9b749 100644 --- a/crates/wit-component/src/encoding/world.rs +++ b/crates/wit-component/src/encoding/world.rs @@ -5,11 +5,13 @@ use crate::validation::{ }; use anyhow::{Context, Result}; use indexmap::{IndexMap, IndexSet}; +use std::borrow::Borrow; use std::collections::HashSet; +use std::hash::Hash; use wasmparser::FuncType; use wit_parser::{ abi::{AbiVariant, WasmSignature, WasmType}, - Function, InterfaceId, LiveTypes, Resolve, TypeId, TypeOwner, WorldId, WorldItem, + Function, InterfaceId, LiveTypes, Resolve, TypeId, TypeOwner, WorldId, WorldItem, WorldKey, }; /// Metadata discovered from the state configured in a `ComponentEncoder`. @@ -27,7 +29,7 @@ pub struct ComponentWorld<'a> { /// adapters. Additionally stores the gc'd wasm for each adapter. pub adapters: IndexMap<&'a str, (ValidatedAdapter<'a>, Vec)>, /// Map of all imports and descriptions of what they're importing. - pub import_map: IndexMap, ImportedInterface<'a>>, + pub import_map: IndexMap, ImportedInterface<'a>>, /// Set of all live types which must be exported either because they're /// directly used or because they're transitively used. pub live_types: IndexMap>, @@ -40,7 +42,7 @@ pub struct ImportedInterface<'a> { /// Required functions on the interface, or the filter on the functions list /// in `interface`. pub required: HashSet<&'a str>, - pub interface: Option<(InterfaceId, String)>, + pub interface: Option, } #[derive(Debug)] @@ -114,7 +116,7 @@ impl<'a> ComponentWorld<'a> { &self, resolve: &Resolve, world: WorldId, - required_exports: &IndexSet, + required_exports: &IndexSet, required_by_import: Option<&IndexMap<&str, FuncType>>, ) -> IndexMap { use wasmparser::ValType; @@ -141,8 +143,9 @@ impl<'a> ComponentWorld<'a> { match &resolve.worlds[world].exports[name] { WorldItem::Function(func) => add_func(func, None), WorldItem::Interface(id) => { + let name = resolve.name_world_key(name); for (_, func) in resolve.interfaces[*id].functions.iter() { - add_func(func, Some(name)); + add_func(func, Some(&name)); } } WorldItem::Type(_) => {} @@ -167,19 +170,20 @@ impl<'a> ComponentWorld<'a> { let resolve = &self.encoder.metadata.resolve; let world = self.encoder.metadata.world; let mut all_required_imports = IndexMap::new(); - for map in self - .adapters - .values() - .map(|(i, _)| &i.required_imports) - .chain([&self.info.required_imports]) - { + for map in self.adapters.values().map(|(i, _)| &i.required_imports) { for (k, v) in map { all_required_imports - .entry(*k) + .entry(k.as_str()) .or_insert_with(IndexSet::new) .extend(v); } } + for (k, v) in self.info.required_imports.iter() { + all_required_imports + .entry(*k) + .or_insert_with(IndexSet::new) + .extend(v); + } for (name, item) in resolve.worlds[world].imports.iter() { add_item( &mut self.import_map, @@ -192,19 +196,20 @@ impl<'a> ComponentWorld<'a> { return Ok(()); fn add_item<'a>( - import_map: &mut IndexMap, ImportedInterface<'a>>, + import_map: &mut IndexMap, ImportedInterface<'a>>, resolve: &'a Resolve, - name: &'a str, + name: &WorldKey, item: &'a WorldItem, required: &IndexMap<&str, IndexSet<&str>>, ) -> Result<()> { + let name = resolve.name_world_key(name); log::trace!("register import `{name}`"); let empty = IndexSet::new(); match item { WorldItem::Function(func) => { let required = required.get(BARE_FUNC_MODULE_NAME).unwrap_or(&empty); // If this function isn't actually required then skip it - if !required.contains(name) { + if !required.contains(name.as_str()) { return Ok(()); } let interface = import_map.entry(None).or_insert_with(|| ImportedInterface { @@ -217,18 +222,17 @@ impl<'a> ComponentWorld<'a> { add_import(interface, resolve, func) } WorldItem::Interface(id) => { - let required = required.get(name).unwrap_or(&empty); - let url = resolve.url_of(*id).unwrap_or(String::new()); + let required = required.get(name.as_str()).unwrap_or(&empty); let interface = import_map .entry(Some(name)) .or_insert_with(|| ImportedInterface { - interface: Some((*id, url)), + interface: Some(*id), direct: Default::default(), indirect: Default::default(), required: Default::default(), }); - assert_eq!(interface.interface.as_ref().unwrap().0, *id); + assert_eq!(interface.interface.unwrap(), *id); for (_name, func) in resolve.interfaces[*id].functions.iter() { // If this function isn't actually required then skip it if required.contains(func.name.as_str()) { @@ -279,7 +283,7 @@ impl<'a> ComponentWorld<'a> { self.add_live_imports(world, &info.required_imports, &mut live); } for (name, item) in resolve.worlds[world].exports.iter() { - log::trace!("add live world export `{name}`"); + log::trace!("add live world export `{}`", resolve.name_world_key(name)); live.add_world_item(resolve, item); } @@ -295,14 +299,17 @@ impl<'a> ComponentWorld<'a> { } } - fn add_live_imports( + fn add_live_imports( &self, world: WorldId, - required: &IndexMap<&str, IndexSet<&str>>, + required: &IndexMap>, live: &mut LiveTypes, - ) { + ) where + S: Borrow + Hash + Eq, + { let resolve = &self.encoder.metadata.resolve; for (name, item) in resolve.worlds[world].imports.iter() { + let name = resolve.name_world_key(name); match item { WorldItem::Function(func) => { let required = match required.get(BARE_FUNC_MODULE_NAME) { diff --git a/crates/wit-component/src/metadata.rs b/crates/wit-component/src/metadata.rs index ca90bf1465..2fe9035ccc 100644 --- a/crates/wit-component/src/metadata.rs +++ b/crates/wit-component/src/metadata.rs @@ -39,9 +39,9 @@ use indexmap::IndexMap; use wasm_encoder::Encode; use wasm_metadata::Producers; use wasmparser::BinaryReader; -use wit_parser::{Document, Package, Resolve, World, WorldId, WorldItem}; +use wit_parser::{Package, PackageName, Resolve, World, WorldId, WorldItem}; -const CURRENT_VERSION: u8 = 0x02; +const CURRENT_VERSION: u8 = 0x03; /// The result of decoding binding information from a WebAssembly binary. /// @@ -62,29 +62,22 @@ impl Default for Bindgen { fn default() -> Bindgen { let mut resolve = Resolve::default(); let package = resolve.packages.alloc(Package { - name: "root".to_string(), - url: None, - documents: Default::default(), - }); - let document = resolve.documents.alloc(Document { - name: "root".to_string(), + name: PackageName { + namespace: "root".to_string(), + name: "root".to_string(), + version: None, + }, interfaces: Default::default(), worlds: Default::default(), - default_world: None, - default_interface: None, - package: Some(package), }); let world = resolve.worlds.alloc(World { name: "root".to_string(), docs: Default::default(), imports: Default::default(), exports: Default::default(), - document, + package: Some(package), }); resolve.packages[package] - .documents - .insert("root".to_string(), document); - resolve.documents[document] .worlds .insert("root".to_string(), world); Bindgen { @@ -160,8 +153,7 @@ pub fn encode( producers: Option<&Producers>, ) -> Result> { let world = &resolve.worlds[world]; - let doc = &resolve.documents[world.document]; - let pkg = &resolve.packages[doc.package.unwrap()]; + let pkg = &resolve.packages[world.package.unwrap()]; assert!( resolve @@ -179,11 +171,9 @@ pub fn encode( StringEncoding::UTF16 => 0x01, StringEncoding::CompactUTF16 => 0x02, }); - pkg.name.encode(&mut ret); - doc.name.encode(&mut ret); world.name.encode(&mut ret); // This appends a wasm binary encoded Component to the ret: - let mut component_builder = crate::encoding::encode_component(resolve, doc.package.unwrap())?; + let mut component_builder = crate::encoding::encode_component(resolve, world.package.unwrap())?; if let Some(p) = producers { component_builder.add_producers(p); @@ -205,16 +195,13 @@ impl Bindgen { 0x02 => StringEncoding::CompactUTF16, byte => bail!("invalid string encoding {byte:#x}"), }; - let pkg_name = reader.read_string()?; - let doc_name = reader.read_string()?; let world_name = reader.read_string()?; - let (resolve, pkg) = match crate::decode(pkg_name, &data[reader.original_position()..])? { + let (resolve, pkg) = match crate::decode(&data[reader.original_position()..])? { DecodedWasm::WitPackage(resolve, pkg) => (resolve, pkg), DecodedWasm::Component(..) => bail!("expected an encoded wit package"), }; - let doc = resolve.packages[pkg].documents[doc_name]; - let world = resolve.documents[doc].worlds[world_name]; + let world = resolve.packages[pkg].worlds[world_name]; let metadata = ModuleMetadata::new(&resolve, world, encoding); let producers = wasm_metadata::Producers::from_wasm(&data[reader.original_position()..])?; Ok(Bindgen { @@ -234,7 +221,7 @@ impl Bindgen { /// /// Note that at this time there's no support for changing string encodings /// between metadata. - pub fn merge(&mut self, other: Bindgen) -> Result<()> { + pub fn merge(&mut self, other: Bindgen) -> Result { let Bindgen { resolve, world, @@ -285,7 +272,7 @@ impl Bindgen { } } - Ok(()) + Ok(world) } } @@ -297,6 +284,7 @@ impl ModuleMetadata { let world = &resolve.worlds[world]; for (name, item) in world.imports.iter() { + let name = resolve.name_world_key(name); match item { WorldItem::Function(_) => { let prev = ret @@ -317,15 +305,16 @@ impl ModuleMetadata { } for (name, item) in world.exports.iter() { + let name = resolve.name_world_key(name); match item { WorldItem::Function(func) => { let name = func.core_export_name(None).into_owned(); - let prev = ret.export_encodings.insert(name, encoding); + let prev = ret.export_encodings.insert(name.clone(), encoding); assert!(prev.is_none()); } WorldItem::Interface(i) => { for (_, func) in resolve.interfaces[*i].functions.iter() { - let name = func.core_export_name(Some(name)).into_owned(); + let name = func.core_export_name(Some(&name)).into_owned(); let prev = ret.export_encodings.insert(name, encoding); assert!(prev.is_none()); } diff --git a/crates/wit-component/src/printing.rs b/crates/wit-component/src/printing.rs index 72b84caff2..ba384e325f 100644 --- a/crates/wit-component/src/printing.rs +++ b/crates/wit-component/src/printing.rs @@ -4,18 +4,23 @@ use wit_parser::*; /// A utility for printing WebAssembly interface definitions to a string. #[derive(Default)] -pub struct DocumentPrinter { +pub struct WitPrinter { output: Output, } -impl DocumentPrinter { - /// Print the given `*.wit` document to a string. - pub fn print(&mut self, resolve: &Resolve, docid: DocumentId) -> Result { - let doc = &resolve.documents[docid]; - for (name, id) in doc.interfaces.iter() { - if Some(*id) == doc.default_interface { - self.output.push_str("default "); - } +impl WitPrinter { + /// Print the given WIT package to a string. + pub fn print(&mut self, resolve: &Resolve, pkgid: PackageId) -> Result { + let pkg = &resolve.packages[pkgid]; + self.output.push_str("package "); + self.print_name(&pkg.name.namespace); + self.output.push_str(":"); + self.print_name(&pkg.name.name); + if let Some(version) = &pkg.name.version { + self.output.push_str(&format!("@{version}")); + } + self.output.push_str("\n\n"); + for (name, id) in pkg.interfaces.iter() { self.output.push_str("interface "); self.print_name(name); self.output.push_str(" {\n"); @@ -23,10 +28,7 @@ impl DocumentPrinter { writeln!(&mut self.output, "}}\n")?; } - for (name, id) in doc.worlds.iter() { - if Some(*id) == doc.default_world { - self.output.push_str("default "); - } + for (name, id) in pkg.worlds.iter() { self.output.push_str("world "); self.print_name(name); self.output.push_str(" {\n"); @@ -101,9 +103,9 @@ impl DocumentPrinter { } // Generate a `use` statement for all imported types. - let my_doc = match owner { - TypeOwner::Interface(id) => resolve.interfaces[id].document, - TypeOwner::World(id) => resolve.worlds[id].document, + let my_pkg = match owner { + TypeOwner::Interface(id) => resolve.interfaces[id].package.unwrap(), + TypeOwner::World(id) => resolve.worlds[id].package.unwrap(), TypeOwner::None => unreachable!(), }; let amt_to_import = types_to_import.len(); @@ -115,7 +117,7 @@ impl DocumentPrinter { // this time. _ => unreachable!(), }; - self.print_path_to_interface(resolve, id, my_doc)?; + self.print_path_to_interface(resolve, id, my_pkg)?; write!(&mut self.output, ".{{")?; for (i, (my_name, other_name)) in tys.into_iter().enumerate() { if i > 0 { @@ -181,19 +183,22 @@ impl DocumentPrinter { fn print_world(&mut self, resolve: &Resolve, id: WorldId) -> Result<()> { let world = &resolve.worlds[id]; - let docid = world.document; + let pkgid = world.package.unwrap(); let mut types = Vec::new(); for (name, import) in world.imports.iter() { match import { - WorldItem::Type(t) => types.push((name.as_str(), *t)), + WorldItem::Type(t) => match name { + WorldKey::Name(s) => types.push((s.as_str(), *t)), + WorldKey::Interface(_) => unreachable!(), + }, _ => { - self.print_world_item(resolve, name, import, docid, "import")?; + self.print_world_item(resolve, name, import, pkgid, "import")?; } } } self.print_types(resolve, TypeOwner::World(id), types.into_iter())?; for (name, export) in world.exports.iter() { - self.print_world_item(resolve, name, export, docid, "export")?; + self.print_world_item(resolve, name, export, pkgid, "export")?; } Ok(()) } @@ -201,32 +206,40 @@ impl DocumentPrinter { fn print_world_item( &mut self, resolve: &Resolve, - name: &str, + name: &WorldKey, item: &WorldItem, - cur_doc: DocumentId, + cur_pkg: PackageId, desc: &str, ) -> Result<()> { self.output.push_str(desc); self.output.push_str(" "); - self.print_name(name); - self.output.push_str(": "); - match item { - WorldItem::Interface(id) => { - if resolve.interfaces[*id].name.is_some() { - self.print_path_to_interface(resolve, *id, cur_doc)?; - self.output.push_str("\n"); - } else { - writeln!(self.output, "interface {{")?; - self.print_interface(resolve, *id)?; - writeln!(self.output, "}}")?; + match name { + WorldKey::Name(name) => { + self.print_name(name); + self.output.push_str(": "); + match item { + WorldItem::Interface(id) => { + assert!(resolve.interfaces[*id].name.is_none()); + writeln!(self.output, "interface {{")?; + self.print_interface(resolve, *id)?; + writeln!(self.output, "}}")?; + } + WorldItem::Function(f) => { + self.print_function(resolve, f)?; + self.output.push_str("\n"); + } + // Types are handled separately + WorldItem::Type(_) => unreachable!(), } } - WorldItem::Function(f) => { - self.print_function(resolve, f)?; + WorldKey::Interface(id) => { + match item { + WorldItem::Interface(id2) => assert_eq!(id, id2), + _ => unreachable!(), + } + self.print_path_to_interface(resolve, *id, cur_pkg)?; self.output.push_str("\n"); } - // Types are handled separately - WorldItem::Type(_) => unreachable!(), } Ok(()) } @@ -235,24 +248,22 @@ impl DocumentPrinter { &mut self, resolve: &Resolve, interface: InterfaceId, - cur_doc: DocumentId, + cur_pkg: PackageId, ) -> Result<()> { - let cur_pkg = resolve.documents[cur_doc].package; let iface = &resolve.interfaces[interface]; - let iface_doc = &resolve.documents[iface.document]; - if iface.document == cur_doc { - self.output.push_str("self"); - } else if cur_pkg == iface_doc.package { - self.output.push_str("pkg."); - self.print_name(&iface_doc.name); + if iface.package == Some(cur_pkg) { + self.print_name(iface.name.as_ref().unwrap()); } else { - let iface_pkg = &resolve.packages[iface_doc.package.unwrap()]; - self.print_name(&iface_pkg.name); - self.output.push_str("."); - self.print_name(&iface_doc.name); + let pkg = &resolve.packages[iface.package.unwrap()].name; + self.print_name(&pkg.namespace); + self.output.push_str(":"); + self.print_name(&pkg.name); + self.output.push_str("/"); + self.print_name(iface.name.as_ref().unwrap()); + if let Some(version) = &pkg.version { + self.output.push_str(&format!("@{version}")); + } } - self.output.push_str("."); - self.print_name(iface.name.as_ref().unwrap()); Ok(()) } @@ -619,7 +630,7 @@ fn is_keyword(name: &str) -> bool { | "float32" | "float64" | "char" | "record" | "flags" | "variant" | "enum" | "union" | "bool" | "string" | "option" | "result" | "future" | "stream" | "list" | "_" | "as" | "from" | "static" | "interface" | "tuple" | "implements" | "world" | "import" - | "export" | "default" | "pkg" | "self" => true, + | "export" | "default" | "pkg" | "self" | "package" => true, _ => false, } } diff --git a/crates/wit-component/src/validation.rs b/crates/wit-component/src/validation.rs index 6e03f1199f..a755ba247f 100644 --- a/crates/wit-component/src/validation.rs +++ b/crates/wit-component/src/validation.rs @@ -1,13 +1,14 @@ use crate::metadata::{Bindgen, ModuleMetadata}; use anyhow::{anyhow, bail, Context, Result}; use indexmap::{map::Entry, IndexMap, IndexSet}; +use wasmparser::names::{KebabName, KebabNameKind}; use wasmparser::{ - types::Types, Encoding, ExternalKind, FuncType, Parser, Payload, TypeRef, ValType, - ValidPayload, Validator, + types::Types, ComponentExternName, Encoding, ExternalKind, FuncType, Parser, Payload, TypeRef, + ValType, ValidPayload, Validator, }; use wit_parser::{ abi::{AbiVariant, WasmSignature, WasmType}, - Function, InterfaceId, Resolve, WorldId, WorldItem, + Function, InterfaceId, PackageName, Resolve, WorldId, WorldItem, WorldKey, }; fn is_canonical_function(name: &str) -> bool { @@ -92,7 +93,7 @@ pub struct ValidatedModule<'a> { pub fn validate_module<'a>( bytes: &'a [u8], metadata: &'a Bindgen, - exports: &IndexSet, + exports: &IndexSet, adapters: &IndexSet<&str>, ) -> Result> { let mut validator = Validator::new(); @@ -176,7 +177,7 @@ pub fn validate_module<'a>( for (name, funcs) in &import_funcs { // An empty module name is indicative of the top-level import namespace, // so look for top-level functions here. - if *name == "$root" { + if *name == BARE_FUNC_MODULE_NAME { validate_imports_top_level(&metadata.resolve, metadata.world, funcs, &types)?; let funcs = funcs.keys().cloned().collect(); let prev = ret.required_imports.insert(BARE_FUNC_MODULE_NAME, funcs); @@ -184,7 +185,7 @@ pub fn validate_module<'a>( continue; } - match world.imports.get(*name) { + match world.imports.get(&world_key(&metadata.resolve, name)) { Some(WorldItem::Interface(interface)) => { let funcs = validate_imported_interface(&metadata.resolve, *interface, name, funcs, &types) @@ -209,7 +210,7 @@ pub fn validate_module<'a>( validate_exported_item( &metadata.resolve, &world.exports[name], - name, + &metadata.resolve.name_world_key(name), &export_funcs, &types, )?; @@ -226,7 +227,7 @@ pub struct ValidatedAdapter<'a> { /// If specified this is the list of required imports from the original set /// of possible imports along with the set of functions required from each /// imported interface. - pub required_imports: IndexMap<&'a str, IndexSet<&'a str>>, + pub required_imports: IndexMap>, /// This is the module and field name of the memory import, if one is /// specified. @@ -373,19 +374,26 @@ pub fn validate_adapter_module<'a>( let funcs = resolve.worlds[world] .imports .iter() - .filter_map(|(name, item)| match item { - WorldItem::Function(_) if funcs.contains_key(name.as_str()) => { - Some(name.as_str()) + .filter_map(|(name, item)| { + let name = match name { + WorldKey::Name(name) => name, + WorldKey::Interface(_) => return None, + }; + match item { + WorldItem::Function(_) if funcs.contains_key(name.as_str()) => { + Some(name.as_str()) + } + _ => None, } - _ => None, }) .collect(); - ret.required_imports.insert(BARE_FUNC_MODULE_NAME, funcs); + ret.required_imports + .insert(BARE_FUNC_MODULE_NAME.to_string(), funcs); continue; } - match resolve.worlds[world].imports.get_full(name) { - Some((_, name, WorldItem::Interface(interface))) => { + match resolve.worlds[world].imports.get(&world_key(resolve, name)) { + Some(WorldItem::Interface(interface)) => { validate_imported_interface(resolve, *interface, name, &funcs, &types) .with_context(|| format!("failed to validate import interface `{name}`"))?; let funcs = resolve.interfaces[*interface] @@ -394,10 +402,10 @@ pub fn validate_adapter_module<'a>( .map(|s| s.as_str()) .filter(|s| funcs.contains_key(s)) .collect(); - let prev = ret.required_imports.insert(name, funcs); + let prev = ret.required_imports.insert(name.to_string(), funcs); assert!(prev.is_none()); } - None | Some((_, _, WorldItem::Function(_) | WorldItem::Type(_))) => { + None | Some(WorldItem::Function(_) | WorldItem::Type(_)) => { bail!( "adapter module requires an import interface named `{}`", name @@ -430,6 +438,39 @@ pub fn validate_adapter_module<'a>( Ok(ret) } +fn world_key(resolve: &Resolve, name: &str) -> WorldKey { + let name = if name.contains('/') { + ComponentExternName::Interface(name) + } else { + ComponentExternName::Kebab(name) + }; + let kebab_name = KebabName::new(name, 0); + let (pkgname, interface) = match kebab_name.as_ref().map(|k| k.kind()) { + Ok(KebabNameKind::Id { + namespace, + package, + version, + interface, + }) => ( + PackageName { + namespace: namespace.as_str().to_string(), + name: package.as_str().to_string(), + version, + }, + interface.as_str(), + ), + _ => return WorldKey::Name(name.as_str().to_string()), + }; + match resolve + .package_names + .get(&pkgname) + .and_then(|p| resolve.packages[*p].interfaces.get(interface)) + { + Some(id) => WorldKey::Interface(*id), + None => WorldKey::Name(name.as_str().to_string()), + } +} + fn validate_imports_top_level<'a>( resolve: &Resolve, world: WorldId, @@ -437,7 +478,7 @@ fn validate_imports_top_level<'a>( types: &Types, ) -> Result<()> { for (name, ty) in funcs { - let func = match resolve.worlds[world].imports.get(*name) { + let func = match resolve.worlds[world].imports.get(&world_key(resolve, name)) { Some(WorldItem::Function(func)) => func, Some(_) => bail!("expected world top-level import `{name}` to be a function"), None => bail!("no top-level imported function `{name}` specified"), @@ -462,9 +503,7 @@ fn validate_imported_interface<'a>( .get(*func_name) .ok_or_else(|| { anyhow!( - "import interface `{}` is missing function `{}` that is required by the module", - name, - func_name, + "import interface `{name}` is missing function `{func_name}` that is required by the module", ) })?; diff --git a/crates/wit-component/tests/components.rs b/crates/wit-component/tests/components.rs index 36de6987c5..af5e8f70f5 100644 --- a/crates/wit-component/tests/components.rs +++ b/crates/wit-component/tests/components.rs @@ -1,9 +1,9 @@ -use anyhow::{anyhow, Result}; +use anyhow::{bail, Context, Result}; use pretty_assertions::assert_eq; use std::{borrow::Cow, fs, path::Path}; use wasm_encoder::{Encode, Section}; -use wit_component::{ComponentEncoder, DecodedWasm, DocumentPrinter, StringEncoding}; -use wit_parser::{PackageId, Resolve}; +use wit_component::{ComponentEncoder, DecodedWasm, StringEncoding, WitPrinter}; +use wit_parser::{PackageId, Resolve, UnresolvedPackage}; /// Tests the encoding of components. /// @@ -56,12 +56,20 @@ fn component_encoding_via_flags() -> Result<()> { let mut encoder = ComponentEncoder::default().module(&module)?.validate(true); encoder = add_adapters(encoder, &path, &resolve, pkg)?; let component_path = path.join("component.wat"); - let component_wit_path = path.join("component.wit"); + let component_wit_path = path.join("component.wit.print"); let error_path = path.join("error.txt"); let bytes = match encoder.encode() { - Ok(bytes) => bytes, + Ok(bytes) => { + if test_case.starts_with("error-") { + bail!("expected an error but got success"); + } + bytes + } Err(err) => { + if !test_case.starts_with("error-") { + return Err(err.into()); + } assert_output(&format!("{err:?}"), &error_path)?; continue; } @@ -69,13 +77,18 @@ fn component_encoding_via_flags() -> Result<()> { let wat = wasmprinter::print_bytes(&bytes)?; assert_output(&wat, &component_path)?; - let (doc, resolve) = match wit_component::decode("component", &bytes)? { + let (pkg, resolve) = match wit_component::decode(&bytes)? { DecodedWasm::WitPackage(..) => unreachable!(), - DecodedWasm::Component(resolve, world) => (resolve.worlds[world].document, resolve), + DecodedWasm::Component(resolve, world) => { + (resolve.worlds[world].package.unwrap(), resolve) + } }; - let wit = DocumentPrinter::default().print(&resolve, doc)?; + let wit = WitPrinter::default().print(&resolve, pkg)?; assert_output(&wit, &component_wit_path)?; + UnresolvedPackage::parse(&component_wit_path, &wit) + .context("failed to parse printed WIT")?; + // Check that the producer data got piped through properly let metadata = wasm_metadata::Metadata::from_binary(&bytes)?; match metadata { @@ -132,13 +145,9 @@ fn add_adapters( fn read_core_module(path: &Path, resolve: &Resolve, pkg: PackageId) -> Result> { let mut wasm = wat::parse_file(path)?; let name = path.file_stem().and_then(|s| s.to_str()).unwrap(); - let doc = *resolve.packages[pkg] - .documents - .get(name) - .ok_or_else(|| anyhow!("failed to find document named `{name}`"))?; - let world = resolve.documents[doc] - .default_world - .ok_or_else(|| anyhow!("failed to find default world in document `{name}`"))?; + let world = resolve + .select_world(pkg, Some(name)) + .context("failed to select a world")?; // Add this producer data to the wit-component metadata so we can make sure it gets through the // translation: diff --git a/crates/wit-component/tests/components/adapt-empty-interface/adapt-old.wit b/crates/wit-component/tests/components/adapt-empty-interface/adapt-old.wit index e38000c63e..3a1842c8ec 100644 --- a/crates/wit-component/tests/components/adapt-empty-interface/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-empty-interface/adapt-old.wit @@ -1,4 +1,4 @@ -default world new { +world adapt-old { import new: interface { thunk-that-is-not-called: func() } diff --git a/crates/wit-component/tests/components/adapt-empty-interface/component.wit b/crates/wit-component/tests/components/adapt-empty-interface/component.wit deleted file mode 100644 index da09ea6eeb..0000000000 --- a/crates/wit-component/tests/components/adapt-empty-interface/component.wit +++ /dev/null @@ -1,2 +0,0 @@ -default world component { -} diff --git a/crates/wit-component/tests/components/adapt-empty-interface/component.wit.print b/crates/wit-component/tests/components/adapt-empty-interface/component.wit.print new file mode 100644 index 0000000000..bcd860d376 --- /dev/null +++ b/crates/wit-component/tests/components/adapt-empty-interface/component.wit.print @@ -0,0 +1,4 @@ +package root:component + +world root { +} diff --git a/crates/wit-component/tests/components/adapt-empty-interface/module.wit b/crates/wit-component/tests/components/adapt-empty-interface/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-empty-interface/module.wit +++ b/crates/wit-component/tests/components/adapt-empty-interface/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/adapt-export-default/adapt-old.wit b/crates/wit-component/tests/components/adapt-export-default/adapt-old.wit index ad8e637513..8e9934c7d1 100644 --- a/crates/wit-component/tests/components/adapt-export-default/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-export-default/adapt-old.wit @@ -1,3 +1,3 @@ -default world new { +world adapt-old { export entrypoint: func() } diff --git a/crates/wit-component/tests/components/adapt-export-default/component.wit b/crates/wit-component/tests/components/adapt-export-default/component.wit deleted file mode 100644 index 9368d1d606..0000000000 --- a/crates/wit-component/tests/components/adapt-export-default/component.wit +++ /dev/null @@ -1,3 +0,0 @@ -default world component { - export entrypoint: func() -} diff --git a/crates/wit-component/tests/components/adapt-export-default/component.wit.print b/crates/wit-component/tests/components/adapt-export-default/component.wit.print new file mode 100644 index 0000000000..3b69830770 --- /dev/null +++ b/crates/wit-component/tests/components/adapt-export-default/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + export entrypoint: func() +} diff --git a/crates/wit-component/tests/components/adapt-export-default/module.wit b/crates/wit-component/tests/components/adapt-export-default/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-export-default/module.wit +++ b/crates/wit-component/tests/components/adapt-export-default/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/adapt-export-namespaced/adapt-old.wat b/crates/wit-component/tests/components/adapt-export-namespaced/adapt-old.wat index 03a9536997..0c4debd062 100644 --- a/crates/wit-component/tests/components/adapt-export-namespaced/adapt-old.wat +++ b/crates/wit-component/tests/components/adapt-export-namespaced/adapt-old.wat @@ -1,4 +1,4 @@ (module (import "__main_module__" "the_entrypoint" (func $entry)) - (export "new#entrypoint" (func $entry)) + (export "foo:foo/new#entrypoint" (func $entry)) ) diff --git a/crates/wit-component/tests/components/adapt-export-namespaced/adapt-old.wit b/crates/wit-component/tests/components/adapt-export-namespaced/adapt-old.wit index 4e4ff9c6bf..177d5d1767 100644 --- a/crates/wit-component/tests/components/adapt-export-namespaced/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-export-namespaced/adapt-old.wit @@ -2,6 +2,6 @@ interface new { entrypoint: func() } -default world brave-new-world { - export new: self.new +world adapt-old { + export new } diff --git a/crates/wit-component/tests/components/adapt-export-namespaced/component.wat b/crates/wit-component/tests/components/adapt-export-namespaced/component.wat index 38871a0a33..3d2f95a658 100644 --- a/crates/wit-component/tests/components/adapt-export-namespaced/component.wat +++ b/crates/wit-component/tests/components/adapt-export-namespaced/component.wat @@ -11,7 +11,7 @@ (core module (;1;) (type (;0;) (func)) (import "__main_module__" "the_entrypoint" (func $entry (;0;) (type 0))) - (export "new#entrypoint" (func $entry)) + (export "foo:foo/new#entrypoint" (func $entry)) ) (core instance (;0;) (instantiate 0)) (alias core export 0 "the_entrypoint" (core func (;0;))) @@ -23,7 +23,7 @@ ) ) (type (;0;) (func)) - (alias core export 2 "new#entrypoint" (core func (;1;))) + (alias core export 2 "foo:foo/new#entrypoint" (core func (;1;))) (func (;0;) (type 0) (canon lift (core func 1))) (component (;0;) (type (;0;) (func)) @@ -38,5 +38,5 @@ (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "new" (instance 0)) + (export (;1;) (interface "foo:foo/new") (instance 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/adapt-export-namespaced/component.wit b/crates/wit-component/tests/components/adapt-export-namespaced/component.wit deleted file mode 100644 index 90160cd85d..0000000000 --- a/crates/wit-component/tests/components/adapt-export-namespaced/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - entrypoint: func() -} - -default world component { - export new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-export-namespaced/component.wit.print b/crates/wit-component/tests/components/adapt-export-namespaced/component.wit.print new file mode 100644 index 0000000000..d4d0543221 --- /dev/null +++ b/crates/wit-component/tests/components/adapt-export-namespaced/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + export foo:foo/new +} diff --git a/crates/wit-component/tests/components/adapt-export-namespaced/module.wit b/crates/wit-component/tests/components/adapt-export-namespaced/module.wit index 234a91911c..3f66e96f0d 100644 --- a/crates/wit-component/tests/components/adapt-export-namespaced/module.wit +++ b/crates/wit-component/tests/components/adapt-export-namespaced/module.wit @@ -1 +1,3 @@ -default world foo {} +package foo:foo + +world module {} diff --git a/crates/wit-component/tests/components/adapt-export-reallocs/adapt-old.wit b/crates/wit-component/tests/components/adapt-export-reallocs/adapt-old.wit index d342fe79d2..33ecfc28d0 100644 --- a/crates/wit-component/tests/components/adapt-export-reallocs/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-export-reallocs/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { read: func(amt: u32) -> list } diff --git a/crates/wit-component/tests/components/adapt-export-reallocs/component.wit b/crates/wit-component/tests/components/adapt-export-reallocs/component.wit deleted file mode 100644 index 49897fff21..0000000000 --- a/crates/wit-component/tests/components/adapt-export-reallocs/component.wit +++ /dev/null @@ -1,8 +0,0 @@ -interface new { - read: func(amt: u32) -> list -} - -default world component { - import new: self.new - export entrypoint: func(args: list) -} diff --git a/crates/wit-component/tests/components/adapt-export-reallocs/component.wit.print b/crates/wit-component/tests/components/adapt-export-reallocs/component.wit.print new file mode 100644 index 0000000000..d7e2f2b45a --- /dev/null +++ b/crates/wit-component/tests/components/adapt-export-reallocs/component.wit.print @@ -0,0 +1,8 @@ +package root:component + +world root { + import new: interface { + read: func(amt: u32) -> list + } + export entrypoint: func(args: list) +} diff --git a/crates/wit-component/tests/components/adapt-export-reallocs/module.wit b/crates/wit-component/tests/components/adapt-export-reallocs/module.wit index 1f99081f58..3f66e96f0d 100644 --- a/crates/wit-component/tests/components/adapt-export-reallocs/module.wit +++ b/crates/wit-component/tests/components/adapt-export-reallocs/module.wit @@ -1 +1,3 @@ -default world empty {} +package foo:foo + +world module {} diff --git a/crates/wit-component/tests/components/adapt-export-save-args/adapt-old.wit b/crates/wit-component/tests/components/adapt-export-save-args/adapt-old.wit index 3f6bd6a293..2185e1f136 100644 --- a/crates/wit-component/tests/components/adapt-export-save-args/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-export-save-args/adapt-old.wit @@ -1,3 +1,3 @@ -default world brave-new-world { +world adapt-old { export entrypoint: func(nargs: u32) } diff --git a/crates/wit-component/tests/components/adapt-export-save-args/component.wit b/crates/wit-component/tests/components/adapt-export-save-args/component.wit.print similarity index 51% rename from crates/wit-component/tests/components/adapt-export-save-args/component.wit rename to crates/wit-component/tests/components/adapt-export-save-args/component.wit.print index e5a72119ea..1946b9c042 100644 --- a/crates/wit-component/tests/components/adapt-export-save-args/component.wit +++ b/crates/wit-component/tests/components/adapt-export-save-args/component.wit.print @@ -1,3 +1,5 @@ -default world component { +package root:component + +world root { export entrypoint: func(nargs: u32) } diff --git a/crates/wit-component/tests/components/adapt-export-save-args/module.wit b/crates/wit-component/tests/components/adapt-export-save-args/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-export-save-args/module.wit +++ b/crates/wit-component/tests/components/adapt-export-save-args/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/adapt-export-with-post-return/adapt-old.wat b/crates/wit-component/tests/components/adapt-export-with-post-return/adapt-old.wat index be58c40117..197c7014ff 100644 --- a/crates/wit-component/tests/components/adapt-export-with-post-return/adapt-old.wat +++ b/crates/wit-component/tests/components/adapt-export-with-post-return/adapt-old.wat @@ -13,7 +13,7 @@ (global $__stack_pointer (mut i32) i32.const 0) (global $allocation_state (mut i32) i32.const 0) - (func (export "new#foo") (result i32) + (func (export "foo:foo/new#foo") (result i32) ;; This is a dummy, non-working implementation, just to make gc.rs do what ;; we want, which is to treat this adapter as if it uses the main module's ;; allocator to allocate and free memory. @@ -24,7 +24,7 @@ unreachable ) - (func (export "cabi_post_new#foo") (param i32) + (func (export "cabi_post_foo:foo/new#foo") (param i32) ;; another dummy implementation (call $free (i32.const 0) (i32.const 0) (i32.const 0)) diff --git a/crates/wit-component/tests/components/adapt-export-with-post-return/adapt-old.wit b/crates/wit-component/tests/components/adapt-export-with-post-return/adapt-old.wit index 930847c54d..5f8405e296 100644 --- a/crates/wit-component/tests/components/adapt-export-with-post-return/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-export-with-post-return/adapt-old.wit @@ -2,6 +2,6 @@ interface new { foo: func() -> string } -default world brave-new-world { - export new: self.new +world adapt-old { + export new } diff --git a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat index 4f516f56fb..cfeff1cfae 100644 --- a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat +++ b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wat @@ -65,8 +65,8 @@ ) (global $__stack_pointer (;0;) (mut i32) i32.const 0) (global $allocation_state (;1;) (mut i32) i32.const 0) - (export "new#foo" (func 2)) - (export "cabi_post_new#foo" (func 3)) + (export "foo:foo/new#foo" (func 2)) + (export "cabi_post_foo:foo/new#foo" (func 3)) ) (core instance (;0;) (instantiate 0)) (alias core export 0 "memory" (core memory (;0;))) @@ -82,8 +82,8 @@ ) ) (type (;0;) (func (result string))) - (alias core export 2 "new#foo" (core func (;3;))) - (alias core export 2 "cabi_post_new#foo" (core func (;4;))) + (alias core export 2 "foo:foo/new#foo" (core func (;3;))) + (alias core export 2 "cabi_post_foo:foo/new#foo" (core func (;4;))) (func (;0;) (type 0) (canon lift (core func 3) (memory 0) string-encoding=utf8 (post-return 4))) (component (;0;) (type (;0;) (func (result string))) @@ -98,5 +98,5 @@ (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "new" (instance 0)) + (export (;1;) (interface "foo:foo/new") (instance 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wit b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wit deleted file mode 100644 index 380b11b06e..0000000000 --- a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - foo: func() -> string -} - -default world component { - export new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-export-with-post-return/component.wit.print b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wit.print new file mode 100644 index 0000000000..d4d0543221 --- /dev/null +++ b/crates/wit-component/tests/components/adapt-export-with-post-return/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + export foo:foo/new +} diff --git a/crates/wit-component/tests/components/adapt-export-with-post-return/module.wit b/crates/wit-component/tests/components/adapt-export-with-post-return/module.wit index 234a91911c..3f66e96f0d 100644 --- a/crates/wit-component/tests/components/adapt-export-with-post-return/module.wit +++ b/crates/wit-component/tests/components/adapt-export-with-post-return/module.wit @@ -1 +1,3 @@ -default world foo {} +package foo:foo + +world module {} diff --git a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/adapt-unused.wat b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/adapt-unused.wat index 75fac0229d..ea9a0b70f9 100644 --- a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/adapt-unused.wat +++ b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/adapt-unused.wat @@ -1,5 +1,5 @@ (module - (import "adapter-imports" "foo" (func $foo (param i32 i32))) + (import "foo:foo/adapter-imports" "foo" (func $foo (param i32 i32))) (func (export "adapter-bar") (param i32 i32) (call $foo (i32.const 0) (i32.const 0)) ) diff --git a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/adapt-unused.wit b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/adapt-unused.wit index 72f5cdc42d..a434c40eac 100644 --- a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/adapt-unused.wit +++ b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/adapt-unused.wit @@ -2,8 +2,8 @@ interface adapter-imports { foo: func(x: string) } -default world the-world { - import adapter-imports: self.adapter-imports +world adapt-unused { + import adapter-imports export adapter-bar: func(x: string) } diff --git a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat index ae5eb2c238..9f084cf645 100644 --- a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat +++ b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wat @@ -5,7 +5,7 @@ (export (;0;) "foo" (func (type 0))) ) ) - (import "adapter-imports" (instance (;0;) (type 0))) + (import (interface "foo:foo/adapter-imports") (instance (;0;) (type 0))) (type (;1;) (func (param "x" string))) (import "foo" (func (;0;) (type 1))) (core module (;0;) @@ -26,7 +26,7 @@ (core module (;1;) (type (;0;) (func (param i32 i32))) (type (;1;) (func (param i32 i32 i32 i32) (result i32))) - (import "adapter-imports" "foo" (func $foo (;0;) (type 0))) + (import "foo:foo/adapter-imports" "foo" (func $foo (;0;) (type 0))) (func (;1;) (type 0) (param i32 i32) i32.const 0 i32.const 0 @@ -46,7 +46,7 @@ i32.const 0 call_indirect (type 0) ) - (func $indirect-adapter-imports-foo (;1;) (type 0) (param i32 i32) + (func $indirect-foo:foo/adapter-imports-foo (;1;) (type 0) (param i32 i32) local.get 0 local.get 1 i32.const 1 @@ -54,7 +54,7 @@ ) (table (;0;) 2 2 funcref) (export "0" (func $indirect-$root-foo)) - (export "1" (func $indirect-adapter-imports-foo)) + (export "1" (func $indirect-foo:foo/adapter-imports-foo)) (export "$imports" (table 0)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") @@ -85,7 +85,7 @@ (export "foo" (func 1)) ) (core instance (;4;) (instantiate 1 - (with "adapter-imports" (instance 3)) + (with "foo:foo/adapter-imports" (instance 3)) ) ) (alias core export 4 "cabi_export_realloc" (core func (;2;))) diff --git a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wit b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wit deleted file mode 100644 index cc54d71d19..0000000000 --- a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wit +++ /dev/null @@ -1,10 +0,0 @@ -interface adapter-imports { - foo: func(x: string) -} - -default world component { - import adapter-imports: self.adapter-imports - import foo: func(x: string) - export bar: func() - export adapter-bar: func(x: string) -} diff --git a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wit.print b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wit.print new file mode 100644 index 0000000000..0b750ef43b --- /dev/null +++ b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/component.wit.print @@ -0,0 +1,8 @@ +package root:component + +world root { + import foo:foo/adapter-imports + import foo: func(x: string) + export bar: func() + export adapter-bar: func(x: string) +} diff --git a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/module.wit b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/module.wit index c5a59c1471..25ed69fadc 100644 --- a/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/module.wit +++ b/crates/wit-component/tests/components/adapt-import-only-used-in-adapter/module.wit @@ -1,4 +1,6 @@ -default world foo { +package foo:foo + +world module { import foo: func(x: string) export bar: func() } diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/adapt-old.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/adapt-old.wit index 7a56eb164a..dab8bec032 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { get-two: func() -> (a: u32, b: u32) } diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wit deleted file mode 100644 index d570b2929b..0000000000 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - get-two: func() -> (a: u32, b: u32) -} - -default world component { - import new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wit.print b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wit.print new file mode 100644 index 0000000000..b1f183513f --- /dev/null +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import new: interface { + get-two: func() -> (a: u32, b: u32) + } +} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/module.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/module.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-adapt-realloc/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/adapt-old.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/adapt-old.wit index 7a56eb164a..dab8bec032 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { get-two: func() -> (a: u32, b: u32) } diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wit deleted file mode 100644 index d570b2929b..0000000000 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - get-two: func() -> (a: u32, b: u32) -} - -default world component { - import new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wit.print b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wit.print new file mode 100644 index 0000000000..b1f183513f --- /dev/null +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import new: interface { + get-two: func() -> (a: u32, b: u32) + } +} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/module.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/module.wit index 1f99081f58..3f66e96f0d 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/module.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc-no-state/module.wit @@ -1 +1,3 @@ -default world empty {} +package foo:foo + +world module {} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/adapt-old.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/adapt-old.wit index 7a56eb164a..dab8bec032 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { get-two: func() -> (a: u32, b: u32) } diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wit deleted file mode 100644 index d570b2929b..0000000000 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - get-two: func() -> (a: u32, b: u32) -} - -default world component { - import new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wit.print b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wit.print new file mode 100644 index 0000000000..b1f183513f --- /dev/null +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import new: interface { + get-two: func() -> (a: u32, b: u32) + } +} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/module.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/module.wit index 1f99081f58..3f66e96f0d 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/module.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-realloc/module.wit @@ -1 +1,3 @@ -default world empty {} +package foo:foo + +world module {} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/adapt-old.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/adapt-old.wit index 7a56eb164a..dab8bec032 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { get-two: func() -> (a: u32, b: u32) } diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wit deleted file mode 100644 index d570b2929b..0000000000 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - get-two: func() -> (a: u32, b: u32) -} - -default world component { - import new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wit.print b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wit.print new file mode 100644 index 0000000000..b1f183513f --- /dev/null +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import new: interface { + get-two: func() -> (a: u32, b: u32) + } +} diff --git a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/module.wit b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/module.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack-with-reallocing-adapter/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/adapt-inject-stack/adapt-old.wit b/crates/wit-component/tests/components/adapt-inject-stack/adapt-old.wit index 7a56eb164a..dab8bec032 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { get-two: func() -> (a: u32, b: u32) } diff --git a/crates/wit-component/tests/components/adapt-inject-stack/component.wit b/crates/wit-component/tests/components/adapt-inject-stack/component.wit deleted file mode 100644 index d570b2929b..0000000000 --- a/crates/wit-component/tests/components/adapt-inject-stack/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - get-two: func() -> (a: u32, b: u32) -} - -default world component { - import new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-inject-stack/component.wit.print b/crates/wit-component/tests/components/adapt-inject-stack/component.wit.print new file mode 100644 index 0000000000..b1f183513f --- /dev/null +++ b/crates/wit-component/tests/components/adapt-inject-stack/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import new: interface { + get-two: func() -> (a: u32, b: u32) + } +} diff --git a/crates/wit-component/tests/components/adapt-inject-stack/module.wit b/crates/wit-component/tests/components/adapt-inject-stack/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-inject-stack/module.wit +++ b/crates/wit-component/tests/components/adapt-inject-stack/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/adapt-list-return/adapt-old.wit b/crates/wit-component/tests/components/adapt-list-return/adapt-old.wit index d321768c2f..35bcef4a63 100644 --- a/crates/wit-component/tests/components/adapt-list-return/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-list-return/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { read: func() -> list } diff --git a/crates/wit-component/tests/components/adapt-list-return/component.wit b/crates/wit-component/tests/components/adapt-list-return/component.wit deleted file mode 100644 index cdcc76911c..0000000000 --- a/crates/wit-component/tests/components/adapt-list-return/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - read: func() -> list -} - -default world component { - import new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-list-return/component.wit.print b/crates/wit-component/tests/components/adapt-list-return/component.wit.print new file mode 100644 index 0000000000..6a5d7c87d0 --- /dev/null +++ b/crates/wit-component/tests/components/adapt-list-return/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import new: interface { + read: func() -> list + } +} diff --git a/crates/wit-component/tests/components/adapt-list-return/module.wit b/crates/wit-component/tests/components/adapt-list-return/module.wit index 1f99081f58..3f66e96f0d 100644 --- a/crates/wit-component/tests/components/adapt-list-return/module.wit +++ b/crates/wit-component/tests/components/adapt-list-return/module.wit @@ -1 +1,3 @@ -default world empty {} +package foo:foo + +world module {} diff --git a/crates/wit-component/tests/components/adapt-memory-simple/adapt-old.wit b/crates/wit-component/tests/components/adapt-memory-simple/adapt-old.wit index 5a86aec124..5dd4f661e2 100644 --- a/crates/wit-component/tests/components/adapt-memory-simple/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-memory-simple/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { log: func(s: string) } diff --git a/crates/wit-component/tests/components/adapt-memory-simple/component.wit b/crates/wit-component/tests/components/adapt-memory-simple/component.wit deleted file mode 100644 index dc408de3cb..0000000000 --- a/crates/wit-component/tests/components/adapt-memory-simple/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface new { - log: func(s: string) -} - -default world component { - import new: self.new -} diff --git a/crates/wit-component/tests/components/adapt-memory-simple/component.wit.print b/crates/wit-component/tests/components/adapt-memory-simple/component.wit.print new file mode 100644 index 0000000000..e7996e6e9e --- /dev/null +++ b/crates/wit-component/tests/components/adapt-memory-simple/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import new: interface { + log: func(s: string) + } +} diff --git a/crates/wit-component/tests/components/adapt-memory-simple/module.wit b/crates/wit-component/tests/components/adapt-memory-simple/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-memory-simple/module.wit +++ b/crates/wit-component/tests/components/adapt-memory-simple/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/adapt-missing-memory/module.wit b/crates/wit-component/tests/components/adapt-missing-memory/module.wit deleted file mode 100644 index 1f99081f58..0000000000 --- a/crates/wit-component/tests/components/adapt-missing-memory/module.wit +++ /dev/null @@ -1 +0,0 @@ -default world empty {} diff --git a/crates/wit-component/tests/components/adapt-multiple/adapt-foo.wit b/crates/wit-component/tests/components/adapt-multiple/adapt-foo.wit index bf449c18ec..20e46ac82d 100644 --- a/crates/wit-component/tests/components/adapt-multiple/adapt-foo.wit +++ b/crates/wit-component/tests/components/adapt-multiple/adapt-foo.wit @@ -1,4 +1,4 @@ -default world new-foo-world { +world adapt-foo { import other1: interface { foo: func() } diff --git a/crates/wit-component/tests/components/adapt-multiple/component.wit b/crates/wit-component/tests/components/adapt-multiple/component.wit deleted file mode 100644 index 5b111ba21f..0000000000 --- a/crates/wit-component/tests/components/adapt-multiple/component.wit +++ /dev/null @@ -1,12 +0,0 @@ -interface other1 { - foo: func() -} - -interface other2 { - bar: func() -} - -default world component { - import other1: self.other1 - import other2: self.other2 -} diff --git a/crates/wit-component/tests/components/adapt-multiple/component.wit.print b/crates/wit-component/tests/components/adapt-multiple/component.wit.print new file mode 100644 index 0000000000..bfdb507a66 --- /dev/null +++ b/crates/wit-component/tests/components/adapt-multiple/component.wit.print @@ -0,0 +1,10 @@ +package root:component + +world root { + import other1: interface { + foo: func() + } + import other2: interface { + bar: func() + } +} diff --git a/crates/wit-component/tests/components/adapt-multiple/module.wit b/crates/wit-component/tests/components/adapt-multiple/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-multiple/module.wit +++ b/crates/wit-component/tests/components/adapt-multiple/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/adapt-preview1/adapt-wasi-snapshot-preview1.wat b/crates/wit-component/tests/components/adapt-preview1/adapt-wasi-snapshot-preview1.wat index f568306e22..0b9abe3ad5 100644 --- a/crates/wit-component/tests/components/adapt-preview1/adapt-wasi-snapshot-preview1.wat +++ b/crates/wit-component/tests/components/adapt-preview1/adapt-wasi-snapshot-preview1.wat @@ -2,7 +2,7 @@ ;; interface (module - (import "my-wasi" "proc-exit" (func $proc_exit (param i32))) + (import "foo:foo/my-wasi" "proc-exit" (func $proc_exit (param i32))) (func (export "proc_exit") (param i32) local.get 0 call $proc_exit diff --git a/crates/wit-component/tests/components/adapt-preview1/adapt-wasi-snapshot-preview1.wit b/crates/wit-component/tests/components/adapt-preview1/adapt-wasi-snapshot-preview1.wit index 65035733e0..c1ffe08ada 100644 --- a/crates/wit-component/tests/components/adapt-preview1/adapt-wasi-snapshot-preview1.wit +++ b/crates/wit-component/tests/components/adapt-preview1/adapt-wasi-snapshot-preview1.wit @@ -7,6 +7,6 @@ interface my-wasi { something-not-used: func() } -default world adapter { - import my-wasi: self.my-wasi +world adapt-wasi-snapshot-preview1 { + import my-wasi } diff --git a/crates/wit-component/tests/components/adapt-preview1/component.wat b/crates/wit-component/tests/components/adapt-preview1/component.wat index 11faec4972..cecd538692 100644 --- a/crates/wit-component/tests/components/adapt-preview1/component.wat +++ b/crates/wit-component/tests/components/adapt-preview1/component.wat @@ -12,7 +12,7 @@ (export (;0;) "proc-exit" (func (type 0))) ) ) - (import "my-wasi" (instance (;1;) (type 1))) + (import (interface "foo:foo/my-wasi") (instance (;1;) (type 1))) (core module (;0;) (type (;0;) (func)) (type (;1;) (func (param i32))) @@ -30,7 +30,7 @@ (core module (;1;) (type (;0;) (func (param i32))) (type (;1;) (func (param i32 i32) (result i32))) - (import "my-wasi" "proc-exit" (func $proc_exit (;0;) (type 0))) + (import "foo:foo/my-wasi" "proc-exit" (func $proc_exit (;0;) (type 0))) (func (;1;) (type 0) (param i32) local.get 0 call $proc_exit @@ -98,7 +98,7 @@ (export "proc-exit" (func 3)) ) (core instance (;5;) (instantiate 1 - (with "my-wasi" (instance 4)) + (with "foo:foo/my-wasi" (instance 4)) ) ) (alias core export 0 "$imports" (core table (;0;))) diff --git a/crates/wit-component/tests/components/adapt-preview1/component.wit b/crates/wit-component/tests/components/adapt-preview1/component.wit deleted file mode 100644 index 25d767a1d2..0000000000 --- a/crates/wit-component/tests/components/adapt-preview1/component.wit +++ /dev/null @@ -1,12 +0,0 @@ -interface foo { - foo: func() -} - -interface my-wasi { - proc-exit: func(code: u32) -} - -default world component { - import foo: self.foo - import my-wasi: self.my-wasi -} diff --git a/crates/wit-component/tests/components/adapt-preview1/component.wit.print b/crates/wit-component/tests/components/adapt-preview1/component.wit.print new file mode 100644 index 0000000000..617992bb3e --- /dev/null +++ b/crates/wit-component/tests/components/adapt-preview1/component.wit.print @@ -0,0 +1,8 @@ +package root:component + +world root { + import foo: interface { + foo: func() + } + import foo:foo/my-wasi +} diff --git a/crates/wit-component/tests/components/adapt-preview1/module.wit b/crates/wit-component/tests/components/adapt-preview1/module.wit index b35cf9a1ec..419a16cf01 100644 --- a/crates/wit-component/tests/components/adapt-preview1/module.wit +++ b/crates/wit-component/tests/components/adapt-preview1/module.wit @@ -1,4 +1,6 @@ -default world my-world { +package foo:foo + +world module { import foo: interface { foo: func() } diff --git a/crates/wit-component/tests/components/adapt-unused/adapt-old.wit b/crates/wit-component/tests/components/adapt-unused/adapt-old.wit index 5a86aec124..5dd4f661e2 100644 --- a/crates/wit-component/tests/components/adapt-unused/adapt-old.wit +++ b/crates/wit-component/tests/components/adapt-unused/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { log: func(s: string) } diff --git a/crates/wit-component/tests/components/adapt-unused/component.wit b/crates/wit-component/tests/components/adapt-unused/component.wit deleted file mode 100644 index da09ea6eeb..0000000000 --- a/crates/wit-component/tests/components/adapt-unused/component.wit +++ /dev/null @@ -1,2 +0,0 @@ -default world component { -} diff --git a/crates/wit-component/tests/components/adapt-unused/component.wit.print b/crates/wit-component/tests/components/adapt-unused/component.wit.print new file mode 100644 index 0000000000..bcd860d376 --- /dev/null +++ b/crates/wit-component/tests/components/adapt-unused/component.wit.print @@ -0,0 +1,4 @@ +package root:component + +world root { +} diff --git a/crates/wit-component/tests/components/adapt-unused/module.wit b/crates/wit-component/tests/components/adapt-unused/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/adapt-unused/module.wit +++ b/crates/wit-component/tests/components/adapt-unused/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/bare-funcs/component.wit b/crates/wit-component/tests/components/bare-funcs/component.wit.print similarity index 77% rename from crates/wit-component/tests/components/bare-funcs/component.wit rename to crates/wit-component/tests/components/bare-funcs/component.wit.print index 82350270c1..91f1f83fca 100644 --- a/crates/wit-component/tests/components/bare-funcs/component.wit +++ b/crates/wit-component/tests/components/bare-funcs/component.wit.print @@ -1,4 +1,6 @@ -default world component { +package root:component + +world root { import foo: func() import bar: func() -> string export baz: func() diff --git a/crates/wit-component/tests/components/bare-funcs/module.wit b/crates/wit-component/tests/components/bare-funcs/module.wit index 4875567e17..3796acf556 100644 --- a/crates/wit-component/tests/components/bare-funcs/module.wit +++ b/crates/wit-component/tests/components/bare-funcs/module.wit @@ -1,4 +1,5 @@ -default world foo { +package foo:foo +world module { import foo: func() import bar: func() -> string export baz: func() diff --git a/crates/wit-component/tests/components/empty-module-import/module.wit b/crates/wit-component/tests/components/empty-module-import/module.wit deleted file mode 100644 index 1f99081f58..0000000000 --- a/crates/wit-component/tests/components/empty-module-import/module.wit +++ /dev/null @@ -1 +0,0 @@ -default world empty {} diff --git a/crates/wit-component/tests/components/empty/component.wit b/crates/wit-component/tests/components/empty/component.wit deleted file mode 100644 index da09ea6eeb..0000000000 --- a/crates/wit-component/tests/components/empty/component.wit +++ /dev/null @@ -1,2 +0,0 @@ -default world component { -} diff --git a/crates/wit-component/tests/components/empty/component.wit.print b/crates/wit-component/tests/components/empty/component.wit.print new file mode 100644 index 0000000000..bcd860d376 --- /dev/null +++ b/crates/wit-component/tests/components/empty/component.wit.print @@ -0,0 +1,4 @@ +package root:component + +world root { +} diff --git a/crates/wit-component/tests/components/empty/module.wit b/crates/wit-component/tests/components/empty/module.wit index 1f99081f58..65c2b79202 100644 --- a/crates/wit-component/tests/components/empty/module.wit +++ b/crates/wit-component/tests/components/empty/module.wit @@ -1 +1,2 @@ -default world empty {} +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/component.wat b/crates/wit-component/tests/components/ensure-default-type-exports/component.wat index 94e27d1d94..e67d3da271 100644 --- a/crates/wit-component/tests/components/ensure-default-type-exports/component.wat +++ b/crates/wit-component/tests/components/ensure-default-type-exports/component.wat @@ -9,11 +9,11 @@ (export (;0;) "a" (func (type 4))) ) ) - (import "foo" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (core module (;0;) (type (;0;) (func (param i32))) (type (;1;) (func (param i32 i32 i32 i32) (result i32))) - (import "foo" "a" (func (;0;) (type 0))) + (import "foo:foo/foo" "a" (func (;0;) (type 0))) (func (;1;) (type 1) (param i32 i32 i32 i32) (result i32) unreachable ) @@ -35,7 +35,7 @@ (export "a" (func 0)) ) (core instance (;1;) (instantiate 0 - (with "foo" (instance 0)) + (with "foo:foo/foo" (instance 0)) ) ) (alias core export 1 "memory" (core memory (;0;))) diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/component.wit b/crates/wit-component/tests/components/ensure-default-type-exports/component.wit deleted file mode 100644 index a7b39a50c9..0000000000 --- a/crates/wit-component/tests/components/ensure-default-type-exports/component.wit +++ /dev/null @@ -1,14 +0,0 @@ -interface foo { - type foo = u8 - - record bar { - x: foo, - } - - a: func(b: bar) -} - -default world component { - import foo: self.foo - export a: func(b: u8) -} diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/component.wit.print b/crates/wit-component/tests/components/ensure-default-type-exports/component.wit.print new file mode 100644 index 0000000000..ca7f581da4 --- /dev/null +++ b/crates/wit-component/tests/components/ensure-default-type-exports/component.wit.print @@ -0,0 +1,6 @@ +package root:component + +world root { + import foo:foo/foo + export a: func(b: u8) +} diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/module.wat b/crates/wit-component/tests/components/ensure-default-type-exports/module.wat index 4ddbbd4714..711b2a1449 100644 --- a/crates/wit-component/tests/components/ensure-default-type-exports/module.wat +++ b/crates/wit-component/tests/components/ensure-default-type-exports/module.wat @@ -1,5 +1,5 @@ (module - (import "foo" "a" (func (param i32))) + (import "foo:foo/foo" "a" (func (param i32))) (memory (export "memory") 1) (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) (func (export "a") (param i32) unreachable) diff --git a/crates/wit-component/tests/components/ensure-default-type-exports/module.wit b/crates/wit-component/tests/components/ensure-default-type-exports/module.wit index c66cd9c4df..a206eb9c12 100644 --- a/crates/wit-component/tests/components/ensure-default-type-exports/module.wit +++ b/crates/wit-component/tests/components/ensure-default-type-exports/module.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { type foo = u8 @@ -8,8 +10,8 @@ interface foo { a: func(b: bar) } -default world my-world { - import foo: self.foo +world module { + import foo export a: func(b: u8) } diff --git a/crates/wit-component/tests/components/adapt-missing-memory/adapt-old.wat b/crates/wit-component/tests/components/error-adapt-missing-memory/adapt-old.wat similarity index 100% rename from crates/wit-component/tests/components/adapt-missing-memory/adapt-old.wat rename to crates/wit-component/tests/components/error-adapt-missing-memory/adapt-old.wat diff --git a/crates/wit-component/tests/components/adapt-missing-memory/adapt-old.wit b/crates/wit-component/tests/components/error-adapt-missing-memory/adapt-old.wit similarity index 64% rename from crates/wit-component/tests/components/adapt-missing-memory/adapt-old.wit rename to crates/wit-component/tests/components/error-adapt-missing-memory/adapt-old.wit index 5a86aec124..5dd4f661e2 100644 --- a/crates/wit-component/tests/components/adapt-missing-memory/adapt-old.wit +++ b/crates/wit-component/tests/components/error-adapt-missing-memory/adapt-old.wit @@ -1,4 +1,4 @@ -default world brave-new-world { +world adapt-old { import new: interface { log: func(s: string) } diff --git a/crates/wit-component/tests/components/adapt-missing-memory/error.txt b/crates/wit-component/tests/components/error-adapt-missing-memory/error.txt similarity index 100% rename from crates/wit-component/tests/components/adapt-missing-memory/error.txt rename to crates/wit-component/tests/components/error-adapt-missing-memory/error.txt diff --git a/crates/wit-component/tests/components/adapt-missing-memory/module.wat b/crates/wit-component/tests/components/error-adapt-missing-memory/module.wat similarity index 100% rename from crates/wit-component/tests/components/adapt-missing-memory/module.wat rename to crates/wit-component/tests/components/error-adapt-missing-memory/module.wat diff --git a/crates/wit-component/tests/components/error-adapt-missing-memory/module.wit b/crates/wit-component/tests/components/error-adapt-missing-memory/module.wit new file mode 100644 index 0000000000..65c2b79202 --- /dev/null +++ b/crates/wit-component/tests/components/error-adapt-missing-memory/module.wit @@ -0,0 +1,2 @@ +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/default-export-sig-mismatch/error.txt b/crates/wit-component/tests/components/error-default-export-sig-mismatch/error.txt similarity index 100% rename from crates/wit-component/tests/components/default-export-sig-mismatch/error.txt rename to crates/wit-component/tests/components/error-default-export-sig-mismatch/error.txt diff --git a/crates/wit-component/tests/components/default-export-sig-mismatch/module.wat b/crates/wit-component/tests/components/error-default-export-sig-mismatch/module.wat similarity index 100% rename from crates/wit-component/tests/components/default-export-sig-mismatch/module.wat rename to crates/wit-component/tests/components/error-default-export-sig-mismatch/module.wat diff --git a/crates/wit-component/tests/components/default-export-sig-mismatch/module.wit b/crates/wit-component/tests/components/error-default-export-sig-mismatch/module.wit similarity index 55% rename from crates/wit-component/tests/components/default-export-sig-mismatch/module.wit rename to crates/wit-component/tests/components/error-default-export-sig-mismatch/module.wit index b8fa3e1312..e1370a6e50 100644 --- a/crates/wit-component/tests/components/default-export-sig-mismatch/module.wit +++ b/crates/wit-component/tests/components/error-default-export-sig-mismatch/module.wit @@ -1,3 +1,5 @@ -default world my-world { +package foo:foo + +world module { export a: func(x: string) -> string } diff --git a/crates/wit-component/tests/components/empty-module-import/error.txt b/crates/wit-component/tests/components/error-empty-module-import/error.txt similarity index 100% rename from crates/wit-component/tests/components/empty-module-import/error.txt rename to crates/wit-component/tests/components/error-empty-module-import/error.txt diff --git a/crates/wit-component/tests/components/empty-module-import/module.wat b/crates/wit-component/tests/components/error-empty-module-import/module.wat similarity index 100% rename from crates/wit-component/tests/components/empty-module-import/module.wat rename to crates/wit-component/tests/components/error-empty-module-import/module.wat diff --git a/crates/wit-component/tests/components/error-empty-module-import/module.wit b/crates/wit-component/tests/components/error-empty-module-import/module.wit new file mode 100644 index 0000000000..65c2b79202 --- /dev/null +++ b/crates/wit-component/tests/components/error-empty-module-import/module.wit @@ -0,0 +1,2 @@ +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/export-sig-mismatch/error.txt b/crates/wit-component/tests/components/error-export-sig-mismatch/error.txt similarity index 100% rename from crates/wit-component/tests/components/export-sig-mismatch/error.txt rename to crates/wit-component/tests/components/error-export-sig-mismatch/error.txt diff --git a/crates/wit-component/tests/components/export-sig-mismatch/module.wat b/crates/wit-component/tests/components/error-export-sig-mismatch/module.wat similarity index 100% rename from crates/wit-component/tests/components/export-sig-mismatch/module.wat rename to crates/wit-component/tests/components/error-export-sig-mismatch/module.wat diff --git a/crates/wit-component/tests/components/export-sig-mismatch/module.wit b/crates/wit-component/tests/components/error-export-sig-mismatch/module.wit similarity index 67% rename from crates/wit-component/tests/components/export-sig-mismatch/module.wit rename to crates/wit-component/tests/components/error-export-sig-mismatch/module.wit index 8e7ef0bbb6..99c485e530 100644 --- a/crates/wit-component/tests/components/export-sig-mismatch/module.wit +++ b/crates/wit-component/tests/components/error-export-sig-mismatch/module.wit @@ -1,4 +1,6 @@ -default world foo { +package foo:foo + +world module { export foo: interface { a: func(x: string) -> string } diff --git a/crates/wit-component/tests/components/import-sig-mismatch/error.txt b/crates/wit-component/tests/components/error-import-sig-mismatch/error.txt similarity index 100% rename from crates/wit-component/tests/components/import-sig-mismatch/error.txt rename to crates/wit-component/tests/components/error-import-sig-mismatch/error.txt diff --git a/crates/wit-component/tests/components/import-sig-mismatch/module.wat b/crates/wit-component/tests/components/error-import-sig-mismatch/module.wat similarity index 100% rename from crates/wit-component/tests/components/import-sig-mismatch/module.wat rename to crates/wit-component/tests/components/error-import-sig-mismatch/module.wat diff --git a/crates/wit-component/tests/components/import-sig-mismatch/module.wit b/crates/wit-component/tests/components/error-import-sig-mismatch/module.wit similarity index 64% rename from crates/wit-component/tests/components/import-sig-mismatch/module.wit rename to crates/wit-component/tests/components/error-import-sig-mismatch/module.wit index 3e06ced973..cc3a41c5a7 100644 --- a/crates/wit-component/tests/components/import-sig-mismatch/module.wit +++ b/crates/wit-component/tests/components/error-import-sig-mismatch/module.wit @@ -1,4 +1,6 @@ -default world foo { +package foo:foo + +world module { import foo: interface { bar: func(s: string) } diff --git a/crates/wit-component/tests/components/invalid-module-import/error.txt b/crates/wit-component/tests/components/error-invalid-module-import/error.txt similarity index 100% rename from crates/wit-component/tests/components/invalid-module-import/error.txt rename to crates/wit-component/tests/components/error-invalid-module-import/error.txt diff --git a/crates/wit-component/tests/components/invalid-module-import/module.wat b/crates/wit-component/tests/components/error-invalid-module-import/module.wat similarity index 100% rename from crates/wit-component/tests/components/invalid-module-import/module.wat rename to crates/wit-component/tests/components/error-invalid-module-import/module.wat diff --git a/crates/wit-component/tests/components/error-invalid-module-import/module.wit b/crates/wit-component/tests/components/error-invalid-module-import/module.wit new file mode 100644 index 0000000000..65c2b79202 --- /dev/null +++ b/crates/wit-component/tests/components/error-invalid-module-import/module.wit @@ -0,0 +1,2 @@ +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/missing-default-export/error.txt b/crates/wit-component/tests/components/error-missing-default-export/error.txt similarity index 100% rename from crates/wit-component/tests/components/missing-default-export/error.txt rename to crates/wit-component/tests/components/error-missing-default-export/error.txt diff --git a/crates/wit-component/tests/components/missing-default-export/module.wat b/crates/wit-component/tests/components/error-missing-default-export/module.wat similarity index 100% rename from crates/wit-component/tests/components/missing-default-export/module.wat rename to crates/wit-component/tests/components/error-missing-default-export/module.wat diff --git a/crates/wit-component/tests/components/error-missing-default-export/module.wit b/crates/wit-component/tests/components/error-missing-default-export/module.wit new file mode 100644 index 0000000000..4ae9b6cf21 --- /dev/null +++ b/crates/wit-component/tests/components/error-missing-default-export/module.wit @@ -0,0 +1,4 @@ +package foo:foo +world module { + export a: func() +} diff --git a/crates/wit-component/tests/components/missing-export/error.txt b/crates/wit-component/tests/components/error-missing-export/error.txt similarity index 100% rename from crates/wit-component/tests/components/missing-export/error.txt rename to crates/wit-component/tests/components/error-missing-export/error.txt diff --git a/crates/wit-component/tests/components/missing-export/module.wat b/crates/wit-component/tests/components/error-missing-export/module.wat similarity index 100% rename from crates/wit-component/tests/components/missing-export/module.wat rename to crates/wit-component/tests/components/error-missing-export/module.wat diff --git a/crates/wit-component/tests/components/missing-export/module.wit b/crates/wit-component/tests/components/error-missing-export/module.wit similarity index 58% rename from crates/wit-component/tests/components/missing-export/module.wit rename to crates/wit-component/tests/components/error-missing-export/module.wit index 6b1871aead..9ea114f479 100644 --- a/crates/wit-component/tests/components/missing-export/module.wit +++ b/crates/wit-component/tests/components/error-missing-export/module.wit @@ -1,4 +1,6 @@ -default world my-world { +package foo:foo + +world module { export foo: interface { a: func() } diff --git a/crates/wit-component/tests/components/missing-import/error.txt b/crates/wit-component/tests/components/error-missing-import-func/error.txt similarity index 100% rename from crates/wit-component/tests/components/missing-import/error.txt rename to crates/wit-component/tests/components/error-missing-import-func/error.txt diff --git a/crates/wit-component/tests/components/missing-import-func/module.wat b/crates/wit-component/tests/components/error-missing-import-func/module.wat similarity index 100% rename from crates/wit-component/tests/components/missing-import-func/module.wat rename to crates/wit-component/tests/components/error-missing-import-func/module.wat diff --git a/crates/wit-component/tests/components/error-missing-import-func/module.wit b/crates/wit-component/tests/components/error-missing-import-func/module.wit new file mode 100644 index 0000000000..38300fede0 --- /dev/null +++ b/crates/wit-component/tests/components/error-missing-import-func/module.wit @@ -0,0 +1,9 @@ +package foo:foo + +interface foo { + a: func() +} + +world module { + import foo +} diff --git a/crates/wit-component/tests/components/error-missing-import/error.txt b/crates/wit-component/tests/components/error-missing-import/error.txt new file mode 100644 index 0000000000..b4d2327fb5 --- /dev/null +++ b/crates/wit-component/tests/components/error-missing-import/error.txt @@ -0,0 +1 @@ +module requires an import interface named `foo` \ No newline at end of file diff --git a/crates/wit-component/tests/components/missing-import/module.wat b/crates/wit-component/tests/components/error-missing-import/module.wat similarity index 100% rename from crates/wit-component/tests/components/missing-import/module.wat rename to crates/wit-component/tests/components/error-missing-import/module.wat diff --git a/crates/wit-component/tests/components/error-missing-import/module.wit b/crates/wit-component/tests/components/error-missing-import/module.wit new file mode 100644 index 0000000000..65c2b79202 --- /dev/null +++ b/crates/wit-component/tests/components/error-missing-import/module.wit @@ -0,0 +1,2 @@ +package foo:foo +world module {} diff --git a/crates/wit-component/tests/components/export-interface-using-import/component.wat b/crates/wit-component/tests/components/export-interface-using-import/component.wat index 25a8be7fc8..73aef30265 100644 --- a/crates/wit-component/tests/components/export-interface-using-import/component.wat +++ b/crates/wit-component/tests/components/export-interface-using-import/component.wat @@ -7,7 +7,7 @@ (export (;3;) "r" (type (eq 2))) ) ) - (import "foo" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (core module (;0;) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") diff --git a/crates/wit-component/tests/components/export-interface-using-import/component.wit b/crates/wit-component/tests/components/export-interface-using-import/component.wit deleted file mode 100644 index b5e8a2747d..0000000000 --- a/crates/wit-component/tests/components/export-interface-using-import/component.wit +++ /dev/null @@ -1,18 +0,0 @@ -interface foo { - record f { - } - - record r { - f: f, - } - -} - -interface x { - use self.foo.{r} -} - -default world component { - import foo: self.foo - export x: self.x -} diff --git a/crates/wit-component/tests/components/export-interface-using-import/component.wit.print b/crates/wit-component/tests/components/export-interface-using-import/component.wit.print new file mode 100644 index 0000000000..22ea09e611 --- /dev/null +++ b/crates/wit-component/tests/components/export-interface-using-import/component.wit.print @@ -0,0 +1,8 @@ +package root:component + +world root { + import foo:foo/foo + export x: interface { + use foo:foo/foo.{r} + } +} diff --git a/crates/wit-component/tests/components/export-interface-using-import/module.wit b/crates/wit-component/tests/components/export-interface-using-import/module.wit index a538ef780e..6918380a89 100644 --- a/crates/wit-component/tests/components/export-interface-using-import/module.wit +++ b/crates/wit-component/tests/components/export-interface-using-import/module.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { record f {} @@ -6,8 +8,8 @@ interface foo { } } -default world the-world { +world module { export x: interface { - use self.foo.{r} + use foo.{r} } } diff --git a/crates/wit-component/tests/components/export-name-shuffling/component.wat b/crates/wit-component/tests/components/export-name-shuffling/component.wat index 2a5ba1c766..2333242b04 100644 --- a/crates/wit-component/tests/components/export-name-shuffling/component.wat +++ b/crates/wit-component/tests/components/export-name-shuffling/component.wat @@ -14,7 +14,7 @@ (export (;1;) "foo" (type 0)) ) (instance (;0;) (instantiate 0)) - (export (;1;) "other-name" (instance 0)) + (export (;1;) (interface "foo:foo/name") (instance 0)) (alias export 1 "foo" (type (;0;))) (type (;1;) (func (param "f" 0))) (alias core export 0 "name#a" (core func (;0;))) diff --git a/crates/wit-component/tests/components/export-name-shuffling/component.wit b/crates/wit-component/tests/components/export-name-shuffling/component.wit deleted file mode 100644 index 8b2fb6ea7e..0000000000 --- a/crates/wit-component/tests/components/export-name-shuffling/component.wit +++ /dev/null @@ -1,15 +0,0 @@ -interface other-name { - record foo { - } - -} - -interface name { - use self.other-name.{foo} - a: func(f: foo) -} - -default world component { - export other-name: self.other-name - export name: self.name -} diff --git a/crates/wit-component/tests/components/export-name-shuffling/component.wit.print b/crates/wit-component/tests/components/export-name-shuffling/component.wit.print new file mode 100644 index 0000000000..22943c96e2 --- /dev/null +++ b/crates/wit-component/tests/components/export-name-shuffling/component.wit.print @@ -0,0 +1,9 @@ +package root:component + +world root { + export foo:foo/name + export name: interface { + use foo:foo/name.{foo} + a: func(f: foo) + } +} diff --git a/crates/wit-component/tests/components/export-name-shuffling/module.wit b/crates/wit-component/tests/components/export-name-shuffling/module.wit index d2e1fea899..77a6ae69d1 100644 --- a/crates/wit-component/tests/components/export-name-shuffling/module.wit +++ b/crates/wit-component/tests/components/export-name-shuffling/module.wit @@ -1,11 +1,14 @@ +package foo:foo + interface name { record foo {} } -default world foo { - export other-name: self.name +world module { + export name + export name: interface { - use self.name.{foo} + use name.{foo} a: func(f: foo) } diff --git a/crates/wit-component/tests/components/export-type-name-conflict/component.wat b/crates/wit-component/tests/components/export-type-name-conflict/component.wat index 3c16861413..2756352701 100644 --- a/crates/wit-component/tests/components/export-type-name-conflict/component.wat +++ b/crates/wit-component/tests/components/export-type-name-conflict/component.wat @@ -5,7 +5,7 @@ (export (;1;) "foo" (type (eq 0))) ) ) - (import "foo" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (core module (;0;) (type (;0;) (func)) (func (;0;) (type 0)) diff --git a/crates/wit-component/tests/components/export-type-name-conflict/component.wit b/crates/wit-component/tests/components/export-type-name-conflict/component.wit deleted file mode 100644 index 015d46624a..0000000000 --- a/crates/wit-component/tests/components/export-type-name-conflict/component.wit +++ /dev/null @@ -1,15 +0,0 @@ -interface foo { - record foo { - } - -} - -interface bar { - use self.foo.{foo as bar} - foo: func() -> bar -} - -default world component { - import foo: self.foo - export bar: self.bar -} diff --git a/crates/wit-component/tests/components/export-type-name-conflict/component.wit.print b/crates/wit-component/tests/components/export-type-name-conflict/component.wit.print new file mode 100644 index 0000000000..e25f5018e4 --- /dev/null +++ b/crates/wit-component/tests/components/export-type-name-conflict/component.wit.print @@ -0,0 +1,9 @@ +package root:component + +world root { + import foo:foo/foo + export bar: interface { + use foo:foo/foo.{foo as bar} + foo: func() -> bar + } +} diff --git a/crates/wit-component/tests/components/export-type-name-conflict/module.wit b/crates/wit-component/tests/components/export-type-name-conflict/module.wit index 3ae02cd2bf..d1990cf8bb 100644 --- a/crates/wit-component/tests/components/export-type-name-conflict/module.wit +++ b/crates/wit-component/tests/components/export-type-name-conflict/module.wit @@ -1,10 +1,12 @@ +package foo:foo + interface foo { record foo {} } -default world bar { +world module { export bar: interface { - use self.foo.{foo as bar} + use foo.{foo as bar} foo: func() -> bar } diff --git a/crates/wit-component/tests/components/export-with-type-alias/component.wat b/crates/wit-component/tests/components/export-with-type-alias/component.wat index 141110ef43..1ac1e8cab9 100644 --- a/crates/wit-component/tests/components/export-with-type-alias/component.wat +++ b/crates/wit-component/tests/components/export-with-type-alias/component.wat @@ -4,7 +4,7 @@ (func (;0;) (type 0) (param i32) (result i32) unreachable ) - (export "foo#c" (func 0)) + (export "foo:foo/foo#c" (func 0)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") (processed-by "my-fake-bindgen" "123.45") @@ -13,7 +13,7 @@ (core instance (;0;) (instantiate 0)) (type (;0;) u8) (type (;1;) (func (param "a" 0) (result 0))) - (alias core export 0 "foo#c" (core func (;0;))) + (alias core export 0 "foo:foo/foo#c" (core func (;0;))) (func (;0;) (type 1) (canon lift (core func 0))) (component (;0;) (type (;0;) u8) @@ -36,5 +36,5 @@ (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "foo" (instance 0)) + (export (;1;) (interface "foo:foo/foo") (instance 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/export-with-type-alias/component.wit b/crates/wit-component/tests/components/export-with-type-alias/component.wit deleted file mode 100644 index c0cce27996..0000000000 --- a/crates/wit-component/tests/components/export-with-type-alias/component.wit +++ /dev/null @@ -1,11 +0,0 @@ -interface foo { - type a = u8 - - type b = a - - c: func(a: a) -> b -} - -default world component { - export foo: self.foo -} diff --git a/crates/wit-component/tests/components/export-with-type-alias/component.wit.print b/crates/wit-component/tests/components/export-with-type-alias/component.wit.print new file mode 100644 index 0000000000..62a65899a8 --- /dev/null +++ b/crates/wit-component/tests/components/export-with-type-alias/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + export foo:foo/foo +} diff --git a/crates/wit-component/tests/components/export-with-type-alias/module.wat b/crates/wit-component/tests/components/export-with-type-alias/module.wat index 994b154665..196f9c956a 100644 --- a/crates/wit-component/tests/components/export-with-type-alias/module.wat +++ b/crates/wit-component/tests/components/export-with-type-alias/module.wat @@ -1,3 +1,3 @@ (module - (func (export "foo#c") (param i32) (result i32) unreachable) + (func (export "foo:foo/foo#c") (param i32) (result i32) unreachable) ) diff --git a/crates/wit-component/tests/components/export-with-type-alias/module.wit b/crates/wit-component/tests/components/export-with-type-alias/module.wit index 87e91a8dcd..ad5e636c22 100644 --- a/crates/wit-component/tests/components/export-with-type-alias/module.wit +++ b/crates/wit-component/tests/components/export-with-type-alias/module.wit @@ -1,9 +1,11 @@ +package foo:foo + interface foo { type a = u8 type b = a c: func(a: a) -> b } -default world the-world { - export foo: self.foo +world module { + export foo } diff --git a/crates/wit-component/tests/components/exports/component.wit b/crates/wit-component/tests/components/exports/component.wit deleted file mode 100644 index 1e3cf130cb..0000000000 --- a/crates/wit-component/tests/components/exports/component.wit +++ /dev/null @@ -1,31 +0,0 @@ -interface bar { - flags x { - a, - b, - c, - } - - a: func(x: x) -} - -interface foo { - variant x { - a, - b(string), - c(s64), - } - - a: func() - - b: func(x: string) -> x - - c: func(x: x) -> string -} - -default world component { - export bar: self.bar - export foo: self.foo - export a: func() - export b: func(a: s8, b: s16, c: s32, d: s64) -> string - export c: func() -> tuple -} diff --git a/crates/wit-component/tests/components/exports/component.wit.print b/crates/wit-component/tests/components/exports/component.wit.print new file mode 100644 index 0000000000..832dcb39b7 --- /dev/null +++ b/crates/wit-component/tests/components/exports/component.wit.print @@ -0,0 +1,29 @@ +package root:component + +world root { + export bar: interface { + flags x { + a, + b, + c, + } + + a: func(x: x) + } + export foo: interface { + variant x { + a, + b(string), + c(s64), + } + + a: func() + + b: func(x: string) -> x + + c: func(x: x) -> string + } + export a: func() + export b: func(a: s8, b: s16, c: s32, d: s64) -> string + export c: func() -> tuple +} diff --git a/crates/wit-component/tests/components/exports/module.wit b/crates/wit-component/tests/components/exports/module.wit index 478e6876ca..922df002d1 100644 --- a/crates/wit-component/tests/components/exports/module.wit +++ b/crates/wit-component/tests/components/exports/module.wit @@ -1,4 +1,6 @@ -default world my-world { +package foo:foo + +world module { export a: func() export b: func(a: s8, b: s16, c: s32, d: s64) -> string export c: func() -> tuple diff --git a/crates/wit-component/tests/components/import-conflict/component.wat b/crates/wit-component/tests/components/import-conflict/component.wat index 440690c800..15306e9b39 100644 --- a/crates/wit-component/tests/components/import-conflict/component.wat +++ b/crates/wit-component/tests/components/import-conflict/component.wat @@ -5,7 +5,7 @@ (export (;0;) "a" (func (type 0))) ) ) - (import "bar" (instance (;0;) (type 0))) + (import (interface "foo:foo/bar") (instance (;0;) (type 0))) (type (;1;) (instance (type (;0;) (list u8)) @@ -13,22 +13,22 @@ (export (;0;) "baz" (func (type 1))) ) ) - (import "baz" (instance (;1;) (type 1))) + (import (interface "foo:foo/baz") (instance (;1;) (type 1))) (type (;2;) (instance (type (;0;) (func)) (export (;0;) "a" (func (type 0))) ) ) - (import "foo" (instance (;2;) (type 2))) + (import (interface "foo:foo/foo") (instance (;2;) (type 2))) (core module (;0;) (type (;0;) (func)) (type (;1;) (func (param i64 i32 i32))) (type (;2;) (func (param i32 i32 i32))) (type (;3;) (func (param i32 i32 i32 i32) (result i32))) - (import "foo" "a" (func (;0;) (type 0))) - (import "bar" "a" (func (;1;) (type 1))) - (import "baz" "baz" (func (;2;) (type 2))) + (import "foo:foo/foo" "a" (func (;0;) (type 0))) + (import "foo:foo/bar" "a" (func (;1;) (type 1))) + (import "foo:foo/baz" "baz" (func (;2;) (type 2))) (func (;3;) (type 3) (param i32 i32 i32 i32) (result i32) unreachable ) @@ -43,14 +43,14 @@ (core module (;1;) (type (;0;) (func (param i64 i32 i32))) (type (;1;) (func (param i32 i32 i32))) - (func $indirect-bar-a (;0;) (type 0) (param i64 i32 i32) + (func $indirect-foo:foo/bar-a (;0;) (type 0) (param i64 i32 i32) local.get 0 local.get 1 local.get 2 i32.const 0 call_indirect (type 0) ) - (func $indirect-baz-baz (;1;) (type 1) (param i32 i32 i32) + (func $indirect-foo:foo/baz-baz (;1;) (type 1) (param i32 i32 i32) local.get 0 local.get 1 local.get 2 @@ -58,8 +58,8 @@ call_indirect (type 1) ) (table (;0;) 2 2 funcref) - (export "0" (func $indirect-bar-a)) - (export "1" (func $indirect-baz-baz)) + (export "0" (func $indirect-foo:foo/bar-a)) + (export "1" (func $indirect-foo:foo/baz-baz)) (export "$imports" (table 0)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") @@ -91,9 +91,9 @@ (export "baz" (func 2)) ) (core instance (;4;) (instantiate 0 - (with "foo" (instance 1)) - (with "bar" (instance 2)) - (with "baz" (instance 3)) + (with "foo:foo/foo" (instance 1)) + (with "foo:foo/bar" (instance 2)) + (with "foo:foo/baz" (instance 3)) ) ) (alias core export 4 "memory" (core memory (;0;))) diff --git a/crates/wit-component/tests/components/import-conflict/component.wit b/crates/wit-component/tests/components/import-conflict/component.wit deleted file mode 100644 index d2726dc7e5..0000000000 --- a/crates/wit-component/tests/components/import-conflict/component.wit +++ /dev/null @@ -1,17 +0,0 @@ -interface bar { - a: func(x: u64, y: string) -} - -interface baz { - baz: func(x: list) -> list -} - -interface foo { - a: func() -} - -default world component { - import bar: self.bar - import baz: self.baz - import foo: self.foo -} diff --git a/crates/wit-component/tests/components/import-conflict/component.wit.print b/crates/wit-component/tests/components/import-conflict/component.wit.print new file mode 100644 index 0000000000..40cd5d91f8 --- /dev/null +++ b/crates/wit-component/tests/components/import-conflict/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import foo:foo/bar + import foo:foo/baz + import foo:foo/foo +} diff --git a/crates/wit-component/tests/components/import-conflict/module.wat b/crates/wit-component/tests/components/import-conflict/module.wat index b7cacf1a01..b0b2aa640c 100644 --- a/crates/wit-component/tests/components/import-conflict/module.wat +++ b/crates/wit-component/tests/components/import-conflict/module.wat @@ -1,7 +1,7 @@ (module - (import "foo" "a" (func)) - (import "bar" "a" (func (param i64 i32 i32))) - (import "baz" "baz" (func (param i32 i32 i32))) + (import "foo:foo/foo" "a" (func)) + (import "foo:foo/bar" "a" (func (param i64 i32 i32))) + (import "foo:foo/baz" "baz" (func (param i32 i32 i32))) (memory (export "memory") 1) (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) -) \ No newline at end of file +) diff --git a/crates/wit-component/tests/components/import-conflict/module.wit b/crates/wit-component/tests/components/import-conflict/module.wit index 4c23d0a296..bb1345b330 100644 --- a/crates/wit-component/tests/components/import-conflict/module.wit +++ b/crates/wit-component/tests/components/import-conflict/module.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { a: func() } @@ -10,8 +12,8 @@ interface baz { baz: func(x: list) -> list } -default world my-world { - import bar: self.bar - import baz: self.baz - import foo: self.foo +world module { + import bar + import baz + import foo } diff --git a/crates/wit-component/tests/components/import-empty-interface/component.wit b/crates/wit-component/tests/components/import-empty-interface/component.wit deleted file mode 100644 index da09ea6eeb..0000000000 --- a/crates/wit-component/tests/components/import-empty-interface/component.wit +++ /dev/null @@ -1,2 +0,0 @@ -default world component { -} diff --git a/crates/wit-component/tests/components/import-empty-interface/component.wit.print b/crates/wit-component/tests/components/import-empty-interface/component.wit.print new file mode 100644 index 0000000000..bcd860d376 --- /dev/null +++ b/crates/wit-component/tests/components/import-empty-interface/component.wit.print @@ -0,0 +1,4 @@ +package root:component + +world root { +} diff --git a/crates/wit-component/tests/components/import-empty-interface/module.wit b/crates/wit-component/tests/components/import-empty-interface/module.wit index b92bce2a81..02b6a5dc23 100644 --- a/crates/wit-component/tests/components/import-empty-interface/module.wit +++ b/crates/wit-component/tests/components/import-empty-interface/module.wit @@ -1,3 +1,5 @@ -default world foo { +package foo:foo + +world module { import foo: interface {} } diff --git a/crates/wit-component/tests/components/import-export-same-iface-name/component.wat b/crates/wit-component/tests/components/import-export-same-iface-name/component.wat new file mode 100644 index 0000000000..e2f8093107 --- /dev/null +++ b/crates/wit-component/tests/components/import-export-same-iface-name/component.wat @@ -0,0 +1,59 @@ +(component + (type (;0;) + (instance + (type (;0;) (func)) + (export (;0;) "a" (func (type 0))) + ) + ) + (import (interface "foo:dep/the-name") (instance (;0;) (type 0))) + (type (;1;) + (instance + (type (;0;) (func)) + (export (;0;) "a" (func (type 0))) + ) + ) + (import (interface "foo:foo/the-name") (instance (;1;) (type 1))) + (core module (;0;) + (type (;0;) (func)) + (import "foo:dep/the-name" "a" (func (;0;) (type 0))) + (import "foo:foo/the-name" "a" (func (;1;) (type 0))) + (func (;2;) (type 0)) + (export "foo:foo/the-name#a" (func 2)) + (@producers + (processed-by "wit-component" "$CARGO_PKG_VERSION") + (processed-by "my-fake-bindgen" "123.45") + ) + ) + (alias export 0 "a" (func (;0;))) + (core func (;0;) (canon lower (func 0))) + (core instance (;0;) + (export "a" (func 0)) + ) + (alias export 1 "a" (func (;1;))) + (core func (;1;) (canon lower (func 1))) + (core instance (;1;) + (export "a" (func 1)) + ) + (core instance (;2;) (instantiate 0 + (with "foo:dep/the-name" (instance 0)) + (with "foo:foo/the-name" (instance 1)) + ) + ) + (type (;2;) (func)) + (alias core export 2 "foo:foo/the-name#a" (core func (;2;))) + (func (;2;) (type 2) (canon lift (core func 2))) + (component (;0;) + (type (;0;) (func)) + (import "import-func-a" (func (;0;) (type 0))) + (type (;1;) (func)) + (export (;1;) "a" (func 0) (func (type 1))) + ) + (instance (;2;) (instantiate 0 + (with "import-func-a" (func 2)) + ) + ) + (@producers + (processed-by "wit-component" "$CARGO_PKG_VERSION") + ) + (export (;3;) (interface "foo:foo/the-name") (instance 2)) +) \ No newline at end of file diff --git a/crates/wit-component/tests/components/import-export-same-iface-name/component.wit.print b/crates/wit-component/tests/components/import-export-same-iface-name/component.wit.print new file mode 100644 index 0000000000..72d127d09d --- /dev/null +++ b/crates/wit-component/tests/components/import-export-same-iface-name/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import foo:dep/the-name + import foo:foo/the-name + export foo:foo/the-name +} diff --git a/crates/wit-component/tests/components/import-export-same-iface-name/deps/dep/foo.wit b/crates/wit-component/tests/components/import-export-same-iface-name/deps/dep/foo.wit new file mode 100644 index 0000000000..c315c9fca8 --- /dev/null +++ b/crates/wit-component/tests/components/import-export-same-iface-name/deps/dep/foo.wit @@ -0,0 +1,5 @@ +package foo:dep + +interface the-name { + a: func() +} diff --git a/crates/wit-component/tests/components/import-export-same-iface-name/module.wat b/crates/wit-component/tests/components/import-export-same-iface-name/module.wat new file mode 100644 index 0000000000..4e9ece5084 --- /dev/null +++ b/crates/wit-component/tests/components/import-export-same-iface-name/module.wat @@ -0,0 +1,5 @@ +(module + (import "foo:dep/the-name" "a" (func)) + (import "foo:foo/the-name" "a" (func)) + (func (export "foo:foo/the-name#a")) +) diff --git a/crates/wit-component/tests/components/import-export-same-iface-name/module.wit b/crates/wit-component/tests/components/import-export-same-iface-name/module.wit new file mode 100644 index 0000000000..ce27d8cb1b --- /dev/null +++ b/crates/wit-component/tests/components/import-export-same-iface-name/module.wit @@ -0,0 +1,11 @@ +package foo:foo + +interface the-name { + a: func() +} + +world module { + import foo:dep/the-name + import the-name + export the-name +} diff --git a/crates/wit-component/tests/components/import-export/component.wit b/crates/wit-component/tests/components/import-export/component.wit deleted file mode 100644 index 04294f3da4..0000000000 --- a/crates/wit-component/tests/components/import-export/component.wit +++ /dev/null @@ -1,15 +0,0 @@ -interface foo { - a: func() -> string -} - -interface bar { - a: func() - - b: func() -> string -} - -default world component { - import foo: self.foo - export bar: self.bar - export a: func(x: string) -> tuple -} diff --git a/crates/wit-component/tests/components/import-export/component.wit.print b/crates/wit-component/tests/components/import-export/component.wit.print new file mode 100644 index 0000000000..37c6cbd6f7 --- /dev/null +++ b/crates/wit-component/tests/components/import-export/component.wit.print @@ -0,0 +1,13 @@ +package root:component + +world root { + import foo: interface { + a: func() -> string + } + export bar: interface { + a: func() + + b: func() -> string + } + export a: func(x: string) -> tuple +} diff --git a/crates/wit-component/tests/components/import-export/module.wit b/crates/wit-component/tests/components/import-export/module.wit index 3b29a2b865..d90fee1fd2 100644 --- a/crates/wit-component/tests/components/import-export/module.wit +++ b/crates/wit-component/tests/components/import-export/module.wit @@ -1,4 +1,6 @@ -default world my-world { +package foo:foo + +world module { import foo: interface { a: func() -> string } diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/adapt-old.wat b/crates/wit-component/tests/components/import-in-adapter-and-main-module/adapt-old.wat index 65a6863807..56db4f5510 100644 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/adapt-old.wat +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/adapt-old.wat @@ -1,11 +1,11 @@ (module - (import "shared-dependency" "f1" (func $f1)) - (import "shared-dependency" "f3" (func $f3)) + (import "foo:shared-dependency/doc" "f1" (func $f1)) + (import "foo:shared-dependency/doc" "f3" (func $f3)) - (import "shared-dependency" "g1" (func $g1 (param i32))) - (import "shared-dependency" "g3" (func $g3 (param i32))) + (import "foo:shared-dependency/doc" "g1" (func $g1 (param i32))) + (import "foo:shared-dependency/doc" "g3" (func $g3 (param i32))) - (import "shared-dependency" "unused-in-adapter" (func)) + (import "foo:shared-dependency/doc" "unused-in-adapter" (func)) (import "env" "memory" (memory 0)) (import "adapter-dep" "foo" (func $foo (result i32))) diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/adapt-old.wit b/crates/wit-component/tests/components/import-in-adapter-and-main-module/adapt-old.wit index 077605bf5e..904c79ea76 100644 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/adapt-old.wit +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/adapt-old.wit @@ -1,8 +1,8 @@ -default world the-adapter { - import shared-dependency: shared-dependency.doc +world adapt-old { + import foo:shared-dependency/doc import adapter-dep: interface { - use shared-dependency.types.{a-typedef} + use foo:shared-dependency/types.{a-typedef} foo: func() -> a-typedef } diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat index 5126e79f41..7eeff34d5b 100644 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wat @@ -11,14 +11,14 @@ (export (;5;) "g3" (func (type 1))) ) ) - (import "shared-dependency" "path:/shared-dependency/doc/doc" (instance (;0;) (type 0))) + (import (interface "foo:shared-dependency/doc") (instance (;0;) (type 0))) (type (;1;) (instance (type (;0;) u32) (export (;1;) "a-typedef" (type (eq 0))) ) ) - (import "types" "path:/shared-dependency/types/types" (instance (;1;) (type 1))) + (import (interface "foo:shared-dependency/types") (instance (;1;) (type 1))) (alias export 1 "a-typedef" (type (;2;))) (type (;3;) (instance @@ -44,10 +44,10 @@ (type (;1;) (func (param i32))) (type (;2;) (func (result i32))) (type (;3;) (func (param i32 i32 i32 i32) (result i32))) - (import "shared-dependency" "f1" (func (;0;) (type 0))) - (import "shared-dependency" "f2" (func (;1;) (type 0))) - (import "shared-dependency" "g1" (func (;2;) (type 1))) - (import "shared-dependency" "g2" (func (;3;) (type 1))) + (import "foo:shared-dependency/doc" "f1" (func (;0;) (type 0))) + (import "foo:shared-dependency/doc" "f2" (func (;1;) (type 0))) + (import "foo:shared-dependency/doc" "g1" (func (;2;) (type 1))) + (import "foo:shared-dependency/doc" "g2" (func (;3;) (type 1))) (import "old" "adapter-f1" (func (;4;) (type 0))) (import "main-dep" "foo" (func (;5;) (type 2))) (func (;6;) (type 3) (param i32 i32 i32 i32) (result i32) @@ -66,10 +66,10 @@ (type (;1;) (func (param i32))) (type (;2;) (func (result i32))) (type (;3;) (func (param i32 i32 i32 i32) (result i32))) - (import "shared-dependency" "f1" (func $f1 (;0;) (type 0))) - (import "shared-dependency" "f3" (func $f3 (;1;) (type 0))) - (import "shared-dependency" "g1" (func $g1 (;2;) (type 1))) - (import "shared-dependency" "g3" (func $g3 (;3;) (type 1))) + (import "foo:shared-dependency/doc" "f1" (func $f1 (;0;) (type 0))) + (import "foo:shared-dependency/doc" "f3" (func $f3 (;1;) (type 0))) + (import "foo:shared-dependency/doc" "g1" (func $g1 (;2;) (type 1))) + (import "foo:shared-dependency/doc" "g3" (func $g3 (;3;) (type 1))) (import "adapter-dep" "foo" (func $foo (;4;) (type 2))) (func (;5;) (type 0) call $f1 @@ -90,22 +90,22 @@ (core module (;2;) (type (;0;) (func (param i32))) (type (;1;) (func)) - (func $indirect-shared-dependency-g1 (;0;) (type 0) (param i32) + (func $indirect-foo:shared-dependency/doc-g1 (;0;) (type 0) (param i32) local.get 0 i32.const 0 call_indirect (type 0) ) - (func $indirect-shared-dependency-g2 (;1;) (type 0) (param i32) + (func $indirect-foo:shared-dependency/doc-g2 (;1;) (type 0) (param i32) local.get 0 i32.const 1 call_indirect (type 0) ) - (func $#func2 (@name "indirect-shared-dependency-g1") (;2;) (type 0) (param i32) + (func $#func2 (@name "indirect-foo:shared-dependency/doc-g1") (;2;) (type 0) (param i32) local.get 0 i32.const 2 call_indirect (type 0) ) - (func $indirect-shared-dependency-g3 (;3;) (type 0) (param i32) + (func $indirect-foo:shared-dependency/doc-g3 (;3;) (type 0) (param i32) local.get 0 i32.const 3 call_indirect (type 0) @@ -115,10 +115,10 @@ call_indirect (type 1) ) (table (;0;) 5 5 funcref) - (export "0" (func $indirect-shared-dependency-g1)) - (export "1" (func $indirect-shared-dependency-g2)) - (export "2" (func $#func2)) - (export "3" (func $indirect-shared-dependency-g3)) + (export "0" (func $indirect-foo:shared-dependency/doc-g1)) + (export "1" (func $indirect-foo:shared-dependency/doc-g2)) + (export "2" (func $#func2)) + (export "3" (func $indirect-foo:shared-dependency/doc-g3)) (export "4" (func $adapt-old-adapter-f1)) (export "$imports" (table 0)) (@producers @@ -162,7 +162,7 @@ (export "adapter-f1" (func 5)) ) (core instance (;4;) (instantiate 0 - (with "shared-dependency" (instance 1)) + (with "foo:shared-dependency/doc" (instance 1)) (with "main-dep" (instance 2)) (with "old" (instance 3)) ) @@ -187,7 +187,7 @@ (export "foo" (func 11)) ) (core instance (;7;) (instantiate 1 - (with "shared-dependency" (instance 5)) + (with "foo:shared-dependency/doc" (instance 5)) (with "adapter-dep" (instance 6)) ) ) diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wit b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wit deleted file mode 100644 index 82dbbcdfde..0000000000 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wit +++ /dev/null @@ -1,35 +0,0 @@ -interface shared-dependency { - f1: func() - - f2: func() - - f3: func() - - g1: func() -> string - - g2: func() -> string - - g3: func() -> string -} - -interface types { - type a-typedef = u32 - -} - -interface main-dep { - use self.types.{a-typedef} - foo: func() -> a-typedef -} - -interface adapter-dep { - use self.types.{a-typedef} - foo: func() -> a-typedef -} - -default world component { - import shared-dependency: self.shared-dependency - import types: self.types - import main-dep: self.main-dep - import adapter-dep: self.adapter-dep -} diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wit.print b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wit.print new file mode 100644 index 0000000000..2958d7c112 --- /dev/null +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/component.wit.print @@ -0,0 +1,14 @@ +package root:component + +world root { + import foo:shared-dependency/doc + import foo:shared-dependency/types + import main-dep: interface { + use foo:shared-dependency/types.{a-typedef} + foo: func() -> a-typedef + } + import adapter-dep: interface { + use foo:shared-dependency/types.{a-typedef} + foo: func() -> a-typedef + } +} diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/deps/shared-dependency/doc.wit b/crates/wit-component/tests/components/import-in-adapter-and-main-module/deps/shared-dependency/doc.wit index b02b572f0e..ad3cbdc56c 100644 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/deps/shared-dependency/doc.wit +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/deps/shared-dependency/doc.wit @@ -1,4 +1,6 @@ -default interface doc { +package foo:shared-dependency + +interface doc { f1: func() f2: func() f3: func() diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/deps/shared-dependency/types.wit b/crates/wit-component/tests/components/import-in-adapter-and-main-module/deps/shared-dependency/types.wit index 04673c8ce1..4119e94839 100644 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/deps/shared-dependency/types.wit +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/deps/shared-dependency/types.wit @@ -1,3 +1,3 @@ -default interface types { +interface types { type a-typedef = u32 } diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/module.wat b/crates/wit-component/tests/components/import-in-adapter-and-main-module/module.wat index 1a0abd1df0..1f17565460 100644 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/module.wat +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/module.wat @@ -1,9 +1,9 @@ (module - (import "shared-dependency" "f1" (func)) - (import "shared-dependency" "f2" (func)) + (import "foo:shared-dependency/doc" "f1" (func)) + (import "foo:shared-dependency/doc" "f2" (func)) - (import "shared-dependency" "g1" (func (param i32))) - (import "shared-dependency" "g2" (func (param i32))) + (import "foo:shared-dependency/doc" "g1" (func (param i32))) + (import "foo:shared-dependency/doc" "g2" (func (param i32))) (import "old" "adapter-f1" (func)) diff --git a/crates/wit-component/tests/components/import-in-adapter-and-main-module/module.wit b/crates/wit-component/tests/components/import-in-adapter-and-main-module/module.wit index 6a28b56da6..2df745b5fe 100644 --- a/crates/wit-component/tests/components/import-in-adapter-and-main-module/module.wit +++ b/crates/wit-component/tests/components/import-in-adapter-and-main-module/module.wit @@ -1,8 +1,10 @@ -default world the-module { - import shared-dependency: shared-dependency.doc +package foo:foo + +world module { + import foo:shared-dependency/doc import main-dep: interface { - use shared-dependency.types.{a-typedef} + use foo:shared-dependency/types.{a-typedef} foo: func() -> a-typedef } diff --git a/crates/wit-component/tests/components/imports/component.wit b/crates/wit-component/tests/components/imports/component.wit deleted file mode 100644 index cbb6b2de1c..0000000000 --- a/crates/wit-component/tests/components/imports/component.wit +++ /dev/null @@ -1,33 +0,0 @@ -interface bar { - record x { - a: u8, - } - - bar1: func(x: string) - - bar2: func(x: x) -} - -interface baz { - type x = s8 - - baz1: func(x: list) - - baz2: func() - - baz3: func(x: x) -} - -interface foo { - foo1: func() - - foo2: func(x: u8) - - foo3: func(x: float32) -} - -default world component { - import bar: self.bar - import baz: self.baz - import foo: self.foo -} diff --git a/crates/wit-component/tests/components/imports/component.wit.print b/crates/wit-component/tests/components/imports/component.wit.print new file mode 100644 index 0000000000..4ca4e77402 --- /dev/null +++ b/crates/wit-component/tests/components/imports/component.wit.print @@ -0,0 +1,29 @@ +package root:component + +world root { + import bar: interface { + record x { + a: u8, + } + + bar1: func(x: string) + + bar2: func(x: x) + } + import baz: interface { + type x = s8 + + baz1: func(x: list) + + baz2: func() + + baz3: func(x: x) + } + import foo: interface { + foo1: func() + + foo2: func(x: u8) + + foo3: func(x: float32) + } +} diff --git a/crates/wit-component/tests/components/imports/module.wit b/crates/wit-component/tests/components/imports/module.wit index c5fad1d34d..a6fcd7a1ee 100644 --- a/crates/wit-component/tests/components/imports/module.wit +++ b/crates/wit-component/tests/components/imports/module.wit @@ -1,4 +1,6 @@ -default world my-world { +package foo:foo + +world module { import bar: interface { record x { a: u8 diff --git a/crates/wit-component/tests/components/invalid-module-import/module.wit b/crates/wit-component/tests/components/invalid-module-import/module.wit deleted file mode 100644 index 234a91911c..0000000000 --- a/crates/wit-component/tests/components/invalid-module-import/module.wit +++ /dev/null @@ -1 +0,0 @@ -default world foo {} diff --git a/crates/wit-component/tests/components/lift-options/component.wat b/crates/wit-component/tests/components/lift-options/component.wat index 6cb45fa016..ccaf935746 100644 --- a/crates/wit-component/tests/components/lift-options/component.wat +++ b/crates/wit-component/tests/components/lift-options/component.wat @@ -72,26 +72,26 @@ (memory (;0;) 1) (export "memory" (memory 0)) (export "cabi_realloc" (func 0)) - (export "foo#a" (func 1)) - (export "foo#b" (func 2)) - (export "foo#c" (func 3)) - (export "foo#d" (func 4)) - (export "foo#e" (func 5)) - (export "foo#f" (func 6)) - (export "foo#g" (func 7)) - (export "foo#h" (func 8)) - (export "foo#i" (func 9)) - (export "foo#j" (func 10)) - (export "foo#k" (func 11)) - (export "foo#l" (func 12)) - (export "cabi_post_foo#l" (func 13)) - (export "foo#m" (func 14)) - (export "cabi_post_foo#m" (func 15)) - (export "foo#n" (func 16)) - (export "foo#o" (func 17)) - (export "cabi_post_foo#o" (func 18)) - (export "foo#p" (func 19)) - (export "cabi_post_foo#p" (func 20)) + (export "foo:foo/my-default#a" (func 1)) + (export "foo:foo/my-default#b" (func 2)) + (export "foo:foo/my-default#c" (func 3)) + (export "foo:foo/my-default#d" (func 4)) + (export "foo:foo/my-default#e" (func 5)) + (export "foo:foo/my-default#f" (func 6)) + (export "foo:foo/my-default#g" (func 7)) + (export "foo:foo/my-default#h" (func 8)) + (export "foo:foo/my-default#i" (func 9)) + (export "foo:foo/my-default#j" (func 10)) + (export "foo:foo/my-default#k" (func 11)) + (export "foo:foo/my-default#l" (func 12)) + (export "cabi_post_foo:foo/my-default#l" (func 13)) + (export "foo:foo/my-default#m" (func 14)) + (export "cabi_post_foo:foo/my-default#m" (func 15)) + (export "foo:foo/my-default#n" (func 16)) + (export "foo:foo/my-default#o" (func 17)) + (export "cabi_post_foo:foo/my-default#o" (func 18)) + (export "foo:foo/my-default#p" (func 19)) + (export "cabi_post_foo:foo/my-default#p" (func 20)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") (processed-by "my-fake-bindgen" "123.45") @@ -101,66 +101,66 @@ (alias core export 0 "memory" (core memory (;0;))) (alias core export 0 "cabi_realloc" (core func (;0;))) (type (;0;) (func)) - (alias core export 0 "foo#a" (core func (;1;))) + (alias core export 0 "foo:foo/my-default#a" (core func (;1;))) (func (;0;) (type 0) (canon lift (core func 1))) (type (;1;) (list string)) (type (;2;) (func (param "x" 1))) - (alias core export 0 "foo#b" (core func (;2;))) + (alias core export 0 "foo:foo/my-default#b" (core func (;2;))) (func (;1;) (type 2) (canon lift (core func 2) (memory 0) (realloc 0) string-encoding=utf8)) (type (;3;) (record (field "s" string))) (type (;4;) (func (param "x" 3))) - (alias core export 0 "foo#c" (core func (;3;))) + (alias core export 0 "foo:foo/my-default#c" (core func (;3;))) (func (;2;) (type 4) (canon lift (core func 3) (memory 0) (realloc 0) string-encoding=utf8)) (type (;5;) (variant (case "s" string))) (type (;6;) (func (param "x" 5))) - (alias core export 0 "foo#d" (core func (;4;))) + (alias core export 0 "foo:foo/my-default#d" (core func (;4;))) (func (;3;) (type 6) (canon lift (core func 4) (memory 0) (realloc 0) string-encoding=utf8)) (type (;7;) (record (field "s" u32))) (type (;8;) (func (param "x" 7))) - (alias core export 0 "foo#e" (core func (;5;))) + (alias core export 0 "foo:foo/my-default#e" (core func (;5;))) (func (;4;) (type 8) (canon lift (core func 5))) (type (;9;) (variant (case "s" u32))) (type (;10;) (func (param "x" 9))) - (alias core export 0 "foo#f" (core func (;6;))) + (alias core export 0 "foo:foo/my-default#f" (core func (;6;))) (func (;5;) (type 10) (canon lift (core func 6))) (type (;11;) (list 3)) (type (;12;) (func (param "x" 11))) - (alias core export 0 "foo#g" (core func (;7;))) + (alias core export 0 "foo:foo/my-default#g" (core func (;7;))) (func (;6;) (type 12) (canon lift (core func 7) (memory 0) (realloc 0) string-encoding=utf8)) (type (;13;) (list 5)) (type (;14;) (func (param "x" 13))) - (alias core export 0 "foo#h" (core func (;8;))) + (alias core export 0 "foo:foo/my-default#h" (core func (;8;))) (func (;7;) (type 14) (canon lift (core func 8) (memory 0) (realloc 0) string-encoding=utf8)) (type (;15;) (list u32)) (type (;16;) (func (param "x" 15))) - (alias core export 0 "foo#i" (core func (;9;))) + (alias core export 0 "foo:foo/my-default#i" (core func (;9;))) (func (;8;) (type 16) (canon lift (core func 9) (memory 0) (realloc 0))) (type (;17;) (func (param "x" u32))) - (alias core export 0 "foo#j" (core func (;10;))) + (alias core export 0 "foo:foo/my-default#j" (core func (;10;))) (func (;9;) (type 17) (canon lift (core func 10))) (type (;18;) (tuple u32 u32)) (type (;19;) (func (result 18))) - (alias core export 0 "foo#k" (core func (;11;))) + (alias core export 0 "foo:foo/my-default#k" (core func (;11;))) (func (;10;) (type 19) (canon lift (core func 11) (memory 0))) (type (;20;) (func (result string))) - (alias core export 0 "foo#l" (core func (;12;))) - (alias core export 0 "cabi_post_foo#l" (core func (;13;))) + (alias core export 0 "foo:foo/my-default#l" (core func (;12;))) + (alias core export 0 "cabi_post_foo:foo/my-default#l" (core func (;13;))) (func (;11;) (type 20) (canon lift (core func 12) (memory 0) string-encoding=utf8 (post-return 13))) (type (;21;) (func (result 15))) - (alias core export 0 "foo#m" (core func (;14;))) - (alias core export 0 "cabi_post_foo#m" (core func (;15;))) + (alias core export 0 "foo:foo/my-default#m" (core func (;14;))) + (alias core export 0 "cabi_post_foo:foo/my-default#m" (core func (;15;))) (func (;12;) (type 21) (canon lift (core func 14) (memory 0) (post-return 15))) (type (;22;) (func (result u32))) - (alias core export 0 "foo#n" (core func (;16;))) + (alias core export 0 "foo:foo/my-default#n" (core func (;16;))) (func (;13;) (type 22) (canon lift (core func 16))) (type (;23;) (func (result 5))) - (alias core export 0 "foo#o" (core func (;17;))) - (alias core export 0 "cabi_post_foo#o" (core func (;18;))) + (alias core export 0 "foo:foo/my-default#o" (core func (;17;))) + (alias core export 0 "cabi_post_foo:foo/my-default#o" (core func (;18;))) (func (;14;) (type 23) (canon lift (core func 17) (memory 0) string-encoding=utf8 (post-return 18))) (type (;24;) (list 9)) (type (;25;) (func (result 24))) - (alias core export 0 "foo#p" (core func (;19;))) - (alias core export 0 "cabi_post_foo#p" (core func (;20;))) + (alias core export 0 "foo:foo/my-default#p" (core func (;19;))) + (alias core export 0 "cabi_post_foo:foo/my-default#p" (core func (;20;))) (func (;15;) (type 25) (canon lift (core func 19) (memory 0) (post-return 20))) (component (;0;) (type (;0;) (func)) @@ -282,5 +282,5 @@ (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "foo" (instance 0)) + (export (;1;) (interface "foo:foo/my-default") (instance 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/lift-options/component.wit b/crates/wit-component/tests/components/lift-options/component.wit deleted file mode 100644 index ef941fcf95..0000000000 --- a/crates/wit-component/tests/components/lift-options/component.wit +++ /dev/null @@ -1,53 +0,0 @@ -interface foo { - record r { - s: string, - } - - variant v { - s(string), - } - - record r-no-string { - s: u32, - } - - variant v-no-string { - s(u32), - } - - a: func() - - b: func(x: list) - - c: func(x: r) - - d: func(x: v) - - e: func(x: r-no-string) - - f: func(x: v-no-string) - - g: func(x: list) - - h: func(x: list) - - i: func(x: list) - - j: func(x: u32) - - k: func() -> tuple - - l: func() -> string - - m: func() -> list - - n: func() -> u32 - - o: func() -> v - - p: func() -> list -} - -default world component { - export foo: self.foo -} diff --git a/crates/wit-component/tests/components/lift-options/component.wit.print b/crates/wit-component/tests/components/lift-options/component.wit.print new file mode 100644 index 0000000000..eef89f13fc --- /dev/null +++ b/crates/wit-component/tests/components/lift-options/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + export foo:foo/my-default +} diff --git a/crates/wit-component/tests/components/lift-options/module.wat b/crates/wit-component/tests/components/lift-options/module.wat index aa6a7acb5b..242c2057af 100644 --- a/crates/wit-component/tests/components/lift-options/module.wat +++ b/crates/wit-component/tests/components/lift-options/module.wat @@ -1,24 +1,24 @@ (module (memory (export "memory") 1) (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) - (func (export "foo#a") unreachable) - (func (export "foo#b") (param i32 i32) unreachable) - (func (export "foo#c") (param i32 i32) unreachable) - (func (export "foo#d") (param i32 i32 i32) unreachable) - (func (export "foo#e") (param i32) unreachable) - (func (export "foo#f") (param i32 i32) unreachable) - (func (export "foo#g") (param i32 i32) unreachable) - (func (export "foo#h") (param i32 i32) unreachable) - (func (export "foo#i") (param i32 i32) unreachable) - (func (export "foo#j") (param i32) unreachable) - (func (export "foo#k") (result i32) unreachable) - (func (export "foo#l") (result i32) unreachable) - (func (export "cabi_post_foo#l") (param i32) unreachable) - (func (export "foo#m") (result i32) unreachable) - (func (export "cabi_post_foo#m") (param i32) unreachable) - (func (export "foo#n") (result i32) unreachable) - (func (export "foo#o") (result i32) unreachable) - (func (export "cabi_post_foo#o") (param i32) unreachable) - (func (export "foo#p") (result i32) unreachable) - (func (export "cabi_post_foo#p") (param i32) unreachable) + (func (export "foo:foo/my-default#a") unreachable) + (func (export "foo:foo/my-default#b") (param i32 i32) unreachable) + (func (export "foo:foo/my-default#c") (param i32 i32) unreachable) + (func (export "foo:foo/my-default#d") (param i32 i32 i32) unreachable) + (func (export "foo:foo/my-default#e") (param i32) unreachable) + (func (export "foo:foo/my-default#f") (param i32 i32) unreachable) + (func (export "foo:foo/my-default#g") (param i32 i32) unreachable) + (func (export "foo:foo/my-default#h") (param i32 i32) unreachable) + (func (export "foo:foo/my-default#i") (param i32 i32) unreachable) + (func (export "foo:foo/my-default#j") (param i32) unreachable) + (func (export "foo:foo/my-default#k") (result i32) unreachable) + (func (export "foo:foo/my-default#l") (result i32) unreachable) + (func (export "cabi_post_foo:foo/my-default#l") (param i32) unreachable) + (func (export "foo:foo/my-default#m") (result i32) unreachable) + (func (export "cabi_post_foo:foo/my-default#m") (param i32) unreachable) + (func (export "foo:foo/my-default#n") (result i32) unreachable) + (func (export "foo:foo/my-default#o") (result i32) unreachable) + (func (export "cabi_post_foo:foo/my-default#o") (param i32) unreachable) + (func (export "foo:foo/my-default#p") (result i32) unreachable) + (func (export "cabi_post_foo:foo/my-default#p") (param i32) unreachable) ) diff --git a/crates/wit-component/tests/components/lift-options/module.wit b/crates/wit-component/tests/components/lift-options/module.wit index b1d4b6db11..a491d67e2f 100644 --- a/crates/wit-component/tests/components/lift-options/module.wit +++ b/crates/wit-component/tests/components/lift-options/module.wit @@ -1,3 +1,5 @@ +package foo:foo + interface my-default { record r { s: string @@ -33,6 +35,6 @@ interface my-default { p: func() -> list } -default world my-world { - export foo: self.my-default +world module { + export my-default } diff --git a/crates/wit-component/tests/components/lower-options/component.wat b/crates/wit-component/tests/components/lower-options/component.wat index 6ffada1bd5..f402a5aff9 100644 --- a/crates/wit-component/tests/components/lower-options/component.wat +++ b/crates/wit-component/tests/components/lower-options/component.wat @@ -49,7 +49,7 @@ (export (;15;) "p" (func (type 29))) ) ) - (import "foo" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (core module (;0;) (type (;0;) (func)) (type (;1;) (func (param i32 i32))) @@ -57,22 +57,22 @@ (type (;3;) (func (param i32))) (type (;4;) (func (result i32))) (type (;5;) (func (param i32 i32 i32 i32) (result i32))) - (import "foo" "a" (func (;0;) (type 0))) - (import "foo" "b" (func (;1;) (type 1))) - (import "foo" "c" (func (;2;) (type 1))) - (import "foo" "d" (func (;3;) (type 2))) - (import "foo" "e" (func (;4;) (type 3))) - (import "foo" "f" (func (;5;) (type 1))) - (import "foo" "g" (func (;6;) (type 1))) - (import "foo" "h" (func (;7;) (type 1))) - (import "foo" "i" (func (;8;) (type 1))) - (import "foo" "j" (func (;9;) (type 3))) - (import "foo" "k" (func (;10;) (type 3))) - (import "foo" "l" (func (;11;) (type 3))) - (import "foo" "m" (func (;12;) (type 3))) - (import "foo" "n" (func (;13;) (type 4))) - (import "foo" "o" (func (;14;) (type 3))) - (import "foo" "p" (func (;15;) (type 3))) + (import "foo:foo/foo" "a" (func (;0;) (type 0))) + (import "foo:foo/foo" "b" (func (;1;) (type 1))) + (import "foo:foo/foo" "c" (func (;2;) (type 1))) + (import "foo:foo/foo" "d" (func (;3;) (type 2))) + (import "foo:foo/foo" "e" (func (;4;) (type 3))) + (import "foo:foo/foo" "f" (func (;5;) (type 1))) + (import "foo:foo/foo" "g" (func (;6;) (type 1))) + (import "foo:foo/foo" "h" (func (;7;) (type 1))) + (import "foo:foo/foo" "i" (func (;8;) (type 1))) + (import "foo:foo/foo" "j" (func (;9;) (type 3))) + (import "foo:foo/foo" "k" (func (;10;) (type 3))) + (import "foo:foo/foo" "l" (func (;11;) (type 3))) + (import "foo:foo/foo" "m" (func (;12;) (type 3))) + (import "foo:foo/foo" "n" (func (;13;) (type 4))) + (import "foo:foo/foo" "o" (func (;14;) (type 3))) + (import "foo:foo/foo" "p" (func (;15;) (type 3))) (func (;16;) (type 5) (param i32 i32 i32 i32) (result i32) unreachable ) @@ -88,80 +88,80 @@ (type (;0;) (func (param i32 i32))) (type (;1;) (func (param i32 i32 i32))) (type (;2;) (func (param i32))) - (func $indirect-foo-b (;0;) (type 0) (param i32 i32) + (func $indirect-foo:foo/foo-b (;0;) (type 0) (param i32 i32) local.get 0 local.get 1 i32.const 0 call_indirect (type 0) ) - (func $indirect-foo-c (;1;) (type 0) (param i32 i32) + (func $indirect-foo:foo/foo-c (;1;) (type 0) (param i32 i32) local.get 0 local.get 1 i32.const 1 call_indirect (type 0) ) - (func $indirect-foo-d (;2;) (type 1) (param i32 i32 i32) + (func $indirect-foo:foo/foo-d (;2;) (type 1) (param i32 i32 i32) local.get 0 local.get 1 local.get 2 i32.const 2 call_indirect (type 1) ) - (func $indirect-foo-g (;3;) (type 0) (param i32 i32) + (func $indirect-foo:foo/foo-g (;3;) (type 0) (param i32 i32) local.get 0 local.get 1 i32.const 3 call_indirect (type 0) ) - (func $indirect-foo-h (;4;) (type 0) (param i32 i32) + (func $indirect-foo:foo/foo-h (;4;) (type 0) (param i32 i32) local.get 0 local.get 1 i32.const 4 call_indirect (type 0) ) - (func $indirect-foo-i (;5;) (type 0) (param i32 i32) + (func $indirect-foo:foo/foo-i (;5;) (type 0) (param i32 i32) local.get 0 local.get 1 i32.const 5 call_indirect (type 0) ) - (func $indirect-foo-k (;6;) (type 2) (param i32) + (func $indirect-foo:foo/foo-k (;6;) (type 2) (param i32) local.get 0 i32.const 6 call_indirect (type 2) ) - (func $indirect-foo-l (;7;) (type 2) (param i32) + (func $indirect-foo:foo/foo-l (;7;) (type 2) (param i32) local.get 0 i32.const 7 call_indirect (type 2) ) - (func $indirect-foo-m (;8;) (type 2) (param i32) + (func $indirect-foo:foo/foo-m (;8;) (type 2) (param i32) local.get 0 i32.const 8 call_indirect (type 2) ) - (func $indirect-foo-o (;9;) (type 2) (param i32) + (func $indirect-foo:foo/foo-o (;9;) (type 2) (param i32) local.get 0 i32.const 9 call_indirect (type 2) ) - (func $indirect-foo-p (;10;) (type 2) (param i32) + (func $indirect-foo:foo/foo-p (;10;) (type 2) (param i32) local.get 0 i32.const 10 call_indirect (type 2) ) (table (;0;) 11 11 funcref) - (export "0" (func $indirect-foo-b)) - (export "1" (func $indirect-foo-c)) - (export "2" (func $indirect-foo-d)) - (export "3" (func $indirect-foo-g)) - (export "4" (func $indirect-foo-h)) - (export "5" (func $indirect-foo-i)) - (export "6" (func $indirect-foo-k)) - (export "7" (func $indirect-foo-l)) - (export "8" (func $indirect-foo-m)) - (export "9" (func $indirect-foo-o)) - (export "10" (func $indirect-foo-p)) + (export "0" (func $indirect-foo:foo/foo-b)) + (export "1" (func $indirect-foo:foo/foo-c)) + (export "2" (func $indirect-foo:foo/foo-d)) + (export "3" (func $indirect-foo:foo/foo-g)) + (export "4" (func $indirect-foo:foo/foo-h)) + (export "5" (func $indirect-foo:foo/foo-i)) + (export "6" (func $indirect-foo:foo/foo-k)) + (export "7" (func $indirect-foo:foo/foo-l)) + (export "8" (func $indirect-foo:foo/foo-m)) + (export "9" (func $indirect-foo:foo/foo-o)) + (export "10" (func $indirect-foo:foo/foo-p)) (export "$imports" (table 0)) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") @@ -229,7 +229,7 @@ (export "n" (func 15)) ) (core instance (;2;) (instantiate 0 - (with "foo" (instance 1)) + (with "foo:foo/foo" (instance 1)) ) ) (alias core export 2 "memory" (core memory (;0;))) diff --git a/crates/wit-component/tests/components/lower-options/component.wit b/crates/wit-component/tests/components/lower-options/component.wit deleted file mode 100644 index b16a03105d..0000000000 --- a/crates/wit-component/tests/components/lower-options/component.wit +++ /dev/null @@ -1,53 +0,0 @@ -interface foo { - record r { - s: string, - } - - variant v { - s(string), - } - - record r-no-string { - s: u32, - } - - variant v-no-string { - s(u32), - } - - a: func() - - b: func(x: list) - - c: func(x: r) - - d: func(x: v) - - e: func(x: r-no-string) - - f: func(x: v-no-string) - - g: func(x: list) - - h: func(x: list) - - i: func(x: list) - - j: func(x: u32) - - k: func() -> tuple - - l: func() -> string - - m: func() -> list - - n: func() -> u32 - - o: func() -> v - - p: func() -> list -} - -default world component { - import foo: self.foo -} diff --git a/crates/wit-component/tests/components/lower-options/component.wit.print b/crates/wit-component/tests/components/lower-options/component.wit.print new file mode 100644 index 0000000000..7ef7c78b37 --- /dev/null +++ b/crates/wit-component/tests/components/lower-options/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + import foo:foo/foo +} diff --git a/crates/wit-component/tests/components/lower-options/module.wat b/crates/wit-component/tests/components/lower-options/module.wat index 4a44c57b33..a0a9f1327d 100644 --- a/crates/wit-component/tests/components/lower-options/module.wat +++ b/crates/wit-component/tests/components/lower-options/module.wat @@ -1,20 +1,20 @@ (module - (import "foo" "a" (func)) - (import "foo" "b" (func (param i32 i32))) - (import "foo" "c" (func (param i32 i32))) - (import "foo" "d" (func (param i32 i32 i32))) - (import "foo" "e" (func (param i32))) - (import "foo" "f" (func (param i32 i32))) - (import "foo" "g" (func (param i32 i32))) - (import "foo" "h" (func (param i32 i32))) - (import "foo" "i" (func (param i32 i32))) - (import "foo" "j" (func (param i32))) - (import "foo" "k" (func (param i32))) - (import "foo" "l" (func (param i32))) - (import "foo" "m" (func (param i32))) - (import "foo" "n" (func (result i32))) - (import "foo" "o" (func (param i32))) - (import "foo" "p" (func (param i32))) + (import "foo:foo/foo" "a" (func)) + (import "foo:foo/foo" "b" (func (param i32 i32))) + (import "foo:foo/foo" "c" (func (param i32 i32))) + (import "foo:foo/foo" "d" (func (param i32 i32 i32))) + (import "foo:foo/foo" "e" (func (param i32))) + (import "foo:foo/foo" "f" (func (param i32 i32))) + (import "foo:foo/foo" "g" (func (param i32 i32))) + (import "foo:foo/foo" "h" (func (param i32 i32))) + (import "foo:foo/foo" "i" (func (param i32 i32))) + (import "foo:foo/foo" "j" (func (param i32))) + (import "foo:foo/foo" "k" (func (param i32))) + (import "foo:foo/foo" "l" (func (param i32))) + (import "foo:foo/foo" "m" (func (param i32))) + (import "foo:foo/foo" "n" (func (result i32))) + (import "foo:foo/foo" "o" (func (param i32))) + (import "foo:foo/foo" "p" (func (param i32))) (memory (export "memory") 1) (func (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) unreachable) -) \ No newline at end of file +) diff --git a/crates/wit-component/tests/components/lower-options/module.wit b/crates/wit-component/tests/components/lower-options/module.wit index d4dae943f7..f39ea6b601 100644 --- a/crates/wit-component/tests/components/lower-options/module.wit +++ b/crates/wit-component/tests/components/lower-options/module.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { record r { s: string @@ -33,6 +35,6 @@ interface foo { p: func() -> list } -default world my-world { - import foo: self.foo +world module { + import foo } diff --git a/crates/wit-component/tests/components/many-same-names/component.wat b/crates/wit-component/tests/components/many-same-names/component.wat new file mode 100644 index 0000000000..c953eae14a --- /dev/null +++ b/crates/wit-component/tests/components/many-same-names/component.wat @@ -0,0 +1,55 @@ +(component + (type (;0;) + (instance + (type (;0;) (record)) + (export (;1;) "r1" (type (eq 0))) + (type (;2;) (record (field "x" 1))) + (export (;3;) "r2" (type (eq 2))) + ) + ) + (import (interface "foo:foo/name") (instance (;0;) (type 0))) + (core module (;0;) + (type (;0;) (func)) + (func (;0;) (type 0)) + (export "name#a" (func 0)) + (@producers + (processed-by "wit-component" "$CARGO_PKG_VERSION") + (processed-by "my-fake-bindgen" "123.45") + ) + ) + (core instance (;0;) (instantiate 0)) + (component (;0;) + (type (;0;) (record)) + (export (;1;) "r1" (type 0)) + (type (;2;) (record (field "x" 1))) + (export (;3;) "r2" (type 2)) + ) + (instance (;1;) (instantiate 0)) + (export (;2;) (interface "foo:foo/name") (instance 1)) + (type (;1;) (func)) + (alias core export 0 "name#a" (core func (;0;))) + (func (;0;) (type 1) (canon lift (core func 0))) + (alias export 2 "r1" (type (;2;))) + (alias export 2 "r2" (type (;3;))) + (component (;1;) + (type (;0;) (record)) + (import "import-type-r1" (type (;1;) (eq 0))) + (type (;2;) (record (field "x" 1))) + (import "import-type-r2" (type (;3;) (eq 2))) + (type (;4;) (func)) + (import "import-func-a" (func (;0;) (type 4))) + (type (;5;) (func)) + (export (;1;) "a" (func 0) (func (type 5))) + (export (;6;) "r2" (type 3)) + ) + (instance (;3;) (instantiate 1 + (with "import-func-a" (func 0)) + (with "import-type-r1" (type 2)) + (with "import-type-r2" (type 3)) + ) + ) + (@producers + (processed-by "wit-component" "$CARGO_PKG_VERSION") + ) + (export (;4;) "name" (instance 3)) +) \ No newline at end of file diff --git a/crates/wit-component/tests/components/many-same-names/component.wit.print b/crates/wit-component/tests/components/many-same-names/component.wit.print new file mode 100644 index 0000000000..9d04a8954c --- /dev/null +++ b/crates/wit-component/tests/components/many-same-names/component.wit.print @@ -0,0 +1,10 @@ +package root:component + +world root { + import foo:foo/name + export foo:foo/name + export name: interface { + use foo:foo/name.{r2} + a: func() + } +} diff --git a/crates/wit-component/tests/components/many-same-names/module.wat b/crates/wit-component/tests/components/many-same-names/module.wat new file mode 100644 index 0000000000..1cb58c5b52 --- /dev/null +++ b/crates/wit-component/tests/components/many-same-names/module.wat @@ -0,0 +1,3 @@ +(module + (func (export "name#a")) +) diff --git a/crates/wit-component/tests/components/many-same-names/module.wit b/crates/wit-component/tests/components/many-same-names/module.wit new file mode 100644 index 0000000000..8fc8a4f90d --- /dev/null +++ b/crates/wit-component/tests/components/many-same-names/module.wit @@ -0,0 +1,19 @@ +package foo:foo + +interface name { + record r1 {} + + record r2 { + x: r1 + } +} + +world module { + import name + export name + + export name: interface { + use name.{r2} + a: func() + } +} diff --git a/crates/wit-component/tests/components/missing-default-export/module.wit b/crates/wit-component/tests/components/missing-default-export/module.wit deleted file mode 100644 index 4e607cdba0..0000000000 --- a/crates/wit-component/tests/components/missing-default-export/module.wit +++ /dev/null @@ -1,3 +0,0 @@ -default world my-world { - export a: func() -} diff --git a/crates/wit-component/tests/components/missing-import-func/error.txt b/crates/wit-component/tests/components/missing-import-func/error.txt deleted file mode 100644 index ea9b14277d..0000000000 --- a/crates/wit-component/tests/components/missing-import-func/error.txt +++ /dev/null @@ -1,4 +0,0 @@ -failed to validate import interface `foo` - -Caused by: - import interface `foo` is missing function `bar` that is required by the module \ No newline at end of file diff --git a/crates/wit-component/tests/components/missing-import-func/module.wit b/crates/wit-component/tests/components/missing-import-func/module.wit deleted file mode 100644 index d0e7916515..0000000000 --- a/crates/wit-component/tests/components/missing-import-func/module.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface foo { - a: func() -} - -default world my-world { - import foo: self.foo -} diff --git a/crates/wit-component/tests/components/missing-import/module.wit b/crates/wit-component/tests/components/missing-import/module.wit deleted file mode 100644 index 1f99081f58..0000000000 --- a/crates/wit-component/tests/components/missing-import/module.wit +++ /dev/null @@ -1 +0,0 @@ -default world empty {} diff --git a/crates/wit-component/tests/components/no-realloc-required/component.wit b/crates/wit-component/tests/components/no-realloc-required/component.wit deleted file mode 100644 index eddb9f98d8..0000000000 --- a/crates/wit-component/tests/components/no-realloc-required/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface foo { - log: func(s: string) -} - -default world component { - import foo: self.foo -} diff --git a/crates/wit-component/tests/components/no-realloc-required/component.wit.print b/crates/wit-component/tests/components/no-realloc-required/component.wit.print new file mode 100644 index 0000000000..f1fc2527b5 --- /dev/null +++ b/crates/wit-component/tests/components/no-realloc-required/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import foo: interface { + log: func(s: string) + } +} diff --git a/crates/wit-component/tests/components/no-realloc-required/module.wit b/crates/wit-component/tests/components/no-realloc-required/module.wit index 558f5ac83f..5c8d412414 100644 --- a/crates/wit-component/tests/components/no-realloc-required/module.wit +++ b/crates/wit-component/tests/components/no-realloc-required/module.wit @@ -1,4 +1,6 @@ -default world foo { +package foo:foo + +world module { import foo: interface { log: func(s: string) } diff --git a/crates/wit-component/tests/components/post-return/component.wit b/crates/wit-component/tests/components/post-return/component.wit deleted file mode 100644 index 5fb868d11a..0000000000 --- a/crates/wit-component/tests/components/post-return/component.wit +++ /dev/null @@ -1,3 +0,0 @@ -default world component { - export a: func() -> string -} diff --git a/crates/wit-component/tests/components/post-return/component.wit.print b/crates/wit-component/tests/components/post-return/component.wit.print new file mode 100644 index 0000000000..a1d34262af --- /dev/null +++ b/crates/wit-component/tests/components/post-return/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + export a: func() -> string +} diff --git a/crates/wit-component/tests/components/post-return/module.wit b/crates/wit-component/tests/components/post-return/module.wit index 1d99c42228..0d0580fad3 100644 --- a/crates/wit-component/tests/components/post-return/module.wit +++ b/crates/wit-component/tests/components/post-return/module.wit @@ -1,3 +1,5 @@ -default world foo { +package foo:foo + +world module { export a: func() -> string } diff --git a/crates/wit-component/tests/components/rename-import-interface/component.wat b/crates/wit-component/tests/components/rename-import-interface/component.wat index ee70df6abc..d9da64c06a 100644 --- a/crates/wit-component/tests/components/rename-import-interface/component.wat +++ b/crates/wit-component/tests/components/rename-import-interface/component.wat @@ -5,10 +5,10 @@ (export (;0;) "the-func" (func (type 0))) ) ) - (import "bar" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (core module (;0;) (type (;0;) (func)) - (import "bar" "the-func" (func (;0;) (type 0))) + (import "foo:foo/foo" "the-func" (func (;0;) (type 0))) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") (processed-by "my-fake-bindgen" "123.45") @@ -23,7 +23,7 @@ (export "the-func" (func 0)) ) (core instance (;1;) (instantiate 0 - (with "bar" (instance 0)) + (with "foo:foo/foo" (instance 0)) ) ) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/rename-import-interface/component.wit b/crates/wit-component/tests/components/rename-import-interface/component.wit deleted file mode 100644 index d2808cbc8e..0000000000 --- a/crates/wit-component/tests/components/rename-import-interface/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface bar { - the-func: func() -} - -default world component { - import bar: self.bar -} diff --git a/crates/wit-component/tests/components/rename-import-interface/component.wit.print b/crates/wit-component/tests/components/rename-import-interface/component.wit.print new file mode 100644 index 0000000000..7ef7c78b37 --- /dev/null +++ b/crates/wit-component/tests/components/rename-import-interface/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + import foo:foo/foo +} diff --git a/crates/wit-component/tests/components/rename-import-interface/module.wat b/crates/wit-component/tests/components/rename-import-interface/module.wat index e639cf3752..3a09d29a69 100644 --- a/crates/wit-component/tests/components/rename-import-interface/module.wat +++ b/crates/wit-component/tests/components/rename-import-interface/module.wat @@ -1,3 +1,3 @@ (module - (import "bar" "the-func" (func)) + (import "foo:foo/foo" "the-func" (func)) ) diff --git a/crates/wit-component/tests/components/rename-import-interface/module.wit b/crates/wit-component/tests/components/rename-import-interface/module.wit index 15eee29f5b..fc1e937347 100644 --- a/crates/wit-component/tests/components/rename-import-interface/module.wit +++ b/crates/wit-component/tests/components/rename-import-interface/module.wit @@ -1,7 +1,9 @@ +package foo:foo + interface foo { the-func: func() } -default world the-world { - import bar: self.foo +world module { + import foo } diff --git a/crates/wit-component/tests/components/rename-interface/component.wat b/crates/wit-component/tests/components/rename-interface/component.wat index 382c876c27..737f347626 100644 --- a/crates/wit-component/tests/components/rename-interface/component.wat +++ b/crates/wit-component/tests/components/rename-interface/component.wat @@ -5,7 +5,7 @@ (export (;1;) "bar" (type (eq 0))) ) ) - (import "different-name" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (alias export 0 "bar" (type (;1;))) (type (;2;) (instance diff --git a/crates/wit-component/tests/components/rename-interface/component.wit b/crates/wit-component/tests/components/rename-interface/component.wit deleted file mode 100644 index 4246a1fb0b..0000000000 --- a/crates/wit-component/tests/components/rename-interface/component.wit +++ /dev/null @@ -1,15 +0,0 @@ -interface different-name { - record bar { - } - -} - -interface other-name { - use self.different-name.{bar} - a: func() -> bar -} - -default world component { - import different-name: self.different-name - import other-name: self.other-name -} diff --git a/crates/wit-component/tests/components/rename-interface/component.wit.print b/crates/wit-component/tests/components/rename-interface/component.wit.print new file mode 100644 index 0000000000..7d8c3347fa --- /dev/null +++ b/crates/wit-component/tests/components/rename-interface/component.wit.print @@ -0,0 +1,9 @@ +package root:component + +world root { + import foo:foo/foo + import other-name: interface { + use foo:foo/foo.{bar} + a: func() -> bar + } +} diff --git a/crates/wit-component/tests/components/rename-interface/module.wit b/crates/wit-component/tests/components/rename-interface/module.wit index 889deb595e..468e6f0fad 100644 --- a/crates/wit-component/tests/components/rename-interface/module.wit +++ b/crates/wit-component/tests/components/rename-interface/module.wit @@ -1,13 +1,15 @@ +package foo:foo + interface foo { record bar {} a: func() -> bar } -default world the-world { - import different-name: self.foo +world module { + import foo import other-name: interface { - use self.foo.{bar} + use foo.{bar} a: func() -> bar } diff --git a/crates/wit-component/tests/components/simple/component.wit b/crates/wit-component/tests/components/simple/component.wit.print similarity index 70% rename from crates/wit-component/tests/components/simple/component.wit rename to crates/wit-component/tests/components/simple/component.wit.print index be8388ec0c..5c7dcae2fd 100644 --- a/crates/wit-component/tests/components/simple/component.wit +++ b/crates/wit-component/tests/components/simple/component.wit.print @@ -1,4 +1,6 @@ -default world component { +package root:component + +world root { export a: func() export b: func() -> string export c: func(x: string) -> string diff --git a/crates/wit-component/tests/components/simple/module.wit b/crates/wit-component/tests/components/simple/module.wit index af939cdbe4..38d41e86d4 100644 --- a/crates/wit-component/tests/components/simple/module.wit +++ b/crates/wit-component/tests/components/simple/module.wit @@ -1,4 +1,6 @@ -default world foo { +package foo:foo + +world module { export a: func() export b: func() -> string export c: func(x: string) -> string diff --git a/crates/wit-component/tests/components/tricky-order/component.wat b/crates/wit-component/tests/components/tricky-order/component.wat index 5b755a0487..b5b5de079e 100644 --- a/crates/wit-component/tests/components/tricky-order/component.wat +++ b/crates/wit-component/tests/components/tricky-order/component.wat @@ -5,7 +5,7 @@ (export (;1;) "name" (type (eq 0))) ) ) - (import "name1" (instance (;0;) (type 0))) + (import (interface "foo:foo/name1") (instance (;0;) (type 0))) (alias export 0 "name" (type (;1;))) (type (;2;) (instance @@ -13,7 +13,7 @@ (export (;1;) "name" (type (eq 0))) ) ) - (import "name2" (instance (;1;) (type 2))) + (import (interface "foo:foo/name2") (instance (;1;) (type 2))) (core module (;0;) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") diff --git a/crates/wit-component/tests/components/tricky-order/component.wit b/crates/wit-component/tests/components/tricky-order/component.wit deleted file mode 100644 index 50a9380a95..0000000000 --- a/crates/wit-component/tests/components/tricky-order/component.wit +++ /dev/null @@ -1,20 +0,0 @@ -interface name1 { - record name { - } - -} - -interface name2 { - use self.name1.{name} -} - -interface name { - use self.name1.{name} - use self.name2.{name as name1} -} - -default world component { - import name1: self.name1 - import name2: self.name2 - export name: self.name -} diff --git a/crates/wit-component/tests/components/tricky-order/component.wit.print b/crates/wit-component/tests/components/tricky-order/component.wit.print new file mode 100644 index 0000000000..0bc89ae660 --- /dev/null +++ b/crates/wit-component/tests/components/tricky-order/component.wit.print @@ -0,0 +1,10 @@ +package root:component + +world root { + import foo:foo/name1 + import foo:foo/name2 + export name: interface { + use foo:foo/name1.{name} + use foo:foo/name2.{name as name1} + } +} diff --git a/crates/wit-component/tests/components/tricky-order/module.wit b/crates/wit-component/tests/components/tricky-order/module.wit index 1228e2c54e..045d2bf180 100644 --- a/crates/wit-component/tests/components/tricky-order/module.wit +++ b/crates/wit-component/tests/components/tricky-order/module.wit @@ -1,16 +1,18 @@ -default interface name1 { +package foo:foo + +interface name1 { record name {} } interface name2 { - use self.name1.{name} + use name1.{name} } -default world name3 { - import name1: self.name1 - import name2: self.name2 +world module { + import name1 + import name2 export name: interface { - use self.name1.{name} - use self.name2.{name as name1} + use name1.{name} + use name2.{name as name1} } } diff --git a/crates/wit-component/tests/components/unused-import/component.wat b/crates/wit-component/tests/components/unused-import/component.wat index 8220fc046c..291ae8f725 100644 --- a/crates/wit-component/tests/components/unused-import/component.wat +++ b/crates/wit-component/tests/components/unused-import/component.wat @@ -5,10 +5,10 @@ (export (;0;) "name" (func (type 0))) ) ) - (import "foo" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (core module (;0;) (type (;0;) (func (param i32))) - (import "foo" "name" (func (;0;) (type 0))) + (import "foo:foo/foo" "name" (func (;0;) (type 0))) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") (processed-by "my-fake-bindgen" "123.45") @@ -23,7 +23,7 @@ (export "name" (func 0)) ) (core instance (;1;) (instantiate 0 - (with "foo" (instance 0)) + (with "foo:foo/foo" (instance 0)) ) ) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/unused-import/component.wit b/crates/wit-component/tests/components/unused-import/component.wit deleted file mode 100644 index 6ad8ced63d..0000000000 --- a/crates/wit-component/tests/components/unused-import/component.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface foo { - name: func(x: bool) -} - -default world component { - import foo: self.foo -} diff --git a/crates/wit-component/tests/components/unused-import/component.wit.print b/crates/wit-component/tests/components/unused-import/component.wit.print new file mode 100644 index 0000000000..7ef7c78b37 --- /dev/null +++ b/crates/wit-component/tests/components/unused-import/component.wit.print @@ -0,0 +1,5 @@ +package root:component + +world root { + import foo:foo/foo +} diff --git a/crates/wit-component/tests/components/unused-import/module.wat b/crates/wit-component/tests/components/unused-import/module.wat index 8fbe7d0093..eede8e1ac4 100644 --- a/crates/wit-component/tests/components/unused-import/module.wat +++ b/crates/wit-component/tests/components/unused-import/module.wat @@ -1,3 +1,3 @@ (module - (import "foo" "name" (func (param i32))) + (import "foo:foo/foo" "name" (func (param i32))) ) diff --git a/crates/wit-component/tests/components/unused-import/module.wit b/crates/wit-component/tests/components/unused-import/module.wit index 1d978499e3..770ec45c46 100644 --- a/crates/wit-component/tests/components/unused-import/module.wit +++ b/crates/wit-component/tests/components/unused-import/module.wit @@ -1,10 +1,12 @@ +package foo:foo + interface bar {} interface foo { name: func(x: bool) } -default world my-world { - import unused: self.bar - import foo: self.foo +world module { + import bar // unused + import foo } diff --git a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat index 82d972b364..396e108458 100644 --- a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat +++ b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wat @@ -7,14 +7,14 @@ (export (;0;) "the-func" (func (type 2))) ) ) - (import "i1" (instance (;0;) (type 0))) + (import (interface "foo:foo/i") (instance (;0;) (type 0))) (alias export 0 "some-type" (type (;1;))) (import "other-name" (type (;2;) (eq 1))) (core module (;0;) (type (;0;) (func (param i32 i64 i32))) (type (;1;) (func (param i32 i32 i32 i32) (result i32))) (type (;2;) (func)) - (import "i1" "the-func" (func (;0;) (type 2))) + (import "foo:foo/i" "the-func" (func (;0;) (type 2))) (func (;1;) (type 2) unreachable ) @@ -22,7 +22,7 @@ unreachable ) (memory (;0;) 0) - (export "i2#the-func" (func 1)) + (export "foo:foo/i#the-func" (func 1)) (export "cabi_realloc" (func 2)) (export "memory" (memory 0)) (@producers @@ -36,14 +36,14 @@ (export "the-func" (func 0)) ) (core instance (;1;) (instantiate 0 - (with "i1" (instance 0)) + (with "foo:foo/i" (instance 0)) ) ) (alias core export 1 "memory" (core memory (;0;))) (alias core export 1 "cabi_realloc" (core func (;1;))) (type (;3;) (record)) (type (;4;) (func (result 3))) - (alias core export 1 "i2#the-func" (core func (;2;))) + (alias core export 1 "foo:foo/i#the-func" (core func (;2;))) (func (;1;) (type 4) (canon lift (core func 2))) (component (;0;) (type (;0;) (record)) @@ -63,5 +63,5 @@ (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;2;) "i2" (instance 1)) + (export (;2;) (interface "foo:foo/i") (instance 1)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wit b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wit deleted file mode 100644 index f12875dc84..0000000000 --- a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wit +++ /dev/null @@ -1,19 +0,0 @@ -interface i1 { - record some-type { - } - - the-func: func() -> some-type -} - -interface i2 { - record some-type { - } - - the-func: func() -> some-type -} - -default world component { - import i1: self.i1 - use self.i1.{some-type as other-name} - export i2: self.i2 -} diff --git a/crates/wit-component/tests/components/worlds-with-type-renamings/component.wit.print b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wit.print new file mode 100644 index 0000000000..de1389d4bf --- /dev/null +++ b/crates/wit-component/tests/components/worlds-with-type-renamings/component.wit.print @@ -0,0 +1,7 @@ +package root:component + +world root { + import foo:foo/i + use foo:foo/i.{some-type as other-name} + export foo:foo/i +} diff --git a/crates/wit-component/tests/components/worlds-with-type-renamings/module.wat b/crates/wit-component/tests/components/worlds-with-type-renamings/module.wat index 217541288e..441a99dda6 100644 --- a/crates/wit-component/tests/components/worlds-with-type-renamings/module.wat +++ b/crates/wit-component/tests/components/worlds-with-type-renamings/module.wat @@ -1,8 +1,8 @@ (module (type (;0;) (func (param i32 i64 i32))) (type (;1;) (func (param i32 i32 i32 i32) (result i32))) - (import "i1" "the-func" (func (;0;))) - (func (export "i2#the-func") + (import "foo:foo/i" "the-func" (func (;0;))) + (func (export "foo:foo/i#the-func") unreachable ) (func (;2;) (export "cabi_realloc") (param i32 i32 i32 i32) (result i32) diff --git a/crates/wit-component/tests/components/worlds-with-type-renamings/module.wit b/crates/wit-component/tests/components/worlds-with-type-renamings/module.wit index cbc0633d79..5d8b65fbe1 100644 --- a/crates/wit-component/tests/components/worlds-with-type-renamings/module.wit +++ b/crates/wit-component/tests/components/worlds-with-type-renamings/module.wit @@ -1,3 +1,5 @@ +package foo:foo + interface i { record some-type { } @@ -6,9 +8,9 @@ interface i { } -default world the-world { - use self.i.{some-type as other-name} +world module { + use i.{some-type as other-name} - import i1: self.i - export i2: self.i + import i + export i } diff --git a/crates/wit-component/tests/components/worlds-with-types/component.wit b/crates/wit-component/tests/components/worlds-with-types/component.wit.print similarity index 66% rename from crates/wit-component/tests/components/worlds-with-types/component.wit rename to crates/wit-component/tests/components/worlds-with-types/component.wit.print index 27045d484e..e68a82150e 100644 --- a/crates/wit-component/tests/components/worlds-with-types/component.wit +++ b/crates/wit-component/tests/components/worlds-with-types/component.wit.print @@ -1,4 +1,6 @@ -default world component { +package root:component + +world root { type t = u32 record r { diff --git a/crates/wit-component/tests/components/worlds-with-types/module.wit b/crates/wit-component/tests/components/worlds-with-types/module.wit index 1b09b9e335..44177ec960 100644 --- a/crates/wit-component/tests/components/worlds-with-types/module.wit +++ b/crates/wit-component/tests/components/worlds-with-types/module.wit @@ -1,4 +1,6 @@ -default world foo { +package foo:foo + +world module { type t = u32 record r { x: t diff --git a/crates/wit-component/tests/interfaces.rs b/crates/wit-component/tests/interfaces.rs index 59d7c75f27..ae225d7171 100644 --- a/crates/wit-component/tests/interfaces.rs +++ b/crates/wit-component/tests/interfaces.rs @@ -2,8 +2,8 @@ use anyhow::{Context, Result}; use pretty_assertions::assert_eq; use std::fs; use std::path::Path; -use wit_component::DocumentPrinter; -use wit_parser::{Resolve, UnresolvedPackage}; +use wit_component::WitPrinter; +use wit_parser::{PackageId, Resolve, UnresolvedPackage}; /// Tests the encoding of a WIT package as a WebAssembly binary. /// @@ -18,6 +18,8 @@ use wit_parser::{Resolve, UnresolvedPackage}; /// the baseline files. #[test] fn interface_encoding() -> Result<()> { + drop(env_logger::init()); + for entry in fs::read_dir("tests/interfaces")? { let path = entry?.path(); let name = match path.file_name().and_then(|s| s.to_str()) { @@ -40,9 +42,11 @@ fn run_test(path: &Path, is_dir: bool) -> Result<()> { let package = if is_dir { resolve.push_dir(path)?.0 } else { - resolve.push(UnresolvedPackage::parse_file(path)?, &Default::default())? + resolve.push(UnresolvedPackage::parse_file(path)?)? }; + assert_print(&resolve, package, path, is_dir)?; + let features = wasmparser::WasmFeatures { component_model: true, ..Default::default() @@ -60,26 +64,10 @@ fn run_test(path: &Path, is_dir: bool) -> Result<()> { // Next decode a fresh WIT package from the WebAssembly generated. Print // this package's documents and assert they all match the expectations. - let name = &resolve.packages[package].name; - let decoded = wit_component::decode(name, &wasm)?; + let decoded = wit_component::decode(&wasm)?; let resolve = decoded.resolve(); - for (id, pkg) in resolve.packages.iter() { - for (name, doc) in pkg.documents.iter() { - let root = if id == decoded.package() { - path.to_path_buf() - } else { - path.join("deps").join(&pkg.name) - }; - let expected = if is_dir { - root.join(format!("{name}.wit.print")) - } else { - root.with_extension("wit.print") - }; - let output = DocumentPrinter::default().print(&resolve, *doc)?; - assert_output(&expected, &output)?; - } - } + assert_print(resolve, decoded.package(), path, is_dir)?; // Finally convert the decoded package to wasm again and make sure it // matches the prior wasm. @@ -92,6 +80,21 @@ fn run_test(path: &Path, is_dir: bool) -> Result<()> { Ok(()) } +fn assert_print(resolve: &Resolve, package: PackageId, path: &Path, is_dir: bool) -> Result<()> { + let pkg = &resolve.packages[package]; + let expected = if is_dir { + path.join(format!("{}.wit.print", &pkg.name.name)) + } else { + path.with_extension("wit.print") + }; + let output = WitPrinter::default().print(&resolve, package)?; + assert_output(&expected, &output)?; + + UnresolvedPackage::parse("foo.wit".as_ref(), &output) + .context("failed to parse printed output")?; + Ok(()) +} + fn assert_output(expected: &Path, actual: &str) -> Result<()> { let actual = actual.replace( concat!("\"", env!("CARGO_PKG_VERSION"), "\""), diff --git a/crates/wit-component/tests/interfaces/console.wat b/crates/wit-component/tests/interfaces/console.wat index ec818f95b6..088d0d694c 100644 --- a/crates/wit-component/tests/interfaces/console.wat +++ b/crates/wit-component/tests/interfaces/console.wat @@ -7,11 +7,11 @@ (export (;0;) "log" (func (type 0))) ) ) - (export (;0;) "console" "pkg:/console/console" (instance (type 0))) + (export (;0;) (interface "foo:console/console") (instance (type 0))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "console" "pkg:/console" (type 0)) + (export (;1;) (interface "foo:console/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/console.wit b/crates/wit-component/tests/interfaces/console.wit index f558b2b3ca..655e251798 100644 --- a/crates/wit-component/tests/interfaces/console.wit +++ b/crates/wit-component/tests/interfaces/console.wit @@ -1,3 +1,5 @@ +package foo:console + interface console { log: func(arg: string) } diff --git a/crates/wit-component/tests/interfaces/console.wit.print b/crates/wit-component/tests/interfaces/console.wit.print index 81a8066f62..73a5363d56 100644 --- a/crates/wit-component/tests/interfaces/console.wit.print +++ b/crates/wit-component/tests/interfaces/console.wit.print @@ -1,3 +1,5 @@ +package foo:console + interface console { log: func(arg: string) } diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate.wat b/crates/wit-component/tests/interfaces/diamond-disambiguate.wat index a4f74d8c81..2bc32e0f9f 100644 --- a/crates/wit-component/tests/interfaces/diamond-disambiguate.wat +++ b/crates/wit-component/tests/interfaces/diamond-disambiguate.wat @@ -7,25 +7,15 @@ (export (;1;) "t2" (type (eq 0))) ) ) - (export (;0;) "shared" "pkg:/shared2/shared" (instance (type 0))) - ) - ) - (export (;1;) "shared2" "pkg:/shared2" (type 0)) - (type (;2;) - (component - (type (;0;) + (export (;0;) (interface "foo:foo/shared2") (instance (type 0))) + (type (;1;) (instance (type (;0;) u8) (export (;1;) "t1" (type (eq 0))) ) ) - (export (;0;) "shared" "pkg:/shared1/shared" (instance (type 0))) - ) - ) - (export (;3;) "shared1" "pkg:/shared1" (type 2)) - (type (;4;) - (component - (type (;0;) + (export (;1;) (interface "foo:foo/shared1") (instance (type 1))) + (type (;2;) (component (type (;0;) (instance @@ -33,7 +23,7 @@ (export (;1;) "t1" (type (eq 0))) ) ) - (import "shared1" "pkg:/shared1/shared" (instance (;0;) (type 0))) + (import (interface "foo:foo/shared1") (instance (;0;) (type 0))) (alias export 0 "t1" (type (;1;))) (type (;2;) (instance @@ -48,7 +38,7 @@ (export (;1;) "t2" (type (eq 0))) ) ) - (import "shared" "pkg:/shared2/shared" (instance (;2;) (type 3))) + (import (interface "foo:foo/shared2") (instance (;2;) (type 3))) (alias export 2 "t2" (type (;4;))) (type (;5;) (instance @@ -59,11 +49,11 @@ (import "bar" (instance (;3;) (type 5))) ) ) - (export (;0;) "w1" "pkg:/join/w1" (component (type 0))) + (export (;0;) (interface "foo:foo/w1") (component (type 2))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;5;) "join" "pkg:/join" (type 4)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate/foo.wit.print b/crates/wit-component/tests/interfaces/diamond-disambiguate/foo.wit.print new file mode 100644 index 0000000000..4856804be2 --- /dev/null +++ b/crates/wit-component/tests/interfaces/diamond-disambiguate/foo.wit.print @@ -0,0 +1,22 @@ +package foo:foo + +interface shared2 { + type t2 = u8 + +} + +interface shared1 { + type t1 = u8 + +} + +world w1 { + import shared1 + import foo: interface { + use shared1.{t1} + } + import shared2 + import bar: interface { + use shared2.{t2} + } +} diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate/join.wit b/crates/wit-component/tests/interfaces/diamond-disambiguate/join.wit index f8bc80c84c..3fe026c27f 100644 --- a/crates/wit-component/tests/interfaces/diamond-disambiguate/join.wit +++ b/crates/wit-component/tests/interfaces/diamond-disambiguate/join.wit @@ -1,10 +1,10 @@ -world w1 { - import shared1: pkg.shared1 +package foo:foo +world w1 { import foo: interface { - use pkg.shared1.{t1} + use shared1.{t1} } import bar: interface { - use pkg.shared2.{t2} + use shared2.{t2} } } diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate/join.wit.print b/crates/wit-component/tests/interfaces/diamond-disambiguate/join.wit.print deleted file mode 100644 index 3c17d5670f..0000000000 --- a/crates/wit-component/tests/interfaces/diamond-disambiguate/join.wit.print +++ /dev/null @@ -1,10 +0,0 @@ -world w1 { - import shared1: pkg.shared1.shared - import foo: interface { - use pkg.shared1.shared.{t1} - } - import shared: pkg.shared2.shared - import bar: interface { - use pkg.shared2.shared.{t2} - } -} diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate/shared1.wit b/crates/wit-component/tests/interfaces/diamond-disambiguate/shared1.wit index 962bb48cf8..e376a9a642 100644 --- a/crates/wit-component/tests/interfaces/diamond-disambiguate/shared1.wit +++ b/crates/wit-component/tests/interfaces/diamond-disambiguate/shared1.wit @@ -1,3 +1,3 @@ -default interface shared { +interface shared1 { type t1 = u8 } diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate/shared1.wit.print b/crates/wit-component/tests/interfaces/diamond-disambiguate/shared1.wit.print deleted file mode 100644 index 5ad822561b..0000000000 --- a/crates/wit-component/tests/interfaces/diamond-disambiguate/shared1.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface shared { - type t1 = u8 - -} - diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate/shared2.wit b/crates/wit-component/tests/interfaces/diamond-disambiguate/shared2.wit index e12498eaeb..0b6e9c84f6 100644 --- a/crates/wit-component/tests/interfaces/diamond-disambiguate/shared2.wit +++ b/crates/wit-component/tests/interfaces/diamond-disambiguate/shared2.wit @@ -1,3 +1,3 @@ -default interface shared { +interface shared2 { type t2 = u8 } diff --git a/crates/wit-component/tests/interfaces/diamond-disambiguate/shared2.wit.print b/crates/wit-component/tests/interfaces/diamond-disambiguate/shared2.wit.print deleted file mode 100644 index 032fea72d2..0000000000 --- a/crates/wit-component/tests/interfaces/diamond-disambiguate/shared2.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface shared { - type t2 = u8 - -} - diff --git a/crates/wit-component/tests/interfaces/diamond.wat b/crates/wit-component/tests/interfaces/diamond.wat index 59c597877a..38b3dba0cb 100644 --- a/crates/wit-component/tests/interfaces/diamond.wat +++ b/crates/wit-component/tests/interfaces/diamond.wat @@ -7,7 +7,7 @@ (export (;1;) "the-enum" (type (eq 0))) ) ) - (export (;0;) "shared" "pkg:/diamond/shared" (instance (type 0))) + (export (;0;) (interface "foo:foo/shared") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -16,7 +16,7 @@ (export (;1;) "the-enum" (type (eq 0))) ) ) - (import "shared" "pkg:/diamond/shared" (instance (;0;) (type 0))) + (import (interface "foo:foo/shared") (instance (;0;) (type 0))) (alias export 0 "the-enum" (type (;1;))) (type (;2;) (instance @@ -24,10 +24,17 @@ (export (;1;) "the-enum" (type (eq 0))) ) ) - (export (;1;) "bar" (instance (type 2))) + (import "foo" (instance (;1;) (type 2))) + (type (;3;) + (instance + (alias outer 1 1 (type (;0;))) + (export (;1;) "the-enum" (type (eq 0))) + ) + ) + (import "bar" (instance (;2;) (type 3))) ) ) - (export (;0;) "w3" "pkg:/diamond/w3" (component (type 1))) + (export (;0;) (interface "foo:foo/w1") (component (type 1))) (type (;2;) (component (type (;0;) @@ -36,7 +43,7 @@ (export (;1;) "the-enum" (type (eq 0))) ) ) - (import "shared" "pkg:/diamond/shared" (instance (;0;) (type 0))) + (import (interface "foo:foo/shared") (instance (;0;) (type 0))) (alias export 0 "the-enum" (type (;1;))) (type (;2;) (instance @@ -54,7 +61,7 @@ (export (;2;) "bar" (instance (type 3))) ) ) - (export (;1;) "w2" "pkg:/diamond/w2" (component (type 2))) + (export (;1;) (interface "foo:foo/w2") (component (type 2))) (type (;3;) (component (type (;0;) @@ -63,7 +70,7 @@ (export (;1;) "the-enum" (type (eq 0))) ) ) - (import "shared" "pkg:/diamond/shared" (instance (;0;) (type 0))) + (import (interface "foo:foo/shared") (instance (;0;) (type 0))) (alias export 0 "the-enum" (type (;1;))) (type (;2;) (instance @@ -71,21 +78,14 @@ (export (;1;) "the-enum" (type (eq 0))) ) ) - (import "foo" (instance (;1;) (type 2))) - (type (;3;) - (instance - (alias outer 1 1 (type (;0;))) - (export (;1;) "the-enum" (type (eq 0))) - ) - ) - (import "bar" (instance (;2;) (type 3))) + (export (;1;) "bar" (instance (type 2))) ) ) - (export (;2;) "w1" "pkg:/diamond/w1" (component (type 3))) + (export (;2;) (interface "foo:foo/w3") (component (type 3))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "diamond" "pkg:/diamond" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/diamond.wit b/crates/wit-component/tests/interfaces/diamond.wit index b5d718b3ae..0625a58e87 100644 --- a/crates/wit-component/tests/interfaces/diamond.wit +++ b/crates/wit-component/tests/interfaces/diamond.wit @@ -1,3 +1,5 @@ +package foo:foo + interface shared { enum the-enum { a @@ -6,24 +8,24 @@ interface shared { world w1 { import foo: interface { - use self.shared.{the-enum} + use shared.{the-enum} } import bar: interface { - use self.shared.{the-enum} + use shared.{the-enum} } } world w2 { import foo: interface { - use self.shared.{the-enum} + use shared.{the-enum} } export bar: interface { - use self.shared.{the-enum} + use shared.{the-enum} } } world w3 { export bar: interface { - use self.shared.{the-enum} + use shared.{the-enum} } } diff --git a/crates/wit-component/tests/interfaces/diamond.wit.print b/crates/wit-component/tests/interfaces/diamond.wit.print index d9801391bf..2b686a10e1 100644 --- a/crates/wit-component/tests/interfaces/diamond.wit.print +++ b/crates/wit-component/tests/interfaces/diamond.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface shared { enum the-enum { a, @@ -5,27 +7,27 @@ interface shared { } -world w3 { - import shared: self.shared - export bar: interface { - use self.shared.{the-enum} +world w1 { + import shared + import foo: interface { + use shared.{the-enum} + } + import bar: interface { + use shared.{the-enum} } } world w2 { - import shared: self.shared + import shared import foo: interface { - use self.shared.{the-enum} + use shared.{the-enum} } export bar: interface { - use self.shared.{the-enum} + use shared.{the-enum} } } -world w1 { - import shared: self.shared - import foo: interface { - use self.shared.{the-enum} - } - import bar: interface { - use self.shared.{the-enum} +world w3 { + import shared + export bar: interface { + use shared.{the-enum} } } diff --git a/crates/wit-component/tests/interfaces/empty.wat b/crates/wit-component/tests/interfaces/empty.wat index a105ccef23..b85aef39fe 100644 --- a/crates/wit-component/tests/interfaces/empty.wat +++ b/crates/wit-component/tests/interfaces/empty.wat @@ -4,28 +4,36 @@ (type (;0;) (instance) ) - (export (;0;) "empty" "pkg:/empty/empty" (instance (type 0))) + (export (;0;) (interface "foo:empty/empty") (instance (type 0))) (type (;1;) (component (type (;0;) (instance) ) - (import "empty" "pkg:/empty/empty" (instance (;0;) (type 0))) + (import (interface "foo:empty/empty") (instance (;0;) (type 0))) (type (;1;) (instance) ) - (export (;1;) "empty2" "pkg:/empty/empty" (instance (type 1))) + (import "empty" (instance (;1;) (type 1))) + (type (;2;) + (instance) + ) + (export (;2;) (interface "foo:empty/empty") (instance (type 2))) + (type (;3;) + (instance) + ) + (export (;3;) "empty2" (instance (type 3))) ) ) - (export (;0;) "empty-world" "pkg:/empty/empty-world" (component (type 1))) + (export (;0;) (interface "foo:empty/empty-world") (component (type 1))) (type (;2;) (component) ) - (export (;1;) "actually-empty-world" "pkg:/empty/actually-empty-world" (component (type 2))) + (export (;1;) (interface "foo:empty/actually-empty-world") (component (type 2))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "empty" "pkg:/empty" (type 0)) + (export (;1;) (interface "foo:empty/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/empty.wit b/crates/wit-component/tests/interfaces/empty.wit index db74436fa7..fce4c42d06 100644 --- a/crates/wit-component/tests/interfaces/empty.wit +++ b/crates/wit-component/tests/interfaces/empty.wit @@ -1,8 +1,12 @@ +package foo:empty + interface empty {} world empty-world { - import empty: self.empty - export empty2: self.empty + import empty + import empty: interface {} + export empty + export empty2: interface {} } world actually-empty-world {} diff --git a/crates/wit-component/tests/interfaces/empty.wit.print b/crates/wit-component/tests/interfaces/empty.wit.print index 31b7961cbc..44b9e27e6b 100644 --- a/crates/wit-component/tests/interfaces/empty.wit.print +++ b/crates/wit-component/tests/interfaces/empty.wit.print @@ -1,9 +1,15 @@ +package foo:empty + interface empty { } world empty-world { - import empty: self.empty - export empty2: self.empty + import empty + import empty: interface { + } + export empty + export empty2: interface { + } } world actually-empty-world { } diff --git a/crates/wit-component/tests/interfaces/export-other-packages-interface.wat b/crates/wit-component/tests/interfaces/export-other-packages-interface.wat index 7112aa82b9..ca7aa80842 100644 --- a/crates/wit-component/tests/interfaces/export-other-packages-interface.wat +++ b/crates/wit-component/tests/interfaces/export-other-packages-interface.wat @@ -9,14 +9,14 @@ (export (;1;) "t" (type (eq 0))) ) ) - (export (;0;) "foo" "path:/the-dep/the-doc/the-interface" (instance (type 0))) + (export (;0;) (interface "foo:the-dep/the-interface") (instance (type 0))) ) ) - (export (;0;) "foo" "pkg:/foo/foo" (component (type 0))) + (export (;0;) (interface "foo:foo/foo") (component (type 0))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "foo" "pkg:/foo" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/export-other-packages-interface/deps/the-dep/the-doc.wit b/crates/wit-component/tests/interfaces/export-other-packages-interface/deps/the-dep/the-doc.wit index c26eb475e7..a95f6a3775 100644 --- a/crates/wit-component/tests/interfaces/export-other-packages-interface/deps/the-dep/the-doc.wit +++ b/crates/wit-component/tests/interfaces/export-other-packages-interface/deps/the-dep/the-doc.wit @@ -1,4 +1,6 @@ -default interface the-interface { +package foo:the-dep + +interface the-interface { type t = u8 } diff --git a/crates/wit-component/tests/interfaces/export-other-packages-interface/deps/the-dep/the-doc.wit.print b/crates/wit-component/tests/interfaces/export-other-packages-interface/deps/the-dep/the-doc.wit.print deleted file mode 100644 index 19e977561b..0000000000 --- a/crates/wit-component/tests/interfaces/export-other-packages-interface/deps/the-dep/the-doc.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface the-interface { - type t = u8 - -} - diff --git a/crates/wit-component/tests/interfaces/export-other-packages-interface/foo.wit b/crates/wit-component/tests/interfaces/export-other-packages-interface/foo.wit index e4ea8aadb2..63721d405b 100644 --- a/crates/wit-component/tests/interfaces/export-other-packages-interface/foo.wit +++ b/crates/wit-component/tests/interfaces/export-other-packages-interface/foo.wit @@ -1,3 +1,5 @@ +package foo:foo + world foo { - export foo: the-dep.the-doc + export foo:the-dep/the-interface } diff --git a/crates/wit-component/tests/interfaces/export-other-packages-interface/foo.wit.print b/crates/wit-component/tests/interfaces/export-other-packages-interface/foo.wit.print index 46cee8925d..63721d405b 100644 --- a/crates/wit-component/tests/interfaces/export-other-packages-interface/foo.wit.print +++ b/crates/wit-component/tests/interfaces/export-other-packages-interface/foo.wit.print @@ -1,3 +1,5 @@ +package foo:foo + world foo { - export foo: the-dep.the-doc.the-interface + export foo:the-dep/the-interface } diff --git a/crates/wit-component/tests/interfaces/exports.wat b/crates/wit-component/tests/interfaces/exports.wat index add12d9df0..f7a4edfdd1 100644 --- a/crates/wit-component/tests/interfaces/exports.wat +++ b/crates/wit-component/tests/interfaces/exports.wat @@ -9,7 +9,7 @@ (export (;0;) "my-function" (func (type 2))) ) ) - (export (;0;) "foo" "pkg:/exports/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -20,14 +20,14 @@ (export (;0;) "my-function" (func (type 2))) ) ) - (export (;0;) "foo" "pkg:/exports/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) ) ) - (export (;0;) "export-foo" "pkg:/exports/export-foo" (component (type 1))) + (export (;0;) (interface "foo:foo/export-foo") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "exports" "pkg:/exports" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/exports.wit b/crates/wit-component/tests/interfaces/exports.wit index c29cb7bdba..542abad8a9 100644 --- a/crates/wit-component/tests/interfaces/exports.wit +++ b/crates/wit-component/tests/interfaces/exports.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { record my-struct { a: u32, @@ -7,5 +9,5 @@ interface foo { } world export-foo { - export foo: self.foo + export foo } diff --git a/crates/wit-component/tests/interfaces/exports.wit.print b/crates/wit-component/tests/interfaces/exports.wit.print index c29cb7bdba..542abad8a9 100644 --- a/crates/wit-component/tests/interfaces/exports.wit.print +++ b/crates/wit-component/tests/interfaces/exports.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface foo { record my-struct { a: u32, @@ -7,5 +9,5 @@ interface foo { } world export-foo { - export foo: self.foo + export foo } diff --git a/crates/wit-component/tests/interfaces/flags.wat b/crates/wit-component/tests/interfaces/flags.wat index 00c06614dd..0bef371737 100644 --- a/crates/wit-component/tests/interfaces/flags.wat +++ b/crates/wit-component/tests/interfaces/flags.wat @@ -33,7 +33,7 @@ (export (;6;) "roundtrip-flag64" (func (type 20))) ) ) - (export (;0;) "imports" "pkg:/flags/imports" (instance (type 0))) + (export (;0;) (interface "foo:flags/imports") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -68,14 +68,14 @@ (export (;6;) "roundtrip-flag64" (func (type 20))) ) ) - (import "imports" "pkg:/flags/imports" (instance (;0;) (type 0))) + (import (interface "foo:flags/imports") (instance (;0;) (type 0))) ) ) - (export (;0;) "flags-world" "pkg:/flags/flags-world" (component (type 1))) + (export (;0;) (interface "foo:flags/flags-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "flags" "pkg:/flags" (type 0)) + (export (;1;) (interface "foo:flags/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/flags.wit b/crates/wit-component/tests/interfaces/flags.wit index 634968911d..6f23fdd3dc 100644 --- a/crates/wit-component/tests/interfaces/flags.wit +++ b/crates/wit-component/tests/interfaces/flags.wit @@ -1,3 +1,5 @@ +package foo:%flags + interface imports { flags flag1 { b0, @@ -163,5 +165,5 @@ interface imports { } world flags-world { - import imports: self.imports + import imports } diff --git a/crates/wit-component/tests/interfaces/flags.wit.print b/crates/wit-component/tests/interfaces/flags.wit.print index 4a2715fab3..644c6d8cb1 100644 --- a/crates/wit-component/tests/interfaces/flags.wit.print +++ b/crates/wit-component/tests/interfaces/flags.wit.print @@ -1,3 +1,5 @@ +package foo:%flags + interface imports { flags flag8 { b0, @@ -163,5 +165,5 @@ interface imports { } world flags-world { - import imports: self.imports + import imports } diff --git a/crates/wit-component/tests/interfaces/floats.wat b/crates/wit-component/tests/interfaces/floats.wat index 0c561cd160..0b3457e418 100644 --- a/crates/wit-component/tests/interfaces/floats.wat +++ b/crates/wit-component/tests/interfaces/floats.wat @@ -13,7 +13,7 @@ (export (;3;) "float64-result" (func (type 3))) ) ) - (export (;0;) "floats" "pkg:/floats/floats" (instance (type 0))) + (export (;0;) (interface "foo:floats/floats") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -28,14 +28,14 @@ (export (;3;) "float64-result" (func (type 3))) ) ) - (import "floats" "pkg:/floats/floats" (instance (;0;) (type 0))) + (import (interface "foo:floats/floats") (instance (;0;) (type 0))) ) ) - (export (;0;) "floats-world" "pkg:/floats/floats-world" (component (type 1))) + (export (;0;) (interface "foo:floats/floats-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "floats" "pkg:/floats" (type 0)) + (export (;1;) (interface "foo:floats/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/floats.wit b/crates/wit-component/tests/interfaces/floats.wit index 8235b096ed..53618a77f0 100644 --- a/crates/wit-component/tests/interfaces/floats.wit +++ b/crates/wit-component/tests/interfaces/floats.wit @@ -1,3 +1,5 @@ +package foo:floats + interface floats { float32-param: func(x: float32) float64-param: func(x: float64) @@ -6,5 +8,5 @@ interface floats { } world floats-world { - import floats: self.floats + import floats } diff --git a/crates/wit-component/tests/interfaces/floats.wit.print b/crates/wit-component/tests/interfaces/floats.wit.print index c3a6f3384a..b770c37e5e 100644 --- a/crates/wit-component/tests/interfaces/floats.wit.print +++ b/crates/wit-component/tests/interfaces/floats.wit.print @@ -1,3 +1,5 @@ +package foo:floats + interface floats { float32-param: func(x: float32) @@ -9,5 +11,5 @@ interface floats { } world floats-world { - import floats: self.floats + import floats } diff --git a/crates/wit-component/tests/interfaces/foreign-use-chain.wat b/crates/wit-component/tests/interfaces/foreign-use-chain.wat index 89f7413c6c..f7827c01c5 100644 --- a/crates/wit-component/tests/interfaces/foreign-use-chain.wat +++ b/crates/wit-component/tests/interfaces/foreign-use-chain.wat @@ -9,7 +9,7 @@ (export (;1;) "the-type" (type (eq 0))) ) ) - (import "the-interface" "path:/bar/bar/the-interface" (instance (;0;) (type 0))) + (import (interface "foo:bar/the-interface") (instance (;0;) (type 0))) (alias export 0 "the-type" (type (;1;))) (type (;2;) (instance @@ -17,14 +17,14 @@ (export (;1;) "bar" (type (eq 0))) ) ) - (import "bar" "path:/bar/bar/the-name" (instance (;1;) (type 2))) + (import (interface "foo:bar/bar") (instance (;1;) (type 2))) ) ) - (export (;0;) "foo" "pkg:/foo/foo" (component (type 0))) + (export (;0;) (interface "foo:foo/foo") (component (type 0))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "foo" "pkg:/foo" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/foreign-use-chain/deps/bar/bar.wit b/crates/wit-component/tests/interfaces/foreign-use-chain/deps/bar/bar.wit index bb925cfe2f..896c8d9d8a 100644 --- a/crates/wit-component/tests/interfaces/foreign-use-chain/deps/bar/bar.wit +++ b/crates/wit-component/tests/interfaces/foreign-use-chain/deps/bar/bar.wit @@ -1,5 +1,7 @@ -default interface the-name { - use self.the-interface.{the-type as bar} +package foo:bar + +interface bar { + use the-interface.{the-type as bar} } interface the-interface { diff --git a/crates/wit-component/tests/interfaces/foreign-use-chain/deps/bar/bar.wit.print b/crates/wit-component/tests/interfaces/foreign-use-chain/deps/bar/bar.wit.print deleted file mode 100644 index b6955182a9..0000000000 --- a/crates/wit-component/tests/interfaces/foreign-use-chain/deps/bar/bar.wit.print +++ /dev/null @@ -1,9 +0,0 @@ -interface the-interface { - type the-type = u8 - -} - -interface the-name { - use self.the-interface.{the-type as bar} -} - diff --git a/crates/wit-component/tests/interfaces/foreign-use-chain/foo.wit b/crates/wit-component/tests/interfaces/foreign-use-chain/foo.wit index 439da06458..74225fc2cd 100644 --- a/crates/wit-component/tests/interfaces/foreign-use-chain/foo.wit +++ b/crates/wit-component/tests/interfaces/foreign-use-chain/foo.wit @@ -1,3 +1,5 @@ -default world foo { - import bar: bar.bar +package foo:foo + +world foo { + import foo:bar/bar } diff --git a/crates/wit-component/tests/interfaces/foreign-use-chain/foo.wit.print b/crates/wit-component/tests/interfaces/foreign-use-chain/foo.wit.print index f4eb14db51..c05357cdf3 100644 --- a/crates/wit-component/tests/interfaces/foreign-use-chain/foo.wit.print +++ b/crates/wit-component/tests/interfaces/foreign-use-chain/foo.wit.print @@ -1,4 +1,6 @@ +package foo:foo + world foo { - import the-interface: bar.bar.the-interface - import bar: bar.bar.the-name + import foo:bar/the-interface + import foo:bar/bar } diff --git a/crates/wit-component/tests/interfaces/import-and-export.wat b/crates/wit-component/tests/interfaces/import-and-export.wat index d382aef5fb..3396721a3e 100644 --- a/crates/wit-component/tests/interfaces/import-and-export.wat +++ b/crates/wit-component/tests/interfaces/import-and-export.wat @@ -7,14 +7,14 @@ (export (;0;) "foo" (func (type 0))) ) ) - (export (;0;) "foo" "pkg:/import-and-export/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) (type (;1;) (instance (type (;0;) (func)) (export (;0;) "bar" (func (type 0))) ) ) - (export (;1;) "bar" "pkg:/import-and-export/bar" (instance (type 1))) + (export (;1;) (interface "foo:foo/bar") (instance (type 1))) (type (;2;) (component (type (;0;) @@ -23,21 +23,21 @@ (export (;0;) "foo" (func (type 0))) ) ) - (import "foo" "pkg:/import-and-export/foo" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (type (;1;) (instance (type (;0;) (func)) (export (;0;) "bar" (func (type 0))) ) ) - (export (;1;) "bar" "pkg:/import-and-export/bar" (instance (type 1))) + (export (;1;) (interface "foo:foo/bar") (instance (type 1))) ) ) - (export (;0;) "import-and-export" "pkg:/import-and-export/import-and-export" (component (type 2))) + (export (;0;) (interface "foo:foo/import-and-export") (component (type 2))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "import-and-export" "pkg:/import-and-export" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/import-and-export.wit b/crates/wit-component/tests/interfaces/import-and-export.wit index a6f028317c..3aabe67040 100644 --- a/crates/wit-component/tests/interfaces/import-and-export.wit +++ b/crates/wit-component/tests/interfaces/import-and-export.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { foo: func() } @@ -7,6 +9,6 @@ interface bar { } world import-and-export { - import foo: self.foo - export bar: self.bar + import foo + export bar } diff --git a/crates/wit-component/tests/interfaces/import-and-export.wit.print b/crates/wit-component/tests/interfaces/import-and-export.wit.print index a6f028317c..3aabe67040 100644 --- a/crates/wit-component/tests/interfaces/import-and-export.wit.print +++ b/crates/wit-component/tests/interfaces/import-and-export.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface foo { foo: func() } @@ -7,6 +9,6 @@ interface bar { } world import-and-export { - import foo: self.foo - export bar: self.bar + import foo + export bar } diff --git a/crates/wit-component/tests/interfaces/integers.wat b/crates/wit-component/tests/interfaces/integers.wat index 7dd4504072..51d4a91bab 100644 --- a/crates/wit-component/tests/interfaces/integers.wat +++ b/crates/wit-component/tests/interfaces/integers.wat @@ -44,7 +44,7 @@ (export (;18;) "multi-ret" (func (type 19))) ) ) - (export (;0;) "integers" "pkg:/integers/integers" (instance (type 0))) + (export (;0;) (interface "foo:foo/integers") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -90,14 +90,14 @@ (export (;18;) "multi-ret" (func (type 19))) ) ) - (import "integers" "pkg:/integers/integers" (instance (;0;) (type 0))) + (import (interface "foo:foo/integers") (instance (;0;) (type 0))) ) ) - (export (;0;) "integers-world" "pkg:/integers/integers-world" (component (type 1))) + (export (;0;) (interface "foo:foo/integers-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "integers" "pkg:/integers" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/integers.wit b/crates/wit-component/tests/interfaces/integers.wit index ef67ac4a94..47b04b7da0 100644 --- a/crates/wit-component/tests/interfaces/integers.wit +++ b/crates/wit-component/tests/interfaces/integers.wit @@ -1,3 +1,5 @@ +package foo:foo + interface integers { a1: func(x: u8) a2: func(x: s8) @@ -21,5 +23,5 @@ interface integers { } world integers-world { - import integers: self.integers + import integers } diff --git a/crates/wit-component/tests/interfaces/integers.wit.print b/crates/wit-component/tests/interfaces/integers.wit.print index d8d88ea2c6..d529056c3c 100644 --- a/crates/wit-component/tests/interfaces/integers.wit.print +++ b/crates/wit-component/tests/interfaces/integers.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface integers { a1: func(x: u8) @@ -39,5 +41,5 @@ interface integers { } world integers-world { - import integers: self.integers + import integers } diff --git a/crates/wit-component/tests/interfaces/lists.wat b/crates/wit-component/tests/interfaces/lists.wat index 0050fad304..e2a3a1f10e 100644 --- a/crates/wit-component/tests/interfaces/lists.wat +++ b/crates/wit-component/tests/interfaces/lists.wat @@ -95,7 +95,7 @@ (export (;27;) "load-store-everything" (func (type 61))) ) ) - (export (;0;) "lists" "pkg:/lists/lists" (instance (type 0))) + (export (;0;) (interface "foo:foo/lists") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -192,14 +192,14 @@ (export (;27;) "load-store-everything" (func (type 61))) ) ) - (import "lists" "pkg:/lists/lists" (instance (;0;) (type 0))) + (import (interface "foo:foo/lists") (instance (;0;) (type 0))) ) ) - (export (;0;) "lists-world" "pkg:/lists/lists-world" (component (type 1))) + (export (;0;) (interface "foo:foo/lists-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "lists" "pkg:/lists" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/lists.wit b/crates/wit-component/tests/interfaces/lists.wit index 38a84ecab8..c6dfa14625 100644 --- a/crates/wit-component/tests/interfaces/lists.wit +++ b/crates/wit-component/tests/interfaces/lists.wit @@ -1,3 +1,5 @@ +package foo:foo + interface lists { record other-record { a1: u32, @@ -90,5 +92,5 @@ interface lists { } world lists-world { - import lists: self.lists + import lists } diff --git a/crates/wit-component/tests/interfaces/lists.wit.print b/crates/wit-component/tests/interfaces/lists.wit.print index f4f3dafe8d..16ac02b413 100644 --- a/crates/wit-component/tests/interfaces/lists.wit.print +++ b/crates/wit-component/tests/interfaces/lists.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface lists { variant other-variant { a, @@ -90,5 +92,5 @@ interface lists { } world lists-world { - import lists: self.lists + import lists } diff --git a/crates/wit-component/tests/interfaces/multi-doc.wat b/crates/wit-component/tests/interfaces/multi-doc.wat index f5963a7a07..15f16eacea 100644 --- a/crates/wit-component/tests/interfaces/multi-doc.wat +++ b/crates/wit-component/tests/interfaces/multi-doc.wat @@ -7,7 +7,7 @@ (export (;1;) "the-type" (type (eq 0))) ) ) - (export (;0;) "b" "pkg:/b/b" (instance (type 0))) + (export (;0;) (interface "foo:foo/b") (instance (type 0))) (alias export 0 "the-type" (type (;1;))) (type (;2;) (instance @@ -15,47 +15,25 @@ (export (;1;) "the-type" (type (eq 0))) ) ) - (export (;1;) "a" "pkg:/b/a" (instance (type 2))) - ) - ) - (export (;1;) "b" "pkg:/b" (type 0)) - (type (;2;) - (component - (type (;0;) - (instance - (type (;0;) (record)) - (export (;1;) "the-type" (type (eq 0))) - ) - ) - (import "b2" "pkg:/b/b" (instance (;0;) (type 0))) - (alias export 0 "the-type" (type (;1;))) - (type (;2;) + (export (;1;) (interface "foo:foo/b2") (instance (type 2))) + (type (;3;) (instance (alias outer 1 1 (type (;0;))) (export (;1;) "the-type" (type (eq 0))) ) ) - (import "a2" "pkg:/b/a" (instance (;1;) (type 2))) - (alias export 1 "the-type" (type (;3;))) + (export (;2;) (interface "foo:foo/a2") (instance (type 3))) (type (;4;) (instance - (alias outer 1 3 (type (;0;))) - (export (;1;) "the-type" (type (eq 0))) - ) - ) - (export (;2;) "b" "pkg:/a/b" (instance (type 4))) - (alias export 2 "the-type" (type (;5;))) - (type (;6;) - (instance - (alias outer 1 5 (type (;0;))) + (alias outer 1 1 (type (;0;))) (export (;1;) "the-type" (type (eq 0))) ) ) - (export (;3;) "a" "pkg:/a/a" (instance (type 6))) + (export (;3;) (interface "foo:foo/a") (instance (type 4))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;3;) "a" "pkg:/a" (type 2)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/multi-doc/a.wit b/crates/wit-component/tests/interfaces/multi-doc/a.wit index 71fb0ce245..c0f959e30b 100644 --- a/crates/wit-component/tests/interfaces/multi-doc/a.wit +++ b/crates/wit-component/tests/interfaces/multi-doc/a.wit @@ -1,7 +1,9 @@ -default interface a { - use self.b.{the-type} +package foo:foo + +interface a { + use b.{the-type} } -interface b { - use pkg.b.{the-type} +interface b2 { + use b.{the-type} } diff --git a/crates/wit-component/tests/interfaces/multi-doc/a.wit.print b/crates/wit-component/tests/interfaces/multi-doc/a.wit.print deleted file mode 100644 index c14ae39d44..0000000000 --- a/crates/wit-component/tests/interfaces/multi-doc/a.wit.print +++ /dev/null @@ -1,8 +0,0 @@ -interface b { - use pkg.b.a.{the-type} -} - -interface a { - use self.b.{the-type} -} - diff --git a/crates/wit-component/tests/interfaces/multi-doc/b.wit b/crates/wit-component/tests/interfaces/multi-doc/b.wit index da21c2e976..94b7a5ff7e 100644 --- a/crates/wit-component/tests/interfaces/multi-doc/b.wit +++ b/crates/wit-component/tests/interfaces/multi-doc/b.wit @@ -1,5 +1,5 @@ -default interface a { - use self.b.{the-type} +interface a2 { + use b.{the-type} } interface b { diff --git a/crates/wit-component/tests/interfaces/multi-doc/b.wit.print b/crates/wit-component/tests/interfaces/multi-doc/b.wit.print deleted file mode 100644 index 4fa21babb6..0000000000 --- a/crates/wit-component/tests/interfaces/multi-doc/b.wit.print +++ /dev/null @@ -1,10 +0,0 @@ -interface b { - record the-type { - } - -} - -interface a { - use self.b.{the-type} -} - diff --git a/crates/wit-component/tests/interfaces/multi-doc/foo.wit.print b/crates/wit-component/tests/interfaces/multi-doc/foo.wit.print new file mode 100644 index 0000000000..ef482f6205 --- /dev/null +++ b/crates/wit-component/tests/interfaces/multi-doc/foo.wit.print @@ -0,0 +1,20 @@ +package foo:foo + +interface b { + record the-type { + } + +} + +interface b2 { + use b.{the-type} +} + +interface a2 { + use b.{the-type} +} + +interface a { + use b.{the-type} +} + diff --git a/crates/wit-component/tests/interfaces/multiple-use.wat b/crates/wit-component/tests/interfaces/multiple-use.wat index 1b665b7bc7..159e54e950 100644 --- a/crates/wit-component/tests/interfaces/multiple-use.wat +++ b/crates/wit-component/tests/interfaces/multiple-use.wat @@ -9,14 +9,14 @@ (export (;3;) "t1" (type (eq 2))) ) ) - (export (;0;) "foo" "pkg:/multiple-use/foo" (instance (type 0))) + (export (;0;) (interface "foo:multiuse/foo") (instance (type 0))) (type (;1;) (instance (type (;0;) u8) (export (;1;) "u" (type (eq 0))) ) ) - (export (;1;) "bar" "pkg:/multiple-use/bar" (instance (type 1))) + (export (;1;) (interface "foo:multiuse/bar") (instance (type 1))) (alias export 0 "t1" (type (;2;))) (alias export 1 "u" (type (;3;))) (alias export 0 "t2" (type (;4;))) @@ -30,11 +30,11 @@ (export (;5;) "t2" (type (eq 4))) ) ) - (export (;2;) "baz" "pkg:/multiple-use/baz" (instance (type 5))) + (export (;2;) (interface "foo:multiuse/baz") (instance (type 5))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "multiple-use" "pkg:/multiple-use" (type 0)) + (export (;1;) (interface "foo:multiuse/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/multiple-use.wit b/crates/wit-component/tests/interfaces/multiple-use.wit index 89e78be94e..33635dc5cd 100644 --- a/crates/wit-component/tests/interfaces/multiple-use.wit +++ b/crates/wit-component/tests/interfaces/multiple-use.wit @@ -1,3 +1,5 @@ +package foo:multiuse + interface foo { type t1 = u8 type t2 = u8 @@ -8,7 +10,7 @@ interface bar { } interface baz { - use self.foo.{t1} - use self.bar.{u} - use self.foo.{t2} + use foo.{t1} + use bar.{u} + use foo.{t2} } diff --git a/crates/wit-component/tests/interfaces/multiple-use.wit.print b/crates/wit-component/tests/interfaces/multiple-use.wit.print index 4aa8d4b04a..3284d8d950 100644 --- a/crates/wit-component/tests/interfaces/multiple-use.wit.print +++ b/crates/wit-component/tests/interfaces/multiple-use.wit.print @@ -1,3 +1,5 @@ +package foo:multiuse + interface foo { type t2 = u8 @@ -11,8 +13,8 @@ interface bar { } interface baz { - use self.foo.{t1} - use self.bar.{u} - use self.foo.{t2} + use foo.{t1} + use bar.{u} + use foo.{t2} } diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain.wat b/crates/wit-component/tests/interfaces/pkg-use-chain.wat index 3934f14d0f..85bf6032a8 100644 --- a/crates/wit-component/tests/interfaces/pkg-use-chain.wat +++ b/crates/wit-component/tests/interfaces/pkg-use-chain.wat @@ -7,7 +7,7 @@ (export (;1;) "a" (type (eq 0))) ) ) - (export (;0;) "a" "pkg:/def/a" (instance (type 0))) + (export (;0;) (interface "foo:chain/a") (instance (type 0))) (alias export 0 "a" (type (;1;))) (type (;2;) (instance @@ -17,29 +17,7 @@ (export (;3;) "name" (type (eq 2))) ) ) - (export (;1;) "name" "pkg:/def/name" (instance (type 2))) - ) - ) - (export (;1;) "def" "pkg:/def" (type 0)) - (type (;2;) - (component - (type (;0;) - (instance - (type (;0;) u8) - (export (;1;) "a" (type (eq 0))) - ) - ) - (import "a" "pkg:/def/a" (instance (;0;) (type 0))) - (alias export 0 "a" (type (;1;))) - (type (;2;) - (instance - (alias outer 1 1 (type (;0;))) - (export (;1;) "a" (type (eq 0))) - (type (;2;) (enum "other")) - (export (;3;) "name" (type (eq 2))) - ) - ) - (import "name" "pkg:/def/name" (instance (;1;) (type 2))) + (export (;1;) (interface "foo:chain/def") (instance (type 2))) (alias export 1 "name" (type (;3;))) (type (;4;) (instance @@ -47,11 +25,11 @@ (export (;1;) "name" (type (eq 0))) ) ) - (export (;2;) "foo" "pkg:/the-use/foo" (instance (type 4))) + (export (;2;) (interface "foo:chain/foo") (instance (type 4))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;3;) "the-use" "pkg:/the-use" (type 2)) + (export (;1;) (interface "foo:chain/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain/chain.wit.print b/crates/wit-component/tests/interfaces/pkg-use-chain/chain.wit.print new file mode 100644 index 0000000000..ccff4b179a --- /dev/null +++ b/crates/wit-component/tests/interfaces/pkg-use-chain/chain.wit.print @@ -0,0 +1,20 @@ +package foo:chain + +interface a { + type a = u8 + +} + +interface def { + use a.{a} + + enum name { + other, + } + +} + +interface foo { + use def.{name} +} + diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain/def.wit b/crates/wit-component/tests/interfaces/pkg-use-chain/def.wit index c683bffa38..f8276c381c 100644 --- a/crates/wit-component/tests/interfaces/pkg-use-chain/def.wit +++ b/crates/wit-component/tests/interfaces/pkg-use-chain/def.wit @@ -1,5 +1,7 @@ -default interface name { - use self.a.{a} +package foo:chain + +interface def { + use a.{a} enum name { other, diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain/def.wit.print b/crates/wit-component/tests/interfaces/pkg-use-chain/def.wit.print deleted file mode 100644 index 8f339366a6..0000000000 --- a/crates/wit-component/tests/interfaces/pkg-use-chain/def.wit.print +++ /dev/null @@ -1,14 +0,0 @@ -interface a { - type a = u8 - -} - -interface name { - use self.a.{a} - - enum name { - other, - } - -} - diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain/the-use.wit b/crates/wit-component/tests/interfaces/pkg-use-chain/the-use.wit index 730e316875..9fb7322f6c 100644 --- a/crates/wit-component/tests/interfaces/pkg-use-chain/the-use.wit +++ b/crates/wit-component/tests/interfaces/pkg-use-chain/the-use.wit @@ -1,3 +1,5 @@ +package foo:chain + interface foo { - use pkg.def.{name} + use def.{name} } diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain/the-use.wit.print b/crates/wit-component/tests/interfaces/pkg-use-chain/the-use.wit.print deleted file mode 100644 index d5392e8af3..0000000000 --- a/crates/wit-component/tests/interfaces/pkg-use-chain/the-use.wit.print +++ /dev/null @@ -1,4 +0,0 @@ -interface foo { - use pkg.def.name.{name} -} - diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain2.wat b/crates/wit-component/tests/interfaces/pkg-use-chain2.wat index b6ca3d2dba..fe88147deb 100644 --- a/crates/wit-component/tests/interfaces/pkg-use-chain2.wat +++ b/crates/wit-component/tests/interfaces/pkg-use-chain2.wat @@ -7,7 +7,7 @@ (export (;1;) "name" (type (eq 0))) ) ) - (export (;0;) "other" "pkg:/bar/other" (instance (type 0))) + (export (;0;) (interface "foo:foo/other") (instance (type 0))) (alias export 0 "name" (type (;1;))) (type (;2;) (instance @@ -17,29 +17,7 @@ (export (;3;) "name" (type (eq 2))) ) ) - (export (;1;) "d" "pkg:/bar/d" (instance (type 2))) - ) - ) - (export (;1;) "bar" "pkg:/bar" (type 0)) - (type (;2;) - (component - (type (;0;) - (instance - (type (;0;) (record)) - (export (;1;) "name" (type (eq 0))) - ) - ) - (import "other" "pkg:/bar/other" (instance (;0;) (type 0))) - (alias export 0 "name" (type (;1;))) - (type (;2;) - (instance - (alias outer 1 1 (type (;0;))) - (export (;1;) "the-name" (type (eq 0))) - (type (;2;) (enum "a")) - (export (;3;) "name" (type (eq 2))) - ) - ) - (import "d" "pkg:/bar/d" (instance (;1;) (type 2))) + (export (;1;) (interface "foo:foo/bar") (instance (type 2))) (alias export 1 "the-name" (type (;3;))) (type (;4;) (instance @@ -47,11 +25,11 @@ (export (;1;) "the-name" (type (eq 0))) ) ) - (export (;2;) "foo" "pkg:/foo/foo" (instance (type 4))) + (export (;2;) (interface "foo:foo/foo") (instance (type 4))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;3;) "foo" "pkg:/foo" (type 2)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit b/crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit index 9f914daa18..f0588f0921 100644 --- a/crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit +++ b/crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit @@ -1,5 +1,5 @@ -default interface d { - use self.other.{name as the-name} +interface bar { + use other.{name as the-name} enum name { a diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit.print b/crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit.print deleted file mode 100644 index 39040e8e52..0000000000 --- a/crates/wit-component/tests/interfaces/pkg-use-chain2/bar.wit.print +++ /dev/null @@ -1,15 +0,0 @@ -interface other { - record name { - } - -} - -interface d { - use self.other.{name as the-name} - - enum name { - a, - } - -} - diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain2/foo.wit b/crates/wit-component/tests/interfaces/pkg-use-chain2/foo.wit index 6b212e1994..f4903f12f5 100644 --- a/crates/wit-component/tests/interfaces/pkg-use-chain2/foo.wit +++ b/crates/wit-component/tests/interfaces/pkg-use-chain2/foo.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { - use pkg.bar.{the-name} + use bar.{the-name} } diff --git a/crates/wit-component/tests/interfaces/pkg-use-chain2/foo.wit.print b/crates/wit-component/tests/interfaces/pkg-use-chain2/foo.wit.print index 3ffe8d5987..5dd138c089 100644 --- a/crates/wit-component/tests/interfaces/pkg-use-chain2/foo.wit.print +++ b/crates/wit-component/tests/interfaces/pkg-use-chain2/foo.wit.print @@ -1,4 +1,21 @@ +package foo:foo + +interface other { + record name { + } + +} + +interface bar { + use other.{name as the-name} + + enum name { + a, + } + +} + interface foo { - use pkg.bar.d.{the-name} + use bar.{the-name} } diff --git a/crates/wit-component/tests/interfaces/preserve-dep-type-order.wat b/crates/wit-component/tests/interfaces/preserve-dep-type-order.wat index fc19d197ad..21027f7c29 100644 --- a/crates/wit-component/tests/interfaces/preserve-dep-type-order.wat +++ b/crates/wit-component/tests/interfaces/preserve-dep-type-order.wat @@ -9,7 +9,7 @@ (export (;3;) "a" (type (eq 2))) ) ) - (import "foo2" "path:/dep/foo/foo" (instance (;0;) (type 0))) + (import (interface "foo:dep/foo") (instance (;0;) (type 0))) (alias export 0 "ty" (type (;1;))) (type (;2;) (instance @@ -17,7 +17,7 @@ (export (;1;) "ty" (type (eq 0))) ) ) - (export (;1;) "foo" "pkg:/foo/foo" (instance (type 2))) + (export (;1;) (interface "foo:foo/foo") (instance (type 2))) (type (;3;) (component (type (;0;) @@ -28,14 +28,14 @@ (export (;3;) "a" (type (eq 2))) ) ) - (import "foo" "path:/dep/foo/foo" (instance (;0;) (type 0))) + (import (interface "foo:dep/foo") (instance (;0;) (type 0))) ) ) - (export (;0;) "bar" "pkg:/foo/bar" (component (type 3))) + (export (;0;) (interface "foo:foo/bar") (component (type 3))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "foo" "pkg:/foo" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/preserve-dep-type-order/deps/dep/foo.wit b/crates/wit-component/tests/interfaces/preserve-dep-type-order/deps/dep/foo.wit index 3196821aa4..661037d443 100644 --- a/crates/wit-component/tests/interfaces/preserve-dep-type-order/deps/dep/foo.wit +++ b/crates/wit-component/tests/interfaces/preserve-dep-type-order/deps/dep/foo.wit @@ -1,4 +1,6 @@ -default interface foo { +package foo:dep + +interface foo { enum a { b } diff --git a/crates/wit-component/tests/interfaces/preserve-dep-type-order/deps/dep/foo.wit.print b/crates/wit-component/tests/interfaces/preserve-dep-type-order/deps/dep/foo.wit.print deleted file mode 100644 index 327135821c..0000000000 --- a/crates/wit-component/tests/interfaces/preserve-dep-type-order/deps/dep/foo.wit.print +++ /dev/null @@ -1,10 +0,0 @@ -interface foo { - record ty { - } - - enum a { - b, - } - -} - diff --git a/crates/wit-component/tests/interfaces/preserve-dep-type-order/foo.wit b/crates/wit-component/tests/interfaces/preserve-dep-type-order/foo.wit index ae08a263d3..eafc191957 100644 --- a/crates/wit-component/tests/interfaces/preserve-dep-type-order/foo.wit +++ b/crates/wit-component/tests/interfaces/preserve-dep-type-order/foo.wit @@ -1,7 +1,9 @@ +package foo:foo + interface foo { - use dep.foo.{ty} + use foo:dep/foo.{ty} } world bar { - import foo: dep.foo + import foo:dep/foo } diff --git a/crates/wit-component/tests/interfaces/preserve-dep-type-order/foo.wit.print b/crates/wit-component/tests/interfaces/preserve-dep-type-order/foo.wit.print index f9c2f983c5..eafc191957 100644 --- a/crates/wit-component/tests/interfaces/preserve-dep-type-order/foo.wit.print +++ b/crates/wit-component/tests/interfaces/preserve-dep-type-order/foo.wit.print @@ -1,7 +1,9 @@ +package foo:foo + interface foo { - use dep.foo.foo.{ty} + use foo:dep/foo.{ty} } world bar { - import foo: dep.foo.foo + import foo:dep/foo } diff --git a/crates/wit-component/tests/interfaces/preserve-foreign-reexport.wat b/crates/wit-component/tests/interfaces/preserve-foreign-reexport.wat index cbc21a7fe4..6c4760c018 100644 --- a/crates/wit-component/tests/interfaces/preserve-foreign-reexport.wat +++ b/crates/wit-component/tests/interfaces/preserve-foreign-reexport.wat @@ -10,14 +10,14 @@ (export (;2;) "bar" (type (eq 1))) ) ) - (export (;0;) "foo" "path:/my-dep/my-doc/my-interface" (instance (type 0))) + (export (;0;) (interface "foo:my-dep/my-interface") (instance (type 0))) ) ) - (export (;0;) "foo" "pkg:/foo/foo" (component (type 0))) + (export (;0;) (interface "foo:foo/foo") (component (type 0))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "foo" "pkg:/foo" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/preserve-foreign-reexport/deps/my-dep/my-doc.wit b/crates/wit-component/tests/interfaces/preserve-foreign-reexport/deps/my-dep/my-doc.wit index 2eeed9cd16..6feaeb1165 100644 --- a/crates/wit-component/tests/interfaces/preserve-foreign-reexport/deps/my-dep/my-doc.wit +++ b/crates/wit-component/tests/interfaces/preserve-foreign-reexport/deps/my-dep/my-doc.wit @@ -1,4 +1,6 @@ -default interface my-interface { +package foo:my-dep + +interface my-interface { record foo {} type bar = foo } diff --git a/crates/wit-component/tests/interfaces/preserve-foreign-reexport/deps/my-dep/my-doc.wit.print b/crates/wit-component/tests/interfaces/preserve-foreign-reexport/deps/my-dep/my-doc.wit.print deleted file mode 100644 index 0c86fc6cc5..0000000000 --- a/crates/wit-component/tests/interfaces/preserve-foreign-reexport/deps/my-dep/my-doc.wit.print +++ /dev/null @@ -1,8 +0,0 @@ -interface my-interface { - record foo { - } - - type bar = foo - -} - diff --git a/crates/wit-component/tests/interfaces/preserve-foreign-reexport/foo.wit b/crates/wit-component/tests/interfaces/preserve-foreign-reexport/foo.wit index ec472fe210..ae83137a39 100644 --- a/crates/wit-component/tests/interfaces/preserve-foreign-reexport/foo.wit +++ b/crates/wit-component/tests/interfaces/preserve-foreign-reexport/foo.wit @@ -1,3 +1,5 @@ +package foo:foo + world foo { - export foo: my-dep.my-doc + export foo:my-dep/my-interface } diff --git a/crates/wit-component/tests/interfaces/preserve-foreign-reexport/foo.wit.print b/crates/wit-component/tests/interfaces/preserve-foreign-reexport/foo.wit.print index f9406dd11a..ae83137a39 100644 --- a/crates/wit-component/tests/interfaces/preserve-foreign-reexport/foo.wit.print +++ b/crates/wit-component/tests/interfaces/preserve-foreign-reexport/foo.wit.print @@ -1,3 +1,5 @@ +package foo:foo + world foo { - export foo: my-dep.my-doc.my-interface + export foo:my-dep/my-interface } diff --git a/crates/wit-component/tests/interfaces/print-keyword.wat b/crates/wit-component/tests/interfaces/print-keyword.wat index 56daad4de7..796d5ec611 100644 --- a/crates/wit-component/tests/interfaces/print-keyword.wat +++ b/crates/wit-component/tests/interfaces/print-keyword.wat @@ -10,11 +10,11 @@ (export (;4;) "record" (type (eq 3))) ) ) - (export (;0;) "interface" "pkg:/print-keyword/interface" (instance (type 0))) + (export (;0;) (interface "foo:foo/interface") (instance (type 0))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "print-keyword" "pkg:/print-keyword" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/print-keyword.wit b/crates/wit-component/tests/interfaces/print-keyword.wit index 9d938a98e8..7cbe90834d 100644 --- a/crates/wit-component/tests/interfaces/print-keyword.wit +++ b/crates/wit-component/tests/interfaces/print-keyword.wit @@ -1,3 +1,5 @@ +package foo:foo + interface %interface { type %type = u32 type %world = %type diff --git a/crates/wit-component/tests/interfaces/print-keyword.wit.print b/crates/wit-component/tests/interfaces/print-keyword.wit.print index 7d930bdcde..ed797422d1 100644 --- a/crates/wit-component/tests/interfaces/print-keyword.wit.print +++ b/crates/wit-component/tests/interfaces/print-keyword.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface %interface { type %type = u32 diff --git a/crates/wit-component/tests/interfaces/records.wat b/crates/wit-component/tests/interfaces/records.wat index 3800d52ee3..0006321673 100644 --- a/crates/wit-component/tests/interfaces/records.wat +++ b/crates/wit-component/tests/interfaces/records.wat @@ -40,7 +40,7 @@ (export (;10;) "typedef-inout" (func (type 23))) ) ) - (export (;0;) "records" "pkg:/records/records" (instance (type 0))) + (export (;0;) (interface "foo:records/records") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -82,7 +82,7 @@ (export (;10;) "typedef-inout" (func (type 23))) ) ) - (import "records" "pkg:/records/records" (instance (;0;) (type 0))) + (import (interface "foo:records/records") (instance (;0;) (type 0))) (type (;1;) (instance (type (;0;) (record (field "a" u32) (field "b" u32))) @@ -122,14 +122,14 @@ (export (;10;) "typedef-inout" (func (type 23))) ) ) - (export (;1;) "records2" "pkg:/records/records" (instance (type 1))) + (export (;1;) (interface "foo:records/records") (instance (type 1))) ) ) - (export (;0;) "records-world" "pkg:/records/records-world" (component (type 1))) + (export (;0;) (interface "foo:records/records-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "records" "pkg:/records" (type 0)) + (export (;1;) (interface "foo:records/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/records.wit b/crates/wit-component/tests/interfaces/records.wit index a61e43f772..65a0378f12 100644 --- a/crates/wit-component/tests/interfaces/records.wit +++ b/crates/wit-component/tests/interfaces/records.wit @@ -1,3 +1,5 @@ +package foo:records + interface records { record empty { } @@ -55,6 +57,6 @@ interface records { } world records-world { - import records: self.records - export records2: self.records + import records + export records } diff --git a/crates/wit-component/tests/interfaces/records.wit.print b/crates/wit-component/tests/interfaces/records.wit.print index 542db7007b..630dea861e 100644 --- a/crates/wit-component/tests/interfaces/records.wit.print +++ b/crates/wit-component/tests/interfaces/records.wit.print @@ -1,3 +1,5 @@ +package foo:records + interface records { record scalars { a: u32, @@ -55,6 +57,6 @@ interface records { } world records-world { - import records: self.records - export records2: self.records + import records + export records } diff --git a/crates/wit-component/tests/interfaces/reference-out-of-order.wat b/crates/wit-component/tests/interfaces/reference-out-of-order.wat index 098ce116f8..b8165234d8 100644 --- a/crates/wit-component/tests/interfaces/reference-out-of-order.wat +++ b/crates/wit-component/tests/interfaces/reference-out-of-order.wat @@ -21,7 +21,7 @@ (export (;3;) "d" (func (type 11))) ) ) - (export (;0;) "foo" "pkg:/reference-out-of-order/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -44,14 +44,14 @@ (export (;3;) "d" (func (type 11))) ) ) - (import "foo" "pkg:/reference-out-of-order/foo" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) ) ) - (export (;0;) "foo-world" "pkg:/reference-out-of-order/foo-world" (component (type 1))) + (export (;0;) (interface "foo:foo/foo-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "reference-out-of-order" "pkg:/reference-out-of-order" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/reference-out-of-order.wit b/crates/wit-component/tests/interfaces/reference-out-of-order.wit index 82a7aaf9c4..51f181a749 100644 --- a/crates/wit-component/tests/interfaces/reference-out-of-order.wit +++ b/crates/wit-component/tests/interfaces/reference-out-of-order.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { a: func(x: r) b: func(x: v) @@ -22,5 +24,5 @@ interface foo { } world foo-world { - import foo: self.foo + import foo } diff --git a/crates/wit-component/tests/interfaces/reference-out-of-order.wit.print b/crates/wit-component/tests/interfaces/reference-out-of-order.wit.print index f37173f262..a331dadde2 100644 --- a/crates/wit-component/tests/interfaces/reference-out-of-order.wit.print +++ b/crates/wit-component/tests/interfaces/reference-out-of-order.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface foo { variant v-no-string { s(u32), @@ -25,5 +27,5 @@ interface foo { } world foo-world { - import foo: self.foo + import foo } diff --git a/crates/wit-component/tests/interfaces/simple-deps.wat b/crates/wit-component/tests/interfaces/simple-deps.wat index b55ad3ee1c..4e84a600b4 100644 --- a/crates/wit-component/tests/interfaces/simple-deps.wat +++ b/crates/wit-component/tests/interfaces/simple-deps.wat @@ -7,7 +7,7 @@ (export (;1;) "some-type" (type (eq 0))) ) ) - (import "types" "path:/some-dep/types/types" (instance (;0;) (type 0))) + (import (interface "foo:some-dep/types") (instance (;0;) (type 0))) (alias export 0 "some-type" (type (;1;))) (type (;2;) (instance @@ -15,11 +15,11 @@ (export (;1;) "some-type" (type (eq 0))) ) ) - (export (;1;) "foo" "pkg:/foo/foo" (instance (type 2))) + (export (;1;) (interface "foo:foo/foo") (instance (type 2))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "foo" "pkg:/foo" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/simple-deps/deps/some-dep/types.wit b/crates/wit-component/tests/interfaces/simple-deps/deps/some-dep/types.wit index 1fd776144d..500f811c12 100644 --- a/crates/wit-component/tests/interfaces/simple-deps/deps/some-dep/types.wit +++ b/crates/wit-component/tests/interfaces/simple-deps/deps/some-dep/types.wit @@ -1,3 +1,5 @@ -default interface types { +package foo:some-dep + +interface types { type some-type = u8 } diff --git a/crates/wit-component/tests/interfaces/simple-deps/deps/some-dep/types.wit.print b/crates/wit-component/tests/interfaces/simple-deps/deps/some-dep/types.wit.print deleted file mode 100644 index 0c1b0124fc..0000000000 --- a/crates/wit-component/tests/interfaces/simple-deps/deps/some-dep/types.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface types { - type some-type = u8 - -} - diff --git a/crates/wit-component/tests/interfaces/simple-deps/foo.wit b/crates/wit-component/tests/interfaces/simple-deps/foo.wit index 0b034021cb..087d0d1590 100644 --- a/crates/wit-component/tests/interfaces/simple-deps/foo.wit +++ b/crates/wit-component/tests/interfaces/simple-deps/foo.wit @@ -1,3 +1,4 @@ +package foo:foo interface foo { - use some-dep.types.{some-type} + use foo:some-dep/types.{some-type} } diff --git a/crates/wit-component/tests/interfaces/simple-deps/foo.wit.print b/crates/wit-component/tests/interfaces/simple-deps/foo.wit.print index eaf5632f3c..66aa458716 100644 --- a/crates/wit-component/tests/interfaces/simple-deps/foo.wit.print +++ b/crates/wit-component/tests/interfaces/simple-deps/foo.wit.print @@ -1,4 +1,6 @@ +package foo:foo + interface foo { - use some-dep.types.types.{some-type} + use foo:some-dep/types.{some-type} } diff --git a/crates/wit-component/tests/interfaces/simple-multi.wat b/crates/wit-component/tests/interfaces/simple-multi.wat index 3d82eabb76..36576a200f 100644 --- a/crates/wit-component/tests/interfaces/simple-multi.wat +++ b/crates/wit-component/tests/interfaces/simple-multi.wat @@ -4,20 +4,15 @@ (type (;0;) (instance) ) - (export (;0;) "foo" "pkg:/foo/foo" (instance (type 0))) - ) - ) - (export (;1;) "foo" "pkg:/foo" (type 0)) - (type (;2;) - (component - (type (;0;) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) + (type (;1;) (instance) ) - (export (;0;) "bar" "pkg:/bar/bar" (instance (type 0))) + (export (;1;) (interface "foo:foo/bar") (instance (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;3;) "bar" "pkg:/bar" (type 2)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/simple-multi/bar.wit.print b/crates/wit-component/tests/interfaces/simple-multi/bar.wit.print deleted file mode 100644 index 1f15fd4e7b..0000000000 --- a/crates/wit-component/tests/interfaces/simple-multi/bar.wit.print +++ /dev/null @@ -1,3 +0,0 @@ -interface bar { -} - diff --git a/crates/wit-component/tests/interfaces/simple-multi/foo.wit b/crates/wit-component/tests/interfaces/simple-multi/foo.wit index 27947d8a47..f8a9027d45 100644 --- a/crates/wit-component/tests/interfaces/simple-multi/foo.wit +++ b/crates/wit-component/tests/interfaces/simple-multi/foo.wit @@ -1 +1,3 @@ +package foo:foo + interface foo {} diff --git a/crates/wit-component/tests/interfaces/simple-multi/foo.wit.print b/crates/wit-component/tests/interfaces/simple-multi/foo.wit.print index 80bb52742a..83c8f7a146 100644 --- a/crates/wit-component/tests/interfaces/simple-multi/foo.wit.print +++ b/crates/wit-component/tests/interfaces/simple-multi/foo.wit.print @@ -1,3 +1,8 @@ +package foo:foo + interface foo { } +interface bar { +} + diff --git a/crates/wit-component/tests/interfaces/simple-use.wat b/crates/wit-component/tests/interfaces/simple-use.wat index c1bb13b653..f30b3eff94 100644 --- a/crates/wit-component/tests/interfaces/simple-use.wat +++ b/crates/wit-component/tests/interfaces/simple-use.wat @@ -7,7 +7,7 @@ (export (;1;) "level" (type (eq 0))) ) ) - (export (;0;) "types" "pkg:/simple-use/types" (instance (type 0))) + (export (;0;) (interface "foo:foo/types") (instance (type 0))) (alias export 0 "level" (type (;1;))) (type (;2;) (instance @@ -17,11 +17,11 @@ (export (;0;) "log" (func (type 2))) ) ) - (export (;1;) "console" "pkg:/simple-use/console" (instance (type 2))) + (export (;1;) (interface "foo:foo/console") (instance (type 2))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "simple-use" "pkg:/simple-use" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/simple-use.wit b/crates/wit-component/tests/interfaces/simple-use.wit index c09566dbe0..69069bd934 100644 --- a/crates/wit-component/tests/interfaces/simple-use.wit +++ b/crates/wit-component/tests/interfaces/simple-use.wit @@ -1,3 +1,5 @@ +package foo:foo + interface types { enum level { info, @@ -6,6 +8,6 @@ interface types { } interface console { - use self.types.{level} + use types.{level} log: func(level: level, msg: string) } diff --git a/crates/wit-component/tests/interfaces/simple-use.wit.print b/crates/wit-component/tests/interfaces/simple-use.wit.print index a71079d3d4..99ec8690f0 100644 --- a/crates/wit-component/tests/interfaces/simple-use.wit.print +++ b/crates/wit-component/tests/interfaces/simple-use.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface types { enum level { info, @@ -7,7 +9,7 @@ interface types { } interface console { - use self.types.{level} + use types.{level} log: func(level: level, msg: string) } diff --git a/crates/wit-component/tests/interfaces/simple-world.wat b/crates/wit-component/tests/interfaces/simple-world.wat index e8f4d8792b..74140a6202 100644 --- a/crates/wit-component/tests/interfaces/simple-world.wat +++ b/crates/wit-component/tests/interfaces/simple-world.wat @@ -7,7 +7,7 @@ (export (;0;) "log" (func (type 0))) ) ) - (export (;0;) "console" "pkg:/simple-world/console" (instance (type 0))) + (export (;0;) (interface "foo:foo/console") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -16,14 +16,14 @@ (export (;0;) "log" (func (type 0))) ) ) - (import "console" "pkg:/simple-world/console" (instance (;0;) (type 0))) + (import (interface "foo:foo/console") (instance (;0;) (type 0))) ) ) - (export (;0;) "the-world" "pkg:/simple-world/the-world" (component (type 1))) + (export (;0;) (interface "foo:foo/the-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "simple-world" "pkg:/simple-world" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/simple-world.wit b/crates/wit-component/tests/interfaces/simple-world.wit index c5d1ef2bb7..3dd0801686 100644 --- a/crates/wit-component/tests/interfaces/simple-world.wit +++ b/crates/wit-component/tests/interfaces/simple-world.wit @@ -1,5 +1,7 @@ +package foo:foo + world the-world { - import console: self.console + import console } interface console { diff --git a/crates/wit-component/tests/interfaces/simple-world.wit.print b/crates/wit-component/tests/interfaces/simple-world.wit.print index e059d63baf..ef62499f08 100644 --- a/crates/wit-component/tests/interfaces/simple-world.wit.print +++ b/crates/wit-component/tests/interfaces/simple-world.wit.print @@ -1,7 +1,9 @@ +package foo:foo + interface console { log: func(arg: string) } world the-world { - import console: self.console + import console } diff --git a/crates/wit-component/tests/interfaces/single-named-result.wat b/crates/wit-component/tests/interfaces/single-named-result.wat index 05a0302b7a..a0ce0956ce 100644 --- a/crates/wit-component/tests/interfaces/single-named-result.wat +++ b/crates/wit-component/tests/interfaces/single-named-result.wat @@ -7,11 +7,11 @@ (export (;0;) "a" (func (type 0))) ) ) - (export (;0;) "foo" "pkg:/single-named-result/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "single-named-result" "pkg:/single-named-result" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/single-named-result.wit b/crates/wit-component/tests/interfaces/single-named-result.wit index 13afc00d1b..8fd946ffd1 100644 --- a/crates/wit-component/tests/interfaces/single-named-result.wit +++ b/crates/wit-component/tests/interfaces/single-named-result.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { a: func() -> (a: u32) } diff --git a/crates/wit-component/tests/interfaces/single-named-result.wit.print b/crates/wit-component/tests/interfaces/single-named-result.wit.print index cd6cb560dc..fe78a21bc2 100644 --- a/crates/wit-component/tests/interfaces/single-named-result.wit.print +++ b/crates/wit-component/tests/interfaces/single-named-result.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface foo { a: func() -> (a: u32) } diff --git a/crates/wit-component/tests/interfaces/type-alias.wat b/crates/wit-component/tests/interfaces/type-alias.wat index 470e40871e..2feb4e343e 100644 --- a/crates/wit-component/tests/interfaces/type-alias.wat +++ b/crates/wit-component/tests/interfaces/type-alias.wat @@ -10,7 +10,7 @@ (export (;0;) "f" (func (type 3))) ) ) - (export (;0;) "foo" "pkg:/type-alias/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -22,7 +22,7 @@ (export (;0;) "f" (func (type 3))) ) ) - (import "foo" "pkg:/type-alias/foo" (instance (;0;) (type 0))) + (import (interface "foo:foo/foo") (instance (;0;) (type 0))) (type (;1;) (instance (type (;0;) u8) @@ -32,14 +32,14 @@ (export (;0;) "f" (func (type 3))) ) ) - (export (;1;) "foo2" "pkg:/type-alias/foo" (instance (type 1))) + (export (;1;) (interface "foo:foo/foo") (instance (type 1))) ) ) - (export (;0;) "my-world" "pkg:/type-alias/my-world" (component (type 1))) + (export (;0;) (interface "foo:foo/my-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "type-alias" "pkg:/type-alias" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/type-alias.wit b/crates/wit-component/tests/interfaces/type-alias.wit index 80da597523..ebf404257d 100644 --- a/crates/wit-component/tests/interfaces/type-alias.wit +++ b/crates/wit-component/tests/interfaces/type-alias.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { type a = u8 type b = a @@ -6,6 +8,6 @@ interface foo { } world my-world { - import foo: self.foo - export foo2: self.foo + import foo + export foo } diff --git a/crates/wit-component/tests/interfaces/type-alias.wit.print b/crates/wit-component/tests/interfaces/type-alias.wit.print index 56c75fcd32..ceb42db28c 100644 --- a/crates/wit-component/tests/interfaces/type-alias.wit.print +++ b/crates/wit-component/tests/interfaces/type-alias.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface foo { type a = u8 @@ -7,6 +9,6 @@ interface foo { } world my-world { - import foo: self.foo - export foo2: self.foo + import foo + export foo } diff --git a/crates/wit-component/tests/interfaces/type-alias2.wat b/crates/wit-component/tests/interfaces/type-alias2.wat index 87c550c508..91a47346d0 100644 --- a/crates/wit-component/tests/interfaces/type-alias2.wat +++ b/crates/wit-component/tests/interfaces/type-alias2.wat @@ -10,7 +10,7 @@ (export (;0;) "f" (func (type 3))) ) ) - (export (;0;) "foo" "pkg:/type-alias2/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -22,14 +22,14 @@ (export (;0;) "f" (func (type 3))) ) ) - (export (;0;) "foo" "pkg:/type-alias2/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) ) ) - (export (;0;) "my-world" "pkg:/type-alias2/my-world" (component (type 1))) + (export (;0;) (interface "foo:foo/my-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "type-alias2" "pkg:/type-alias2" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/type-alias2.wit b/crates/wit-component/tests/interfaces/type-alias2.wit index 0af05e5896..b3a3d3fc07 100644 --- a/crates/wit-component/tests/interfaces/type-alias2.wit +++ b/crates/wit-component/tests/interfaces/type-alias2.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { flags a { b, @@ -9,5 +11,5 @@ interface foo { } world my-world { - export foo: self.foo + export foo } diff --git a/crates/wit-component/tests/interfaces/type-alias2.wit.print b/crates/wit-component/tests/interfaces/type-alias2.wit.print index 0af05e5896..b3a3d3fc07 100644 --- a/crates/wit-component/tests/interfaces/type-alias2.wit.print +++ b/crates/wit-component/tests/interfaces/type-alias2.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface foo { flags a { b, @@ -9,5 +11,5 @@ interface foo { } world my-world { - export foo: self.foo + export foo } diff --git a/crates/wit-component/tests/interfaces/upstream-deps-same-name.wat b/crates/wit-component/tests/interfaces/upstream-deps-same-name.wat index c719d92b9f..2dc006c00d 100644 --- a/crates/wit-component/tests/interfaces/upstream-deps-same-name.wat +++ b/crates/wit-component/tests/interfaces/upstream-deps-same-name.wat @@ -7,14 +7,14 @@ (export (;1;) "ty" (type (eq 0))) ) ) - (import "the-iface" "path:/a/the-name/the-iface" (instance (;0;) (type 0))) + (import (interface "foo:a/the-name") (instance (;0;) (type 0))) (type (;1;) (instance (type (;0;) u8) (export (;1;) "ty" (type (eq 0))) ) ) - (import "the-iface2" "path:/b/the-name/the-iface" (instance (;1;) (type 1))) + (import (interface "foo:b/the-name") (instance (;1;) (type 1))) (alias export 0 "ty" (type (;2;))) (alias export 1 "ty" (type (;3;))) (type (;4;) @@ -25,11 +25,11 @@ (export (;3;) "ty2" (type (eq 2))) ) ) - (export (;2;) "a" "pkg:/foo/a" (instance (type 4))) + (export (;2;) (interface "foo:foo/a") (instance (type 4))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "foo" "pkg:/foo" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/a/the-name.wit b/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/a/the-name.wit index 7256683239..dc0d8f016c 100644 --- a/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/a/the-name.wit +++ b/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/a/the-name.wit @@ -1,3 +1,4 @@ -default interface the-iface { +package foo:a +interface the-name { type ty = u8 } diff --git a/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/a/the-name.wit.print b/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/a/the-name.wit.print deleted file mode 100644 index a0f0577eba..0000000000 --- a/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/a/the-name.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface the-iface { - type ty = u8 - -} - diff --git a/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/b/the-name.wit b/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/b/the-name.wit index 7256683239..92ff659a3c 100644 --- a/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/b/the-name.wit +++ b/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/b/the-name.wit @@ -1,3 +1,4 @@ -default interface the-iface { +package foo:b +interface the-name { type ty = u8 } diff --git a/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/b/the-name.wit.print b/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/b/the-name.wit.print deleted file mode 100644 index a0f0577eba..0000000000 --- a/crates/wit-component/tests/interfaces/upstream-deps-same-name/deps/b/the-name.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface the-iface { - type ty = u8 - -} - diff --git a/crates/wit-component/tests/interfaces/upstream-deps-same-name/foo.wit b/crates/wit-component/tests/interfaces/upstream-deps-same-name/foo.wit index 8199b7a83b..ee38300a02 100644 --- a/crates/wit-component/tests/interfaces/upstream-deps-same-name/foo.wit +++ b/crates/wit-component/tests/interfaces/upstream-deps-same-name/foo.wit @@ -1,4 +1,6 @@ +package foo:foo + interface a { - use a.the-name.{ty} - use b.the-name.{ty as ty2} + use foo:a/the-name.{ty} + use foo:b/the-name.{ty as ty2} } diff --git a/crates/wit-component/tests/interfaces/upstream-deps-same-name/foo.wit.print b/crates/wit-component/tests/interfaces/upstream-deps-same-name/foo.wit.print index 504600d9be..4f16d68b3e 100644 --- a/crates/wit-component/tests/interfaces/upstream-deps-same-name/foo.wit.print +++ b/crates/wit-component/tests/interfaces/upstream-deps-same-name/foo.wit.print @@ -1,5 +1,7 @@ +package foo:foo + interface a { - use a.the-name.the-iface.{ty} - use b.the-name.the-iface.{ty as ty2} + use foo:a/the-name.{ty} + use foo:b/the-name.{ty as ty2} } diff --git a/crates/wit-component/tests/interfaces/use-chain.wat b/crates/wit-component/tests/interfaces/use-chain.wat index b880ae7fdc..34fabfc874 100644 --- a/crates/wit-component/tests/interfaces/use-chain.wat +++ b/crates/wit-component/tests/interfaces/use-chain.wat @@ -9,7 +9,7 @@ (export (;3;) "c" (type (eq 2))) ) ) - (export (;0;) "foo" "pkg:/use-chain/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) (alias export 0 "c" (type (;1;))) (type (;2;) (instance @@ -17,7 +17,7 @@ (export (;1;) "c" (type (eq 0))) ) ) - (export (;1;) "bar" "pkg:/use-chain/bar" (instance (type 2))) + (export (;1;) (interface "foo:foo/bar") (instance (type 2))) (alias export 1 "c" (type (;3;))) (type (;4;) (instance @@ -25,11 +25,11 @@ (export (;1;) "c" (type (eq 0))) ) ) - (export (;2;) "baz" "pkg:/use-chain/baz" (instance (type 4))) + (export (;2;) (interface "foo:foo/baz") (instance (type 4))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "use-chain" "pkg:/use-chain" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/use-chain.wit b/crates/wit-component/tests/interfaces/use-chain.wit index 61bfb307d2..a8169f83d2 100644 --- a/crates/wit-component/tests/interfaces/use-chain.wit +++ b/crates/wit-component/tests/interfaces/use-chain.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { type a = u32 type b = a @@ -5,9 +7,9 @@ interface foo { } interface bar { - use self.foo.{c} + use foo.{c} } interface baz { - use self.bar.{c} + use bar.{c} } diff --git a/crates/wit-component/tests/interfaces/use-chain.wit.print b/crates/wit-component/tests/interfaces/use-chain.wit.print index 35910f70ef..902f62fd82 100644 --- a/crates/wit-component/tests/interfaces/use-chain.wit.print +++ b/crates/wit-component/tests/interfaces/use-chain.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface foo { type a = u32 @@ -8,10 +10,10 @@ interface foo { } interface bar { - use self.foo.{c} + use foo.{c} } interface baz { - use self.bar.{c} + use bar.{c} } diff --git a/crates/wit-component/tests/interfaces/use-for-type.wat b/crates/wit-component/tests/interfaces/use-for-type.wat index 852e844da5..8730037c73 100644 --- a/crates/wit-component/tests/interfaces/use-for-type.wat +++ b/crates/wit-component/tests/interfaces/use-for-type.wat @@ -4,14 +4,14 @@ (type (;0;) (instance) ) - (export (;0;) "foo" "pkg:/use-for-type/foo" (instance (type 0))) + (export (;0;) (interface "foo:foo/foo") (instance (type 0))) (type (;1;) (instance (type (;0;) u8) (export (;1;) "t" (type (eq 0))) ) ) - (export (;1;) "bar" "pkg:/use-for-type/bar" (instance (type 1))) + (export (;1;) (interface "foo:foo/bar") (instance (type 1))) (alias export 1 "t" (type (;2;))) (type (;3;) (instance @@ -21,11 +21,11 @@ (export (;3;) "bar" (type (eq 2))) ) ) - (export (;2;) "baz" "pkg:/use-for-type/baz" (instance (type 3))) + (export (;2;) (interface "foo:foo/baz") (instance (type 3))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "use-for-type" "pkg:/use-for-type" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/use-for-type.wit b/crates/wit-component/tests/interfaces/use-for-type.wit index fa40150280..36dfac2201 100644 --- a/crates/wit-component/tests/interfaces/use-for-type.wit +++ b/crates/wit-component/tests/interfaces/use-for-type.wit @@ -1,4 +1,6 @@ -default interface foo { +package foo:foo + +interface foo { } interface bar { @@ -6,7 +8,7 @@ interface bar { } interface baz { - use self.bar.{t} + use bar.{t} record bar { a: t, diff --git a/crates/wit-component/tests/interfaces/use-for-type.wit.print b/crates/wit-component/tests/interfaces/use-for-type.wit.print index 8f81480bd8..001dd2dca1 100644 --- a/crates/wit-component/tests/interfaces/use-for-type.wit.print +++ b/crates/wit-component/tests/interfaces/use-for-type.wit.print @@ -1,3 +1,5 @@ +package foo:foo + interface foo { } @@ -7,7 +9,7 @@ interface bar { } interface baz { - use self.bar.{t} + use bar.{t} record bar { a: t, diff --git a/crates/wit-component/tests/interfaces/variants.wat b/crates/wit-component/tests/interfaces/variants.wat index 3433c3af7a..8f744239c5 100644 --- a/crates/wit-component/tests/interfaces/variants.wat +++ b/crates/wit-component/tests/interfaces/variants.wat @@ -95,7 +95,7 @@ (export (;19;) "expected-simple" (func (type 69))) ) ) - (export (;0;) "variants" "pkg:/variants/variants" (instance (type 0))) + (export (;0;) (interface "foo:variants/variants") (instance (type 0))) (type (;1;) (component (type (;0;) @@ -192,14 +192,14 @@ (export (;19;) "expected-simple" (func (type 69))) ) ) - (import "variants" "pkg:/variants/variants" (instance (;0;) (type 0))) + (import (interface "foo:variants/variants") (instance (;0;) (type 0))) ) ) - (export (;0;) "variants-world" "pkg:/variants/variants-world" (component (type 1))) + (export (;0;) (interface "foo:variants/variants-world") (component (type 1))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "variants" "pkg:/variants" (type 0)) + (export (;1;) (interface "foo:variants/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/variants.wit b/crates/wit-component/tests/interfaces/variants.wit index bb642626f6..195ffac4fb 100644 --- a/crates/wit-component/tests/interfaces/variants.wit +++ b/crates/wit-component/tests/interfaces/variants.wit @@ -1,3 +1,5 @@ +package foo:variants + interface variants { enum e1 { a, @@ -79,5 +81,5 @@ interface variants { } world variants-world { - import variants: self.variants + import variants } diff --git a/crates/wit-component/tests/interfaces/variants.wit.print b/crates/wit-component/tests/interfaces/variants.wit.print index 3e9a73b346..ea6a3d8a0b 100644 --- a/crates/wit-component/tests/interfaces/variants.wit.print +++ b/crates/wit-component/tests/interfaces/variants.wit.print @@ -1,3 +1,5 @@ +package foo:variants + interface variants { union u1 { u32, @@ -98,5 +100,5 @@ interface variants { } world variants-world { - import variants: self.variants + import variants } diff --git a/crates/wit-component/tests/interfaces/wasi-http.wat b/crates/wit-component/tests/interfaces/wasi-http.wat index 2e9a4ba50c..fc12047d17 100644 --- a/crates/wit-component/tests/interfaces/wasi-http.wat +++ b/crates/wit-component/tests/interfaces/wasi-http.wat @@ -7,7 +7,7 @@ (export (;1;) "pollable" (type (eq 0))) ) ) - (import "poll" "path:/poll/poll/poll" (instance (;0;) (type 0))) + (import (interface "wasi:poll/poll") (instance (;0;) (type 0))) (alias export 0 "pollable" (type (;1;))) (type (;2;) (instance @@ -21,7 +21,7 @@ (export (;7;) "input-stream" (type (eq 6))) ) ) - (import "streams" "path:/io/streams/streams" (instance (;1;) (type 2))) + (import (interface "wasi:io/streams") (instance (;1;) (type 2))) (alias export 1 "input-stream" (type (;3;))) (alias export 1 "output-stream" (type (;4;))) (type (;5;) @@ -138,75 +138,7 @@ (export (;32;) "listen-to-future-incoming-response" (func (type 76))) ) ) - (export (;2;) "types" "pkg:/types/types" (instance (type 5))) - ) - ) - (export (;1;) "types" "pkg:/types" (type 0)) - (type (;2;) - (component - (type (;0;) - (instance - (type (;0;) u32) - (export (;1;) "pollable" (type (eq 0))) - ) - ) - (import "poll" "path:/poll/poll/poll" (instance (;0;) (type 0))) - (alias export 0 "pollable" (type (;1;))) - (type (;2;) - (instance - (alias outer 1 1 (type (;0;))) - (export (;1;) "pollable" (type (eq 0))) - (type (;2;) (record)) - (export (;3;) "stream-error" (type (eq 2))) - (type (;4;) u32) - (export (;5;) "output-stream" (type (eq 4))) - (type (;6;) u32) - (export (;7;) "input-stream" (type (eq 6))) - ) - ) - (import "streams" "path:/io/streams/streams" (instance (;1;) (type 2))) - (alias export 1 "input-stream" (type (;3;))) - (alias export 1 "output-stream" (type (;4;))) - (type (;5;) - (instance - (alias outer 1 3 (type (;0;))) - (export (;1;) "input-stream" (type (eq 0))) - (alias outer 1 4 (type (;2;))) - (export (;3;) "output-stream" (type (eq 2))) - (alias outer 1 1 (type (;4;))) - (export (;5;) "pollable" (type (eq 4))) - (type (;6;) u16) - (export (;7;) "status-code" (type (eq 6))) - (type (;8;) (variant (case "HTTP") (case "HTTPS") (case "other" string))) - (export (;9;) "scheme" (type (eq 8))) - (type (;10;) u32) - (export (;11;) "response-outparam" (type (eq 10))) - (type (;12;) (option u32)) - (type (;13;) (record (field "connect-timeout-ms" 12) (field "first-byte-timeout-ms" 12) (field "between-bytes-timeout-ms" 12))) - (export (;14;) "request-options" (type (eq 13))) - (export (;15;) "outgoing-stream" (type (eq 3))) - (type (;16;) u32) - (export (;17;) "outgoing-response" (type (eq 16))) - (type (;18;) u32) - (export (;19;) "outgoing-request" (type (eq 18))) - (type (;20;) (variant (case "get") (case "head") (case "post") (case "put") (case "delete") (case "connect") (case "options") (case "trace") (case "patch") (case "other" string))) - (export (;21;) "method" (type (eq 20))) - (export (;22;) "incoming-stream" (type (eq 1))) - (type (;23;) u32) - (export (;24;) "incoming-response" (type (eq 23))) - (type (;25;) u32) - (export (;26;) "incoming-request" (type (eq 25))) - (type (;27;) u32) - (export (;28;) "future-incoming-response" (type (eq 27))) - (type (;29;) u32) - (export (;30;) "fields" (type (eq 29))) - (export (;31;) "trailers" (type (eq 30))) - (export (;32;) "headers" (type (eq 30))) - (type (;33;) (variant (case "invalid-url" string) (case "timeout-error" string) (case "protocol-error" string) (case "unexpected-error" string))) - (export (;34;) "error" (type (eq 33))) - ) - ) - (import "types" "pkg:/types/types" (instance (;2;) (type 5))) + (export (;2;) (interface "wasi:http/types") (instance (type 5))) (alias export 2 "outgoing-request" (type (;6;))) (alias export 2 "request-options" (type (;7;))) (alias export 2 "future-incoming-response" (type (;8;))) @@ -223,94 +155,21 @@ (export (;0;) "handle" (func (type 7))) ) ) - (export (;3;) "outgoing-handler" "pkg:/outgoing-handler/outgoing-handler" (instance (type 9))) - ) - ) - (export (;3;) "outgoing-handler" "pkg:/outgoing-handler" (type 2)) - (type (;4;) - (component - (type (;0;) - (instance - (type (;0;) u32) - (export (;1;) "pollable" (type (eq 0))) - ) - ) - (import "poll" "path:/poll/poll/poll" (instance (;0;) (type 0))) - (alias export 0 "pollable" (type (;1;))) - (type (;2;) - (instance - (alias outer 1 1 (type (;0;))) - (export (;1;) "pollable" (type (eq 0))) - (type (;2;) (record)) - (export (;3;) "stream-error" (type (eq 2))) - (type (;4;) u32) - (export (;5;) "output-stream" (type (eq 4))) - (type (;6;) u32) - (export (;7;) "input-stream" (type (eq 6))) - ) - ) - (import "streams" "path:/io/streams/streams" (instance (;1;) (type 2))) - (alias export 1 "input-stream" (type (;3;))) - (alias export 1 "output-stream" (type (;4;))) - (type (;5;) - (instance - (alias outer 1 3 (type (;0;))) - (export (;1;) "input-stream" (type (eq 0))) - (alias outer 1 4 (type (;2;))) - (export (;3;) "output-stream" (type (eq 2))) - (alias outer 1 1 (type (;4;))) - (export (;5;) "pollable" (type (eq 4))) - (type (;6;) u16) - (export (;7;) "status-code" (type (eq 6))) - (type (;8;) (variant (case "HTTP") (case "HTTPS") (case "other" string))) - (export (;9;) "scheme" (type (eq 8))) - (type (;10;) u32) - (export (;11;) "response-outparam" (type (eq 10))) - (type (;12;) (option u32)) - (type (;13;) (record (field "connect-timeout-ms" 12) (field "first-byte-timeout-ms" 12) (field "between-bytes-timeout-ms" 12))) - (export (;14;) "request-options" (type (eq 13))) - (export (;15;) "outgoing-stream" (type (eq 3))) - (type (;16;) u32) - (export (;17;) "outgoing-response" (type (eq 16))) - (type (;18;) u32) - (export (;19;) "outgoing-request" (type (eq 18))) - (type (;20;) (variant (case "get") (case "head") (case "post") (case "put") (case "delete") (case "connect") (case "options") (case "trace") (case "patch") (case "other" string))) - (export (;21;) "method" (type (eq 20))) - (export (;22;) "incoming-stream" (type (eq 1))) - (type (;23;) u32) - (export (;24;) "incoming-response" (type (eq 23))) - (type (;25;) u32) - (export (;26;) "incoming-request" (type (eq 25))) - (type (;27;) u32) - (export (;28;) "future-incoming-response" (type (eq 27))) - (type (;29;) u32) - (export (;30;) "fields" (type (eq 29))) - (export (;31;) "trailers" (type (eq 30))) - (export (;32;) "headers" (type (eq 30))) - (type (;33;) (variant (case "invalid-url" string) (case "timeout-error" string) (case "protocol-error" string) (case "unexpected-error" string))) - (export (;34;) "error" (type (eq 33))) - ) - ) - (import "types" "pkg:/types/types" (instance (;2;) (type 5))) - (alias export 2 "incoming-request" (type (;6;))) - (alias export 2 "response-outparam" (type (;7;))) - (type (;8;) + (export (;3;) (interface "wasi:http/outgoing-handler") (instance (type 9))) + (alias export 2 "incoming-request" (type (;10;))) + (alias export 2 "response-outparam" (type (;11;))) + (type (;12;) (instance - (alias outer 1 6 (type (;0;))) + (alias outer 1 10 (type (;0;))) (export (;1;) "incoming-request" (type (eq 0))) - (alias outer 1 7 (type (;2;))) + (alias outer 1 11 (type (;2;))) (export (;3;) "response-outparam" (type (eq 2))) (type (;4;) (func (param "request" 1) (param "response-out" 3))) (export (;0;) "handle" (func (type 4))) ) ) - (export (;3;) "incoming-handler" "pkg:/incoming-handler/incoming-handler" (instance (type 8))) - ) - ) - (export (;5;) "incoming-handler" "pkg:/incoming-handler" (type 4)) - (type (;6;) - (component - (type (;0;) + (export (;4;) (interface "wasi:http/incoming-handler") (instance (type 12))) + (type (;13;) (component (type (;0;) (instance @@ -324,7 +183,7 @@ (export (;2;) "insecure-random" (func (type 4))) ) ) - (import "random" "path:/random/random/random" (instance (;0;) (type 0))) + (import (interface "wasi:random/random") (instance (;0;) (type 0))) (type (;1;) (instance (type (;0;) (enum "trace" "debug" "info" "warn" "error")) @@ -333,7 +192,7 @@ (export (;0;) "log" (func (type 2))) ) ) - (import "console" "path:/logging/handler/handler" (instance (;1;) (type 1))) + (import (interface "wasi:logging/handler") (instance (;1;) (type 1))) (type (;2;) (instance (type (;0;) u32) @@ -346,7 +205,7 @@ (export (;1;) "poll-oneoff" (func (type 5))) ) ) - (import "poll" "path:/poll/poll/poll" (instance (;2;) (type 2))) + (import (interface "wasi:poll/poll") (instance (;2;) (type 2))) (alias export 2 "pollable" (type (;3;))) (type (;4;) (instance @@ -391,7 +250,7 @@ (export (;14;) "drop-output-stream" (func (type 23))) ) ) - (import "streams" "path:/io/streams/streams" (instance (;3;) (type 4))) + (import (interface "wasi:io/streams") (instance (;3;) (type 4))) (alias export 3 "input-stream" (type (;5;))) (alias export 3 "output-stream" (type (;6;))) (type (;7;) @@ -508,7 +367,7 @@ (export (;32;) "listen-to-future-incoming-response" (func (type 76))) ) ) - (import "types" "pkg:/types/types" (instance (;4;) (type 7))) + (import (interface "wasi:http/types") (instance (;4;) (type 7))) (alias export 4 "outgoing-request" (type (;8;))) (alias export 4 "request-options" (type (;9;))) (alias export 4 "future-incoming-response" (type (;10;))) @@ -525,7 +384,7 @@ (export (;0;) "handle" (func (type 7))) ) ) - (import "default-outgoing-HTTP" "pkg:/outgoing-handler/outgoing-handler" (instance (;5;) (type 11))) + (import (interface "wasi:http/outgoing-handler") (instance (;5;) (type 11))) (alias export 4 "incoming-request" (type (;12;))) (alias export 4 "response-outparam" (type (;13;))) (type (;14;) @@ -538,14 +397,14 @@ (export (;0;) "handle" (func (type 4))) ) ) - (export (;6;) "HTTP" "pkg:/incoming-handler/incoming-handler" (instance (type 14))) + (export (;6;) (interface "wasi:http/incoming-handler") (instance (type 14))) ) ) - (export (;0;) "proxy" "pkg:/proxy/proxy" (component (type 0))) + (export (;0;) (interface "wasi:http/proxy") (component (type 13))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;7;) "proxy" "pkg:/proxy" (type 6)) + (export (;1;) (interface "wasi:http/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/wasi-http/deps/io/streams.wit b/crates/wit-component/tests/interfaces/wasi-http/deps/io/streams.wit index c1567fd4c1..008e36cf59 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/deps/io/streams.wit +++ b/crates/wit-component/tests/interfaces/wasi-http/deps/io/streams.wit @@ -1,10 +1,12 @@ +package wasi:io + /// WASI I/O is an I/O abstraction API which is currently focused on providing /// stream types. /// /// In the future, the component model is expected to add built-in stream types; /// when it does, they are expected to subsume this API. -default interface streams { - use poll.poll.{pollable} +interface streams { + use wasi:poll/poll.{pollable} /// An error type returned from a stream operation. Currently this /// doesn't provide any additional information. diff --git a/crates/wit-component/tests/interfaces/wasi-http/deps/io/streams.wit.print b/crates/wit-component/tests/interfaces/wasi-http/deps/io/streams.wit.print deleted file mode 100644 index f21b2eb402..0000000000 --- a/crates/wit-component/tests/interfaces/wasi-http/deps/io/streams.wit.print +++ /dev/null @@ -1,41 +0,0 @@ -interface streams { - use poll.poll.poll.{pollable} - - record stream-error { - } - - type output-stream = u32 - - type input-stream = u32 - - read: func(this: input-stream, len: u64) -> result, bool>, stream-error> - - blocking-read: func(this: input-stream, len: u64) -> result, bool>, stream-error> - - skip: func(this: input-stream, len: u64) -> result, stream-error> - - blocking-skip: func(this: input-stream, len: u64) -> result, stream-error> - - subscribe-to-input-stream: func(this: input-stream) -> pollable - - drop-input-stream: func(this: input-stream) - - write: func(this: output-stream, buf: list) -> result - - blocking-write: func(this: output-stream, buf: list) -> result - - write-zeroes: func(this: output-stream, len: u64) -> result - - blocking-write-zeroes: func(this: output-stream, len: u64) -> result - - splice: func(this: output-stream, src: input-stream, len: u64) -> result, stream-error> - - blocking-splice: func(this: output-stream, src: input-stream, len: u64) -> result, stream-error> - - forward: func(this: output-stream, src: input-stream) -> result - - subscribe-to-output-stream: func(this: output-stream) -> pollable - - drop-output-stream: func(this: output-stream) -} - diff --git a/crates/wit-component/tests/interfaces/wasi-http/deps/logging/handler.wit b/crates/wit-component/tests/interfaces/wasi-http/deps/logging/handler.wit index c9632b9cc4..e6b077be8a 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/deps/logging/handler.wit +++ b/crates/wit-component/tests/interfaces/wasi-http/deps/logging/handler.wit @@ -1,6 +1,8 @@ +package wasi:logging + /// WASI Logging is a logging API intended to let users emit log messages with /// simple priority levels and context values. -default interface handler { +interface handler { /// A log level, describing a kind of message. enum level { /// Describes messages about the values of variables and the flow of diff --git a/crates/wit-component/tests/interfaces/wasi-http/deps/logging/handler.wit.print b/crates/wit-component/tests/interfaces/wasi-http/deps/logging/handler.wit.print deleted file mode 100644 index 927e2ed7e5..0000000000 --- a/crates/wit-component/tests/interfaces/wasi-http/deps/logging/handler.wit.print +++ /dev/null @@ -1,12 +0,0 @@ -interface handler { - enum level { - trace, - debug, - info, - warn, - error, - } - - log: func(level: level, context: string, message: string) -} - diff --git a/crates/wit-component/tests/interfaces/wasi-http/deps/poll/poll.wit b/crates/wit-component/tests/interfaces/wasi-http/deps/poll/poll.wit index 28f08e17d7..cf5d8779c1 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/deps/poll/poll.wit +++ b/crates/wit-component/tests/interfaces/wasi-http/deps/poll/poll.wit @@ -1,6 +1,8 @@ +package wasi:poll + /// A poll API intended to let users wait for I/O events on multiple handles /// at once. -default interface poll { +interface poll { /// A "pollable" handle. /// /// This is conceptually represents a `stream<_, _>`, or in other words, diff --git a/crates/wit-component/tests/interfaces/wasi-http/deps/poll/poll.wit.print b/crates/wit-component/tests/interfaces/wasi-http/deps/poll/poll.wit.print deleted file mode 100644 index 6f4de8c8fa..0000000000 --- a/crates/wit-component/tests/interfaces/wasi-http/deps/poll/poll.wit.print +++ /dev/null @@ -1,8 +0,0 @@ -interface poll { - type pollable = u32 - - drop-pollable: func(this: pollable) - - poll-oneoff: func(in: list) -> list -} - diff --git a/crates/wit-component/tests/interfaces/wasi-http/deps/random/random.wit b/crates/wit-component/tests/interfaces/wasi-http/deps/random/random.wit index 2080ddfde9..f956798d54 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/deps/random/random.wit +++ b/crates/wit-component/tests/interfaces/wasi-http/deps/random/random.wit @@ -1,8 +1,10 @@ +package wasi:random + /// WASI Random is a random data API. /// /// It is intended to be portable at least between Unix-family platforms and /// Windows. -default interface random { +interface random { /// Return `len` cryptographically-secure pseudo-random bytes. /// /// This function must produce data from an adequately seeded diff --git a/crates/wit-component/tests/interfaces/wasi-http/deps/random/random.wit.print b/crates/wit-component/tests/interfaces/wasi-http/deps/random/random.wit.print deleted file mode 100644 index 4d4b667929..0000000000 --- a/crates/wit-component/tests/interfaces/wasi-http/deps/random/random.wit.print +++ /dev/null @@ -1,8 +0,0 @@ -interface random { - get-random-bytes: func(len: u64) -> list - - get-random-u64: func() -> u64 - - insecure-random: func() -> tuple -} - diff --git a/crates/wit-component/tests/interfaces/wasi-http/types.wit.print b/crates/wit-component/tests/interfaces/wasi-http/http.wit.print similarity index 83% rename from crates/wit-component/tests/interfaces/wasi-http/types.wit.print rename to crates/wit-component/tests/interfaces/wasi-http/http.wit.print index 4f76d323f1..5ad1f984a8 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/types.wit.print +++ b/crates/wit-component/tests/interfaces/wasi-http/http.wit.print @@ -1,6 +1,8 @@ +package wasi:http + interface types { - use io.streams.streams.{input-stream, output-stream} - use poll.poll.poll.{pollable} + use wasi:io/streams.{input-stream, output-stream} + use wasi:poll/poll.{pollable} type status-code = u16 @@ -125,3 +127,22 @@ interface types { listen-to-future-incoming-response: func(f: future-incoming-response) -> pollable } +interface outgoing-handler { + use types.{outgoing-request, request-options, future-incoming-response} + handle: func(request: outgoing-request, options: option) -> future-incoming-response +} + +interface incoming-handler { + use types.{incoming-request, response-outparam} + handle: func(request: incoming-request, response-out: response-outparam) +} + +world proxy { + import wasi:random/random + import wasi:logging/handler + import wasi:poll/poll + import wasi:io/streams + import types + import outgoing-handler + export incoming-handler +} diff --git a/crates/wit-component/tests/interfaces/wasi-http/incoming-handler.wit b/crates/wit-component/tests/interfaces/wasi-http/incoming-handler.wit index 3b1c29aae2..f98429fed1 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/incoming-handler.wit +++ b/crates/wit-component/tests/interfaces/wasi-http/incoming-handler.wit @@ -6,8 +6,8 @@ // `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface // that takes a `request` parameter and returns a `response` result. // -default interface incoming-handler { - use pkg.types.{incoming-request, response-outparam} +interface incoming-handler { + use types.{incoming-request, response-outparam} // The `handle` function takes an outparam instead of returning its response // so that the component may stream its response while streaming any other diff --git a/crates/wit-component/tests/interfaces/wasi-http/incoming-handler.wit.print b/crates/wit-component/tests/interfaces/wasi-http/incoming-handler.wit.print deleted file mode 100644 index e7aff451be..0000000000 --- a/crates/wit-component/tests/interfaces/wasi-http/incoming-handler.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface incoming-handler { - use pkg.types.types.{incoming-request, response-outparam} - handle: func(request: incoming-request, response-out: response-outparam) -} - diff --git a/crates/wit-component/tests/interfaces/wasi-http/outgoing-handler.wit b/crates/wit-component/tests/interfaces/wasi-http/outgoing-handler.wit index abe812ffab..06c8e469f9 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/outgoing-handler.wit +++ b/crates/wit-component/tests/interfaces/wasi-http/outgoing-handler.wit @@ -5,8 +5,8 @@ // `wasi:http/outgoing-handler` into a single `wasi:http/handler` interface // that takes a `request` parameter and returns a `response` result. // -default interface outgoing-handler { - use pkg.types.{outgoing-request, request-options, future-incoming-response} +interface outgoing-handler { + use types.{outgoing-request, request-options, future-incoming-response} // The parameter and result types of the `handle` function allow the caller // to concurrently stream the bodies of the outgoing request and the incoming diff --git a/crates/wit-component/tests/interfaces/wasi-http/outgoing-handler.wit.print b/crates/wit-component/tests/interfaces/wasi-http/outgoing-handler.wit.print deleted file mode 100644 index 7e913981c1..0000000000 --- a/crates/wit-component/tests/interfaces/wasi-http/outgoing-handler.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface outgoing-handler { - use pkg.types.types.{outgoing-request, request-options, future-incoming-response} - handle: func(request: outgoing-request, options: option) -> future-incoming-response -} - diff --git a/crates/wit-component/tests/interfaces/wasi-http/proxy.wit b/crates/wit-component/tests/interfaces/wasi-http/proxy.wit index abf157fb37..a0330490f5 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/proxy.wit +++ b/crates/wit-component/tests/interfaces/wasi-http/proxy.wit @@ -2,23 +2,23 @@ // hosts that includes HTTP forward and reverse proxies. Components targeting // this world may concurrently stream in and out any number of incoming and // outgoing HTTP requests. -default world proxy { +world proxy { // HTTP proxies have access to time and randomness. - import random: random.random + import wasi:random/random // TODO: add `import wall-clock: clocks.wall-clock` // TODO: add `import monotonic-clock: clocks.monotonic-clock` // This is the default logging handler to use when user code simply wants to // log to a developer-facing console (e.g., via `console.log()`). - import console: logging.handler + import wasi:logging/handler // This is the default handler to use when user code simply wants to make an // HTTP request (e.g., via `fetch()`). - import default-outgoing-HTTP: pkg.outgoing-handler + import outgoing-handler // The host delivers incoming HTTP requests to a component by calling the // `handle` function of this exported interface. A host may arbitrarily reuse // or not reuse component instance when delivering incoming HTTP requests and // thus a component must be able to handle 0..N calls to `handle`. - export HTTP: pkg.incoming-handler + export incoming-handler } diff --git a/crates/wit-component/tests/interfaces/wasi-http/proxy.wit.print b/crates/wit-component/tests/interfaces/wasi-http/proxy.wit.print deleted file mode 100644 index 109faef65d..0000000000 --- a/crates/wit-component/tests/interfaces/wasi-http/proxy.wit.print +++ /dev/null @@ -1,9 +0,0 @@ -world proxy { - import random: random.random.random - import console: logging.handler.handler - import poll: poll.poll.poll - import streams: io.streams.streams - import types: pkg.types.types - import default-outgoing-HTTP: pkg.outgoing-handler.outgoing-handler - export HTTP: pkg.incoming-handler.incoming-handler -} diff --git a/crates/wit-component/tests/interfaces/wasi-http/types.wit b/crates/wit-component/tests/interfaces/wasi-http/types.wit index 5675ff5d77..09cd3742bb 100644 --- a/crates/wit-component/tests/interfaces/wasi-http/types.wit +++ b/crates/wit-component/tests/interfaces/wasi-http/types.wit @@ -1,10 +1,12 @@ +package wasi:http + // The `wasi:http/types` interface is meant to be imported by components to // define the HTTP resource types and operations used by the component's // imported and exported interfaces. -default interface types { - use io.streams.{input-stream, output-stream} - use poll.poll.{pollable} - +interface types { + use wasi:io/streams.{input-stream, output-stream} + use wasi:poll/poll.{pollable} + // This type corresponds to HTTP standard Methods. variant method { get, diff --git a/crates/wit-component/tests/interfaces/world-inline-interface.wat b/crates/wit-component/tests/interfaces/world-inline-interface.wat index bdbd45bdb1..860e01735c 100644 --- a/crates/wit-component/tests/interfaces/world-inline-interface.wat +++ b/crates/wit-component/tests/interfaces/world-inline-interface.wat @@ -13,11 +13,11 @@ (export (;1;) "bar" (instance (type 1))) ) ) - (export (;0;) "has-inline" "pkg:/world-inline-interface/has-inline" (component (type 0))) + (export (;0;) (interface "foo:foo/has-inline") (component (type 0))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "world-inline-interface" "pkg:/world-inline-interface" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/world-inline-interface.wit b/crates/wit-component/tests/interfaces/world-inline-interface.wit index 9940392eca..7c4a63382a 100644 --- a/crates/wit-component/tests/interfaces/world-inline-interface.wit +++ b/crates/wit-component/tests/interfaces/world-inline-interface.wit @@ -1,3 +1,5 @@ +package foo:foo + world has-inline { import foo: interface {} export bar: interface {} diff --git a/crates/wit-component/tests/interfaces/world-inline-interface.wit.print b/crates/wit-component/tests/interfaces/world-inline-interface.wit.print index 33ec54b02d..780ad00717 100644 --- a/crates/wit-component/tests/interfaces/world-inline-interface.wit.print +++ b/crates/wit-component/tests/interfaces/world-inline-interface.wit.print @@ -1,3 +1,5 @@ +package foo:foo + world has-inline { import foo: interface { } diff --git a/crates/wit-component/tests/interfaces/world-pkg-conflict.wat b/crates/wit-component/tests/interfaces/world-pkg-conflict.wat index e3a4dfb181..d671aadd14 100644 --- a/crates/wit-component/tests/interfaces/world-pkg-conflict.wat +++ b/crates/wit-component/tests/interfaces/world-pkg-conflict.wat @@ -7,19 +7,7 @@ (export (;1;) "t" (type (eq 0))) ) ) - (export (;0;) "a" "pkg:/bar/a" (instance (type 0))) - ) - ) - (export (;1;) "bar" "pkg:/bar" (type 0)) - (type (;2;) - (component - (type (;0;) - (instance - (type (;0;) u32) - (export (;1;) "t" (type (eq 0))) - ) - ) - (import "a2" "pkg:/bar/a" (instance (;0;) (type 0))) + (export (;0;) (interface "foo:foo/a") (instance (type 0))) (alias export 0 "t" (type (;1;))) (type (;2;) (instance @@ -27,15 +15,15 @@ (export (;1;) "t" (type (eq 0))) ) ) - (export (;1;) "foo" "pkg:/foo/foo" (instance (type 2))) + (export (;1;) (interface "foo:foo/foo") (instance (type 2))) (type (;3;) (component) ) - (export (;0;) "a" "pkg:/foo/a" (component (type 3))) + (export (;0;) (interface "foo:foo/c") (component (type 3))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;3;) "foo" "pkg:/foo" (type 2)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/world-pkg-conflict/bar.wit b/crates/wit-component/tests/interfaces/world-pkg-conflict/bar.wit index 838dace272..3e09d4d235 100644 --- a/crates/wit-component/tests/interfaces/world-pkg-conflict/bar.wit +++ b/crates/wit-component/tests/interfaces/world-pkg-conflict/bar.wit @@ -1,3 +1,3 @@ -default interface a { +interface a { type t = u32 } diff --git a/crates/wit-component/tests/interfaces/world-pkg-conflict/bar.wit.print b/crates/wit-component/tests/interfaces/world-pkg-conflict/bar.wit.print deleted file mode 100644 index ff3567f5b4..0000000000 --- a/crates/wit-component/tests/interfaces/world-pkg-conflict/bar.wit.print +++ /dev/null @@ -1,5 +0,0 @@ -interface a { - type t = u32 - -} - diff --git a/crates/wit-component/tests/interfaces/world-pkg-conflict/foo.wit b/crates/wit-component/tests/interfaces/world-pkg-conflict/foo.wit index 14b4e32c55..c34d99d378 100644 --- a/crates/wit-component/tests/interfaces/world-pkg-conflict/foo.wit +++ b/crates/wit-component/tests/interfaces/world-pkg-conflict/foo.wit @@ -1,7 +1,9 @@ -world a { +package foo:foo + +world c { } interface foo { - use pkg.bar.{t} + use a.{t} } diff --git a/crates/wit-component/tests/interfaces/world-pkg-conflict/foo.wit.print b/crates/wit-component/tests/interfaces/world-pkg-conflict/foo.wit.print index 470eae117d..2cee9337ae 100644 --- a/crates/wit-component/tests/interfaces/world-pkg-conflict/foo.wit.print +++ b/crates/wit-component/tests/interfaces/world-pkg-conflict/foo.wit.print @@ -1,6 +1,13 @@ +package foo:foo + +interface a { + type t = u32 + +} + interface foo { - use pkg.bar.a.{t} + use a.{t} } -world a { +world c { } diff --git a/crates/wit-component/tests/interfaces/world-top-level.wat b/crates/wit-component/tests/interfaces/world-top-level.wat index e79060df6c..39fe9a9d01 100644 --- a/crates/wit-component/tests/interfaces/world-top-level.wat +++ b/crates/wit-component/tests/interfaces/world-top-level.wat @@ -2,20 +2,6 @@ (type (;0;) (component (type (;0;) - (component - (type (;0;) (func)) - (import "foo" (func (;0;) (type 0))) - ) - ) - (export (;0;) "just-import" "pkg:/world-top-level/just-import" (component (type 0))) - (type (;1;) - (component - (type (;0;) (func)) - (export (;0;) "foo" (func (type 0))) - ) - ) - (export (;1;) "just-export" "pkg:/world-top-level/just-export" (component (type 1))) - (type (;2;) (component (type (;0;) (instance) @@ -34,11 +20,25 @@ (export (;3;) "bar2" (func (type 4))) ) ) - (export (;2;) "foo" "pkg:/world-top-level/foo" (component (type 2))) + (export (;0;) (interface "foo:foo/foo") (component (type 0))) + (type (;1;) + (component + (type (;0;) (func)) + (import "foo" (func (;0;) (type 0))) + ) + ) + (export (;1;) (interface "foo:foo/just-import") (component (type 1))) + (type (;2;) + (component + (type (;0;) (func)) + (export (;0;) "foo" (func (type 0))) + ) + ) + (export (;2;) (interface "foo:foo/just-export") (component (type 2))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "world-top-level" "pkg:/world-top-level" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/world-top-level.wit b/crates/wit-component/tests/interfaces/world-top-level.wit index 58e891e17c..c3107da91c 100644 --- a/crates/wit-component/tests/interfaces/world-top-level.wit +++ b/crates/wit-component/tests/interfaces/world-top-level.wit @@ -1,3 +1,5 @@ +package foo:foo + world foo { import foo: func() export foo2: func() diff --git a/crates/wit-component/tests/interfaces/world-top-level.wit.print b/crates/wit-component/tests/interfaces/world-top-level.wit.print index a5249ac837..d602d16218 100644 --- a/crates/wit-component/tests/interfaces/world-top-level.wit.print +++ b/crates/wit-component/tests/interfaces/world-top-level.wit.print @@ -1,9 +1,5 @@ -world just-import { - import foo: func() -} -world just-export { - export foo: func() -} +package foo:foo + world foo { import some-interface: interface { } @@ -14,3 +10,9 @@ world foo { export foo2: func() export bar2: func() -> u32 } +world just-import { + import foo: func() +} +world just-export { + export foo: func() +} diff --git a/crates/wit-component/tests/interfaces/worlds-with-types.wat b/crates/wit-component/tests/interfaces/worlds-with-types.wat index 6232f86360..8b8d3bdd9d 100644 --- a/crates/wit-component/tests/interfaces/worlds-with-types.wat +++ b/crates/wit-component/tests/interfaces/worlds-with-types.wat @@ -7,8 +7,19 @@ (export (;1;) "foo" (type (eq 0))) ) ) - (export (;0;) "import-me" "pkg:/worlds-with-types/import-me" (instance (type 0))) + (export (;0;) (interface "foo:foo/import-me") (instance (type 0))) (type (;1;) + (component + (type (;0;) (record)) + (import "foo" (type (;1;) (eq 0))) + (import "bar" (type (;2;) (eq 1))) + (type (;3;) (func (param "a" 1) (result 2))) + (import "a" (func (;0;) (type 3))) + (export (;1;) "b" (func (type 3))) + ) + ) + (export (;0;) (interface "foo:foo/simple") (component (type 1))) + (type (;2;) (component (type (;0;) (instance @@ -16,7 +27,7 @@ (export (;1;) "foo" (type (eq 0))) ) ) - (import "import-me" "pkg:/worlds-with-types/import-me" (instance (;0;) (type 0))) + (import (interface "foo:foo/import-me") (instance (;0;) (type 0))) (alias export 0 "foo" (type (;1;))) (import "foo" (type (;2;) (eq 1))) (type (;3;) (func (param "a" 2))) @@ -24,22 +35,11 @@ (export (;1;) "b" (func (type 3))) ) ) - (export (;0;) "with-imports" "pkg:/worlds-with-types/with-imports" (component (type 1))) - (type (;2;) - (component - (type (;0;) (record)) - (import "foo" (type (;1;) (eq 0))) - (import "bar" (type (;2;) (eq 1))) - (type (;3;) (func (param "a" 1) (result 2))) - (import "a" (func (;0;) (type 3))) - (export (;1;) "b" (func (type 3))) - ) - ) - (export (;1;) "simple" "pkg:/worlds-with-types/simple" (component (type 2))) + (export (;1;) (interface "foo:foo/with-imports") (component (type 2))) ) ) (@producers (processed-by "wit-component" "$CARGO_PKG_VERSION") ) - (export (;1;) "worlds-with-types" "pkg:/worlds-with-types" (type 0)) + (export (;1;) (interface "foo:foo/wit") (type 0)) ) \ No newline at end of file diff --git a/crates/wit-component/tests/interfaces/worlds-with-types.wit b/crates/wit-component/tests/interfaces/worlds-with-types.wit index d114243597..44fc574dc6 100644 --- a/crates/wit-component/tests/interfaces/worlds-with-types.wit +++ b/crates/wit-component/tests/interfaces/worlds-with-types.wit @@ -1,3 +1,5 @@ +package foo:foo + world simple { record foo { } @@ -13,7 +15,7 @@ interface import-me { } world with-imports { - use self.import-me.{foo} + use import-me.{foo} import a: func(a: foo) export b: func(a: foo) diff --git a/crates/wit-component/tests/interfaces/worlds-with-types.wit.print b/crates/wit-component/tests/interfaces/worlds-with-types.wit.print index 931274fd83..683f72935b 100644 --- a/crates/wit-component/tests/interfaces/worlds-with-types.wit.print +++ b/crates/wit-component/tests/interfaces/worlds-with-types.wit.print @@ -1,14 +1,10 @@ +package foo:foo + interface import-me { type foo = u32 } -world with-imports { - import import-me: self.import-me - import a: func(a: foo) - use self.import-me.{foo} - export b: func(a: foo) -} world simple { import a: func(a: foo) -> bar record foo { @@ -18,3 +14,9 @@ world simple { export b: func(a: foo) -> bar } +world with-imports { + import import-me + import a: func(a: foo) + use import-me.{foo} + export b: func(a: foo) +} diff --git a/crates/wit-component/tests/merge.rs b/crates/wit-component/tests/merge.rs index 94b1b46c91..c56570abab 100644 --- a/crates/wit-component/tests/merge.rs +++ b/crates/wit-component/tests/merge.rs @@ -2,7 +2,7 @@ use anyhow::{Context, Result}; use pretty_assertions::assert_eq; use std::collections::HashSet; use std::{fs, path::Path}; -use wit_component::DocumentPrinter; +use wit_component::WitPrinter; use wit_parser::{Resolve, TypeOwner, WorldItem}; /// This is a test which iterates over the `tests/merge` directory and treats @@ -42,16 +42,13 @@ fn merging() -> Result<()> { "should have failed to merge" ); assert_valid_resolve(&into); - for (_id, pkg) in into.packages.iter() { - for (name, doc) in pkg.documents.iter() { - let expected = path - .join("merge") - .join(&pkg.name) - .join(name) - .with_extension("wit"); - let output = DocumentPrinter::default().print(&into, *doc)?; - assert_output(&expected, &output)?; - } + for (id, pkg) in into.packages.iter() { + let expected = path + .join("merge") + .join(&pkg.name.name) + .with_extension("wit"); + let output = WitPrinter::default().print(&into, id)?; + assert_output(&expected, &output)?; } } Err(e) => { @@ -82,53 +79,32 @@ fn assert_output(expected: &Path, actual: &str) -> Result<()> { } fn assert_valid_resolve(resolve: &Resolve) { - let mut package_documents = Vec::new(); - for (id, package) in resolve.packages.iter() { - for (name, doc) in package.documents.iter() { - let doc = &resolve.documents[*doc]; - assert_eq!(*name, doc.name); - assert_eq!(doc.package, Some(id)); - } - package_documents.push(package.documents.values().copied().collect::>()); - } - - let mut document_interfaces = Vec::new(); - let mut document_worlds = Vec::new(); - for (id, doc) in resolve.documents.iter() { - if let Some(pkgid) = doc.package { - assert!(resolve.packages.get(pkgid).is_some()); - assert!(package_documents[pkgid.index()].contains(&id)); - } + let mut package_interfaces = Vec::new(); + let mut package_worlds = Vec::new(); + for (id, pkg) in resolve.packages.iter() { let mut interfaces = HashSet::new(); - for (name, iface) in doc.interfaces.iter() { + for (name, iface) in pkg.interfaces.iter() { assert!(interfaces.insert(*iface)); let iface = &resolve.interfaces[*iface]; assert_eq!(name, iface.name.as_ref().unwrap()); - assert_eq!(iface.document, id); + assert_eq!(iface.package.unwrap(), id); } - document_interfaces.push(doc.interfaces.values().copied().collect::>()); + package_interfaces.push(pkg.interfaces.values().copied().collect::>()); let mut worlds = HashSet::new(); - for (name, world) in doc.worlds.iter() { + for (name, world) in pkg.worlds.iter() { assert!(worlds.insert(*world)); let world = &resolve.worlds[*world]; assert_eq!(*name, world.name); - assert_eq!(world.document, id); - } - document_worlds.push(doc.worlds.values().copied().collect::>()); - - if let Some(id) = doc.default_interface { - assert!(interfaces.contains(&id)); - } - if let Some(id) = doc.default_world { - assert!(worlds.contains(&id)); + assert_eq!(world.package.unwrap(), id); } + package_worlds.push(pkg.worlds.values().copied().collect::>()); } let mut interface_types = Vec::new(); for (id, iface) in resolve.interfaces.iter() { - assert!(resolve.documents.get(iface.document).is_some()); + assert!(resolve.packages.get(iface.package.unwrap()).is_some()); if iface.name.is_some() { - assert!(document_interfaces[iface.document.index()].contains(&id)); + assert!(package_interfaces[iface.package.unwrap().index()].contains(&id)); } for (name, ty) in iface.types.iter() { @@ -144,20 +120,20 @@ fn assert_valid_resolve(resolve: &Resolve) { let mut world_types = Vec::new(); for (id, world) in resolve.worlds.iter() { - assert!(resolve.documents.get(world.document).is_some()); - assert!(document_worlds[world.document.index()].contains(&id)); + assert!(resolve.packages.get(world.package.unwrap()).is_some()); + assert!(package_worlds[world.package.unwrap().index()].contains(&id)); let mut types = HashSet::new(); for (name, item) in world.imports.iter().chain(world.exports.iter()) { match item { WorldItem::Interface(_) => {} WorldItem::Function(f) => { - assert_eq!(f.name, *name); + assert_eq!(f.name, name.clone().unwrap_name()); } WorldItem::Type(ty) => { assert!(types.insert(*ty)); let ty = &resolve.types[*ty]; - assert_eq!(ty.name.as_ref(), Some(name)); + assert_eq!(ty.name, Some(name.clone().unwrap_name())); assert_eq!(ty.owner, TypeOwner::World(id)); } } diff --git a/crates/wit-component/tests/merge/bad-interface1/error.txt b/crates/wit-component/tests/merge/bad-interface1/error.txt index 0fbe06bf28..951bb365d3 100644 --- a/crates/wit-component/tests/merge/bad-interface1/error.txt +++ b/crates/wit-component/tests/merge/bad-interface1/error.txt @@ -1,6 +1,5 @@ -failed to merge package `foo` into existing copy +failed to merge package `foo:foo` into existing copy Caused by: - 0: failed to merge document `a` into existing copy - 1: failed to merge interface `a` - 2: expected type `a` to be present \ No newline at end of file + 0: failed to merge interface `a` + 1: expected type `a` to be present \ No newline at end of file diff --git a/crates/wit-component/tests/merge/bad-interface1/from/a.wit b/crates/wit-component/tests/merge/bad-interface1/from/a.wit index e4ad26d3d7..9450b43251 100644 --- a/crates/wit-component/tests/merge/bad-interface1/from/a.wit +++ b/crates/wit-component/tests/merge/bad-interface1/from/a.wit @@ -1,3 +1,5 @@ +package foo:%from + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-interface1/from/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-interface1/from/deps/foo/a.wit index 27e826261a..9110557017 100644 --- a/crates/wit-component/tests/merge/bad-interface1/from/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-interface1/from/deps/foo/a.wit @@ -1,4 +1,5 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } - diff --git a/crates/wit-component/tests/merge/bad-interface1/into/a.wit b/crates/wit-component/tests/merge/bad-interface1/into/a.wit index a26bc50b92..d29a31d254 100644 --- a/crates/wit-component/tests/merge/bad-interface1/into/a.wit +++ b/crates/wit-component/tests/merge/bad-interface1/into/a.wit @@ -1,3 +1,5 @@ +package foo:into + interface a { - use foo.a.{b} + use foo:foo/a.{b} } diff --git a/crates/wit-component/tests/merge/bad-interface1/into/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-interface1/into/deps/foo/a.wit index dd381ab466..b8b88dd739 100644 --- a/crates/wit-component/tests/merge/bad-interface1/into/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-interface1/into/deps/foo/a.wit @@ -1,4 +1,6 @@ -default interface a { +package foo:foo + +interface a { type b = s32 } diff --git a/crates/wit-component/tests/merge/bad-interface2/error.txt b/crates/wit-component/tests/merge/bad-interface2/error.txt index 5f9d3ffa85..bbb5f232b2 100644 --- a/crates/wit-component/tests/merge/bad-interface2/error.txt +++ b/crates/wit-component/tests/merge/bad-interface2/error.txt @@ -1,6 +1,5 @@ -failed to merge package `foo` into existing copy +failed to merge package `foo:foo` into existing copy Caused by: - 0: failed to merge document `a` into existing copy - 1: failed to merge interface `a` - 2: expected function `a` to be present \ No newline at end of file + 0: failed to merge interface `a` + 1: expected function `a` to be present \ No newline at end of file diff --git a/crates/wit-component/tests/merge/bad-interface2/from/a.wit b/crates/wit-component/tests/merge/bad-interface2/from/a.wit index 199015ee5e..470e63ae93 100644 --- a/crates/wit-component/tests/merge/bad-interface2/from/a.wit +++ b/crates/wit-component/tests/merge/bad-interface2/from/a.wit @@ -1,3 +1,5 @@ +package foo:%from + interface a { - use foo.a.{t} + use foo:foo/a.{t} } diff --git a/crates/wit-component/tests/merge/bad-interface2/from/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-interface2/from/deps/foo/a.wit index 6e227228b2..2afd16d748 100644 --- a/crates/wit-component/tests/merge/bad-interface2/from/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-interface2/from/deps/foo/a.wit @@ -1,4 +1,6 @@ -default interface a { +package foo:foo + +interface a { type t = u32 a: func() diff --git a/crates/wit-component/tests/merge/bad-interface2/into/a.wit b/crates/wit-component/tests/merge/bad-interface2/into/a.wit index 199015ee5e..0e958da913 100644 --- a/crates/wit-component/tests/merge/bad-interface2/into/a.wit +++ b/crates/wit-component/tests/merge/bad-interface2/into/a.wit @@ -1,3 +1,5 @@ +package foo:into + interface a { - use foo.a.{t} + use foo:foo/a.{t} } diff --git a/crates/wit-component/tests/merge/bad-interface2/into/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-interface2/into/deps/foo/a.wit index ffacff0cb2..f9454dd6a6 100644 --- a/crates/wit-component/tests/merge/bad-interface2/into/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-interface2/into/deps/foo/a.wit @@ -1,4 +1,6 @@ -default interface a { +package foo:foo + +interface a { type t = u32 b: func() diff --git a/crates/wit-component/tests/merge/bad-world1/error.txt b/crates/wit-component/tests/merge/bad-world1/error.txt index 3f557f31e1..f04e2ed0c2 100644 --- a/crates/wit-component/tests/merge/bad-world1/error.txt +++ b/crates/wit-component/tests/merge/bad-world1/error.txt @@ -1,6 +1,5 @@ -failed to merge package `foo` into existing copy +failed to merge package `foo:foo` into existing copy Caused by: - 0: failed to merge document `a` into existing copy - 1: failed to merge world `foo` - 2: import `b` not found in target world \ No newline at end of file + 0: failed to merge world `foo` + 1: import `b` not found in target world \ No newline at end of file diff --git a/crates/wit-component/tests/merge/bad-world1/from/a.wit b/crates/wit-component/tests/merge/bad-world1/from/a.wit index e4ad26d3d7..7c17115280 100644 --- a/crates/wit-component/tests/merge/bad-world1/from/a.wit +++ b/crates/wit-component/tests/merge/bad-world1/from/a.wit @@ -1,3 +1,4 @@ +package foo:%from interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world1/from/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world1/from/deps/foo/a.wit index 806f2dff23..f57218402d 100644 --- a/crates/wit-component/tests/merge/bad-world1/from/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world1/from/deps/foo/a.wit @@ -1,7 +1,11 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } world foo { - import b: self.a + import b: interface { + type a = u32 + } } diff --git a/crates/wit-component/tests/merge/bad-world1/into/a.wit b/crates/wit-component/tests/merge/bad-world1/into/a.wit index e4ad26d3d7..435e17c2e4 100644 --- a/crates/wit-component/tests/merge/bad-world1/into/a.wit +++ b/crates/wit-component/tests/merge/bad-world1/into/a.wit @@ -1,3 +1,4 @@ +package foo:into interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world1/into/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world1/into/deps/foo/a.wit index a74effb045..9b324fb280 100644 --- a/crates/wit-component/tests/merge/bad-world1/into/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world1/into/deps/foo/a.wit @@ -1,7 +1,9 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } world foo { - import a: self.a + import a } diff --git a/crates/wit-component/tests/merge/bad-world2/error.txt b/crates/wit-component/tests/merge/bad-world2/error.txt index f85100543c..bca74e7b04 100644 --- a/crates/wit-component/tests/merge/bad-world2/error.txt +++ b/crates/wit-component/tests/merge/bad-world2/error.txt @@ -1,6 +1,5 @@ -failed to merge package `foo` into existing copy +failed to merge package `foo:foo` into existing copy Caused by: - 0: failed to merge document `a` into existing copy - 1: failed to merge world `foo` - 2: world contains different number of imports than expected \ No newline at end of file + 0: failed to merge world `foo` + 1: world contains different number of imports than expected \ No newline at end of file diff --git a/crates/wit-component/tests/merge/bad-world2/from/a.wit b/crates/wit-component/tests/merge/bad-world2/from/a.wit index e4ad26d3d7..9450b43251 100644 --- a/crates/wit-component/tests/merge/bad-world2/from/a.wit +++ b/crates/wit-component/tests/merge/bad-world2/from/a.wit @@ -1,3 +1,5 @@ +package foo:%from + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world2/from/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world2/from/deps/foo/a.wit index 48460f0c39..5ab008c826 100644 --- a/crates/wit-component/tests/merge/bad-world2/from/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world2/from/deps/foo/a.wit @@ -1,4 +1,6 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } diff --git a/crates/wit-component/tests/merge/bad-world2/into/a.wit b/crates/wit-component/tests/merge/bad-world2/into/a.wit index e4ad26d3d7..ed66a78180 100644 --- a/crates/wit-component/tests/merge/bad-world2/into/a.wit +++ b/crates/wit-component/tests/merge/bad-world2/into/a.wit @@ -1,3 +1,5 @@ +package foo:into + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world2/into/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world2/into/deps/foo/a.wit index a74effb045..9b324fb280 100644 --- a/crates/wit-component/tests/merge/bad-world2/into/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world2/into/deps/foo/a.wit @@ -1,7 +1,9 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } world foo { - import a: self.a + import a } diff --git a/crates/wit-component/tests/merge/bad-world3/error.txt b/crates/wit-component/tests/merge/bad-world3/error.txt index a427a9e472..daf6860fff 100644 --- a/crates/wit-component/tests/merge/bad-world3/error.txt +++ b/crates/wit-component/tests/merge/bad-world3/error.txt @@ -1,6 +1,5 @@ -failed to merge package `foo` into existing copy +failed to merge package `foo:foo` into existing copy Caused by: - 0: failed to merge document `a` into existing copy - 1: failed to merge world `foo` - 2: world contains different number of exports than expected \ No newline at end of file + 0: failed to merge world `foo` + 1: world contains different number of exports than expected \ No newline at end of file diff --git a/crates/wit-component/tests/merge/bad-world3/from/a.wit b/crates/wit-component/tests/merge/bad-world3/from/a.wit index e4ad26d3d7..9450b43251 100644 --- a/crates/wit-component/tests/merge/bad-world3/from/a.wit +++ b/crates/wit-component/tests/merge/bad-world3/from/a.wit @@ -1,3 +1,5 @@ +package foo:%from + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world3/from/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world3/from/deps/foo/a.wit index 48460f0c39..5ab008c826 100644 --- a/crates/wit-component/tests/merge/bad-world3/from/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world3/from/deps/foo/a.wit @@ -1,4 +1,6 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } diff --git a/crates/wit-component/tests/merge/bad-world3/into/a.wit b/crates/wit-component/tests/merge/bad-world3/into/a.wit index e4ad26d3d7..ed66a78180 100644 --- a/crates/wit-component/tests/merge/bad-world3/into/a.wit +++ b/crates/wit-component/tests/merge/bad-world3/into/a.wit @@ -1,3 +1,5 @@ +package foo:into + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world3/into/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world3/into/deps/foo/a.wit index 2e891eac5f..e287ffb7bb 100644 --- a/crates/wit-component/tests/merge/bad-world3/into/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world3/into/deps/foo/a.wit @@ -1,7 +1,9 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } world foo { - export a: self.a + export a } diff --git a/crates/wit-component/tests/merge/bad-world4/error.txt b/crates/wit-component/tests/merge/bad-world4/error.txt index e113a02ea1..5cf21c9247 100644 --- a/crates/wit-component/tests/merge/bad-world4/error.txt +++ b/crates/wit-component/tests/merge/bad-world4/error.txt @@ -1,6 +1,5 @@ -failed to merge package `foo` into existing copy +failed to merge package `foo:foo` into existing copy Caused by: - 0: failed to merge document `a` into existing copy - 1: failed to merge world `foo` - 2: export `b` not found in target world \ No newline at end of file + 0: failed to merge world `foo` + 1: export `b` not found in target world \ No newline at end of file diff --git a/crates/wit-component/tests/merge/bad-world4/from/a.wit b/crates/wit-component/tests/merge/bad-world4/from/a.wit index e4ad26d3d7..9450b43251 100644 --- a/crates/wit-component/tests/merge/bad-world4/from/a.wit +++ b/crates/wit-component/tests/merge/bad-world4/from/a.wit @@ -1,3 +1,5 @@ +package foo:%from + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world4/from/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world4/from/deps/foo/a.wit index 6a593a7e1c..6164abd1ca 100644 --- a/crates/wit-component/tests/merge/bad-world4/from/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world4/from/deps/foo/a.wit @@ -1,7 +1,11 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } world foo { - export b: self.a + export b: interface { + type a = u32 + } } diff --git a/crates/wit-component/tests/merge/bad-world4/into/a.wit b/crates/wit-component/tests/merge/bad-world4/into/a.wit index e4ad26d3d7..ed66a78180 100644 --- a/crates/wit-component/tests/merge/bad-world4/into/a.wit +++ b/crates/wit-component/tests/merge/bad-world4/into/a.wit @@ -1,3 +1,5 @@ +package foo:into + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world4/into/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world4/into/deps/foo/a.wit index 2e891eac5f..e287ffb7bb 100644 --- a/crates/wit-component/tests/merge/bad-world4/into/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world4/into/deps/foo/a.wit @@ -1,7 +1,9 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } world foo { - export a: self.a + export a } diff --git a/crates/wit-component/tests/merge/bad-world5/error.txt b/crates/wit-component/tests/merge/bad-world5/error.txt index 91b49b9396..9eb40e7551 100644 --- a/crates/wit-component/tests/merge/bad-world5/error.txt +++ b/crates/wit-component/tests/merge/bad-world5/error.txt @@ -1,7 +1,5 @@ -failed to merge package `foo` into existing copy +failed to merge package `foo:foo` into existing copy Caused by: - 0: failed to merge document `a` into existing copy - 1: failed to merge world `foo` - 2: import `a` didn't match target world - 3: interfaces are not the same \ No newline at end of file + 0: failed to merge world `foo` + 1: import `a` not found in target world \ No newline at end of file diff --git a/crates/wit-component/tests/merge/bad-world5/from/a.wit b/crates/wit-component/tests/merge/bad-world5/from/a.wit index e4ad26d3d7..9450b43251 100644 --- a/crates/wit-component/tests/merge/bad-world5/from/a.wit +++ b/crates/wit-component/tests/merge/bad-world5/from/a.wit @@ -1,3 +1,5 @@ +package foo:%from + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world5/from/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world5/from/deps/foo/a.wit index 88ee308faf..67333842c5 100644 --- a/crates/wit-component/tests/merge/bad-world5/from/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world5/from/deps/foo/a.wit @@ -1,4 +1,6 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } diff --git a/crates/wit-component/tests/merge/bad-world5/into/a.wit b/crates/wit-component/tests/merge/bad-world5/into/a.wit index e4ad26d3d7..ed66a78180 100644 --- a/crates/wit-component/tests/merge/bad-world5/into/a.wit +++ b/crates/wit-component/tests/merge/bad-world5/into/a.wit @@ -1,3 +1,5 @@ +package foo:into + interface a { - use foo.a.{a} + use foo:foo/a.{a} } diff --git a/crates/wit-component/tests/merge/bad-world5/into/deps/foo/a.wit b/crates/wit-component/tests/merge/bad-world5/into/deps/foo/a.wit index a74effb045..9b324fb280 100644 --- a/crates/wit-component/tests/merge/bad-world5/into/deps/foo/a.wit +++ b/crates/wit-component/tests/merge/bad-world5/into/deps/foo/a.wit @@ -1,7 +1,9 @@ -default interface a { +package foo:foo + +interface a { type a = u32 } world foo { - import a: self.a + import a } diff --git a/crates/wit-component/tests/merge/success/from/a.wit b/crates/wit-component/tests/merge/success/from/a.wit index 67cbcfc9e3..987aa763af 100644 --- a/crates/wit-component/tests/merge/success/from/a.wit +++ b/crates/wit-component/tests/merge/success/from/a.wit @@ -1,5 +1,7 @@ +package foo:%from + interface a { - use foo.only-from.only-from.{r} + use foo:foo/only-from.{r} foo: func() } diff --git a/crates/wit-component/tests/merge/success/from/deps/foo/shared.wit b/crates/wit-component/tests/merge/success/from/deps/foo/shared.wit index c0edd7054c..117aedad10 100644 --- a/crates/wit-component/tests/merge/success/from/deps/foo/shared.wit +++ b/crates/wit-component/tests/merge/success/from/deps/foo/shared.wit @@ -1,11 +1,13 @@ -interface only-from { +package foo:foo + +interface shared-only-from { variant v { c1, } bar: func(x: v) - use only-from-dep.a.{a} + use foo:only-from-dep/a.{a} } interface shared { @@ -13,9 +15,9 @@ interface shared { } world shared-world { - import a: self.shared + import shared - export b: self.shared + export shared type c = u32 diff --git a/crates/wit-component/tests/merge/success/from/deps/only-from-dep/a.wit b/crates/wit-component/tests/merge/success/from/deps/only-from-dep/a.wit index b2c77a17c4..ce3f3599aa 100644 --- a/crates/wit-component/tests/merge/success/from/deps/only-from-dep/a.wit +++ b/crates/wit-component/tests/merge/success/from/deps/only-from-dep/a.wit @@ -1,3 +1,5 @@ -default interface foo { +package foo:only-from-dep + +interface a { type a = u32 } diff --git a/crates/wit-component/tests/merge/success/into/b.wit b/crates/wit-component/tests/merge/success/into/b.wit index 44ee7aea90..df1292feb6 100644 --- a/crates/wit-component/tests/merge/success/into/b.wit +++ b/crates/wit-component/tests/merge/success/into/b.wit @@ -1,5 +1,7 @@ +package foo:into + interface b { - use foo.only-into.only-into.{r} + use foo:foo/only-into.{r} foo: func() } diff --git a/crates/wit-component/tests/merge/success/into/deps/foo/shared.wit b/crates/wit-component/tests/merge/success/into/deps/foo/shared.wit index cfa3eb14e4..1cbbce5705 100644 --- a/crates/wit-component/tests/merge/success/into/deps/foo/shared.wit +++ b/crates/wit-component/tests/merge/success/into/deps/foo/shared.wit @@ -1,4 +1,6 @@ -interface only-into { +package foo:foo + +interface shared-only-into { variant v { c1, } @@ -11,9 +13,9 @@ interface shared { } world shared-world { - import a: self.shared + import shared - export b: self.shared + export shared type c = u32 diff --git a/crates/wit-component/tests/merge/success/merge/foo/shared.wit b/crates/wit-component/tests/merge/success/merge/foo.wit similarity index 53% rename from crates/wit-component/tests/merge/success/merge/foo/shared.wit rename to crates/wit-component/tests/merge/success/merge/foo.wit index 68fb5714e1..a5d4f4e3ad 100644 --- a/crates/wit-component/tests/merge/success/merge/foo/shared.wit +++ b/crates/wit-component/tests/merge/success/merge/foo.wit @@ -1,18 +1,27 @@ +package foo:foo + +interface shared-only-into { + variant v { + c1, + } + + bar: func(x: v) +} + interface shared { type a = u32 } interface only-into { - variant v { - c1, + record r { } - bar: func(x: v) + foo: func() -> r } -interface only-from { - use only-from-dep.a.foo.{a} +interface shared-only-from { + use foo:only-from-dep/a.{a} variant v { c1, @@ -21,11 +30,18 @@ interface only-from { bar: func(x: v) } +interface only-from { + record r { + } + + foo: func() -> r +} + world shared-world { - import a: self.shared + import shared import d: interface { } type c = u32 - export b: self.shared + export shared } diff --git a/crates/wit-component/tests/merge/success/merge/foo/only-from.wit b/crates/wit-component/tests/merge/success/merge/foo/only-from.wit deleted file mode 100644 index f8258177a0..0000000000 --- a/crates/wit-component/tests/merge/success/merge/foo/only-from.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface only-from { - record r { - } - - foo: func() -> r -} - diff --git a/crates/wit-component/tests/merge/success/merge/foo/only-into.wit b/crates/wit-component/tests/merge/success/merge/foo/only-into.wit deleted file mode 100644 index ae159a367c..0000000000 --- a/crates/wit-component/tests/merge/success/merge/foo/only-into.wit +++ /dev/null @@ -1,7 +0,0 @@ -interface only-into { - record r { - } - - foo: func() -> r -} - diff --git a/crates/wit-component/tests/merge/success/merge/from.wit b/crates/wit-component/tests/merge/success/merge/from.wit new file mode 100644 index 0000000000..8720527126 --- /dev/null +++ b/crates/wit-component/tests/merge/success/merge/from.wit @@ -0,0 +1,7 @@ +package foo:%from + +interface a { + use foo:foo/only-from.{r} + foo: func() +} + diff --git a/crates/wit-component/tests/merge/success/merge/from/a.wit b/crates/wit-component/tests/merge/success/merge/from/a.wit deleted file mode 100644 index 09f2ae02d6..0000000000 --- a/crates/wit-component/tests/merge/success/merge/from/a.wit +++ /dev/null @@ -1,5 +0,0 @@ -interface a { - use foo.only-from.only-from.{r} - foo: func() -} - diff --git a/crates/wit-component/tests/merge/success/merge/into.wit b/crates/wit-component/tests/merge/success/merge/into.wit new file mode 100644 index 0000000000..55e4b952e0 --- /dev/null +++ b/crates/wit-component/tests/merge/success/merge/into.wit @@ -0,0 +1,7 @@ +package foo:into + +interface b { + use foo:foo/only-into.{r} + foo: func() +} + diff --git a/crates/wit-component/tests/merge/success/merge/into/b.wit b/crates/wit-component/tests/merge/success/merge/into/b.wit deleted file mode 100644 index fe57f4668b..0000000000 --- a/crates/wit-component/tests/merge/success/merge/into/b.wit +++ /dev/null @@ -1,5 +0,0 @@ -interface b { - use foo.only-into.only-into.{r} - foo: func() -} - diff --git a/crates/wit-component/tests/merge/success/merge/only-from-dep.wit b/crates/wit-component/tests/merge/success/merge/only-from-dep.wit new file mode 100644 index 0000000000..fa8b3336ef --- /dev/null +++ b/crates/wit-component/tests/merge/success/merge/only-from-dep.wit @@ -0,0 +1,7 @@ +package foo:only-from-dep + +interface a { + type a = u32 + +} + diff --git a/crates/wit-component/tests/merge/success/merge/only-from-dep/a.wit b/crates/wit-component/tests/merge/success/merge/only-from-dep/a.wit deleted file mode 100644 index bac7278001..0000000000 --- a/crates/wit-component/tests/merge/success/merge/only-from-dep/a.wit +++ /dev/null @@ -1,5 +0,0 @@ -default interface foo { - type a = u32 - -} - diff --git a/crates/wit-parser/Cargo.toml b/crates/wit-parser/Cargo.toml index 3fa880e5d4..83915aea4a 100644 --- a/crates/wit-parser/Cargo.toml +++ b/crates/wit-parser/Cargo.toml @@ -20,6 +20,7 @@ pulldown-cmark = { version = "0.8", default-features = false } unicode-xid = "0.2.2" log = { workspace = true } url = { workspace = true } +semver = { workspace = true } [dev-dependencies] rayon = "1" diff --git a/crates/wit-parser/src/ast.rs b/crates/wit-parser/src/ast.rs index c2a93ae2a1..329440a789 100644 --- a/crates/wit-parser/src/ast.rs +++ b/crates/wit-parser/src/ast.rs @@ -1,6 +1,7 @@ use crate::{Error, UnresolvedPackage}; use anyhow::{bail, Context, Result}; use lex::{Span, Token, Tokenizer}; +use semver::Version; use std::borrow::Cow; use std::convert::TryFrom; use std::fmt; @@ -15,22 +16,27 @@ pub mod toposort; pub use lex::validate_id; pub struct Ast<'a> { - pub items: Vec>, + package_id: Option>, + items: Vec>, } impl<'a> Ast<'a> { pub fn parse(lexer: &mut Tokenizer<'a>) -> Result { let mut items = Vec::new(); + let mut package_id = None; + if lexer.eat(Token::Package)? { + package_id = Some(PackageName::parse(lexer)?); + } while lexer.clone().next()?.is_some() { let docs = parse_docs(lexer)?; items.push(AstItem::parse(lexer, docs)?); } - Ok(Self { items }) + Ok(Self { package_id, items }) } fn for_each_path<'b>( &'b self, - mut f: impl FnMut(Option<&'b Id<'a>>, &'b UsePath<'a>, Option<&[UseName<'a>]>) -> Result<()>, + mut f: impl FnMut(Option<&'b Id<'a>>, &'b UsePath<'a>, Option<&'b [UseName<'a>]>) -> Result<()>, ) -> Result<()> { for item in self.items.iter() { match item { @@ -61,7 +67,7 @@ impl<'a> Ast<'a> { Ok(()) } ExternKind::Path(path) => f(None, path, None), - ExternKind::Func(_) => Ok(()), + ExternKind::Func(..) => Ok(()), }; for kind in imports { @@ -79,51 +85,99 @@ impl<'a> Ast<'a> { } } } + AstItem::Use(u) => { + f(None, &u.item, None)?; + } } } Ok(()) } } -pub enum AstItem<'a> { +enum AstItem<'a> { Interface(Interface<'a>), World(World<'a>), + Use(ToplevelUse<'a>), } impl<'a> AstItem<'a> { fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result { - let mut clone = tokens.clone(); - let token = match clone.next()? { - Some((_span, Token::Default)) => clone.next()?, - other => other, - }; - match token { + match tokens.clone().next()? { Some((_span, Token::Interface)) => Interface::parse(tokens, docs).map(Self::Interface), Some((_span, Token::World)) => World::parse(tokens, docs).map(Self::World), - other => Err(err_expected(tokens, "`default`, `world` or `interface`", other).into()), + Some((_span, Token::Use)) => ToplevelUse::parse(tokens).map(Self::Use), + other => Err(err_expected(tokens, "`world`, `interface` or `use`", other).into()), + } + } +} + +#[derive(Debug, Clone)] +struct PackageName<'a> { + span: Span, + namespace: Id<'a>, + name: Id<'a>, + version: Option<(Span, Version)>, +} + +impl<'a> PackageName<'a> { + fn parse(tokens: &mut Tokenizer<'a>) -> Result { + let namespace = parse_id(tokens)?; + tokens.expect(Token::Colon)?; + let name = parse_id(tokens)?; + let version = parse_opt_version(tokens)?; + Ok(PackageName { + span: Span { + start: namespace.span.start, + end: version + .as_ref() + .map(|(s, _)| s.end) + .unwrap_or(name.span.end), + }, + namespace, + name, + version, + }) + } + + fn package_name(&self) -> crate::PackageName { + crate::PackageName { + namespace: self.namespace.name.to_string(), + name: self.name.name.to_string(), + version: self.version.as_ref().map(|(_, v)| v.clone()), } } } -pub struct World<'a> { +struct ToplevelUse<'a> { + item: UsePath<'a>, + as_: Option>, +} + +impl<'a> ToplevelUse<'a> { + fn parse(tokens: &mut Tokenizer<'a>) -> Result { + tokens.expect(Token::Use)?; + let item = UsePath::parse(tokens)?; + let as_ = if tokens.eat(Token::As)? { + Some(parse_id(tokens)?) + } else { + None + }; + Ok(ToplevelUse { item, as_ }) + } +} + +struct World<'a> { docs: Docs<'a>, name: Id<'a>, items: Vec>, - default: bool, } impl<'a> World<'a> { fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result { - let default = tokens.eat(Token::Default)?; tokens.expect(Token::World)?; let name = parse_id(tokens)?; let items = Self::parse_items(tokens)?; - Ok(World { - docs, - name, - items, - default, - }) + Ok(World { docs, name, items }) } fn parse_items(tokens: &mut Tokenizer<'a>) -> Result>> { @@ -140,7 +194,7 @@ impl<'a> World<'a> { } } -pub enum WorldItem<'a> { +enum WorldItem<'a> { Import(Import<'a>), Export(Export<'a>), Use(Use<'a>), @@ -173,80 +227,92 @@ impl<'a> WorldItem<'a> { } } -pub struct Import<'a> { +struct Import<'a> { docs: Docs<'a>, - name: Id<'a>, kind: ExternKind<'a>, } impl<'a> Import<'a> { fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result> { tokens.expect(Token::Import)?; - let name = parse_id(tokens)?; - tokens.expect(Token::Colon)?; let kind = ExternKind::parse(tokens)?; - Ok(Import { docs, name, kind }) + Ok(Import { docs, kind }) } } -pub struct Export<'a> { +struct Export<'a> { docs: Docs<'a>, - name: Id<'a>, kind: ExternKind<'a>, } impl<'a> Export<'a> { fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result> { tokens.expect(Token::Export)?; - let name = parse_id(tokens)?; - tokens.expect(Token::Colon)?; let kind = ExternKind::parse(tokens)?; - Ok(Export { docs, name, kind }) + Ok(Export { docs, kind }) } } -pub enum ExternKind<'a> { - Interface(Span, Vec>), +enum ExternKind<'a> { + Interface(Id<'a>, Vec>), Path(UsePath<'a>), - Func(Func<'a>), + Func(Id<'a>, Func<'a>), } impl<'a> ExternKind<'a> { fn parse(tokens: &mut Tokenizer<'a>) -> Result> { - match tokens.clone().next()? { - Some((_span, Token::Id | Token::ExplicitId | Token::Pkg | Token::Self_)) => { - UsePath::parse(tokens).map(ExternKind::Path) + // Create a copy of the token stream to test out if this is a function + // or an interface import. In those situations the token stream gets + // reset to the state of the clone and we continue down those paths. + // + // If neither a function nor an interface appears here though then the + // clone is thrown away and the original token stream is parsed for an + // interface. This will redo the original ID parse and the original + // colon parse, but that shouldn't be too too bad perf-wise. + let mut clone = tokens.clone(); + let id = parse_id(&mut clone)?; + if clone.eat(Token::Colon)? { + // import foo: func(...) + if clone.clone().eat(Token::Func)? { + *tokens = clone; + return Ok(ExternKind::Func(id, Func::parse(tokens)?)); } - Some((_span, Token::Interface)) => { - let span = tokens.expect(Token::Interface)?; - let items = Interface::parse_items(tokens)?; - Ok(ExternKind::Interface(span, items)) + + // import foo: interface { ... } + if clone.eat(Token::Interface)? { + *tokens = clone; + return Ok(ExternKind::Interface(id, Interface::parse_items(tokens)?)); } - Some((_span, Token::Func)) => Ok(ExternKind::Func(Func::parse(tokens)?)), - other => Err(err_expected(tokens, "path, value, or interface", other).into()), + } + + // import foo + // import foo/bar + // import foo:bar/baz + Ok(ExternKind::Path(UsePath::parse(tokens)?)) + } + + fn span(&self) -> Span { + match self { + ExternKind::Interface(id, _) => id.span, + ExternKind::Path(UsePath::Id(id)) => id.span, + ExternKind::Path(UsePath::Package { name, .. }) => name.span, + ExternKind::Func(id, _) => id.span, } } } -pub struct Interface<'a> { +struct Interface<'a> { docs: Docs<'a>, name: Id<'a>, items: Vec>, - default: bool, } impl<'a> Interface<'a> { fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result { - let default = tokens.eat(Token::Default)?; tokens.expect(Token::Interface)?; let name = parse_id(tokens)?; let items = Self::parse_items(tokens)?; - Ok(Interface { - docs, - name, - items, - default, - }) + Ok(Interface { docs, name, items }) } pub(super) fn parse_items(tokens: &mut Tokenizer<'a>) -> Result>> { @@ -263,33 +329,62 @@ impl<'a> Interface<'a> { } } -pub enum InterfaceItem<'a> { +enum InterfaceItem<'a> { TypeDef(TypeDef<'a>), Value(Value<'a>), Use(Use<'a>), } -pub struct Use<'a> { - pub from: UsePath<'a>, - pub names: Vec>, +struct Use<'a> { + from: UsePath<'a>, + names: Vec>, } -pub enum UsePath<'a> { - Self_(Id<'a>), - Package { - doc: Id<'a>, - iface: Option>, - }, - Dependency { - dep: Id<'a>, - doc: Id<'a>, - iface: Option>, - }, +#[derive(Debug)] +enum UsePath<'a> { + Id(Id<'a>), + Package { id: PackageName<'a>, name: Id<'a> }, } -pub struct UseName<'a> { - pub name: Id<'a>, - pub as_: Option>, +impl<'a> UsePath<'a> { + fn parse(tokens: &mut Tokenizer<'a>) -> Result { + let id = parse_id(tokens)?; + if tokens.eat(Token::Colon)? { + // `foo:bar/baz@1.0` + let namespace = id; + let pkg_name = parse_id(tokens)?; + tokens.expect(Token::Slash)?; + let name = parse_id(tokens)?; + let version = parse_opt_version(tokens)?; + Ok(UsePath::Package { + id: PackageName { + span: Span { + start: namespace.span.start, + end: pkg_name.span.end, + }, + namespace, + name: pkg_name, + version, + }, + name, + }) + } else { + // `foo` + Ok(UsePath::Id(id)) + } + } + + fn name(&self) -> &Id<'a> { + match self { + UsePath::Id(id) => id, + UsePath::Package { name, .. } => name, + } + } +} + +struct UseName<'a> { + name: Id<'a>, + as_: Option>, } impl<'a> Use<'a> { @@ -318,50 +413,10 @@ impl<'a> Use<'a> { } } -impl<'a> UsePath<'a> { - fn parse(tokens: &mut Tokenizer<'a>) -> Result { - match tokens.clone().next()? { - Some((_span, Token::Self_)) => { - tokens.expect(Token::Self_)?; - tokens.expect(Token::Period)?; - let name = parse_id(tokens)?; - Ok(UsePath::Self_(name)) - } - Some((_span, Token::Pkg)) => { - tokens.expect(Token::Pkg)?; - tokens.expect(Token::Period)?; - let doc = parse_id(tokens)?; - let mut clone = tokens.clone(); - let iface = if clone.eat(Token::Period)? && !clone.eat(Token::LeftBrace)? { - tokens.expect(Token::Period)?; - Some(parse_id(tokens)?) - } else { - None - }; - Ok(UsePath::Package { doc, iface }) - } - Some((_span, Token::Id | Token::ExplicitId)) => { - let dep = parse_id(tokens)?; - tokens.expect(Token::Period)?; - let doc = parse_id(tokens)?; - let mut clone = tokens.clone(); - let iface = if clone.eat(Token::Period)? && !clone.eat(Token::LeftBrace)? { - tokens.expect(Token::Period)?; - Some(parse_id(tokens)?) - } else { - None - }; - Ok(UsePath::Dependency { dep, doc, iface }) - } - other => return Err(err_expected(tokens, "`self`, `pkg`, or identifier", other).into()), - } - } -} - #[derive(Debug, Clone)] pub struct Id<'a> { - pub name: &'a str, - pub span: Span, + name: &'a str, + span: Span, } impl<'a> From<&'a str> for Id<'a> { @@ -378,7 +433,7 @@ pub struct Docs<'a> { docs: Vec>, } -pub struct TypeDef<'a> { +struct TypeDef<'a> { docs: Docs<'a>, name: Id<'a>, ty: Type<'a>, @@ -462,7 +517,7 @@ struct Stream<'a> { end: Option>>, } -pub struct Value<'a> { +struct Value<'a> { docs: Docs<'a>, name: Id<'a>, kind: ValueKind<'a>, @@ -489,7 +544,7 @@ enum ValueKind<'a> { Func(Func<'a>), } -pub struct Func<'a> { +struct Func<'a> { params: ParamList<'a>, results: ResultList<'a>, } @@ -691,6 +746,56 @@ fn parse_id<'a>(tokens: &mut Tokenizer<'a>) -> Result> { } } +fn parse_opt_version(tokens: &mut Tokenizer<'_>) -> Result> { + if !tokens.eat(Token::At)? { + return Ok(None); + } + let start = tokens.expect(Token::Integer)?.start; + tokens.expect(Token::Period)?; + tokens.expect(Token::Integer)?; + tokens.expect(Token::Period)?; + let end = tokens.expect(Token::Integer)?.end; + let mut span = Span { start, end }; + eat_ids(tokens, Token::Minus, &mut span)?; + eat_ids(tokens, Token::Plus, &mut span)?; + let string = tokens.get_span(span); + let version = Version::parse(string).map_err(|e| Error { + span, + msg: e.to_string(), + })?; + return Ok(Some((span, version))); + + fn eat_ids(tokens: &mut Tokenizer<'_>, prefix: Token, end: &mut Span) -> Result<()> { + if !tokens.eat(prefix)? { + return Ok(()); + } + loop { + match tokens.next()? { + Some((span, Token::Id)) | Some((span, Token::Integer)) => end.end = span.end, + other => break Err(err_expected(tokens, "an id or integer", other).into()), + } + + // If there's no trailing period, then this semver identifier is + // done. + let mut clone = tokens.clone(); + if !clone.eat(Token::Period)? { + break Ok(()); + } + + // If there's more to the identifier, then eat the period for real + // and continue + if clone.eat(Token::Id)? || clone.eat(Token::Integer)? { + tokens.eat(Token::Period)?; + continue; + } + + // Otherwise for something like `use foo:bar/baz@1.2.3+foo.{` stop + // the parsing here. + break Ok(()); + } + } +} + fn parse_docs<'a>(tokens: &mut Tokenizer<'a>) -> Result> { let mut docs = Docs::default(); let mut clone = tokens.clone(); @@ -894,7 +999,6 @@ pub struct SourceMap { struct Source { offset: u32, path: PathBuf, - name: String, contents: String, } @@ -906,32 +1010,21 @@ impl SourceMap { /// Reads the file `path` on the filesystem and appends its contents to this /// [`SourceMap`]. - /// - /// This method pushes a new document into the source map. The name of the - /// document is derived from the filename of the `path` provided. pub fn push_file(&mut self, path: &Path) -> Result<()> { let contents = std::fs::read_to_string(path) .with_context(|| format!("failed to read file {path:?}"))?; - let filename = match path.file_name().and_then(|s| s.to_str()) { - Some(stem) => stem, - None => bail!("no filename for {path:?}"), - }; - let name = match filename.find('.') { - Some(i) => &filename[..i], - None => filename, - }; - self.push(path, name, contents); + self.push(path, contents); Ok(()) } /// Appends the given contents with the given path into this source map. /// - /// Each path added to a [`SourceMap`] will become a document in the final - /// package. The `path` provided is not read from the filesystem and is - /// instead only used during error messages. The `name` provided is the name - /// of the document within the WIT package and must be a valid WIT - /// identifier. - pub fn push(&mut self, path: &Path, name: &str, contents: impl Into) { + /// The `path` provided is not read from the filesystem and is instead only + /// used during error messages. Each file added to a [`SourceMap`] is + /// used to create the final parsed package namely by unioning all the + /// interfaces and worlds defined together. Note that each file has its own + /// personal namespace, however, for top-level `use` and such. + pub fn push(&mut self, path: &Path, contents: impl Into) { let mut contents = contents.into(); if path.extension().and_then(|s| s.to_str()) == Some("md") { log::debug!("automatically unwrapping markdown container"); @@ -942,7 +1035,6 @@ impl SourceMap { offset: self.offset, path: path.to_path_buf(), contents, - name: name.to_string(), }); self.offset = new_offset; @@ -985,23 +1077,20 @@ impl SourceMap { } /// Parses the files added to this source map into an [`UnresolvedPackage`]. - /// - /// All files previously added are considered documents of the package to be - /// returned. - pub fn parse(self, name: &str, url: Option<&str>) -> Result { + pub fn parse(self) -> Result { let mut doc = self.rewrite_error(|| { let mut resolver = Resolver::default(); let mut srcs = self.sources.iter().collect::>(); - srcs.sort_by_key(|src| &src.name); + srcs.sort_by_key(|src| &src.path); for src in srcs { let mut tokens = Tokenizer::new(&src.contents, src.offset) .with_context(|| format!("failed to tokenize path: {}", src.path.display()))?; let ast = Ast::parse(&mut tokens)?; - resolver.push(&src.name, ast).with_context(|| { + resolver.push(ast).with_context(|| { format!("failed to start resolving path: {}", src.path.display()) })?; } - resolver.resolve(name, url) + resolver.resolve() })?; doc.source_map = self; Ok(doc) @@ -1097,3 +1186,22 @@ impl SourceMap { self.sources.iter().map(|src| src.path.as_path()) } } + +pub(crate) enum AstUsePath { + Name(String), + Package(crate::PackageName, String), +} + +pub(crate) fn parse_use_path(s: &str) -> Result { + let mut tokens = Tokenizer::new(s, 0)?; + let path = UsePath::parse(&mut tokens)?; + if tokens.next()?.is_some() { + bail!("trailing tokens in path specifier"); + } + Ok(match path { + UsePath::Id(id) => AstUsePath::Name(id.name.to_string()), + UsePath::Package { id, name } => { + AstUsePath::Package(id.package_name(), name.name.to_string()) + } + }) +} diff --git a/crates/wit-parser/src/ast/lex.rs b/crates/wit-parser/src/ast/lex.rs index 5023a854a9..4c79c37bc8 100644 --- a/crates/wit-parser/src/ast/lex.rs +++ b/crates/wit-parser/src/ast/lex.rs @@ -46,6 +46,10 @@ pub enum Token { GreaterThan, RArrow, Star, + At, + Slash, + Plus, + Minus, Use, Type, @@ -79,16 +83,15 @@ pub enum Token { Static, Interface, Tuple, - Implements, Import, Export, World, - Default, - Pkg, - Self_, + Package, Id, ExplicitId, + + Integer, } #[derive(Eq, PartialEq, Debug)] @@ -174,6 +177,7 @@ impl<'a> Tokenizer<'a> { break; } } + Comment // eat a block comment if it's `/*...` } else if self.eatc('*') { let mut depth = 1; @@ -188,11 +192,10 @@ impl<'a> Tokenizer<'a> { _ => {} } } + Comment } else { - return Err(Error::Unexpected(start, ch)); + Slash } - - Comment } '=' => Equals, ',' => Comma, @@ -206,13 +209,15 @@ impl<'a> Tokenizer<'a> { '<' => LessThan, '>' => GreaterThan, '*' => Star, + '@' => At, '-' => { if self.eatc('>') { RArrow } else { - return Err(Error::Unexpected(start, '-')); + Minus } } + '+' => Plus, '%' => { let mut iter = self.chars.clone(); if let Some((_, ch)) = iter.next() { @@ -272,16 +277,26 @@ impl<'a> Tokenizer<'a> { "static" => Static, "interface" => Interface, "tuple" => Tuple, - "implements" => Implements, "world" => World, "import" => Import, "export" => Export, - "default" => Default, - "pkg" => Pkg, - "self" => Self_, + "package" => Package, _ => Id, } } + + ch if ch.is_ascii_digit() => { + let mut iter = self.chars.clone(); + while let Some((_, ch)) = iter.next() { + if !ch.is_ascii_digit() { + break; + } + self.chars = iter.clone(); + } + + Integer + } + ch => return Err(Error::Unexpected(start, ch)), }; let end = match self.chars.clone().next() { @@ -504,18 +519,20 @@ impl Token { ExplicitId => "an '%' identifier", RArrow => "`->`", Star => "`*`", + At => "`@`", + Slash => "`/`", + Plus => "`+`", + Minus => "`-`", As => "keyword `as`", From_ => "keyword `from`", Static => "keyword `static`", Interface => "keyword `interface`", Tuple => "keyword `tuple`", - Implements => "keyword `implements`", Import => "keyword `import`", Export => "keyword `export`", World => "keyword `world`", - Default => "keyword `default`", - Self_ => "keyword `self`", - Pkg => "keyword `pkg`", + Package => "keyword `package`", + Integer => "an integer", } } } diff --git a/crates/wit-parser/src/ast/resolve.rs b/crates/wit-parser/src/ast/resolve.rs index ba499cb532..08505fa645 100644 --- a/crates/wit-parser/src/ast/resolve.rs +++ b/crates/wit-parser/src/ast/resolve.rs @@ -1,34 +1,80 @@ use super::{Error, ParamList, ResultList, ValueKind}; use crate::ast::toposort::toposort; use crate::*; -use anyhow::{anyhow, bail, Result}; +use anyhow::{bail, Result}; use indexmap::IndexMap; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::mem; #[derive(Default)] pub struct Resolver<'a> { - asts: IndexMap<&'a str, ast::Ast<'a>>, + /// Current package named learned through the ASTs pushed onto this resolver. + package_name: Option, + + /// All WIT files which are going to be resolved together. + asts: Vec>, + + // Arenas that get plumbed to the final `UnresolvedPackage` types: Arena, - anon_types: HashMap, interfaces: Arena, - documents: Arena, worlds: Arena, - document_lookup: IndexMap<&'a str, DocumentId>, - document_interfaces: Vec>, + + // Interning structure for types which-need-not-be-named such as + // `list` and such. + anon_types: HashMap, + + /// The index within `self.ast_items` that lookups should go through. This + /// is updated as the ASTs are walked. + cur_ast_index: usize, + + /// A map per `ast::Ast` which keeps track of the file's top level names in + /// scope. This maps each name onto either a world or an interface, handling + /// things like `use` at the top level. + ast_items: Vec>, + + /// A map for the entire package being created of all names defined within, + /// along with the ID they're mapping to. + package_items: IndexMap<&'a str, AstItem>, + + /// A per-interface map of name to item-in-the-interface. This is the same + /// length as `self.types` and is pushed to whenever `self.types` is pushed + /// to. interface_types: Vec>, - foreign_deps: IndexMap<&'a str, IndexMap<&'a str, DocumentId>>, + + /// Metadata about foreign dependencies which are not defined in this + /// package. This map is keyed by the name of the package being imported + /// from. The next level of key is the name of the interface being imported + /// from, and the final value is the assigned ID of the interface. + foreign_deps: IndexMap>, + + /// All interfaces that are present within `self.foreign_deps`. + foreign_interfaces: HashSet, + + /// The current type lookup scope which will eventually make its way into + /// `self.interface_types`. type_lookup: IndexMap<&'a str, (TypeOrItem, Span)>, + /// An assigned span for where all types inserted into `self.types` as + /// imported from foreign interfaces. These types all show up first in the + /// `self.types` arena and this span is used to generate an error message + /// pointing to it if the item isn't actually defined. unknown_type_spans: Vec, + + /// Spans for each world in `self.world` to assign for each import/export + /// for later error reporting. world_spans: Vec<(Vec, Vec)>, - document_spans: Vec, + + /// The span of each interface's definition which is used for error + /// reporting during the final `Resolve` phase. interface_spans: Vec, + + /// Spans per entry in `self.foreign_deps` for where the dependency was + /// introduced to print an error message if necessary. foreign_dep_spans: Vec, } -#[derive(Copy, Clone)] -enum DocumentItem { +#[derive(Debug, Copy, Clone)] +enum AstItem { Interface(InterfaceId), World(WorldId), } @@ -59,71 +105,93 @@ enum TypeOrItem { } impl<'a> Resolver<'a> { - pub(crate) fn push(&mut self, name: &'a str, ast: ast::Ast<'a>) -> Result<()> { - // Note that this specifically uses `map_err` instead of `with_context` - // since the error returned from `validate_id` is an `Error` which has a - // filename and a line number, but there's no filename or line number - // associated with this error so we just want the string message. - crate::validate_id(name) - .map_err(|e| anyhow!("name of document isn't a valid WIT identifier `{name}`: {e}"))?; - - let prev = self.asts.insert(name, ast); - if prev.is_some() { - bail!("document `{name}` is defined more than once"); + pub(crate) fn push(&mut self, ast: ast::Ast<'a>) -> Result<()> { + // As each WIT file is pushed into this resolver keep track of the + // current package name assigned. Only one file needs to mention it, but + // if multiple mention it then they must all match. + if let Some(cur) = &ast.package_id { + let cur_name = cur.package_name(); + if let Some(prev) = &self.package_name { + if cur_name != *prev { + bail!(Error { + span: cur.span, + msg: format!( + "package identifier `{cur_name}` does not match \ + previous package name of `{prev}`" + ), + }) + } + } + self.package_name = Some(cur_name); } + self.asts.push(ast); Ok(()) } - pub(crate) fn resolve(&mut self, name: &str, url: Option<&str>) -> Result { - self.populate_foreign_deps(); + pub(crate) fn resolve(&mut self) -> Result { + // At least one of the WIT files must have a `package` annotation. + let name = match &self.package_name { + Some(name) => name.clone(), + None => bail!("no `package` header was found in any WIT file for this package"), + }; - // Determine the dependencies between documents in the current package - // we're parsing to perform a topological sort and how to visit the - // documents in order. - let mut doc_deps = IndexMap::new(); - for (name, ast) in self.asts.iter() { - let mut deps = Vec::new(); - ast.for_each_path(|_, path, _names| { - let doc = match path { - ast::UsePath::Package { doc, iface: _ } => doc, - _ => return Ok(()), - }; - // If this document imports from itself using `pkg` syntax - // that's ok and skip this dependency to prevent it from - // otherwise being flagged as cyclic. - if doc.name == *name { - return Ok(()); - } - deps.push(doc.clone()); - Ok(()) - }) - .unwrap(); + // First populate information about foreign dependencies and the general + // structure of the package. This should resolve the "base" of many + // `use` statements and additionally generate a topological ordering of + // all interfaces in the package to visit. + let asts = mem::take(&mut self.asts); + self.populate_foreign_interfaces(&asts); + let order = self.populate_ast_items(&asts)?; + self.populate_foreign_types(&asts)?; - let prev = doc_deps.insert(*name, deps); - assert!(prev.is_none()); + // Use the topological ordering of all interfaces to resolve all + // interfaces in-order. Note that a reverse-mapping from ID to AST is + // generated here to assist with this. + let mut id_to_ast = IndexMap::new(); + for (i, ast) in asts.iter().enumerate() { + for item in ast.items.iter() { + if let ast::AstItem::Interface(interface) = item { + let id = match self.ast_items[i][interface.name.name] { + AstItem::Interface(id) => id, + AstItem::World(_) => unreachable!(), + }; + id_to_ast.insert(id, (interface, i)); + } + } + } + for id in order { + let (interface, i) = &id_to_ast[&id]; + self.cur_ast_index = *i; + self.resolve_interface(id, &interface.items, &interface.docs)?; } - let order = toposort("document", &doc_deps)?; - log::debug!("toposort for documents is {order:?}"); - let mut asts = mem::take(&mut self.asts); - for name in order { - let ast = asts.remove(&name).unwrap(); - self.resolve_document(name, &ast)?; + // With all interfaces out of the way the next order of business is to + // take care of all the worlds. Worlds only depend on interfaces so no + // topological ordering is necessary here. + for (i, ast) in asts.iter().enumerate() { + self.cur_ast_index = i; + for item in ast.items.iter() { + if let ast::AstItem::World(world) = item { + let id = match self.ast_items[i][world.name.name] { + AstItem::World(id) => id, + AstItem::Interface(_) => unreachable!(), + }; + self.resolve_world(id, world)?; + } + } } Ok(UnresolvedPackage { - name: name.to_string(), - url: url.map(|s| s.to_string()), + name, worlds: mem::take(&mut self.worlds), types: mem::take(&mut self.types), interfaces: mem::take(&mut self.interfaces), - documents: mem::take(&mut self.documents), foreign_deps: self .foreign_deps .iter() .map(|(name, deps)| { ( - name.to_string(), + name.clone(), deps.iter() .map(|(name, id)| (name.to_string(), *id)) .collect(), @@ -132,87 +200,262 @@ impl<'a> Resolver<'a> { .collect(), unknown_type_spans: mem::take(&mut self.unknown_type_spans), world_spans: mem::take(&mut self.world_spans), - document_spans: mem::take(&mut self.document_spans), interface_spans: mem::take(&mut self.interface_spans), foreign_dep_spans: mem::take(&mut self.foreign_dep_spans), source_map: SourceMap::default(), }) } - /// Populate "unknown" for all types referenced from foreign packages as - /// well as inserting interfaces for referenced interfaces. + /// Registers all foreign dependencies made within the ASTs provided. /// - /// This will populate the initial set of documents/interfaces/types with - /// everything referenced from foreign packages, or those through - /// `UsePath::Dependency`. The items created here are extracted later via - /// `resolve_path`. - fn populate_foreign_deps(&mut self) { - for (_, ast) in self.asts.iter() { - ast.for_each_path(|_, path, names| { - let (dep, doc, iface) = match path { - ast::UsePath::Dependency { dep, doc, iface } => (dep, doc, iface), + /// This will populate the `self.foreign_{deps,interfaces}` maps with all + /// `UsePath::Package` entries. + fn populate_foreign_interfaces(&mut self, asts: &[ast::Ast<'a>]) { + let mut foreign_deps = mem::take(&mut self.foreign_deps); + let mut foreign_interfaces = mem::take(&mut self.foreign_interfaces); + for ast in asts { + ast.for_each_path(|_, path, _names| { + let (id, name) = match path { + ast::UsePath::Package { id, name } => (id, name), _ => return Ok(()), }; - let deps = self.foreign_deps.entry(dep.name).or_insert_with(|| { - self.foreign_dep_spans.push(dep.span); + let deps = foreign_deps.entry(id.package_name()).or_insert_with(|| { + self.foreign_dep_spans.push(id.span); IndexMap::new() }); - let doc_span = doc.span; - let doc = *deps.entry(doc.name).or_insert_with(|| { - log::trace!("creating a document for foreign dep: {}", dep.name); - self.document_interfaces.push(IndexMap::new()); - self.document_spans.push(doc_span); - self.documents.alloc(Document { - name: doc.name.to_string(), - default_interface: None, - default_world: None, - interfaces: IndexMap::new(), - worlds: IndexMap::new(), - package: None, - }) + let id = *deps.entry(name.name).or_insert_with(|| { + log::trace!( + "creating an interface for foreign dep: {}/{}", + id.package_name(), + name.name + ); + self.alloc_interface(name.span) }); - let iface = match iface { - Some(iface) => { - let item = self.document_interfaces[doc.index()] - .entry(iface.name) - .or_insert_with(|| { - self.interface_types.push(IndexMap::new()); - self.interface_spans.push(iface.span); - let id = self.interfaces.alloc(Interface { - name: Some(iface.name.to_string()), - types: IndexMap::new(), - docs: Docs::default(), - document: doc, - functions: IndexMap::new(), - }); - DocumentItem::Interface(id) - }); - match item { - DocumentItem::Interface(id) => *id, - _ => unreachable!(), + foreign_interfaces.insert(id); + + Ok(()) + }) + .unwrap(); + } + self.foreign_deps = foreign_deps; + self.foreign_interfaces = foreign_interfaces; + } + + fn alloc_interface(&mut self, span: Span) -> InterfaceId { + self.interface_types.push(IndexMap::new()); + self.interface_spans.push(span); + self.interfaces.alloc(Interface { + name: None, + types: IndexMap::new(), + docs: Docs::default(), + functions: IndexMap::new(), + package: None, + }) + } + + /// This method will create a `World` and an `Interface` for all items + /// present in the specified set of ASTs. Additionally maps for each AST are + /// generated for resolving use-paths later on. + fn populate_ast_items(&mut self, asts: &[ast::Ast<'a>]) -> Result> { + let mut package_items = IndexMap::new(); + + // Validate that all worlds and interfaces have unique names within this + // package across all ASTs which make up the package. + let mut ast_namespaces = Vec::new(); + let mut order = IndexMap::new(); + for ast in asts { + let mut ast_ns = IndexMap::new(); + for item in ast.items.iter() { + match item { + ast::AstItem::Interface(i) => { + if package_items.insert(i.name.name, i.name.span).is_some() { + bail!(Error { + span: i.name.span, + msg: format!("duplicate item named `{}`", i.name.name), + }) } + let prev = ast_ns.insert(i.name.name, ()); + assert!(prev.is_none()); + let prev = order.insert(i.name.name, Vec::new()); + assert!(prev.is_none()); + } + ast::AstItem::World(w) => { + if package_items.insert(w.name.name, w.name.span).is_some() { + bail!(Error { + span: w.name.span, + msg: format!("duplicate item named `{}", w.name.name), + }) + } + let prev = ast_ns.insert(w.name.name, ()); + assert!(prev.is_none()); + } + // These are processed down below. + ast::AstItem::Use(_) => {} + } + } + ast_namespaces.push(ast_ns); + } + + // Next record dependencies between interfaces as induced via `use` + // paths. This step is used to perform a topological sort of all + // interfaces to ensure there are no cycles and to generate an ordering + // which we can resolve in. + enum ItemSource<'a> { + Foreign, + Local(ast::Id<'a>), + } + + for ast in asts { + // Record, in the context of this file, what all names are defined + // at the top level and whether they point to other items in this + // package or foreign items. Foreign deps are ignored for + // topological ordering. + let mut ast_ns = IndexMap::new(); + for item in ast.items.iter() { + let (name, src) = match item { + ast::AstItem::Use(u) => { + let name = u.as_.as_ref().unwrap_or(u.item.name()); + let src = match &u.item { + ast::UsePath::Id(id) => ItemSource::Local(id.clone()), + ast::UsePath::Package { .. } => ItemSource::Foreign, + }; + (name, src) } - None => *self.documents[doc] - .default_interface - .get_or_insert_with(|| { - self.interface_types.push(IndexMap::new()); - self.interface_spans.push(doc_span); - self.interfaces.alloc(Interface { - name: None, - types: IndexMap::new(), - docs: Docs::default(), - document: doc, - functions: IndexMap::new(), + ast::AstItem::Interface(i) => (&i.name, ItemSource::Local(i.name.clone())), + ast::AstItem::World(w) => (&w.name, ItemSource::Local(w.name.clone())), + }; + if ast_ns.insert(name.name, (name.span, src)).is_some() { + bail!(Error { + span: name.span, + msg: format!("duplicate name `{}` in this file", name.name), + }); + } + } + + // With this file's namespace information look at all `use` paths + // and record dependencies between interfaces. + ast.for_each_path(|iface, path, _names| { + // If this import isn't contained within an interface then it's + // in a world and it doesn't need to participate in our + // topo-sort. + let iface = match iface { + Some(name) => name, + None => return Ok(()), + }; + let used_name = match path { + ast::UsePath::Id(id) => id, + ast::UsePath::Package { .. } => return Ok(()), + }; + match ast_ns.get(used_name.name) { + Some((_, ItemSource::Foreign)) => return Ok(()), + Some((_, ItemSource::Local(id))) => { + order[iface.name].push(id.clone()); + } + None => match package_items.get(used_name.name) { + Some(_) => { + order[iface.name].push(used_name.clone()); + } + None => { + bail!(Error { + span: used_name.span, + msg: format!( + "interface `{name}` not found in package", + name = used_name.name + ), }) - }), + } + }, + } + Ok(()) + })?; + } + + let order = toposort("interface", &order)?; + + // Allocate interfaces in-order now that the ordering is defined. This + // is then used to build up internal maps for each AST which are stored + // in `self.ast_items`. + let mut interface_ids = IndexMap::new(); + let mut id_order = Vec::new(); + for name in order { + let id = self.alloc_interface(package_items[name]); + self.interfaces[id].name = Some(name.to_string()); + let prev = interface_ids.insert(name, id); + assert!(prev.is_none()); + id_order.push(id); + } + for ast in asts { + let mut items = IndexMap::new(); + for item in ast.items.iter() { + let (name, ast_item) = match item { + ast::AstItem::Use(u) => { + let name = u.as_.as_ref().unwrap_or(u.item.name()); + let item = match &u.item { + ast::UsePath::Id(name) => { + *interface_ids.get(name.name).ok_or_else(|| Error { + span: name.span, + msg: format!( + "interface `{name}` does not exist", + name = name.name + ), + })? + } + ast::UsePath::Package { id, name } => { + self.foreign_deps[&id.package_name()][name.name] + } + }; + (name.name, AstItem::Interface(item)) + } + ast::AstItem::Interface(i) => { + (i.name.name, AstItem::Interface(interface_ids[i.name.name])) + } + ast::AstItem::World(w) => { + let id = self.worlds.alloc(World { + name: w.name.name.to_string(), + docs: Docs::default(), + exports: IndexMap::new(), + imports: IndexMap::new(), + package: None, + }); + (w.name.name, AstItem::World(id)) + } }; + let prev = items.insert(name, ast_item); + assert!(prev.is_none()); + // Items defined via `use` don't go into the package namespace, + // only the file namespace. + if !matches!(item, ast::AstItem::Use(_)) { + let prev = self.package_items.insert(name, ast_item); + assert!(prev.is_none()); + } + } + self.ast_items.push(items); + } + Ok(id_order) + } + + /// Generate a `Type::Unknown` entry for all types imported from foreign + /// packages. + /// + /// This is done after all interfaces are generated so `self.resolve_path` + /// can be used to determine if what's being imported from is a foreign + /// interface or not. + fn populate_foreign_types(&mut self, asts: &[ast::Ast<'a>]) -> Result<()> { + for (i, ast) in asts.iter().enumerate() { + self.cur_ast_index = i; + ast.for_each_path(|_, path, names| { let names = match names { Some(names) => names, None => return Ok(()), }; + let iface = self.resolve_path(path)?; + if !self.foreign_interfaces.contains(&iface) { + return Ok(()); + } + let lookup = &mut self.interface_types[iface.index()]; for name in names { // If this name has already been defined then use that prior @@ -235,165 +478,14 @@ impl<'a> Resolver<'a> { } Ok(()) - }) - .unwrap(); - } - } - - fn resolve_document(&mut self, name: &'a str, ast: &ast::Ast<'a>) -> Result { - // Verify all top-level names in this document are unique, and save off - // the name of the default interface for drawing topological - // dependencies in a moment. - let mut names = HashMap::new(); - let mut default_interface_name = None; - let mut deps = IndexMap::new(); - for item in ast.items.iter() { - let name = match item { - ast::AstItem::Interface(i) => { - if i.default && default_interface_name.is_none() { - default_interface_name = Some(i.name.name); - } - &i.name - } - ast::AstItem::World(w) => &w.name, - }; - deps.insert(name.name, Vec::new()); - if names.insert(name.name, item).is_some() { - return Err(Error { - span: name.span, - msg: format!("name `{}` previously defined in document", name.name), - } - .into()); - } - } - - // Walk all `UsePath` entries in this AST and record dependencies - // between interfaces. These are dependencies specified via `use - // self...` or via `use pkg.this-doc...`. - ast.for_each_path(|iface, path, _names| { - // If this import isn't contained within an interface then it's in a - // world and it doesn't need to participate in our topo-sort. - let iface = match iface { - Some(name) => name, - None => return Ok(()), - }; - let deps = &mut deps[iface.name]; - match path { - // Self-deps are what we're mostly interested in here. - ast::UsePath::Self_(name) => deps.push(name.clone()), - - // Self-deps via the package happen when the `doc` name listed - // is the same as the name of the document being defined. - ast::UsePath::Package { doc, iface } => { - if doc.name != name { - return Ok(()); - } - let name = match iface { - Some(name) => name.clone(), - None => { - let name = default_interface_name.ok_or_else(|| Error { - span: doc.span, - msg: format!("no `default` interface in document to use from"), - })?; - ast::Id { - span: doc.span, - name, - } - } - }; - deps.push(name); - } - - // Dependencies on other packages don't participate in this - // topological ordering. - ast::UsePath::Dependency { .. } => {} - } - Ok(()) - })?; - let order = toposort("interface", &deps)?; - log::debug!("toposort for interfaces in `{name}` is {order:?}"); - - // Allocate a document ID and then start processing all of the - // interfaces as defined by our `order` to insert new interfaces into - // this. - let document_id = self.documents.alloc(Document { - name: name.to_string(), - default_interface: None, - default_world: None, - interfaces: IndexMap::new(), - worlds: IndexMap::new(), - package: None, - }); - self.document_interfaces.push(IndexMap::new()); - self.document_lookup.insert(name, document_id); - - let mut worlds = Vec::new(); - for name in order { - let interface = match names.remove(&name).unwrap() { - ast::AstItem::Interface(i) => i, - ast::AstItem::World(world) => { - worlds.push((name, world)); - continue; - } - }; - let id = self.resolve_interface( - document_id, - Some(interface.name.name), - &interface.items, - &interface.docs, - )?; - if interface.default { - let prev = &mut self.documents[document_id].default_interface; - if prev.is_some() { - return Err(Error { - span: interface.name.span, - msg: format!("cannot specify more than one `default` interface"), - } - .into()); - } - *prev = Some(id); - } - let prev = self.documents[document_id] - .interfaces - .insert(name.to_string(), id); - assert!(prev.is_none()); - } - - // After all interfaces are defined then process all worlds as all items - // they import from should now be available. - for (name, world) in worlds { - let id = self.resolve_world(document_id, world)?; - if world.default { - let prev = &mut self.documents[document_id].default_world; - if prev.is_some() { - return Err(Error { - span: world.name.span, - msg: format!("cannot specify more than one `default` world"), - } - .into()); - } - *prev = Some(id); - } - let prev = self.documents[document_id] - .worlds - .insert(name.to_string(), id); - assert!(prev.is_none()); + })?; } - - Ok(document_id) + Ok(()) } - fn resolve_world(&mut self, document: DocumentId, world: &ast::World<'a>) -> Result { + fn resolve_world(&mut self, world_id: WorldId, world: &ast::World<'a>) -> Result { let docs = self.docs(&world.docs); - let world_id = self.worlds.alloc(World { - docs, - document, - name: world.name.name.to_string(), - exports: IndexMap::new(), - imports: IndexMap::new(), - }); - self.document_interfaces[document.index()] - .insert(world.name.name, DocumentItem::World(world_id)); + self.worlds[world_id].docs = docs; self.resolve_types( TypeOwner::World(world_id), @@ -422,23 +514,22 @@ impl<'a> Resolver<'a> { } self.worlds[world_id] .imports - .insert(name.to_string(), WorldItem::Type(id)); + .insert(WorldKey::Name(name.to_string()), WorldItem::Type(id)); import_spans.push(*span); } TypeOrItem::Item(_) => unreachable!(), } } - let mut imported_interfaces = HashMap::new(); - let mut exported_interfaces = HashMap::new(); + let mut imported_interfaces = HashSet::new(); + let mut exported_interfaces = HashSet::new(); for item in world.items.iter() { - let (docs, name, kind, desc, spans, interfaces) = match item { + let (docs, kind, desc, spans, interfaces) = match item { // handled in `resolve_types` ast::WorldItem::Use(_) | ast::WorldItem::Type(_) => continue, ast::WorldItem::Import(import) => ( &import.docs, - &import.name, &import.kind, "import", &mut import_spans, @@ -446,35 +537,36 @@ impl<'a> Resolver<'a> { ), ast::WorldItem::Export(export) => ( &export.docs, - &export.name, &export.kind, "export", &mut export_spans, &mut exported_interfaces, ), }; - let prev = used_names.insert(name.name, desc); - if let Some(prev) = prev { - return Err(Error { - span: name.span, - msg: format!( - "{desc} `{name}` conflicts with prior {prev} of same name", - name = name.name - ), + let key = match kind { + ast::ExternKind::Interface(name, _) | ast::ExternKind::Func(name, _) => { + let prev = used_names.insert(name.name, desc); + if let Some(prev) = prev { + return Err(Error { + span: kind.span(), + msg: format!( + "{desc} `{name}` conflicts with prior {prev} of same name", + name = name.name + ), + } + .into()); + } + WorldKey::Name(name.name.to_string()) } - .into()); - } - let world_item = self.resolve_world_item(docs, name.name, document, kind)?; + ast::ExternKind::Path(path) => WorldKey::Interface(self.resolve_path(path)?), + }; + let world_item = self.resolve_world_item(docs, kind)?; if let WorldItem::Interface(id) = world_item { - if interfaces.insert(id, name.name).is_some() { - return Err(Error { - span: name.span, - msg: format!( - "interface `{name}` cannot be {desc}ed more than once", - name = name.name - ), - } - .into()); + if !interfaces.insert(id) { + bail!(Error { + span: kind.span(), + msg: format!("interface cannot be {desc}ed more than once"), + }) } } let dst = if desc == "import" { @@ -482,9 +574,9 @@ impl<'a> Resolver<'a> { } else { &mut self.worlds[world_id].exports }; - let prev = dst.insert(name.name.to_string(), world_item); + let prev = dst.insert(key, world_item); assert!(prev.is_none()); - spans.push(name.span); + spans.push(kind.span()); } self.world_spans.push((import_spans, export_spans)); self.type_lookup.clear(); @@ -495,14 +587,13 @@ impl<'a> Resolver<'a> { fn resolve_world_item( &mut self, docs: &ast::Docs<'a>, - name: &str, - document: DocumentId, kind: &ast::ExternKind<'a>, ) -> Result { match kind { - ast::ExternKind::Interface(_span, items) => { + ast::ExternKind::Interface(name, items) => { let prev = mem::take(&mut self.type_lookup); - let id = self.resolve_interface(document, None, items, docs)?; + let id = self.alloc_interface(name.span); + self.resolve_interface(id, items, docs)?; self.type_lookup = prev; Ok(WorldItem::Interface(id)) } @@ -510,8 +601,8 @@ impl<'a> Resolver<'a> { let id = self.resolve_path(path)?; Ok(WorldItem::Interface(id)) } - ast::ExternKind::Func(func) => { - let func = self.resolve_function(docs, name, func)?; + ast::ExternKind::Func(name, func) => { + let func = self.resolve_function(docs, name.name, func)?; Ok(WorldItem::Function(func)) } } @@ -519,23 +610,12 @@ impl<'a> Resolver<'a> { fn resolve_interface( &mut self, - document: DocumentId, - name: Option<&'a str>, + interface_id: InterfaceId, fields: &[ast::InterfaceItem<'a>], docs: &ast::Docs<'a>, - ) -> Result { + ) -> Result<()> { let docs = self.docs(docs); - let interface_id = self.interfaces.alloc(Interface { - docs, - document, - name: name.map(|s| s.to_string()), - functions: IndexMap::new(), - types: IndexMap::new(), - }); - if let Some(name) = name { - self.document_interfaces[document.index()] - .insert(name, DocumentItem::Interface(interface_id)); - } + self.interfaces[interface_id].docs = docs; self.resolve_types( TypeOwner::Interface(interface_id), @@ -576,10 +656,9 @@ impl<'a> Resolver<'a> { } let lookup = mem::take(&mut self.type_lookup); - assert_eq!(interface_id.index(), self.interface_types.len()); - self.interface_types.push(lookup); + self.interface_types[interface_id.index()] = lookup; - Ok(interface_id) + Ok(()) } fn resolve_types<'b>( @@ -700,60 +779,31 @@ impl<'a> Resolver<'a> { fn resolve_path(&self, path: &ast::UsePath<'a>) -> Result { match path { - ast::UsePath::Self_(iface) => { - match self.document_interfaces.last().unwrap().get(iface.name) { - Some(DocumentItem::Interface(id)) => Ok(*id), - Some(DocumentItem::World(_)) => bail!(Error { - span: iface.span, - msg: format!( - "name `{}` is defined as a world, not an interface", - iface.name - ), - }), - None => bail!(Error { - span: iface.span, - msg: format!("interface does not exist"), - }), - } - } - ast::UsePath::Package { doc, iface } => { - let doc_id = self.document_lookup[doc.name]; - match iface { - // If `iface` was provided then it must have been previously - // processed - Some(id) => { - let lookup = &self.document_interfaces[doc_id.index()]; - match lookup.get(id.name) { - Some(DocumentItem::Interface(id)) => Ok(*id), - Some(DocumentItem::World(_)) => Err(Error { - span: id.span, - msg: format!("cannot import from world `{}`", id.name), - } - .into()), - None => bail!(Error { - span: id.span, - msg: format!("interface does not exist"), - }), - } + ast::UsePath::Id(id) => { + let item = self.ast_items[self.cur_ast_index] + .get(id.name) + .or_else(|| self.package_items.get(id.name)); + match item { + Some(AstItem::Interface(id)) => Ok(*id), + Some(AstItem::World(_)) => { + bail!(Error { + span: id.span, + msg: format!( + "name `{}` is defined as a world, not an interface", + id.name + ), + }) + } + None => { + bail!(Error { + span: id.span, + msg: format!("interface `{name}` does not exist", name = id.name), + }) } - None => self.documents[doc_id].default_interface.ok_or_else(|| { - Error { - span: doc.span, - msg: format!("document does not specify a default interface"), - } - .into() - }), } } - ast::UsePath::Dependency { dep, doc, iface } => { - let doc = self.foreign_deps[dep.name][doc.name]; - match iface { - Some(name) => match self.document_interfaces[doc.index()][name.name] { - DocumentItem::Interface(id) => Ok(id), - DocumentItem::World(_) => unreachable!(), - }, - None => Ok(self.documents[doc].default_interface.unwrap()), - } + ast::UsePath::Package { id, name } => { + Ok(self.foreign_deps[&id.package_name()][name.name]) } } } diff --git a/crates/wit-parser/src/lib.rs b/crates/wit-parser/src/lib.rs index f697b4200d..d5d2fb2cb0 100644 --- a/crates/wit-parser/src/lib.rs +++ b/crates/wit-parser/src/lib.rs @@ -1,6 +1,7 @@ -use anyhow::{anyhow, Context, Result}; +use anyhow::{Context, Result}; use id_arena::{Arena, Id}; use indexmap::IndexMap; +use semver::Version; use std::borrow::Cow; use std::fmt; use std::path::Path; @@ -25,7 +26,6 @@ pub fn validate_id(s: &str) -> Result<()> { pub type WorldId = Id; pub type InterfaceId = Id; pub type TypeId = Id; -pub type DocumentId = Id; /// Representation of a parsed WIT package which has not resolved external /// dependencies yet. @@ -54,15 +54,8 @@ pub type DocumentId = Id; /// performing this resolution themselves. #[derive(Clone)] pub struct UnresolvedPackage { - /// Local name for this package. - pub name: String, - - /// Optionally-specified URL for this package. - /// - /// Must be specified for non-local dependencies. Note that this is never - /// automatically set from [`UnresolvedPackage::parse`] methods, and it must - /// be manually configured in the return value. - pub url: Option, + /// The namespace, name, and version information for this package. + pub name: PackageName, /// All worlds from all documents within this package. /// @@ -85,30 +78,61 @@ pub struct UnresolvedPackage { /// other types transitively that are already iterated over. pub types: Arena, - /// All documents found within this package. - /// - /// Documents are sorted topologically in this arena with respect to imports - /// between them. - pub documents: Arena, - /// All foreign dependencies that this package depends on. /// /// These foreign dependencies must be resolved to convert this unresolved /// package into a `Resolve`. The map here is keyed by the name of the - /// foreign package that this depends on, and the sub-map is keyed by a - /// document name followed by the identifier within `self.documents`. The - /// fields of `self.documents` describes the required types, interfaces, - /// etc, that are required from each foreign package. - pub foreign_deps: IndexMap>, + /// foreign package that this depends on, and the sub-map is keyed by an + /// interface name followed by the identifier within `self.interfaces`. The + /// fields of `self.interfaces` describes the required types that are from + /// each foreign interface. + pub foreign_deps: IndexMap>, unknown_type_spans: Vec, world_spans: Vec<(Vec, Vec)>, - document_spans: Vec, interface_spans: Vec, foreign_dep_spans: Vec, source_map: SourceMap, } +/// A structure used to keep track of the name of a package, containing optional +/// information such as a namespace and version information. +/// +/// This is directly encoded as an "ID" in the binary component representation +/// with an interfaced tacked on as well. +#[derive(Debug, Clone, Hash, Eq, PartialEq, Ord, PartialOrd)] +pub struct PackageName { + /// A namespace such as `wasi` in `wasi:foo/bar` + pub namespace: String, + /// The kebab-name of this package, which is always specified. + pub name: String, + /// Optional major/minor version information. + pub version: Option, +} + +impl PackageName { + /// Returns the ID that this package name would assign the `interface` name + /// specified. + pub fn interface_id(&self, interface: &str) -> String { + let mut s = String::new(); + s.push_str(&format!("{}:{}/{interface}", self.namespace, self.name)); + if let Some(version) = &self.version { + s.push_str(&format!("@{version}")); + } + s + } +} + +impl fmt::Display for PackageName { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}:{}", self.namespace, self.name)?; + if let Some(version) = &self.version { + write!(f, "@{version}")?; + } + Ok(()) + } +} + #[derive(Debug)] struct Error { span: Span, @@ -130,16 +154,8 @@ impl UnresolvedPackage { /// will not be able to use `pkg` use paths to other documents. pub fn parse(path: &Path, contents: &str) -> Result { let mut map = SourceMap::default(); - let name = path - .file_name() - .and_then(|s| s.to_str()) - .ok_or_else(|| anyhow!("path doesn't end in a valid package name {path:?}"))?; - let name = match name.find('.') { - Some(i) => &name[..i], - None => name, - }; - map.push(path, name, contents); - map.parse(name, None) + map.push(path, contents); + map.parse() } /// Parse a WIT package at the provided path. @@ -171,10 +187,6 @@ impl UnresolvedPackage { /// `path` into the returned package. pub fn parse_dir(path: &Path) -> Result { let mut map = SourceMap::default(); - let name = path - .file_name() - .and_then(|s| s.to_str()) - .ok_or_else(|| anyhow!("path doesn't end in a valid package name {path:?}"))?; let cx = || format!("failed to read directory {path:?}"); for entry in path.read_dir().with_context(&cx)? { let entry = entry.with_context(&cx)?; @@ -197,7 +209,7 @@ impl UnresolvedPackage { } map.push_file(&path)?; } - map.parse(name, None) + map.parse() } /// Returns an iterator over the list of source files that were read when @@ -207,34 +219,6 @@ impl UnresolvedPackage { } } -/// Represents the result of parsing a wit document. -#[derive(Debug, Clone)] -pub struct Document { - pub name: String, - - /// The top-level interfaces contained in the document. - /// - /// The interfaces here are listed in topological order of the - /// dependencies between them. - pub interfaces: IndexMap, - - /// The worlds contained in the document. - pub worlds: IndexMap, - - /// The default interface of this document, if any. - /// - /// This interface will also be listed in `self.interfaces` - pub default_interface: Option, - - /// The default world of this document, if any. - /// - /// This will also be listed in `self.worlds`. - pub default_world: Option, - - /// The package that this document belongs to. - pub package: Option, -} - #[derive(Debug, Clone)] pub struct World { /// The WIT identifier name of this world. @@ -244,13 +228,34 @@ pub struct World { pub docs: Docs, /// All imported items into this interface, both worlds and functions. - pub imports: IndexMap, + pub imports: IndexMap, /// All exported items from this interface, both worlds and functions. - pub exports: IndexMap, + pub exports: IndexMap, + + /// The package that owns this world. + pub package: Option, +} + +/// The key to the import/export maps of a world. Either a kebab-name or a +/// unique interface. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum WorldKey { + /// A kebab-name. + Name(String), + /// An interface which is assigned no kebab-name. + Interface(InterfaceId), +} - /// The document that owns this world. - pub document: DocumentId, +impl WorldKey { + /// Asserts that this is `WorldKey::Name` and returns the name. + #[track_caller] + pub fn unwrap_name(self) -> String { + match self { + WorldKey::Name(name) => name, + WorldKey::Interface(_) => panic!("expected a name, found interface"), + } + } } #[derive(Debug, Clone)] @@ -287,8 +292,8 @@ pub struct Interface { /// Exported functions from this interface. pub functions: IndexMap, - /// The document that this interface belongs to. - pub document: DocumentId, + /// The package that owns this interface. + pub package: Option, } #[derive(Debug, Clone, PartialEq)] diff --git a/crates/wit-parser/src/live.rs b/crates/wit-parser/src/live.rs index 28a755382b..d236cf1ccd 100644 --- a/crates/wit-parser/src/live.rs +++ b/crates/wit-parser/src/live.rs @@ -1,6 +1,4 @@ -use crate::{ - DocumentId, Function, InterfaceId, Resolve, Type, TypeDefKind, TypeId, WorldId, WorldItem, -}; +use crate::{Function, InterfaceId, Resolve, Type, TypeDefKind, TypeId, WorldId, WorldItem}; use indexmap::IndexSet; #[derive(Default)] @@ -17,16 +15,6 @@ impl LiveTypes { self.set.len() } - pub fn add_document(&mut self, resolve: &Resolve, doc: DocumentId) { - let doc = &resolve.documents[doc]; - for (_, id) in doc.interfaces.iter() { - self.add_interface(resolve, *id); - } - for (_, id) in doc.worlds.iter() { - self.add_world(resolve, *id); - } - } - pub fn add_interface(&mut self, resolve: &Resolve, iface: InterfaceId) { let iface = &resolve.interfaces[iface]; for (_, id) in iface.types.iter() { diff --git a/crates/wit-parser/src/resolve.rs b/crates/wit-parser/src/resolve.rs index 4294e70dd3..125c3c7f29 100644 --- a/crates/wit-parser/src/resolve.rs +++ b/crates/wit-parser/src/resolve.rs @@ -1,16 +1,15 @@ use crate::ast::lex::Span; +use crate::ast::{parse_use_path, AstUsePath}; use crate::{ - Document, DocumentId, Error, Function, Interface, InterfaceId, Results, Type, TypeDef, - TypeDefKind, TypeId, TypeOwner, UnresolvedPackage, World, WorldId, WorldItem, + Error, Function, Interface, InterfaceId, PackageName, Results, Type, TypeDef, TypeDefKind, + TypeId, TypeOwner, UnresolvedPackage, World, WorldId, WorldItem, WorldKey, }; use anyhow::{anyhow, bail, Context, Result}; use id_arena::{Arena, Id}; use indexmap::{IndexMap, IndexSet}; use std::collections::{HashMap, HashSet}; -use std::fmt::Write; use std::mem; use std::path::{Path, PathBuf}; -use url::Url; /// Representation of a fully resolved set of WIT packages. /// @@ -30,21 +29,26 @@ pub struct Resolve { pub worlds: Arena, pub interfaces: Arena, pub types: Arena, - pub documents: Arena, pub packages: Arena, + pub package_names: IndexMap, } +/// A WIT package within a `Resolve`. +/// +/// A package is a collection of interfaces and worlds. Packages additionally +/// have a unique identifier that affects generated components and uniquely +/// identifiers this particular package. #[derive(Clone)] pub struct Package { - /// Locally-known name of this package. - pub name: String, + /// A unique name corresponding to this package. + pub name: PackageName, - /// Optionally-specified URL of this package, must be specified for remote - /// dependencies. - pub url: Option, + /// All interfaces contained in this packaged, keyed by the interface's + /// name. + pub interfaces: IndexMap, - /// Documents contained within this package, organized by name. - pub documents: IndexMap, + /// All worlds contained in this package, keyed by the world's name. + pub worlds: IndexMap, } pub type PackageId = Id; @@ -58,119 +62,90 @@ impl Resolve { /// Parses the filesystem directory at `path` as a WIT package and returns /// the fully resolved [`PackageId`] as a result. /// - /// This method is intended for testing and convenience for now and isn't - /// the only way to push packages into this [`Resolve`]. This will - /// interpret `path` as a directory where all `*.wit` files in that - /// directory are members of the package. - /// /// Dependencies referenced by the WIT package at `path` will be loaded from - /// a `deps/$name` directory under `path` where `$name` is the name of the - /// dependency loaded. If `deps/$name` does not exist then an error will be - /// returned indicating that the dependency is not defined. All dependencies - /// are listed in a flat namespace under `$path/deps` so they can refer to - /// each other. + /// a `deps/..` directory under `path`. All directories under `deps/` will + /// be parsed as a WIT package. The directory name containing each package + /// is not used as each package is otherwise self-identifying. /// /// This function returns the [`PackageId`] of the root parsed package at /// `path`, along with a list of all paths that were consumed during parsing /// for the root package and all dependency packages. pub fn push_dir(&mut self, path: &Path) -> Result<(PackageId, Vec)> { - // Maintain a `to_parse` stack of packages that have yet to be parsed - // along with an `enqueued` set of all the prior parsed packages and - // packages enqueued to be parsed. These are then used to fill the - // `packages` map with parsed, but unresolved, packages. The `pkg_deps` - // map then tracks dependencies between packages. - let mut to_parse = Vec::new(); - let mut enqueued = HashSet::new(); - let mut packages = IndexMap::new(); - let mut pkg_deps = IndexMap::new(); - to_parse.push((path.to_path_buf(), None)); - enqueued.insert(path.to_path_buf()); - while let Some((pkg_root, url)) = to_parse.pop() { - let mut pkg = UnresolvedPackage::parse_dir(&pkg_root) - .with_context(|| format!("failed to parse package: {}", path.display()))?; - pkg.url = url; - - let mut deps = Vec::new(); - pkg.source_map.rewrite_error(|| { - for (i, (dep, _)) in pkg.foreign_deps.iter().enumerate() { - let path = path.join("deps").join(dep); - let span = pkg.foreign_dep_spans[i]; - // If this is the first request to parse `path` then push it - // onto our stack, otherwise it's already there so skip it. - if enqueued.insert(path.clone()) { - if !path.is_dir() { - bail!(Error { - span, - msg: format!( - "dependency on `{dep}` doesn't exist at: {}", - path.display() - ), - }) - } - let url = Some(format!("path:/{dep}")); - to_parse.push((path.clone(), url)); - } - deps.push((path, span)); - } - Ok(()) - })?; + let pkg = UnresolvedPackage::parse_dir(path) + .with_context(|| format!("failed to parse package: {}", path.display()))?; - let prev = packages.insert(pkg_root.clone(), pkg); - assert!(prev.is_none()); - pkg_deps.insert(pkg_root, deps); - } + let deps = path.join("deps"); + let mut deps = parse_deps_dir(&deps) + .with_context(|| format!("failed to parse dependency directory: {}", deps.display()))?; // Perform a simple topological sort which will bail out on cycles // and otherwise determine the order that packages must be added to // this `Resolve`. let mut order = IndexSet::new(); let mut visiting = HashSet::new(); - for (dep, _) in pkg_deps.iter() { - visit(dep, &pkg_deps, &packages, &mut order, &mut visiting)?; - } + visit(&pkg, &deps, &mut order, &mut visiting)?; // Using the topological ordering insert each package incrementally. // Additionally note that the last item visited here is the root // package, which is the one returned here. - let mut package_ids = IndexMap::new(); let mut last = None; let mut files = Vec::new(); - for path in order { - let pkg = packages.remove(path).unwrap(); - let mut deps = HashMap::new(); - for ((dep, _), (path, _span)) in pkg.foreign_deps.iter().zip(&pkg_deps[path]) { - deps.insert(dep.clone(), package_ids[&**path]); - } + let mut pkg = Some(pkg); + for name in order { + let pkg = deps.remove(&name).unwrap_or_else(|| pkg.take().unwrap()); files.extend(pkg.source_files().map(|p| p.to_path_buf())); - let pkgid = self.push(pkg, &deps)?; - package_ids.insert(path, pkgid); + let pkgid = self.push(pkg)?; last = Some(pkgid); } return Ok((last.unwrap(), files)); + fn parse_deps_dir(path: &Path) -> Result> { + let mut ret = HashMap::new(); + // If there's no `deps` dir, then there's no deps, so return the + // empty set. + if !path.exists() { + return Ok(ret); + } + for dep in path.read_dir().context("failed to read directory")? { + let dep = dep.context("failed to read directory iterator")?; + let path = dep.path(); + let pkg = UnresolvedPackage::parse_dir(&path) + .with_context(|| format!("failed to parse package: {}", path.display()))?; + let prev = ret.insert(pkg.name.clone(), pkg); + if let Some(prev) = prev { + bail!("duplicate definitions of package `{}` found", prev.name); + } + } + Ok(ret) + } + fn visit<'a>( - path: &'a Path, - deps: &'a IndexMap>, - pkgs: &IndexMap, - order: &mut IndexSet<&'a Path>, - visiting: &mut HashSet<&'a Path>, + pkg: &'a UnresolvedPackage, + deps: &'a HashMap, + order: &mut IndexSet, + visiting: &mut HashSet<&'a PackageName>, ) -> Result<()> { - if order.contains(path) { + if order.contains(&pkg.name) { return Ok(()); } - pkgs[path].source_map.rewrite_error(|| { - for (dep, span) in deps[path].iter() { + pkg.source_map.rewrite_error(|| { + for (i, (dep, _)) in pkg.foreign_deps.iter().enumerate() { + let span = pkg.foreign_dep_spans[i]; if !visiting.insert(dep) { bail!(Error { - span: *span, + span, msg: format!("package depends on itself"), }); } - visit(dep, deps, pkgs, order, visiting)?; - assert!(visiting.remove(&**dep)); + let dep = deps.get(dep).ok_or_else(|| Error { + span, + msg: format!("failed to find package `{dep}` in `deps` directory"), + })?; + visit(dep, deps, order, visiting)?; + assert!(visiting.remove(&dep.name)); } - assert!(order.insert(path)); + assert!(order.insert(pkg.name.clone())); Ok(()) }) } @@ -184,13 +159,9 @@ impl Resolve { /// /// Any dependency resolution error or otherwise world-elaboration error /// will be returned here. If successful a package identifier is returned. - pub fn push( - &mut self, - mut unresolved: UnresolvedPackage, - deps: &HashMap, - ) -> Result { + pub fn push(&mut self, mut unresolved: UnresolvedPackage) -> Result { let source_map = mem::take(&mut unresolved.source_map); - source_map.rewrite_error(|| Remap::default().append(self, unresolved, deps)) + source_map.rewrite_error(|| Remap::default().append(self, unresolved)) } pub fn all_bits_valid(&self, ty: &Type) -> bool { @@ -255,9 +226,7 @@ impl Resolve { package_map, interface_map, type_map, - doc_map, world_map, - documents_to_add, interfaces_to_add, worlds_to_add, .. @@ -286,8 +255,8 @@ impl Resolve { types, worlds, interfaces, - documents, packages, + package_names, } = resolve; let mut moved_types = Vec::new(); @@ -316,40 +285,44 @@ impl Resolve { for (id, mut world) in worlds { let new_id = world_map.get(&id).copied().unwrap_or_else(|| { moved_worlds.push(id); - for (_, item) in world.imports.iter_mut().chain(&mut world.exports) { - match item { - WorldItem::Function(f) => remap.update_function(f), - WorldItem::Interface(i) => *i = remap.interfaces[i.index()], - WorldItem::Type(i) => *i = remap.types[i.index()], + let update = |map: &mut IndexMap| { + for (mut name, mut item) in mem::take(map) { + remap.update_world_key(&mut name); + match &mut item { + WorldItem::Function(f) => remap.update_function(f), + WorldItem::Interface(i) => *i = remap.interfaces[i.index()], + WorldItem::Type(i) => *i = remap.types[i.index()], + } + map.insert(name, item); } - } + }; + update(&mut world.imports); + update(&mut world.exports); self.worlds.alloc(world) }); assert_eq!(remap.worlds.len(), id.index()); remap.worlds.push(new_id); } - let mut moved_documents = Vec::new(); - for (id, mut doc) in documents { - let new_id = doc_map.get(&id).copied().unwrap_or_else(|| { - moved_documents.push(id); - remap.update_document(&mut doc); - self.documents.alloc(doc) + for (id, mut pkg) in packages { + let new_id = package_map.get(&id).copied().unwrap_or_else(|| { + for (_, id) in pkg.interfaces.iter_mut() { + *id = remap.interfaces[id.index()]; + } + for (_, id) in pkg.worlds.iter_mut() { + *id = remap.worlds[id.index()]; + } + self.packages.alloc(pkg) }); - assert_eq!(remap.documents.len(), id.index()); - remap.documents.push(new_id); + assert_eq!(remap.packages.len(), id.index()); + remap.packages.push(new_id); } - for (id, mut pkg) in packages { - for (_, doc) in pkg.documents.iter_mut() { - *doc = remap.documents[doc.index()]; + for (name, id) in package_names { + let id = remap.packages[id.index()]; + if let Some(prev) = self.package_names.insert(name, id) { + assert_eq!(prev, id); } - let new_id = package_map - .get(&id) - .copied() - .unwrap_or_else(|| self.packages.alloc(pkg)); - assert_eq!(remap.packages.len(), id.index()); - remap.packages.push(new_id); } // Fixup all "parent" links now. @@ -359,21 +332,15 @@ impl Resolve { // lists built incrementally above. The ids in the `moved_*` lists // are ids within `resolve`, so they're translated through `remap` to // ids within `self`. - for id in moved_documents { - let id = remap.documents[id.index()]; - if let Some(pkg) = &mut self.documents[id].package { - *pkg = remap.packages[pkg.index()]; - } - } for id in moved_worlds { let id = remap.worlds[id.index()]; - let doc = &mut self.worlds[id].document; - *doc = remap.documents[doc.index()]; + let pkg = self.worlds[id].package.as_mut().unwrap(); + *pkg = remap.packages[pkg.index()]; } for id in moved_interfaces { let id = remap.interfaces[id.index()]; - let doc = &mut self.interfaces[id].document; - *doc = remap.documents[doc.index()]; + let pkg = self.interfaces[id].package.as_mut().unwrap(); + *pkg = remap.packages[pkg.index()]; } for id in moved_types { let id = remap.types[id.index()]; @@ -384,24 +351,18 @@ impl Resolve { } } - // And finally process documents that were present in `resolve` but were + // And finally process items that were present in `resolve` but were // not present in `self`. This is only done for merged packages as // documents may be added to `self.documents` but wouldn't otherwise be // present in the `documents` field of the corresponding package. - for (name, pkg, doc) in documents_to_add { + for (name, pkg, iface) in interfaces_to_add { let prev = self.packages[pkg] - .documents - .insert(name, remap.documents[doc.index()]); - assert!(prev.is_none()); - } - for (name, doc, iface) in interfaces_to_add { - let prev = self.documents[doc] .interfaces .insert(name, remap.interfaces[iface.index()]); assert!(prev.is_none()); } - for (name, doc, world) in worlds_to_add { - let prev = self.documents[doc] + for (name, pkg, world) in worlds_to_add { + let prev = self.packages[pkg] .worlds .insert(name, remap.worlds[world.index()]); assert!(prev.is_none()); @@ -455,6 +416,8 @@ impl Resolve { if let WorldItem::Interface(id) = import { if let Some(prev) = into_imports_by_id.get(id) { if *prev != name { + let name = self.name_world_key(name); + let prev = self.name_world_key(prev); bail!("import `{name}` conflicts with previous name of `{prev}`"); } } @@ -466,6 +429,8 @@ impl Resolve { // so it's left as an error. if let WorldItem::Interface(id) = export { if let Some(prev) = into_exports_by_id.get(id) { + let name = self.name_world_key(name); + let prev = self.name_world_key(prev); bail!("export `{name}` conflicts with previous name of `{prev}`"); } } @@ -481,7 +446,10 @@ impl Resolve { (WorldItem::Interface(from), WorldItem::Interface(into)) if from == into => { continue } - _ => bail!("duplicate import found for interface `{name}`"), + _ => { + let name = self.name_world_key(name); + bail!("duplicate import found for interface `{name}`"); + } }, None => new_imports.push((name.clone(), from_import.clone())), } @@ -493,7 +461,10 @@ impl Resolve { // if the worlds have disjoint sets of exports. for (name, export) in from_world.exports.iter() { match into_world.exports.get(name) { - Some(_) => bail!("duplicate export found for interface `{name}`"), + Some(_) => { + let name = self.name_world_key(name); + bail!("duplicate export found for interface `{name}`"); + } None => new_exports.push((name.clone(), export.clone())), } } @@ -512,82 +483,83 @@ impl Resolve { Ok(()) } - /// Returns the URL of the specified `interface`, if available. - /// - /// This currently creates a URL based on the URL of the package that - /// `interface` resides in. If the package owner of `interface` does not - /// specify a URL then `None` will be returned. + /// Returns the ID of the specified `interface`. /// - /// If the `interface` specified does not have a name then `None` will be - /// returned as well. - pub fn url_of(&self, interface: InterfaceId) -> Option { + /// Returns `None` for unnamed interfaces. + pub fn id_of(&self, interface: InterfaceId) -> Option { let interface = &self.interfaces[interface]; - let doc = &self.documents[interface.document]; - let package = &self.packages[doc.package.unwrap()]; - let mut base = Url::parse(package.url.as_ref()?).unwrap(); - base.path_segments_mut() - .unwrap() - .push(&doc.name) - .push(interface.name.as_ref()?); - Some(base.to_string()) + let package = &self.packages[interface.package.unwrap()]; + let mut base = String::new(); + base.push_str(&package.name.namespace); + base.push_str(":"); + base.push_str(&package.name.name); + base.push_str("/"); + base.push_str(interface.name.as_ref()?); + if let Some(version) = &package.name.version { + base.push_str(&format!("@{version}")); + } + Some(base) } - /// Attempts to locate a default world for the `pkg` specified within this - /// [`Resolve`]. Optionally takes a string-based `world` "specifier" to - /// resolve the world. + /// Attempts to locate a world given the "default" package `pkg` and the + /// optional string specifier `world`. + /// + /// This method is intended to be used by bindings generation tools to + /// select a world from either `pkg` or a package in this `Resolve`. + /// + /// If `world` is `None` then `pkg` must have precisely one world which will + /// be returned. /// - /// This is intended for use by bindings generators and such as the default - /// logic for locating a world within a package used for binding. The - /// `world` argument is typically a user-specified argument (which again is - /// optional and not required) where the `pkg` is determined ambiently by - /// the integration. + /// If `world` is `Some` then it can either be: /// - /// If `world` is `None` (e.g. not specified by a user) then the package - /// must have exactly one `default world` within its documents, otherwise an - /// error will be returned. If `world` is `Some` then it's a `.`-separated - /// name where the first element is the name of the document and the second, - /// optional, element is the name of the `world`. For example the name `foo` - /// would mean the `default world` of the `foo` document. The name `foo.bar` - /// would mean the world named `bar` in the `foo` document. + /// * A kebab-name of a world contained within `pkg` which is being + /// selected, such as `"the-world"`. + /// + /// * An ID-based form of a world which is selected within this `Resolve`, + /// ignoring `pkg`. For example `"wasi:http/proxy"`. + /// + /// If successful the corresponding `WorldId` is returned, otherwise an + /// error is returned. pub fn select_world(&self, pkg: PackageId, world: Option<&str>) -> Result { - match world { - Some(world) => { - let mut parts = world.splitn(2, '.'); - let doc = parts.next().unwrap(); - let world = parts.next(); - let doc = *self.packages[pkg] - .documents - .get(doc) - .ok_or_else(|| anyhow!("no document named `{doc}` in package"))?; - match world { - Some(name) => self.documents[doc] - .worlds - .get(name) - .copied() - .ok_or_else(|| anyhow!("no world named `{name}` in document")), - None => self.documents[doc] - .default_world - .ok_or_else(|| anyhow!("no default world in document")), - } - } + let world = match world { + Some(world) => world, None => { - if self.packages[pkg].documents.is_empty() { - bail!("no documents found in package") + let pkg = &self.packages[pkg]; + match pkg.worlds.len() { + 0 => bail!("no worlds found in package `{}`", pkg.name), + 1 => return Ok(*pkg.worlds.values().next().unwrap()), + _ => bail!( + "multiple worlds found in package `{}`: one must be explicitly chosen", + pkg.name + ), } + } + }; - let mut unique_default_world = None; - for (_name, doc) in &self.packages[pkg].documents { - if let Some(default_world) = self.documents[*doc].default_world { - if unique_default_world.is_some() { - bail!("multiple default worlds found in package, one must be specified") - } else { - unique_default_world = Some(default_world); - } - } - } + let path = parse_use_path(world) + .with_context(|| format!("failed to parse world specifier `{world}`"))?; + let (pkg, world) = match path { + AstUsePath::Name(name) => (pkg, name), + AstUsePath::Package(pkg, interface) => ( + *self + .package_names + .get(&pkg) + .ok_or_else(|| anyhow!("unknown package `{pkg}`"))?, + interface, + ), + }; + let pkg = &self.packages[pkg]; + pkg.worlds + .get(&world) + .copied() + .ok_or_else(|| anyhow!("no world named `{world}` in package")) + } - unique_default_world.ok_or_else(|| anyhow!("no default world in package")) - } + /// Assigns a human readable name to the `WorldKey` specified. + pub fn name_world_key(&self, key: &WorldKey) -> String { + match key { + WorldKey::Name(s) => s.to_string(), + WorldKey::Interface(i) => self.id_of(*i).expect("unexpected anonymous interface"), } } } @@ -599,7 +571,6 @@ pub struct Remap { pub types: Vec, pub interfaces: Vec, pub worlds: Vec, - pub documents: Vec, pub packages: Vec, } @@ -608,13 +579,11 @@ impl Remap { &mut self, resolve: &mut Resolve, unresolved: UnresolvedPackage, - deps: &HashMap, ) -> Result { - self.process_foreign_deps(resolve, &unresolved, deps)?; + self.process_foreign_deps(resolve, &unresolved)?; let foreign_types = self.types.len(); let foreign_interfaces = self.interfaces.len(); - let foreign_documents = self.documents.len(); let foreign_worlds = self.worlds.len(); // Copy over all types first, updating any intra-type references. Note @@ -675,37 +644,30 @@ impl Remap { } } - // And the final major step is transferring documents to `Resolve` - // which is just updating a few identifiers here and there. - for (id, mut doc) in unresolved.documents.into_iter().skip(foreign_documents) { - self.update_document(&mut doc); - let new_id = resolve.documents.alloc(doc); - assert_eq!(self.documents.len(), id.index()); - self.documents.push(new_id); - } - - // Fixup "parent" ids now that everything has been identifier + // Fixup "parent" ids now that everything has been identified + let pkgid = resolve.packages.alloc(Package { + name: unresolved.name.clone(), + interfaces: Default::default(), + worlds: Default::default(), + }); + let prev = resolve.package_names.insert(unresolved.name.clone(), pkgid); + assert!(prev.is_none()); for id in self.interfaces.iter().skip(foreign_interfaces) { - let doc = &mut resolve.interfaces[*id].document; - *doc = self.documents[doc.index()]; + let iface = &mut resolve.interfaces[*id]; + iface.package = Some(pkgid); + if let Some(name) = &iface.name { + let prev = resolve.packages[pkgid].interfaces.insert(name.clone(), *id); + assert!(prev.is_none()); + } } for id in self.worlds.iter().skip(foreign_worlds) { - let doc = &mut resolve.worlds[*id].document; - *doc = self.documents[doc.index()]; - } - let mut documents = IndexMap::new(); - for id in self.documents.iter().skip(foreign_documents) { - let prev = documents.insert(resolve.documents[*id].name.clone(), *id); + let world = &mut resolve.worlds[*id]; + world.package = Some(pkgid); + let prev = resolve.packages[pkgid] + .worlds + .insert(world.name.clone(), *id); assert!(prev.is_none()); } - let pkgid = resolve.packages.alloc(Package { - name: unresolved.name, - url: unresolved.url, - documents, - }); - for (_, id) in resolve.packages[pkgid].documents.iter() { - resolve.documents[*id].package = Some(pkgid); - } Ok(pkgid) } @@ -713,81 +675,62 @@ impl Remap { &mut self, resolve: &mut Resolve, unresolved: &UnresolvedPackage, - deps: &HashMap, ) -> Result<()> { - // First, connect all references to foreign documents to actual - // documents within `resolve`, building up the initial entries of - // the `self.documents` mapping. - let mut document_to_package = HashMap::new(); - for (i, (pkg, docs)) in unresolved.foreign_deps.iter().enumerate() { - for (doc, unresolved_doc_id) in docs { - let prev = document_to_package.insert( - *unresolved_doc_id, - (pkg, doc, unresolved.foreign_dep_spans[i]), + // Invert the `foreign_deps` map to be keyed by interface id to get + // used in the loops below. + let mut interface_to_package = HashMap::new(); + for (i, (pkg_name, interfaces)) in unresolved.foreign_deps.iter().enumerate() { + for (interface, unresolved_interface_id) in interfaces { + let prev = interface_to_package.insert( + *unresolved_interface_id, + (pkg_name, interface, unresolved.foreign_dep_spans[i]), ); assert!(prev.is_none()); } } - for (unresolved_doc_id, _doc) in unresolved.documents.iter() { - let (pkg, doc, span) = match document_to_package.get(&unresolved_doc_id) { - Some(items) => *items, - None => break, - }; - let pkgid = *deps.get(pkg).ok_or_else(|| Error { - span, - msg: format!("no package dependency specified for `{pkg}`"), - })?; - let package = &resolve.packages[pkgid]; - let docid = *package.documents.get(doc).ok_or_else(|| Error { - span: unresolved.document_spans[unresolved_doc_id.index()], - msg: format!("package `{pkg}` does not define document `{doc}`"), - })?; - - assert_eq!(self.documents.len(), unresolved_doc_id.index()); - self.documents.push(docid); - } - for (id, _) in unresolved.documents.iter().skip(self.documents.len()) { - assert!( - document_to_package.get(&id).is_none(), - "found foreign document after local documents" - ); - } - - // Next, for all documents that are referenced in this `Resolve` - // determine the mapping of all interfaces that they refer to. + // Connect all interfaces referred to in `interface_to_package`, which + // are at the front of `unresolved.interfaces`, to interfaces already + // contained within `resolve`. for (unresolved_iface_id, unresolved_iface) in unresolved.interfaces.iter() { - let doc_id = match self.documents.get(unresolved_iface.document.index()) { - Some(i) => *i, + let (pkg_name, interface, span) = match interface_to_package.get(&unresolved_iface_id) { + Some(items) => *items, // All foreign interfaces are defined first, so the first one // which is defined in a non-foreign document means that all // further interfaces will be non-foreign as well. None => break, }; + let pkgid = resolve + .package_names + .get(pkg_name) + .copied() + .ok_or_else(|| Error { + span, + msg: format!("package not found"), + })?; // Functions can't be imported so this should be empty. assert!(unresolved_iface.functions.is_empty()); - let document = &resolve.documents[doc_id]; + let pkg = &resolve.packages[pkgid]; let span = unresolved.interface_spans[unresolved_iface_id.index()]; - let iface_id = match &unresolved_iface.name { - Some(name) => *document.interfaces.get(name).ok_or_else(|| Error { - span, - msg: format!("interface not defined in document"), - })?, - None => document.default_interface.ok_or_else(|| Error { + let iface_id = pkg + .interfaces + .get(interface) + .copied() + .ok_or_else(|| Error { span, - msg: format!("default interface not specified in document"), - })?, - }; + msg: format!("interface not found in package"), + })?; assert_eq!(self.interfaces.len(), unresolved_iface_id.index()); self.interfaces.push(iface_id); } - for (_, iface) in unresolved.interfaces.iter().skip(self.interfaces.len()) { - if self.documents.get(iface.document.index()).is_some() { - panic!("found foreign interface after local interfaces"); - } + for (id, _) in unresolved.interfaces.iter().skip(self.interfaces.len()) { + assert!( + interface_to_package.get(&id).is_none(), + "found foreign interface after local interface" + ); } // And finally iterate over all foreign-defined types and determine @@ -812,7 +755,7 @@ impl Remap { .get(name) .ok_or_else(|| Error { span, - msg: format!("type not defined in interface"), + msg: format!("type `{name}` not defined in interface"), })?; assert_eq!(self.types.len(), unresolved_type_id.index()); self.types.push(type_id); @@ -936,81 +879,61 @@ impl Remap { // Here each import of an interface is recorded and then additionally // explicitly named imports of interfaces are recorded as well for // determining names later on. - let mut explicit_import_names = HashMap::new(); - let mut explicit_export_names = HashMap::new(); - let mut imports = Vec::new(); - let mut exports = Vec::new(); let mut import_funcs = Vec::new(); - let mut export_funcs = Vec::new(); let mut import_types = Vec::new(); - for ((name, item), span) in mem::take(&mut world.imports).into_iter().zip(import_spans) { + for ((mut name, item), span) in mem::take(&mut world.imports).into_iter().zip(import_spans) + { + self.update_world_key(&mut name); match item { WorldItem::Interface(id) => { let id = self.interfaces[id.index()]; - imports.push((id, *span)); - let prev = explicit_import_names.insert(id, name); - assert!(prev.is_none()); + self.add_world_import(resolve, world, name, id); } WorldItem::Function(mut f) => { self.update_function(&mut f); - import_funcs.push((name, f, *span)); + import_funcs.push((name.unwrap_name(), f, *span)); } WorldItem::Type(id) => { let id = self.types[id.index()]; - import_types.push((name, id, *span)); + import_types.push((name.unwrap_name(), id, *span)); + } + } + } + + for (_name, id, _span) in import_types.iter() { + if let TypeDefKind::Type(Type::Id(other)) = resolve.types[*id].kind { + if let TypeOwner::Interface(owner) = resolve.types[other].owner { + let name = WorldKey::Interface(owner); + self.add_world_import(resolve, world, name, owner); } } } - for ((name, item), span) in mem::take(&mut world.exports).into_iter().zip(export_spans) { + + let mut export_funcs = Vec::new(); + for ((mut name, item), span) in mem::take(&mut world.exports).into_iter().zip(export_spans) + { + self.update_world_key(&mut name); match item { WorldItem::Interface(id) => { let id = self.interfaces[id.index()]; - exports.push((id, *span)); - let prev = explicit_export_names.insert(id, name); - assert!(prev.is_none()); + self.add_world_export(resolve, world, name, id); } WorldItem::Function(mut f) => { self.update_function(&mut f); + let name = match name { + WorldKey::Name(name) => name, + WorldKey::Interface(_) => unreachable!(), + }; export_funcs.push((name, f, *span)); } WorldItem::Type(_) => unreachable!(), } } - // Next all imports and their transitive imports are processed. This - // is done through a `stack` of `Action` items which is processed in - // LIFO order, meaning that an action of processing the dependencies - // is pushed after processing the node itself. The dependency processing - // will push more items onto the stack as necessary. - let mut elaborate = WorldElaborator { - resolve, - world, - imports_processed: Default::default(), - exports_processed: Default::default(), - resolving_stack: Default::default(), - explicit_import_names: &explicit_import_names, - explicit_export_names: &explicit_export_names, - names: Default::default(), - }; - for (id, span) in imports { - elaborate.import(id, span)?; - } - for (_name, id, span) in import_types.iter() { - if let TypeDefKind::Type(Type::Id(other)) = resolve.types[*id].kind { - if let TypeOwner::Interface(owner) = resolve.types[other].owner { - elaborate.import(owner, *span)?; - } - } - } - for (id, span) in exports { - elaborate.export(id, span)?; - } - for (name, id, span) in import_types { - let prev = elaborate - .world + let prev = world .imports - .insert(name.clone(), WorldItem::Type(id)); + .insert(WorldKey::Name(name.clone()), WorldItem::Type(id)); if prev.is_some() { bail!(Error { msg: format!("export of type `{name}` shadows previously imported interface"), @@ -1022,7 +945,7 @@ impl Remap { for (name, func, span) in import_funcs { let prev = world .imports - .insert(name.clone(), WorldItem::Function(func)); + .insert(WorldKey::Name(name.clone()), WorldItem::Function(func)); if prev.is_some() { bail!(Error { msg: format!( @@ -1035,8 +958,8 @@ impl Remap { for (name, func, span) in export_funcs { let prev = world .exports - .insert(name.clone(), WorldItem::Function(func)); - if prev.is_some() || world.imports.contains_key(&name) { + .insert(WorldKey::Name(name.clone()), WorldItem::Function(func)); + if prev.is_some() || world.imports.contains_key(&WorldKey::Name(name.clone())) { bail!(Error { msg: format!( "export of function `{name}` shadows previously exported interface" @@ -1052,129 +975,74 @@ impl Remap { Ok(()) } - fn update_document(&self, doc: &mut Document) { - for (_name, iface) in doc.interfaces.iter_mut() { - *iface = self.interfaces[iface.index()]; - } - for (_name, world) in doc.worlds.iter_mut() { - *world = self.worlds[world.index()]; - } - if let Some(default) = &mut doc.default_interface { - *default = self.interfaces[default.index()]; - } - if let Some(default) = &mut doc.default_world { - *default = self.worlds[default.index()]; + fn update_world_key(&self, key: &mut WorldKey) { + match key { + WorldKey::Name(_) => {} + WorldKey::Interface(id) => { + *id = self.interfaces[id.index()]; + } } } -} - -struct WorldElaborator<'a, 'b> { - resolve: &'a Resolve, - world: &'b mut World, - explicit_import_names: &'a HashMap, - explicit_export_names: &'a HashMap, - names: HashMap, - - /// Set of imports which are either imported into the world already or in - /// the `stack` to get processed, used to ensure the same dependency isn't - /// pushed multiple times into the stack. - imports_processed: HashSet, - exports_processed: HashSet, - - /// Dependency chain of why we're importing the top of `stack`, used to - /// print an error message. - resolving_stack: Vec<(InterfaceId, bool)>, -} -impl<'a> WorldElaborator<'a, '_> { - fn import(&mut self, id: InterfaceId, span: Span) -> Result<()> { - self.recurse(id, span, true) - } - - fn export(&mut self, id: InterfaceId, span: Span) -> Result<()> { - self.recurse(id, span, false) - } - - fn recurse(&mut self, id: InterfaceId, span: Span, import: bool) -> Result<()> { - let processed = if import { - &mut self.imports_processed - } else { - &mut self.exports_processed - }; - if !processed.insert(id) { - return Ok(()); - } - - self.resolving_stack.push((id, import)); - for (_, ty) in self.resolve.interfaces[id].types.iter() { - let ty = match self.resolve.types[*ty].kind { - TypeDefKind::Type(Type::Id(id)) => id, - _ => continue, - }; - let dep = match self.resolve.types[ty].owner { - TypeOwner::None => continue, - TypeOwner::Interface(other) => other, - TypeOwner::World(_) => unreachable!(), - }; - let import = import || !self.explicit_export_names.contains_key(&dep); - - self.recurse(dep, span, import)?; + fn add_world_import( + &self, + resolve: &Resolve, + world: &mut World, + key: WorldKey, + id: InterfaceId, + ) { + if world.imports.contains_key(&key) { + return; } - assert_eq!(self.resolving_stack.pop(), Some((id, import))); - let name = self.name_of(id, import); - let prev = self.names.insert(name.clone(), import); + foreach_interface_dep(resolve, id, |dep| { + self.add_world_import(resolve, world, WorldKey::Interface(dep), dep); + }); + let prev = world.imports.insert(key, WorldItem::Interface(id)); + assert!(prev.is_none()); + } - if prev.is_none() { - let set = if import { - &mut self.world.imports - } else { - &mut self.world.exports - }; - let prev = set.insert(name.clone(), WorldItem::Interface(id)); - assert!(prev.is_none()); - return Ok(()); + fn add_world_export( + &self, + resolve: &Resolve, + world: &mut World, + key: WorldKey, + id: InterfaceId, + ) { + if world + .exports + .insert(key, WorldItem::Interface(id)) + .is_some() + { + return; } - let desc = |import: bool| { - if import { - "import" - } else { - "export" + foreach_interface_dep(resolve, id, |dep| { + if !world.exports.contains_key(&WorldKey::Interface(dep)) { + self.add_world_import(resolve, world, WorldKey::Interface(dep), dep); } - }; - - let mut msg = format!("{} of `{}`", desc(import), self.name_of(id, import)); - if self.resolving_stack.is_empty() { - msg.push_str(" "); - } else { - msg.push_str("\n"); - } - for (i, import) in self.resolving_stack.iter().rev() { - writeln!( - msg, - " .. which is depended on by {} `{}`", - desc(*import), - self.name_of(*i, *import) - ) - .unwrap(); - } - writeln!( - msg, - "conflicts with a previous interface using the name `{name}`", - ) - .unwrap(); - bail!(Error { span, msg }) + }); } +} - fn name_of(&self, id: InterfaceId, import: bool) -> &'a String { - let set = if import { - &self.explicit_import_names - } else { - &self.explicit_export_names +fn foreach_interface_dep( + resolve: &Resolve, + interface: InterfaceId, + mut f: impl FnMut(InterfaceId), +) { + for (_, ty) in resolve.interfaces[interface].types.iter() { + let ty = match resolve.types[*ty].kind { + TypeDefKind::Type(Type::Id(id)) => id, + _ => continue, + }; + let dep = match resolve.types[ty].owner { + TypeOwner::None => continue, + TypeOwner::Interface(other) => other, + TypeOwner::World(_) => unreachable!(), }; - set.get(&id) - .unwrap_or_else(|| self.resolve.interfaces[id].name.as_ref().unwrap()) + if dep != interface { + f(dep); + } } } @@ -1191,10 +1059,6 @@ struct MergeMap<'a> { /// found to be equivalent. type_map: HashMap, - /// A map of document ids in `from` to those in `into` for those that are - /// found to be equivalent. - doc_map: HashMap, - /// A map of world ids in `from` to those in `into` for those that are /// found to be equivalent. world_map: HashMap, @@ -1203,68 +1067,46 @@ struct MergeMap<'a> { /// /// The elements here are: /// - /// * The name of the document + /// * The name of the interface/world /// * The ID within `into` of the package being added to - /// * The ID within `from` of the document being added. - documents_to_add: Vec<(String, PackageId, DocumentId)>, - interfaces_to_add: Vec<(String, DocumentId, InterfaceId)>, - worlds_to_add: Vec<(String, DocumentId, WorldId)>, + /// * The ID within `from` of the item being added. + interfaces_to_add: Vec<(String, PackageId, InterfaceId)>, + worlds_to_add: Vec<(String, PackageId, WorldId)>, /// Which `Resolve` is being merged from. from: &'a Resolve, /// Which `Resolve` is being merged into. into: &'a Resolve, - - /// A cache of packages, keyed by name/url, within `into`. - packages_in_into: HashMap<(&'a String, &'a Option), PackageId>, } impl<'a> MergeMap<'a> { fn new(from: &'a Resolve, into: &'a Resolve) -> Result> { - let mut packages_in_into = HashMap::new(); - for (id, package) in into.packages.iter() { - log::trace!("previous package {}/{:?}", package.name, package.url); - if package.url.is_none() { - continue; - } - let prev = packages_in_into.insert((&package.name, &package.url), id); - if prev.is_some() { - bail!( - "found duplicate name/url combination in current resolve: {}/{:?}", - package.name, - package.url - ); - } - } Ok(MergeMap { package_map: Default::default(), interface_map: Default::default(), type_map: Default::default(), - doc_map: Default::default(), world_map: Default::default(), - documents_to_add: Default::default(), interfaces_to_add: Default::default(), worlds_to_add: Default::default(), from, into, - packages_in_into, }) } fn build(&mut self) -> Result<()> { for (from_id, from) in self.from.packages.iter() { - let into_id = match self.packages_in_into.get(&(&from.name, &from.url)) { + let into_id = match self.into.package_names.get(&from.name) { Some(id) => *id, // This package, according to its name and url, is not present // in `self` so it needs to get added below. None => { - log::trace!("adding unique package {} / {:?}", from.name, from.url); + log::trace!("adding unique package {}", from.name); continue; } }; - log::trace!("merging duplicate package {} / {:?}", from.name, from.url); + log::trace!("merging duplicate package {}", from.name); self.build_package(from_id, into_id).with_context(|| { format!("failed to merge package `{}` into existing copy", from.name) @@ -1281,40 +1123,11 @@ impl<'a> MergeMap<'a> { let from = &self.from.packages[from_id]; let into = &self.into.packages[into_id]; - // All documents in `from` should already be present in `into` to get - // merged, or it's assumed `self.from` contains a view of the package - // which happens to contain more files. In this situation the job of - // merging will be to add a new document to the package within - // `self.into` which is queued up with `self.documents_to_add`. - for (name, from_id) in from.documents.iter() { - let into_id = match into.documents.get(name) { - Some(id) => *id, - None => { - self.documents_to_add - .push((name.clone(), into_id, *from_id)); - continue; - } - }; - - self.build_document(*from_id, into_id) - .with_context(|| format!("failed to merge document `{name}` into existing copy"))?; - } - - Ok(()) - } - - fn build_document(&mut self, from_id: DocumentId, into_id: DocumentId) -> Result<()> { - let prev = self.doc_map.insert(from_id, into_id); - assert!(prev.is_none()); - - let from_doc = &self.from.documents[from_id]; - let into_doc = &self.into.documents[into_id]; - - // Like documents above if an interface is present in `from_id` but not - // present in `into_id` then it can be copied over wholesale. That - // copy is scheduled to happen within the `self.interfaces_to_add` list. - for (name, from_interface_id) in from_doc.interfaces.iter() { - let into_interface_id = match into_doc.interfaces.get(name) { + // If an interface is present in `from_id` but not present in `into_id` + // then it can be copied over wholesale. That copy is scheduled to + // happen within the `self.interfaces_to_add` list. + for (name, from_interface_id) in from.interfaces.iter() { + let into_interface_id = match into.interfaces.get(name) { Some(id) => *id, None => { self.interfaces_to_add @@ -1327,8 +1140,8 @@ impl<'a> MergeMap<'a> { .with_context(|| format!("failed to merge interface `{name}`"))?; } - for (name, from_world_id) in from_doc.worlds.iter() { - let into_world_id = match into_doc.worlds.get(name) { + for (name, from_world_id) in from.worlds.iter() { + let into_world_id = match into.worlds.get(name) { Some(id) => *id, None => { self.worlds_to_add @@ -1340,6 +1153,7 @@ impl<'a> MergeMap<'a> { self.build_world(*from_world_id, into_world_id) .with_context(|| format!("failed to merge world `{name}`"))?; } + Ok(()) } @@ -1411,27 +1225,40 @@ impl<'a> MergeMap<'a> { bail!("world contains different number of exports than expected"); } - for (name, from) in from_world.imports.iter() { + for (from_name, from) in from_world.imports.iter() { + let into_name = self.map_name(from_name); + let name_str = self.from.name_world_key(from_name); let into = into_world .imports - .get(name) - .ok_or_else(|| anyhow!("import `{name}` not found in target world"))?; + .get(&into_name) + .ok_or_else(|| anyhow!("import `{name_str}` not found in target world"))?; self.match_world_item(from, into) - .with_context(|| format!("import `{name}` didn't match target world"))?; + .with_context(|| format!("import `{name_str}` didn't match target world"))?; } - for (name, from) in from_world.exports.iter() { + for (from_name, from) in from_world.exports.iter() { + let into_name = self.map_name(from_name); + let name_str = self.from.name_world_key(from_name); let into = into_world .exports - .get(name) - .ok_or_else(|| anyhow!("export `{name}` not found in target world"))?; + .get(&into_name) + .ok_or_else(|| anyhow!("export `{name_str}` not found in target world"))?; self.match_world_item(from, into) - .with_context(|| format!("export `{name}` didn't match target world"))?; + .with_context(|| format!("export `{name_str}` didn't match target world"))?; } Ok(()) } + fn map_name(&self, from_name: &WorldKey) -> WorldKey { + match from_name { + WorldKey::Name(s) => WorldKey::Name(s.clone()), + WorldKey::Interface(id) => { + WorldKey::Interface(self.interface_map.get(id).copied().unwrap_or(*id)) + } + } + } + fn match_world_item(&mut self, from: &WorldItem, into: &WorldItem) -> Result<()> { match (from, into) { (WorldItem::Interface(from), WorldItem::Interface(into)) => { diff --git a/crates/wit-parser/tests/all.rs b/crates/wit-parser/tests/all.rs index 8e41fc5b91..c1c1132c66 100644 --- a/crates/wit-parser/tests/all.rs +++ b/crates/wit-parser/tests/all.rs @@ -106,7 +106,7 @@ impl Runner<'_> { let result = if test.is_dir() { resolve.push_dir(test).map(|(id, _)| id) } else { - UnresolvedPackage::parse_file(test).and_then(|p| resolve.push(p, &Default::default())) + UnresolvedPackage::parse_file(test).and_then(|p| resolve.push(p)) }; let result = if test.iter().any(|s| s == "parse-fail") { diff --git a/crates/wit-parser/tests/ui/comments.wit b/crates/wit-parser/tests/ui/comments.wit index 9b38918e7f..bb899d0641 100644 --- a/crates/wit-parser/tests/ui/comments.wit +++ b/crates/wit-parser/tests/ui/comments.wit @@ -1,3 +1,5 @@ +package foo:comments + // hello // world // why, yes diff --git a/crates/wit-parser/tests/ui/diamond1/deps/dep1/types.wit b/crates/wit-parser/tests/ui/diamond1/deps/dep1/types.wit new file mode 100644 index 0000000000..9e7afb30ae --- /dev/null +++ b/crates/wit-parser/tests/ui/diamond1/deps/dep1/types.wit @@ -0,0 +1,2 @@ +package foo:dep1 +interface types {} diff --git a/crates/wit-parser/tests/ui/diamond1/deps/dep2/types.wit b/crates/wit-parser/tests/ui/diamond1/deps/dep2/types.wit new file mode 100644 index 0000000000..8825ffb02f --- /dev/null +++ b/crates/wit-parser/tests/ui/diamond1/deps/dep2/types.wit @@ -0,0 +1,2 @@ +package foo:dep2 +interface types {} diff --git a/crates/wit-parser/tests/ui/diamond1/join.wit b/crates/wit-parser/tests/ui/diamond1/join.wit new file mode 100644 index 0000000000..a6c4208fc2 --- /dev/null +++ b/crates/wit-parser/tests/ui/diamond1/join.wit @@ -0,0 +1,6 @@ +package foo:foo + +world foo { + import foo:dep1/types + import foo:dep2/types +} diff --git a/crates/wit-parser/tests/ui/disambiguate-diamond/shared1.wit b/crates/wit-parser/tests/ui/disambiguate-diamond/shared1.wit index e65165ac2d..f655d9b009 100644 --- a/crates/wit-parser/tests/ui/disambiguate-diamond/shared1.wit +++ b/crates/wit-parser/tests/ui/disambiguate-diamond/shared1.wit @@ -1,3 +1,3 @@ -default interface shared { +interface shared1 { type the-type = u32 } diff --git a/crates/wit-parser/tests/ui/disambiguate-diamond/shared2.wit b/crates/wit-parser/tests/ui/disambiguate-diamond/shared2.wit index e65165ac2d..4e19192462 100644 --- a/crates/wit-parser/tests/ui/disambiguate-diamond/shared2.wit +++ b/crates/wit-parser/tests/ui/disambiguate-diamond/shared2.wit @@ -1,3 +1,3 @@ -default interface shared { +interface shared2 { type the-type = u32 } diff --git a/crates/wit-parser/tests/ui/disambiguate-diamond/world.wit b/crates/wit-parser/tests/ui/disambiguate-diamond/world.wit index 80ab9be490..f9021b731f 100644 --- a/crates/wit-parser/tests/ui/disambiguate-diamond/world.wit +++ b/crates/wit-parser/tests/ui/disambiguate-diamond/world.wit @@ -1,11 +1,13 @@ +package foo:diamond + world foo { import foo: interface { - use pkg.shared1.{the-type} + use shared1.{the-type} } import bar: interface { - use pkg.shared2.{the-type} + use shared2.{the-type} } - import shared1: pkg.shared1 - import shared2: pkg.shared2 + import shared1 + import shared2 } diff --git a/crates/wit-parser/tests/ui/embedded.wit.md b/crates/wit-parser/tests/ui/embedded.wit.md index e9ea859192..4bfaa2a344 100644 --- a/crates/wit-parser/tests/ui/embedded.wit.md +++ b/crates/wit-parser/tests/ui/embedded.wit.md @@ -3,6 +3,8 @@ containing stuff, and also some code blocks, wit and other. ```wit +package foo:foo + interface foo { ``` diff --git a/crates/wit-parser/tests/ui/empty.wit b/crates/wit-parser/tests/ui/empty.wit index e69de29bb2..cfc0ac5ba2 100644 --- a/crates/wit-parser/tests/ui/empty.wit +++ b/crates/wit-parser/tests/ui/empty.wit @@ -0,0 +1 @@ +package foo:empty diff --git a/crates/wit-parser/tests/ui/foreign-deps/deps/another-pkg/other-doc.wit b/crates/wit-parser/tests/ui/foreign-deps/deps/another-pkg/other-doc.wit index 04933294d2..dc584c6302 100644 --- a/crates/wit-parser/tests/ui/foreign-deps/deps/another-pkg/other-doc.wit +++ b/crates/wit-parser/tests/ui/foreign-deps/deps/another-pkg/other-doc.wit @@ -1 +1,3 @@ +package foo:another-pkg + interface other-interface {} diff --git a/crates/wit-parser/tests/ui/foreign-deps/deps/corp/saas.wit b/crates/wit-parser/tests/ui/foreign-deps/deps/corp/saas.wit index 5a2b10d0d0..f476b526d3 100644 --- a/crates/wit-parser/tests/ui/foreign-deps/deps/corp/saas.wit +++ b/crates/wit-parser/tests/ui/foreign-deps/deps/corp/saas.wit @@ -1,2 +1,4 @@ -default interface saas { +package foo:corp + +interface saas { } diff --git a/crates/wit-parser/tests/ui/foreign-deps/deps/different-pkg/the-doc.wit b/crates/wit-parser/tests/ui/foreign-deps/deps/different-pkg/the-doc.wit index f192837fb6..ddeeab873f 100644 --- a/crates/wit-parser/tests/ui/foreign-deps/deps/different-pkg/the-doc.wit +++ b/crates/wit-parser/tests/ui/foreign-deps/deps/different-pkg/the-doc.wit @@ -1 +1,2 @@ -default interface i {} +package foo:different-pkg +interface i {} diff --git a/crates/wit-parser/tests/ui/foreign-deps/deps/foreign-pkg/the-doc.wit b/crates/wit-parser/tests/ui/foreign-deps/deps/foreign-pkg/the-doc.wit index 1fb9bad8de..cba7a70e9f 100644 --- a/crates/wit-parser/tests/ui/foreign-deps/deps/foreign-pkg/the-doc.wit +++ b/crates/wit-parser/tests/ui/foreign-deps/deps/foreign-pkg/the-doc.wit @@ -1,3 +1,5 @@ -default interface the-default { +package foo:foreign-pkg + +interface the-default { type some-type = u32 } diff --git a/crates/wit-parser/tests/ui/foreign-deps/deps/some-pkg/some-doc.wit b/crates/wit-parser/tests/ui/foreign-deps/deps/some-pkg/some-doc.wit index 8228c1d6f0..3bad202e2a 100644 --- a/crates/wit-parser/tests/ui/foreign-deps/deps/some-pkg/some-doc.wit +++ b/crates/wit-parser/tests/ui/foreign-deps/deps/some-pkg/some-doc.wit @@ -1,4 +1,6 @@ -default interface the-default { +package foo:some-pkg + +interface the-default { type from-default = string } diff --git a/crates/wit-parser/tests/ui/foreign-deps/deps/wasi/clocks.wit b/crates/wit-parser/tests/ui/foreign-deps/deps/wasi/clocks.wit index 18a3575649..0ea67674ad 100644 --- a/crates/wit-parser/tests/ui/foreign-deps/deps/wasi/clocks.wit +++ b/crates/wit-parser/tests/ui/foreign-deps/deps/wasi/clocks.wit @@ -1,3 +1,5 @@ -default interface wasi-clocks { +package foo:wasi + +interface clocks { type timestamp = u64 } diff --git a/crates/wit-parser/tests/ui/foreign-deps/deps/wasi/filesystem.wit b/crates/wit-parser/tests/ui/foreign-deps/deps/wasi/filesystem.wit index b0a97a6cda..1ed63e3da3 100644 --- a/crates/wit-parser/tests/ui/foreign-deps/deps/wasi/filesystem.wit +++ b/crates/wit-parser/tests/ui/foreign-deps/deps/wasi/filesystem.wit @@ -1,4 +1,6 @@ -default interface wasi-filesystem { +package foo:wasi + +interface filesystem { record stat { ino: u64 } diff --git a/crates/wit-parser/tests/ui/foreign-deps/root.wit b/crates/wit-parser/tests/ui/foreign-deps/root.wit index d2325e855a..557cbda2f9 100644 --- a/crates/wit-parser/tests/ui/foreign-deps/root.wit +++ b/crates/wit-parser/tests/ui/foreign-deps/root.wit @@ -1,31 +1,44 @@ +package foo:root + interface foo { - use wasi.clocks.{timestamp} - use wasi.filesystem.{stat} + use foo:wasi/clocks.{timestamp} + use foo:wasi/filesystem.{stat} } world my-world { - import wasi-fs: wasi.filesystem - import wasi-clocks: wasi.clocks + import foo:wasi/filesystem + import foo:wasi/clocks + + export foo:corp/saas +} + +use foo:wasi/filesystem as filesystem +use foo:wasi/clocks as clocks - export saas: corp.saas +world my-world2 { + import filesystem + import clocks + export foo + export foo:corp/saas } interface bar { - use some-pkg.some-doc.{from-default} - use some-pkg.some-doc.some-interface.{another-type} - use some-pkg.some-doc.some-interface.{} - use some-pkg.some-doc.another-interface.{yet-another-type} - use different-pkg.the-doc.{} + use filesystem.{} + use foo:some-pkg/the-default.{from-default} + use foo:some-pkg/some-interface.{another-type} + use foo:some-pkg/some-interface.{} + use foo:some-pkg/another-interface.{yet-another-type} + use foo:different-pkg/i.{} } world bars-world { - import foo: some-pkg.some-doc - import bar: another-pkg.other-doc.other-interface + import foo:some-pkg/the-default + import foo:another-pkg/other-interface } interface use1 { - use foreign-pkg.the-doc.{some-type} + use foo:foreign-pkg/the-default.{some-type} } interface use2 { - use foreign-pkg.the-doc.{some-type} + use foo:foreign-pkg/the-default.{some-type} } diff --git a/crates/wit-parser/tests/ui/functions.wit b/crates/wit-parser/tests/ui/functions.wit index 4ff518ac7e..b08183a9b6 100644 --- a/crates/wit-parser/tests/ui/functions.wit +++ b/crates/wit-parser/tests/ui/functions.wit @@ -1,3 +1,5 @@ +package foo:functions + interface functions { f1: func() f2: func(a: u32) diff --git a/crates/wit-parser/tests/ui/many-names/a.wit b/crates/wit-parser/tests/ui/many-names/a.wit new file mode 100644 index 0000000000..e3f9eab0a9 --- /dev/null +++ b/crates/wit-parser/tests/ui/many-names/a.wit @@ -0,0 +1,2 @@ +interface x {} +use x as name diff --git a/crates/wit-parser/tests/ui/many-names/b.wit b/crates/wit-parser/tests/ui/many-names/b.wit new file mode 100644 index 0000000000..b603f1762f --- /dev/null +++ b/crates/wit-parser/tests/ui/many-names/b.wit @@ -0,0 +1,5 @@ +package foo:name + +world name { + import name: interface {} +} diff --git a/crates/wit-parser/tests/ui/multi-file/bar.wit b/crates/wit-parser/tests/ui/multi-file/bar.wit index 9946d4ba33..67f33432c2 100644 --- a/crates/wit-parser/tests/ui/multi-file/bar.wit +++ b/crates/wit-parser/tests/ui/multi-file/bar.wit @@ -1,9 +1,11 @@ -default interface irrelevant-name { +package foo:multi-file + +interface irrelevant-name { record a-name {} } interface depends-on-later-item { - use self.depend-on-me.{x} + use depend-on-me.{x} } interface depend-on-me { @@ -11,8 +13,8 @@ interface depend-on-me { } world more-depends-on-later-things { - import foo: self.later-interface - export bar: self.later-interface + import later-interface + export later-interface } interface later-interface { diff --git a/crates/wit-parser/tests/ui/multi-file/cycle-a.wit b/crates/wit-parser/tests/ui/multi-file/cycle-a.wit new file mode 100644 index 0000000000..559ee39238 --- /dev/null +++ b/crates/wit-parser/tests/ui/multi-file/cycle-a.wit @@ -0,0 +1,7 @@ +interface cycle1 { + type t = u32 +} + +interface cycle3 { + use cycle2.{t} +} diff --git a/crates/wit-parser/tests/ui/multi-file/cycle-b.wit b/crates/wit-parser/tests/ui/multi-file/cycle-b.wit new file mode 100644 index 0000000000..85f2612962 --- /dev/null +++ b/crates/wit-parser/tests/ui/multi-file/cycle-b.wit @@ -0,0 +1,3 @@ +interface cycle2 { + use cycle1.{t} +} diff --git a/crates/wit-parser/tests/ui/multi-file/foo.wit b/crates/wit-parser/tests/ui/multi-file/foo.wit index cf9e621b29..7992d2ef3e 100644 --- a/crates/wit-parser/tests/ui/multi-file/foo.wit +++ b/crates/wit-parser/tests/ui/multi-file/foo.wit @@ -1,15 +1,31 @@ +package foo:multi-file + interface foo { type x = u32 } -default interface something-else { +use foo as foo2 + +interface something-else { type y = u64 } +use depend-on-me as a-different-name + interface bar { - use self.foo.{x} - use pkg.foo.foo.{x as x2} - use pkg.foo.{y} - use self.something-else.{y as y2} - use pkg.bar.{a-name} + use foo.{x} + use foo.{x as x2} + use foo2.{x as x3} + use a-different-name.{x as x4} + use something-else.{y} + use something-else.{y as y2} + use irrelevant-name.{a-name} +} + +world the-world { + import a-different-name + + use a-different-name.{x} + + import foo: func() -> x } diff --git a/crates/wit-parser/tests/ui/package-syntax1.wit b/crates/wit-parser/tests/ui/package-syntax1.wit new file mode 100644 index 0000000000..5a649110c2 --- /dev/null +++ b/crates/wit-parser/tests/ui/package-syntax1.wit @@ -0,0 +1 @@ +package foo:foo diff --git a/crates/wit-parser/tests/ui/package-syntax3.wit b/crates/wit-parser/tests/ui/package-syntax3.wit new file mode 100644 index 0000000000..4e7ea6c552 --- /dev/null +++ b/crates/wit-parser/tests/ui/package-syntax3.wit @@ -0,0 +1 @@ +package foo:bar diff --git a/crates/wit-parser/tests/ui/package-syntax4.wit b/crates/wit-parser/tests/ui/package-syntax4.wit new file mode 100644 index 0000000000..08a4d024e7 --- /dev/null +++ b/crates/wit-parser/tests/ui/package-syntax4.wit @@ -0,0 +1 @@ +package foo:bar@2.0.0 diff --git a/crates/wit-parser/tests/ui/parse-fail/alias-no-type.wit.result b/crates/wit-parser/tests/ui/parse-fail/alias-no-type.wit.result index 6b9c20d947..d25b316c26 100644 --- a/crates/wit-parser/tests/ui/parse-fail/alias-no-type.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/alias-no-type.wit.result @@ -1,5 +1 @@ -type `bar` does not exist - --> tests/ui/parse-fail/alias-no-type.wit:3:14 - | - 3 | type foo = bar - | ^-- \ No newline at end of file +no `package` header was found in any WIT file for this package \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-diamond.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-diamond.wit.result deleted file mode 100644 index 71c657210b..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-diamond.wit.result +++ /dev/null @@ -1,8 +0,0 @@ -import of `shared` - .. which is depended on by import `b` -conflicts with a previous interface using the name `shared` - - --> tests/ui/parse-fail/bad-diamond/join.wit:3:10 - | - 3 | import b: pkg.b - | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-diamond/a.wit b/crates/wit-parser/tests/ui/parse-fail/bad-diamond/a.wit deleted file mode 100644 index 0c33f97761..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-diamond/a.wit +++ /dev/null @@ -1,9 +0,0 @@ -interface shared { - type foo = u32 -} - -default interface a { - use self.shared.{foo} - - a: func() -> foo -} diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-diamond/b.wit b/crates/wit-parser/tests/ui/parse-fail/bad-diamond/b.wit deleted file mode 100644 index 3aeda1af16..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-diamond/b.wit +++ /dev/null @@ -1,9 +0,0 @@ -interface shared { - type foo = u32 -} - -default interface b { - use self.shared.{foo} - - a: func() -> foo -} diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-diamond/join.wit b/crates/wit-parser/tests/ui/parse-fail/bad-diamond/join.wit deleted file mode 100644 index 289cf6df5a..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-diamond/join.wit +++ /dev/null @@ -1,4 +0,0 @@ -world foo { - import a: pkg.a - import b: pkg.b -} diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-function.wit b/crates/wit-parser/tests/ui/parse-fail/bad-function.wit index 202abb5a72..2c25621b9f 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-function.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-function.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + interface foo { x: func(param: nonexistent) } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-function.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-function.wit.result index a5c199de70..79120745a7 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-function.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-function.wit.result @@ -1,5 +1,5 @@ name `nonexistent` is not defined - --> tests/ui/parse-fail/bad-function.wit:4:18 + --> tests/ui/parse-fail/bad-function.wit:6:18 | - 4 | x: func(param: nonexistent) + 6 | x: func(param: nonexistent) | ^---------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-function2.wit b/crates/wit-parser/tests/ui/parse-fail/bad-function2.wit index c80e3e670f..ed121e2872 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-function2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-function2.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + interface foo { x: func() -> nonexistent } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-function2.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-function2.wit.result index e2ea68da10..910a88f41d 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-function2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-function2.wit.result @@ -1,5 +1,5 @@ name `nonexistent` is not defined - --> tests/ui/parse-fail/bad-function2.wit:4:16 + --> tests/ui/parse-fail/bad-function2.wit:6:16 | - 4 | x: func() -> nonexistent + 6 | x: func() -> nonexistent | ^---------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg1.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-pkg1.wit.result index b55b5e3631..e664619234 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg1.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg1.wit.result @@ -1,5 +1,8 @@ -dependency on `nonexistent` doesn't exist at: tests/ui/parse-fail/bad-pkg1/deps/nonexistent - --> tests/ui/parse-fail/bad-pkg1/root.wit:2:7 - | - 2 | use nonexistent.foo.{} - | ^---------- \ No newline at end of file +failed to parse package: tests/ui/parse-fail/bad-pkg1 + +Caused by: + interface `nonexistent` not found in package + --> tests/ui/parse-fail/bad-pkg1/root.wit:4:7 + | + 4 | use nonexistent.{} + | ^---------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg1/root.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg1/root.wit index 7b0d8a0ff8..b93a124941 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg1/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg1/root.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { - use nonexistent.foo.{} + use nonexistent.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg2.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-pkg2.wit.result index 9cd96bd756..8b7201ea12 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg2.wit.result @@ -1,5 +1,5 @@ -package `bar` does not define document `nonexistent` - --> tests/ui/parse-fail/bad-pkg2/root.wit:2:11 +interface not found in package + --> tests/ui/parse-fail/bad-pkg2/root.wit:4:15 | - 2 | use bar.nonexistent.{} - | ^---------- \ No newline at end of file + 4 | use foo:bar/nonexistent.{} + | ^---------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg2/deps/bar/empty.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg2/deps/bar/empty.wit new file mode 100644 index 0000000000..4e7ea6c552 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg2/deps/bar/empty.wit @@ -0,0 +1 @@ +package foo:bar diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg2/root.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg2/root.wit index eee9664002..eb653b44d4 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg2/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg2/root.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { - use bar.nonexistent.{} + use foo:bar/nonexistent.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg3.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-pkg3.wit.result index 432a7dffeb..f2e6683b67 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg3.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg3.wit.result @@ -1,5 +1,5 @@ -default interface not specified in document - --> tests/ui/parse-fail/bad-pkg3/root.wit:2:11 +interface not found in package + --> tests/ui/parse-fail/bad-pkg3/root.wit:4:15 | - 2 | use bar.baz.{} - | ^-- \ No newline at end of file + 4 | use foo:bar/baz.{} + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg3/deps/bar/baz.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg3/deps/bar/baz.wit index e69de29bb2..80ffc36d84 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg3/deps/bar/baz.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg3/deps/bar/baz.wit @@ -0,0 +1,2 @@ +package foo:bar +world baz {} diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg3/root.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg3/root.wit index 5bc31123f5..7c76fc549b 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg3/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg3/root.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { - use bar.baz.{} + use foo:bar/baz.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg4.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-pkg4.wit.result index cdf2fba8c3..3657cd14ac 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg4.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg4.wit.result @@ -1,5 +1,5 @@ -type not defined in interface - --> tests/ui/parse-fail/bad-pkg4/root.wit:2:16 +type `a-name` not defined in interface + --> tests/ui/parse-fail/bad-pkg4/root.wit:3:20 | - 2 | use bar.baz.{a-name} - | ^----- \ No newline at end of file + 3 | use foo:bar/baz.{a-name} + | ^----- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg4/deps/bar/baz.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg4/deps/bar/baz.wit index baa2185796..239ac3bd80 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg4/deps/bar/baz.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg4/deps/bar/baz.wit @@ -1,3 +1,4 @@ -default interface irrelevant-name { +package foo:bar +interface baz { a-name: func() } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg4/root.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg4/root.wit index f1af5052ee..5de0ff6b9d 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg4/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg4/root.wit @@ -1,3 +1,4 @@ +package foo:foo interface foo { - use bar.baz.{a-name} + use foo:bar/baz.{a-name} } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg5.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-pkg5.wit.result index da07d92785..500d74cf74 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg5.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg5.wit.result @@ -1,5 +1,5 @@ -type not defined in interface - --> tests/ui/parse-fail/bad-pkg5/root.wit:2:16 +type `nonexistent` not defined in interface + --> tests/ui/parse-fail/bad-pkg5/root.wit:3:20 | - 2 | use bar.baz.{nonexistent} - | ^---------- \ No newline at end of file + 3 | use foo:bar/baz.{nonexistent} + | ^---------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg5/deps/bar/baz.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg5/deps/bar/baz.wit index 65ffc3ac20..6bdda5bbc4 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg5/deps/bar/baz.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg5/deps/bar/baz.wit @@ -1,2 +1,3 @@ -default interface irrelevant-name { +package foo:bar +interface baz { } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg5/root.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg5/root.wit index 0f19c0cce9..f4d8ea5684 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg5/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg5/root.wit @@ -1,3 +1,4 @@ +package foo:foo interface foo { - use bar.baz.{nonexistent} + use foo:bar/baz.{nonexistent} } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg6.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-pkg6.wit.result index 91c24db610..73c73a9be0 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg6.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg6.wit.result @@ -1,5 +1,5 @@ -interface not defined in document - --> tests/ui/parse-fail/bad-pkg6/root.wit:2:15 +failed to find package `foo:bar` in `deps` directory + --> tests/ui/parse-fail/bad-pkg6/root.wit:3:7 | - 2 | use bar.baz.nonexistent.{} - | ^---------- \ No newline at end of file + 3 | use foo:bar/baz.{} + | ^------ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg6/deps/bar/baz.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg6/deps/bar/baz.wit index e69de29bb2..195539f4c0 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg6/deps/bar/baz.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg6/deps/bar/baz.wit @@ -0,0 +1,4 @@ +package foo:baz + +interface bar {} + diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg6/root.wit b/crates/wit-parser/tests/ui/parse-fail/bad-pkg6/root.wit index 7c244a4d42..7c3602d6f0 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-pkg6/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-pkg6/root.wit @@ -1,3 +1,4 @@ +package foo:foo interface foo { - use bar.baz.nonexistent.{} + use foo:bar/baz.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-world-type1.wit b/crates/wit-parser/tests/ui/parse-fail/bad-world-type1.wit index 0fbd79fd2e..6c5a15374a 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-world-type1.wit +++ b/crates/wit-parser/tests/ui/parse-fail/bad-world-type1.wit @@ -1,3 +1,4 @@ +package foo:foo world a { type a = u32 import a: func() diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-world-type1.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-world-type1.wit.result index 3c993d17c0..2b32378d5d 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-world-type1.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/bad-world-type1.wit.result @@ -1,5 +1,5 @@ import `a` conflicts with prior import of same name - --> tests/ui/parse-fail/bad-world-type1.wit:3:10 + --> tests/ui/parse-fail/bad-world-type1.wit:4:10 | - 3 | import a: func() + 4 | import a: func() | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-world-type2.wit.result b/crates/wit-parser/tests/ui/parse-fail/bad-world-type2.wit.result deleted file mode 100644 index 054382328f..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/bad-world-type2.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -import of function `foo` shadows previously imported interface - --> tests/ui/parse-fail/bad-world-type2.wit:8:10 - | - 8 | import foo: func() - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/conflicting-package.wit.result b/crates/wit-parser/tests/ui/parse-fail/conflicting-package.wit.result new file mode 100644 index 0000000000..2b18334ff8 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/conflicting-package.wit.result @@ -0,0 +1,8 @@ +failed to parse package: tests/ui/parse-fail/conflicting-package + +Caused by: + package identifier `foo:b` does not match previous package name of `foo:a` + --> tests/ui/parse-fail/conflicting-package/b.wit:1:9 + | + 1 | package foo:b + | ^---- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/conflicting-package/a.wit b/crates/wit-parser/tests/ui/parse-fail/conflicting-package/a.wit new file mode 100644 index 0000000000..9cd1c0eccf --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/conflicting-package/a.wit @@ -0,0 +1 @@ +package foo:a diff --git a/crates/wit-parser/tests/ui/parse-fail/conflicting-package/b.wit b/crates/wit-parser/tests/ui/parse-fail/conflicting-package/b.wit new file mode 100644 index 0000000000..860805c624 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/conflicting-package/b.wit @@ -0,0 +1 @@ +package foo:b diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle.wit b/crates/wit-parser/tests/ui/parse-fail/cycle.wit index 707477b7e2..335595d8a1 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle.wit +++ b/crates/wit-parser/tests/ui/parse-fail/cycle.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { type foo = foo diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle.wit.result b/crates/wit-parser/tests/ui/parse-fail/cycle.wit.result index fbb1a6457a..3639b3c217 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/cycle.wit.result @@ -1,5 +1,5 @@ type `foo` depends on itself - --> tests/ui/parse-fail/cycle.wit:4:14 + --> tests/ui/parse-fail/cycle.wit:5:14 | - 4 | type foo = foo + 5 | type foo = foo | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle2.wit b/crates/wit-parser/tests/ui/parse-fail/cycle2.wit index 28e6b6aa1a..65aab1a86b 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/cycle2.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { type foo = bar diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle2.wit.result b/crates/wit-parser/tests/ui/parse-fail/cycle2.wit.result index 946175ab6b..2e4a52900e 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/cycle2.wit.result @@ -1,5 +1,5 @@ type `bar` depends on itself - --> tests/ui/parse-fail/cycle2.wit:4:14 + --> tests/ui/parse-fail/cycle2.wit:5:14 | - 4 | type foo = bar + 5 | type foo = bar | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle3.wit b/crates/wit-parser/tests/ui/parse-fail/cycle3.wit index 8bcc56666d..59a42a32c9 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle3.wit +++ b/crates/wit-parser/tests/ui/parse-fail/cycle3.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { type foo = bar diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle3.wit.result b/crates/wit-parser/tests/ui/parse-fail/cycle3.wit.result index facc6386e7..ffdfec0aa2 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle3.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/cycle3.wit.result @@ -1,5 +1,5 @@ type `bar` depends on itself - --> tests/ui/parse-fail/cycle3.wit:4:14 + --> tests/ui/parse-fail/cycle3.wit:5:14 | - 4 | type foo = bar + 5 | type foo = bar | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle4.wit b/crates/wit-parser/tests/ui/parse-fail/cycle4.wit index 39c6d4bfcf..716ac832af 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle4.wit +++ b/crates/wit-parser/tests/ui/parse-fail/cycle4.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { type foo = bar diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle4.wit.result b/crates/wit-parser/tests/ui/parse-fail/cycle4.wit.result index 45e9c17a0f..67325b779f 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle4.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/cycle4.wit.result @@ -1,5 +1,5 @@ type `bar` depends on itself - --> tests/ui/parse-fail/cycle4.wit:4:14 + --> tests/ui/parse-fail/cycle4.wit:5:14 | - 4 | type foo = bar + 5 | type foo = bar | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle5.wit b/crates/wit-parser/tests/ui/parse-fail/cycle5.wit index 3c26d9b249..2aa73441ed 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle5.wit +++ b/crates/wit-parser/tests/ui/parse-fail/cycle5.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { type foo = bar diff --git a/crates/wit-parser/tests/ui/parse-fail/cycle5.wit.result b/crates/wit-parser/tests/ui/parse-fail/cycle5.wit.result index 0fd4f5c82b..22064dac1e 100644 --- a/crates/wit-parser/tests/ui/parse-fail/cycle5.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/cycle5.wit.result @@ -1,5 +1,5 @@ type `bar` depends on itself - --> tests/ui/parse-fail/cycle5.wit:4:14 + --> tests/ui/parse-fail/cycle5.wit:5:14 | - 4 | type foo = bar + 5 | type foo = bar | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/default-interface1.wit b/crates/wit-parser/tests/ui/parse-fail/default-interface1.wit deleted file mode 100644 index c6c4238802..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/default-interface1.wit +++ /dev/null @@ -1,3 +0,0 @@ -// parse-fail -default interface foo {} -default interface bar {} diff --git a/crates/wit-parser/tests/ui/parse-fail/default-interface1.wit.result b/crates/wit-parser/tests/ui/parse-fail/default-interface1.wit.result deleted file mode 100644 index a98ae7d335..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/default-interface1.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -cannot specify more than one `default` interface - --> tests/ui/parse-fail/default-interface1.wit:3:19 - | - 3 | default interface bar {} - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/default-world1.wit b/crates/wit-parser/tests/ui/parse-fail/default-world1.wit deleted file mode 100644 index df2d36e299..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/default-world1.wit +++ /dev/null @@ -1,3 +0,0 @@ -// parse-fail -default world foo {} -default world bar {} diff --git a/crates/wit-parser/tests/ui/parse-fail/default-world1.wit.result b/crates/wit-parser/tests/ui/parse-fail/default-world1.wit.result deleted file mode 100644 index e46b2538f2..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/default-world1.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -cannot specify more than one `default` world - --> tests/ui/parse-fail/default-world1.wit:3:15 - | - 3 | default world bar {} - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-functions.wit b/crates/wit-parser/tests/ui/parse-fail/duplicate-functions.wit index 6b63355eb9..b581d731e6 100644 --- a/crates/wit-parser/tests/ui/parse-fail/duplicate-functions.wit +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-functions.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + interface foo { foo: func() foo: func() diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-functions.wit.result b/crates/wit-parser/tests/ui/parse-fail/duplicate-functions.wit.result index c0ab243fa6..30ec5002b4 100644 --- a/crates/wit-parser/tests/ui/parse-fail/duplicate-functions.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-functions.wit.result @@ -1,5 +1,5 @@ name `foo` is defined more than once - --> tests/ui/parse-fail/duplicate-functions.wit:5:3 + --> tests/ui/parse-fail/duplicate-functions.wit:7:3 | - 5 | foo: func() + 7 | foo: func() | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-interface.wit b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface.wit index c58d11fa01..c5fecdd775 100644 --- a/crates/wit-parser/tests/ui/parse-fail/duplicate-interface.wit +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface.wit @@ -1,4 +1,6 @@ // parse-fail +package foo:foo + interface foo {} interface foo {} diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-interface.wit.result b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface.wit.result index 293005fe64..f6351f30e1 100644 --- a/crates/wit-parser/tests/ui/parse-fail/duplicate-interface.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface.wit.result @@ -1,5 +1,5 @@ -name `foo` previously defined in document - --> tests/ui/parse-fail/duplicate-interface.wit:4:11 +duplicate item named `foo` + --> tests/ui/parse-fail/duplicate-interface.wit:6:11 | - 4 | interface foo {} + 6 | interface foo {} | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2.wit.result b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2.wit.result new file mode 100644 index 0000000000..7ed7ec2b29 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2.wit.result @@ -0,0 +1,8 @@ +failed to parse package: tests/ui/parse-fail/duplicate-interface2 + +Caused by: + duplicate item named `foo` + --> tests/ui/parse-fail/duplicate-interface2/foo2.wit:3:11 + | + 3 | interface foo {} + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2/foo.wit b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2/foo.wit new file mode 100644 index 0000000000..f8a9027d45 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2/foo.wit @@ -0,0 +1,3 @@ +package foo:foo + +interface foo {} diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2/foo2.wit b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2/foo2.wit new file mode 100644 index 0000000000..f8a9027d45 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-interface2/foo2.wit @@ -0,0 +1,3 @@ +package foo:foo + +interface foo {} diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-type.wit b/crates/wit-parser/tests/ui/parse-fail/duplicate-type.wit index 7b23f438b1..7284164b1d 100644 --- a/crates/wit-parser/tests/ui/parse-fail/duplicate-type.wit +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-type.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { type foo = s32 diff --git a/crates/wit-parser/tests/ui/parse-fail/duplicate-type.wit.result b/crates/wit-parser/tests/ui/parse-fail/duplicate-type.wit.result index 9efd0d2c4f..09187e9f52 100644 --- a/crates/wit-parser/tests/ui/parse-fail/duplicate-type.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/duplicate-type.wit.result @@ -1,5 +1,5 @@ name `foo` is defined more than once - --> tests/ui/parse-fail/duplicate-type.wit:5:8 + --> tests/ui/parse-fail/duplicate-type.wit:6:8 | - 5 | type foo = s32 + 6 | type foo = s32 | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/empty-enum.wit b/crates/wit-parser/tests/ui/parse-fail/empty-enum.wit index abf7c1197f..2b95777717 100644 --- a/crates/wit-parser/tests/ui/parse-fail/empty-enum.wit +++ b/crates/wit-parser/tests/ui/parse-fail/empty-enum.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { enum t {} diff --git a/crates/wit-parser/tests/ui/parse-fail/empty-enum.wit.result b/crates/wit-parser/tests/ui/parse-fail/empty-enum.wit.result index 9347fca423..894a82a00d 100644 --- a/crates/wit-parser/tests/ui/parse-fail/empty-enum.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/empty-enum.wit.result @@ -1,5 +1,5 @@ empty enum - --> tests/ui/parse-fail/empty-enum.wit:4:8 + --> tests/ui/parse-fail/empty-enum.wit:5:8 | - 4 | enum t {} + 5 | enum t {} | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/empty-union.wit b/crates/wit-parser/tests/ui/parse-fail/empty-union.wit index 84e8f9ecec..1128fd1ea6 100644 --- a/crates/wit-parser/tests/ui/parse-fail/empty-union.wit +++ b/crates/wit-parser/tests/ui/parse-fail/empty-union.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { union t {} diff --git a/crates/wit-parser/tests/ui/parse-fail/empty-union.wit.result b/crates/wit-parser/tests/ui/parse-fail/empty-union.wit.result index af11fb72c4..14189756bb 100644 --- a/crates/wit-parser/tests/ui/parse-fail/empty-union.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/empty-union.wit.result @@ -1,5 +1,5 @@ empty union - --> tests/ui/parse-fail/empty-union.wit:4:9 + --> tests/ui/parse-fail/empty-union.wit:5:9 | - 4 | union t {} + 5 | union t {} | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/empty-variant1.wit b/crates/wit-parser/tests/ui/parse-fail/empty-variant1.wit index 8081a45ad2..23ba7e189d 100644 --- a/crates/wit-parser/tests/ui/parse-fail/empty-variant1.wit +++ b/crates/wit-parser/tests/ui/parse-fail/empty-variant1.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { variant t {} diff --git a/crates/wit-parser/tests/ui/parse-fail/empty-variant1.wit.result b/crates/wit-parser/tests/ui/parse-fail/empty-variant1.wit.result index 68bdc00808..9c42ba4c0f 100644 --- a/crates/wit-parser/tests/ui/parse-fail/empty-variant1.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/empty-variant1.wit.result @@ -1,5 +1,5 @@ empty variant - --> tests/ui/parse-fail/empty-variant1.wit:4:11 + --> tests/ui/parse-fail/empty-variant1.wit:5:11 | - 4 | variant t {} + 5 | variant t {} | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/export-twice.wit b/crates/wit-parser/tests/ui/parse-fail/export-twice.wit new file mode 100644 index 0000000000..eaeb478c9e --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/export-twice.wit @@ -0,0 +1,8 @@ +package foo:foo + +interface foo {} + +world bar { + export foo + export foo +} diff --git a/crates/wit-parser/tests/ui/parse-fail/export-twice.wit.result b/crates/wit-parser/tests/ui/parse-fail/export-twice.wit.result new file mode 100644 index 0000000000..d796998a16 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/export-twice.wit.result @@ -0,0 +1,5 @@ +interface cannot be exported more than once + --> tests/ui/parse-fail/export-twice.wit:7:10 + | + 7 | export foo + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit index 4e865f9033..ac0e8e4de3 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit +++ b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit @@ -1,3 +1,4 @@ +package foo:foo world foo { import a: func() export a: func() diff --git a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit.result b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit.result index 838baa6ee3..27caf399c3 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap1.wit.result @@ -1,5 +1,5 @@ export `a` conflicts with prior import of same name - --> tests/ui/parse-fail/import-export-overlap1.wit:3:10 + --> tests/ui/parse-fail/import-export-overlap1.wit:4:10 | - 3 | export a: func() + 4 | export a: func() | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit index 1680efebb2..4622babb4b 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit @@ -1,3 +1,4 @@ +package foo:foo world foo { import a: func() export a: interface {} diff --git a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit.result b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit.result index af16080e10..88ca1c1997 100644 --- a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap2.wit.result @@ -1,5 +1,5 @@ export `a` conflicts with prior import of same name - --> tests/ui/parse-fail/import-export-overlap2.wit:3:10 + --> tests/ui/parse-fail/import-export-overlap2.wit:4:10 | - 3 | export a: interface {} + 4 | export a: interface {} | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap3.wit b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap3.wit deleted file mode 100644 index 183e991594..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap3.wit +++ /dev/null @@ -1,11 +0,0 @@ -interface a { - type t = u32 -} - -world foo { - import b: interface { - use self.a.{t} - } - export a: interface {} -} - diff --git a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap3.wit.result b/crates/wit-parser/tests/ui/parse-fail/import-export-overlap3.wit.result deleted file mode 100644 index 677d5a9640..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/import-export-overlap3.wit.result +++ /dev/null @@ -1,6 +0,0 @@ -export of `a` conflicts with a previous interface using the name `a` - - --> tests/ui/parse-fail/import-export-overlap3.wit:9:10 - | - 9 | export a: interface {} - | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/import-twice.wit b/crates/wit-parser/tests/ui/parse-fail/import-twice.wit new file mode 100644 index 0000000000..7d9a6d8cd1 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/import-twice.wit @@ -0,0 +1,8 @@ +package foo:foo + +interface foo {} + +world bar { + import foo + import foo +} diff --git a/crates/wit-parser/tests/ui/parse-fail/import-twice.wit.result b/crates/wit-parser/tests/ui/parse-fail/import-twice.wit.result new file mode 100644 index 0000000000..7dfe127a4a --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/import-twice.wit.result @@ -0,0 +1,5 @@ +interface cannot be imported more than once + --> tests/ui/parse-fail/import-twice.wit:7:10 + | + 7 | import foo + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/invalid-md.wit.result b/crates/wit-parser/tests/ui/parse-fail/invalid-md.wit.result index 6a5becd6b6..ed4f7e1c7a 100644 --- a/crates/wit-parser/tests/ui/parse-fail/invalid-md.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/invalid-md.wit.result @@ -1,4 +1,4 @@ -expected `default`, `world` or `interface`, found keyword `type` +expected `world`, `interface` or `use`, found keyword `type` --> tests/ui/parse-fail/invalid-md.md:6:1 | 6 | type foo = bar diff --git a/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference.wit b/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference.wit index da9286726d..512837e6bb 100644 --- a/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference.wit +++ b/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { x: func() diff --git a/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference.wit.result b/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference.wit.result index 1c872a1c05..d7861f14f4 100644 --- a/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference.wit.result @@ -1,5 +1,5 @@ type `x` does not exist - --> tests/ui/parse-fail/invalid-type-reference.wit:6:8 + --> tests/ui/parse-fail/invalid-type-reference.wit:8:8 | - 6 | a: x + 8 | a: x | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference2.wit b/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference2.wit index c2f7393c61..694ccbc27a 100644 --- a/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference2.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { x: func() y: func() -> x diff --git a/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference2.wit.result b/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference2.wit.result index 6637a36a23..f3899ab548 100644 --- a/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/invalid-type-reference2.wit.result @@ -1,5 +1,5 @@ cannot use function `x` as a type - --> tests/ui/parse-fail/invalid-type-reference2.wit:3:16 + --> tests/ui/parse-fail/invalid-type-reference2.wit:5:16 | - 3 | y: func() -> x + 5 | y: func() -> x | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/invalid@filename.wit b/crates/wit-parser/tests/ui/parse-fail/invalid@filename.wit deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/crates/wit-parser/tests/ui/parse-fail/invalid@filename.wit.result b/crates/wit-parser/tests/ui/parse-fail/invalid@filename.wit.result deleted file mode 100644 index 461cca9d53..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/invalid@filename.wit.result +++ /dev/null @@ -1,4 +0,0 @@ -failed to start resolving path: tests/ui/parse-fail/invalid@filename.wit - -Caused by: - name of document isn't a valid WIT identifier `invalid@filename`: invalid character in identifier '@' \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-pkg2/deps/bar/.gitkeep b/crates/wit-parser/tests/ui/parse-fail/missing-package.wit similarity index 100% rename from crates/wit-parser/tests/ui/parse-fail/bad-pkg2/deps/bar/.gitkeep rename to crates/wit-parser/tests/ui/parse-fail/missing-package.wit diff --git a/crates/wit-parser/tests/ui/parse-fail/missing-package.wit.result b/crates/wit-parser/tests/ui/parse-fail/missing-package.wit.result new file mode 100644 index 0000000000..d25b316c26 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/missing-package.wit.result @@ -0,0 +1 @@ +no `package` header was found in any WIT file for this package \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use.wit.result b/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use.wit.result new file mode 100644 index 0000000000..e938b272fe --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use.wit.result @@ -0,0 +1,8 @@ +failed to parse package: tests/ui/parse-fail/no-access-to-sibling-use + +Caused by: + interface `bar-renamed` does not exist + --> tests/ui/parse-fail/no-access-to-sibling-use/foo.wit:3:5 + | + 3 | use bar-renamed + | ^---------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use/bar.wit b/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use/bar.wit new file mode 100644 index 0000000000..a08b230595 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use/bar.wit @@ -0,0 +1 @@ +use bar as bar-renamed diff --git a/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use/foo.wit b/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use/foo.wit new file mode 100644 index 0000000000..01778b7343 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/no-access-to-sibling-use/foo.wit @@ -0,0 +1,5 @@ +package foo:foo + +use bar-renamed + +interface bar {} diff --git a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle.wit.result b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle.wit.result index d7fbbe1104..fa1777f538 100644 --- a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle.wit.result @@ -1,5 +1,5 @@ package depends on itself - --> tests/ui/parse-fail/pkg-cycle/deps/a1/root.wit:2:7 + --> tests/ui/parse-fail/pkg-cycle/deps/a1/root.wit:3:7 | - 2 | use a1.foo.{} - | ^- \ No newline at end of file + 3 | use foo:a1/foo.{} + | ^----- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle/deps/a1/root.wit b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle/deps/a1/root.wit index 9a23dbfd35..fc18ee3a52 100644 --- a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle/deps/a1/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle/deps/a1/root.wit @@ -1,3 +1,4 @@ +package foo:a1 interface foo { - use a1.foo.{} + use foo:a1/foo.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle/root.wit b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle/root.wit index 9a23dbfd35..1eae323140 100644 --- a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle/root.wit @@ -1,3 +1,4 @@ +package foo:foo interface foo { - use a1.foo.{} + use foo:a1/foo.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2.wit.result b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2.wit.result index b7ccf5a080..82d1af2645 100644 --- a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2.wit.result @@ -1,5 +1,5 @@ package depends on itself - --> tests/ui/parse-fail/pkg-cycle2/deps/a2/root.wit:2:7 + --> tests/ui/parse-fail/pkg-cycle2/deps/a2/root.wit:3:7 | - 2 | use a1.foo.{} - | ^- \ No newline at end of file + 3 | use foo:a1/foo.{} + | ^----- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/deps/a1/root.wit b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/deps/a1/root.wit index 9e8ae2bbfd..ff53a7eb37 100644 --- a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/deps/a1/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/deps/a1/root.wit @@ -1,3 +1,4 @@ +package foo:a1 interface foo { - use a2.foo.{} + use foo:a2/foo.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/deps/a2/root.wit b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/deps/a2/root.wit index 9a23dbfd35..b52fe4029b 100644 --- a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/deps/a2/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/deps/a2/root.wit @@ -1,3 +1,4 @@ +package foo:a2 interface foo { - use a1.foo.{} + use foo:a1/foo.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/root.wit b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/root.wit index 9a23dbfd35..45c0d2255b 100644 --- a/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/root.wit +++ b/crates/wit-parser/tests/ui/parse-fail/pkg-cycle2/root.wit @@ -1,3 +1,4 @@ +package foo:root interface foo { - use a1.foo.{} + use foo:a1/foo.{} } diff --git a/crates/wit-parser/tests/ui/parse-fail/undefined-typed.wit b/crates/wit-parser/tests/ui/parse-fail/undefined-typed.wit index 7467f94de6..46eff1d7f4 100644 --- a/crates/wit-parser/tests/ui/parse-fail/undefined-typed.wit +++ b/crates/wit-parser/tests/ui/parse-fail/undefined-typed.wit @@ -1,4 +1,5 @@ // parse-fail +package foo:foo interface foo { type foo = bar diff --git a/crates/wit-parser/tests/ui/parse-fail/undefined-typed.wit.result b/crates/wit-parser/tests/ui/parse-fail/undefined-typed.wit.result index aba06b4bc2..162404ae7c 100644 --- a/crates/wit-parser/tests/ui/parse-fail/undefined-typed.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/undefined-typed.wit.result @@ -1,5 +1,5 @@ type `bar` does not exist - --> tests/ui/parse-fail/undefined-typed.wit:4:14 + --> tests/ui/parse-fail/undefined-typed.wit:5:14 | - 4 | type foo = bar + 5 | type foo = bar | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unknown-interface.wit b/crates/wit-parser/tests/ui/parse-fail/unknown-interface.wit index 8fe521bfb5..3f735e53f0 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unknown-interface.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unknown-interface.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + world foo { - import bar: self.bar + import bar } diff --git a/crates/wit-parser/tests/ui/parse-fail/unknown-interface.wit.result b/crates/wit-parser/tests/ui/parse-fail/unknown-interface.wit.result index 143852253c..4ae873138c 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unknown-interface.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unknown-interface.wit.result @@ -1,5 +1,5 @@ -interface does not exist - --> tests/ui/parse-fail/unknown-interface.wit:4:20 +interface `bar` does not exist + --> tests/ui/parse-fail/unknown-interface.wit:6:10 | - 4 | import bar: self.bar - | ^-- \ No newline at end of file + 6 | import bar + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface1.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface1.wit index cc1b6ae35f..12167a224e 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface1.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface1.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + world foo { - import foo: self.foo + import foo } diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface1.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface1.wit.result index dc6cea3c5d..13bfe93286 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface1.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface1.wit.result @@ -1,5 +1,5 @@ name `foo` is defined as a world, not an interface - --> tests/ui/parse-fail/unresolved-interface1.wit:4:20 + --> tests/ui/parse-fail/unresolved-interface1.wit:6:10 | - 4 | import foo: self.foo - | ^-- \ No newline at end of file + 6 | import foo + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface2.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface2.wit index 8a67d92f00..5aa93b234c 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface2.wit @@ -1,6 +1,8 @@ // parse-fail +package foo:foo + world foo { - import foo: self.bar + import bar } diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface2.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface2.wit.result index f230df6eb8..2a89904c2b 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface2.wit.result @@ -1,5 +1,5 @@ -interface does not exist - --> tests/ui/parse-fail/unresolved-interface2.wit:4:20 +interface `bar` does not exist + --> tests/ui/parse-fail/unresolved-interface2.wit:6:10 | - 4 | import foo: self.bar - | ^-- \ No newline at end of file + 6 | import bar + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface3.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface3.wit index 61683dde44..f799bfb785 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface3.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface3.wit @@ -1,5 +1,5 @@ // parse-fail -world foo { - import foo: pkg.foo.bar -} +package foo:foo + +use bar as foo diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface3.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface3.wit.result index b7c4ba676c..716eab1237 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface3.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface3.wit.result @@ -1,5 +1,5 @@ -document `foo` does not exist - --> tests/ui/parse-fail/unresolved-interface3.wit:4:19 +interface `bar` does not exist + --> tests/ui/parse-fail/unresolved-interface3.wit:5:5 | - 4 | import foo: pkg.foo.bar - | ^-- \ No newline at end of file + 5 | use bar as foo + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit index 29817a23be..63ea8b92ae 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + world foo { - import foo: pkg.unresolved-interface4 + import some:dependency/iface } diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit.result index e3f55f5ba0..3e772ae61a 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface4.wit.result @@ -1,5 +1,5 @@ -document does not specify a default interface - --> tests/ui/parse-fail/unresolved-interface4.wit:4:19 +package not found + --> tests/ui/parse-fail/unresolved-interface4.wit:6:10 | - 4 | import foo: pkg.unresolved-interface4 - | ^-------------------- \ No newline at end of file + 6 | import some:dependency/iface + | ^-------------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface5.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface5.wit deleted file mode 100644 index fa943c2a59..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface5.wit +++ /dev/null @@ -1,5 +0,0 @@ -// parse-fail - -world foo { - import foo: pkg.unresolved-interface5.bar -} diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface5.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-interface5.wit.result deleted file mode 100644 index fc5a01ae26..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-interface5.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -interface does not exist - --> tests/ui/parse-fail/unresolved-interface5.wit:4:41 - | - 4 | import foo: pkg.unresolved-interface5.bar - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use1.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use1.wit index f4b7dd5bef..745b44b961 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use1.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use1.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + interface foo { - use self.bar.{x} + use bar.{x} } diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use1.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use1.wit.result index 33708bc6c9..c539ca41d9 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use1.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use1.wit.result @@ -1,5 +1,5 @@ -interface `bar` does not exist - --> tests/ui/parse-fail/unresolved-use1.wit:4:12 +interface `bar` not found in package + --> tests/ui/parse-fail/unresolved-use1.wit:6:7 | - 4 | use self.bar.{x} - | ^-- \ No newline at end of file + 6 | use bar.{x} + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use10.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use10.wit.result index bb1504e286..df68a38728 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use10.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use10.wit.result @@ -1,8 +1,8 @@ failed to parse package: tests/ui/parse-fail/unresolved-use10 Caused by: - document does not specify a default interface - --> tests/ui/parse-fail/unresolved-use10/bar.wit:2:11 + name `thing` is not defined + --> tests/ui/parse-fail/unresolved-use10/bar.wit:4:12 | - 2 | use pkg.foo.{thing} - | ^-- \ No newline at end of file + 4 | use foo.{thing} + | ^---- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use10/bar.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use10/bar.wit index 82806f689e..e6c479bc93 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use10/bar.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use10/bar.wit @@ -1,3 +1,5 @@ +package foo:foo + interface bar { - use pkg.foo.{thing} + use foo.{thing} } diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use11.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use11.wit.result deleted file mode 100644 index afdbcf6f66..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use11.wit.result +++ /dev/null @@ -1,8 +0,0 @@ -failed to parse package: tests/ui/parse-fail/unresolved-use11 - -Caused by: - name `thing` is not defined - --> tests/ui/parse-fail/unresolved-use11/bar.wit:2:16 - | - 2 | use pkg.foo.{thing} - | ^---- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use11/bar.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use11/bar.wit deleted file mode 100644 index 82806f689e..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use11/bar.wit +++ /dev/null @@ -1,3 +0,0 @@ -interface bar { - use pkg.foo.{thing} -} diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use11/foo.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use11/foo.wit deleted file mode 100644 index 3e6a7e9ced..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use11/foo.wit +++ /dev/null @@ -1,2 +0,0 @@ -default interface foo { -} diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use2.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use2.wit index 402c72b61c..69ae75f0b8 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use2.wit @@ -1,7 +1,9 @@ // parse-fail +package foo:foo + interface foo { - use self.bar.{x} + use bar.{x} } interface bar { diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use2.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use2.wit.result index 3a43a8feb3..f44ca7cf2e 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use2.wit.result @@ -1,5 +1,5 @@ name `x` is not defined - --> tests/ui/parse-fail/unresolved-use2.wit:4:17 + --> tests/ui/parse-fail/unresolved-use2.wit:6:12 | - 4 | use self.bar.{x} - | ^ \ No newline at end of file + 6 | use bar.{x} + | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use3.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use3.wit index 6b34d6cac4..9064ef8332 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use3.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use3.wit @@ -1,7 +1,9 @@ // parse-fail +package foo:foo + interface foo { - use self.bar.{x} + use bar.{x} } interface bar { diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use3.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use3.wit.result index 3d82f08104..9f29adbd34 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use3.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use3.wit.result @@ -1,5 +1,5 @@ cannot import function `x` - --> tests/ui/parse-fail/unresolved-use3.wit:4:17 + --> tests/ui/parse-fail/unresolved-use3.wit:6:12 | - 4 | use self.bar.{x} - | ^ \ No newline at end of file + 6 | use bar.{x} + | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use4.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use4.wit deleted file mode 100644 index a82a94b450..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use4.wit +++ /dev/null @@ -1,5 +0,0 @@ -// parse-fail - -interface foo { - use pkg.something-that-does-not-exist.{x} -} diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use4.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use4.wit.result deleted file mode 100644 index 43bffddede..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use4.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -document `something-that-does-not-exist` does not exist - --> tests/ui/parse-fail/unresolved-use4.wit:4:11 - | - 4 | use pkg.something-that-does-not-exist.{x} - | ^---------------------------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use5.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use5.wit deleted file mode 100644 index f349f39f0d..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use5.wit +++ /dev/null @@ -1,6 +0,0 @@ -// parse-fail - -interface foo { - use pkg.unresolved-use5.{x} -} - diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use5.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use5.wit.result deleted file mode 100644 index e361c989ae..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use5.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -no `default` interface in document to use from - --> tests/ui/parse-fail/unresolved-use5.wit:4:11 - | - 4 | use pkg.unresolved-use5.{x} - | ^-------------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use6.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use6.wit deleted file mode 100644 index 125b2e3dcf..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use6.wit +++ /dev/null @@ -1,5 +0,0 @@ -// parse-fail - -interface foo { - use pkg.unresolved-use6.nonexistent.{x} -} diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use6.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use6.wit.result deleted file mode 100644 index e174fa5426..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use6.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -interface `nonexistent` does not exist - --> tests/ui/parse-fail/unresolved-use6.wit:4:27 - | - 4 | use pkg.unresolved-use6.nonexistent.{x} - | ^---------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use7.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use7.wit index c08f490950..69ae75f0b8 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use7.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use7.wit @@ -1,7 +1,9 @@ // parse-fail +package foo:foo + interface foo { - use pkg.unresolved-use7.bar.{x} + use bar.{x} } interface bar { diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use7.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use7.wit.result index 418dd27c65..acb4720e3c 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use7.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use7.wit.result @@ -1,5 +1,5 @@ name `x` is not defined - --> tests/ui/parse-fail/unresolved-use7.wit:4:32 + --> tests/ui/parse-fail/unresolved-use7.wit:6:12 | - 4 | use pkg.unresolved-use7.bar.{x} - | ^ \ No newline at end of file + 6 | use bar.{x} + | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use8.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use8.wit index dad0d2eb28..b0c9db9118 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use8.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use8.wit @@ -1,7 +1,9 @@ // parse-fail +package foo:foo + world foo { import foo: interface { - use self.foo.{i32} + use foo.{i32} } } diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use8.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use8.wit.result index 8ed307231f..5ebb30c8db 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use8.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use8.wit.result @@ -1,5 +1,5 @@ name `foo` is defined as a world, not an interface - --> tests/ui/parse-fail/unresolved-use8.wit:5:14 + --> tests/ui/parse-fail/unresolved-use8.wit:7:9 | - 5 | use self.foo.{i32} - | ^-- \ No newline at end of file + 7 | use foo.{i32} + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use9.wit b/crates/wit-parser/tests/ui/parse-fail/unresolved-use9.wit index 83ba81ad7c..5fc2b3845a 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use9.wit +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use9.wit @@ -1,7 +1,9 @@ // parse-fail +package foo:foo + world foo { import foo: interface { - use self.bar.{i32} + use bar.{i32} } } diff --git a/crates/wit-parser/tests/ui/parse-fail/unresolved-use9.wit.result b/crates/wit-parser/tests/ui/parse-fail/unresolved-use9.wit.result index 7bcfad2e5a..5e8ee39982 100644 --- a/crates/wit-parser/tests/ui/parse-fail/unresolved-use9.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/unresolved-use9.wit.result @@ -1,5 +1,5 @@ -interface does not exist - --> tests/ui/parse-fail/unresolved-use9.wit:5:14 +interface `bar` does not exist + --> tests/ui/parse-fail/unresolved-use9.wit:7:9 | - 5 | use self.bar.{i32} - | ^-- \ No newline at end of file + 7 | use bar.{i32} + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-conflict.wit b/crates/wit-parser/tests/ui/parse-fail/use-conflict.wit index 20e158e133..266723ef37 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-conflict.wit +++ b/crates/wit-parser/tests/ui/parse-fail/use-conflict.wit @@ -1,9 +1,11 @@ // parse-fail +package foo:foo + interface foo { type x = u32 } interface bar { - use self.foo.{x, x} + use foo.{x, x} } diff --git a/crates/wit-parser/tests/ui/parse-fail/use-conflict.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-conflict.wit.result index 2cbe95d2e2..aab7474e7c 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-conflict.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/use-conflict.wit.result @@ -1,5 +1,5 @@ name `x` is defined more than once - --> tests/ui/parse-fail/use-conflict.wit:8:20 + --> tests/ui/parse-fail/use-conflict.wit:10:15 | - 8 | use self.foo.{x, x} - | ^ \ No newline at end of file + 10 | use foo.{x, x} + | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-conflict2.wit b/crates/wit-parser/tests/ui/parse-fail/use-conflict2.wit index 11a16519bd..94116902ad 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-conflict2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/use-conflict2.wit @@ -1,11 +1,13 @@ // parse-fail +package foo:foo + interface foo { type x = u32 } interface bar { - use self.foo.{x} + use foo.{x} type x = s64 } diff --git a/crates/wit-parser/tests/ui/parse-fail/use-conflict2.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-conflict2.wit.result index 3c70f63445..623febeee9 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-conflict2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/use-conflict2.wit.result @@ -1,5 +1,5 @@ name `x` is defined more than once - --> tests/ui/parse-fail/use-conflict2.wit:10:8 + --> tests/ui/parse-fail/use-conflict2.wit:12:8 | - 10 | type x = s64 + 12 | type x = s64 | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-conflict3.wit b/crates/wit-parser/tests/ui/parse-fail/use-conflict3.wit index 53a85b0318..5f2d418f8c 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-conflict3.wit +++ b/crates/wit-parser/tests/ui/parse-fail/use-conflict3.wit @@ -1,11 +1,13 @@ // parse-fail +package foo:foo + interface foo { type x = u32 } interface bar { - use self.foo.{x} + use foo.{x} x: func() } diff --git a/crates/wit-parser/tests/ui/parse-fail/use-conflict3.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-conflict3.wit.result index c9e7e41e21..2928d26aa2 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-conflict3.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/use-conflict3.wit.result @@ -1,5 +1,5 @@ name `x` is defined more than once - --> tests/ui/parse-fail/use-conflict3.wit:10:3 + --> tests/ui/parse-fail/use-conflict3.wit:12:3 | - 10 | x: func() + 12 | x: func() | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-cycle1.wit b/crates/wit-parser/tests/ui/parse-fail/use-cycle1.wit index a1abaeca50..b961b8db60 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-cycle1.wit +++ b/crates/wit-parser/tests/ui/parse-fail/use-cycle1.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + interface foo { - use self.foo.{bar} + use foo.{bar} } diff --git a/crates/wit-parser/tests/ui/parse-fail/use-cycle1.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-cycle1.wit.result index 8c7950ed91..c0150a6008 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-cycle1.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/use-cycle1.wit.result @@ -1,5 +1,5 @@ interface `foo` depends on itself - --> tests/ui/parse-fail/use-cycle1.wit:4:12 + --> tests/ui/parse-fail/use-cycle1.wit:5:11 | - 4 | use self.foo.{bar} - | ^-- \ No newline at end of file + 5 | interface foo { + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-cycle2.wit b/crates/wit-parser/tests/ui/parse-fail/use-cycle2.wit deleted file mode 100644 index 7d416e30eb..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-cycle2.wit +++ /dev/null @@ -1,5 +0,0 @@ -// parse-fail - -interface foo { - use pkg.use-cycle2.foo.{bar} -} diff --git a/crates/wit-parser/tests/ui/parse-fail/use-cycle2.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-cycle2.wit.result deleted file mode 100644 index 8af25543a8..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-cycle2.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -interface `foo` depends on itself - --> tests/ui/parse-fail/use-cycle2.wit:4:22 - | - 4 | use pkg.use-cycle2.foo.{bar} - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-cycle3.wit b/crates/wit-parser/tests/ui/parse-fail/use-cycle3.wit deleted file mode 100644 index 7edf782278..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-cycle3.wit +++ /dev/null @@ -1,6 +0,0 @@ -// parse-fail - -default interface foo { - // TODO: this could use a better error message - use pkg.use-cycle3.{bar} -} diff --git a/crates/wit-parser/tests/ui/parse-fail/use-cycle3.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-cycle3.wit.result deleted file mode 100644 index ff6d459c48..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-cycle3.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -interface `foo` depends on itself - --> tests/ui/parse-fail/use-cycle3.wit:5:11 - | - 5 | use pkg.use-cycle3.{bar} - | ^--------- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-cycle4.wit b/crates/wit-parser/tests/ui/parse-fail/use-cycle4.wit index 9fe1fbae34..f8bef245cb 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-cycle4.wit +++ b/crates/wit-parser/tests/ui/parse-fail/use-cycle4.wit @@ -1,13 +1,14 @@ // parse-fail +package foo:foo interface foo { - use self.bar.{y} + use bar.{y} type x = u32 } interface bar { - use self.foo.{x} + use foo.{x} type y = u32 } diff --git a/crates/wit-parser/tests/ui/parse-fail/use-cycle4.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-cycle4.wit.result index 65b739418c..79b327045d 100644 --- a/crates/wit-parser/tests/ui/parse-fail/use-cycle4.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/use-cycle4.wit.result @@ -1,5 +1,5 @@ interface `bar` depends on itself - --> tests/ui/parse-fail/use-cycle4.wit:4:12 + --> tests/ui/parse-fail/use-cycle4.wit:10:11 | - 4 | use self.bar.{y} - | ^-- \ No newline at end of file + 10 | interface bar { + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world.wit b/crates/wit-parser/tests/ui/parse-fail/use-from-package-world.wit deleted file mode 100644 index 5fdf01a23e..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world.wit +++ /dev/null @@ -1,8 +0,0 @@ -// parse-fail - -world foo { -} - -interface bar { - use pkg.use-from-package-world.foo.{x} -} diff --git a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-from-package-world.wit.result deleted file mode 100644 index e1dc970fa6..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -interface does not exist - --> tests/ui/parse-fail/use-from-package-world.wit:7:34 - | - 7 | use pkg.use-from-package-world.foo.{x} - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2.wit.result deleted file mode 100644 index 95608cfb58..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2.wit.result +++ /dev/null @@ -1,8 +0,0 @@ -failed to parse package: tests/ui/parse-fail/use-from-package-world2 - -Caused by: - cannot import from world `foo` - --> tests/ui/parse-fail/use-from-package-world2/bar.wit:2:15 - | - 2 | use pkg.foo.foo.{thing} - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2/bar.wit b/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2/bar.wit deleted file mode 100644 index 078c0c348f..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2/bar.wit +++ /dev/null @@ -1,3 +0,0 @@ -interface bar { - use pkg.foo.foo.{thing} -} diff --git a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2/foo.wit b/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2/foo.wit deleted file mode 100644 index c2e6c53e73..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/use-from-package-world2/foo.wit +++ /dev/null @@ -1,2 +0,0 @@ -world foo { -} diff --git a/crates/wit-parser/tests/ui/parse-fail/use-shadow1.wit b/crates/wit-parser/tests/ui/parse-fail/use-shadow1.wit new file mode 100644 index 0000000000..29b3cf6335 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/use-shadow1.wit @@ -0,0 +1,7 @@ +package foo:foo + +use foo as bar + +interface foo {} + +interface bar {} diff --git a/crates/wit-parser/tests/ui/parse-fail/use-shadow1.wit.result b/crates/wit-parser/tests/ui/parse-fail/use-shadow1.wit.result new file mode 100644 index 0000000000..cdce8b4cc4 --- /dev/null +++ b/crates/wit-parser/tests/ui/parse-fail/use-shadow1.wit.result @@ -0,0 +1,5 @@ +duplicate name `bar` in this file + --> tests/ui/parse-fail/use-shadow1.wit:7:11 + | + 7 | interface bar {} + | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import1.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-implicit-import1.wit.result deleted file mode 100644 index a8e23a5c6c..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import1.wit.result +++ /dev/null @@ -1,6 +0,0 @@ -import of `foo` conflicts with a previous interface using the name `foo` - - --> tests/ui/parse-fail/world-implicit-import1.wit:9:10 - | - 9 | import foo: interface {} - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import2.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-implicit-import2.wit.result deleted file mode 100644 index e6d9a48076..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import2.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -import of function `foo` shadows previously imported interface - --> tests/ui/parse-fail/world-implicit-import2.wit:8:10 - | - 8 | import foo: func() -> g - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import3.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-implicit-import3.wit.result deleted file mode 100644 index fac2c20c45..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import3.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -export of function `foo` shadows previously exported interface - --> tests/ui/parse-fail/world-implicit-import3.wit:8:10 - | - 8 | export foo: func() -> g - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-interface-clash.wit b/crates/wit-parser/tests/ui/parse-fail/world-interface-clash.wit index edc358f041..dbc015b289 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-interface-clash.wit +++ b/crates/wit-parser/tests/ui/parse-fail/world-interface-clash.wit @@ -1,2 +1,3 @@ +package foo:foo interface foo {} world foo {} diff --git a/crates/wit-parser/tests/ui/parse-fail/world-interface-clash.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-interface-clash.wit.result index 396ada61ad..c8159d3e52 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-interface-clash.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/world-interface-clash.wit.result @@ -1,5 +1,5 @@ -name `foo` previously defined in document - --> tests/ui/parse-fail/world-interface-clash.wit:2:7 +duplicate item named `foo + --> tests/ui/parse-fail/world-interface-clash.wit:3:7 | - 2 | world foo {} + 3 | world foo {} | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-fields.wit b/crates/wit-parser/tests/ui/parse-fail/world-same-fields.wit deleted file mode 100644 index 8906f0d526..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-fields.wit +++ /dev/null @@ -1,9 +0,0 @@ -// parse-fail - -interface foo {} -interface bar {} - -world a { - import foo: self.foo - import foo: self.bar -} diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-fields.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-same-fields.wit.result deleted file mode 100644 index a21a34d807..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-fields.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -import `foo` conflicts with prior import of same name - --> tests/ui/parse-fail/world-same-fields.wit:8:10 - | - 8 | import foo: self.bar - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-fields2.wit b/crates/wit-parser/tests/ui/parse-fail/world-same-fields2.wit index 5fc043a011..c39cdc52a5 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-fields2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/world-same-fields2.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + world a { import foo: interface {} import foo: interface {} diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-fields2.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-same-fields2.wit.result index fbf18162eb..3498be115f 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-fields2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/world-same-fields2.wit.result @@ -1,5 +1,5 @@ import `foo` conflicts with prior import of same name - --> tests/ui/parse-fail/world-same-fields2.wit:5:10 + --> tests/ui/parse-fail/world-same-fields2.wit:7:10 | - 5 | import foo: interface {} + 7 | import foo: interface {} | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-fields3.wit b/crates/wit-parser/tests/ui/parse-fail/world-same-fields3.wit index e48a2aedb5..e7e2d8e7fe 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-fields3.wit +++ b/crates/wit-parser/tests/ui/parse-fail/world-same-fields3.wit @@ -1,5 +1,7 @@ // parse-fail +package foo:foo + world a { export foo: interface {} export foo: interface {} diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-fields3.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-same-fields3.wit.result index 60b1d3c5e8..bf4a4bc61b 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-fields3.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/world-same-fields3.wit.result @@ -1,5 +1,5 @@ export `foo` conflicts with prior export of same name - --> tests/ui/parse-fail/world-same-fields3.wit:5:10 + --> tests/ui/parse-fail/world-same-fields3.wit:7:10 | - 5 | export foo: interface {} + 7 | export foo: interface {} | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-fields4.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-same-fields4.wit.result deleted file mode 100644 index 26d54e6159..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-fields4.wit.result +++ /dev/null @@ -1,8 +0,0 @@ -import of `shared` - .. which is depended on by export `a-name` -conflicts with a previous interface using the name `shared` - - --> tests/ui/parse-fail/world-same-fields4.wit:7:10 - | - 7 | export a-name: interface { - | ^----- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-import.wit b/crates/wit-parser/tests/ui/parse-fail/world-same-import.wit deleted file mode 100644 index fedaaa76ca..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-import.wit +++ /dev/null @@ -1,6 +0,0 @@ -interface foo {} - -world bar { - import foo: self.foo - import bar: self.foo -} diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-import.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-same-import.wit.result deleted file mode 100644 index 750845b7a4..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-import.wit.result +++ /dev/null @@ -1,5 +0,0 @@ -interface `bar` cannot be imported more than once - --> tests/ui/parse-fail/world-same-import.wit:5:10 - | - 5 | import bar: self.foo - | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-top-level-func.wit b/crates/wit-parser/tests/ui/parse-fail/world-top-level-func.wit index 7bf7e5fce9..813bb9578d 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-top-level-func.wit +++ b/crates/wit-parser/tests/ui/parse-fail/world-top-level-func.wit @@ -1,3 +1,4 @@ +package foo:foo world foo { import foo: func() import foo: func() diff --git a/crates/wit-parser/tests/ui/parse-fail/world-top-level-func.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-top-level-func.wit.result index 4a54d901b2..8eb1cc53f9 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-top-level-func.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/world-top-level-func.wit.result @@ -1,5 +1,5 @@ import `foo` conflicts with prior import of same name - --> tests/ui/parse-fail/world-top-level-func.wit:3:10 + --> tests/ui/parse-fail/world-top-level-func.wit:4:10 | - 3 | import foo: func() + 4 | import foo: func() | ^-- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/world-top-level-func2.wit b/crates/wit-parser/tests/ui/parse-fail/world-top-level-func2.wit index d872f06792..f2c06efac7 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-top-level-func2.wit +++ b/crates/wit-parser/tests/ui/parse-fail/world-top-level-func2.wit @@ -1,3 +1,4 @@ +package foo:foo world foo { import foo: func(a: b) } diff --git a/crates/wit-parser/tests/ui/parse-fail/world-top-level-func2.wit.result b/crates/wit-parser/tests/ui/parse-fail/world-top-level-func2.wit.result index 8e845ca0c3..1fe06a9326 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-top-level-func2.wit.result +++ b/crates/wit-parser/tests/ui/parse-fail/world-top-level-func2.wit.result @@ -1,5 +1,5 @@ name `b` is not defined - --> tests/ui/parse-fail/world-top-level-func2.wit:2:23 + --> tests/ui/parse-fail/world-top-level-func2.wit:3:23 | - 2 | import foo: func(a: b) + 3 | import foo: func(a: b) | ^ \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/parse-fail/worlds-same-fields5.wit.result b/crates/wit-parser/tests/ui/parse-fail/worlds-same-fields5.wit.result deleted file mode 100644 index cc854dab4b..0000000000 --- a/crates/wit-parser/tests/ui/parse-fail/worlds-same-fields5.wit.result +++ /dev/null @@ -1,9 +0,0 @@ -import of `i1` - .. which is depended on by import `i2` - .. which is depended on by export `i5` -conflicts with a previous interface using the name `i1` - - --> tests/ui/parse-fail/worlds-same-fields5.wit:15:10 - | - 15 | export i5: self.i3 - | ^- \ No newline at end of file diff --git a/crates/wit-parser/tests/ui/shared-types.wit b/crates/wit-parser/tests/ui/shared-types.wit index be072d9e76..f91fbe214e 100644 --- a/crates/wit-parser/tests/ui/shared-types.wit +++ b/crates/wit-parser/tests/ui/shared-types.wit @@ -1,3 +1,5 @@ +package foo:shared + world foo { import foo: interface { a: func() -> list diff --git a/crates/wit-parser/tests/ui/type-then-eof.wit b/crates/wit-parser/tests/ui/type-then-eof.wit index e4c454399b..a15f263a35 100644 --- a/crates/wit-parser/tests/ui/type-then-eof.wit +++ b/crates/wit-parser/tests/ui/type-then-eof.wit @@ -1,3 +1,5 @@ +package foo:foo + interface foo { foo: func() -> string } diff --git a/crates/wit-parser/tests/ui/types.wit b/crates/wit-parser/tests/ui/types.wit index c9082389c6..bee74acfa5 100644 --- a/crates/wit-parser/tests/ui/types.wit +++ b/crates/wit-parser/tests/ui/types.wit @@ -1,3 +1,5 @@ +package foo:types + interface types { type t1 = u8 type t2 = u16 diff --git a/crates/wit-parser/tests/ui/use-chain.wit b/crates/wit-parser/tests/ui/use-chain.wit new file mode 100644 index 0000000000..6191ebb06c --- /dev/null +++ b/crates/wit-parser/tests/ui/use-chain.wit @@ -0,0 +1,11 @@ +package foo:name + +interface foo { + record foo {} +} + +use foo as bar + +interface name { + use bar.{foo} +} diff --git a/crates/wit-parser/tests/ui/use.wit b/crates/wit-parser/tests/ui/use.wit index af27a7c32a..24856692a3 100644 --- a/crates/wit-parser/tests/ui/use.wit +++ b/crates/wit-parser/tests/ui/use.wit @@ -1,5 +1,7 @@ +package foo:foo + interface foo { - use self.bar.{the-type} + use bar.{the-type} } interface bar { @@ -7,27 +9,26 @@ interface bar { } interface baz { - use self.foo.{the-type} - use self.bar.{the-type as test} + use foo.{the-type} + use bar.{the-type as test} } interface empty { } interface use-from-empty { - use self.empty.{} - use pkg.%use.empty.{} + use empty.{} + use empty.{} } - interface use-multiple { - use self.baz.{the-type, test} + use baz.{the-type, test} some-function: func(x: the-type) -> test } interface trailing-comma { - use self.foo.{the-type,} + use foo.{the-type,} record the-foo { a: the-type } } diff --git a/crates/wit-parser/tests/ui/versions/deps/a1/foo.wit b/crates/wit-parser/tests/ui/versions/deps/a1/foo.wit new file mode 100644 index 0000000000..dbf541495b --- /dev/null +++ b/crates/wit-parser/tests/ui/versions/deps/a1/foo.wit @@ -0,0 +1,5 @@ +package a:a@1.0.0 + +interface foo { + type t = u32 +} diff --git a/crates/wit-parser/tests/ui/versions/deps/a2/foo.wit b/crates/wit-parser/tests/ui/versions/deps/a2/foo.wit new file mode 100644 index 0000000000..dfd6625f41 --- /dev/null +++ b/crates/wit-parser/tests/ui/versions/deps/a2/foo.wit @@ -0,0 +1,5 @@ +package a:a@2.0.0 + +interface foo { + type t = u32 +} diff --git a/crates/wit-parser/tests/ui/versions/foo.wit b/crates/wit-parser/tests/ui/versions/foo.wit new file mode 100644 index 0000000000..5dfab6802b --- /dev/null +++ b/crates/wit-parser/tests/ui/versions/foo.wit @@ -0,0 +1,7 @@ +package foo:versions + +interface foo { + use a:a/foo@1.0.0.{t} + use a:a/foo@2.0.0.{t as t2} +} + diff --git a/crates/wit-parser/tests/ui/wasi.wit b/crates/wit-parser/tests/ui/wasi.wit index 4edfbaeec9..df2bf0f434 100644 --- a/crates/wit-parser/tests/ui/wasi.wit +++ b/crates/wit-parser/tests/ui/wasi.wit @@ -1,3 +1,5 @@ +package wasi:filesystem + interface wasi { enum clockid { // The clock measuring real time. Time value zero corresponds with diff --git a/crates/wit-parser/tests/ui/world-diamond.wit b/crates/wit-parser/tests/ui/world-diamond.wit index 5de78b35c5..025e10cbf6 100644 --- a/crates/wit-parser/tests/ui/world-diamond.wit +++ b/crates/wit-parser/tests/ui/world-diamond.wit @@ -1,20 +1,22 @@ +package foo:foo + interface shared { type foo = u32 } interface i1 { - use self.shared.{foo} + use shared.{foo} a: func() -> foo } interface i2 { - use self.shared.{foo} + use shared.{foo} a: func() -> foo } world the-world { - import i1: self.i1 - import i2: self.i2 + import i1 + import i2 } diff --git a/crates/wit-parser/tests/ui/parse-fail/bad-world-type2.wit b/crates/wit-parser/tests/ui/world-iface-no-collide.wit similarity index 69% rename from crates/wit-parser/tests/ui/parse-fail/bad-world-type2.wit rename to crates/wit-parser/tests/ui/world-iface-no-collide.wit index 42cd3248a6..62d178527c 100644 --- a/crates/wit-parser/tests/ui/parse-fail/bad-world-type2.wit +++ b/crates/wit-parser/tests/ui/world-iface-no-collide.wit @@ -1,9 +1,11 @@ +package foo:foo + interface foo { type t = u32 } world bar { - use self.foo.{t} + use foo.{t} import foo: func() } diff --git a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import1.wit b/crates/wit-parser/tests/ui/world-implicit-import1.wit similarity index 77% rename from crates/wit-parser/tests/ui/parse-fail/world-implicit-import1.wit rename to crates/wit-parser/tests/ui/world-implicit-import1.wit index cbaedc8bc9..ea679ccc30 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import1.wit +++ b/crates/wit-parser/tests/ui/world-implicit-import1.wit @@ -1,10 +1,12 @@ +package foo:foo + interface foo { type a = u32 } world the-world { import bar: interface { - use self.foo.{a} + use foo.{a} } import foo: interface {} } diff --git a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import2.wit b/crates/wit-parser/tests/ui/world-implicit-import2.wit similarity index 70% rename from crates/wit-parser/tests/ui/parse-fail/world-implicit-import2.wit rename to crates/wit-parser/tests/ui/world-implicit-import2.wit index 5740f82601..4079ace9c5 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import2.wit +++ b/crates/wit-parser/tests/ui/world-implicit-import2.wit @@ -1,9 +1,11 @@ +package foo:foo + interface foo { type g = char } world w { - use self.foo.{g} + use foo.{g} import foo: func() -> g } diff --git a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import3.wit b/crates/wit-parser/tests/ui/world-implicit-import3.wit similarity index 70% rename from crates/wit-parser/tests/ui/parse-fail/world-implicit-import3.wit rename to crates/wit-parser/tests/ui/world-implicit-import3.wit index b02afa3d9b..29f4e78045 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-implicit-import3.wit +++ b/crates/wit-parser/tests/ui/world-implicit-import3.wit @@ -1,9 +1,11 @@ +package foo:foo + interface foo { type g = char } world w { - use self.foo.{g} + use foo.{g} export foo: func() -> g } diff --git a/crates/wit-parser/tests/ui/parse-fail/world-same-fields4.wit b/crates/wit-parser/tests/ui/world-same-fields4.wit similarity index 76% rename from crates/wit-parser/tests/ui/parse-fail/world-same-fields4.wit rename to crates/wit-parser/tests/ui/world-same-fields4.wit index 766d29fbc3..2b12082760 100644 --- a/crates/wit-parser/tests/ui/parse-fail/world-same-fields4.wit +++ b/crates/wit-parser/tests/ui/world-same-fields4.wit @@ -1,3 +1,5 @@ +package foo:foo + interface shared { type a = u32 } @@ -5,7 +7,7 @@ interface shared { world foo { import shared: interface {} export a-name: interface { - use self.shared.{a} + use shared.{a} } } diff --git a/crates/wit-parser/tests/ui/world-top-level-funcs.wit b/crates/wit-parser/tests/ui/world-top-level-funcs.wit index afcd693ce8..f54f43884d 100644 --- a/crates/wit-parser/tests/ui/world-top-level-funcs.wit +++ b/crates/wit-parser/tests/ui/world-top-level-funcs.wit @@ -1,3 +1,5 @@ +package foo:foo + world foo { import foo: func() export foo2: func() diff --git a/crates/wit-parser/tests/ui/parse-fail/worlds-same-fields5.wit b/crates/wit-parser/tests/ui/worlds-same-fields5.wit similarity index 58% rename from crates/wit-parser/tests/ui/parse-fail/worlds-same-fields5.wit rename to crates/wit-parser/tests/ui/worlds-same-fields5.wit index f460e1f51d..1c6826418a 100644 --- a/crates/wit-parser/tests/ui/parse-fail/worlds-same-fields5.wit +++ b/crates/wit-parser/tests/ui/worlds-same-fields5.wit @@ -1,16 +1,17 @@ +package foo:foo interface i1 { type t = u32 } interface i2 { - use self.i1.{t} + use i1.{t} } interface i3 { - use self.i2.{t} + use i2.{t} } world test { import i1: interface {} - export i4: self.i1 - export i5: self.i3 + export i1 + export i3 } diff --git a/crates/wit-parser/tests/ui/worlds-with-types.wit b/crates/wit-parser/tests/ui/worlds-with-types.wit index 3ca4903a8f..30f96aa9fd 100644 --- a/crates/wit-parser/tests/ui/worlds-with-types.wit +++ b/crates/wit-parser/tests/ui/worlds-with-types.wit @@ -1,3 +1,5 @@ +package foo:foo + world foo { type a = u32 type b = a @@ -11,9 +13,9 @@ interface disambiguate { } world bar { - import disambiguate2: self.disambiguate + import disambiguate - use self.disambiguate.{t} + use disambiguate.{t} export foo: func() -> t } diff --git a/crates/wit-parser/tests/ui/worlds.wit b/crates/wit-parser/tests/ui/worlds.wit index a42b5224cc..aa8014b84a 100644 --- a/crates/wit-parser/tests/ui/worlds.wit +++ b/crates/wit-parser/tests/ui/worlds.wit @@ -1,40 +1,37 @@ +package foo:foo + interface foo {} interface bar {} world the-world { - import foo: self.foo - import bar: self.bar + import foo + import bar import baz: interface { foo: func() } - export foo2: self.foo - export bar2: self.bar + export foo + export bar export baz2: interface { foo: func() } } -default world a-different-world { - import foo: self.foo +world a-different-world { + import foo } interface i1 { type t = u32 } interface i2 { - use self.i1.{t} + use i1.{t} } interface i3 { - use self.i2.{t} + use i2.{t} } world test { - import i3: self.i3 - - export i4: self.i1 - - // This should insert an implicit dependency on `i2` as an import, and then - // i2's dependency on i1 should be wired up to i3's implicit imported - // dependency on i1. - export i5: self.i3 + import i3 + export i1 + export i3 } diff --git a/crates/wit-smith/Cargo.toml b/crates/wit-smith/Cargo.toml index e675377d21..57853c5d65 100644 --- a/crates/wit-smith/Cargo.toml +++ b/crates/wit-smith/Cargo.toml @@ -12,3 +12,5 @@ arbitrary = { workspace = true, features = ["derive"] } wit-component = { workspace = true } wit-parser = { workspace = true } clap = { workspace = true, optional = true } +indexmap = { workspace = true } +log = { workspace = true } diff --git a/crates/wit-smith/src/config.rs b/crates/wit-smith/src/config.rs index 4b3a1cf080..ab2d9304b9 100644 --- a/crates/wit-smith/src/config.rs +++ b/crates/wit-smith/src/config.rs @@ -11,12 +11,12 @@ pub struct Config { pub max_interface_items: usize, #[cfg_attr(feature = "clap", clap(long, default_value_t = Config::default().max_world_items))] pub max_world_items: usize, - #[cfg_attr(feature = "clap", clap(long, default_value_t = Config::default().max_doc_items))] - pub max_doc_items: usize, - #[cfg_attr(feature = "clap", clap(long, default_value_t = Config::default().max_documents))] - pub max_documents: usize, + #[cfg_attr(feature = "clap", clap(long, default_value_t = Config::default().max_pkg_items))] + pub max_pkg_items: usize, #[cfg_attr(feature = "clap", clap(long, default_value_t = Config::default().max_type_parts))] pub max_type_parts: usize, + #[cfg_attr(feature = "clap", clap(long, default_value_t = Config::default().max_files_per_package))] + pub max_files_per_package: usize, } impl Default for Config { @@ -26,9 +26,9 @@ impl Default for Config { max_type_size: 100, max_interface_items: 10, max_world_items: 10, - max_doc_items: 10, - max_documents: 10, + max_pkg_items: 10, max_type_parts: 10, + max_files_per_package: 10, } } } @@ -37,11 +37,11 @@ impl Arbitrary<'_> for Config { fn arbitrary(u: &mut Unstructured<'_>) -> Result { Ok(Config { max_packages: u.int_in_range(1..=20)?, - max_documents: u.int_in_range(1..=10)?, + max_files_per_package: u.int_in_range(1..=10)?, max_type_size: u.int_in_range(0..=1000)?, max_interface_items: u.int_in_range(0..=20)?, max_world_items: u.int_in_range(0..=10)?, - max_doc_items: u.int_in_range(0..=10)?, + max_pkg_items: u.int_in_range(0..=10)?, max_type_parts: u.int_in_range(1..=10)?, }) } diff --git a/crates/wit-smith/src/generate.rs b/crates/wit-smith/src/generate.rs index a7ab46d634..a6025a98b0 100644 --- a/crates/wit-smith/src/generate.rs +++ b/crates/wit-smith/src/generate.rs @@ -1,42 +1,48 @@ use crate::config::Config; use arbitrary::{Arbitrary, Result, Unstructured}; +use indexmap::IndexMap; +use std::collections::hash_map::{Entry, HashMap}; use std::collections::HashSet; -use std::mem; +use std::fmt::Write; +use std::rc::Rc; use std::str; use wit_parser::*; pub struct Generator { config: Config, packages: PackageList, - documents: DocumentList, - interfaces: InterfaceList, next_interface_id: u32, } type TypeList = Vec<(String, usize)>; -type InterfaceList = Vec<(String, u32, bool, TypeList)>; -type DocumentList = Vec<(String, InterfaceList)>; -type PackageList = Vec<(String, DocumentList)>; +type InterfaceList = IndexMap; +type PackageList = Vec<(PackageName, InterfaceList)>; struct InterfaceGenerator<'a> { gen: &'a Generator, + file: &'a mut File, config: &'a Config, unique_names: HashSet, - types_in_interface: Vec<(String, usize)>, + types_in_interface: TypeList, } pub struct Package { - pub name: String, + pub name: PackageName, pub sources: SourceMap, } +#[derive(Clone)] +pub struct PackageName { + pub namespace: String, + pub name: String, + pub version: Option<(u32, u32)>, +} + impl Generator { pub fn new(config: Config) -> Generator { Generator { config, packages: Default::default(), - documents: Default::default(), - interfaces: Default::default(), next_interface_id: 0, } } @@ -45,110 +51,209 @@ impl Generator { let mut packages = Vec::new(); let mut names = HashSet::new(); while packages.len() < self.config.max_packages && (packages.is_empty() || u.arbitrary()?) { - let name = gen_unique_name(u, &mut names)?; - let (sources, documents) = self.gen_package(u)?; - if documents.len() > 0 { - self.packages.push((name.clone(), documents)); + let (pkg, interfaces) = self.gen_package(u, &mut names)?; + if interfaces.len() > 0 { + self.packages.push((pkg.name.clone(), interfaces)); } - packages.push(Package { name, sources }); + packages.push(pkg); } Ok(packages) } - fn gen_package(&mut self, u: &mut Unstructured<'_>) -> Result<(SourceMap, DocumentList)> { - let mut map = SourceMap::new(); - let mut count = 0; - let mut names = HashSet::new(); - - while count < self.config.max_documents && (count == 0 || u.arbitrary()?) { - let name = gen_unique_name(u, &mut names)?; - let (doc, interfaces) = self.gen_document(u)?; - map.push(format!("{name}.wit").as_ref(), &name, doc); - count += 1; - if interfaces.len() > 0 { - self.documents.push((name, interfaces)); - } - } - - Ok((map, mem::take(&mut self.documents))) - } + fn gen_package( + &mut self, + u: &mut Unstructured<'_>, + names: &mut HashSet, + ) -> Result<(Package, InterfaceList)> { + let namespace = gen_unique_name(u, names)?; + let name = gen_unique_name(u, names)?; + let version = if u.arbitrary()? { + Some((u.arbitrary()?, u.arbitrary()?)) + } else { + None + }; + let mut ret = Package { + name: PackageName { + namespace, + name, + version, + }, + sources: SourceMap::new(), + }; - fn gen_document(&mut self, u: &mut Unstructured<'_>) -> Result<(String, InterfaceList)> { #[derive(Arbitrary)] enum Generate { - World, Interface, + Use, + World, Done, } - let mut pieces = Vec::new(); - let mut has_default_interface = false; - let mut has_default_world = false; - let mut names = HashSet::new(); - while pieces.len() < self.config.max_doc_items && !u.is_empty() { - let name = gen_unique_name(u, &mut names)?; + let mut items = 0; + let mut files = vec![File::default()]; + let mut package_names = HashSet::new(); + let mut package = File::default(); + log::debug!("===================== new package ===================="); + while items < self.config.max_pkg_items && !u.is_empty() { + items += 1; + let max = if files.len() < self.config.max_files_per_package { + files.len() + 1 + } else { + files.len() + }; + let i = u.int_in_range(0..=max)?; + let file = match files.get_mut(i) { + Some(file) => file, + None => { + files.push(File { + items: Vec::new(), + namespace: package + .interfaces + .iter() + .map(|(k, _)| (k.clone(), Definition::Package)) + .collect(), + interfaces: package.interfaces.clone(), + }); + files.last_mut().unwrap() + } + }; match u.arbitrary()? { - Generate::World => pieces.push(self.gen_world(u, &name, &mut has_default_world)?), + Generate::World => { + let name = file.gen_unique_package_name(u, &mut package_names)?; + log::debug!("new world `{name}` in {i}"); + let world = self.gen_world(u, &name, file)?; + file.items.push(world); + } Generate::Interface => { + let name = file.gen_unique_package_name(u, &mut package_names)?; + log::debug!("new interface `{name}` in {i}"); let id = self.next_interface_id; self.next_interface_id += 1; - let (src, types) = - self.gen_interface(u, Some(&name), &mut has_default_interface)?; - if types.len() > 0 { - self.interfaces - .push((name, id, src.starts_with("default"), types)); + let (src, types) = self.gen_interface(u, Some(&name), file)?; + file.items.push(src); + if types.is_empty() { + continue; + } + let interface = FileInterface { + name, + id, + types: Rc::new(types), + }; + + // This interface is defined at the package level, and it + // must be unique. + let prev = package + .interfaces + .insert(interface.name.clone(), interface.clone()); + assert!(prev.is_none()); + + // This is also defined at the file level, and it must be + // unique here too. + let prev = file + .interfaces + .insert(interface.name.clone(), interface.clone()); + assert!(prev.is_none()); + + // Insert the definition into all other files as well. + for file in files.iter_mut() { + file.insert_definition(interface.clone()); } - pieces.push(src); + } + Generate::Use => { + let mut piece = String::new(); + piece.push_str("use "); + let (name, id, types) = match self.gen_path(u, &mut package, &mut piece)? { + Some(i) => i, + None => continue, + }; + let name = name.to_string(); + let types = types.clone(); + let name = + if file.namespace.get(&name) == Some(&Definition::File) || u.arbitrary()? { + let name = file.gen_unique_file_name(u)?; + piece.push_str(" as %"); + piece.push_str(&name); + name + } else { + file.namespace.insert(name.clone(), Definition::File); + name + }; + log::debug!("new use `{name}` in {i}"); + file.interfaces + .insert(name.clone(), FileInterface { name, id, types }); + file.items.push(piece) } Generate::Done => break, - } + }; } - shuffle(u, &mut pieces)?; - let mut ret = String::new(); - for piece in pieces { - ret.push_str(&piece); - ret.push_str("\n\n"); + + shuffle(u, &mut files)?; + for file in files.iter_mut() { + shuffle(u, &mut file.items)?; + } + + let mut has_name = false; + let len = files.len(); + for (i, file) in files.iter_mut().enumerate() { + let mut s = String::new(); + if u.arbitrary()? || (!has_name && i == len - 1) { + has_name = true; + s.push_str("package "); + s.push_str("%"); + s.push_str(&ret.name.namespace); + s.push_str(":"); + s.push_str("%"); + s.push_str(&ret.name.name); + if let Some((a, b)) = ret.name.version { + s.push_str(&format!("@{a}.{b}")); + } + s.push_str("\n\n"); + } + for piece in file.items.iter() { + s.push_str(&piece); + s.push_str("\n\n"); + } + log::trace!("==============================================="); + log::trace!("{s}"); + ret.sources.push(format!("wit{i}.wit").as_ref(), &s); } - Ok((ret, mem::take(&mut self.interfaces))) + Ok((ret, package.interfaces)) } fn gen_world( &mut self, u: &mut Unstructured<'_>, name: &str, - has_default: &mut bool, + file: &mut File, ) -> Result { - InterfaceGenerator::new(self).gen_world(u, name, has_default) + InterfaceGenerator::new(self, file).gen_world(u, name) } fn gen_interface( &mut self, u: &mut Unstructured<'_>, name: Option<&str>, - has_default: &mut bool, + file: &mut File, ) -> Result<(String, TypeList)> { - let mut gen = InterfaceGenerator::new(self); - let ret = gen.gen_interface(u, name, has_default)?; + let mut gen = InterfaceGenerator::new(self, file); + let ret = gen.gen_interface(u, name)?; Ok((ret, gen.types_in_interface)) } - fn gen_path( - &self, + fn gen_path<'a>( + &'a self, u: &mut Unstructured<'_>, + file: &'a mut File, dst: &mut String, - ) -> Result> { + ) -> Result)>> { enum Choice { Interfaces, - Documents, Packages, } let mut choices = Vec::new(); - if !self.interfaces.is_empty() { + if !file.interfaces.is_empty() { choices.push(Choice::Interfaces); } - if !self.documents.is_empty() { - choices.push(Choice::Documents); - } if !self.packages.is_empty() { choices.push(Choice::Packages); } @@ -157,70 +262,54 @@ impl Generator { } Ok(match u.choose(&choices)? { Choice::Interfaces => { - dst.push_str("self."); - let (name, id, _default, types) = u.choose(&self.interfaces)?; - dst.push_str("%"); - dst.push_str(name); - Some((*id, types)) - } - Choice::Documents => { - dst.push_str("pkg."); - let (name, ifaces) = u.choose(&self.documents)?; + let i = u.int_in_range(0..=file.interfaces.len() - 1)?; + let (name, i) = file.interfaces.get_index(i).unwrap(); + // Once a name is used from a file's local namespace then it + // can't be overridden in that namespace so switch it to a file + // definition from whatever it previously was. + file.namespace.insert(name.clone(), Definition::File); dst.push_str("%"); - dst.push_str(name); - let (name, id, default, types) = u.choose(ifaces)?; - if !*default || !u.arbitrary()? { - dst.push_str("."); - dst.push_str("%"); - dst.push_str(name); - } - Some((*id, types)) + dst.push_str(&i.name); + Some((&i.name, i.id, &i.types)) } Choice::Packages => { - let (name, docs) = u.choose(&self.packages)?; + let (pkg, ifaces) = u.choose(&self.packages)?; dst.push_str("%"); - dst.push_str(name); - dst.push_str("."); - let (name, ifaces) = u.choose(docs)?; + dst.push_str(&pkg.namespace); + dst.push_str(":"); dst.push_str("%"); - dst.push_str(name); - let (name, id, default, types) = u.choose(ifaces)?; - if !*default || !u.arbitrary()? { - dst.push_str("."); - dst.push_str("%"); - dst.push_str(name); + dst.push_str(&pkg.name); + dst.push_str("/"); + let i = u.int_in_range(0..=ifaces.len() - 1)?; + let i = &ifaces[i]; + dst.push_str("%"); + dst.push_str(&i.name); + if let Some((a, b)) = &pkg.version { + dst.push_str(&format!("@{a}.{b}")); } - Some((*id, types)) + Some((&i.name, i.id, &i.types)) } }) } } impl<'a> InterfaceGenerator<'a> { - fn new(gen: &'a Generator) -> InterfaceGenerator<'a> { + fn new(gen: &'a Generator, file: &'a mut File) -> InterfaceGenerator<'a> { // Claim the name `memory` to avoid conflicting with the canonical ABI // always using a linear memory named `memory`. let mut unique_names = HashSet::new(); unique_names.insert("memory".to_string()); InterfaceGenerator { gen, + file, config: &gen.config, types_in_interface: Vec::new(), unique_names, } } - fn gen_interface( - &mut self, - u: &mut Unstructured<'_>, - name: Option<&str>, - has_default: &mut bool, - ) -> Result { + fn gen_interface(&mut self, u: &mut Unstructured<'_>, name: Option<&str>) -> Result { let mut ret = String::new(); - if !*has_default && u.arbitrary()? { - *has_default = true; - ret.push_str("default "); - } ret.push_str("interface "); if let Some(name) = name { ret.push_str("%"); @@ -267,17 +356,8 @@ impl<'a> InterfaceGenerator<'a> { Ok(ret) } - fn gen_world( - &mut self, - u: &mut Unstructured<'_>, - name: &str, - has_default: &mut bool, - ) -> Result { + fn gen_world(&mut self, u: &mut Unstructured<'_>, name: &str) -> Result { let mut ret = String::new(); - if !*has_default && u.arbitrary()? { - *has_default = true; - ret.push_str("default "); - } ret.push_str("world %"); ret.push_str(name); ret.push_str(" {\n"); @@ -303,35 +383,40 @@ impl<'a> InterfaceGenerator<'a> { while parts.len() < self.config.max_world_items && !u.is_empty() && u.arbitrary()? { let kind = u.arbitrary::()?; - let direction = match kind { - ItemKind::Func(dir) | ItemKind::Interface(dir) | ItemKind::AnonInterface(dir) => { - Some(dir) - } - ItemKind::Type | ItemKind::Use => None, + let (direction, named) = match kind { + ItemKind::Func(dir) | ItemKind::AnonInterface(dir) => (Some(dir), true), + ItemKind::Interface(dir) => (Some(dir), false), + ItemKind::Type => (None, true), + ItemKind::Use => (None, false), }; let mut part = String::new(); - let name = match direction { - Some(Direction::Import) | None => gen_unique_name(u, &mut self.unique_names)?, - Some(Direction::Export) => gen_unique_name(u, &mut self.unique_names)?, - }; if let Some(dir) = direction { part.push_str(match dir { - Direction::Import => "import", - Direction::Export => "export", + Direction::Import => "import ", + Direction::Export => "export ", }); - part.push_str(" %"); - part.push_str(&name); - part.push_str(": "); } + let name = if named { + let name = gen_unique_name(u, &mut self.unique_names)?; + if direction.is_some() { + part.push_str("%"); + part.push_str(&name); + part.push_str(": "); + } + Some(name) + } else { + None + }; + match kind { ItemKind::Func(_) => { self.gen_func_sig(u, &mut part)?; } ItemKind::Interface(dir) => { - let id = match self.gen.gen_path(u, &mut part)? { - Some((id, _types)) => id, + let id = match self.gen.gen_path(u, self.file, &mut part)? { + Some((_name, id, _types)) => id, // If an interface couldn't be chosen or wasn't // chosen then skip this import. A unique name was // selecteed above but we just sort of leave that @@ -353,11 +438,12 @@ impl<'a> InterfaceGenerator<'a> { } ItemKind::AnonInterface(_) => { let iface = - InterfaceGenerator::new(self.gen).gen_interface(u, None, &mut true)?; + InterfaceGenerator::new(self.gen, self.file).gen_interface(u, None)?; part.push_str(&iface); } ItemKind::Type => { + let name = name.unwrap(); let (size, typedef) = self.gen_typedef(u, &name)?; assert!(part.is_empty()); part = typedef; @@ -387,7 +473,7 @@ impl<'a> InterfaceGenerator<'a> { fn gen_use(&mut self, u: &mut Unstructured<'_>, part: &mut String) -> Result { let mut path = String::new(); - let (_id, types) = match self.gen.gen_path(u, &mut path)? { + let (_name, _id, types) = match self.gen.gen_path(u, self.file, &mut path)? { Some(types) => types, None => return Ok(false), }; @@ -395,6 +481,7 @@ impl<'a> InterfaceGenerator<'a> { part.push_str(&path); part.push_str(".{"); let (name, size) = u.choose(types)?; + let size = *size; part.push_str("%"); part.push_str(name); let name = if self.unique_names.contains(name) || u.arbitrary()? { @@ -406,7 +493,7 @@ impl<'a> InterfaceGenerator<'a> { assert!(self.unique_names.insert(name.clone())); name.clone() }; - self.types_in_interface.push((name, *size)); + self.types_in_interface.push((name, size)); part.push_str("}"); Ok(true) } @@ -672,7 +759,6 @@ impl<'a> InterfaceGenerator<'a> { } fn gen_unique_name(u: &mut Unstructured<'_>, set: &mut HashSet) -> Result { - use std::fmt::Write; let mut name = gen_name(u)?; while !set.insert(name.clone()) { write!(&mut name, "{}", set.len()).unwrap(); @@ -713,3 +799,91 @@ fn shuffle(u: &mut Unstructured<'_>, mut slice: &mut [T]) -> Result<()> { } Ok(()) } + +#[derive(Default)] +struct File { + items: Vec, + namespace: HashMap, + interfaces: IndexMap, +} + +#[derive(Clone)] +struct FileInterface { + name: String, + id: u32, + types: Rc, +} + +#[derive(PartialEq)] +enum Definition { + Package, + File, +} + +impl File { + fn gen_unique_package_name( + &mut self, + u: &mut Unstructured<'_>, + names: &mut HashSet, + ) -> Result { + let mut name = gen_name(u)?; + loop { + // Find a package-unique name first + if !names.insert(name.clone()) { + write!(&mut name, "{}", names.len()).unwrap(); + continue; + } + + // Then make sure it's file-unique too + if self.claim_file_name(&mut name) { + break; + } + } + Ok(name) + } + + fn gen_unique_file_name(&mut self, u: &mut Unstructured<'_>) -> Result { + let mut name = gen_name(u)?; + while !self.claim_file_name(&mut name) { + // try again on the next iteration + } + Ok(name) + } + + fn claim_file_name(&mut self, name: &mut String) -> bool { + match self.namespace.entry(name.clone()) { + Entry::Occupied(mut e) => match e.get() { + // If this name is already claimed elsewhere in the package + // then that's ok as we're going to shadow it, so switch it + // to a file definition. + Definition::Package => *e.get_mut() = Definition::File, + + // If it's already defined in the file try to add more stuff + // to the name to make the next try not collide. + Definition::File => { + name.push_str("y"); + write!(name, "{}", self.namespace.len()).unwrap(); + return false; + } + }, + + // Not defined? Claim it. + Entry::Vacant(v) => { + v.insert(Definition::File); + } + } + true + } + + fn insert_definition(&mut self, def: FileInterface) { + match self.namespace.get(&def.name) { + Some(Definition::File) => return, + Some(Definition::Package) => unreachable!(), + None => {} + } + let prev = self.namespace.insert(def.name.clone(), Definition::Package); + assert!(prev.is_none()); + let prev = self.interfaces.insert(def.name.clone(), def); + assert!(prev.is_none()); + } +} diff --git a/crates/wit-smith/src/lib.rs b/crates/wit-smith/src/lib.rs index 6307bc1c23..4dfdb8deb2 100644 --- a/crates/wit-smith/src/lib.rs +++ b/crates/wit-smith/src/lib.rs @@ -6,7 +6,6 @@ //! type structures. use arbitrary::{Result, Unstructured}; -use std::collections::HashMap; use wit_parser::Resolve; mod config; @@ -20,26 +19,13 @@ mod generate; pub fn smith(config: &Config, u: &mut Unstructured<'_>) -> Result> { let pkgs = generate::Generator::new(config.clone()).gen(u)?; let mut resolve = Resolve::default(); - let mut deps = HashMap::new(); let mut last = None; for pkg in pkgs { - let url = format!("my-scheme:/{}", pkg.name); - let unresolved = pkg.sources.parse(&pkg.name, Some(&url)).unwrap(); - let id = match resolve.push(unresolved, &deps) { + let unresolved = pkg.sources.parse().unwrap(); + let id = match resolve.push(unresolved) { Ok(id) => id, - Err(e) => { - let err = e.to_string(); - if err.contains("conflicts with a previous") - || err.contains("shadows previously imported") - || err.contains("shadows previously exported") - { - return Err(arbitrary::Error::IncorrectFormat); - } - panic!("bad wit parse: {e:?}") - } + Err(e) => panic!("bad wit parse: {e:?}"), }; - let prev = deps.insert(pkg.name, id); - assert!(prev.is_none()); last = Some(id); } let pkg = last.unwrap(); diff --git a/fuzz/fuzz_targets/roundtrip-wit.rs b/fuzz/fuzz_targets/roundtrip-wit.rs index 92e62e1eda..c2c5cc3f26 100644 --- a/fuzz/fuzz_targets/roundtrip-wit.rs +++ b/fuzz/fuzz_targets/roundtrip-wit.rs @@ -1,8 +1,8 @@ #![no_main] use libfuzzer_sys::fuzz_target; +use std::borrow::Cow; use std::path::Path; -use std::{borrow::Cow, collections::HashMap}; use wasm_encoder::{CustomSection, Encode, Section}; use wit_component::*; use wit_parser::{Resolve, SourceMap}; @@ -19,13 +19,13 @@ fuzz_target!(|data: &[u8]| { Err(_) => return, }; write_file("doc1.wasm", &wasm); - let (resolve, _pkg) = match wit_component::decode("root", &wasm).unwrap() { + let (resolve, _pkg) = match wit_component::decode(&wasm).unwrap() { DecodedWasm::WitPackage(resolve, pkg) => (resolve, pkg), DecodedWasm::Component(..) => unreachable!(), }; roundtrip_through_printing("doc1", &resolve, &wasm); - let (resolve2, pkg2) = match wit_component::decode("root", &wasm).unwrap() { + let (resolve2, pkg2) = match wit_component::decode(&wasm).unwrap() { DecodedWasm::WitPackage(resolve, pkg) => (resolve, pkg), DecodedWasm::Component(..) => unreachable!(), }; @@ -65,27 +65,23 @@ fuzz_target!(|data: &[u8]| { .validate_all(&wasm) .unwrap(); - wit_component::decode("root", &wasm).unwrap(); + wit_component::decode(&wasm).unwrap(); } }); fn roundtrip_through_printing(file: &str, resolve: &Resolve, wasm: &[u8]) { // For all packages in `resolve` print them all to a string, then re-parse // them and insert them into a `new_resolve`. - let mut new_deps = HashMap::new(); let mut new_resolve = Resolve::default(); let mut last = None; - for (_, pkg) in resolve.packages.iter() { + for (id, pkg) in resolve.packages.iter() { let mut map = SourceMap::new(); let pkg_name = &pkg.name; - for (name, doc) in pkg.documents.iter() { - let doc = DocumentPrinter::default().print(resolve, *doc).unwrap(); - write_file(&format!("{file}-{pkg_name}-{name}.wit"), &doc); - map.push(format!("{name}.wit").as_ref(), &name, doc); - } - let unresolved = map.parse(&pkg.name, pkg.url.as_deref()).unwrap(); - let id = new_resolve.push(unresolved, &new_deps).unwrap(); - new_deps.insert(pkg.name.clone(), id); + let doc = WitPrinter::default().print(resolve, id).unwrap(); + write_file(&format!("{file}-{pkg_name}.wit"), &doc); + map.push(format!("{pkg_name}.wit").as_ref(), doc); + let unresolved = map.parse().unwrap(); + let id = new_resolve.push(unresolved).unwrap(); last = Some(id); } diff --git a/src/bin/wasm-tools/component.rs b/src/bin/wasm-tools/component.rs index 544ec5d621..993a200ceb 100644 --- a/src/bin/wasm-tools/component.rs +++ b/src/bin/wasm-tools/component.rs @@ -1,13 +1,13 @@ //! The WebAssembly component tool command line interface. -use anyhow::{anyhow, bail, Context, Result}; +use anyhow::{bail, Context, Result}; use clap::Parser; use std::borrow::Cow; use std::io::Read; use std::path::{Path, PathBuf}; use wasm_encoder::{Encode, Section}; use wasm_tools::Output; -use wit_component::{ComponentEncoder, DecodedWasm, DocumentPrinter, StringEncoding}; +use wit_component::{ComponentEncoder, DecodedWasm, StringEncoding, WitPrinter}; use wit_parser::{PackageId, Resolve, UnresolvedPackage}; /// WebAssembly wit-based component tooling. @@ -249,31 +249,6 @@ pub struct WitOpts { #[clap(flatten)] output: wasm_tools::OutputArg, - /// If a WIT package is being parsed, then this is the optionally specified - /// name of the WIT package. If not specified this is automatically inferred - /// from the filename. - #[clap(long)] - name: Option, - - /// When printing a WIT package, the default mode, this option is used to - /// indicate which document is printed within the package if more than one - /// document is present. - #[clap(short, long, conflicts_with = "wasm", conflicts_with = "wat")] - document: Option, - - /// Emit a full WIT package into the specified directory when printing the - /// text form. - /// - /// This is incompatible with `-o`. - #[clap( - long, - conflicts_with = "output", - conflicts_with = "wasm", - conflicts_with = "wat", - conflicts_with = "document" - )] - out_dir: Option, - /// Emit a WebAssembly binary representation instead of the WIT text format. #[clap(short, long, conflicts_with = "wat")] wasm: bool, @@ -296,14 +271,6 @@ impl WitOpts { /// Executes the application. fn run(self) -> Result<()> { - let name = match &self.name { - Some(name) => name.as_str(), - None => match &self.input { - Some(path) => path.file_stem().unwrap().to_str().unwrap(), - None => "component", - }, - }; - // First up determine the actual `DecodedWasm` as the input. This could // come from a number of sources: // @@ -322,7 +289,7 @@ impl WitOpts { Some(input) => match input.extension().and_then(|s| s.to_str()) { Some("wat") | Some("wasm") => { let bytes = wat::parse_file(&input)?; - decode_wasm(name, &bytes).context("failed to decode WIT document")? + decode_wasm(&bytes).context("failed to decode WIT document")? } _ => { let (resolve, id) = parse_wit(input)?; @@ -341,7 +308,7 @@ impl WitOpts { e })?; - decode_wasm(name, &bytes).context("failed to decode WIT document")? + decode_wasm(&bytes).context("failed to decode WIT document")? } else { let stdin = match std::str::from_utf8(&stdin) { Ok(s) => s, @@ -349,7 +316,7 @@ impl WitOpts { }; let mut resolve = Resolve::default(); let pkg = UnresolvedPackage::parse("".as_ref(), stdin)?; - let id = resolve.push(pkg, &Default::default())?; + let id = resolve.push(pkg)?; DecodedWasm::WitPackage(resolve, id) } } @@ -357,55 +324,18 @@ impl WitOpts { // Now that the WIT document has been decoded, it's time to emit it. // This interprets all of the output options and performs such a task. - match &self.out_dir { - Some(dir) => { - assert!(self.output.output_path().is_none()); - assert!(!self.wasm && !self.wat); - assert!(self.document.is_none()); - let package = match &decoded { - DecodedWasm::WitPackage(_, package) => *package, - - DecodedWasm::Component(resolve, world) => { - let doc = resolve.worlds[*world].document; - resolve.documents[doc].package.unwrap() - } - }; - let resolve = decoded.resolve(); - std::fs::create_dir_all(&dir) - .with_context(|| format!("failed to create {dir:?}"))?; - for (name, doc) in resolve.packages[package].documents.iter() { - let output = DocumentPrinter::default().print(&resolve, *doc)?; - let path = dir.join(format!("{name}.wit")); - std::fs::write(&path, output) - .with_context(|| format!("failed to write {path:?}"))?; - } - } - None => { - if self.wasm || self.wat { - self.emit_wasm(&decoded)?; - } else { - self.emit_wit(&decoded)?; - } - } + if self.wasm || self.wat { + self.emit_wasm(&decoded)?; + } else { + self.emit_wit(&decoded)?; } Ok(()) } fn emit_wasm(&self, decoded: &DecodedWasm) -> Result<()> { assert!(self.wasm || self.wat); - assert!(self.out_dir.is_none()); - assert!(self.document.is_none()); - - let pkg = match decoded { - DecodedWasm::WitPackage(_resolve, pkg) => *pkg, - DecodedWasm::Component(resolve, world) => { - let doc = resolve.worlds[*world].document; - resolve.documents[doc].package.unwrap() - } - }; - let resolve = decoded.resolve(); - let bytes = wit_component::encode(&resolve, pkg)?; + let bytes = wit_component::encode(decoded.resolve(), decoded.package())?; if !self.skip_validation { wasmparser::Validator::new_with_features(wasmparser::WasmFeatures { component_model: true, @@ -422,32 +352,11 @@ impl WitOpts { fn emit_wit(&self, decoded: &DecodedWasm) -> Result<()> { assert!(!self.wasm && !self.wat); - assert!(self.out_dir.is_none()); if self.wat { bail!("the `--wat` option can only be combined with `--wasm`"); } - let doc = match decoded { - DecodedWasm::WitPackage(resolve, pkg) => { - let pkg = &resolve.packages[*pkg]; - match &self.document { - Some(name) => *pkg - .documents - .get(name) - .ok_or_else(|| anyhow!("no document named `{name}` found in package"))?, - None => match pkg.documents.len() { - 1 => *pkg.documents.iter().next().unwrap().1, - _ => bail!( - "more than document found in package, \ - specify which to print with `-d name`" - ), - }, - } - } - DecodedWasm::Component(resolve, world) => resolve.worlds[*world].document, - }; - - let output = DocumentPrinter::default().print(decoded.resolve(), doc)?; + let output = WitPrinter::default().print(decoded.resolve(), decoded.package())?; self.output.output(Output::Wat(&output))?; Ok(()) } @@ -465,7 +374,7 @@ fn parse_wit(path: &Path) -> Result<(Resolve, PackageId)> { e.set_path(path); e })?; - match wit_component::decode("root-package-name", &bytes)? { + match wit_component::decode(&bytes)? { DecodedWasm::Component(..) => { bail!("specified path is a component, not a wit package") } @@ -477,7 +386,7 @@ fn parse_wit(path: &Path) -> Result<(Resolve, PackageId)> { Err(_) => bail!("input file is not valid utf-8"), }; let pkg = UnresolvedPackage::parse(&path, text)?; - resolve.push(pkg, &Default::default())? + resolve.push(pkg)? } }; Ok((resolve, id)) @@ -511,9 +420,9 @@ fn is_wasm(bytes: &[u8]) -> bool { false } -fn decode_wasm(name: &str, bytes: &[u8]) -> Result { +fn decode_wasm(bytes: &[u8]) -> Result { if wasmparser::Parser::is_component(bytes) { - wit_component::decode(name, bytes) + wit_component::decode(bytes) } else { let (_wasm, bindgen) = wit_component::metadata::decode(bytes)?; Ok(DecodedWasm::Component(bindgen.resolve, bindgen.world)) diff --git a/tests/cli/dump/alias.wat.stdout b/tests/cli/dump/alias.wat.stdout index 80b9f12093..cb3c4c1c6f 100644 --- a/tests/cli/dump/alias.wat.stdout +++ b/tests/cli/dump/alias.wat.stdout @@ -1,18 +1,18 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 1f | component type section 0xa | 01 | 1 count - 0xb | 42 04 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: "f1", url: "", ty: Func(0) }, Type(Func(ComponentFuncType { params: [("p1", Primitive(String))], results: Named([]) })), Export { name: "f2", url: "", ty: Func(1) }]) + 0xb | 42 04 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab("f1"), ty: Func(0) }, Type(Func(ComponentFuncType { params: [("p1", Primitive(String))], results: Named([]) })), Export { name: Kebab("f2"), ty: Func(1) }]) | 00 01 00 04 - | 02 66 31 00 + | 00 02 66 31 | 01 00 01 40 | 01 02 70 31 | 73 01 00 04 - | 02 66 32 00 + | 00 02 66 32 | 01 01 0x29 | 0a 06 | component import section 0x2b | 01 | 1 count - 0x2c | 01 69 00 05 | [instance 0] ComponentImport { name: "i", url: "", ty: Instance(0) } + 0x2c | 00 01 69 05 | [instance 0] ComponentImport { name: Kebab("i"), ty: Instance(0) } | 00 0x31 | 06 13 | component alias section 0x33 | 03 | 3 count diff --git a/tests/cli/dump/alias2.wat.stdout b/tests/cli/dump/alias2.wat.stdout index cb043b86a9..4e86f597de 100644 --- a/tests/cli/dump/alias2.wat.stdout +++ b/tests/cli/dump/alias2.wat.stdout @@ -1,55 +1,55 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 30 | component type section 0xa | 01 | 1 count - 0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: "a", url: "", ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: "b", url: "", ty: Func(0) }, Export { name: "c", url: "", ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: "d", url: "", ty: Instance(1) }, Type(Component([])), Export { name: "e", url: "", ty: Component(2) }]) - | 00 04 01 61 - | 00 00 11 00 + 0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: Kebab("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab("b"), ty: Func(0) }, Export { name: Kebab("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: Kebab("d"), ty: Instance(1) }, Type(Component([])), Export { name: Kebab("e"), ty: Component(2) }]) + | 00 04 00 01 + | 61 00 11 00 | 01 40 00 01 - | 00 04 01 62 - | 00 01 00 04 - | 01 63 00 02 + | 00 04 00 01 + | 62 01 00 04 + | 00 01 63 02 | 73 01 42 00 - | 04 01 64 00 + | 04 00 01 64 | 05 01 01 41 - | 00 04 01 65 - | 00 04 02 + | 00 04 00 01 + | 65 04 02 0x3a | 0a 06 | component import section 0x3c | 01 | 1 count - 0x3d | 01 61 00 05 | [instance 0] ComponentImport { name: "a", url: "", ty: Instance(0) } + 0x3d | 00 01 61 05 | [instance 0] ComponentImport { name: Kebab("a"), ty: Instance(0) } | 00 0x42 | 04 59 | [component 0] inline size - 0x44 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x44 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x4c | 03 03 | core type section 0x4e | 01 | 1 count 0x4f | 50 00 | [core type 0] Module([]) 0x51 | 0a 07 | component import section 0x53 | 01 | 1 count - 0x54 | 01 61 00 00 | [module 0] ComponentImport { name: "a", url: "", ty: Module(0) } + 0x54 | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) } | 11 00 0x5a | 07 05 | component type section 0x5c | 01 | 1 count 0x5d | 40 00 01 00 | [type 0] Func(ComponentFuncType { params: [], results: Named([]) }) 0x61 | 0a 0b | component import section 0x63 | 02 | 2 count - 0x64 | 01 62 00 01 | [func 0] ComponentImport { name: "b", url: "", ty: Func(0) } + 0x64 | 00 01 62 01 | [func 0] ComponentImport { name: Kebab("b"), ty: Func(0) } | 00 - 0x69 | 01 63 00 02 | [value 0] ComponentImport { name: "c", url: "", ty: Value(Primitive(String)) } + 0x69 | 00 01 63 02 | [value 0] ComponentImport { name: Kebab("c"), ty: Value(Primitive(String)) } | 73 0x6e | 07 03 | component type section 0x70 | 01 | 1 count 0x71 | 42 00 | [type 1] Instance([]) 0x73 | 0a 06 | component import section 0x75 | 01 | 1 count - 0x76 | 01 64 00 05 | [instance 0] ComponentImport { name: "d", url: "", ty: Instance(1) } + 0x76 | 00 01 64 05 | [instance 0] ComponentImport { name: Kebab("d"), ty: Instance(1) } | 01 0x7b | 07 03 | component type section 0x7d | 01 | 1 count 0x7e | 41 00 | [type 2] Component([]) 0x80 | 0a 06 | component import section 0x82 | 01 | 1 count - 0x83 | 01 65 00 04 | [component 0] ComponentImport { name: "e", url: "", ty: Component(2) } + 0x83 | 00 01 65 04 | [component 0] ComponentImport { name: Kebab("e"), ty: Component(2) } | 02 0x88 | 00 13 | custom section 0x8a | 0e 63 6f 6d | name: "component-name" @@ -79,14 +79,14 @@ | 01 64 05 01 | 01 65 04 01 0xd5 | 04 34 | [component 2] inline size - 0xd7 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0xd7 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0xdf | 06 05 | component alias section 0xe1 | 01 | 1 count 0xe2 | 03 02 01 00 | alias [type 0] Outer { kind: Type, count: 1, index: 0 } 0xe6 | 0a 06 | component import section 0xe8 | 01 | 1 count - 0xe9 | 01 61 00 05 | [instance 0] ComponentImport { name: "a", url: "", ty: Instance(0) } + 0xe9 | 00 01 61 05 | [instance 0] ComponentImport { name: Kebab("a"), ty: Instance(0) } | 00 0xee | 00 1b | custom section 0xf0 | 0e 63 6f 6d | name: "component-name" @@ -110,137 +110,138 @@ | 64 0x123 | 04 00 00 01 | alias [component 3] InstanceExport { kind: Component, instance_index: 0, name: "e" } | 65 - 0x128 | 05 1f | component instance section + 0x128 | 05 24 | component instance section 0x12a | 02 | 2 count - 0x12b | 01 05 01 61 | [instance 4] FromExports([ComponentExport { name: "a", url: "", kind: Module, index: 1, ty: None }, ComponentExport { name: "b", url: "", kind: Func, index: 1, ty: None }, ComponentExport { name: "c", url: "", kind: Value, index: 1, ty: None }, ComponentExport { name: "d", url: "", kind: Instance, index: 3, ty: None }, ComponentExport { name: "e", url: "", kind: Component, index: 3, ty: None }]) - | 00 11 01 01 - | 62 01 01 01 - | 63 02 01 01 - | 64 05 03 01 - | 65 04 03 - 0x142 | 00 02 01 01 | [instance 5] Instantiate { component_index: 2, args: [ComponentInstantiationArg { name: "a", kind: Instance, index: 4 }] } + 0x12b | 01 05 00 01 | [instance 4] FromExports([ComponentExport { name: Kebab("a"), kind: Module, index: 1, ty: None }, ComponentExport { name: Kebab("b"), kind: Func, index: 1, ty: None }, ComponentExport { name: Kebab("c"), kind: Value, index: 1, ty: None }, ComponentExport { name: Kebab("d"), kind: Instance, index: 3, ty: None }, ComponentExport { name: Kebab("e"), kind: Component, index: 3, ty: None }]) + | 61 00 11 01 + | 00 01 62 01 + | 01 00 01 63 + | 02 01 00 01 + | 64 05 03 00 + | 01 65 04 03 + 0x147 | 00 02 01 01 | [instance 5] Instantiate { component_index: 2, args: [ComponentInstantiationArg { name: "a", kind: Instance, index: 4 }] } | 61 05 04 - 0x149 | 01 48 | [core module 2] inline size - 0x14b | 00 61 73 6d | version 1 (Module) + 0x14e | 01 48 | [core module 2] inline size + 0x150 | 00 61 73 6d | version 1 (Module) | 01 00 00 00 - 0x153 | 01 04 | type section - 0x155 | 01 | 1 count - 0x156 | 60 00 00 | [type 0] Func(FuncType { params: [], returns: [] }) - 0x159 | 03 02 | func section - 0x15b | 01 | 1 count - 0x15c | 00 | [func 0] type 0 - 0x15d | 04 04 | table section - 0x15f | 01 | 1 count - 0x160 | 70 00 01 | [table 0] Table { ty: TableType { element_type: funcref, initial: 1, maximum: None }, init: RefNull } - 0x163 | 05 03 | memory section - 0x165 | 01 | 1 count - 0x166 | 00 01 | [memory 0] MemoryType { memory64: false, shared: false, initial: 1, maximum: None } - 0x168 | 06 04 | global section + 0x158 | 01 04 | type section + 0x15a | 01 | 1 count + 0x15b | 60 00 00 | [type 0] Func(FuncType { params: [], returns: [] }) + 0x15e | 03 02 | func section + 0x160 | 01 | 1 count + 0x161 | 00 | [func 0] type 0 + 0x162 | 04 04 | table section + 0x164 | 01 | 1 count + 0x165 | 70 00 01 | [table 0] Table { ty: TableType { element_type: funcref, initial: 1, maximum: None }, init: RefNull } + 0x168 | 05 03 | memory section 0x16a | 01 | 1 count - 0x16b | 7f 00 | [global 0] GlobalType { content_type: I32, mutable: false } - 0x16d | 0b | end - 0x16e | 07 11 | export section - 0x170 | 04 | 4 count - 0x171 | 01 31 00 00 | export Export { name: "1", kind: Func, index: 0 } - 0x175 | 01 32 02 00 | export Export { name: "2", kind: Memory, index: 0 } - 0x179 | 01 33 03 00 | export Export { name: "3", kind: Global, index: 0 } - 0x17d | 01 34 01 00 | export Export { name: "4", kind: Table, index: 0 } - 0x181 | 0a 04 | code section - 0x183 | 01 | 1 count + 0x16b | 00 01 | [memory 0] MemoryType { memory64: false, shared: false, initial: 1, maximum: None } + 0x16d | 06 04 | global section + 0x16f | 01 | 1 count + 0x170 | 7f 00 | [global 0] GlobalType { content_type: I32, mutable: false } + 0x172 | 0b | end + 0x173 | 07 11 | export section + 0x175 | 04 | 4 count + 0x176 | 01 31 00 00 | export Export { name: "1", kind: Func, index: 0 } + 0x17a | 01 32 02 00 | export Export { name: "2", kind: Memory, index: 0 } + 0x17e | 01 33 03 00 | export Export { name: "3", kind: Global, index: 0 } + 0x182 | 01 34 01 00 | export Export { name: "4", kind: Table, index: 0 } + 0x186 | 0a 04 | code section + 0x188 | 01 | 1 count ============== func 0 ==================== - 0x184 | 02 | size of function - 0x185 | 00 | 0 local blocks - 0x186 | 0b | end - 0x187 | 00 0a | custom section - 0x189 | 04 6e 61 6d | name: "name" + 0x189 | 02 | size of function + 0x18a | 00 | 0 local blocks + 0x18b | 0b | end + 0x18c | 00 0a | custom section + 0x18e | 04 6e 61 6d | name: "name" | 65 - 0x18e | 00 03 | module name - 0x190 | 02 6d 31 | "m1" - 0x193 | 01 35 | [core module 3] inline size - 0x195 | 00 61 73 6d | version 1 (Module) + 0x193 | 00 03 | module name + 0x195 | 02 6d 31 | "m1" + 0x198 | 01 35 | [core module 3] inline size + 0x19a | 00 61 73 6d | version 1 (Module) | 01 00 00 00 - 0x19d | 01 04 | type section - 0x19f | 01 | 1 count - 0x1a0 | 60 00 00 | [type 0] Func(FuncType { params: [], returns: [] }) - 0x1a3 | 02 19 | import section - 0x1a5 | 04 | 4 count - 0x1a6 | 00 01 31 00 | import [func 0] Import { module: "", name: "1", ty: Func(0) } + 0x1a2 | 01 04 | type section + 0x1a4 | 01 | 1 count + 0x1a5 | 60 00 00 | [type 0] Func(FuncType { params: [], returns: [] }) + 0x1a8 | 02 19 | import section + 0x1aa | 04 | 4 count + 0x1ab | 00 01 31 00 | import [func 0] Import { module: "", name: "1", ty: Func(0) } | 00 - 0x1ab | 00 01 32 02 | import [memory 0] Import { module: "", name: "2", ty: Memory(MemoryType { memory64: false, shared: false, initial: 1, maximum: None }) } + 0x1b0 | 00 01 32 02 | import [memory 0] Import { module: "", name: "2", ty: Memory(MemoryType { memory64: false, shared: false, initial: 1, maximum: None }) } | 00 01 - 0x1b1 | 00 01 33 03 | import [global 0] Import { module: "", name: "3", ty: Global(GlobalType { content_type: I32, mutable: false }) } + 0x1b6 | 00 01 33 03 | import [global 0] Import { module: "", name: "3", ty: Global(GlobalType { content_type: I32, mutable: false }) } | 7f 00 - 0x1b7 | 00 01 34 01 | import [table 0] Import { module: "", name: "4", ty: Table(TableType { element_type: funcref, initial: 1, maximum: None }) } + 0x1bc | 00 01 34 01 | import [table 0] Import { module: "", name: "4", ty: Table(TableType { element_type: funcref, initial: 1, maximum: None }) } | 70 00 01 - 0x1be | 00 0a | custom section - 0x1c0 | 04 6e 61 6d | name: "name" + 0x1c3 | 00 0a | custom section + 0x1c5 | 04 6e 61 6d | name: "name" | 65 - 0x1c5 | 00 03 | module name - 0x1c7 | 02 6d 32 | "m2" - 0x1ca | 02 0a | core instance section - 0x1cc | 02 | 2 count - 0x1cd | 00 02 00 | [core instance 0] Instantiate { module_index: 2, args: [] } - 0x1d0 | 00 03 01 00 | [core instance 1] Instantiate { module_index: 3, args: [InstantiationArg { name: "", kind: Instance, index: 0 }] } + 0x1ca | 00 03 | module name + 0x1cc | 02 6d 32 | "m2" + 0x1cf | 02 0a | core instance section + 0x1d1 | 02 | 2 count + 0x1d2 | 00 02 00 | [core instance 0] Instantiate { module_index: 2, args: [] } + 0x1d5 | 00 03 01 00 | [core instance 1] Instantiate { module_index: 3, args: [InstantiationArg { name: "", kind: Instance, index: 0 }] } | 12 00 - 0x1d6 | 06 19 | component alias section - 0x1d8 | 04 | 4 count - 0x1d9 | 00 00 01 00 | alias [core func 0] CoreInstanceExport { kind: Func, instance_index: 0, name: "1" } + 0x1db | 06 19 | component alias section + 0x1dd | 04 | 4 count + 0x1de | 00 00 01 00 | alias [core func 0] CoreInstanceExport { kind: Func, instance_index: 0, name: "1" } | 01 31 - 0x1df | 00 02 01 00 | alias [core memory 0] CoreInstanceExport { kind: Memory, instance_index: 0, name: "2" } + 0x1e4 | 00 02 01 00 | alias [core memory 0] CoreInstanceExport { kind: Memory, instance_index: 0, name: "2" } | 01 32 - 0x1e5 | 00 03 01 00 | alias [core global 0] CoreInstanceExport { kind: Global, instance_index: 0, name: "3" } + 0x1ea | 00 03 01 00 | alias [core global 0] CoreInstanceExport { kind: Global, instance_index: 0, name: "3" } | 01 33 - 0x1eb | 00 01 01 00 | alias [core table 0] CoreInstanceExport { kind: Table, instance_index: 0, name: "4" } + 0x1f0 | 00 01 01 00 | alias [core table 0] CoreInstanceExport { kind: Table, instance_index: 0, name: "4" } | 01 34 - 0x1f1 | 02 19 | core instance section - 0x1f3 | 02 | 2 count - 0x1f4 | 01 04 01 31 | [core instance 2] FromExports([Export { name: "1", kind: Func, index: 0 }, Export { name: "2", kind: Memory, index: 0 }, Export { name: "3", kind: Global, index: 0 }, Export { name: "4", kind: Table, index: 0 }]) + 0x1f6 | 02 19 | core instance section + 0x1f8 | 02 | 2 count + 0x1f9 | 01 04 01 31 | [core instance 2] FromExports([Export { name: "1", kind: Func, index: 0 }, Export { name: "2", kind: Memory, index: 0 }, Export { name: "3", kind: Global, index: 0 }, Export { name: "4", kind: Table, index: 0 }]) | 00 00 01 32 | 02 00 01 33 | 03 00 01 34 | 01 00 - 0x206 | 00 03 01 00 | [core instance 3] Instantiate { module_index: 3, args: [InstantiationArg { name: "", kind: Instance, index: 2 }] } + 0x20b | 00 03 01 00 | [core instance 3] Instantiate { module_index: 3, args: [InstantiationArg { name: "", kind: Instance, index: 2 }] } | 12 02 - 0x20c | 00 76 | custom section - 0x20e | 0e 63 6f 6d | name: "component-name" + 0x211 | 00 76 | custom section + 0x213 | 0e 63 6f 6d | name: "component-name" | 70 6f 6e 65 | 6e 74 2d 6e | 61 6d 65 - 0x21d | 01 06 00 00 | core func section - 0x221 | 01 | 1 count - 0x222 | 00 01 66 | Naming { index: 0, name: "f" } - 0x225 | 01 06 00 01 | core table section - 0x229 | 01 | 1 count - 0x22a | 00 01 74 | Naming { index: 0, name: "t" } - 0x22d | 01 06 00 02 | core memory section - 0x231 | 01 | 1 count - 0x232 | 00 01 6d | Naming { index: 0, name: "m" } - 0x235 | 01 06 00 03 | core global section - 0x239 | 01 | 1 count - 0x23a | 00 01 67 | Naming { index: 0, name: "g" } - 0x23d | 01 0e 00 11 | core module section - 0x241 | 03 | 3 count - 0x242 | 01 01 6d | Naming { index: 1, name: "m" } - 0x245 | 02 02 6d 31 | Naming { index: 2, name: "m1" } - 0x249 | 03 02 6d 32 | Naming { index: 3, name: "m2" } - 0x24d | 01 06 00 12 | core instance section - 0x251 | 01 | 1 count - 0x252 | 00 01 69 | Naming { index: 0, name: "i" } - 0x255 | 01 05 01 | func section - 0x258 | 01 | 1 count - 0x259 | 01 01 66 | Naming { index: 1, name: "f" } - 0x25c | 01 05 02 | value section - 0x25f | 01 | 1 count - 0x260 | 01 01 76 | Naming { index: 1, name: "v" } - 0x263 | 01 05 03 | type section - 0x266 | 01 | 1 count - 0x267 | 00 01 74 | Naming { index: 0, name: "t" } - 0x26a | 01 0d 04 | component section - 0x26d | 03 | 3 count - 0x26e | 00 01 63 | Naming { index: 0, name: "c" } - 0x271 | 02 02 63 32 | Naming { index: 2, name: "c2" } - 0x275 | 03 02 63 33 | Naming { index: 3, name: "c3" } - 0x279 | 01 09 05 | instance section - 0x27c | 02 | 2 count - 0x27d | 00 01 69 | Naming { index: 0, name: "i" } - 0x280 | 03 02 69 32 | Naming { index: 3, name: "i2" } + 0x222 | 01 06 00 00 | core func section + 0x226 | 01 | 1 count + 0x227 | 00 01 66 | Naming { index: 0, name: "f" } + 0x22a | 01 06 00 01 | core table section + 0x22e | 01 | 1 count + 0x22f | 00 01 74 | Naming { index: 0, name: "t" } + 0x232 | 01 06 00 02 | core memory section + 0x236 | 01 | 1 count + 0x237 | 00 01 6d | Naming { index: 0, name: "m" } + 0x23a | 01 06 00 03 | core global section + 0x23e | 01 | 1 count + 0x23f | 00 01 67 | Naming { index: 0, name: "g" } + 0x242 | 01 0e 00 11 | core module section + 0x246 | 03 | 3 count + 0x247 | 01 01 6d | Naming { index: 1, name: "m" } + 0x24a | 02 02 6d 31 | Naming { index: 2, name: "m1" } + 0x24e | 03 02 6d 32 | Naming { index: 3, name: "m2" } + 0x252 | 01 06 00 12 | core instance section + 0x256 | 01 | 1 count + 0x257 | 00 01 69 | Naming { index: 0, name: "i" } + 0x25a | 01 05 01 | func section + 0x25d | 01 | 1 count + 0x25e | 01 01 66 | Naming { index: 1, name: "f" } + 0x261 | 01 05 02 | value section + 0x264 | 01 | 1 count + 0x265 | 01 01 76 | Naming { index: 1, name: "v" } + 0x268 | 01 05 03 | type section + 0x26b | 01 | 1 count + 0x26c | 00 01 74 | Naming { index: 0, name: "t" } + 0x26f | 01 0d 04 | component section + 0x272 | 03 | 3 count + 0x273 | 00 01 63 | Naming { index: 0, name: "c" } + 0x276 | 02 02 63 32 | Naming { index: 2, name: "c2" } + 0x27a | 03 02 63 33 | Naming { index: 3, name: "c3" } + 0x27e | 01 09 05 | instance section + 0x281 | 02 | 2 count + 0x282 | 00 01 69 | Naming { index: 0, name: "i" } + 0x285 | 03 02 69 32 | Naming { index: 3, name: "i2" } diff --git a/tests/cli/dump/bundled.wat.stdout b/tests/cli/dump/bundled.wat.stdout index 26cee44a26..28636d0280 100644 --- a/tests/cli/dump/bundled.wat.stdout +++ b/tests/cli/dump/bundled.wat.stdout @@ -1,24 +1,24 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 30 | component type section 0xa | 01 | 1 count - 0xb | 42 06 01 70 | [type 0] Instance([Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("len", Primitive(U32))], results: Unnamed(Type(0)) })), Export { name: "read", url: "", ty: Func(1) }, Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("buf", Type(2))], results: Unnamed(Primitive(U32)) })), Export { name: "write", url: "", ty: Func(3) }]) + 0xb | 42 06 01 70 | [type 0] Instance([Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("len", Primitive(U32))], results: Unnamed(Type(0)) })), Export { name: Kebab("read"), ty: Func(1) }, Type(Defined(List(Primitive(U8)))), Type(Func(ComponentFuncType { params: [("buf", Type(2))], results: Unnamed(Primitive(U32)) })), Export { name: Kebab("write"), ty: Func(3) }]) | 7d 01 40 01 | 03 6c 65 6e | 79 00 00 04 - | 04 72 65 61 - | 64 00 01 01 + | 00 04 72 65 + | 61 64 01 01 | 01 70 7d 01 | 40 01 03 62 | 75 66 02 00 - | 79 04 05 77 - | 72 69 74 65 - | 00 01 03 + | 79 04 00 05 + | 77 72 69 74 + | 65 01 03 0x3a | 0a 0e | component import section 0x3c | 01 | 1 count - 0x3d | 09 77 61 73 | [instance 0] ComponentImport { name: "wasi-file", url: "", ty: Instance(0) } - | 69 2d 66 69 - | 6c 65 00 05 + 0x3d | 00 09 77 61 | [instance 0] ComponentImport { name: Kebab("wasi-file"), ty: Instance(0) } + | 73 69 2d 66 + | 69 6c 65 05 | 00 0x4a | 01 44 | [core module 0] inline size 0x4c | 00 61 73 6d | version 1 (Module) @@ -189,8 +189,8 @@ | 01 0x1e0 | 0b 0a | component export section 0x1e2 | 01 | 1 count - 0x1e3 | 04 77 6f 72 | export ComponentExport { name: "work", url: "", kind: Func, index: 1, ty: None } - | 6b 00 01 01 + 0x1e3 | 00 04 77 6f | export ComponentExport { name: Kebab("work"), kind: Func, index: 1, ty: None } + | 72 6b 01 01 | 00 0x1ec | 00 7c | custom section 0x1ee | 0e 63 6f 6d | name: "component-name" diff --git a/tests/cli/dump/component-expand-bundle.wat.stdout b/tests/cli/dump/component-expand-bundle.wat.stdout index 652d028b4a..cce60beb29 100644 --- a/tests/cli/dump/component-expand-bundle.wat.stdout +++ b/tests/cli/dump/component-expand-bundle.wat.stdout @@ -1,5 +1,5 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 01 29 | [core module 0] inline size 0xa | 00 61 73 6d | version 1 (Module) | 01 00 00 00 diff --git a/tests/cli/dump/component-expand-bundle2.wat.stdout b/tests/cli/dump/component-expand-bundle2.wat.stdout index d46e182223..03470f0279 100644 --- a/tests/cli/dump/component-expand-bundle2.wat.stdout +++ b/tests/cli/dump/component-expand-bundle2.wat.stdout @@ -1,14 +1,14 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 04 31 | [component 0] inline size - 0xa | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0xa | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x12 | 01 08 | [core module 0] inline size 0x14 | 00 61 73 6d | version 1 (Module) | 01 00 00 00 0x1c | 0b 08 | component export section 0x1e | 01 | 1 count - 0x1f | 01 65 00 00 | export ComponentExport { name: "e", url: "", kind: Module, index: 0, ty: None } + 0x1f | 00 01 65 00 | export ComponentExport { name: Kebab("e"), kind: Module, index: 0, ty: None } | 11 00 00 0x26 | 00 13 | custom section 0x28 | 0e 63 6f 6d | name: "component-name" @@ -18,16 +18,16 @@ 0x37 | 00 02 | component name 0x39 | 01 63 | "c" 0x3b | 04 35 | [component 1] inline size - 0x3d | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x3d | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x45 | 07 0d | component type section 0x47 | 01 | 1 count - 0x48 | 41 02 00 50 | [type 0] Component([CoreType(Module([])), Import(ComponentImport { name: "i", url: "", ty: Module(0) })]) - | 00 03 01 69 - | 00 00 11 00 + 0x48 | 41 02 00 50 | [type 0] Component([CoreType(Module([])), Import(ComponentImport { name: Kebab("i"), ty: Module(0) })]) + | 00 03 00 01 + | 69 00 11 00 0x54 | 0a 06 | component import section 0x56 | 01 | 1 count - 0x57 | 01 69 00 04 | [component 0] ComponentImport { name: "i", url: "", ty: Component(0) } + 0x57 | 00 01 69 04 | [component 0] ComponentImport { name: Kebab("i"), ty: Component(0) } | 00 0x5c | 00 14 | custom section 0x5e | 0e 63 6f 6d | name: "component-name" @@ -43,24 +43,24 @@ 0x7a | 01 | 1 count 0x7b | 00 11 00 00 | alias [module 0] InstanceExport { kind: Module, instance_index: 0, name: "e" } | 01 65 - 0x81 | 05 0f | component instance section + 0x81 | 05 10 | component instance section 0x83 | 02 | 2 count - 0x84 | 01 01 01 65 | [instance 1] FromExports([ComponentExport { name: "e", url: "", kind: Module, index: 0, ty: None }]) - | 00 11 00 - 0x8b | 00 01 01 01 | [instance 2] Instantiate { component_index: 1, args: [ComponentInstantiationArg { name: "i", kind: Instance, index: 1 }] } + 0x84 | 01 01 00 01 | [instance 1] FromExports([ComponentExport { name: Kebab("e"), kind: Module, index: 0, ty: None }]) + | 65 00 11 00 + 0x8c | 00 01 01 01 | [instance 2] Instantiate { component_index: 1, args: [ComponentInstantiationArg { name: "i", kind: Instance, index: 1 }] } | 69 05 01 - 0x92 | 00 29 | custom section - 0x94 | 0e 63 6f 6d | name: "component-name" + 0x93 | 00 29 | custom section + 0x95 | 0e 63 6f 6d | name: "component-name" | 70 6f 6e 65 | 6e 74 2d 6e | 61 6d 65 - 0xa3 | 01 06 00 11 | core module section - 0xa7 | 01 | 1 count - 0xa8 | 00 01 6d | Naming { index: 0, name: "m" } - 0xab | 01 09 04 | component section - 0xae | 02 | 2 count - 0xaf | 00 01 63 | Naming { index: 0, name: "c" } - 0xb2 | 01 02 63 32 | Naming { index: 1, name: "c2" } - 0xb6 | 01 05 05 | instance section - 0xb9 | 01 | 1 count - 0xba | 00 01 43 | Naming { index: 0, name: "C" } + 0xa4 | 01 06 00 11 | core module section + 0xa8 | 01 | 1 count + 0xa9 | 00 01 6d | Naming { index: 0, name: "m" } + 0xac | 01 09 04 | component section + 0xaf | 02 | 2 count + 0xb0 | 00 01 63 | Naming { index: 0, name: "c" } + 0xb3 | 01 02 63 32 | Naming { index: 1, name: "c2" } + 0xb7 | 01 05 05 | instance section + 0xba | 01 | 1 count + 0xbb | 00 01 43 | Naming { index: 0, name: "C" } diff --git a/tests/cli/dump/component-inline-export-import.wat.stdout b/tests/cli/dump/component-inline-export-import.wat.stdout index 83983bd09e..8ac44f5c23 100644 --- a/tests/cli/dump/component-inline-export-import.wat.stdout +++ b/tests/cli/dump/component-inline-export-import.wat.stdout @@ -1,21 +1,21 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 03 | component type section 0xa | 01 | 1 count 0xb | 41 00 | [type 0] Component([]) 0xd | 0a 05 | component import section 0xf | 01 | 1 count - 0x10 | 00 00 04 00 | [component 0] ComponentImport { name: "", url: "", ty: Component(0) } + 0x10 | 00 00 04 00 | [component 0] ComponentImport { name: Kebab(""), ty: Component(0) } 0x14 | 03 03 | core type section 0x16 | 01 | 1 count 0x17 | 50 00 | [core type 0] Module([]) 0x19 | 0a 07 | component import section 0x1b | 01 | 1 count - 0x1c | 01 61 00 00 | [module 0] ComponentImport { name: "a", url: "", ty: Module(0) } + 0x1c | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) } | 11 00 0x22 | 0b 0d | component export section 0x24 | 02 | 2 count - 0x25 | 00 00 04 00 | export ComponentExport { name: "", url: "", kind: Component, index: 0, ty: None } + 0x25 | 00 00 04 00 | export ComponentExport { name: Kebab(""), kind: Component, index: 0, ty: None } | 00 - 0x2a | 01 61 00 00 | export ComponentExport { name: "a", url: "", kind: Module, index: 0, ty: None } + 0x2a | 00 01 61 00 | export ComponentExport { name: Kebab("a"), kind: Module, index: 0, ty: None } | 11 00 00 diff --git a/tests/cli/dump/component-inline-type.wat.stdout b/tests/cli/dump/component-inline-type.wat.stdout index 6ed828b8e0..d6d55e5de9 100644 --- a/tests/cli/dump/component-inline-type.wat.stdout +++ b/tests/cli/dump/component-inline-type.wat.stdout @@ -1,30 +1,30 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 03 | component type section 0xa | 01 | 1 count 0xb | 41 00 | [type 0] Component([]) 0xd | 0a 06 | component import section 0xf | 01 | 1 count - 0x10 | 01 61 00 04 | [component 0] ComponentImport { name: "a", url: "", ty: Component(0) } + 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: Kebab("a"), ty: Component(0) } | 00 0x15 | 03 03 | core type section 0x17 | 01 | 1 count 0x18 | 50 00 | [core type 0] Module([]) 0x1a | 0a 07 | component import section 0x1c | 01 | 1 count - 0x1d | 01 62 00 00 | [module 0] ComponentImport { name: "b", url: "", ty: Module(0) } + 0x1d | 00 01 62 00 | [module 0] ComponentImport { name: Kebab("b"), ty: Module(0) } | 11 00 0x23 | 07 03 | component type section 0x25 | 01 | 1 count 0x26 | 42 00 | [type 1] Instance([]) 0x28 | 0a 06 | component import section 0x2a | 01 | 1 count - 0x2b | 01 63 00 05 | [instance 0] ComponentImport { name: "c", url: "", ty: Instance(1) } + 0x2b | 00 01 63 05 | [instance 0] ComponentImport { name: Kebab("c"), ty: Instance(1) } | 01 0x30 | 07 05 | component type section 0x32 | 01 | 1 count 0x33 | 40 00 01 00 | [type 2] Func(ComponentFuncType { params: [], results: Named([]) }) 0x37 | 0a 06 | component import section 0x39 | 01 | 1 count - 0x3a | 01 64 00 01 | [func 0] ComponentImport { name: "d", url: "", ty: Func(2) } + 0x3a | 00 01 64 01 | [func 0] ComponentImport { name: Kebab("d"), ty: Func(2) } | 02 diff --git a/tests/cli/dump/component-instance-type.wat.stdout b/tests/cli/dump/component-instance-type.wat.stdout index 26a143f36c..00233fd99e 100644 --- a/tests/cli/dump/component-instance-type.wat.stdout +++ b/tests/cli/dump/component-instance-type.wat.stdout @@ -1,17 +1,17 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 28 | component type section 0xa | 01 | 1 count - 0xb | 42 03 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Type(Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Alias(Outer { kind: Type, count: 1, index: 0 }), Import(ComponentImport { name: "1", url: "", ty: Func(0) }), Export { name: "1", url: "", ty: Func(1) }])), Export { name: "c5", url: "", ty: Component(1) }]) + 0xb | 42 03 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Type(Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Alias(Outer { kind: Type, count: 1, index: 0 }), Import(ComponentImport { name: Kebab("1"), ty: Func(0) }), Export { name: Kebab("1"), ty: Func(1) }])), Export { name: Kebab("c5"), ty: Component(1) }]) | 00 01 00 01 | 41 04 01 40 | 00 01 00 02 | 03 02 01 00 - | 03 01 31 00 - | 01 00 04 01 - | 31 00 01 01 - | 04 02 63 35 - | 00 04 01 + | 03 00 01 31 + | 01 00 04 00 + | 01 31 01 01 + | 04 00 02 63 + | 35 04 01 0x32 | 00 1a | custom section 0x34 | 0e 63 6f 6d | name: "component-name" | 70 6f 6e 65 diff --git a/tests/cli/dump/component-linking.wat.stdout b/tests/cli/dump/component-linking.wat.stdout index 80fb557f62..98b16dc777 100644 --- a/tests/cli/dump/component-linking.wat.stdout +++ b/tests/cli/dump/component-linking.wat.stdout @@ -1,55 +1,55 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 30 | component type section 0xa | 01 | 1 count - 0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: "a", url: "", ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: "b", url: "", ty: Func(0) }, Export { name: "c", url: "", ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: "d", url: "", ty: Instance(1) }, Type(Component([])), Export { name: "e", url: "", ty: Component(2) }]) - | 00 04 01 61 - | 00 00 11 00 + 0xb | 42 09 00 50 | [type 0] Instance([CoreType(Module([])), Export { name: Kebab("a"), ty: Module(0) }, Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab("b"), ty: Func(0) }, Export { name: Kebab("c"), ty: Value(Primitive(String)) }, Type(Instance([])), Export { name: Kebab("d"), ty: Instance(1) }, Type(Component([])), Export { name: Kebab("e"), ty: Component(2) }]) + | 00 04 00 01 + | 61 00 11 00 | 01 40 00 01 - | 00 04 01 62 - | 00 01 00 04 - | 01 63 00 02 + | 00 04 00 01 + | 62 01 00 04 + | 00 01 63 02 | 73 01 42 00 - | 04 01 64 00 + | 04 00 01 64 | 05 01 01 41 - | 00 04 01 65 - | 00 04 02 + | 00 04 00 01 + | 65 04 02 0x3a | 0a 06 | component import section 0x3c | 01 | 1 count - 0x3d | 01 61 00 05 | [instance 0] ComponentImport { name: "a", url: "", ty: Instance(0) } + 0x3d | 00 01 61 05 | [instance 0] ComponentImport { name: Kebab("a"), ty: Instance(0) } | 00 0x42 | 04 59 | [component 0] inline size - 0x44 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x44 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x4c | 03 03 | core type section 0x4e | 01 | 1 count 0x4f | 50 00 | [core type 0] Module([]) 0x51 | 0a 07 | component import section 0x53 | 01 | 1 count - 0x54 | 01 61 00 00 | [module 0] ComponentImport { name: "a", url: "", ty: Module(0) } + 0x54 | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) } | 11 00 0x5a | 07 05 | component type section 0x5c | 01 | 1 count 0x5d | 40 00 01 00 | [type 0] Func(ComponentFuncType { params: [], results: Named([]) }) 0x61 | 0a 0b | component import section 0x63 | 02 | 2 count - 0x64 | 01 62 00 01 | [func 0] ComponentImport { name: "b", url: "", ty: Func(0) } + 0x64 | 00 01 62 01 | [func 0] ComponentImport { name: Kebab("b"), ty: Func(0) } | 00 - 0x69 | 01 63 00 02 | [value 0] ComponentImport { name: "c", url: "", ty: Value(Primitive(String)) } + 0x69 | 00 01 63 02 | [value 0] ComponentImport { name: Kebab("c"), ty: Value(Primitive(String)) } | 73 0x6e | 07 03 | component type section 0x70 | 01 | 1 count 0x71 | 42 00 | [type 1] Instance([]) 0x73 | 0a 06 | component import section 0x75 | 01 | 1 count - 0x76 | 01 64 00 05 | [instance 0] ComponentImport { name: "d", url: "", ty: Instance(1) } + 0x76 | 00 01 64 05 | [instance 0] ComponentImport { name: Kebab("d"), ty: Instance(1) } | 01 0x7b | 07 03 | component type section 0x7d | 01 | 1 count 0x7e | 41 00 | [type 2] Component([]) 0x80 | 0a 06 | component import section 0x82 | 01 | 1 count - 0x83 | 01 65 00 04 | [component 0] ComponentImport { name: "e", url: "", ty: Component(2) } + 0x83 | 00 01 65 04 | [component 0] ComponentImport { name: Kebab("e"), ty: Component(2) } | 02 0x88 | 00 13 | custom section 0x8a | 0e 63 6f 6d | name: "component-name" diff --git a/tests/cli/dump/component-outer-alias.wat.stdout b/tests/cli/dump/component-outer-alias.wat.stdout index 187fe2ea8e..54124dd772 100644 --- a/tests/cli/dump/component-outer-alias.wat.stdout +++ b/tests/cli/dump/component-outer-alias.wat.stdout @@ -1,5 +1,5 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 0e | component type section 0xa | 02 | 2 count 0xb | 73 | [type 0] Defined(Primitive(String)) @@ -7,8 +7,8 @@ | 02 01 00 01 | 40 00 00 00 0x18 | 04 2e | [component 0] inline size - 0x1a | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x1a | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x22 | 06 05 | component alias section 0x24 | 01 | 1 count 0x25 | 03 02 01 00 | alias [type 0] Outer { kind: Type, count: 1, index: 0 } @@ -24,8 +24,8 @@ 0x44 | 01 | 1 count 0x45 | 00 01 74 | Naming { index: 0, name: "t" } 0x48 | 04 32 | [component 1] inline size - 0x4a | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x4a | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x52 | 06 05 | component alias section 0x54 | 01 | 1 count 0x55 | 03 02 01 00 | alias [type 0] Outer { kind: Type, count: 1, index: 0 } @@ -45,8 +45,8 @@ 0x7e | 01 | 1 count 0x7f | 7d | [type 2] Defined(Primitive(U8)) 0x80 | 04 33 | [component 2] inline size - 0x82 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x82 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8a | 06 05 | component alias section 0x8c | 01 | 1 count 0x8d | 03 02 01 02 | alias [type 0] Outer { kind: Type, count: 1, index: 2 } diff --git a/tests/cli/dump/import-modules.wat.stdout b/tests/cli/dump/import-modules.wat.stdout index 3cc12aef81..c0b717b792 100644 --- a/tests/cli/dump/import-modules.wat.stdout +++ b/tests/cli/dump/import-modules.wat.stdout @@ -1,5 +1,5 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 03 0d | core type section 0xa | 01 | 1 count 0xb | 50 02 01 60 | [core type 0] Module([Type(Func(FuncType { params: [], returns: [] })), Import(Import { module: "", name: "f", ty: Func(0) })]) @@ -7,7 +7,7 @@ | 01 66 00 00 0x17 | 0a 07 | component import section 0x19 | 01 | 1 count - 0x1a | 01 61 00 00 | [module 0] ComponentImport { name: "a", url: "", ty: Module(0) } + 0x1a | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) } | 11 00 0x20 | 01 2b | [core module 1] inline size 0x22 | 00 61 73 6d | version 1 (Module) diff --git a/tests/cli/dump/instance-expand.wat.stdout b/tests/cli/dump/instance-expand.wat.stdout index 89c67f8cb3..1efe59db4b 100644 --- a/tests/cli/dump/instance-expand.wat.stdout +++ b/tests/cli/dump/instance-expand.wat.stdout @@ -1,13 +1,13 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 0d | component type section 0xa | 01 | 1 count - 0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: "", url: "", ty: Func(0) }]) + 0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab(""), ty: Func(0) }]) | 00 01 00 04 | 00 00 01 00 0x17 | 0a 06 | component import section 0x19 | 01 | 1 count - 0x1a | 01 61 00 05 | [instance 0] ComponentImport { name: "a", url: "", ty: Instance(0) } + 0x1a | 00 01 61 05 | [instance 0] ComponentImport { name: Kebab("a"), ty: Instance(0) } | 00 0x1f | 00 16 | custom section 0x21 | 0e 63 6f 6d | name: "component-name" diff --git a/tests/cli/dump/instance-type.wat.stdout b/tests/cli/dump/instance-type.wat.stdout index 5451e56004..98c33d3fe7 100644 --- a/tests/cli/dump/instance-type.wat.stdout +++ b/tests/cli/dump/instance-type.wat.stdout @@ -1,10 +1,10 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 17 | component type section 0xa | 02 | 2 count - 0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: "", url: "", ty: Func(0) }]) + 0xb | 42 02 01 40 | [type 0] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab(""), ty: Func(0) }]) | 00 01 00 04 | 00 00 01 00 - 0x17 | 42 02 01 42 | [type 1] Instance([Type(Instance([])), Export { name: "", url: "", ty: Instance(0) }]) + 0x17 | 42 02 01 42 | [type 1] Instance([Type(Instance([])), Export { name: Kebab(""), ty: Instance(0) }]) | 00 04 00 00 | 05 00 diff --git a/tests/cli/dump/instance-type2.wat.stdout b/tests/cli/dump/instance-type2.wat.stdout index 84828cd333..7d77ef7e3b 100644 --- a/tests/cli/dump/instance-type2.wat.stdout +++ b/tests/cli/dump/instance-type2.wat.stdout @@ -1,12 +1,12 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 18 | component type section 0xa | 04 | 4 count 0xb | 42 00 | [type 0] Instance([]) - 0xd | 42 01 04 00 | [type 1] Instance([Export { name: "", url: "", ty: Instance(0) }]) + 0xd | 42 01 04 00 | [type 1] Instance([Export { name: Kebab(""), ty: Instance(0) }]) | 00 05 00 0x14 | 42 00 | [type 2] Instance([]) - 0x16 | 42 02 02 03 | [type 3] Instance([Alias(Outer { kind: Type, count: 1, index: 2 }), Export { name: "", url: "", ty: Instance(0) }]) + 0x16 | 42 02 02 03 | [type 3] Instance([Alias(Outer { kind: Type, count: 1, index: 2 }), Export { name: Kebab(""), ty: Instance(0) }]) | 02 01 02 04 | 00 00 05 00 0x22 | 00 16 | custom section diff --git a/tests/cli/dump/instantiate.wat.stdout b/tests/cli/dump/instantiate.wat.stdout index b203d6f901..aa26fcdc74 100644 --- a/tests/cli/dump/instantiate.wat.stdout +++ b/tests/cli/dump/instantiate.wat.stdout @@ -1,18 +1,18 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 03 | component type section 0xa | 01 | 1 count 0xb | 41 00 | [type 0] Component([]) 0xd | 0a 06 | component import section 0xf | 01 | 1 count - 0x10 | 01 61 00 04 | [component 0] ComponentImport { name: "a", url: "", ty: Component(0) } + 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: Kebab("a"), ty: Component(0) } | 00 0x15 | 07 05 | component type section 0x17 | 01 | 1 count 0x18 | 40 00 01 00 | [type 1] Func(ComponentFuncType { params: [], results: Named([]) }) 0x1c | 0a 06 | component import section 0x1e | 01 | 1 count - 0x1f | 01 66 00 01 | [func 0] ComponentImport { name: "f", url: "", ty: Func(1) } + 0x1f | 00 01 66 01 | [func 0] ComponentImport { name: Kebab("f"), ty: Func(1) } | 01 0x24 | 05 08 | component instance section 0x26 | 01 | 1 count diff --git a/tests/cli/dump/instantiate2.wat.stdout b/tests/cli/dump/instantiate2.wat.stdout index 8d557e3e81..e6ef6544dc 100644 --- a/tests/cli/dump/instantiate2.wat.stdout +++ b/tests/cli/dump/instantiate2.wat.stdout @@ -1,14 +1,14 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 0e | component type section 0xa | 01 | 1 count - 0xb | 41 02 01 40 | [type 0] Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Import(ComponentImport { name: "a", url: "", ty: Func(0) })]) + 0xb | 41 02 01 40 | [type 0] Component([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Import(ComponentImport { name: Kebab("a"), ty: Func(0) })]) | 00 01 00 03 - | 01 61 00 01 + | 00 01 61 01 | 00 0x18 | 0a 06 | component import section 0x1a | 01 | 1 count - 0x1b | 01 61 00 04 | [component 0] ComponentImport { name: "a", url: "", ty: Component(0) } + 0x1b | 00 01 61 04 | [component 0] ComponentImport { name: Kebab("a"), ty: Component(0) } | 00 0x20 | 05 04 | component instance section 0x22 | 01 | 1 count diff --git a/tests/cli/dump/module-types.wat.stdout b/tests/cli/dump/module-types.wat.stdout index 840a8e2638..2fcf6328c9 100644 --- a/tests/cli/dump/module-types.wat.stdout +++ b/tests/cli/dump/module-types.wat.stdout @@ -1,5 +1,5 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 03 23 | core type section 0xa | 01 | 1 count 0xb | 50 05 01 60 | [core type 0] Module([Type(Func(FuncType { params: [], returns: [] })), Import(Import { module: "", name: "f", ty: Func(0) }), Import(Import { module: "", name: "g", ty: Global(GlobalType { content_type: I32, mutable: false }) }), Import(Import { module: "", name: "t", ty: Table(TableType { element_type: funcref, initial: 1, maximum: None }) }), Import(Import { module: "", name: "m", ty: Memory(MemoryType { memory64: false, shared: false, initial: 1, maximum: None }) })]) @@ -13,7 +13,7 @@ | 00 01 0x2d | 0a 07 | component import section 0x2f | 01 | 1 count - 0x30 | 01 61 00 00 | [module 0] ComponentImport { name: "a", url: "", ty: Module(0) } + 0x30 | 00 01 61 00 | [module 0] ComponentImport { name: Kebab("a"), ty: Module(0) } | 11 00 0x36 | 07 03 | component type section 0x38 | 01 | 1 count diff --git a/tests/cli/dump/nested-component.wat.stdout b/tests/cli/dump/nested-component.wat.stdout index 1a944d6480..2607c05809 100644 --- a/tests/cli/dump/nested-component.wat.stdout +++ b/tests/cli/dump/nested-component.wat.stdout @@ -1,30 +1,30 @@ - 0x0 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x0 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x8 | 07 03 | component type section 0xa | 01 | 1 count 0xb | 41 00 | [type 0] Component([]) 0xd | 0a 06 | component import section 0xf | 01 | 1 count - 0x10 | 01 61 00 04 | [component 0] ComponentImport { name: "a", url: "", ty: Component(0) } + 0x10 | 00 01 61 04 | [component 0] ComponentImport { name: Kebab("a"), ty: Component(0) } | 00 0x15 | 04 08 | [component 1] inline size - 0x17 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x17 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x1f | 04 08 | [component 2] inline size - 0x21 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x21 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x29 | 04 08 | [component 3] inline size - 0x2b | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x2b | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x33 | 04 12 | [component 4] inline size - 0x35 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x35 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x3d | 04 08 | [component 0] inline size - 0x3f | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x3f | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x47 | 04 73 | [component 5] inline size - 0x49 | 00 61 73 6d | version 12 (Component) - | 0c 00 01 00 + 0x49 | 00 61 73 6d | version 13 (Component) + | 0d 00 01 00 0x51 | 01 13 | [core module 0] inline size 0x53 | 00 61 73 6d | version 1 (Module) | 01 00 00 00 @@ -39,25 +39,25 @@ | 73 01 00 0x70 | 0a 06 | component import section 0x72 | 01 | 1 count - 0x73 | 01 61 00 01 | [func 0] ComponentImport { name: "a", url: "", ty: Func(0) } + 0x73 | 00 01 61 01 | [func 0] ComponentImport { name: Kebab("a"), ty: Func(0) } | 00 0x78 | 0b 08 | component export section 0x7a | 01 | 1 count - 0x7b | 01 61 00 00 | export ComponentExport { name: "a", url: "", kind: Module, index: 0, ty: None } + 0x7b | 00 01 61 00 | export ComponentExport { name: Kebab("a"), kind: Module, index: 0, ty: None } | 11 00 00 0x82 | 07 0e | component type section 0x84 | 01 | 1 count - 0x85 | 42 02 01 40 | [type 1] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: "a", url: "", ty: Func(0) }]) + 0x85 | 42 02 01 40 | [type 1] Instance([Type(Func(ComponentFuncType { params: [], results: Named([]) })), Export { name: Kebab("a"), ty: Func(0) }]) | 00 01 00 04 - | 01 61 00 01 + | 00 01 61 01 | 00 0x92 | 0a 06 | component import section 0x94 | 01 | 1 count - 0x95 | 01 62 00 05 | [instance 0] ComponentImport { name: "b", url: "", ty: Instance(1) } + 0x95 | 00 01 62 05 | [instance 0] ComponentImport { name: Kebab("b"), ty: Instance(1) } | 01 0x9a | 0b 07 | component export section 0x9c | 01 | 1 count - 0x9d | 01 62 00 05 | export ComponentExport { name: "b", url: "", kind: Instance, index: 0, ty: None } + 0x9d | 00 01 62 05 | export ComponentExport { name: Kebab("b"), kind: Instance, index: 0, ty: None } | 00 00 0xa3 | 00 17 | custom section 0xa5 | 0e 63 6f 6d | name: "component-name" @@ -69,5 +69,5 @@ 0xb9 | 00 01 6d | Naming { index: 0, name: "m" } 0xbc | 0b 07 | component export section 0xbe | 01 | 1 count - 0xbf | 01 61 00 04 | export ComponentExport { name: "a", url: "", kind: Component, index: 3, ty: None } + 0xbf | 00 01 61 04 | export ComponentExport { name: Kebab("a"), kind: Component, index: 3, ty: None } | 03 00 diff --git a/tests/cli/print-core-wasm-wit.wit b/tests/cli/print-core-wasm-wit.wit index c77e1713f9..bad24b4bf7 100644 --- a/tests/cli/print-core-wasm-wit.wit +++ b/tests/cli/print-core-wasm-wit.wit @@ -1,9 +1,11 @@ // RUN: component embed --dummy % | component wit +package foo:foo + interface my-interface { foo: func() } -default world my-world { - import my-interface: self.my-interface +world my-world { + import my-interface } diff --git a/tests/cli/print-core-wasm-wit.wit.stdout b/tests/cli/print-core-wasm-wit.wit.stdout index 9a5a088f8d..e5a97071d8 100644 --- a/tests/cli/print-core-wasm-wit.wit.stdout +++ b/tests/cli/print-core-wasm-wit.wit.stdout @@ -1,3 +1,5 @@ +package root:root + world root { - import my-interface: print-core-wasm-wit.print-core-wasm-wit.my-interface + import foo:foo/my-interface } diff --git a/tests/local/component-model/export.wast b/tests/local/component-model/export.wast index 9e9d50560b..e9d6146b4b 100644 --- a/tests/local/component-model/export.wast +++ b/tests/local/component-model/export.wast @@ -43,25 +43,11 @@ (component (import "a" (func)) - (export "b" "https://example.com" (func 0)) + (export (interface "wasi:http/types@2.0.0") (func 0)) ) -;; Empty URLs are treated as no URL +;; import/exports can overlap on ids (component - (import "a" (func)) - (export "b" "" (func 0)) + (import (interface "wasi:http/types@2.0.0") (func)) + (export (interface "wasi:http/types@2.0.0") (func 0)) ) - -(assert_invalid - (component - (import "a" (func)) - (export "b" "foo" (func 0)) - ) - "relative URL without a base") - -(assert_invalid - (component - (import "a" "https://example.com" (func)) - (import "b" "https://example.com" (func)) - ) - "duplicate import URL `https://example.com/`") diff --git a/tests/local/component-model/import.wast b/tests/local/component-model/import.wast index 069d4bcb67..f5509298a8 100644 --- a/tests/local/component-model/import.wast +++ b/tests/local/component-model/import.wast @@ -72,7 +72,7 @@ "(import \"a\" (func))" "(import \"a\" (func))" ) - "import name `a` conflicts with previous import name `a`") + "import name `a` conflicts with previous name `a`") (assert_malformed (component quote @@ -81,7 +81,7 @@ "(import \"a\" (func))" "))" ) - "import name `a` conflicts with previous import name `a`") + "import name `a` conflicts with previous name `a`") (assert_invalid (component @@ -109,30 +109,80 @@ ) (component - (import "a" "https://example.com" (func)) -) - -;; Empty URLs are treated as no URL -(component - (import "a" "" (func)) + (import (interface "wasi:http/types") (func)) + (import (interface "wasi:http/types@1.0.0") (func)) + (import (interface "wasi:http/types@2.0.0") (func)) + (import (interface "a-b:c-d/e-f@123456.7890.488") (func)) + (import (interface "a:b/c@1.2.3") (func)) + (import (interface "a:b/c@0.0.0") (func)) + (import (interface "a:b/c@0.0.0+abcd") (func)) + (import (interface "a:b/c@0.0.0+abcd-efg") (func)) + (import (interface "a:b/c@0.0.0-abcd+efg") (func)) + (import (interface "a:b/c@0.0.0-abcd.1.2+efg.4.ee.5") (func)) ) (assert_invalid (component - (import "a" "foo" (func)) + (import (interface "wasi:http/types") (func)) + (import (interface "wasi:http/types") (func)) ) - "relative URL without a base") + "conflicts with previous name") (assert_invalid - (component - (import "a" "https://example.com" (func)) - (import "b" "https://example.com" (func)) - ) - "duplicate import URL `https://example.com/`") + (component (import (interface "") (func))) + "failed to find `:` character") +(assert_invalid + (component (import (interface "wasi") (func))) + "failed to find `:` character") +(assert_invalid + (component (import (interface "wasi:") (func))) + "failed to find `/` character") +(assert_invalid + (component (import (interface "wasi:/") (func))) + "not in kebab case") +(assert_invalid + (component (import (interface ":/") (func))) + "not in kebab case") +(assert_invalid + (component (import (interface "wasi/http") (func))) + "failed to find `:` character") +(assert_invalid + (component (import (interface "wasi:http/TyPeS") (func))) + "`TyPeS` is not in kebab case") +(assert_invalid + (component (import (interface "WaSi:http/types") (func))) + "`WaSi` is not in kebab case") +(assert_invalid + (component (import (interface "wasi:HtTp/types") (func))) + "`HtTp` is not in kebab case") +(assert_invalid + (component (import (interface "wasi:http/types@") (func))) + "empty string") +(assert_invalid + (component (import (interface "wasi:http/types@.") (func))) + "unexpected character '.'") +(assert_invalid + (component (import (interface "wasi:http/types@1.") (func))) + "unexpected end of input") +(assert_invalid + (component (import (interface "wasi:http/types@a.2") (func))) + "unexpected character 'a'") +(assert_invalid + (component (import (interface "wasi:http/types@2.b") (func))) + "unexpected character 'b'") +(assert_invalid + (component (import (interface "wasi:http/types@2.0x0") (func))) + "unexpected character 'x'") +(assert_invalid + (component (import (interface "wasi:http/types@2.0.0+") (func))) + "empty identifier segment") +(assert_invalid + (component (import (interface "wasi:http/types@2.0.0-") (func))) + "empty identifier segment") (assert_invalid (component (import "a" (func $a)) (export "a" (func $a)) ) - "export name `a` conflicts with previous import name `a`") + "export name `a` conflicts with previous name `a`") diff --git a/tests/local/component-model/instance-type.wast b/tests/local/component-model/instance-type.wast index 86fc310ede..4446e5ee80 100644 --- a/tests/local/component-model/instance-type.wast +++ b/tests/local/component-model/instance-type.wast @@ -180,7 +180,7 @@ (type (instance (export "a" (func)) (export "a" (func))))) - "export name `a` conflicts with previous export name `a`") + "export name `a` conflicts with previous name `a`") (assert_invalid (component diff --git a/tests/local/component-model/instantiate.wast b/tests/local/component-model/instantiate.wast index de07ba9985..562cda77b0 100644 --- a/tests/local/component-model/instantiate.wast +++ b/tests/local/component-model/instantiate.wast @@ -529,7 +529,7 @@ (export "a" (component $c)) ) ) - "instance export name `a` conflicts with previous export name `a`") + "instance export name `a` conflicts with previous name `a`") (component (import "a" (instance $i)) diff --git a/tests/local/component-model/naming.wast b/tests/local/component-model/naming.wast index 42228f74a2..c3a6c7eabb 100644 --- a/tests/local/component-model/naming.wast +++ b/tests/local/component-model/naming.wast @@ -1,10 +1,7 @@ -(assert_invalid - (component - (func (import "a")) - (component) - (instance (instantiate 0 (with "NotKebab-Case" (func 0)))) - ) - "instantiation argument name `NotKebab-Case` is not in kebab case" +(component + (func (import "a")) + (component) + (instance (instantiate 0 (with "NotKebab-Case" (func 0)))) ) (assert_invalid @@ -12,7 +9,7 @@ (import "f" (func)) (instance (export "1" (func 0))) ) - "instance export name `1` is not in kebab case" + "`1` is not in kebab case" ) (assert_invalid @@ -20,7 +17,7 @@ (instance) (alias export 0 "Xml" (func)) ) - "alias export name `Xml` is not in kebab case" + "instance 0 has no export named `Xml`" ) (assert_invalid @@ -63,40 +60,40 @@ (component (type (func (result "uP" string))) ) - "function result name `uP` is not in kebab case" + "name `uP` is not in kebab case" ) (assert_invalid (component (type (component (export "NevEr" (func)))) ) - "export name `NevEr` is not in kebab case" + "`NevEr` is not in kebab case" ) (assert_invalid (component (type (component (import "GonnA" (func)))) ) - "import name `GonnA` is not in kebab case" + "`GonnA` is not in kebab case" ) (assert_invalid (component (type (instance (export "lET" (func)))) ) - "export name `lET` is not in kebab case" + "`lET` is not in kebab case" ) (assert_invalid (component (instance (export "YoU")) ) - "export name `YoU` is not in kebab case" + "`YoU` is not in kebab case" ) (assert_invalid (component (instance (import "DOWn")) ) - "import name `DOWn` is not in kebab case" + "`DOWn` is not in kebab case" ) diff --git a/tests/local/component-model/resources.wast b/tests/local/component-model/resources.wast index 2d44ac96c7..c6fbca440d 100644 --- a/tests/local/component-model/resources.wast +++ b/tests/local/component-model/resources.wast @@ -900,7 +900,7 @@ (assert_invalid (component (import "[static]" (func))) - "not in kebab case") + "failed to find `.` character") ;; validation of `[constructor]foo` (assert_invalid @@ -932,10 +932,10 @@ ;; validation of `[method]a.b` (assert_invalid (component (import "[method]" (func))) - "not in kebab case") + "failed to find `.` character") (assert_invalid (component (import "[method]a" (func))) - "not in kebab case") + "failed to find `.` character") (assert_invalid (component (import "[method]a." (func))) "not in kebab case") @@ -969,10 +969,10 @@ ;; validation of `[static]a.b` (assert_invalid (component (import "[static]" (func))) - "not in kebab case") + "failed to find `.` character") (assert_invalid (component (import "[static]a" (func))) - "not in kebab case") + "failed to find `.` character") (assert_invalid (component (import "[static]a." (func))) "not in kebab case") @@ -1044,13 +1044,10 @@ ) "resource used in function does not have a name in this context") -;; Test that even unused arguments to instantiation have kebab-case checked -(assert_invalid - (component - (component $C) - (instance (instantiate $C (with "this is not kebab case" (component $C)))) - ) - "is not in kebab case") +(component + (component $C) + (instance (instantiate $C (with "this is not kebab case" (component $C)))) +) ;; Test that unused arguments to instantiation are not validated to have ;; appropriate types with respect to kebab naming conventions which require diff --git a/tests/local/component-model/start.wast b/tests/local/component-model/start.wast index 7e596fa4fb..31a86e1c78 100644 --- a/tests/local/component-model/start.wast +++ b/tests/local/component-model/start.wast @@ -74,7 +74,7 @@ (assert_invalid (component binary - "\00asm" "\0c\00\01\00" ;; component header + "\00asm" "\0d\00\01\00" ;; component header "\07\05" ;; type section, 5 bytes large "\01" ;; 1 count @@ -82,10 +82,9 @@ "\00" ;; parameters, 0 count "\01\00" ;; results, named, 0 count - "\0a\06" ;; import section, 5 bytes large + "\0a\06" ;; import section, 6 bytes large "\01" ;; 1 count - "\01a" ;; name = "a" - "\00" ;; url = "" + "\00\01a" ;; name = "a" "\01\00" ;; type = func ($type 0) "\09\06" ;; start section, 6 bytes large @@ -97,7 +96,7 @@ (assert_invalid (component binary - "\00asm" "\0c\00\01\00" ;; component header + "\00asm" "\0d\00\01\00" ;; component header "\07\05" ;; type section, 5 bytes large "\01" ;; 1 count @@ -105,10 +104,9 @@ "\00" ;; parameters, 0 count "\01\00" ;; results, named, 0 count - "\0a\06" ;; import section, 5 bytes large + "\0a\06" ;; import section, 6 bytes large "\01" ;; 1 count - "\01a" ;; name = "a" - "\00" ;; url = "" + "\00\01a" ;; name = "a" "\01\00" ;; type = func ($type 0) "\09\04" ;; start section, 4 bytes large diff --git a/tests/local/component-model/types.wast b/tests/local/component-model/types.wast index 76096d0cd4..742f257bad 100644 --- a/tests/local/component-model/types.wast +++ b/tests/local/component-model/types.wast @@ -107,7 +107,7 @@ (export "A" (func)) )) ) - "export name `A` conflicts with previous export name `a`") + "export name `A` conflicts with previous name `a`") (assert_invalid (component @@ -116,7 +116,7 @@ (import "a" (func)) )) ) - "import name `a` conflicts with previous import name `A`") + "import name `a` conflicts with previous name `A`") (assert_invalid (component $c @@ -195,7 +195,7 @@ (export "FOO-bar-BAZ" (func)) )) ) - "export name `FOO-bar-BAZ` conflicts with previous export name `foo-BAR-baz`") + "export name `FOO-bar-BAZ` conflicts with previous name `foo-BAR-baz`") (assert_invalid (component $c diff --git a/tests/local/component-model/very-nested.wast b/tests/local/component-model/very-nested.wast index 6705cf360c..8e82efe31c 100644 --- a/tests/local/component-model/very-nested.wast +++ b/tests/local/component-model/very-nested.wast @@ -1562,7 +1562,7 @@ (component) ) ) - "conflicts with previous export name") + "conflicts with previous name") (assert_invalid (component diff --git a/tests/snapshots/local/component-model/export.wast/7.print b/tests/snapshots/local/component-model/export.wast/7.print index e2870b4caf..19402892e6 100644 --- a/tests/snapshots/local/component-model/export.wast/7.print +++ b/tests/snapshots/local/component-model/export.wast/7.print @@ -1,5 +1,5 @@ (component (type (;0;) (func)) (import "a" (func (;0;) (type 0))) - (export (;1;) "b" "https://example.com" (func 0)) + (export (;1;) (interface "wasi:http/types@2.0.0") (func 0)) ) \ No newline at end of file diff --git a/tests/snapshots/local/component-model/export.wast/8.print b/tests/snapshots/local/component-model/export.wast/8.print index 3a48808767..ce88c858a7 100644 --- a/tests/snapshots/local/component-model/export.wast/8.print +++ b/tests/snapshots/local/component-model/export.wast/8.print @@ -1,5 +1,5 @@ (component (type (;0;) (func)) - (import "a" (func (;0;) (type 0))) - (export (;1;) "b" (func 0)) + (import (interface "wasi:http/types@2.0.0") (func (;0;) (type 0))) + (export (;1;) (interface "wasi:http/types@2.0.0") (func 0)) ) \ No newline at end of file diff --git a/tests/snapshots/local/component-model/import.wast/14.print b/tests/snapshots/local/component-model/import.wast/14.print index 4846c17dde..95fa2297b2 100644 --- a/tests/snapshots/local/component-model/import.wast/14.print +++ b/tests/snapshots/local/component-model/import.wast/14.print @@ -1,4 +1,22 @@ (component (type (;0;) (func)) - (import "a" "https://example.com" (func (;0;) (type 0))) + (import (interface "wasi:http/types") (func (;0;) (type 0))) + (type (;1;) (func)) + (import (interface "wasi:http/types@1.0.0") (func (;1;) (type 1))) + (type (;2;) (func)) + (import (interface "wasi:http/types@2.0.0") (func (;2;) (type 2))) + (type (;3;) (func)) + (import (interface "a-b:c-d/e-f@123456.7890.488") (func (;3;) (type 3))) + (type (;4;) (func)) + (import (interface "a:b/c@1.2.3") (func (;4;) (type 4))) + (type (;5;) (func)) + (import (interface "a:b/c@0.0.0") (func (;5;) (type 5))) + (type (;6;) (func)) + (import (interface "a:b/c@0.0.0+abcd") (func (;6;) (type 6))) + (type (;7;) (func)) + (import (interface "a:b/c@0.0.0+abcd-efg") (func (;7;) (type 7))) + (type (;8;) (func)) + (import (interface "a:b/c@0.0.0-abcd+efg") (func (;8;) (type 8))) + (type (;9;) (func)) + (import (interface "a:b/c@0.0.0-abcd.1.2+efg.4.ee.5") (func (;9;) (type 9))) ) \ No newline at end of file diff --git a/tests/snapshots/local/component-model/import.wast/15.print b/tests/snapshots/local/component-model/import.wast/15.print deleted file mode 100644 index 29a69bebb8..0000000000 --- a/tests/snapshots/local/component-model/import.wast/15.print +++ /dev/null @@ -1,4 +0,0 @@ -(component - (type (;0;) (func)) - (import "a" (func (;0;) (type 0))) -) \ No newline at end of file diff --git a/tests/snapshots/local/component-model/naming.wast/0.print b/tests/snapshots/local/component-model/naming.wast/0.print new file mode 100644 index 0000000000..29425ffb83 --- /dev/null +++ b/tests/snapshots/local/component-model/naming.wast/0.print @@ -0,0 +1,9 @@ +(component + (type (;0;) (func)) + (import "a" (func (;0;) (type 0))) + (component (;0;)) + (instance (;0;) (instantiate 0 + (with "NotKebab-Case" (func 0)) + ) + ) +) \ No newline at end of file diff --git a/tests/snapshots/local/component-model/resources.wast/105.print b/tests/snapshots/local/component-model/resources.wast/105.print new file mode 100644 index 0000000000..3277a8a234 --- /dev/null +++ b/tests/snapshots/local/component-model/resources.wast/105.print @@ -0,0 +1,7 @@ +(component + (component $C (;0;)) + (instance (;0;) (instantiate $C + (with "this is not kebab case" (component $C)) + ) + ) +) \ No newline at end of file