add csharp_generate_const option

This commit is contained in:
neuecc 2023-08-15 21:18:30 +09:00
parent 511053bb5c
commit 6e5a623352
17 changed files with 830 additions and 728 deletions

View File

@ -30,6 +30,7 @@ pub struct BindgenOptions {
pub csharp_if_dll_name: String, pub csharp_if_dll_name: String,
pub csharp_use_function_pointer: bool, pub csharp_use_function_pointer: bool,
pub csharp_imported_namespaces: Vec<String>, pub csharp_imported_namespaces: Vec<String>,
pub csharp_generate_const: bool,
} }
impl Default for Builder { impl Default for Builder {
@ -53,6 +54,7 @@ impl Default for Builder {
csharp_if_dll_name: "".to_string(), csharp_if_dll_name: "".to_string(),
csharp_use_function_pointer: true, csharp_use_function_pointer: true,
csharp_imported_namespaces: vec![], csharp_imported_namespaces: vec![],
csharp_generate_const: false,
}, },
} }
} }
@ -181,6 +183,12 @@ impl Builder {
self self
} }
/// conifure C# generate const, default is false
pub fn csharp_generate_const(mut self, csharp_generate_const: bool) -> Builder {
self.options.csharp_generate_const = csharp_generate_const;
self
}
pub fn generate_csharp_file<P: AsRef<Path>>( pub fn generate_csharp_file<P: AsRef<Path>>(
&self, &self,
csharp_output_path: P, csharp_output_path: P,

View File

@ -79,6 +79,7 @@ pub fn emit_csharp(
aliases: &AliasMap, aliases: &AliasMap,
structs: &Vec<RustStruct>, structs: &Vec<RustStruct>,
enums: &Vec<RustEnum>, enums: &Vec<RustEnum>,
consts: &Vec<RustConst>,
options: &BindgenOptions, options: &BindgenOptions,
) -> String { ) -> String {
// configure // configure
@ -290,6 +291,27 @@ pub fn emit_csharp(
enum_string.push('\n'); enum_string.push('\n');
} }
let mut const_string = String::new();
for item in consts {
let type_name = item.rust_type.to_csharp_string(
options,
aliases,
false,
&"".to_string(),
&"".to_string(),
);
const_string.push_str(
format!(
" public {} {} = {};",
type_name,
escape_name(item.const_name.as_str()),
item.value
)
.as_str(),
);
}
let mut imported_namespaces = String::new(); let mut imported_namespaces = String::new();
for name in &options.csharp_imported_namespaces { for name in &options.csharp_imported_namespaces {
imported_namespaces.push_str_ln(format!("using {name};").as_str()); imported_namespaces.push_str_ln(format!("using {name};").as_str());
@ -317,6 +339,7 @@ namespace {namespace}
{structs_string} {structs_string}
{enum_string} {enum_string}
{const_string}
}} }}
" "
); );

View File

@ -14,7 +14,7 @@ use emitter::*;
use field_map::FieldMap; use field_map::FieldMap;
use parser::*; use parser::*;
use std::{collections::HashSet, error::Error}; use std::{collections::HashSet, error::Error};
use type_meta::{ExternMethod, RustEnum, RustStruct, RustType}; use type_meta::{ExternMethod, RustEnum, RustStruct, RustType, RustConst};
enum GenerateKind { enum GenerateKind {
InputBindgen, InputBindgen,
@ -34,6 +34,7 @@ pub(crate) fn generate(
let mut aliases = AliasMap::new(); let mut aliases = AliasMap::new();
let mut structs: Vec<RustStruct> = vec![]; let mut structs: Vec<RustStruct> = vec![];
let mut enums: Vec<RustEnum> = vec![]; let mut enums: Vec<RustEnum> = vec![];
let mut consts: Vec<RustConst> = vec![];
for path in paths { for path in paths {
let file_content = std::fs::read_to_string(path) let file_content = std::fs::read_to_string(path)
@ -47,6 +48,10 @@ pub(crate) fn generate(
collect_type_alias(&file_ast, &mut aliases); collect_type_alias(&file_ast, &mut aliases);
collect_struct(&file_ast, &mut structs); collect_struct(&file_ast, &mut structs);
collect_enum(&file_ast, &mut enums); collect_enum(&file_ast, &mut enums);
if options.csharp_generate_const {
collect_const(&file_ast, &mut consts);
}
} }
// collect using_types // collect using_types
@ -82,7 +87,7 @@ pub(crate) fn generate(
} else { } else {
None None
}; };
let csharp = emit_csharp(&methods, &aliases, &structs, &enums, options); let csharp = emit_csharp(&methods, &aliases, &structs, &enums, &consts, options);
Ok((rust, csharp)) Ok((rust, csharp))
} }

View File

@ -11,8 +11,8 @@ enum FnItem {
/// build a Vec of all Items, unless the Item is a Item::Mod, then append the Item contents of the vect /// build a Vec of all Items, unless the Item is a Item::Mod, then append the Item contents of the vect
/// Do this recursively. /// Do this recursively.
/// This is not memory-efficient, would work better with an iterator, but does not seem performance critical. /// This is not memory-efficient, would work better with an iterator, but does not seem performance critical.
fn depth_first_module_walk<'a>(ast: &'a Vec<Item>) -> Vec<&'a syn::Item>{ fn depth_first_module_walk<'a>(ast: &'a Vec<Item>) -> Vec<&'a syn::Item> {
let mut unwrapped_items : Vec<&syn::Item> = vec![]; let mut unwrapped_items: Vec<&syn::Item> = vec![];
for item in ast { for item in ast {
match item { match item {
Item::Mod(m) => match &m.content { Item::Mod(m) => match &m.content {
@ -232,6 +232,49 @@ fn collect_fields_unnamed(fields: &syn::FieldsUnnamed) -> Vec<FieldMember> {
result result
} }
pub fn collect_const(ast: &syn::File, result: &mut Vec<RustConst>) {
for item in depth_first_module_walk(&ast.items) {
if let Item::Const(ct) = item {
// pub const Ident: ty = expr
let const_name = ct.ident.to_string();
let t = parse_type(&ct.ty);
if let syn::Expr::Lit(lit_expr) = &*ct.expr {
let value = match &lit_expr.lit {
syn::Lit::Str(s) => {
format!("{}", s.value())
}
syn::Lit::ByteStr(bs) => {
format!("{:?}", bs.value())
}
syn::Lit::Byte(b) => {
format!("{:?}", b.value())
}
syn::Lit::Char(c) => {
format!("'{}'", c.value())
}
syn::Lit::Int(i) => {
format!("{}", i.base10_parse::<i64>().unwrap())
}
syn::Lit::Float(f) => {
format!("{}", f.base10_parse::<f64>().unwrap())
}
syn::Lit::Bool(b) => {
format!("{}", b.value)
}
_ => format!(""),
};
result.push(RustConst {
const_name: const_name,
rust_type: t,
value: value,
});
}
}
}
}
pub fn collect_enum(ast: &syn::File, result: &mut Vec<RustEnum>) { pub fn collect_enum(ast: &syn::File, result: &mut Vec<RustEnum>) {
for item in depth_first_module_walk(&ast.items) { for item in depth_first_module_walk(&ast.items) {
if let Item::Enum(t) = item { if let Item::Enum(t) = item {

View File

@ -101,6 +101,13 @@ pub struct RustEnum {
pub is_flags: bool, pub is_flags: bool,
} }
#[derive(Clone, Debug)]
pub struct RustConst {
pub const_name: String,
pub rust_type: RustType,
pub value: String,
}
impl RustType { impl RustType {
pub fn to_rust_string(&self, type_path: &str) -> String { pub fn to_rust_string(&self, type_path: &str) -> String {
let mut sb = String::new(); let mut sb = String::new();

View File

@ -7,6 +7,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CsBindgen namespace CsBindgen
{ {
internal static unsafe partial class NativeMethods internal static unsafe partial class NativeMethods
@ -247,5 +248,6 @@ namespace CsBindgen
} }
} }

View File

@ -7,6 +7,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CsBindgen namespace CsBindgen
{ {
internal static unsafe partial class NestedModuleTests internal static unsafe partial class NestedModuleTests
@ -40,5 +41,6 @@ namespace CsBindgen
} }
} }

View File

@ -7,6 +7,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CsBindgen namespace CsBindgen
{ {
internal static unsafe partial class LibBullet3 internal static unsafe partial class LibBullet3
@ -1789,5 +1790,6 @@ namespace CsBindgen
} }

View File

@ -7,6 +7,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Physx namespace Physx
{ {
internal static unsafe partial class LibPhysx internal static unsafe partial class LibPhysx
@ -11267,5 +11268,6 @@ namespace Physx
} }
} }

View File

@ -7,6 +7,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace PixivApi.ImageFile namespace PixivApi.ImageFile
{ {
internal static unsafe partial class LibPng16 internal static unsafe partial class LibPng16
@ -1087,5 +1088,6 @@ namespace PixivApi.ImageFile
} }

View File

@ -7,6 +7,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CsBindgen namespace CsBindgen
{ {
public static unsafe partial class LibLz4 public static unsafe partial class LibLz4
@ -450,5 +451,6 @@ namespace CsBindgen
} }

View File

@ -7,6 +7,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CsBindgen namespace CsBindgen
{ {
internal static unsafe partial class LibQuiche internal static unsafe partial class LibQuiche
@ -558,5 +559,6 @@ namespace CsBindgen
} }

View File

@ -7,6 +7,7 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace CsBindgen namespace CsBindgen
{ {
internal static unsafe partial class LibZstd internal static unsafe partial class LibZstd
@ -306,5 +307,6 @@ namespace CsBindgen
} }