Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(go-namespaces): Split generated Go files into multiple packages #784

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions crates/c/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use heck::*;
use std::collections::{HashMap, HashSet};
use std::fmt::Write;
use std::mem;
use std::path::PathBuf;
use wit_bindgen_core::abi::{self, AbiVariant, Bindgen, Bitcast, Instruction, LiftLower, WasmType};
use wit_bindgen_core::{
dealias, uwrite, uwriteln, wit_parser::*, Direction, Files, InterfaceGenerator as _, Ns,
Expand Down Expand Up @@ -52,6 +53,9 @@ pub struct Opts {
// Skip generating C object file
#[cfg_attr(feature = "clap", arg(long, default_value_t = false))]
pub no_object_file: bool,
/// output directory
#[cfg_attr(feature = "clap", arg(long, hide = true))]
pub c_out_dir: Option<String>,
}

impl Opts {
Expand Down Expand Up @@ -375,11 +379,16 @@ impl WorldGenerator for C {
#endif"
);

files.push(&format!("{snake}.h"), h_str.as_bytes());
files.push(&format!("{snake}.c"), c_str.as_bytes());
let dst = match &self.opts.c_out_dir {
Some(path) => path,
None => "",
};

files.push(&format!("{dst}{snake}.h"), h_str.as_bytes());
files.push(&format!("{dst}{snake}.c"), c_str.as_bytes());
if !self.opts.no_object_file {
files.push(
&format!("{snake}_component_type.o",),
&format!("{dst}{snake}_component_type.o",),
component_type_object::object(resolve, id, self.opts.string_encoding)
.unwrap()
.as_slice(),
Expand Down
76 changes: 55 additions & 21 deletions crates/go/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use wit_bindgen_core::wit_parser::{
Field, Function, FunctionKind, Handle, InterfaceId, LiveTypes, Resolve, Type, TypeDefKind,
TypeId, TypeOwner, WorldKey,
};
use wit_bindgen_core::{uwriteln, Direction, InterfaceGenerator as _, Source};
use wit_bindgen_core::{uwriteln, Direction, InterfaceGenerator as _, Source, WorldGenerator};

use crate::path::GoPath;

use super::{avoid_keyword, bindgen, TinyGo};

Expand Down Expand Up @@ -61,7 +63,7 @@ impl InterfaceGenerator<'_> {
assert!(prev.is_none());

// add Go types to the list
let mut name = self.owner_namespace(ty);
let mut name = "".to_string();
name.push_str(&self.ty_name(&Type::Id(ty)));

let prev = self.gen.type_names.insert(ty, name.clone());
Expand Down Expand Up @@ -101,7 +103,7 @@ impl InterfaceGenerator<'_> {
c_owner_namespace(
self.interface,
matches!(self.direction, Direction::Import),
self.gen.world.clone(),
self.gen.world.name().to_string(),
self.resolve,
id,
)
Expand All @@ -127,18 +129,18 @@ impl InterfaceGenerator<'_> {
WorldKey::Name(k) => k.to_upper_camel_case(),
WorldKey::Interface(id) => {
let mut name = String::new();
if matches!(self.direction, Direction::Export) {
name.push_str("Exports");
}
// if matches!(self.direction, Direction::Export) {
// name.push_str("Exports");
// }
let iface = &self.resolve.interfaces[*id];
let pkg = &self.resolve.packages[iface.package.unwrap()];
name.push_str(&pkg.name.namespace.to_upper_camel_case());
name.push_str(&pkg.name.name.to_upper_camel_case());
if let Some(version) = &pkg.name.version {
let version = version.to_string().replace(['.', '-', '+'], "_");
name.push_str(&version);
name.push('_');
}
// let pkg = &self.resolve.packages[iface.package.unwrap()];
// name.push_str(&pkg.name.namespace.to_upper_camel_case());
// name.push_str(&pkg.name.name.to_upper_camel_case());
// if let Some(version) = &pkg.name.version {
// let version = version.to_string().replace(['.', '-', '+'], "_");
// name.push_str(&version);
// name.push('_');
// }
name.push_str(&iface.name.as_ref().unwrap().to_upper_camel_case());
name
}
Expand Down Expand Up @@ -171,13 +173,13 @@ impl InterfaceGenerator<'_> {
/// Otherwise, the type name is not converted.
pub(crate) fn type_name(&self, ty_name: &str, convert: bool) -> String {
let mut name = String::new();
let namespace = self.namespace();
// let namespace = self.namespace();
let ty_name = if convert {
ty_name.to_upper_camel_case()
} else {
ty_name.into()
};
name.push_str(&namespace);
// name.push_str(&namespace);
name.push_str(&ty_name);
name
}
Expand Down Expand Up @@ -530,13 +532,13 @@ impl InterfaceGenerator<'_> {
c_func_name(
matches!(direction, Direction::Import),
self.resolve,
&self.gen.world,
self.gen.world.name(),
self.interface.map(|(_, key)| key),
func,
)
} else {
// do not want to generate public functions
format!("{}{}", self.namespace(), self.func_name(func)).to_lower_camel_case()
self.func_name(func).to_lower_camel_case()
};

if matches!(direction, Direction::Export) {
Expand Down Expand Up @@ -577,8 +579,8 @@ impl InterfaceGenerator<'_> {

match func.kind {
FunctionKind::Freestanding => {
let namespace = self.namespace();
self.src.push_str(&namespace);
// let namespace = self.namespace();
// self.src.push_str(&namespace);
}
FunctionKind::Method(ty) => {
let ty = self.get_ty(&Type::Id(ty));
Expand Down Expand Up @@ -820,7 +822,7 @@ impl InterfaceGenerator<'_> {
let name = c_func_name(
matches!(self.direction, Direction::Import),
self.resolve,
&self.gen.world,
self.gen.world.name(),
self.interface.map(|(_, key)| key),
func,
);
Expand Down Expand Up @@ -990,6 +992,37 @@ impl InterfaceGenerator<'_> {
}
self.src.push_str("}\n");
}

pub(crate) fn start_append_submodule(&mut self, name: &WorldKey) -> (String, Vec<String>) {
let snake = match name {
WorldKey::Name(name) => avoid_keyword(name),
WorldKey::Interface(id) => {
avoid_keyword(self.resolve.interfaces[*id].name.as_ref().unwrap())
}
};
let module_path: Vec<String> = name.to_path(&self.resolve, self.direction);
(snake, module_path)
}

pub(crate) fn finish_append_submodule(mut self, snake: &str, module_path: Vec<String>) {
self.finish();
let _ = match self.direction {
Direction::Import => self.gen.go_import_packages.push(
snake,
self.src,
self.preamble,
&self.gen.world,
module_path,
),
Direction::Export => self.gen.go_export_packages.push(
snake,
self.src,
self.preamble,
&self.gen.world,
module_path,
),
};
}
}

impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
Expand Down Expand Up @@ -1227,6 +1260,7 @@ impl<'a> wit_bindgen_core::InterfaceGenerator<'a> for InterfaceGenerator<'a> {
) {
let name = self.type_name(name, true);
let ty = self.get_ty(ty);
// TODO: determine where `ty` is from and add import path to preamble
self.src.push_str(&format!("type {name} = {ty}\n"));
}

Expand Down
Loading
Loading