Skip to content

Commit 7e2ebd3

Browse files
committed
Add support for named implements in Go
Signed-off-by: Jeremy Fleitz <jeremy@cosmonic.com>
1 parent 93a5f4e commit 7e2ebd3

2 files changed

Lines changed: 39 additions & 17 deletions

File tree

crates/go/src/lib.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,8 @@ struct Go {
221221
interface_names: HashMap<InterfaceId, WorldKey>,
222222
interfaces: BTreeMap<String, InterfaceData>,
223223
export_interfaces: BTreeMap<String, InterfaceData>,
224-
types: HashSet<TypeId>,
224+
// Add String to the types to allow for implements of the same type in different interfaces to be generated.
225+
types: HashSet<(String, TypeId)>,
225226
resources: HashMap<TypeId, Direction>,
226227
futures_and_streams: HashMap<(TypeId, bool), Option<WorldKey>>,
227228
}
@@ -742,11 +743,11 @@ impl WorldGenerator for Go {
742743
self.interface_names.insert(id, name.clone());
743744
}
744745

746+
let package = self.interface_name(resolve, Some(name));
745747
let mut data = {
746748
let mut generator = InterfaceGenerator::new(self, resolve, Some((id, name)), true);
747749
for (name, ty) in resolve.interfaces[id].types.iter() {
748-
if !generator.generator.types.contains(ty) {
749-
generator.generator.types.insert(*ty);
750+
if generator.generator.types.insert((package.clone(), *ty)) {
750751
generator.define_type(name, *ty);
751752
}
752753
}
@@ -756,10 +757,7 @@ impl WorldGenerator for Go {
756757
for (_, func) in &resolve.interfaces[id].functions {
757758
data.extend(self.import(resolve, func, Some(name)));
758759
}
759-
self.interfaces
760-
.entry(self.interface_name(resolve, Some(name)))
761-
.or_default()
762-
.extend(data);
760+
self.interfaces.entry(package).or_default().extend(data);
763761

764762
Ok(())
765763
}
@@ -792,26 +790,25 @@ impl WorldGenerator for Go {
792790
self.interface_names.insert(id, name.clone());
793791
}
794792

793+
let package = self.interface_name(resolve, Some(name));
795794
for (type_name, ty) in &resolve.interfaces[id].types {
796795
let exported = matches!(resolve.types[*ty].kind, TypeDefKind::Resource)
797796
|| self.has_exported_resource(resolve, Type::Id(*ty));
798797

799798
let mut generator = InterfaceGenerator::new(self, resolve, Some((id, name)), false);
800799

801-
if exported || !generator.generator.types.contains(ty) {
802-
generator.generator.types.insert(*ty);
800+
if generator.generator.types.insert((package.clone(), *ty)) || exported {
803801
generator.define_type(type_name, *ty);
804802
}
805803

806804
let data = generator.into();
807805

808-
let name = self.interface_name(resolve, Some(name));
809806
if exported {
810807
&mut self.export_interfaces
811808
} else {
812809
&mut self.interfaces
813810
}
814-
.entry(name)
811+
.entry(package.clone())
815812
.or_default()
816813
.extend(data);
817814
}
@@ -845,18 +842,15 @@ impl WorldGenerator for Go {
845842
types: &[(&str, TypeId)],
846843
_files: &mut Files,
847844
) {
845+
let package = self.interface_name(resolve, None);
848846
let mut generator = InterfaceGenerator::new(self, resolve, None, true);
849847
for (name, ty) in types {
850-
if !generator.generator.types.contains(ty) {
851-
generator.generator.types.insert(*ty);
848+
if generator.generator.types.insert((package.clone(), *ty)) {
852849
generator.define_type(name, *ty);
853850
}
854851
}
855852
let data = generator.into();
856-
self.interfaces
857-
.entry(self.interface_name(resolve, None))
858-
.or_default()
859-
.extend(data);
853+
self.interfaces.entry(package).or_default().extend(data);
860854
}
861855

862856
fn finish(&mut self, resolve: &Resolve, id: WorldId, files: &mut Files) -> Result<()> {

tests/codegen/issue1642.wit

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package foo:foo;
2+
3+
interface store {
4+
variant error {
5+
no-such-store,
6+
access-denied,
7+
other(string),
8+
}
9+
10+
record key-response {
11+
keys: list<string>,
12+
cursor: option<u64>,
13+
}
14+
15+
resource bucket {
16+
open: static func(identifier: string) -> result<bucket, error>;
17+
get: func(key: string) -> result<option<list<u8>>, error>;
18+
list-keys: func(cursor: option<u64>) -> result<key-response, error>;
19+
}
20+
}
21+
22+
world the-world {
23+
// Import the same type under separate names to test implements.
24+
import primary: store;
25+
import secondary: store;
26+
// Ensure non-named imports still works.
27+
import store;
28+
}

0 commit comments

Comments
 (0)