components: Fix bindgen! with renamed interfaces (#5968)
This follows the same strategy pioneered by the `wit-bindgen` guest Rust bindgen which keeps track of the latest name of an interface for how to refer to an interface. Closes #5961
This commit is contained in:
14
crates/component-macro/tests/codegen/rename.wit
Normal file
14
crates/component-macro/tests/codegen/rename.wit
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
interface red {
|
||||||
|
use self.green.{thing}
|
||||||
|
|
||||||
|
foo: func() -> thing
|
||||||
|
}
|
||||||
|
|
||||||
|
interface green {
|
||||||
|
type thing = s32
|
||||||
|
}
|
||||||
|
|
||||||
|
default world neptune {
|
||||||
|
import blue: self.red
|
||||||
|
import orange: self.green
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::rust::{to_rust_ident, to_rust_upper_camel_case, RustGenerator, TypeMode};
|
use crate::rust::{to_rust_ident, to_rust_upper_camel_case, RustGenerator, TypeMode};
|
||||||
use crate::types::{TypeInfo, Types};
|
use crate::types::{TypeInfo, Types};
|
||||||
use heck::*;
|
use heck::*;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::{BTreeMap, HashMap};
|
||||||
use std::fmt::Write as _;
|
use std::fmt::Write as _;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@@ -33,6 +33,7 @@ struct Wasmtime {
|
|||||||
exports: Exports,
|
exports: Exports,
|
||||||
types: Types,
|
types: Types,
|
||||||
sizes: SizeAlign,
|
sizes: SizeAlign,
|
||||||
|
interface_names: HashMap<InterfaceId, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Import {
|
enum Import {
|
||||||
@@ -113,6 +114,7 @@ impl Wasmtime {
|
|||||||
Import::Function { sig, add_to_linker }
|
Import::Function { sig, add_to_linker }
|
||||||
}
|
}
|
||||||
WorldItem::Interface(id) => {
|
WorldItem::Interface(id) => {
|
||||||
|
gen.gen.interface_names.insert(*id, snake.clone());
|
||||||
gen.current_interface = Some(*id);
|
gen.current_interface = Some(*id);
|
||||||
gen.types(*id);
|
gen.types(*id);
|
||||||
gen.generate_trappable_error_types(TypeOwner::Interface(*id));
|
gen.generate_trappable_error_types(TypeOwner::Interface(*id));
|
||||||
@@ -159,6 +161,7 @@ impl Wasmtime {
|
|||||||
}
|
}
|
||||||
WorldItem::Type(_) => unreachable!(),
|
WorldItem::Type(_) => unreachable!(),
|
||||||
WorldItem::Interface(id) => {
|
WorldItem::Interface(id) => {
|
||||||
|
gen.gen.interface_names.insert(*id, snake.clone());
|
||||||
gen.current_interface = Some(*id);
|
gen.current_interface = Some(*id);
|
||||||
gen.types(*id);
|
gen.types(*id);
|
||||||
gen.generate_trappable_error_types(TypeOwner::Interface(*id));
|
gen.generate_trappable_error_types(TypeOwner::Interface(*id));
|
||||||
@@ -1382,8 +1385,18 @@ impl<'a> RustGenerator<'a> for InterfaceGenerator<'a> {
|
|||||||
self.resolve
|
self.resolve
|
||||||
}
|
}
|
||||||
|
|
||||||
fn current_interface(&self) -> Option<InterfaceId> {
|
fn path_to_interface(&self, interface: InterfaceId) -> Option<String> {
|
||||||
self.current_interface
|
match self.current_interface {
|
||||||
|
Some(id) if id == interface => None,
|
||||||
|
_ => {
|
||||||
|
let name = &self.gen.interface_names[&interface];
|
||||||
|
Some(if self.current_interface.is_some() {
|
||||||
|
format!("super::{name}")
|
||||||
|
} else {
|
||||||
|
name.clone()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_str(&mut self, s: &str) {
|
fn push_str(&mut self, s: &str) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ pub trait RustGenerator<'a> {
|
|||||||
|
|
||||||
fn push_str(&mut self, s: &str);
|
fn push_str(&mut self, s: &str);
|
||||||
fn info(&self, ty: TypeId) -> TypeInfo;
|
fn info(&self, ty: TypeId) -> TypeInfo;
|
||||||
fn current_interface(&self) -> Option<InterfaceId>;
|
fn path_to_interface(&self, interface: InterfaceId) -> Option<String>;
|
||||||
|
|
||||||
fn print_ty(&mut self, ty: &Type, mode: TypeMode) {
|
fn print_ty(&mut self, ty: &Type, mode: TypeMode) {
|
||||||
match ty {
|
match ty {
|
||||||
@@ -64,20 +64,10 @@ pub trait RustGenerator<'a> {
|
|||||||
self.result_name(id)
|
self.result_name(id)
|
||||||
};
|
};
|
||||||
if let TypeOwner::Interface(id) = ty.owner {
|
if let TypeOwner::Interface(id) = ty.owner {
|
||||||
if let Some(name) = &self.resolve().interfaces[id].name {
|
if let Some(path) = self.path_to_interface(id) {
|
||||||
match self.current_interface() {
|
self.push_str(&path);
|
||||||
Some(cur) if cur == id => {}
|
|
||||||
Some(_other) => {
|
|
||||||
self.push_str("super::");
|
|
||||||
self.push_str(&name.to_snake_case());
|
|
||||||
self.push_str("::");
|
self.push_str("::");
|
||||||
}
|
}
|
||||||
None => {
|
|
||||||
self.push_str(&name.to_snake_case());
|
|
||||||
self.push_str("::");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.push_str(&name);
|
self.push_str(&name);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user