diff --git a/testdata/issues/issue306.wit b/testdata/issues/issue306.wit index d52e2b80..6a0213fe 100644 --- a/testdata/issues/issue306.wit +++ b/testdata/issues/issue306.wit @@ -1,4 +1,3 @@ -// https://github.com/bytecodealliance/go-modules/issues/306 package issues:issue306@0.1.0; world w { diff --git a/testdata/issues/issue306.wit.json b/testdata/issues/issue306.wit.json index b0b42f62..4128efbb 100644 --- a/testdata/issues/issue306.wit.json +++ b/testdata/issues/issue306.wit.json @@ -78,9 +78,6 @@ }, { "name": "issues:issue306@0.1.0", - "docs": { - "contents": "https://github.com/bytecodealliance/go-modules/issues/306" - }, "interfaces": {}, "worlds": { "w": 1 diff --git a/testdata/issues/issue306.wit.json.golden.wit b/testdata/issues/issue306.wit.json.golden.wit index cdef08fb..c5674bf9 100644 --- a/testdata/issues/issue306.wit.json.golden.wit +++ b/testdata/issues/issue306.wit.json.golden.wit @@ -1,11 +1,9 @@ package issues:dep1@0.2.1; world w { - @since(version = 0.2.0) import issues:dep2/gated-interface; } -/// https://github.com/bytecodealliance/go-modules/issues/306 package issues:issue306@0.1.0 { world w { import issues:dep2/gated-interface; diff --git a/testdata/issues/issue325-processed.wit b/testdata/issues/issue325-processed.wit new file mode 100644 index 00000000..b23a59f6 --- /dev/null +++ b/testdata/issues/issue325-processed.wit @@ -0,0 +1,34 @@ +package issues:issue325; + +world w { + @unstable(feature = active) + import issues:dep2/i@0.2.0; + @unstable(feature = active) + use issues:dep2/i@0.2.0.{r}; +} + +package issues:dep1@0.1.0 { + world w { + import issues:dep2/i@0.2.0; + } +} + +package issues:unstable@0.1.0 { + world w { + @unstable(feature = active) + import issues:dep2/i@0.2.0; + @unstable(feature = active) + use issues:dep2/i@0.2.0.{r}; + } +} + +package issues:dep2@0.2.0 { + interface i { + resource r; + } + + world w { + @since(version = 0.2.0) + import i; + } +} diff --git a/testdata/issues/issue325-processed.wit.json b/testdata/issues/issue325-processed.wit.json new file mode 100644 index 00000000..4a41e59b --- /dev/null +++ b/testdata/issues/issue325-processed.wit.json @@ -0,0 +1,152 @@ +{ + "worlds": [ + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0, + "stability": { + "stable": { + "since": "0.2.0" + } + } + } + } + }, + "exports": {}, + "package": 0 + }, + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0 + } + } + }, + "exports": {}, + "package": 1 + }, + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "r": { + "type": 1 + } + }, + "exports": {}, + "package": 2 + }, + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "r": { + "type": 2 + } + }, + "exports": {}, + "package": 3 + } + ], + "interfaces": [ + { + "name": "i", + "types": { + "r": 0 + }, + "functions": {}, + "package": 0 + } + ], + "types": [ + { + "name": "r", + "kind": "resource", + "owner": { + "interface": 0 + } + }, + { + "name": "r", + "kind": { + "type": 0 + }, + "owner": { + "world": 2 + }, + "stability": { + "unstable": { + "feature": "active" + } + } + }, + { + "name": "r", + "kind": { + "type": 0 + }, + "owner": { + "world": 3 + }, + "stability": { + "unstable": { + "feature": "active" + } + } + } + ], + "packages": [ + { + "name": "issues:dep2@0.2.0", + "interfaces": { + "i": 0 + }, + "worlds": { + "w": 0 + } + }, + { + "name": "issues:dep1@0.1.0", + "interfaces": {}, + "worlds": { + "w": 1 + } + }, + { + "name": "issues:issue325", + "interfaces": {}, + "worlds": { + "w": 2 + } + }, + { + "name": "issues:unstable@0.1.0", + "interfaces": {}, + "worlds": { + "w": 3 + } + } + ] +} \ No newline at end of file diff --git a/testdata/issues/issue325-processed.wit.json.golden.wit b/testdata/issues/issue325-processed.wit.json.golden.wit new file mode 100644 index 00000000..b23a59f6 --- /dev/null +++ b/testdata/issues/issue325-processed.wit.json.golden.wit @@ -0,0 +1,34 @@ +package issues:issue325; + +world w { + @unstable(feature = active) + import issues:dep2/i@0.2.0; + @unstable(feature = active) + use issues:dep2/i@0.2.0.{r}; +} + +package issues:dep1@0.1.0 { + world w { + import issues:dep2/i@0.2.0; + } +} + +package issues:unstable@0.1.0 { + world w { + @unstable(feature = active) + import issues:dep2/i@0.2.0; + @unstable(feature = active) + use issues:dep2/i@0.2.0.{r}; + } +} + +package issues:dep2@0.2.0 { + interface i { + resource r; + } + + world w { + @since(version = 0.2.0) + import i; + } +} diff --git a/testdata/issues/issue325.wit b/testdata/issues/issue325.wit new file mode 100644 index 00000000..e6d24673 --- /dev/null +++ b/testdata/issues/issue325.wit @@ -0,0 +1,31 @@ +package issues:issue325; + +world w { + @unstable(feature = active) + include issues:dep1/w@0.1.0; + include issues:unstable/w@0.1.0; +} + +package issues:unstable@0.1.0 { + world w { + @unstable(feature = active) + use issues:dep2/i@0.2.0.{r}; + } +} + +package issues:dep1@0.1.0 { + world w { + include issues:dep2/w@0.2.0; + } +} + +package issues:dep2@0.2.0 { + world w { + @since(version = 0.2.0) + import i; + } + + interface i { + resource r; + } +} diff --git a/testdata/issues/issue325.wit.json b/testdata/issues/issue325.wit.json new file mode 100644 index 00000000..d45fbafe --- /dev/null +++ b/testdata/issues/issue325.wit.json @@ -0,0 +1,143 @@ +{ + "worlds": [ + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0, + "stability": { + "stable": { + "since": "0.2.0" + } + } + } + } + }, + "exports": {}, + "package": 0 + }, + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0, + "stability": { + "stable": { + "since": "0.2.0" + } + } + } + } + }, + "exports": {}, + "package": 1 + }, + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "r": { + "type": 1 + } + }, + "exports": {}, + "package": 2 + }, + { + "name": "w", + "imports": { + "interface-0": { + "interface": { + "id": 0, + "stability": { + "stable": { + "since": "0.2.0" + } + } + } + }, + "r": { + "type": 1 + } + }, + "exports": {}, + "package": 3 + } + ], + "interfaces": [ + { + "name": "i", + "types": { + "r": 0 + }, + "functions": {}, + "package": 0 + } + ], + "types": [ + { + "name": "r", + "kind": "resource", + "owner": { + "interface": 0 + } + }, + { + "name": "r", + "kind": { + "type": 0 + }, + "owner": { + "world": 2 + }, + "stability": { + "unstable": { + "feature": "active" + } + } + } + ], + "packages": [ + { + "name": "issues:dep2@0.2.0", + "interfaces": { + "i": 0 + }, + "worlds": { + "w": 0 + } + }, + { + "name": "issues:dep1@0.1.0", + "interfaces": {}, + "worlds": { + "w": 1 + } + }, + { + "name": "issues:unstable@0.1.0", + "interfaces": {}, + "worlds": { + "w": 2 + } + }, + { + "name": "issues:issue325", + "interfaces": {}, + "worlds": { + "w": 3 + } + } + ] +} \ No newline at end of file diff --git a/testdata/issues/issue325.wit.json.golden.wit b/testdata/issues/issue325.wit.json.golden.wit new file mode 100644 index 00000000..6bb4b1bd --- /dev/null +++ b/testdata/issues/issue325.wit.json.golden.wit @@ -0,0 +1,33 @@ +package issues:issue325; + +world w { + import issues:dep2/i@0.2.0; + @unstable(feature = active) + use issues:dep2/i@0.2.0.{r}; +} + +package issues:dep1@0.1.0 { + world w { + import issues:dep2/i@0.2.0; + } +} + +package issues:unstable@0.1.0 { + world w { + @unstable(feature = active) + import issues:dep2/i@0.2.0; + @unstable(feature = active) + use issues:dep2/i@0.2.0.{r}; + } +} + +package issues:dep2@0.2.0 { + interface i { + resource r; + } + + world w { + @since(version = 0.2.0) + import i; + } +} diff --git a/testdata/wit-parser/error-context.wit.json b/testdata/wit-parser/error-context.wit.json index 555a2543..617e37d1 100644 --- a/testdata/wit-parser/error-context.wit.json +++ b/testdata/wit-parser/error-context.wit.json @@ -13,14 +13,14 @@ "params": [ { "name": "x", - "type": 1 + "type": "error-context" }, { "name": "y", "type": 0 } ], - "result": 2 + "result": 1 } }, "package": 0 @@ -29,22 +29,19 @@ "types": [ { "name": "t1", - "kind": "error-context", + "kind": { + "type": "error-context" + }, "owner": { "interface": 0 } }, - { - "name": null, - "kind": "error-context", - "owner": null - }, { "name": null, "kind": { "result": { "ok": null, - "err": 1 + "err": "error-context" } }, "owner": null diff --git a/testdata/wit-parser/gated-include-use-with-stable.wit b/testdata/wit-parser/gated-include-use-with-stable.wit new file mode 100644 index 00000000..159ffb39 --- /dev/null +++ b/testdata/wit-parser/gated-include-use-with-stable.wit @@ -0,0 +1,75 @@ +package wasmtime:test; + +world test{ + @unstable(feature = active) + include wasi:unstable/imports@0.2.3; + include wasi:foo/imports@0.2.3; +} + +world test-ordered{ + include wasi:foo/imports@0.2.3; + @unstable(feature = active) + include wasi:unstable/imports@0.2.3; +} + +package wasi:unstable@0.2.3 { + @unstable(feature = active) + world imports { + @unstable(feature = active) + use wasi:dep2/stable@0.2.3.{stable-resource}; + @unstable(feature = active) + use wasi:dep-unversioned/unversioned.{unversioned-resource}; + @unstable(feature = active) + use wasi:dep-unstable/unstable.{unstable-resource}; + } +} + +package wasi:foo@0.2.3 { + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + include wasi:dep2/imports@0.2.3; + include wasi:dep-unversioned/imports; + include wasi:dep-unstable/imports; + } +} + +package wasi:dep2@0.2.3 { + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import stable; + } + @since(version = 0.2.1) + interface stable { + resource stable-resource { + } + } +} + +package wasi:dep-unversioned{ + world imports { + import unversioned; + } + interface unversioned { + resource unversioned-resource { + + } + } +} + +package wasi:dep-unstable{ + @unstable(feature = active) + world imports { + @unstable(feature = active) + import unstable; + } + @unstable(feature = active) + interface unstable { + @unstable(feature = active) + resource unstable-resource { + + } + } +} + diff --git a/testdata/wit-parser/gated-include-use-with-stable.wit.json b/testdata/wit-parser/gated-include-use-with-stable.wit.json new file mode 100644 index 00000000..471d6b4c --- /dev/null +++ b/testdata/wit-parser/gated-include-use-with-stable.wit.json @@ -0,0 +1,397 @@ +{ + "worlds": [ + { + "name": "imports", + "imports": { + "interface-0": { + "interface": { + "id": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + } + } + }, + "exports": {}, + "package": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + }, + { + "name": "imports", + "imports": { + "interface-1": { + "interface": { + "id": 1 + } + } + }, + "exports": {}, + "package": 1 + }, + { + "name": "imports", + "imports": { + "interface-2": { + "interface": { + "id": 2, + "stability": { + "stable": { + "since": "0.2.0" + } + } + } + } + }, + "exports": {}, + "package": 2, + "stability": { + "stable": { + "since": "0.2.0" + } + } + }, + { + "name": "imports", + "imports": { + "interface-2": { + "interface": { + "id": 2, + "stability": { + "stable": { + "since": "0.2.0" + } + } + } + }, + "interface-1": { + "interface": { + "id": 1 + } + }, + "interface-0": { + "interface": { + "id": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + } + } + }, + "exports": {}, + "package": 3, + "stability": { + "stable": { + "since": "0.2.0" + } + } + }, + { + "name": "imports", + "imports": { + "interface-2": { + "interface": { + "id": 2, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "stable-resource": { + "type": 3 + }, + "interface-1": { + "interface": { + "id": 1, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "unversioned-resource": { + "type": 4 + }, + "interface-0": { + "interface": { + "id": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "unstable-resource": { + "type": 5 + } + }, + "exports": {}, + "package": 4, + "stability": { + "unstable": { + "feature": "active" + } + } + }, + { + "name": "test", + "imports": { + "interface-2": { + "interface": { + "id": 2, + "stability": { + "stable": { + "since": "0.2.0" + } + } + } + }, + "stable-resource": { + "type": 3 + }, + "interface-1": { + "interface": { + "id": 1, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "unversioned-resource": { + "type": 4 + }, + "interface-0": { + "interface": { + "id": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "unstable-resource": { + "type": 5 + } + }, + "exports": {}, + "package": 5 + }, + { + "name": "test-ordered", + "imports": { + "interface-2": { + "interface": { + "id": 2, + "stability": { + "stable": { + "since": "0.2.0" + } + } + } + }, + "interface-1": { + "interface": { + "id": 1, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "interface-0": { + "interface": { + "id": 0, + "stability": { + "unstable": { + "feature": "active" + } + } + } + }, + "stable-resource": { + "type": 3 + }, + "unversioned-resource": { + "type": 4 + }, + "unstable-resource": { + "type": 5 + } + }, + "exports": {}, + "package": 5 + } + ], + "interfaces": [ + { + "name": "unstable", + "types": { + "unstable-resource": 0 + }, + "functions": {}, + "stability": { + "unstable": { + "feature": "active" + } + }, + "package": 0 + }, + { + "name": "unversioned", + "types": { + "unversioned-resource": 1 + }, + "functions": {}, + "package": 1 + }, + { + "name": "stable", + "types": { + "stable-resource": 2 + }, + "functions": {}, + "stability": { + "stable": { + "since": "0.2.1" + } + }, + "package": 2 + } + ], + "types": [ + { + "name": "unstable-resource", + "kind": "resource", + "owner": { + "interface": 0 + }, + "stability": { + "unstable": { + "feature": "active" + } + } + }, + { + "name": "unversioned-resource", + "kind": "resource", + "owner": { + "interface": 1 + } + }, + { + "name": "stable-resource", + "kind": "resource", + "owner": { + "interface": 2 + } + }, + { + "name": "stable-resource", + "kind": { + "type": 2 + }, + "owner": { + "world": 4 + }, + "stability": { + "unstable": { + "feature": "active" + } + } + }, + { + "name": "unversioned-resource", + "kind": { + "type": 1 + }, + "owner": { + "world": 4 + }, + "stability": { + "unstable": { + "feature": "active" + } + } + }, + { + "name": "unstable-resource", + "kind": { + "type": 0 + }, + "owner": { + "world": 4 + }, + "stability": { + "unstable": { + "feature": "active" + } + } + } + ], + "packages": [ + { + "name": "wasi:dep-unstable", + "interfaces": { + "unstable": 0 + }, + "worlds": { + "imports": 0 + } + }, + { + "name": "wasi:dep-unversioned", + "interfaces": { + "unversioned": 1 + }, + "worlds": { + "imports": 1 + } + }, + { + "name": "wasi:dep2@0.2.3", + "interfaces": { + "stable": 2 + }, + "worlds": { + "imports": 2 + } + }, + { + "name": "wasi:foo@0.2.3", + "interfaces": {}, + "worlds": { + "imports": 3 + } + }, + { + "name": "wasi:unstable@0.2.3", + "interfaces": {}, + "worlds": { + "imports": 4 + } + }, + { + "name": "wasmtime:test", + "interfaces": {}, + "worlds": { + "test": 5, + "test-ordered": 6 + } + } + ] +} \ No newline at end of file diff --git a/testdata/wit-parser/gated-include-use-with-stable.wit.json.golden.wit b/testdata/wit-parser/gated-include-use-with-stable.wit.json.golden.wit new file mode 100644 index 00000000..1e515fb0 --- /dev/null +++ b/testdata/wit-parser/gated-include-use-with-stable.wit.json.golden.wit @@ -0,0 +1,94 @@ +package wasmtime:test; + +world test { + import wasi:dep2/stable@0.2.3; + @unstable(feature = active) + use wasi:dep2/stable@0.2.3.{stable-resource}; + @unstable(feature = active) + import wasi:dep-unversioned/unversioned; + @unstable(feature = active) + use wasi:dep-unversioned/unversioned.{unversioned-resource}; + @unstable(feature = active) + import wasi:dep-unstable/unstable; + @unstable(feature = active) + use wasi:dep-unstable/unstable.{unstable-resource}; +} + +world test-ordered { + import wasi:dep2/stable@0.2.3; + @unstable(feature = active) + import wasi:dep-unversioned/unversioned; + @unstable(feature = active) + import wasi:dep-unstable/unstable; + @unstable(feature = active) + use wasi:dep2/stable@0.2.3.{stable-resource}; + @unstable(feature = active) + use wasi:dep-unversioned/unversioned.{unversioned-resource}; + @unstable(feature = active) + use wasi:dep-unstable/unstable.{unstable-resource}; +} + +package wasi:foo@0.2.3 { + @since(version = 0.2.0) + world imports { + import wasi:dep2/stable@0.2.3; + import wasi:dep-unversioned/unversioned; + @unstable(feature = active) + import wasi:dep-unstable/unstable; + } +} + +package wasi:unstable@0.2.3 { + @unstable(feature = active) + world imports { + @unstable(feature = active) + import wasi:dep2/stable@0.2.3; + @unstable(feature = active) + use wasi:dep2/stable@0.2.3.{stable-resource}; + @unstable(feature = active) + import wasi:dep-unversioned/unversioned; + @unstable(feature = active) + use wasi:dep-unversioned/unversioned.{unversioned-resource}; + @unstable(feature = active) + import wasi:dep-unstable/unstable; + @unstable(feature = active) + use wasi:dep-unstable/unstable.{unstable-resource}; + } +} + +package wasi:dep-unstable { + @unstable(feature = active) + interface unstable { + @unstable(feature = active) + resource unstable-resource; + } + + @unstable(feature = active) + world imports { + @unstable(feature = active) + import unstable; + } +} + +package wasi:dep-unversioned { + interface unversioned { + resource unversioned-resource; + } + + world imports { + import unversioned; + } +} + +package wasi:dep2@0.2.3 { + @since(version = 0.2.1) + interface stable { + resource stable-resource; + } + + @since(version = 0.2.0) + world imports { + @since(version = 0.2.0) + import stable; + } +} diff --git a/testdata/wit-parser/gated-use.wit.json.golden.wit b/testdata/wit-parser/gated-use.wit.json.golden.wit index 49345d35..c7b0e91e 100644 --- a/testdata/wit-parser/gated-use.wit.json.golden.wit +++ b/testdata/wit-parser/gated-use.wit.json.golden.wit @@ -1,7 +1,7 @@ -package wasi:dep2@0.2.3; +package wasmtime:test; -interface stable {} +interface types {} -package wasmtime:test { - interface types {} +package wasi:dep2@0.2.3 { + interface stable {} } diff --git a/testdata/wit-parser/packages-nested-with-semver.wit.json.golden.wit b/testdata/wit-parser/packages-nested-with-semver.wit.json.golden.wit index 2f649238..491da28d 100644 --- a/testdata/wit-parser/packages-nested-with-semver.wit.json.golden.wit +++ b/testdata/wit-parser/packages-nested-with-semver.wit.json.golden.wit @@ -1,13 +1,15 @@ -package foo:name@1.0.0; +package foo:root; -interface i1 { - type a = u32; -} +package foo:name@1.0.0 { + interface i1 { + type a = u32; + } -world w1 { - import i1; - import imp1: interface { - use i1.{a}; + world w1 { + import i1; + import imp1: interface { + use i1.{a}; + } } } @@ -23,5 +25,3 @@ package foo:name@1.0.1 { } } } - -package foo:root {} diff --git a/testdata/wit-parser/version-syntax.wit.json.golden.wit b/testdata/wit-parser/version-syntax.wit.json.golden.wit index c6acac8c..13220696 100644 --- a/testdata/wit-parser/version-syntax.wit.json.golden.wit +++ b/testdata/wit-parser/version-syntax.wit.json.golden.wit @@ -1,4 +1,6 @@ -package a:b@1.0.0; +package foo:root; + +package a:b@1.0.0 {} package a:b@1.0.0-11-a {} @@ -15,5 +17,3 @@ package a:b@1.0.1-1+1 {} package a:b@1.0.1-1a+1a {} package a:b@1.0.1-a+a {} - -package foo:root {} diff --git a/wit/bindgen/generator.go b/wit/bindgen/generator.go index d9794922..a499bcd1 100644 --- a/wit/bindgen/generator.go +++ b/wit/bindgen/generator.go @@ -176,16 +176,6 @@ func newGenerator(res *wit.Resolve, opts ...Option) (*generator, error) { return g, nil } -// TODO: factor this out -func findWorld(r *wit.Resolve, pattern string) *wit.World { - for _, w := range r.Worlds { - if w.Match(pattern) { - return w - } - } - return nil -} - func (g *generator) generate() ([]*gen.Package, error) { g.detectVersionedPackages() err := g.defineWorlds() @@ -237,6 +227,11 @@ func (g *generator) define(dir wit.Direction, v wit.Node) (defined bool) { func (g *generator) defineWorlds() error { g.opts.logger.Infof("Generating Go for %d world(s)\n", len(g.res.Worlds)) for _, w := range g.res.Worlds { + // Define a Go package for every world, regardless of use + _, err := g.defineGoPackage(w, nil, "") + if err != nil { + return err + } if w == g.world || g.world == nil { err := g.defineWorld(w) if err != nil { @@ -256,7 +251,7 @@ func (g *generator) defineWorld(w *wit.World) error { g.moduleNames[w] = id.String() - pkg, err := g.newPackage(w, nil, "") + pkg, err := g.defineGoPackage(w, nil, "") if err != nil { return err } @@ -326,7 +321,7 @@ func (g *generator) defineInterface(w *wit.World, dir wit.Direction, i *wit.Inte g.moduleNames[i] = id.String() } - pkg, err := g.newPackage(w, i, name) + pkg, err := g.defineGoPackage(w, i, name) if err != nil { return err } @@ -2245,20 +2240,20 @@ func (g *generator) abiFile(pkg *gen.Package) *gen.File { } func (g *generator) fileFor(owner wit.TypeOwner) *gen.File { - pkg := g.packageFor(owner) + pkg := g.goPackageFor(owner) file := pkg.File(path.Base(pkg.Path) + ".wit.go") file.GeneratedBy = g.opts.generatedBy return file } func (g *generator) witFileFor(owner wit.TypeOwner) *gen.File { - pkg := g.packageFor(owner) + pkg := g.goPackageFor(owner) file := pkg.File(path.Base(pkg.Path) + ".wit") return file } func (g *generator) exportsFileFor(owner wit.TypeOwner) *gen.File { - pkg := g.packageFor(owner) + pkg := g.goPackageFor(owner) file := pkg.File(path.Base(pkg.Path) + ".exports.go") file.GeneratedBy = g.opts.generatedBy if len(file.Header) == 0 { @@ -2273,7 +2268,7 @@ func (g *generator) exportsFileFor(owner wit.TypeOwner) *gen.File { } func (g *generator) wasmFileFor(owner wit.TypeOwner) *gen.File { - pkg := g.packageFor(owner) + pkg := g.goPackageFor(owner) file := pkg.File(path.Base(pkg.Path) + ".wasm.go") file.GeneratedBy = g.opts.generatedBy if len(file.Header) == 0 { @@ -2283,7 +2278,7 @@ func (g *generator) wasmFileFor(owner wit.TypeOwner) *gen.File { } func (g *generator) cgoFileFor(owner wit.TypeOwner) *gen.File { - pkg := g.packageFor(owner) + pkg := g.goPackageFor(owner) file := pkg.File(path.Base(pkg.Path) + ".cgo.go") file.GeneratedBy = g.opts.generatedBy if file.GoBuild == "" { @@ -2292,11 +2287,16 @@ func (g *generator) cgoFileFor(owner wit.TypeOwner) *gen.File { return file } -func (g *generator) packageFor(owner wit.TypeOwner) *gen.Package { - return g.witPackages[owner] +func (g *generator) goPackageFor(owner wit.TypeOwner) *gen.Package { + pkg := g.witPackages[owner] + if pkg == nil { + panic(fmt.Sprintf("BUG: nil package for wit.TypeOwner %s (%T: %p)", + owner.WITPackage().Name.String(), owner, owner)) + } + return pkg } -func (g *generator) newPackage(w *wit.World, i *wit.Interface, name string) (*gen.Package, error) { +func (g *generator) defineGoPackage(w *wit.World, i *wit.Interface, name string) (*gen.Package, error) { var owner wit.TypeOwner var id wit.Ident diff --git a/wit/package.go b/wit/package.go index 6c088182..2e39a02b 100644 --- a/wit/package.go +++ b/wit/package.go @@ -59,6 +59,10 @@ func comparePackages(a, b *Package) int { case DependsOn(b, a): // fmt.Fprintln(os.Stderr, b.Name.String()+" depends on "+a.Name.String()) return -1 + case a.Name.Version == nil && b.Name.Version != nil: + return 1 + case a.Name.Version != nil && a.Name.Version == nil: + return -1 } // fmt.Fprintln(os.Stderr, a.Name.String()+" does not depend on "+b.Name.String()) return -1 * strings.Compare(a.Name.String(), b.Name.String()) diff --git a/wit/stability.go b/wit/stability.go index 583282f0..1406d9eb 100644 --- a/wit/stability.go +++ b/wit/stability.go @@ -8,6 +8,7 @@ import ( type Stability interface { Node isStability() + Versioned() bool } // _stability is an embeddable type that conforms to the [Stability] interface. @@ -24,9 +25,19 @@ type Stable struct { Deprecated *semver.Version } +// Versioned always returns true for [Stable]. +func (*Stable) Versioned() bool { + return true +} + // Unstable represents an unstable WIT feature defined by name. type Unstable struct { _stability Feature string Deprecated *semver.Version } + +// Versioned returns whether [Unstable] is deprecated. +func (u *Unstable) Versioned() bool { + return u.Deprecated != nil +} diff --git a/wit/wit.go b/wit/wit.go index c0b49914..c1f8b70f 100644 --- a/wit/wit.go +++ b/wit/wit.go @@ -175,9 +175,9 @@ func (s *Stable) WIT(ctx Node, _ string) string { case *World: w = ctx } - if w != nil && w.Package.Name.Version != nil { + if w != nil { pv := w.Package.Name.Version - if pv.LessThan(s.Since) { + if pv == nil || pv.LessThan(s.Since) { return "" } } @@ -333,6 +333,18 @@ func (ref *InterfaceRef) WIT(ctx Node, name string) string { if ref.Stability == nil { return ref.Interface.WIT(ctx, name) } + var w *World + switch ctx := ctx.(type) { + case worldImport: + w = ctx.World + case worldExport: + w = ctx.World + case *World: + w = ctx + } + if ref.Stability.Versioned() && w != nil && w.Package != ref.Interface.Package { + return ref.Interface.WIT(ctx, name) + } return newline(ref.Stability.WIT(ctx, "")) + ref.Interface.WIT(ctx, name) }