diff --git a/csbindgen-tests/build.rs b/csbindgen-tests/build.rs index c7d6140..a1eb32b 100644 --- a/csbindgen-tests/build.rs +++ b/csbindgen-tests/build.rs @@ -102,6 +102,15 @@ fn main() -> Result<(), Box> { .generate_csharp_file("../dotnet-sandbox/NestedModuleTests.cs") .unwrap(); + csbindgen::Builder::default() + .input_extern_file("src/negative_constants.rs") + .csharp_class_name("NegativeConstantsTests") + .csharp_dll_name("csbindgen_tests_negative_constants") + .csharp_use_function_pointer(true) + .csharp_generate_const_filter(|_| true) + .generate_csharp_file("../dotnet-sandbox/NegativeConstantsTests.cs") + .unwrap(); + csbindgen::Builder::new() .input_bindgen_file("src/zstd.rs") .method_filter(|x| x.starts_with("ZSTD_")) diff --git a/csbindgen-tests/src/negative_constants.rs b/csbindgen-tests/src/negative_constants.rs new file mode 100644 index 0000000..c113324 --- /dev/null +++ b/csbindgen-tests/src/negative_constants.rs @@ -0,0 +1,6 @@ +pub const CONST_U32: u32 = 1; +pub const CONST_U16: u16 = 42; +pub const CONST_U32_IN_BRACKETS: u32 = (420); +pub const CONST_I32: i32 = -1; +pub const CONST_I16: i16 = -42; +pub const CONST_I32_IN_BRACKETS: i32 = (-(420)); diff --git a/csbindgen/src/parser.rs b/csbindgen/src/parser.rs index 8ea6c16..a033e9b 100644 --- a/csbindgen/src/parser.rs +++ b/csbindgen/src/parser.rs @@ -382,32 +382,32 @@ pub fn collect_const( if filter(const_name.as_str()) { 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()) + let expr = peel_expr(ct.expr.as_ref()); + let value = match expr { + syn::Expr::Lit(lit_expr) => match &lit_expr.lit { + syn::Lit::Str(s) => Some(format!("\"{}\"", s.value())), + syn::Lit::ByteStr(bs) => Some(format!("{:?}", bs.value())), + syn::Lit::Byte(b) => Some(format!("{}", b.value())), + syn::Lit::Char(c) => Some(format!("'{}'", c.value())), + syn::Lit::Int(i) => Some(format!("{}", i.base10_parse::().unwrap())), + syn::Lit::Float(f) => Some(format!("{}", f.base10_parse::().unwrap())), + syn::Lit::Bool(b) => Some(format!("{}", b.value)), + _ => Some(String::new()), + }, + syn::Expr::Unary(unary_expr) if matches!(unary_expr.op, syn::UnOp::Neg(_)) => { + let inner = peel_expr(unary_expr.expr.as_ref()); + match inner { + syn::Expr::Lit(lit_expr) => match &lit_expr.lit { + syn::Lit::Int(i) => Some(format!("-{}", i.base10_digits())), + syn::Lit::Float(f) => Some(format!("-{}", f.base10_digits())), + _ => None, + }, + _ => None, } - 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::().unwrap()) - } - syn::Lit::Float(f) => { - format!("{}", f.base10_parse::().unwrap()) - } - syn::Lit::Bool(b) => { - format!("{}", b.value) - } - _ => String::new(), - }; - + } + _ => None, + }; + if let Some(value) = value { result.push(RustConst { const_name, rust_type: t, @@ -728,6 +728,16 @@ fn parse_type(t: &syn::Type) -> RustType { } } +fn peel_expr(mut e: &syn::Expr) -> &syn::Expr { + loop { + match e { + syn::Expr::Group(g) => e = &g.expr, + syn::Expr::Paren(p) => e = &p.expr, + _ => return e, + } + } +} + fn parse_type_path(t: &syn::TypePath) -> RustType { let last_segment = t.path.segments.last().unwrap(); if let syn::PathArguments::AngleBracketed(x) = &last_segment.arguments { diff --git a/dotnet-sandbox/NegativeConstantsTests.cs b/dotnet-sandbox/NegativeConstantsTests.cs new file mode 100644 index 0000000..0ab5509 --- /dev/null +++ b/dotnet-sandbox/NegativeConstantsTests.cs @@ -0,0 +1,32 @@ +// +// This code is generated by csbindgen. +// DON'T CHANGE THIS DIRECTLY. +// +#pragma warning disable CS8500 +#pragma warning disable CS8981 +using System; +using System.Runtime.InteropServices; + + +namespace CsBindgen +{ + internal static unsafe partial class NegativeConstantsTests + { + const string __DllName = "csbindgen_tests_negative_constants"; + + internal const uint CONST_U32 = 1; + internal const ushort CONST_U16 = 42; + internal const uint CONST_U32_IN_BRACKETS = 420; + internal const int CONST_I32 = -1; + internal const short CONST_I16 = -42; + internal const int CONST_I32_IN_BRACKETS = -420; + + + + + + } + + + +}