Skip to content

Commit

Permalink
make source trait generic on language backend
Browse files Browse the repository at this point in the history
  • Loading branch information
fredszaq committed Jun 30, 2023
1 parent 48416dc commit 96cea22
Show file tree
Hide file tree
Showing 18 changed files with 1,716 additions and 1,052 deletions.
41 changes: 26 additions & 15 deletions src/bindgen/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ use std::rc::Rc;

use crate::bindgen::config::{Config, Language};
use crate::bindgen::ir::{
Constant, Function, ItemContainer, ItemMap, Path as BindgenPath, Static, Struct, Typedef,
Constant, Documentation, Enum, Function, ItemContainer, ItemMap, Literal, OpaqueItem,
Path as BindgenPath, Static, Struct, Type, Typedef, Union,
};
use crate::bindgen::language_backend::{
CLikeLanguageBackend, CythonLanguageBackend, LanguageBackend, NamespaceOperation,
Expand Down Expand Up @@ -74,8 +75,6 @@ impl Bindings {

/// Peels through typedefs to allow resolving structs.
fn resolved_struct_path<'a>(&self, path: &'a BindgenPath) -> Cow<'a, BindgenPath> {
use crate::bindgen::ir::Type;

let mut resolved_path = Cow::Borrowed(path);
loop {
let mut found = None;
Expand Down Expand Up @@ -204,15 +203,27 @@ impl Bindings {
pub fn write<F: Write>(&self, file: F) {
match self.config.language {
Language::Cxx | Language::C => {
self.write_with_backend(file, CLikeLanguageBackend::new(self.config.clone()))
self.write_with_backend(file, &CLikeLanguageBackend::new(self.config.clone()))
}
Language::Cython => {
self.write_with_backend(file, CythonLanguageBackend::new(self.config.clone()))
self.write_with_backend(file, &CythonLanguageBackend::new(self.config.clone()))
}
}
}

pub fn write_with_backend<F: Write, LB: LanguageBackend>(&self, file: F, language_backend: LB) {
pub fn write_with_backend<F: Write, LB: LanguageBackend>(&self, file: F, language_backend: &LB)
where
Enum: Source<LB>,
Struct: Source<LB>,
Union: Source<LB>,
OpaqueItem: Source<LB>,
Typedef: Source<LB>,
Static: Source<LB>,
Function: Source<LB>,
Type: Source<LB>,
Documentation: Source<LB>,
Literal: Source<LB>,
{
if self.noop {
return;
}
Expand All @@ -228,7 +239,7 @@ impl Bindings {
for constant in &self.constants {
if constant.uses_only_primitive_types() {
out.new_line_if_not_start();
constant.write(&self.config, &mut out, None);
constant.write(&self.config, language_backend, &mut out, None);
out.new_line();
}
}
Expand All @@ -247,19 +258,19 @@ impl Bindings {
match *item {
ItemContainer::Constant(..) => unreachable!(),
ItemContainer::Static(..) => unreachable!(),
ItemContainer::Enum(ref x) => x.write(&self.config, &mut out),
ItemContainer::Struct(ref x) => x.write(&self.config, &mut out),
ItemContainer::Union(ref x) => x.write(&self.config, &mut out),
ItemContainer::OpaqueItem(ref x) => x.write(&self.config, &mut out),
ItemContainer::Typedef(ref x) => x.write(&self.config, &mut out),
ItemContainer::Enum(ref x) => x.write(language_backend, &mut out),
ItemContainer::Struct(ref x) => x.write(language_backend, &mut out),
ItemContainer::Union(ref x) => x.write(language_backend, &mut out),
ItemContainer::OpaqueItem(ref x) => x.write(language_backend, &mut out),
ItemContainer::Typedef(ref x) => x.write(language_backend, &mut out),
}
out.new_line();
}

for constant in &self.constants {
if !constant.uses_only_primitive_types() {
out.new_line_if_not_start();
constant.write(&self.config, &mut out, None);
constant.write(&self.config, language_backend, &mut out, None);
out.new_line();
}
}
Expand Down Expand Up @@ -293,13 +304,13 @@ impl Bindings {

for global in &self.globals {
out.new_line_if_not_start();
global.write(&self.config, &mut out);
global.write(language_backend, &mut out);
out.new_line();
}

for function in &self.functions {
out.new_line_if_not_start();
function.write(&self.config, &mut out);
function.write(language_backend, &mut out);
out.new_line();
}

Expand Down
77 changes: 57 additions & 20 deletions src/bindgen/cdecl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use std::io::Write;
use crate::bindgen::config::Layout;
use crate::bindgen::declarationtyperesolver::DeclarationType;
use crate::bindgen::ir::{ConstExpr, Function, GenericArgument, Type};
use crate::bindgen::writer::{ListType, SourceWriter};
use crate::bindgen::language_backend::LanguageBackend;
use crate::bindgen::writer::{ListType, Source, SourceWriter};
use crate::bindgen::{Config, Language};

// This code is for translating Rust types into C declarations.
Expand Down Expand Up @@ -188,7 +189,15 @@ impl CDecl {
}
}

fn write<F: Write>(&self, out: &mut SourceWriter<F>, ident: Option<&str>, config: &Config) {
fn write<F: Write, LB: LanguageBackend>(
&self,
language_backend: &LB,
out: &mut SourceWriter<F>,
ident: Option<&str>,
config: &Config,
) where
GenericArgument: Source<LB>,
{
// Write the type-specifier and type-qualifier first
if !self.type_qualifers.is_empty() {
write!(out, "{} ", self.type_qualifers);
Expand All @@ -204,7 +213,11 @@ impl CDecl {

if !self.type_generic_args.is_empty() {
out.write("<");
out.write_horizontal_source_list(&self.type_generic_args, ListType::Join(", "));
out.write_horizontal_source_list(
language_backend,
&self.type_generic_args,
ListType::Join(", "),
);
out.write(">");
}

Expand Down Expand Up @@ -286,11 +299,14 @@ impl CDecl {
out.write("void");
}

fn write_vertical<F: Write>(
fn write_vertical<F: Write, LB: LanguageBackend>(
language_backend: &LB,
out: &mut SourceWriter<F>,
config: &Config,
args: &[(Option<String>, CDecl)],
) {
) where
GenericArgument: Source<LB>,
{
let align_length = out.line_length_for_align();
out.push_set_spaces(align_length);
for (i, (arg_ident, arg_ty)) in args.iter().enumerate() {
Expand All @@ -302,16 +318,19 @@ impl CDecl {
// Convert &Option<String> to Option<&str>
let arg_ident = arg_ident.as_ref().map(|x| x.as_ref());

arg_ty.write(out, arg_ident, config);
arg_ty.write(language_backend, out, arg_ident, config);
}
out.pop_tab();
}

fn write_horizontal<F: Write>(
fn write_horizontal<F: Write, LB: LanguageBackend>(
language_backend: &LB,
out: &mut SourceWriter<F>,
config: &Config,
args: &[(Option<String>, CDecl)],
) {
) where
GenericArgument: Source<LB>,
{
for (i, (arg_ident, arg_ty)) in args.iter().enumerate() {
if i != 0 {
out.write(", ");
Expand All @@ -320,19 +339,19 @@ impl CDecl {
// Convert &Option<String> to Option<&str>
let arg_ident = arg_ident.as_ref().map(|x| x.as_ref());

arg_ty.write(out, arg_ident, config);
arg_ty.write(language_backend, out, arg_ident, config);
}
}

match layout {
Layout::Vertical => write_vertical(out, config, args),
Layout::Horizontal => write_horizontal(out, config, args),
Layout::Vertical => write_vertical(language_backend, out, config, args),
Layout::Horizontal => write_horizontal(language_backend, out, config, args),
Layout::Auto => {
if !out.try_write(
|out| write_horizontal(out, config, args),
|out| write_horizontal(language_backend, out, config, args),
config.line_length,
) {
write_vertical(out, config, args)
write_vertical(language_backend, out, config, args)
}
}
}
Expand All @@ -351,19 +370,37 @@ impl CDecl {
}
}

pub fn write_func<F: Write>(
pub fn write_func<F: Write, LB: LanguageBackend>(
language_backend: &LB,
out: &mut SourceWriter<F>,
f: &Function,
layout: Layout,
config: &Config,
) {
CDecl::from_func(f, layout, config).write(out, Some(f.path().name()), config);
) where
GenericArgument: Source<LB>,
{
CDecl::from_func(f, layout, config).write(language_backend, out, Some(f.path().name()), config);
}

pub fn write_field<F: Write>(out: &mut SourceWriter<F>, t: &Type, ident: &str, config: &Config) {
CDecl::from_type(t, config).write(out, Some(ident), config);
pub fn write_field<F: Write, LB: LanguageBackend>(
language_backend: &LB,
out: &mut SourceWriter<F>,
t: &Type,
ident: &str,
config: &Config,
) where
GenericArgument: Source<LB>,
{
CDecl::from_type(t, config).write(language_backend, out, Some(ident), config);
}

pub fn write_type<F: Write>(out: &mut SourceWriter<F>, t: &Type, config: &Config) {
CDecl::from_type(t, config).write(out, None, config);
pub fn write_type<F: Write, LB: LanguageBackend>(
language_backend: &LB,
out: &mut SourceWriter<F>,
t: &Type,
config: &Config,
) where
GenericArgument: Source<LB>,
{
CDecl::from_type(t, config).write(language_backend, out, None, config);
}

0 comments on commit 96cea22

Please sign in to comment.