Skip to content

Commit

Permalink
Lowercase the numeric types
Browse files Browse the repository at this point in the history
Lowercasing numeric types introduces a problem. In C# custom types are
implemented with `using` directive, and the `using` directive expects
and identifier on the right side of `=`. Lowercase numeric types are
not identifiers, but rather reserved keywords. So its not possible to
define a type alias using a lowercase numeric type as the underlying
type. To use numeric types as the underlying type, the uppercase
system type counterparts must be used

To generate correct code for custom types, create new filter
`type_name_custom`, that formats these types in their respective system
type counterparts.

Signed-off-by: Kristupas Antanavicius <[email protected]>
  • Loading branch information
arg0d committed Sep 28, 2023
1 parent 2dd5f7c commit d125d21
Show file tree
Hide file tree
Showing 22 changed files with 278 additions and 32 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions bindgen/src/gen_cs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,30 @@ pub mod filters {
Ok(codetype.type_label(oracle()))
}

pub fn type_name_custom(typ: &Type) -> Result<String, askama::Error> {
// Lowercasing numeric types introduces a problem. In C# custom types are
// implemented with `using` directive, and the `using` directive expects
// and identifier on the right side of `=`. Lowercase numeric types are
// not identifiers, but rather reserved keywords. So its not possible to
// define a type alias using a lowercase numeric type as the underlying
// type. To use numeric types as the underlying type, the uppercase
// numeric system type counterparts must be used.
match typ {
Type::Boolean => Ok("Boolean".to_string()),
Type::Int8 => Ok("SByte".to_string()),
Type::Int16 => Ok("Int16".to_string()),
Type::Int32 => Ok("Int32".to_string()),
Type::Int64 => Ok("Int64".to_string()),
Type::UInt8 => Ok("Byte".to_string()),
Type::UInt16 => Ok("UInt16".to_string()),
Type::UInt32 => Ok("UInt32".to_string()),
Type::UInt64 => Ok("UInt64".to_string()),
Type::Float32 => Ok("Single".to_string()),
Type::Float64 => Ok("Double".to_string()),
_ => type_name(typ),
}
}

pub fn canonical_name(codetype: &impl CodeType) -> Result<String, askama::Error> {
Ok(codetype.canonical_name(oracle()))
}
Expand Down
22 changes: 11 additions & 11 deletions bindgen/src/gen_cs/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ macro_rules! impl_code_type_for_primitive {
};
}

impl_code_type_for_primitive!(BooleanCodeType, "Boolean", "Boolean");
impl_code_type_for_primitive!(BooleanCodeType, "bool", "Boolean");
impl_code_type_for_primitive!(StringCodeType, "String", "String");
impl_code_type_for_primitive!(Int8CodeType, "SByte", "SByte");
impl_code_type_for_primitive!(Int16CodeType, "Int16", "Short");
impl_code_type_for_primitive!(Int32CodeType, "Int32", "Int");
impl_code_type_for_primitive!(Int64CodeType, "Int64", "Long");
impl_code_type_for_primitive!(UInt8CodeType, "Byte", "Byte");
impl_code_type_for_primitive!(UInt16CodeType, "UInt16", "UShort");
impl_code_type_for_primitive!(UInt32CodeType, "UInt32", "UInt");
impl_code_type_for_primitive!(UInt64CodeType, "UInt64", "ULong");
impl_code_type_for_primitive!(Float32CodeType, "Single", "Float");
impl_code_type_for_primitive!(Float64CodeType, "Double", "Double");
impl_code_type_for_primitive!(Int8CodeType, "sbyte", "Int8");
impl_code_type_for_primitive!(Int16CodeType, "short", "Int16");
impl_code_type_for_primitive!(Int32CodeType, "int", "Int32");
impl_code_type_for_primitive!(Int64CodeType, "long", "Int64");
impl_code_type_for_primitive!(UInt8CodeType, "byte", "UInt8");
impl_code_type_for_primitive!(UInt16CodeType, "ushort", "UInt16");
impl_code_type_for_primitive!(UInt32CodeType, "uint", "UInt32");
impl_code_type_for_primitive!(UInt64CodeType, "ulong", "UInt64");
impl_code_type_for_primitive!(Float32CodeType, "float", "Float");
impl_code_type_for_primitive!(Float64CodeType, "double", "Double");
2 changes: 1 addition & 1 deletion bindgen/templates/CustomTypeTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* is needed because the UDL type name is used in function/method signatures.
* It's also what we have an external type that references a custom type.
*/
{{- self.add_type_alias(name, builtin|type_name) }}
{{- self.add_type_alias(name, builtin|type_name_custom) }}
{{- self.add_type_alias(ffi_converter_name, builtin|ffi_converter_name) }}

{%- when Some with (config) %}
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/Float32Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterFloat: FfiConverter<float, float> {
public static FfiConverterFloat INSTANCE = new FfiConverterFloat();
class {{ ffi_converter_name }}: FfiConverter<float, float> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override float Lift(float value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/Float64Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterDouble: FfiConverter<double, double> {
public static FfiConverterDouble INSTANCE = new FfiConverterDouble();
class {{ ffi_converter_name }}: FfiConverter<double, double> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override double Lift(double value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/Int16Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterShort: FfiConverter<short, short> {
public static FfiConverterShort INSTANCE = new FfiConverterShort();
class {{ ffi_converter_name }}: FfiConverter<short, short> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override short Lift(short value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/Int32Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterInt: FfiConverter<int, int> {
public static FfiConverterInt INSTANCE = new FfiConverterInt();
class {{ ffi_converter_name }}: FfiConverter<int, int> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override int Lift(int value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/Int64Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterLong: FfiConverter<long, long> {
public static FfiConverterLong INSTANCE = new FfiConverterLong();
class {{ ffi_converter_name }}: FfiConverter<long, long> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override long Lift(long value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/Int8Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterSByte: FfiConverter<sbyte, sbyte> {
public static FfiConverterSByte INSTANCE = new FfiConverterSByte();
class {{ ffi_converter_name }}: FfiConverter<sbyte, sbyte> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override sbyte Lift(sbyte value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/UInt16Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterUShort: FfiConverter<ushort, ushort> {
public static FfiConverterUShort INSTANCE = new FfiConverterUShort();
class {{ ffi_converter_name }}: FfiConverter<ushort, ushort> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override ushort Lift(ushort value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/UInt32Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterUInt: FfiConverter<uint, uint> {
public static FfiConverterUInt INSTANCE = new FfiConverterUInt();
class {{ ffi_converter_name }}: FfiConverter<uint, uint> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override uint Lift(uint value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/UInt64Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterULong: FfiConverter<ulong, ulong> {
public static FfiConverterULong INSTANCE = new FfiConverterULong();
class {{ ffi_converter_name }}: FfiConverter<ulong, ulong> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override ulong Lift(ulong value) {
return value;
Expand Down
4 changes: 2 additions & 2 deletions bindgen/templates/UInt8Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */#}

class FfiConverterByte: FfiConverter<byte, byte> {
public static FfiConverterByte INSTANCE = new FfiConverterByte();
class {{ ffi_converter_name }}: FfiConverter<byte, byte> {
public static {{ ffi_converter_name }} INSTANCE = new {{ ffi_converter_name }}();

public override byte Lift(byte value) {
return value;
Expand Down
32 changes: 32 additions & 0 deletions dotnet-tests/UniffiCS.binding_tests/TestCustomTypesBuiltin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

using System;
using uniffi.custom_types_builtin;

public class TestCustomTypesBuiltin {
[Fact]
public void CustomTypesWork() {
var demo = CustomTypesBuiltinMethods.GetCustomTypesBuiltin();
AssertDemo(demo);

demo = CustomTypesBuiltinMethods.ReturnCustomTypesBuiltin(demo);
AssertDemo(demo);
}

void AssertDemo(CustomTypesBuiltin demo) {
Assert.Equal("Hello, world!", demo.@string);
Assert.True(demo.boolean);
Assert.Equal(SByte.MaxValue, demo.int8);
Assert.Equal(Int16.MaxValue, demo.int16);
Assert.Equal(Int32.MaxValue, demo.int32);
Assert.Equal(Int64.MaxValue, demo.int64);
Assert.Equal(Byte.MaxValue, demo.uint8);
Assert.Equal(UInt16.MaxValue, demo.uint16);
Assert.Equal(UInt32.MaxValue, demo.uint32);
Assert.Equal(UInt64.MaxValue, demo.uint64);
Assert.Equal(Single.MaxValue, demo.@float);
Assert.Equal(Double.MaxValue, demo.@double);
}
}
1 change: 1 addition & 0 deletions fixtures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ crate-type = ["cdylib", "lib"]

[dependencies]
global-methods-class-name = { path = "global-methods-class-name" }
uniffi-cs-custom-types-builtin = { path = "custom-types-builtin" }
uniffi-cs-disposable-fixture = { path = "disposable" }
uniffi-example-arithmetic = { path = "../3rd-party/uniffi-rs/examples/arithmetic" }
uniffi-example-callbacks = { path = "../3rd-party/uniffi-rs/examples/callbacks" }
Expand Down
19 changes: 19 additions & 0 deletions fixtures/custom-types-builtin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "uniffi-cs-custom-types-builtin"
version = "1.0.0"
edition = "2021"
publish = false

[lib]
crate-type = ["lib", "cdylib"]
name = "uniffi_cs_custom_types_builtin"

[dependencies]
once_cell = "1.12"
paste = "1.0"
thiserror = "1.0"
uniffi = {path = "../../3rd-party/uniffi-rs/uniffi", features=["build"]}
uniffi_macros = {path = "../../3rd-party/uniffi-rs/uniffi_macros"}

[build-dependencies]
uniffi = {path = "../../3rd-party/uniffi-rs/uniffi", features=["bindgen-tests"]}
7 changes: 7 additions & 0 deletions fixtures/custom-types-builtin/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

fn main() {
uniffi::generate_scaffolding("./src/custom-types-builtin.udl").unwrap();
}
71 changes: 71 additions & 0 deletions fixtures/custom-types-builtin/src/custom-types-builtin.udl
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Ensure that builtin types can be used as the underlying type in custom types.

[Custom]
typedef string MyString;

// using sequence or record as the underlying type produces broken code

// [Custom]
// typedef sequence<string> Array;

// [Custom]
// typedef record<string, string> Table;

[Custom]
typedef boolean Boolean;

[Custom]
typedef i8 Int8;

[Custom]
typedef i16 Int16;

[Custom]
typedef i32 Int32;

[Custom]
typedef i64 Int64;

[Custom]
typedef u8 UInt8;

[Custom]
typedef u16 UInt16;

[Custom]
typedef u32 UInt32;

[Custom]
typedef u64 UInt64;

[Custom]
typedef float Float;

[Custom]
typedef double Double;

dictionary CustomTypesBuiltin {
MyString string;
// Array array;
// Table table;
Boolean boolean;
Int8 int8;
Int16 int16;
Int32 int32;
Int64 int64;
UInt8 uint8;
UInt16 uint16;
UInt32 uint32;
UInt64 uint64;
Float float;
Double double;
};

namespace custom_types_builtin {
CustomTypesBuiltin get_custom_types_builtin();
CustomTypesBuiltin return_custom_types_builtin(CustomTypesBuiltin custom_types);
};
Loading

0 comments on commit d125d21

Please sign in to comment.