From b4f50c55625b1fe2070a64fc0d80788bfbf9a32a Mon Sep 17 00:00:00 2001 From: Robert Bastian <4706271+robertbastian@users.noreply.github.com> Date: Fri, 17 Nov 2023 23:38:36 +0100 Subject: [PATCH 1/3] files --- example/dart/lib/ICU4XDataProvider.g.dart | 45 + example/dart/lib/ICU4XFixedDecimal.g.dart | 63 + .../lib/ICU4XFixedDecimalFormatter.g.dart | 65 + .../ICU4XFixedDecimalFormatterOptions.g.dart | 62 + .../ICU4XFixedDecimalGroupingStrategy.g.dart | 20 + example/dart/lib/ICU4XLocale.g.dart | 56 + example/dart/lib/lib.g.dart | 281 +--- feature_tests/dart/lib/AttrEnum.g.dart | 12 + feature_tests/dart/lib/AttrOpaque1.g.dart | 36 + feature_tests/dart/lib/AttrOpaque2.g.dart | 16 + feature_tests/dart/lib/Bar.g.dart | 16 + feature_tests/dart/lib/BorrowedFields.g.dart | 53 + .../dart/lib/BorrowedFieldsReturning.g.dart | 42 + feature_tests/dart/lib/ContiguousEnum.g.dart | 13 + feature_tests/dart/lib/ErrorEnum.g.dart | 11 + feature_tests/dart/lib/ErrorStruct.g.dart | 49 + feature_tests/dart/lib/Float64Vec.g.dart | 68 + feature_tests/dart/lib/Foo.g.dart | 89 ++ feature_tests/dart/lib/ImportedStruct.g.dart | 49 + feature_tests/dart/lib/MyEnum.g.dart | 43 + feature_tests/dart/lib/MyString.g.dart | 65 + feature_tests/dart/lib/MyStruct.g.dart | 115 ++ feature_tests/dart/lib/One.g.dart | 217 +++ feature_tests/dart/lib/Opaque.g.dart | 52 + feature_tests/dart/lib/OptionOpaque.g.dart | 61 + .../dart/lib/OptionOpaqueChar.g.dart | 28 + feature_tests/dart/lib/OptionStruct.g.dart | 59 + feature_tests/dart/lib/RefList.g.dart | 28 + .../dart/lib/RefListParameter.g.dart | 17 + feature_tests/dart/lib/ResultOpaque.g.dart | 123 ++ feature_tests/dart/lib/Two.g.dart | 16 + feature_tests/dart/lib/UnimportedEnum.g.dart | 12 + feature_tests/dart/lib/lib.g.dart | 1176 ++--------------- tool/src/dart/class.rs | 183 ++- tool/src/dart/formatter.rs | 24 + tool/src/dart/mod.rs | 23 +- tool/templates/dart/base.dart.jinja | 4 +- 37 files changed, 1820 insertions(+), 1472 deletions(-) create mode 100644 example/dart/lib/ICU4XDataProvider.g.dart create mode 100644 example/dart/lib/ICU4XFixedDecimal.g.dart create mode 100644 example/dart/lib/ICU4XFixedDecimalFormatter.g.dart create mode 100644 example/dart/lib/ICU4XFixedDecimalFormatterOptions.g.dart create mode 100644 example/dart/lib/ICU4XFixedDecimalGroupingStrategy.g.dart create mode 100644 example/dart/lib/ICU4XLocale.g.dart create mode 100644 feature_tests/dart/lib/AttrEnum.g.dart create mode 100644 feature_tests/dart/lib/AttrOpaque1.g.dart create mode 100644 feature_tests/dart/lib/AttrOpaque2.g.dart create mode 100644 feature_tests/dart/lib/Bar.g.dart create mode 100644 feature_tests/dart/lib/BorrowedFields.g.dart create mode 100644 feature_tests/dart/lib/BorrowedFieldsReturning.g.dart create mode 100644 feature_tests/dart/lib/ContiguousEnum.g.dart create mode 100644 feature_tests/dart/lib/ErrorEnum.g.dart create mode 100644 feature_tests/dart/lib/ErrorStruct.g.dart create mode 100644 feature_tests/dart/lib/Float64Vec.g.dart create mode 100644 feature_tests/dart/lib/Foo.g.dart create mode 100644 feature_tests/dart/lib/ImportedStruct.g.dart create mode 100644 feature_tests/dart/lib/MyEnum.g.dart create mode 100644 feature_tests/dart/lib/MyString.g.dart create mode 100644 feature_tests/dart/lib/MyStruct.g.dart create mode 100644 feature_tests/dart/lib/One.g.dart create mode 100644 feature_tests/dart/lib/Opaque.g.dart create mode 100644 feature_tests/dart/lib/OptionOpaque.g.dart create mode 100644 feature_tests/dart/lib/OptionOpaqueChar.g.dart create mode 100644 feature_tests/dart/lib/OptionStruct.g.dart create mode 100644 feature_tests/dart/lib/RefList.g.dart create mode 100644 feature_tests/dart/lib/RefListParameter.g.dart create mode 100644 feature_tests/dart/lib/ResultOpaque.g.dart create mode 100644 feature_tests/dart/lib/Two.g.dart create mode 100644 feature_tests/dart/lib/UnimportedEnum.g.dart diff --git a/example/dart/lib/ICU4XDataProvider.g.dart b/example/dart/lib/ICU4XDataProvider.g.dart new file mode 100644 index 000000000..f3b77d8ee --- /dev/null +++ b/example/dart/lib/ICU4XDataProvider.g.dart @@ -0,0 +1,45 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +/// An ICU4X data provider, capable of loading ICU4X data keys from some source. +/// +/// See the [Rust documentation for `icu_provider`](https://docs.rs/icu_provider/latest/icu_provider/index.html) for more information. +class ICU4XDataProvider implements ffi.Finalizable { + final ffi.Pointer _underlying; + + ICU4XDataProvider._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = + ffi.NativeFinalizer(_capi('ICU4XDataProvider_destroy')); + + /// See the [Rust documentation for `get_static_provider`](https://docs.rs/icu_testdata/latest/icu_testdata/fn.get_static_provider.html) for more information. + factory ICU4XDataProvider.static_() { + final result = _ICU4XDataProvider_new_static(); + return ICU4XDataProvider._(result); + } + // ignore: non_constant_identifier_names + static final _ICU4XDataProvider_new_static = + _capi Function()>>( + 'ICU4XDataProvider_new_static') + .asFunction Function()>(isLeaf: true); + + /// This exists as a regression test for https://github.com/rust-diplomat/diplomat/issues/155 + static void returnsResult() { + final result = _ICU4XDataProvider_returns_result(); + if (!result.isOk) { + throw VoidError(); + } + } + + // ignore: non_constant_identifier_names + static final _ICU4XDataProvider_returns_result = + _capi>( + 'ICU4XDataProvider_returns_result') + .asFunction<_ResultVoidVoid Function()>(isLeaf: true); +} diff --git a/example/dart/lib/ICU4XFixedDecimal.g.dart b/example/dart/lib/ICU4XFixedDecimal.g.dart new file mode 100644 index 000000000..656d763ee --- /dev/null +++ b/example/dart/lib/ICU4XFixedDecimal.g.dart @@ -0,0 +1,63 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +/// See the [Rust documentation for `FixedDecimal`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html) for more information. +class ICU4XFixedDecimal implements ffi.Finalizable { + final ffi.Pointer _underlying; + + ICU4XFixedDecimal._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = + ffi.NativeFinalizer(_capi('ICU4XFixedDecimal_destroy')); + + /// Construct an [`ICU4XFixedDecimal`] from an integer. + factory ICU4XFixedDecimal(int v) { + final result = _ICU4XFixedDecimal_new(v); + return ICU4XFixedDecimal._(result); + } + // ignore: non_constant_identifier_names + static final _ICU4XFixedDecimal_new = + _capi Function(ffi.Int32)>>( + 'ICU4XFixedDecimal_new') + .asFunction Function(int)>(isLeaf: true); + + /// Multiply the [`ICU4XFixedDecimal`] by a given power of ten. + /// + /// See the [Rust documentation for `multiply_pow10`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html#method.multiply_pow10) for more information. + void multiplyPow10(int power) { + _ICU4XFixedDecimal_multiply_pow10(_underlying, power); + } + + // ignore: non_constant_identifier_names + static final _ICU4XFixedDecimal_multiply_pow10 = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, + ffi.Int16)>>('ICU4XFixedDecimal_multiply_pow10') + .asFunction, int)>(isLeaf: true); + + /// Format the [`ICU4XFixedDecimal`] as a string. + /// + /// See the [Rust documentation for `write_to`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html#method.write_to) for more information. + @override + String toString() { + final writeable = _Writeable(); + final result = + _ICU4XFixedDecimal_to_string(_underlying, writeable._underlying); + return result.isOk ? writeable.finalize() : throw VoidError(); + } + + // ignore: non_constant_identifier_names + static final _ICU4XFixedDecimal_to_string = _capi< + ffi.NativeFunction< + _ResultVoidVoid Function(ffi.Pointer, + ffi.Pointer)>>('ICU4XFixedDecimal_to_string') + .asFunction< + _ResultVoidVoid Function( + ffi.Pointer, ffi.Pointer)>(isLeaf: true); +} diff --git a/example/dart/lib/ICU4XFixedDecimalFormatter.g.dart b/example/dart/lib/ICU4XFixedDecimalFormatter.g.dart new file mode 100644 index 000000000..bf6a622f0 --- /dev/null +++ b/example/dart/lib/ICU4XFixedDecimalFormatter.g.dart @@ -0,0 +1,65 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +/// An ICU4X Fixed Decimal Format object, capable of formatting a [`ICU4XFixedDecimal`] as a string. +/// +/// See the [Rust documentation for `FixedDecimalFormatter`](https://docs.rs/icu/latest/icu/decimal/struct.FixedDecimalFormatter.html) for more information. +class ICU4XFixedDecimalFormatter implements ffi.Finalizable { + final ffi.Pointer _underlying; + + ICU4XFixedDecimalFormatter._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = + ffi.NativeFinalizer(_capi('ICU4XFixedDecimalFormatter_destroy')); + + /// Creates a new [`ICU4XFixedDecimalFormatter`] from locale data. + /// + /// See the [Rust documentation for `try_new`](https://docs.rs/icu/latest/icu/decimal/struct.FixedDecimalFormatter.html#method.try_new) for more information. + factory ICU4XFixedDecimalFormatter.tryNew(ICU4XLocale locale, + ICU4XDataProvider provider, ICU4XFixedDecimalFormatterOptions options) { + final result = _ICU4XFixedDecimalFormatter_try_new( + locale._underlying, provider._underlying, options._underlying); + return result.isOk + ? ICU4XFixedDecimalFormatter._(result.union.ok) + : throw VoidError(); + } + // ignore: non_constant_identifier_names + static final _ICU4XFixedDecimalFormatter_try_new = _capi< + ffi.NativeFunction< + _ResultOpaqueVoid Function( + ffi.Pointer, + ffi.Pointer, + _ICU4XFixedDecimalFormatterOptionsFfi)>>( + 'ICU4XFixedDecimalFormatter_try_new') + .asFunction< + _ResultOpaqueVoid Function( + ffi.Pointer, + ffi.Pointer, + _ICU4XFixedDecimalFormatterOptionsFfi)>(isLeaf: true); + + /// Formats a [`ICU4XFixedDecimal`] to a string. + /// + /// See the [Rust documentation for `format`](https://docs.rs/icu/latest/icu/decimal/struct.FixedDecimalFormatter.html#method.format) for more information. + String formatWrite(ICU4XFixedDecimal value) { + final writeable = _Writeable(); + _ICU4XFixedDecimalFormatter_format_write( + _underlying, value._underlying, writeable._underlying); + return writeable.finalize(); + } + + // ignore: non_constant_identifier_names + static final _ICU4XFixedDecimalFormatter_format_write = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>>( + 'ICU4XFixedDecimalFormatter_format_write') + .asFunction< + void Function(ffi.Pointer, ffi.Pointer, + ffi.Pointer)>(isLeaf: true); +} diff --git a/example/dart/lib/ICU4XFixedDecimalFormatterOptions.g.dart b/example/dart/lib/ICU4XFixedDecimalFormatterOptions.g.dart new file mode 100644 index 000000000..f779b0228 --- /dev/null +++ b/example/dart/lib/ICU4XFixedDecimalFormatterOptions.g.dart @@ -0,0 +1,62 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class _ICU4XFixedDecimalFormatterOptionsFfi extends ffi.Struct { + @ffi.Int32() + external int groupingStrategy; + @ffi.Bool() + external bool someOtherConfig; +} + +class ICU4XFixedDecimalFormatterOptions { + final _ICU4XFixedDecimalFormatterOptionsFfi _underlying; + + // ignore: unused_element + ICU4XFixedDecimalFormatterOptions._(this._underlying); + + factory ICU4XFixedDecimalFormatterOptions() { + final pointer = ffi2.calloc<_ICU4XFixedDecimalFormatterOptionsFfi>(); + final result = ICU4XFixedDecimalFormatterOptions._(pointer.ref); + _callocFree.attach(result, pointer.cast()); + return result; + } + + ICU4XFixedDecimalGroupingStrategy get groupingStrategy => + ICU4XFixedDecimalGroupingStrategy.values[_underlying.groupingStrategy]; + set groupingStrategy(ICU4XFixedDecimalGroupingStrategy groupingStrategy) { + _underlying.groupingStrategy = groupingStrategy.index; + } + + bool get someOtherConfig => _underlying.someOtherConfig; + set someOtherConfig(bool someOtherConfig) { + _underlying.someOtherConfig = someOtherConfig; + } + + factory ICU4XFixedDecimalFormatterOptions() { + final result = _ICU4XFixedDecimalFormatterOptions_default(); + return ICU4XFixedDecimalFormatterOptions._(result); + } + // ignore: non_constant_identifier_names + static final _ICU4XFixedDecimalFormatterOptions_default = _capi< + ffi.NativeFunction< + _ICU4XFixedDecimalFormatterOptionsFfi + Function()>>('ICU4XFixedDecimalFormatterOptions_default') + .asFunction<_ICU4XFixedDecimalFormatterOptionsFfi Function()>( + isLeaf: true); + + @override + bool operator ==(Object other) => + other is ICU4XFixedDecimalFormatterOptions && + other._underlying.groupingStrategy == _underlying.groupingStrategy && + other._underlying.someOtherConfig == _underlying.someOtherConfig; + + @override + int get hashCode => Object.hashAll([ + _underlying.groupingStrategy, + _underlying.someOtherConfig, + ]); +} diff --git a/example/dart/lib/ICU4XFixedDecimalGroupingStrategy.g.dart b/example/dart/lib/ICU4XFixedDecimalGroupingStrategy.g.dart new file mode 100644 index 000000000..3addfa907 --- /dev/null +++ b/example/dart/lib/ICU4XFixedDecimalGroupingStrategy.g.dart @@ -0,0 +1,20 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +enum ICU4XFixedDecimalGroupingStrategy { + /// Auto grouping + auto, + + /// No grouping + never, + + /// Always group + always, + + /// At least 2 groups + min2; +} diff --git a/example/dart/lib/ICU4XLocale.g.dart b/example/dart/lib/ICU4XLocale.g.dart new file mode 100644 index 000000000..14883629b --- /dev/null +++ b/example/dart/lib/ICU4XLocale.g.dart @@ -0,0 +1,56 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +/// An ICU4X Locale, capable of representing strings like `"en-US"`. +/// +/// See the [Rust documentation for `Locale`](https://docs.rs/icu/latest/icu/locid/struct.Locale.html) for more information. +class ICU4XLocale implements ffi.Finalizable { + final ffi.Pointer _underlying; + + ICU4XLocale._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('ICU4XLocale_destroy')); + + /// Construct an [`ICU4XLocale`] from a locale identifier represented as a string. + factory ICU4XLocale(String name) { + final alloc = ffi2.Arena(); + final nameSlice = _SliceFfi2Utf8._fromDart(name, alloc); + + final result = _ICU4XLocale_new(nameSlice._bytes, nameSlice._length); + alloc.releaseAll(); + return ICU4XLocale._(result); + } + // ignore: non_constant_identifier_names + static final _ICU4XLocale_new = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Size)>>('ICU4XLocale_new') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, int)>(isLeaf: true); + + /// Construct an [`ICU4XLocale`] from a locale identifier represented as bytes. + factory ICU4XLocale.fromBytes(Uint8List bytes) { + final alloc = ffi2.Arena(); + final bytesSlice = _SliceFfiUint8._fromDart(bytes, alloc); + + final result = + _ICU4XLocale_new_from_bytes(bytesSlice._bytes, bytesSlice._length); + alloc.releaseAll(); + return ICU4XLocale._(result); + } + // ignore: non_constant_identifier_names + static final _ICU4XLocale_new_from_bytes = _capi< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Size)>>('ICU4XLocale_new_from_bytes') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, int)>(isLeaf: true); +} diff --git a/example/dart/lib/lib.g.dart b/example/dart/lib/lib.g.dart index 7d3c5b030..91d7891b3 100644 --- a/example/dart/lib/lib.g.dart +++ b/example/dart/lib/lib.g.dart @@ -7,287 +7,18 @@ import 'dart:convert'; import 'dart:ffi' as ffi; import 'dart:typed_data'; import 'package:ffi/ffi.dart' as ffi2; +part 'ICU4XDataProvider.g.dart'; +part 'ICU4XFixedDecimal.g.dart'; +part 'ICU4XFixedDecimalFormatter.g.dart'; +part 'ICU4XFixedDecimalFormatterOptions.g.dart'; +part 'ICU4XFixedDecimalGroupingStrategy.g.dart'; +part 'ICU4XLocale.g.dart'; late final ffi.Pointer Function(String) _capi; void init(String path) => _capi = ffi.DynamicLibrary.open(path).lookup; final _callocFree = Finalizer(ffi2.calloc.free); -/// An ICU4X data provider, capable of loading ICU4X data keys from some source. -/// -/// See the [Rust documentation for `icu_provider`](https://docs.rs/icu_provider/latest/icu_provider/index.html) for more information. -class ICU4XDataProvider implements ffi.Finalizable { - final ffi.Pointer _underlying; - - ICU4XDataProvider._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = - ffi.NativeFinalizer(_capi('ICU4XDataProvider_destroy')); - - /// See the [Rust documentation for `get_static_provider`](https://docs.rs/icu_testdata/latest/icu_testdata/fn.get_static_provider.html) for more information. - factory ICU4XDataProvider.static_() { - final result = _ICU4XDataProvider_new_static(); - return ICU4XDataProvider._(result); - } - // ignore: non_constant_identifier_names - static final _ICU4XDataProvider_new_static = - _capi Function()>>( - 'ICU4XDataProvider_new_static') - .asFunction Function()>(isLeaf: true); - - /// This exists as a regression test for https://github.com/rust-diplomat/diplomat/issues/155 - static void returnsResult() { - final result = _ICU4XDataProvider_returns_result(); - if (!result.isOk) { - throw VoidError(); - } - } - - // ignore: non_constant_identifier_names - static final _ICU4XDataProvider_returns_result = - _capi>( - 'ICU4XDataProvider_returns_result') - .asFunction<_ResultVoidVoid Function()>(isLeaf: true); -} - -/// See the [Rust documentation for `FixedDecimal`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html) for more information. -class ICU4XFixedDecimal implements ffi.Finalizable { - final ffi.Pointer _underlying; - - ICU4XFixedDecimal._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = - ffi.NativeFinalizer(_capi('ICU4XFixedDecimal_destroy')); - - /// Construct an [`ICU4XFixedDecimal`] from an integer. - factory ICU4XFixedDecimal(int v) { - final result = _ICU4XFixedDecimal_new(v); - return ICU4XFixedDecimal._(result); - } - // ignore: non_constant_identifier_names - static final _ICU4XFixedDecimal_new = - _capi Function(ffi.Int32)>>( - 'ICU4XFixedDecimal_new') - .asFunction Function(int)>(isLeaf: true); - - /// Multiply the [`ICU4XFixedDecimal`] by a given power of ten. - /// - /// See the [Rust documentation for `multiply_pow10`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html#method.multiply_pow10) for more information. - void multiplyPow10(int power) { - _ICU4XFixedDecimal_multiply_pow10(_underlying, power); - } - - // ignore: non_constant_identifier_names - static final _ICU4XFixedDecimal_multiply_pow10 = _capi< - ffi.NativeFunction< - ffi.Void Function(ffi.Pointer, - ffi.Int16)>>('ICU4XFixedDecimal_multiply_pow10') - .asFunction, int)>(isLeaf: true); - - /// Format the [`ICU4XFixedDecimal`] as a string. - /// - /// See the [Rust documentation for `write_to`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html#method.write_to) for more information. - @override - String toString() { - final writeable = _Writeable(); - final result = - _ICU4XFixedDecimal_to_string(_underlying, writeable._underlying); - return result.isOk ? writeable.finalize() : throw VoidError(); - } - - // ignore: non_constant_identifier_names - static final _ICU4XFixedDecimal_to_string = _capi< - ffi.NativeFunction< - _ResultVoidVoid Function(ffi.Pointer, - ffi.Pointer)>>('ICU4XFixedDecimal_to_string') - .asFunction< - _ResultVoidVoid Function( - ffi.Pointer, ffi.Pointer)>(isLeaf: true); -} - -/// An ICU4X Fixed Decimal Format object, capable of formatting a [`ICU4XFixedDecimal`] as a string. -/// -/// See the [Rust documentation for `FixedDecimalFormatter`](https://docs.rs/icu/latest/icu/decimal/struct.FixedDecimalFormatter.html) for more information. -class ICU4XFixedDecimalFormatter implements ffi.Finalizable { - final ffi.Pointer _underlying; - - ICU4XFixedDecimalFormatter._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = - ffi.NativeFinalizer(_capi('ICU4XFixedDecimalFormatter_destroy')); - - /// Creates a new [`ICU4XFixedDecimalFormatter`] from locale data. - /// - /// See the [Rust documentation for `try_new`](https://docs.rs/icu/latest/icu/decimal/struct.FixedDecimalFormatter.html#method.try_new) for more information. - factory ICU4XFixedDecimalFormatter.tryNew(ICU4XLocale locale, - ICU4XDataProvider provider, ICU4XFixedDecimalFormatterOptions options) { - final result = _ICU4XFixedDecimalFormatter_try_new( - locale._underlying, provider._underlying, options._underlying); - return result.isOk - ? ICU4XFixedDecimalFormatter._(result.union.ok) - : throw VoidError(); - } - // ignore: non_constant_identifier_names - static final _ICU4XFixedDecimalFormatter_try_new = _capi< - ffi.NativeFunction< - _ResultOpaqueVoid Function( - ffi.Pointer, - ffi.Pointer, - _ICU4XFixedDecimalFormatterOptionsFfi)>>( - 'ICU4XFixedDecimalFormatter_try_new') - .asFunction< - _ResultOpaqueVoid Function( - ffi.Pointer, - ffi.Pointer, - _ICU4XFixedDecimalFormatterOptionsFfi)>(isLeaf: true); - - /// Formats a [`ICU4XFixedDecimal`] to a string. - /// - /// See the [Rust documentation for `format`](https://docs.rs/icu/latest/icu/decimal/struct.FixedDecimalFormatter.html#method.format) for more information. - String formatWrite(ICU4XFixedDecimal value) { - final writeable = _Writeable(); - _ICU4XFixedDecimalFormatter_format_write( - _underlying, value._underlying, writeable._underlying); - return writeable.finalize(); - } - - // ignore: non_constant_identifier_names - static final _ICU4XFixedDecimalFormatter_format_write = _capi< - ffi.NativeFunction< - ffi.Void Function(ffi.Pointer, - ffi.Pointer, ffi.Pointer)>>( - 'ICU4XFixedDecimalFormatter_format_write') - .asFunction< - void Function(ffi.Pointer, ffi.Pointer, - ffi.Pointer)>(isLeaf: true); -} - -class _ICU4XFixedDecimalFormatterOptionsFfi extends ffi.Struct { - @ffi.Int32() - external int groupingStrategy; - @ffi.Bool() - external bool someOtherConfig; -} - -class ICU4XFixedDecimalFormatterOptions { - final _ICU4XFixedDecimalFormatterOptionsFfi _underlying; - - // ignore: unused_element - ICU4XFixedDecimalFormatterOptions._(this._underlying); - - factory ICU4XFixedDecimalFormatterOptions() { - final pointer = ffi2.calloc<_ICU4XFixedDecimalFormatterOptionsFfi>(); - final result = ICU4XFixedDecimalFormatterOptions._(pointer.ref); - _callocFree.attach(result, pointer.cast()); - return result; - } - - ICU4XFixedDecimalGroupingStrategy get groupingStrategy => - ICU4XFixedDecimalGroupingStrategy.values[_underlying.groupingStrategy]; - set groupingStrategy(ICU4XFixedDecimalGroupingStrategy groupingStrategy) { - _underlying.groupingStrategy = groupingStrategy.index; - } - - bool get someOtherConfig => _underlying.someOtherConfig; - set someOtherConfig(bool someOtherConfig) { - _underlying.someOtherConfig = someOtherConfig; - } - - factory ICU4XFixedDecimalFormatterOptions() { - final result = _ICU4XFixedDecimalFormatterOptions_default(); - return ICU4XFixedDecimalFormatterOptions._(result); - } - // ignore: non_constant_identifier_names - static final _ICU4XFixedDecimalFormatterOptions_default = _capi< - ffi.NativeFunction< - _ICU4XFixedDecimalFormatterOptionsFfi - Function()>>('ICU4XFixedDecimalFormatterOptions_default') - .asFunction<_ICU4XFixedDecimalFormatterOptionsFfi Function()>( - isLeaf: true); - - @override - bool operator ==(Object other) => - other is ICU4XFixedDecimalFormatterOptions && - other._underlying.groupingStrategy == _underlying.groupingStrategy && - other._underlying.someOtherConfig == _underlying.someOtherConfig; - - @override - int get hashCode => Object.hashAll([ - _underlying.groupingStrategy, - _underlying.someOtherConfig, - ]); -} - -enum ICU4XFixedDecimalGroupingStrategy { - /// Auto grouping - auto, - - /// No grouping - never, - - /// Always group - always, - - /// At least 2 groups - min2; -} - -/// An ICU4X Locale, capable of representing strings like `"en-US"`. -/// -/// See the [Rust documentation for `Locale`](https://docs.rs/icu/latest/icu/locid/struct.Locale.html) for more information. -class ICU4XLocale implements ffi.Finalizable { - final ffi.Pointer _underlying; - - ICU4XLocale._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('ICU4XLocale_destroy')); - - /// Construct an [`ICU4XLocale`] from a locale identifier represented as a string. - factory ICU4XLocale(String name) { - final alloc = ffi2.Arena(); - final nameSlice = _SliceFfi2Utf8._fromDart(name, alloc); - - final result = _ICU4XLocale_new(nameSlice._bytes, nameSlice._length); - alloc.releaseAll(); - return ICU4XLocale._(result); - } - // ignore: non_constant_identifier_names - static final _ICU4XLocale_new = _capi< - ffi.NativeFunction< - ffi.Pointer Function( - ffi.Pointer, ffi.Size)>>('ICU4XLocale_new') - .asFunction< - ffi.Pointer Function( - ffi.Pointer, int)>(isLeaf: true); - - /// Construct an [`ICU4XLocale`] from a locale identifier represented as bytes. - factory ICU4XLocale.fromBytes(Uint8List bytes) { - final alloc = ffi2.Arena(); - final bytesSlice = _SliceFfiUint8._fromDart(bytes, alloc); - - final result = - _ICU4XLocale_new_from_bytes(bytesSlice._bytes, bytesSlice._length); - alloc.releaseAll(); - return ICU4XLocale._(result); - } - // ignore: non_constant_identifier_names - static final _ICU4XLocale_new_from_bytes = _capi< - ffi.NativeFunction< - ffi.Pointer Function(ffi.Pointer, - ffi.Size)>>('ICU4XLocale_new_from_bytes') - .asFunction< - ffi.Pointer Function( - ffi.Pointer, int)>(isLeaf: true); -} - class _ResultOpaqueVoidUnion extends ffi.Union { external ffi.Pointer ok; } diff --git a/feature_tests/dart/lib/AttrEnum.g.dart b/feature_tests/dart/lib/AttrEnum.g.dart new file mode 100644 index 000000000..245e4abf5 --- /dev/null +++ b/feature_tests/dart/lib/AttrEnum.g.dart @@ -0,0 +1,12 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +enum AttrEnum { + a, + b, + c; +} diff --git a/feature_tests/dart/lib/AttrOpaque1.g.dart b/feature_tests/dart/lib/AttrOpaque1.g.dart new file mode 100644 index 000000000..9413ed240 --- /dev/null +++ b/feature_tests/dart/lib/AttrOpaque1.g.dart @@ -0,0 +1,36 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class AttrOpaque1 implements ffi.Finalizable { + final ffi.Pointer _underlying; + + AttrOpaque1._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('AttrOpaque1_destroy')); + + void method() { + _AttrOpaque1_method(_underlying); + } + + // ignore: non_constant_identifier_names + static final _AttrOpaque1_method = + _capi)>>( + 'AttrOpaque1_method') + .asFunction)>(isLeaf: true); + + void methodDisabledcpp() { + _AttrOpaque1_method_disabledcpp(_underlying); + } + + // ignore: non_constant_identifier_names + static final _AttrOpaque1_method_disabledcpp = + _capi)>>( + 'AttrOpaque1_method_disabledcpp') + .asFunction)>(isLeaf: true); +} diff --git a/feature_tests/dart/lib/AttrOpaque2.g.dart b/feature_tests/dart/lib/AttrOpaque2.g.dart new file mode 100644 index 000000000..b36045bf3 --- /dev/null +++ b/feature_tests/dart/lib/AttrOpaque2.g.dart @@ -0,0 +1,16 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class AttrOpaque2 implements ffi.Finalizable { + final ffi.Pointer _underlying; + + AttrOpaque2._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('AttrOpaque2_destroy')); +} diff --git a/feature_tests/dart/lib/Bar.g.dart b/feature_tests/dart/lib/Bar.g.dart new file mode 100644 index 000000000..ab0a9cdf4 --- /dev/null +++ b/feature_tests/dart/lib/Bar.g.dart @@ -0,0 +1,16 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class Bar implements ffi.Finalizable { + final ffi.Pointer _underlying; + + Bar._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('Bar_destroy')); +} diff --git a/feature_tests/dart/lib/BorrowedFields.g.dart b/feature_tests/dart/lib/BorrowedFields.g.dart new file mode 100644 index 000000000..e50b5f96c --- /dev/null +++ b/feature_tests/dart/lib/BorrowedFields.g.dart @@ -0,0 +1,53 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class _BorrowedFieldsFfi extends ffi.Struct { + external _SliceFfiUint16 a; + external _SliceFfi2Utf8 b; +} + +class BorrowedFields { + final _BorrowedFieldsFfi _underlying; + + // ignore: unused_element + BorrowedFields._(this._underlying); + + factory BorrowedFields() { + final pointer = ffi2.calloc<_BorrowedFieldsFfi>(); + final result = BorrowedFields._(pointer.ref); + _callocFree.attach(result, pointer.cast()); + return result; + } + + Uint16List get a => _underlying.a._asDart; + set a(Uint16List a) { + final alloc = ffi2.calloc; + alloc.free(_underlying.a._bytes); + final aSlice = _SliceFfiUint16._fromDart(a, alloc); + _underlying.a = aSlice; + } + + String get b => _underlying.b._asDart; + set b(String b) { + final alloc = ffi2.calloc; + alloc.free(_underlying.b._bytes); + final bSlice = _SliceFfi2Utf8._fromDart(b, alloc); + _underlying.b = bSlice; + } + + @override + bool operator ==(Object other) => + other is BorrowedFields && + other._underlying.a == _underlying.a && + other._underlying.b == _underlying.b; + + @override + int get hashCode => Object.hashAll([ + _underlying.a, + _underlying.b, + ]); +} diff --git a/feature_tests/dart/lib/BorrowedFieldsReturning.g.dart b/feature_tests/dart/lib/BorrowedFieldsReturning.g.dart new file mode 100644 index 000000000..b158b04bf --- /dev/null +++ b/feature_tests/dart/lib/BorrowedFieldsReturning.g.dart @@ -0,0 +1,42 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class _BorrowedFieldsReturningFfi extends ffi.Struct { + external _SliceFfiUint8 bytes; +} + +class BorrowedFieldsReturning { + final _BorrowedFieldsReturningFfi _underlying; + + // ignore: unused_element + BorrowedFieldsReturning._(this._underlying); + + factory BorrowedFieldsReturning() { + final pointer = ffi2.calloc<_BorrowedFieldsReturningFfi>(); + final result = BorrowedFieldsReturning._(pointer.ref); + _callocFree.attach(result, pointer.cast()); + return result; + } + + Uint8List get bytes => _underlying.bytes._asDart; + set bytes(Uint8List bytes) { + final alloc = ffi2.calloc; + alloc.free(_underlying.bytes._bytes); + final bytesSlice = _SliceFfiUint8._fromDart(bytes, alloc); + _underlying.bytes = bytesSlice; + } + + @override + bool operator ==(Object other) => + other is BorrowedFieldsReturning && + other._underlying.bytes == _underlying.bytes; + + @override + int get hashCode => Object.hashAll([ + _underlying.bytes, + ]); +} diff --git a/feature_tests/dart/lib/ContiguousEnum.g.dart b/feature_tests/dart/lib/ContiguousEnum.g.dart new file mode 100644 index 000000000..385f7e966 --- /dev/null +++ b/feature_tests/dart/lib/ContiguousEnum.g.dart @@ -0,0 +1,13 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +enum ContiguousEnum { + c, + d, + e, + f; +} diff --git a/feature_tests/dart/lib/ErrorEnum.g.dart b/feature_tests/dart/lib/ErrorEnum.g.dart new file mode 100644 index 000000000..17be3a38d --- /dev/null +++ b/feature_tests/dart/lib/ErrorEnum.g.dart @@ -0,0 +1,11 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +enum ErrorEnum { + foo, + bar; +} diff --git a/feature_tests/dart/lib/ErrorStruct.g.dart b/feature_tests/dart/lib/ErrorStruct.g.dart new file mode 100644 index 000000000..8fbbca964 --- /dev/null +++ b/feature_tests/dart/lib/ErrorStruct.g.dart @@ -0,0 +1,49 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class _ErrorStructFfi extends ffi.Struct { + @ffi.Int32() + external int i; + @ffi.Int32() + external int j; +} + +class ErrorStruct { + final _ErrorStructFfi _underlying; + + // ignore: unused_element + ErrorStruct._(this._underlying); + + factory ErrorStruct() { + final pointer = ffi2.calloc<_ErrorStructFfi>(); + final result = ErrorStruct._(pointer.ref); + _callocFree.attach(result, pointer.cast()); + return result; + } + + int get i => _underlying.i; + set i(int i) { + _underlying.i = i; + } + + int get j => _underlying.j; + set j(int j) { + _underlying.j = j; + } + + @override + bool operator ==(Object other) => + other is ErrorStruct && + other._underlying.i == _underlying.i && + other._underlying.j == _underlying.j; + + @override + int get hashCode => Object.hashAll([ + _underlying.i, + _underlying.j, + ]); +} diff --git a/feature_tests/dart/lib/Float64Vec.g.dart b/feature_tests/dart/lib/Float64Vec.g.dart new file mode 100644 index 000000000..fbe3f1580 --- /dev/null +++ b/feature_tests/dart/lib/Float64Vec.g.dart @@ -0,0 +1,68 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class Float64Vec implements ffi.Finalizable { + final ffi.Pointer _underlying; + + Float64Vec._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('Float64Vec_destroy')); + + factory Float64Vec(Float64List v) { + final alloc = ffi2.Arena(); + final vSlice = _SliceFfiDouble._fromDart(v, alloc); + + final result = _Float64Vec_new(vSlice._bytes, vSlice._length); + alloc.releaseAll(); + return Float64Vec._(result); + } + // ignore: non_constant_identifier_names + static final _Float64Vec_new = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Size)>>('Float64Vec_new') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, int)>(isLeaf: true); + + void fillSlice(Float64List v) { + final alloc = ffi2.Arena(); + final vSlice = _SliceFfiDouble._fromDart(v, alloc); + + _Float64Vec_fill_slice(_underlying, vSlice._bytes, vSlice._length); + alloc.releaseAll(); + } + + // ignore: non_constant_identifier_names + static final _Float64Vec_fill_slice = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, + ffi.Pointer, ffi.Size)>>('Float64Vec_fill_slice') + .asFunction< + void Function(ffi.Pointer, ffi.Pointer, + int)>(isLeaf: true); + + void setValue(Float64List newSlice) { + final alloc = ffi2.Arena(); + final newSliceSlice = _SliceFfiDouble._fromDart(newSlice, alloc); + + _Float64Vec_set_value( + _underlying, newSliceSlice._bytes, newSliceSlice._length); + alloc.releaseAll(); + } + + // ignore: non_constant_identifier_names + static final _Float64Vec_set_value = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, + ffi.Pointer, ffi.Size)>>('Float64Vec_set_value') + .asFunction< + void Function(ffi.Pointer, ffi.Pointer, + int)>(isLeaf: true); +} diff --git a/feature_tests/dart/lib/Foo.g.dart b/feature_tests/dart/lib/Foo.g.dart new file mode 100644 index 000000000..5a0a64f4f --- /dev/null +++ b/feature_tests/dart/lib/Foo.g.dart @@ -0,0 +1,89 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class Foo implements ffi.Finalizable { + final ffi.Pointer _underlying; + + Foo._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('Foo_destroy')); + + factory Foo(String x) { + final alloc = ffi2.Arena(); + final xSlice = _SliceFfi2Utf8._fromDart(x, alloc); + + final result = _Foo_new(xSlice._bytes, xSlice._length); + alloc.releaseAll(); + return Foo._(result); + } + // ignore: non_constant_identifier_names + static final _Foo_new = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Size)>>('Foo_new') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, int)>(isLeaf: true); + + Bar get getBar { + final result = _Foo_get_bar(_underlying); + return Bar._(result); + } + + // ignore: non_constant_identifier_names + static final _Foo_get_bar = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer)>>('Foo_get_bar') + .asFunction Function(ffi.Pointer)>( + isLeaf: true); + + factory Foo.static_(String x) { + final alloc = ffi2.Arena(); + final xSlice = _SliceFfi2Utf8._fromDart(x, alloc); + + final result = _Foo_new_static(xSlice._bytes, xSlice._length); + alloc.releaseAll(); + return Foo._(result); + } + // ignore: non_constant_identifier_names + static final _Foo_new_static = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Size)>>('Foo_new_static') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, int)>(isLeaf: true); + + BorrowedFieldsReturning get asReturning { + final result = _Foo_as_returning(_underlying); + return BorrowedFieldsReturning._(result); + } + + // ignore: non_constant_identifier_names + static final _Foo_as_returning = _capi< + ffi.NativeFunction< + _BorrowedFieldsReturningFfi Function( + ffi.Pointer)>>('Foo_as_returning') + .asFunction< + _BorrowedFieldsReturningFfi Function( + ffi.Pointer)>(isLeaf: true); + + factory Foo.extractFromFields(BorrowedFields fields) { + final result = _Foo_extract_from_fields(fields._underlying); + return Foo._(result); + } + // ignore: non_constant_identifier_names + static final _Foo_extract_from_fields = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + _BorrowedFieldsFfi)>>('Foo_extract_from_fields') + .asFunction Function(_BorrowedFieldsFfi)>( + isLeaf: true); +} diff --git a/feature_tests/dart/lib/ImportedStruct.g.dart b/feature_tests/dart/lib/ImportedStruct.g.dart new file mode 100644 index 000000000..92106acc1 --- /dev/null +++ b/feature_tests/dart/lib/ImportedStruct.g.dart @@ -0,0 +1,49 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class _ImportedStructFfi extends ffi.Struct { + @ffi.Int32() + external int foo; + @ffi.Uint8() + external int count; +} + +class ImportedStruct { + final _ImportedStructFfi _underlying; + + // ignore: unused_element + ImportedStruct._(this._underlying); + + factory ImportedStruct() { + final pointer = ffi2.calloc<_ImportedStructFfi>(); + final result = ImportedStruct._(pointer.ref); + _callocFree.attach(result, pointer.cast()); + return result; + } + + UnimportedEnum get foo => UnimportedEnum.values[_underlying.foo]; + set foo(UnimportedEnum foo) { + _underlying.foo = foo.index; + } + + int get count => _underlying.count; + set count(int count) { + _underlying.count = count; + } + + @override + bool operator ==(Object other) => + other is ImportedStruct && + other._underlying.foo == _underlying.foo && + other._underlying.count == _underlying.count; + + @override + int get hashCode => Object.hashAll([ + _underlying.foo, + _underlying.count, + ]); +} diff --git a/feature_tests/dart/lib/MyEnum.g.dart b/feature_tests/dart/lib/MyEnum.g.dart new file mode 100644 index 000000000..c6235f8c3 --- /dev/null +++ b/feature_tests/dart/lib/MyEnum.g.dart @@ -0,0 +1,43 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +enum MyEnum { + a, + b, + c, + d, + e, + f; + + int get _underlying { + switch (this) { + case a: + return -2; + case b: + return -1; + case c: + return 0; + case d: + return 1; + case e: + return 2; + case f: + return 3; + } + } + + int intoValue() { + final result = _MyEnum_into_value(_underlying); + return result; + } + + // ignore: non_constant_identifier_names + static final _MyEnum_into_value = + _capi>( + 'MyEnum_into_value') + .asFunction(isLeaf: true); +} diff --git a/feature_tests/dart/lib/MyString.g.dart b/feature_tests/dart/lib/MyString.g.dart new file mode 100644 index 000000000..f50b561a1 --- /dev/null +++ b/feature_tests/dart/lib/MyString.g.dart @@ -0,0 +1,65 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class MyString implements ffi.Finalizable { + final ffi.Pointer _underlying; + + MyString._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('MyString_destroy')); + + factory MyString(String v) { + final alloc = ffi2.Arena(); + final vSlice = _SliceFfi2Utf8._fromDart(v, alloc); + + final result = _MyString_new(vSlice._bytes, vSlice._length); + alloc.releaseAll(); + return MyString._(result); + } + // ignore: non_constant_identifier_names + static final _MyString_new = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Size)>>('MyString_new') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, int)>(isLeaf: true); + + void setStr(String newStr) { + final alloc = ffi2.Arena(); + final newStrSlice = _SliceFfi2Utf8._fromDart(newStr, alloc); + + _MyString_set_str(_underlying, newStrSlice._bytes, newStrSlice._length); + alloc.releaseAll(); + } + + // ignore: non_constant_identifier_names + static final _MyString_set_str = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, ffi.Pointer, + ffi.Size)>>('MyString_set_str') + .asFunction< + void Function(ffi.Pointer, ffi.Pointer, + int)>(isLeaf: true); + + String get getStr { + final writeable = _Writeable(); + _MyString_get_str(_underlying, writeable._underlying); + return writeable.finalize(); + } + + // ignore: non_constant_identifier_names + static final _MyString_get_str = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, + ffi.Pointer)>>('MyString_get_str') + .asFunction< + void Function( + ffi.Pointer, ffi.Pointer)>(isLeaf: true); +} diff --git a/feature_tests/dart/lib/MyStruct.g.dart b/feature_tests/dart/lib/MyStruct.g.dart new file mode 100644 index 000000000..1f8ea2c02 --- /dev/null +++ b/feature_tests/dart/lib/MyStruct.g.dart @@ -0,0 +1,115 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class _MyStructFfi extends ffi.Struct { + @ffi.Uint8() + external int a; + @ffi.Bool() + external bool b; + @ffi.Uint8() + external int c; + @ffi.Uint64() + external int d; + @ffi.Int32() + external int e; + @ffi.Uint32() + external int f; + @ffi.Int32() + external int g; +} + +class MyStruct { + final _MyStructFfi _underlying; + + // ignore: unused_element + MyStruct._(this._underlying); + + factory MyStruct() { + final pointer = ffi2.calloc<_MyStructFfi>(); + final result = MyStruct._(pointer.ref); + _callocFree.attach(result, pointer.cast()); + return result; + } + + int get a => _underlying.a; + set a(int a) { + _underlying.a = a; + } + + bool get b => _underlying.b; + set b(bool b) { + _underlying.b = b; + } + + int get c => _underlying.c; + set c(int c) { + _underlying.c = c; + } + + int get d => _underlying.d; + set d(int d) { + _underlying.d = d; + } + + int get e => _underlying.e; + set e(int e) { + _underlying.e = e; + } + + int get f => _underlying.f; + set f(int f) { + _underlying.f = f; + } + + MyEnum get g => + MyEnum.values.firstWhere((v) => v._underlying == _underlying.g); + set g(MyEnum g) { + _underlying.g = g._underlying; + } + + factory MyStruct() { + final result = _MyStruct_new(); + return MyStruct._(result); + } + // ignore: non_constant_identifier_names + static final _MyStruct_new = + _capi>('MyStruct_new') + .asFunction<_MyStructFfi Function()>(isLeaf: true); + + int intoA() { + final result = _MyStruct_into_a(_underlying); + return result; + } + + // ignore: non_constant_identifier_names + static final _MyStruct_into_a = + _capi>( + 'MyStruct_into_a') + .asFunction(isLeaf: true); + + @override + bool operator ==(Object other) => + other is MyStruct && + other._underlying.a == _underlying.a && + other._underlying.b == _underlying.b && + other._underlying.c == _underlying.c && + other._underlying.d == _underlying.d && + other._underlying.e == _underlying.e && + other._underlying.f == _underlying.f && + other._underlying.g == _underlying.g; + + @override + int get hashCode => Object.hashAll([ + _underlying.a, + _underlying.b, + _underlying.c, + _underlying.d, + _underlying.e, + _underlying.f, + _underlying.g, + ]); +} diff --git a/feature_tests/dart/lib/One.g.dart b/feature_tests/dart/lib/One.g.dart new file mode 100644 index 000000000..c3d07f97b --- /dev/null +++ b/feature_tests/dart/lib/One.g.dart @@ -0,0 +1,217 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class One implements ffi.Finalizable { + final ffi.Pointer _underlying; + + One._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('One_destroy')); + + factory One.transitivity(One hold, One nohold) { + final result = _One_transitivity(hold._underlying, nohold._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_transitivity = _capi< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>('One_transitivity') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(isLeaf: true); + + factory One.cycle(Two hold, One nohold) { + final result = _One_cycle(hold._underlying, nohold._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_cycle = _capi< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>('One_cycle') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(isLeaf: true); + + factory One.manyDependents(One a, One b, Two c, Two d, Two nohold) { + final result = _One_many_dependents(a._underlying, b._underlying, + c._underlying, d._underlying, nohold._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_many_dependents = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('One_many_dependents') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(isLeaf: true); + + factory One.returnOutlivesParam(Two hold, One nohold) { + final result = + _One_return_outlives_param(hold._underlying, nohold._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_return_outlives_param = _capi< + ffi.NativeFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer)>>('One_return_outlives_param') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>(isLeaf: true); + + factory One.diamondTop(One top, One left, One right, One bottom) { + final result = _One_diamond_top(top._underlying, left._underlying, + right._underlying, bottom._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_diamond_top = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('One_diamond_top') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(isLeaf: true); + + factory One.diamondLeft(One top, One left, One right, One bottom) { + final result = _One_diamond_left(top._underlying, left._underlying, + right._underlying, bottom._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_diamond_left = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('One_diamond_left') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(isLeaf: true); + + factory One.diamondRight(One top, One left, One right, One bottom) { + final result = _One_diamond_right(top._underlying, left._underlying, + right._underlying, bottom._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_diamond_right = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('One_diamond_right') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(isLeaf: true); + + factory One.diamondBottom(One top, One left, One right, One bottom) { + final result = _One_diamond_bottom(top._underlying, left._underlying, + right._underlying, bottom._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_diamond_bottom = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('One_diamond_bottom') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(isLeaf: true); + + factory One.diamondAndNestedTypes(One a, One b, One c, One d, One nohold) { + final result = _One_diamond_and_nested_types(a._underlying, b._underlying, + c._underlying, d._underlying, nohold._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_diamond_and_nested_types = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('One_diamond_and_nested_types') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(isLeaf: true); + + factory One.implicitBounds(One explicitHold, One implicitHold, One nohold) { + final result = _One_implicit_bounds( + explicitHold._underlying, implicitHold._underlying, nohold._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_implicit_bounds = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('One_implicit_bounds') + .asFunction< + ffi.Pointer Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(isLeaf: true); + + factory One.implicitBoundsDeep( + One explicit, One implicit1, One implicit2, One nohold) { + final result = _One_implicit_bounds_deep(explicit._underlying, + implicit1._underlying, implicit2._underlying, nohold._underlying); + return One._(result); + } + // ignore: non_constant_identifier_names + static final _One_implicit_bounds_deep = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>('One_implicit_bounds_deep') + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(isLeaf: true); +} diff --git a/feature_tests/dart/lib/Opaque.g.dart b/feature_tests/dart/lib/Opaque.g.dart new file mode 100644 index 000000000..4e2038cc1 --- /dev/null +++ b/feature_tests/dart/lib/Opaque.g.dart @@ -0,0 +1,52 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class Opaque implements ffi.Finalizable { + final ffi.Pointer _underlying; + + Opaque._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('Opaque_destroy')); + + factory Opaque() { + final result = _Opaque_new(); + return Opaque._(result); + } + // ignore: non_constant_identifier_names + static final _Opaque_new = + _capi Function()>>( + 'Opaque_new') + .asFunction Function()>(isLeaf: true); + + /// See the [Rust documentation for `something`](https://docs.rs/Something/latest/struct.Something.html#method.something) for more information. + /// + /// See the [Rust documentation for `something_else`](https://docs.rs/Something/latest/struct.Something.html#method.something_else) for more information. + /// + /// Additional information: [1](https://docs.rs/Something/latest/struct.Something.html#method.something_small), [2](https://docs.rs/SomethingElse/latest/struct.SomethingElse.html#method.something) + void assertStruct(MyStruct s) { + _Opaque_assert_struct(_underlying, s._underlying); + } + + // ignore: non_constant_identifier_names + static final _Opaque_assert_struct = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, + _MyStructFfi)>>('Opaque_assert_struct') + .asFunction, _MyStructFfi)>( + isLeaf: true); + + static final int returnsUsize = + _capi>('Opaque_returns_usize') + .asFunction(isLeaf: true)(); + + static final ImportedStruct returnsImported = + _capi>( + 'Opaque_returns_imported') + .asFunction<_ImportedStructFfi Function()>(isLeaf: true)(); +} diff --git a/feature_tests/dart/lib/OptionOpaque.g.dart b/feature_tests/dart/lib/OptionOpaque.g.dart new file mode 100644 index 000000000..c543bfe81 --- /dev/null +++ b/feature_tests/dart/lib/OptionOpaque.g.dart @@ -0,0 +1,61 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + + +class OptionOpaque implements ffi.Finalizable { + + final ffi.Pointer _underlying; + + OptionOpaque._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('OptionOpaque_destroy')); + + +static OptionOpaque? new_(int i) { + + final result = _OptionOpaque_new(i); + return result.address == 0 ? null : OptionOpaque._(result); + } + // ignore: non_constant_identifier_names + static final _OptionOpaque_new= _capi Function(ffi.Int32)>>('OptionOpaque_new') + .asFunction Function(int)>(isLeaf: true); + + + +static final OptionOpaque? none = _capi Function()>>('OptionOpaque_new_none').asFunction Function()>(isLeaf: true)(); + + +static final OptionStruct struct = _capi>('OptionOpaque_new_struct').asFunction<_OptionStructFfi Function()>(isLeaf: true)(); + + +static final OptionStruct structNones = _capi>('OptionOpaque_new_struct_nones').asFunction<_OptionStructFfi Function()>(isLeaf: true)(); + + +void assertInteger(int i) { + + _OptionOpaque_assert_integer(_underlying,i); + } + // ignore: non_constant_identifier_names + static final _OptionOpaque_assert_integer= _capi, ffi.Int32)>>('OptionOpaque_assert_integer') + .asFunction, int)>(isLeaf: true); + + + +static bool optionOpaqueArgument(OptionOpaque? arg) { + + final result = _OptionOpaque_option_opaque_argument(arg == null ? ffi.Pointer.fromAddress(0) ? arg._underlying); + return result; + } + // ignore: non_constant_identifier_names + static final _OptionOpaque_option_opaque_argument= _capi)>>('OptionOpaque_option_opaque_argument') + .asFunction)>(isLeaf: true); + + + } + diff --git a/feature_tests/dart/lib/OptionOpaqueChar.g.dart b/feature_tests/dart/lib/OptionOpaqueChar.g.dart new file mode 100644 index 000000000..a6989f4f6 --- /dev/null +++ b/feature_tests/dart/lib/OptionOpaqueChar.g.dart @@ -0,0 +1,28 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class OptionOpaqueChar implements ffi.Finalizable { + final ffi.Pointer _underlying; + + OptionOpaqueChar._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = + ffi.NativeFinalizer(_capi('OptionOpaqueChar_destroy')); + + void assertChar(int ch) { + _OptionOpaqueChar_assert_char(_underlying, ch); + } + + // ignore: non_constant_identifier_names + static final _OptionOpaqueChar_assert_char = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, + ffi.Uint32)>>('OptionOpaqueChar_assert_char') + .asFunction, int)>(isLeaf: true); +} diff --git a/feature_tests/dart/lib/OptionStruct.g.dart b/feature_tests/dart/lib/OptionStruct.g.dart new file mode 100644 index 000000000..c2cbf62d6 --- /dev/null +++ b/feature_tests/dart/lib/OptionStruct.g.dart @@ -0,0 +1,59 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + + +class _OptionStructFfi extends ffi.Struct { + external ffi.Pointer a; + external ffi.Pointer b; + @ffi.Uint32() + external int c; + external ffi.Pointer d; +} + +class OptionStruct { + final _OptionStructFfi _underlying; + + // ignore: unused_element + OptionStruct._(this._underlying); + + factory OptionStruct() { + final pointer = ffi2.calloc<_OptionStructFfi>(); + final result = OptionStruct._(pointer.ref); + _callocFree.attach(result, pointer.cast()); + return result; + } + + OptionOpaque? get a => _underlying.a.address == 0 ? null : OptionOpaque._(_underlying.a); + set a(OptionOpaque? a) { + _underlying.a = a == null ? ffi.Pointer.fromAddress(0) ? a._underlying; + } +OptionOpaqueChar? get b => _underlying.b.address == 0 ? null : OptionOpaqueChar._(_underlying.b); + set b(OptionOpaqueChar? b) { + _underlying.b = b == null ? ffi.Pointer.fromAddress(0) ? b._underlying; + } +int get c => _underlying.c; + set c(int c) { + _underlying.c = c; + } +OptionOpaque? get d => _underlying.d.address == 0 ? null : OptionOpaque._(_underlying.d); + set d(OptionOpaque? d) { + _underlying.d = d == null ? ffi.Pointer.fromAddress(0) ? d._underlying; + } + + + @override + bool operator ==(Object other) => + other is OptionStruct + && other._underlying.a == _underlying.a + && other._underlying.b == _underlying.b + && other._underlying.c == _underlying.c + && other._underlying.d == _underlying.d; + + @override + int get hashCode => Object.hashAll([_underlying.a,_underlying.b,_underlying.c,_underlying.d,]); +} + diff --git a/feature_tests/dart/lib/RefList.g.dart b/feature_tests/dart/lib/RefList.g.dart new file mode 100644 index 000000000..d6e699adb --- /dev/null +++ b/feature_tests/dart/lib/RefList.g.dart @@ -0,0 +1,28 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class RefList implements ffi.Finalizable { + final ffi.Pointer _underlying; + + RefList._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('RefList_destroy')); + + factory RefList.node(RefListParameter data) { + final result = _RefList_node(data._underlying); + return RefList._(result); + } + // ignore: non_constant_identifier_names + static final _RefList_node = _capi< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer)>>('RefList_node') + .asFunction Function(ffi.Pointer)>( + isLeaf: true); +} diff --git a/feature_tests/dart/lib/RefListParameter.g.dart b/feature_tests/dart/lib/RefListParameter.g.dart new file mode 100644 index 000000000..ea2c61018 --- /dev/null +++ b/feature_tests/dart/lib/RefListParameter.g.dart @@ -0,0 +1,17 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class RefListParameter implements ffi.Finalizable { + final ffi.Pointer _underlying; + + RefListParameter._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = + ffi.NativeFinalizer(_capi('RefListParameter_destroy')); +} diff --git a/feature_tests/dart/lib/ResultOpaque.g.dart b/feature_tests/dart/lib/ResultOpaque.g.dart new file mode 100644 index 000000000..f28df4eca --- /dev/null +++ b/feature_tests/dart/lib/ResultOpaque.g.dart @@ -0,0 +1,123 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class ResultOpaque implements ffi.Finalizable { + final ffi.Pointer _underlying; + + ResultOpaque._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('ResultOpaque_destroy')); + + factory ResultOpaque(int i) { + final result = _ResultOpaque_new(i); + return result.isOk + ? ResultOpaque._(result.union.ok) + : throw ErrorEnum.values[result.union.err]; + } + // ignore: non_constant_identifier_names + static final _ResultOpaque_new = + _capi>( + 'ResultOpaque_new') + .asFunction<_ResultOpaqueInt32 Function(int)>(isLeaf: true); + + factory ResultOpaque.failingFoo() { + final result = _ResultOpaque_new_failing_foo(); + return result.isOk + ? ResultOpaque._(result.union.ok) + : throw ErrorEnum.values[result.union.err]; + } + // ignore: non_constant_identifier_names + static final _ResultOpaque_new_failing_foo = + _capi>( + 'ResultOpaque_new_failing_foo') + .asFunction<_ResultOpaqueInt32 Function()>(isLeaf: true); + + factory ResultOpaque.failingBar() { + final result = _ResultOpaque_new_failing_bar(); + return result.isOk + ? ResultOpaque._(result.union.ok) + : throw ErrorEnum.values[result.union.err]; + } + // ignore: non_constant_identifier_names + static final _ResultOpaque_new_failing_bar = + _capi>( + 'ResultOpaque_new_failing_bar') + .asFunction<_ResultOpaqueInt32 Function()>(isLeaf: true); + + factory ResultOpaque.failingUnit() { + final result = _ResultOpaque_new_failing_unit(); + return result.isOk ? ResultOpaque._(result.union.ok) : throw VoidError(); + } + // ignore: non_constant_identifier_names + static final _ResultOpaque_new_failing_unit = + _capi>( + 'ResultOpaque_new_failing_unit') + .asFunction<_ResultOpaqueVoid Function()>(isLeaf: true); + + factory ResultOpaque.failingStruct(int i) { + final result = _ResultOpaque_new_failing_struct(i); + return result.isOk + ? ResultOpaque._(result.union.ok) + : throw ErrorStruct._(result.union.err); + } + // ignore: non_constant_identifier_names + static final _ResultOpaque_new_failing_struct = _capi< + ffi + .NativeFunction<_ResultOpaqueErrorStructFfi Function(ffi.Int32)>>( + 'ResultOpaque_new_failing_struct') + .asFunction<_ResultOpaqueErrorStructFfi Function(int)>(isLeaf: true); + + static void newInErr(int i) { + final result = _ResultOpaque_new_in_err(i); + if (!result.isOk) { + throw ResultOpaque._(result.union.err); + } + } + + // ignore: non_constant_identifier_names + static final _ResultOpaque_new_in_err = + _capi>( + 'ResultOpaque_new_in_err') + .asFunction<_ResultVoidOpaque Function(int)>(isLeaf: true); + + static int newInt(int i) { + final result = _ResultOpaque_new_int(i); + return result.isOk ? result.union.ok : throw VoidError(); + } + + // ignore: non_constant_identifier_names + static final _ResultOpaque_new_int = + _capi>( + 'ResultOpaque_new_int') + .asFunction<_ResultInt32Void Function(int)>(isLeaf: true); + + static ErrorEnum newInEnumErr(int i) { + final result = _ResultOpaque_new_in_enum_err(i); + return result.isOk + ? ErrorEnum.values[result.union.ok] + : throw ResultOpaque._(result.union.err); + } + + // ignore: non_constant_identifier_names + static final _ResultOpaque_new_in_enum_err = + _capi>( + 'ResultOpaque_new_in_enum_err') + .asFunction<_ResultInt32Opaque Function(int)>(isLeaf: true); + + void assertInteger(int i) { + _ResultOpaque_assert_integer(_underlying, i); + } + + // ignore: non_constant_identifier_names + static final _ResultOpaque_assert_integer = _capi< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer, + ffi.Int32)>>('ResultOpaque_assert_integer') + .asFunction, int)>(isLeaf: true); +} diff --git a/feature_tests/dart/lib/Two.g.dart b/feature_tests/dart/lib/Two.g.dart new file mode 100644 index 000000000..10b69fc73 --- /dev/null +++ b/feature_tests/dart/lib/Two.g.dart @@ -0,0 +1,16 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +class Two implements ffi.Finalizable { + final ffi.Pointer _underlying; + + Two._(this._underlying) { + _finalizer.attach(this, _underlying.cast()); + } + + static final _finalizer = ffi.NativeFinalizer(_capi('Two_destroy')); +} diff --git a/feature_tests/dart/lib/UnimportedEnum.g.dart b/feature_tests/dart/lib/UnimportedEnum.g.dart new file mode 100644 index 000000000..3c9c55229 --- /dev/null +++ b/feature_tests/dart/lib/UnimportedEnum.g.dart @@ -0,0 +1,12 @@ +// generated by diplomat-tool + +// https://github.com/dart-lang/sdk/issues/53946 +// ignore_for_file: non_native_function_type_argument_to_pointer + +part of 'lib.g.dart'; + +enum UnimportedEnum { + a, + b, + c; +} diff --git a/feature_tests/dart/lib/lib.g.dart b/feature_tests/dart/lib/lib.g.dart index c4b5b9a66..d7f3e69fe 100644 --- a/feature_tests/dart/lib/lib.g.dart +++ b/feature_tests/dart/lib/lib.g.dart @@ -7,1110 +7,110 @@ import 'dart:convert'; import 'dart:ffi' as ffi; import 'dart:typed_data'; import 'package:ffi/ffi.dart' as ffi2; +part 'AttrEnum.g.dart'; +part 'AttrOpaque1.g.dart'; +part 'AttrOpaque2.g.dart'; +part 'Bar.g.dart'; +part 'BorrowedFields.g.dart'; +part 'BorrowedFieldsReturning.g.dart'; +part 'ContiguousEnum.g.dart'; +part 'ErrorEnum.g.dart'; +part 'ErrorStruct.g.dart'; +part 'Float64Vec.g.dart'; +part 'Foo.g.dart'; +part 'ImportedStruct.g.dart'; +part 'MyEnum.g.dart'; +part 'MyString.g.dart'; +part 'MyStruct.g.dart'; +part 'One.g.dart'; +part 'Opaque.g.dart'; +part 'OptionOpaque.g.dart'; +part 'OptionOpaqueChar.g.dart'; +part 'OptionStruct.g.dart'; +part 'RefList.g.dart'; +part 'RefListParameter.g.dart'; +part 'ResultOpaque.g.dart'; +part 'Two.g.dart'; +part 'UnimportedEnum.g.dart'; late final ffi.Pointer Function(String) _capi; void init(String path) => _capi = ffi.DynamicLibrary.open(path).lookup; final _callocFree = Finalizer(ffi2.calloc.free); - -enum AttrEnum { - a, - b, - c; -} - - -class AttrOpaque1 implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - AttrOpaque1._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('AttrOpaque1_destroy')); - - -void method() { - - _AttrOpaque1_method(_underlying); - } - // ignore: non_constant_identifier_names - static final _AttrOpaque1_method= _capi)>>('AttrOpaque1_method') - .asFunction)>(isLeaf: true); - - - -void methodDisabledcpp() { - - _AttrOpaque1_method_disabledcpp(_underlying); - } - // ignore: non_constant_identifier_names - static final _AttrOpaque1_method_disabledcpp= _capi)>>('AttrOpaque1_method_disabledcpp') - .asFunction)>(isLeaf: true); - - - } - - -class AttrOpaque2 implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - AttrOpaque2._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('AttrOpaque2_destroy')); - - } - - -class Bar implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - Bar._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('Bar_destroy')); - - } - - -class _BorrowedFieldsFfi extends ffi.Struct { - external _SliceFfiUint16 a; - external _SliceFfi2Utf8 b; -} - -class BorrowedFields { - final _BorrowedFieldsFfi _underlying; - - // ignore: unused_element - BorrowedFields._(this._underlying); - - factory BorrowedFields() { - final pointer = ffi2.calloc<_BorrowedFieldsFfi>(); - final result = BorrowedFields._(pointer.ref); - _callocFree.attach(result, pointer.cast()); - return result; - } - - Uint16List get a => _underlying.a._asDart; - set a(Uint16List a) { - final alloc = ffi2.calloc; - alloc.free(_underlying.a._bytes); - final aSlice = _SliceFfiUint16._fromDart(a, alloc); - _underlying.a = aSlice; - } -String get b => _underlying.b._asDart; - set b(String b) { - final alloc = ffi2.calloc; - alloc.free(_underlying.b._bytes); - final bSlice = _SliceFfi2Utf8._fromDart(b, alloc); - _underlying.b = bSlice; - } - - - @override - bool operator ==(Object other) => - other is BorrowedFields - && other._underlying.a == _underlying.a - && other._underlying.b == _underlying.b; - - @override - int get hashCode => Object.hashAll([_underlying.a,_underlying.b,]); -} - - -class _BorrowedFieldsReturningFfi extends ffi.Struct { - external _SliceFfiUint8 bytes; -} - -class BorrowedFieldsReturning { - final _BorrowedFieldsReturningFfi _underlying; - - // ignore: unused_element - BorrowedFieldsReturning._(this._underlying); - - factory BorrowedFieldsReturning() { - final pointer = ffi2.calloc<_BorrowedFieldsReturningFfi>(); - final result = BorrowedFieldsReturning._(pointer.ref); - _callocFree.attach(result, pointer.cast()); - return result; - } - - Uint8List get bytes => _underlying.bytes._asDart; - set bytes(Uint8List bytes) { - final alloc = ffi2.calloc; - alloc.free(_underlying.bytes._bytes); - final bytesSlice = _SliceFfiUint8._fromDart(bytes, alloc); - _underlying.bytes = bytesSlice; - } - - - @override - bool operator ==(Object other) => - other is BorrowedFieldsReturning - && other._underlying.bytes == _underlying.bytes; - - @override - int get hashCode => Object.hashAll([_underlying.bytes,]); -} - - -enum ContiguousEnum { - c, - d, - e, - f; -} - - -enum ErrorEnum { - foo, - bar; -} - - -class _ErrorStructFfi extends ffi.Struct { - @ffi.Int32() - external int i; - @ffi.Int32() - external int j; -} - -class ErrorStruct { - final _ErrorStructFfi _underlying; - - // ignore: unused_element - ErrorStruct._(this._underlying); - - factory ErrorStruct() { - final pointer = ffi2.calloc<_ErrorStructFfi>(); - final result = ErrorStruct._(pointer.ref); - _callocFree.attach(result, pointer.cast()); - return result; - } - - int get i => _underlying.i; - set i(int i) { - _underlying.i = i; - } -int get j => _underlying.j; - set j(int j) { - _underlying.j = j; - } - - - @override - bool operator ==(Object other) => - other is ErrorStruct - && other._underlying.i == _underlying.i - && other._underlying.j == _underlying.j; - - @override - int get hashCode => Object.hashAll([_underlying.i,_underlying.j,]); -} - - -class Float64Vec implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - Float64Vec._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('Float64Vec_destroy')); - - -factory Float64Vec(Float64List v) { - final alloc = ffi2.Arena(); - final vSlice = _SliceFfiDouble._fromDart(v, alloc); - - final result = _Float64Vec_new(vSlice._bytes,vSlice._length);alloc.releaseAll(); - return Float64Vec._(result); - } - // ignore: non_constant_identifier_names - static final _Float64Vec_new= _capi Function(ffi.Pointer, ffi.Size)>>('Float64Vec_new') - .asFunction Function(ffi.Pointer, int)>(isLeaf: true); - - - -void fillSlice(Float64List v) { - final alloc = ffi2.Arena(); - final vSlice = _SliceFfiDouble._fromDart(v, alloc); - - _Float64Vec_fill_slice(_underlying,vSlice._bytes,vSlice._length);alloc.releaseAll(); - } - // ignore: non_constant_identifier_names - static final _Float64Vec_fill_slice= _capi, ffi.Pointer, ffi.Size)>>('Float64Vec_fill_slice') - .asFunction, ffi.Pointer, int)>(isLeaf: true); - - - -void setValue(Float64List newSlice) { - final alloc = ffi2.Arena(); - final newSliceSlice = _SliceFfiDouble._fromDart(newSlice, alloc); - - _Float64Vec_set_value(_underlying,newSliceSlice._bytes,newSliceSlice._length);alloc.releaseAll(); - } - // ignore: non_constant_identifier_names - static final _Float64Vec_set_value= _capi, ffi.Pointer, ffi.Size)>>('Float64Vec_set_value') - .asFunction, ffi.Pointer, int)>(isLeaf: true); - - - } - - -class Foo implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - Foo._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('Foo_destroy')); - - -factory Foo(String x) { - final alloc = ffi2.Arena(); - final xSlice = _SliceFfi2Utf8._fromDart(x, alloc); - - final result = _Foo_new(xSlice._bytes,xSlice._length);alloc.releaseAll(); - return Foo._(result); - } - // ignore: non_constant_identifier_names - static final _Foo_new= _capi Function(ffi.Pointer, ffi.Size)>>('Foo_new') - .asFunction Function(ffi.Pointer, int)>(isLeaf: true); - - - -Bar get getBar { - - final result = _Foo_get_bar(_underlying); - return Bar._(result); - } - // ignore: non_constant_identifier_names - static final _Foo_get_bar= _capi Function(ffi.Pointer)>>('Foo_get_bar') - .asFunction Function(ffi.Pointer)>(isLeaf: true); - - - -factory Foo.static_(String x) { - final alloc = ffi2.Arena(); - final xSlice = _SliceFfi2Utf8._fromDart(x, alloc); - - final result = _Foo_new_static(xSlice._bytes,xSlice._length);alloc.releaseAll(); - return Foo._(result); - } - // ignore: non_constant_identifier_names - static final _Foo_new_static= _capi Function(ffi.Pointer, ffi.Size)>>('Foo_new_static') - .asFunction Function(ffi.Pointer, int)>(isLeaf: true); - - - -BorrowedFieldsReturning get asReturning { - - final result = _Foo_as_returning(_underlying); - return BorrowedFieldsReturning._(result); - } - // ignore: non_constant_identifier_names - static final _Foo_as_returning= _capi)>>('Foo_as_returning') - .asFunction<_BorrowedFieldsReturningFfi Function(ffi.Pointer)>(isLeaf: true); - - - -factory Foo.extractFromFields(BorrowedFields fields) { - - final result = _Foo_extract_from_fields(fields._underlying); - return Foo._(result); - } - // ignore: non_constant_identifier_names - static final _Foo_extract_from_fields= _capi Function(_BorrowedFieldsFfi)>>('Foo_extract_from_fields') - .asFunction Function(_BorrowedFieldsFfi)>(isLeaf: true); - - - } - - -class _ImportedStructFfi extends ffi.Struct { - @ffi.Int32() - external int foo; - @ffi.Uint8() - external int count; -} - -class ImportedStruct { - final _ImportedStructFfi _underlying; - - // ignore: unused_element - ImportedStruct._(this._underlying); - - factory ImportedStruct() { - final pointer = ffi2.calloc<_ImportedStructFfi>(); - final result = ImportedStruct._(pointer.ref); - _callocFree.attach(result, pointer.cast()); - return result; - } - - UnimportedEnum get foo => UnimportedEnum.values[_underlying.foo]; - set foo(UnimportedEnum foo) { - _underlying.foo = foo.index; - } -int get count => _underlying.count; - set count(int count) { - _underlying.count = count; - } - - - @override - bool operator ==(Object other) => - other is ImportedStruct - && other._underlying.foo == _underlying.foo - && other._underlying.count == _underlying.count; - - @override - int get hashCode => Object.hashAll([_underlying.foo,_underlying.count,]); -} - - -enum MyEnum { - a, - b, - c, - d, - e, - f; - - int get _underlying { - switch (this) { - case a: - return -2; - case b: - return -1; - case c: - return 0; - case d: - return 1; - case e: - return 2; - case f: - return 3; - } - } - - - -int intoValue() { - - final result = _MyEnum_into_value(_underlying); - return result; - } - // ignore: non_constant_identifier_names - static final _MyEnum_into_value= _capi>('MyEnum_into_value') - .asFunction(isLeaf: true); - - -} - - -class MyString implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - MyString._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('MyString_destroy')); - - -factory MyString(String v) { - final alloc = ffi2.Arena(); - final vSlice = _SliceFfi2Utf8._fromDart(v, alloc); - - final result = _MyString_new(vSlice._bytes,vSlice._length);alloc.releaseAll(); - return MyString._(result); - } - // ignore: non_constant_identifier_names - static final _MyString_new= _capi Function(ffi.Pointer, ffi.Size)>>('MyString_new') - .asFunction Function(ffi.Pointer, int)>(isLeaf: true); - - - -void setStr(String newStr) { - final alloc = ffi2.Arena(); - final newStrSlice = _SliceFfi2Utf8._fromDart(newStr, alloc); - - _MyString_set_str(_underlying,newStrSlice._bytes,newStrSlice._length);alloc.releaseAll(); - } - // ignore: non_constant_identifier_names - static final _MyString_set_str= _capi, ffi.Pointer, ffi.Size)>>('MyString_set_str') - .asFunction, ffi.Pointer, int)>(isLeaf: true); - - - -String get getStr { - - final writeable = _Writeable(); - _MyString_get_str(_underlying,writeable._underlying); - return writeable.finalize(); - } - // ignore: non_constant_identifier_names - static final _MyString_get_str= _capi, ffi.Pointer)>>('MyString_get_str') - .asFunction, ffi.Pointer)>(isLeaf: true); - - - } - - -class _MyStructFfi extends ffi.Struct { - @ffi.Uint8() - external int a; - @ffi.Bool() - external bool b; - @ffi.Uint8() - external int c; - @ffi.Uint64() - external int d; - @ffi.Int32() - external int e; - @ffi.Uint32() - external int f; - @ffi.Int32() - external int g; -} - -class MyStruct { - final _MyStructFfi _underlying; - - // ignore: unused_element - MyStruct._(this._underlying); - - factory MyStruct() { - final pointer = ffi2.calloc<_MyStructFfi>(); - final result = MyStruct._(pointer.ref); - _callocFree.attach(result, pointer.cast()); - return result; - } - - int get a => _underlying.a; - set a(int a) { - _underlying.a = a; - } -bool get b => _underlying.b; - set b(bool b) { - _underlying.b = b; - } -int get c => _underlying.c; - set c(int c) { - _underlying.c = c; - } -int get d => _underlying.d; - set d(int d) { - _underlying.d = d; - } -int get e => _underlying.e; - set e(int e) { - _underlying.e = e; - } -int get f => _underlying.f; - set f(int f) { - _underlying.f = f; - } -MyEnum get g => MyEnum.values.firstWhere((v) => v._underlying == _underlying.g); - set g(MyEnum g) { - _underlying.g = g._underlying; - } - -factory MyStruct() { - - final result = _MyStruct_new(); - return MyStruct._(result); - } - // ignore: non_constant_identifier_names - static final _MyStruct_new= _capi>('MyStruct_new') - .asFunction<_MyStructFfi Function()>(isLeaf: true); - -int intoA() { - - final result = _MyStruct_into_a(_underlying); - return result; - } - // ignore: non_constant_identifier_names - static final _MyStruct_into_a= _capi>('MyStruct_into_a') - .asFunction(isLeaf: true); - - - @override - bool operator ==(Object other) => - other is MyStruct - && other._underlying.a == _underlying.a - && other._underlying.b == _underlying.b - && other._underlying.c == _underlying.c - && other._underlying.d == _underlying.d - && other._underlying.e == _underlying.e - && other._underlying.f == _underlying.f - && other._underlying.g == _underlying.g; - - @override - int get hashCode => Object.hashAll([_underlying.a,_underlying.b,_underlying.c,_underlying.d,_underlying.e,_underlying.f,_underlying.g,]); -} - - -class One implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - One._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('One_destroy')); - - -factory One.transitivity(One hold, One nohold) { - - final result = _One_transitivity(hold._underlying,nohold._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_transitivity= _capi Function(ffi.Pointer, ffi.Pointer)>>('One_transitivity') - .asFunction Function(ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.cycle(Two hold, One nohold) { - - final result = _One_cycle(hold._underlying,nohold._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_cycle= _capi Function(ffi.Pointer, ffi.Pointer)>>('One_cycle') - .asFunction Function(ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.manyDependents(One a, One b, Two c, Two d, Two nohold) { - - final result = _One_many_dependents(a._underlying,b._underlying,c._underlying,d._underlying,nohold._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_many_dependents= _capi Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>>('One_many_dependents') - .asFunction Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.returnOutlivesParam(Two hold, One nohold) { - - final result = _One_return_outlives_param(hold._underlying,nohold._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_return_outlives_param= _capi Function(ffi.Pointer, ffi.Pointer)>>('One_return_outlives_param') - .asFunction Function(ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.diamondTop(One top, One left, One right, One bottom) { - - final result = _One_diamond_top(top._underlying,left._underlying,right._underlying,bottom._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_diamond_top= _capi Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>>('One_diamond_top') - .asFunction Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.diamondLeft(One top, One left, One right, One bottom) { - - final result = _One_diamond_left(top._underlying,left._underlying,right._underlying,bottom._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_diamond_left= _capi Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>>('One_diamond_left') - .asFunction Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.diamondRight(One top, One left, One right, One bottom) { - - final result = _One_diamond_right(top._underlying,left._underlying,right._underlying,bottom._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_diamond_right= _capi Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>>('One_diamond_right') - .asFunction Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.diamondBottom(One top, One left, One right, One bottom) { - - final result = _One_diamond_bottom(top._underlying,left._underlying,right._underlying,bottom._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_diamond_bottom= _capi Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>>('One_diamond_bottom') - .asFunction Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.diamondAndNestedTypes(One a, One b, One c, One d, One nohold) { - - final result = _One_diamond_and_nested_types(a._underlying,b._underlying,c._underlying,d._underlying,nohold._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_diamond_and_nested_types= _capi Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>>('One_diamond_and_nested_types') - .asFunction Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.implicitBounds(One explicitHold, One implicitHold, One nohold) { - - final result = _One_implicit_bounds(explicitHold._underlying,implicitHold._underlying,nohold._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_implicit_bounds= _capi Function(ffi.Pointer, ffi.Pointer, ffi.Pointer)>>('One_implicit_bounds') - .asFunction Function(ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - -factory One.implicitBoundsDeep(One explicit, One implicit1, One implicit2, One nohold) { - - final result = _One_implicit_bounds_deep(explicit._underlying,implicit1._underlying,implicit2._underlying,nohold._underlying); - return One._(result); - } - // ignore: non_constant_identifier_names - static final _One_implicit_bounds_deep= _capi Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>>('One_implicit_bounds_deep') - .asFunction Function(ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>(isLeaf: true); - - - } - - -class Opaque implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - Opaque._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('Opaque_destroy')); - - -factory Opaque() { - - final result = _Opaque_new(); - return Opaque._(result); - } - // ignore: non_constant_identifier_names - static final _Opaque_new= _capi Function()>>('Opaque_new') - .asFunction Function()>(isLeaf: true); - - - -/// See the [Rust documentation for `something`](https://docs.rs/Something/latest/struct.Something.html#method.something) for more information. -/// -/// See the [Rust documentation for `something_else`](https://docs.rs/Something/latest/struct.Something.html#method.something_else) for more information. -/// -/// Additional information: [1](https://docs.rs/Something/latest/struct.Something.html#method.something_small), [2](https://docs.rs/SomethingElse/latest/struct.SomethingElse.html#method.something) -void assertStruct(MyStruct s) { - - _Opaque_assert_struct(_underlying,s._underlying); - } - // ignore: non_constant_identifier_names - static final _Opaque_assert_struct= _capi, _MyStructFfi)>>('Opaque_assert_struct') - .asFunction, _MyStructFfi)>(isLeaf: true); - - - -static final int returnsUsize = _capi>('Opaque_returns_usize').asFunction(isLeaf: true)(); - - -static final ImportedStruct returnsImported = _capi>('Opaque_returns_imported').asFunction<_ImportedStructFfi Function()>(isLeaf: true)(); - - } - - -class OptionOpaque implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - OptionOpaque._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('OptionOpaque_destroy')); - - -static OptionOpaque? new_(int i) { - - final result = _OptionOpaque_new(i); - return result.address == 0 ? null : OptionOpaque._(result); - } - // ignore: non_constant_identifier_names - static final _OptionOpaque_new= _capi Function(ffi.Int32)>>('OptionOpaque_new') - .asFunction Function(int)>(isLeaf: true); - - - -static final OptionOpaque? none = _capi Function()>>('OptionOpaque_new_none').asFunction Function()>(isLeaf: true)(); - - -static final OptionStruct struct = _capi>('OptionOpaque_new_struct').asFunction<_OptionStructFfi Function()>(isLeaf: true)(); - - -static final OptionStruct structNones = _capi>('OptionOpaque_new_struct_nones').asFunction<_OptionStructFfi Function()>(isLeaf: true)(); - - -void assertInteger(int i) { - - _OptionOpaque_assert_integer(_underlying,i); - } - // ignore: non_constant_identifier_names - static final _OptionOpaque_assert_integer= _capi, ffi.Int32)>>('OptionOpaque_assert_integer') - .asFunction, int)>(isLeaf: true); - - - -static bool optionOpaqueArgument(OptionOpaque? arg) { - - final result = _OptionOpaque_option_opaque_argument(arg == null ? ffi.Pointer.fromAddress(0) ? arg._underlying); - return result; - } - // ignore: non_constant_identifier_names - static final _OptionOpaque_option_opaque_argument= _capi)>>('OptionOpaque_option_opaque_argument') - .asFunction)>(isLeaf: true); - - - } - - -class OptionOpaqueChar implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - OptionOpaqueChar._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('OptionOpaqueChar_destroy')); - - -void assertChar(int ch) { - - _OptionOpaqueChar_assert_char(_underlying,ch); - } - // ignore: non_constant_identifier_names - static final _OptionOpaqueChar_assert_char= _capi, ffi.Uint32)>>('OptionOpaqueChar_assert_char') - .asFunction, int)>(isLeaf: true); - - - } - - -class _OptionStructFfi extends ffi.Struct { - external ffi.Pointer a; - external ffi.Pointer b; - @ffi.Uint32() - external int c; - external ffi.Pointer d; -} - -class OptionStruct { - final _OptionStructFfi _underlying; - - // ignore: unused_element - OptionStruct._(this._underlying); - - factory OptionStruct() { - final pointer = ffi2.calloc<_OptionStructFfi>(); - final result = OptionStruct._(pointer.ref); - _callocFree.attach(result, pointer.cast()); - return result; - } - - OptionOpaque? get a => _underlying.a.address == 0 ? null : OptionOpaque._(_underlying.a); - set a(OptionOpaque? a) { - _underlying.a = a == null ? ffi.Pointer.fromAddress(0) ? a._underlying; - } -OptionOpaqueChar? get b => _underlying.b.address == 0 ? null : OptionOpaqueChar._(_underlying.b); - set b(OptionOpaqueChar? b) { - _underlying.b = b == null ? ffi.Pointer.fromAddress(0) ? b._underlying; - } -int get c => _underlying.c; - set c(int c) { - _underlying.c = c; - } -OptionOpaque? get d => _underlying.d.address == 0 ? null : OptionOpaque._(_underlying.d); - set d(OptionOpaque? d) { - _underlying.d = d == null ? ffi.Pointer.fromAddress(0) ? d._underlying; - } - - - @override - bool operator ==(Object other) => - other is OptionStruct - && other._underlying.a == _underlying.a - && other._underlying.b == _underlying.b - && other._underlying.c == _underlying.c - && other._underlying.d == _underlying.d; - - @override - int get hashCode => Object.hashAll([_underlying.a,_underlying.b,_underlying.c,_underlying.d,]); -} - - -class RefList implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - RefList._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('RefList_destroy')); - - -factory RefList.node(RefListParameter data) { - - final result = _RefList_node(data._underlying); - return RefList._(result); - } - // ignore: non_constant_identifier_names - static final _RefList_node= _capi Function(ffi.Pointer)>>('RefList_node') - .asFunction Function(ffi.Pointer)>(isLeaf: true); - - - } - - -class RefListParameter implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - RefListParameter._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('RefListParameter_destroy')); - - } - - -class ResultOpaque implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - ResultOpaque._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('ResultOpaque_destroy')); - - -factory ResultOpaque(int i) { - - final result = _ResultOpaque_new(i); - return result.isOk ? ResultOpaque._(result.union.ok) : throw ErrorEnum.values[result.union.err]; - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_new= _capi>('ResultOpaque_new') - .asFunction<_ResultOpaqueInt32 Function(int)>(isLeaf: true); - - - -factory ResultOpaque.failingFoo() { - - final result = _ResultOpaque_new_failing_foo(); - return result.isOk ? ResultOpaque._(result.union.ok) : throw ErrorEnum.values[result.union.err]; - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_new_failing_foo= _capi>('ResultOpaque_new_failing_foo') - .asFunction<_ResultOpaqueInt32 Function()>(isLeaf: true); - - - -factory ResultOpaque.failingBar() { - - final result = _ResultOpaque_new_failing_bar(); - return result.isOk ? ResultOpaque._(result.union.ok) : throw ErrorEnum.values[result.union.err]; - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_new_failing_bar= _capi>('ResultOpaque_new_failing_bar') - .asFunction<_ResultOpaqueInt32 Function()>(isLeaf: true); - - - -factory ResultOpaque.failingUnit() { - - final result = _ResultOpaque_new_failing_unit(); - return result.isOk ? ResultOpaque._(result.union.ok) : throw VoidError(); - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_new_failing_unit= _capi>('ResultOpaque_new_failing_unit') - .asFunction<_ResultOpaqueVoid Function()>(isLeaf: true); - - - -factory ResultOpaque.failingStruct(int i) { - - final result = _ResultOpaque_new_failing_struct(i); - return result.isOk ? ResultOpaque._(result.union.ok) : throw ErrorStruct._(result.union.err); - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_new_failing_struct= _capi>('ResultOpaque_new_failing_struct') - .asFunction<_ResultOpaqueErrorStructFfi Function(int)>(isLeaf: true); - - - -static void newInErr(int i) { - - final result = _ResultOpaque_new_in_err(i); - if (!result.isOk) { throw ResultOpaque._(result.union.err); } - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_new_in_err= _capi>('ResultOpaque_new_in_err') - .asFunction<_ResultVoidOpaque Function(int)>(isLeaf: true); - - - -static int newInt(int i) { - - final result = _ResultOpaque_new_int(i); - return result.isOk ? result.union.ok : throw VoidError(); - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_new_int= _capi>('ResultOpaque_new_int') - .asFunction<_ResultInt32Void Function(int)>(isLeaf: true); - - - -static ErrorEnum newInEnumErr(int i) { - - final result = _ResultOpaque_new_in_enum_err(i); - return result.isOk ? ErrorEnum.values[result.union.ok] : throw ResultOpaque._(result.union.err); - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_new_in_enum_err= _capi>('ResultOpaque_new_in_enum_err') - .asFunction<_ResultInt32Opaque Function(int)>(isLeaf: true); - - - -void assertInteger(int i) { - - _ResultOpaque_assert_integer(_underlying,i); - } - // ignore: non_constant_identifier_names - static final _ResultOpaque_assert_integer= _capi, ffi.Int32)>>('ResultOpaque_assert_integer') - .asFunction, int)>(isLeaf: true); - - - } - - -class Two implements ffi.Finalizable { - - final ffi.Pointer _underlying; - - Two._(this._underlying) { - _finalizer.attach(this, _underlying.cast()); - } - - static final _finalizer = ffi.NativeFinalizer(_capi('Two_destroy')); - - } - - -enum UnimportedEnum { - a, - b, - c; -} - class _ResultInt32OpaqueUnion extends ffi.Union { - @ffi.Int32() - external int ok; - - external ffi.Pointer err; + @ffi.Int32() + external int ok; + external ffi.Pointer err; } + class _ResultInt32Opaque extends ffi.Struct { - external _ResultInt32OpaqueUnion union; + external _ResultInt32OpaqueUnion union; - @ffi.Bool() - external bool isOk; + @ffi.Bool() + external bool isOk; } class _ResultInt32VoidUnion extends ffi.Union { - @ffi.Int32() - external int ok; - + @ffi.Int32() + external int ok; } + class _ResultInt32Void extends ffi.Struct { - external _ResultInt32VoidUnion union; + external _ResultInt32VoidUnion union; - @ffi.Bool() - external bool isOk; + @ffi.Bool() + external bool isOk; } class _ResultOpaqueErrorStructFfiUnion extends ffi.Union { - external ffi.Pointer ok; - - external _ErrorStructFfi err; + external ffi.Pointer ok; + external _ErrorStructFfi err; } + class _ResultOpaqueErrorStructFfi extends ffi.Struct { - external _ResultOpaqueErrorStructFfiUnion union; + external _ResultOpaqueErrorStructFfiUnion union; - @ffi.Bool() - external bool isOk; + @ffi.Bool() + external bool isOk; } class _ResultOpaqueInt32Union extends ffi.Union { - external ffi.Pointer ok; - - @ffi.Int32() - external int err; + external ffi.Pointer ok; + @ffi.Int32() + external int err; } + class _ResultOpaqueInt32 extends ffi.Struct { - external _ResultOpaqueInt32Union union; + external _ResultOpaqueInt32Union union; - @ffi.Bool() - external bool isOk; + @ffi.Bool() + external bool isOk; } class _ResultOpaqueVoidUnion extends ffi.Union { - external ffi.Pointer ok; - + external ffi.Pointer ok; } + class _ResultOpaqueVoid extends ffi.Struct { - external _ResultOpaqueVoidUnion union; + external _ResultOpaqueVoidUnion union; - @ffi.Bool() - external bool isOk; + @ffi.Bool() + external bool isOk; } class _ResultVoidOpaqueUnion extends ffi.Union { - external ffi.Pointer err; - + external ffi.Pointer err; } + class _ResultVoidOpaque extends ffi.Struct { - external _ResultVoidOpaqueUnion union; + external _ResultVoidOpaqueUnion union; - @ffi.Bool() - external bool isOk; + @ffi.Bool() + external bool isOk; } class _SliceFfi2Utf8 extends ffi.Struct { @@ -1118,13 +118,14 @@ class _SliceFfi2Utf8 extends ffi.Struct { @ffi.Size() external int _length; + /// Produces a slice from a Dart object. The Dart object's data is copied into the given allocator /// as it cannot be borrowed directly, and gets freed with the slice object. // ignore: unused_element static _SliceFfi2Utf8 _fromDart(String value, ffi.Allocator allocator) { final pointer = allocator<_SliceFfi2Utf8>(); - final slice = pointer.ref; - final units = Utf8Encoder().convert(value); + final slice = pointer.ref; + final units = Utf8Encoder().convert(value); slice._length = units.length; slice._bytes = allocator(slice._length).cast(); slice._bytes.cast().asTypedList(slice._length).setAll(0, units); @@ -1133,7 +134,8 @@ class _SliceFfi2Utf8 extends ffi.Struct { } // ignore: unused_element - String get _asDart => Utf8Decoder().convert(_bytes.cast().asTypedList(_length)); + String get _asDart => + Utf8Decoder().convert(_bytes.cast().asTypedList(_length)); // This is expensive @override @@ -1143,7 +145,8 @@ class _SliceFfi2Utf8 extends ffi.Struct { } for (var i = 0; i < _length; i++) { - if (other._bytes.cast()[i] != _bytes.cast()[i]) {return false; + if (other._bytes.cast()[i] != _bytes.cast()[i]) { + return false; } } return true; @@ -1154,19 +157,19 @@ class _SliceFfi2Utf8 extends ffi.Struct { int get hashCode => _length.hashCode; } - class _SliceFfiDouble extends ffi.Struct { external ffi.Pointer _bytes; @ffi.Size() external int _length; + /// Produces a slice from a Dart object. The Dart object's data is copied into the given allocator /// as it cannot be borrowed directly, and gets freed with the slice object. // ignore: unused_element static _SliceFfiDouble _fromDart(Float64List value, ffi.Allocator allocator) { final pointer = allocator<_SliceFfiDouble>(); - final slice = pointer.ref; - slice._length = value.length; + final slice = pointer.ref; + slice._length = value.length; slice._bytes = allocator(slice._length); slice._bytes.asTypedList(slice._length).setAll(0, value); @@ -1183,8 +186,9 @@ class _SliceFfiDouble extends ffi.Struct { return false; } - for (var i = 0; i < _length; i++) {if (other._bytes[i] != _bytes[i]) { - return false; + for (var i = 0; i < _length; i++) { + if (other._bytes[i] != _bytes[i]) { + return false; } } return true; @@ -1195,19 +199,19 @@ class _SliceFfiDouble extends ffi.Struct { int get hashCode => _length.hashCode; } - class _SliceFfiUint16 extends ffi.Struct { external ffi.Pointer _bytes; @ffi.Size() external int _length; + /// Produces a slice from a Dart object. The Dart object's data is copied into the given allocator /// as it cannot be borrowed directly, and gets freed with the slice object. // ignore: unused_element static _SliceFfiUint16 _fromDart(Uint16List value, ffi.Allocator allocator) { final pointer = allocator<_SliceFfiUint16>(); - final slice = pointer.ref; - slice._length = value.length; + final slice = pointer.ref; + slice._length = value.length; slice._bytes = allocator(slice._length); slice._bytes.asTypedList(slice._length).setAll(0, value); @@ -1224,8 +228,9 @@ class _SliceFfiUint16 extends ffi.Struct { return false; } - for (var i = 0; i < _length; i++) {if (other._bytes[i] != _bytes[i]) { - return false; + for (var i = 0; i < _length; i++) { + if (other._bytes[i] != _bytes[i]) { + return false; } } return true; @@ -1236,19 +241,19 @@ class _SliceFfiUint16 extends ffi.Struct { int get hashCode => _length.hashCode; } - class _SliceFfiUint8 extends ffi.Struct { external ffi.Pointer _bytes; @ffi.Size() external int _length; + /// Produces a slice from a Dart object. The Dart object's data is copied into the given allocator /// as it cannot be borrowed directly, and gets freed with the slice object. // ignore: unused_element static _SliceFfiUint8 _fromDart(Uint8List value, ffi.Allocator allocator) { final pointer = allocator<_SliceFfiUint8>(); - final slice = pointer.ref; - slice._length = value.length; + final slice = pointer.ref; + slice._length = value.length; slice._bytes = allocator(slice._length); slice._bytes.asTypedList(slice._length).setAll(0, value); @@ -1265,8 +270,9 @@ class _SliceFfiUint8 extends ffi.Struct { return false; } - for (var i = 0; i < _length; i++) {if (other._bytes[i] != _bytes[i]) { - return false; + for (var i = 0; i < _length; i++) { + if (other._bytes[i] != _bytes[i]) { + return false; } } return true; @@ -1277,7 +283,6 @@ class _SliceFfiUint8 extends ffi.Struct { int get hashCode => _length.hashCode; } - /// An unspecified error value class VoidError {} @@ -1291,10 +296,12 @@ class _Writeable { .asFunction Function(int)>(); String finalize() { - final string = _getBytes(_underlying).toDartString(length: _len(_underlying)); + final string = + _getBytes(_underlying).toDartString(length: _len(_underlying)); _destroy(_underlying); return string; } + static final _len = _capi)>>( 'diplomat_buffer_writeable_len') @@ -1303,11 +310,10 @@ class _Writeable { ffi.NativeFunction< ffi.Pointer Function(ffi.Pointer)>>( 'diplomat_buffer_writeable_get_bytes') - .asFunction Function(ffi.Pointer)>(isLeaf: true); + .asFunction Function(ffi.Pointer)>( + isLeaf: true); static final _destroy = _capi)>>( 'diplomat_buffer_writeable_destroy') .asFunction)>(isLeaf: true); } - - diff --git a/tool/src/dart/class.rs b/tool/src/dart/class.rs index 225b178ca..c74a835d0 100644 --- a/tool/src/dart/class.rs +++ b/tool/src/dart/class.rs @@ -8,57 +8,94 @@ use std::borrow::Cow; use std::collections::BTreeMap; use std::collections::BTreeSet; +impl<'tcx> DartContext<'tcx> { + pub fn gen_root( + &self, + mut directives: BTreeSet>, + helper_classes: BTreeMap, + ) { + directives.insert(self.formatter.fmt_renamed_import("dart:ffi", "ffi")); + directives.insert( + self.formatter + .fmt_renamed_import("package:ffi/ffi.dart", "ffi2"), + ); + self.files.add_file( + self.formatter.fmt_file_name("lib"), + Class { + body: include_str!("../../templates/dart/init.dart").into(), + directives, + helper_classes, + } + .render(), + ); + } + + pub fn gen_ty( + &self, + id: TypeId, + directives: &mut BTreeSet>, + helper_classes: &mut BTreeMap, + ) { + let ty = self.tcx.resolve_type(id); + + let _guard = self.errors.set_context_ty(ty.name().as_str().into()); + + let name = self.formatter.fmt_type_name(id); + directives.insert(self.formatter.fmt_part(&name)); + + let mut tgcx = TyGenContext { + imports: directives, + helper_classes, + cx: self, + }; + + let body = match ty { + TypeDef::Enum(o) => tgcx.gen_enum(o, id, &name), + TypeDef::Opaque(o) => tgcx.gen_opaque_def(o, id, &name), + TypeDef::Struct(s) => tgcx.gen_struct_def(s, id, &name), + TypeDef::OutStruct(s) => tgcx.gen_struct_def(s, id, &name), + _ => unreachable!("unknown AST/HIR variant"), + }; + + self.files.add_file( + self.formatter.fmt_file_name(&name), + Class { + body, + directives: BTreeSet::from_iter([self.formatter.fmt_part_of_lib()]), + helper_classes: Default::default(), + } + .render(), + ); + } +} + #[derive(PartialEq, Ord, PartialOrd, Clone, Eq, Debug)] -pub struct Class<'tcx> { - // Only for sorting - name: Cow<'tcx, str>, +struct Class { body: String, - imports: BTreeSet, + directives: BTreeSet>, helper_classes: BTreeMap, } -impl<'tcx> Class<'tcx> { - pub fn init() -> Self { - Self { - name: Default::default(), - body: include_str!("../../templates/dart/init.dart").into(), - imports: [Import { - path: "dart:ffi".into(), - suffix: " as ffi".into(), - }] - .into_iter() - .collect(), - helper_classes: Default::default(), - } - } - - pub fn append(mut self, other: Self) -> Self { - self.body.push_str("\n\n"); - self.body.push_str(&other.body); - self.imports.extend(other.imports); - self.helper_classes.extend(other.helper_classes); - self - } - - pub fn render(self) -> String { +impl Class { + fn render(self) -> String { #[derive(askama::Template)] #[template(path = "dart/base.dart.jinja", escape = "none")] struct ClassTemplate { - imports: BTreeSet, + directives: BTreeSet>, body: String, helper_classes: BTreeMap, } let Self { body, - imports, + directives, helper_classes, .. } = self; ClassTemplate { body, - imports, + directives, helper_classes, } .render() @@ -66,42 +103,9 @@ impl<'tcx> Class<'tcx> { } } -impl<'tcx> DartContext<'tcx> { - pub fn gen_ty(&self, id: TypeId) -> Class<'tcx> { - let ty = self.tcx.resolve_type(id); - - let mut imports = BTreeSet::new(); - let mut helper_classes = BTreeMap::new(); - let _guard = self.errors.set_context_ty(ty.name().as_str().into()); - - let mut tgcx = TyGenContext { - imports: &mut imports, - helper_classes: &mut helper_classes, - cx: self, - }; - - let name = self.formatter.fmt_type_name(id); - - let body = match ty { - TypeDef::Enum(o) => tgcx.gen_enum(o, id, &name), - TypeDef::Opaque(o) => tgcx.gen_opaque_def(o, id, &name), - TypeDef::Struct(s) => tgcx.gen_struct_def(s, id, &name), - TypeDef::OutStruct(s) => tgcx.gen_struct_def(s, id, &name), - _ => unreachable!("unknown AST/HIR variant"), - }; - - Class { - name, - body, - imports, - helper_classes, - } - } -} - pub struct TyGenContext<'a, 'dartcx, 'tcx> { cx: &'dartcx DartContext<'tcx>, - imports: &'a mut BTreeSet, + imports: &'a mut BTreeSet>, helper_classes: &'a mut BTreeMap, } @@ -146,10 +150,8 @@ impl<'a, 'dartcx, 'tcx: 'dartcx> TyGenContext<'a, 'dartcx, 'tcx> { destructor: String, } - self.imports.extend([Import { - path: "dart:ffi".into(), - suffix: " as ffi".into(), - }]); + self.imports + .insert(self.cx.formatter.fmt_renamed_import("dart:ffi", "ffi")); let methods = ty .methods @@ -194,10 +196,8 @@ impl<'a, 'dartcx, 'tcx: 'dartcx> TyGenContext<'a, 'dartcx, 'tcx> { set_slice_conversions: Vec>, } - self.imports.insert(Import { - path: "dart:ffi".into(), - suffix: " as ffi".into(), - }); + self.imports + .insert(self.cx.formatter.fmt_renamed_import("dart:ffi", "ffi")); let fields = ty .fields @@ -275,10 +275,8 @@ impl<'a, 'dartcx, 'tcx: 'dartcx> TyGenContext<'a, 'dartcx, 'tcx> { method.name.as_str().into(), ); - self.imports.insert(Import { - path: "dart:ffi".into(), - suffix: " as ffi".into(), - }); + self.imports + .insert(self.cx.formatter.fmt_renamed_import("dart:ffi", "ffi")); let c_method_name = self.cx.formatter.fmt_c_method_name(id, method); @@ -507,7 +505,7 @@ impl<'a, 'dartcx, 'tcx: 'dartcx> TyGenContext<'a, 'dartcx, 'tcx> { Type::Slice(hir::Slice::Str(_lifetime)) => self.cx.formatter.fmt_string().into(), Type::Slice(hir::Slice::Primitive(_, p)) => { self.imports - .insert(Import::simple("dart:typed_data".into())); + .insert(self.cx.formatter.fmt_import("dart:typed_data")); self.cx.formatter.fmt_primitive_list_type(p).into() } _ => unreachable!("unknown AST/HIR variant"), @@ -658,16 +656,17 @@ impl<'a, 'dartcx, 'tcx: 'dartcx> TyGenContext<'a, 'dartcx, 'tcx> { from_dart: &'static str, } - self.imports.insert(Import { - path: "package:ffi/ffi.dart".into(), - suffix: " as ffi2".into(), - }); + self.imports.insert( + self.cx + .formatter + .fmt_renamed_import("package:ffi/ffi.dart", "ffi2"), + ); let dart_ty = match slice { hir::Slice::Str(..) => self.cx.formatter.fmt_string(), hir::Slice::Primitive(_, p) => { self.imports - .insert(Import::simple("dart:typed_data".into())); + .insert(self.cx.formatter.fmt_import("dart:typed_data")); self.cx.formatter.fmt_primitive_list_type(*p) } _ => todo!("{slice:?}"), @@ -687,7 +686,8 @@ impl<'a, 'dartcx, 'tcx: 'dartcx> TyGenContext<'a, 'dartcx, 'tcx> { let to_dart = match slice { hir::Slice::Str(..) => { - self.imports.insert(Import::simple("dart:convert".into())); + self.imports + .insert(self.cx.formatter.fmt_import("dart:convert")); "Utf8Decoder().convert(_bytes.cast().asTypedList(_length))" } // TODO: How to read ffi.Size? @@ -955,21 +955,6 @@ struct MethodInfo<'a> { dart_return_expression: Option>, } -#[derive(PartialEq, Ord, PartialOrd, Clone, Eq, Debug)] -struct Import { - path: Cow<'static, str>, - suffix: Cow<'static, str>, -} - -impl Import { - fn simple(path: Cow<'static, str>) -> Self { - Import { - path, - suffix: "".into(), - } - } -} - #[derive(PartialEq, Ord, PartialOrd, Clone, Eq, Debug)] struct ResultClass { ok_name: String, diff --git a/tool/src/dart/formatter.rs b/tool/src/dart/formatter.rs index ea9bad44f..359545d65 100644 --- a/tool/src/dart/formatter.rs +++ b/tool/src/dart/formatter.rs @@ -37,9 +37,33 @@ impl<'tcx> DartFormatter<'tcx> { } } + pub fn fmt_file_name(&self, name: &str) -> String { + format!("{name}.g.dart") + } + + pub fn fmt_import(&self, path: &str) -> Cow<'static, str> { + format!("import '{path}';").into() + } + + pub fn fmt_renamed_import(&self, path: &str, name: &str) -> Cow<'static, str> { + format!("import '{path}' as {name};").into() + } + + pub fn fmt_part_of_lib(&self) -> Cow<'static, str> { + format!("part of '{}';", self.fmt_file_name("lib")).into() + } + + pub fn fmt_part(&self, part: &str) -> Cow<'static, str> { + format!("part '{}';", self.fmt_file_name(part)).into() + } + pub fn fmt_docs(&self, docs: &hir::Docs) -> String { docs.to_markdown(self.docs_url_generator, MarkdownStyle::Normal) .replace('\n', "\n/// ") + .replace( + &format!("`{}", self.strip_prefix.as_deref().unwrap_or("")), + "`", + ) } pub fn fmt_destructor_name(&self, id: TypeId) -> String { diff --git a/tool/src/dart/mod.rs b/tool/src/dart/mod.rs index 046031d8a..e5ef2dddb 100644 --- a/tool/src/dart/mod.rs +++ b/tool/src/dart/mod.rs @@ -34,16 +34,17 @@ impl<'tcx> DartContext<'tcx> { /// /// Will populate self.files as a result pub fn run(&self) { - self.files.add_file( - "lib.g.dart".to_string(), - self.tcx - .all_types() - .filter(|(_, ty)| !ty.attrs().disable) - .map(|(id, _)| self.gen_ty(id)) - .collect::>() - .into_iter() - .fold(class::Class::init(), class::Class::append) - .render(), - ); + let mut directives = Default::default(); + let mut helper_classes = Default::default(); + + for (id, ty) in self.tcx.all_types() { + if ty.attrs().disable { + continue; + } + + self.gen_ty(id, &mut directives, &mut helper_classes); + } + + self.gen_root(directives, helper_classes); } } diff --git a/tool/templates/dart/base.dart.jinja b/tool/templates/dart/base.dart.jinja index 58b8a4b3d..698abc0cb 100644 --- a/tool/templates/dart/base.dart.jinja +++ b/tool/templates/dart/base.dart.jinja @@ -3,8 +3,8 @@ // https://github.com/dart-lang/sdk/issues/53946 // ignore_for_file: non_native_function_type_argument_to_pointer -{% for import in imports -%} -import '{{import.path}}'{{import.suffix}}; +{% for directive in directives -%} +{{directive}} {% endfor %} {{ body }} From c9a6b04b1c5f455b8025e0d3a83e7707b91d482f Mon Sep 17 00:00:00 2001 From: Robert Bastian <4706271+robertbastian@users.noreply.github.com> Date: Sat, 18 Nov 2023 00:19:49 +0100 Subject: [PATCH 2/3] docss --- tool/src/dart/class.rs | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tool/src/dart/class.rs b/tool/src/dart/class.rs index c74a835d0..b33309a96 100644 --- a/tool/src/dart/class.rs +++ b/tool/src/dart/class.rs @@ -7,6 +7,7 @@ use diplomat_core::hir::{ use std::borrow::Cow; use std::collections::BTreeMap; use std::collections::BTreeSet; +use std::fmt::Write; impl<'tcx> DartContext<'tcx> { pub fn gen_root( @@ -428,7 +429,20 @@ impl<'a, 'dartcx, 'tcx: 'dartcx> TyGenContext<'a, 'dartcx, 'tcx> { format!("{return_ty} {method_name}({params})") }; - let docs = self.cx.formatter.fmt_docs(&method.docs); + let mut docs = self.cx.formatter.fmt_docs(&method.docs); + + if let hir::ReturnType::Fallible(_, e) = &method.output { + write!( + &mut docs, + "\n///\n/// Throws [{}] on failure.", + &if let Some(e) = e { + self.gen_type_name(e) + } else { + "VoidError".into() + }, + ) + .unwrap(); + } Some(MethodInfo { method, @@ -895,21 +909,16 @@ impl<'a, 'dartcx, 'tcx: 'dartcx> TyGenContext<'a, 'dartcx, 'tcx> { "VoidError()".into() } }; + let err_check = + format!("if (!{var_name}.isOk) {{ throw {err_conversion}; }}").into(); let ok_conversion = match ok { // Note: the `writeable` variable is a string initialized in the template Some(SuccessType::Writeable) => "writeable.finalize()".into(), Some(SuccessType::OutType(o)) => self.gen_c_to_dart_for_type(o, ok_path.into()), - None => { - return Some( - format!("if (!{var_name}.isOk) {{ throw {err_conversion}; }}").into(), - ) - } + None => return Some(err_check), &Some(_) => unreachable!("unknown AST/HIR variant"), }; - Some( - format!("return {var_name}.isOk ? {ok_conversion} : throw {err_conversion};") - .into(), - ) + Some(format!("{err_check}\nreturn {ok_conversion};").into()) } ReturnType::Infallible(Some(_)) => unreachable!("unknown AST/HIR variant"), } From 0d239a9a476635e8f8b05ad7af20581f7f2feaf8 Mon Sep 17 00:00:00 2001 From: Robert Bastian <4706271+robertbastian@users.noreply.github.com> Date: Sat, 18 Nov 2023 13:24:46 +0100 Subject: [PATCH 3/3] gen --- example/dart/lib/ICU4XDataProvider.g.dart | 2 + example/dart/lib/ICU4XFixedDecimal.g.dart | 7 +- .../lib/ICU4XFixedDecimalFormatter.g.dart | 9 ++- feature_tests/dart/lib/ResultOpaque.g.dart | 69 ++++++++++++++----- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/example/dart/lib/ICU4XDataProvider.g.dart b/example/dart/lib/ICU4XDataProvider.g.dart index f3b77d8ee..c719a51c5 100644 --- a/example/dart/lib/ICU4XDataProvider.g.dart +++ b/example/dart/lib/ICU4XDataProvider.g.dart @@ -30,6 +30,8 @@ class ICU4XDataProvider implements ffi.Finalizable { .asFunction Function()>(isLeaf: true); /// This exists as a regression test for https://github.com/rust-diplomat/diplomat/issues/155 + /// + /// Throws [VoidError] on failure. static void returnsResult() { final result = _ICU4XDataProvider_returns_result(); if (!result.isOk) { diff --git a/example/dart/lib/ICU4XFixedDecimal.g.dart b/example/dart/lib/ICU4XFixedDecimal.g.dart index 656d763ee..736d08bae 100644 --- a/example/dart/lib/ICU4XFixedDecimal.g.dart +++ b/example/dart/lib/ICU4XFixedDecimal.g.dart @@ -44,12 +44,17 @@ class ICU4XFixedDecimal implements ffi.Finalizable { /// Format the [`ICU4XFixedDecimal`] as a string. /// /// See the [Rust documentation for `write_to`](https://docs.rs/fixed_decimal/latest/fixed_decimal/struct.FixedDecimal.html#method.write_to) for more information. + /// + /// Throws [VoidError] on failure. @override String toString() { final writeable = _Writeable(); final result = _ICU4XFixedDecimal_to_string(_underlying, writeable._underlying); - return result.isOk ? writeable.finalize() : throw VoidError(); + if (!result.isOk) { + throw VoidError(); + } + return writeable.finalize(); } // ignore: non_constant_identifier_names diff --git a/example/dart/lib/ICU4XFixedDecimalFormatter.g.dart b/example/dart/lib/ICU4XFixedDecimalFormatter.g.dart index bf6a622f0..57d299070 100644 --- a/example/dart/lib/ICU4XFixedDecimalFormatter.g.dart +++ b/example/dart/lib/ICU4XFixedDecimalFormatter.g.dart @@ -21,13 +21,16 @@ class ICU4XFixedDecimalFormatter implements ffi.Finalizable { /// Creates a new [`ICU4XFixedDecimalFormatter`] from locale data. /// /// See the [Rust documentation for `try_new`](https://docs.rs/icu/latest/icu/decimal/struct.FixedDecimalFormatter.html#method.try_new) for more information. + /// + /// Throws [VoidError] on failure. factory ICU4XFixedDecimalFormatter.tryNew(ICU4XLocale locale, ICU4XDataProvider provider, ICU4XFixedDecimalFormatterOptions options) { final result = _ICU4XFixedDecimalFormatter_try_new( locale._underlying, provider._underlying, options._underlying); - return result.isOk - ? ICU4XFixedDecimalFormatter._(result.union.ok) - : throw VoidError(); + if (!result.isOk) { + throw VoidError(); + } + return ICU4XFixedDecimalFormatter._(result.union.ok); } // ignore: non_constant_identifier_names static final _ICU4XFixedDecimalFormatter_try_new = _capi< diff --git a/feature_tests/dart/lib/ResultOpaque.g.dart b/feature_tests/dart/lib/ResultOpaque.g.dart index f28df4eca..0db9a898e 100644 --- a/feature_tests/dart/lib/ResultOpaque.g.dart +++ b/feature_tests/dart/lib/ResultOpaque.g.dart @@ -14,11 +14,15 @@ class ResultOpaque implements ffi.Finalizable { static final _finalizer = ffi.NativeFinalizer(_capi('ResultOpaque_destroy')); + /// + /// + /// Throws [ErrorEnum] on failure. factory ResultOpaque(int i) { final result = _ResultOpaque_new(i); - return result.isOk - ? ResultOpaque._(result.union.ok) - : throw ErrorEnum.values[result.union.err]; + if (!result.isOk) { + throw ErrorEnum.values[result.union.err]; + } + return ResultOpaque._(result.union.ok); } // ignore: non_constant_identifier_names static final _ResultOpaque_new = @@ -26,11 +30,15 @@ class ResultOpaque implements ffi.Finalizable { 'ResultOpaque_new') .asFunction<_ResultOpaqueInt32 Function(int)>(isLeaf: true); + /// + /// + /// Throws [ErrorEnum] on failure. factory ResultOpaque.failingFoo() { final result = _ResultOpaque_new_failing_foo(); - return result.isOk - ? ResultOpaque._(result.union.ok) - : throw ErrorEnum.values[result.union.err]; + if (!result.isOk) { + throw ErrorEnum.values[result.union.err]; + } + return ResultOpaque._(result.union.ok); } // ignore: non_constant_identifier_names static final _ResultOpaque_new_failing_foo = @@ -38,11 +46,15 @@ class ResultOpaque implements ffi.Finalizable { 'ResultOpaque_new_failing_foo') .asFunction<_ResultOpaqueInt32 Function()>(isLeaf: true); + /// + /// + /// Throws [ErrorEnum] on failure. factory ResultOpaque.failingBar() { final result = _ResultOpaque_new_failing_bar(); - return result.isOk - ? ResultOpaque._(result.union.ok) - : throw ErrorEnum.values[result.union.err]; + if (!result.isOk) { + throw ErrorEnum.values[result.union.err]; + } + return ResultOpaque._(result.union.ok); } // ignore: non_constant_identifier_names static final _ResultOpaque_new_failing_bar = @@ -50,9 +62,15 @@ class ResultOpaque implements ffi.Finalizable { 'ResultOpaque_new_failing_bar') .asFunction<_ResultOpaqueInt32 Function()>(isLeaf: true); + /// + /// + /// Throws [VoidError] on failure. factory ResultOpaque.failingUnit() { final result = _ResultOpaque_new_failing_unit(); - return result.isOk ? ResultOpaque._(result.union.ok) : throw VoidError(); + if (!result.isOk) { + throw VoidError(); + } + return ResultOpaque._(result.union.ok); } // ignore: non_constant_identifier_names static final _ResultOpaque_new_failing_unit = @@ -60,11 +78,15 @@ class ResultOpaque implements ffi.Finalizable { 'ResultOpaque_new_failing_unit') .asFunction<_ResultOpaqueVoid Function()>(isLeaf: true); + /// + /// + /// Throws [ErrorStruct] on failure. factory ResultOpaque.failingStruct(int i) { final result = _ResultOpaque_new_failing_struct(i); - return result.isOk - ? ResultOpaque._(result.union.ok) - : throw ErrorStruct._(result.union.err); + if (!result.isOk) { + throw ErrorStruct._(result.union.err); + } + return ResultOpaque._(result.union.ok); } // ignore: non_constant_identifier_names static final _ResultOpaque_new_failing_struct = _capi< @@ -73,6 +95,9 @@ class ResultOpaque implements ffi.Finalizable { 'ResultOpaque_new_failing_struct') .asFunction<_ResultOpaqueErrorStructFfi Function(int)>(isLeaf: true); + /// + /// + /// Throws [ResultOpaque] on failure. static void newInErr(int i) { final result = _ResultOpaque_new_in_err(i); if (!result.isOk) { @@ -86,9 +111,15 @@ class ResultOpaque implements ffi.Finalizable { 'ResultOpaque_new_in_err') .asFunction<_ResultVoidOpaque Function(int)>(isLeaf: true); + /// + /// + /// Throws [VoidError] on failure. static int newInt(int i) { final result = _ResultOpaque_new_int(i); - return result.isOk ? result.union.ok : throw VoidError(); + if (!result.isOk) { + throw VoidError(); + } + return result.union.ok; } // ignore: non_constant_identifier_names @@ -97,11 +128,15 @@ class ResultOpaque implements ffi.Finalizable { 'ResultOpaque_new_int') .asFunction<_ResultInt32Void Function(int)>(isLeaf: true); + /// + /// + /// Throws [ResultOpaque] on failure. static ErrorEnum newInEnumErr(int i) { final result = _ResultOpaque_new_in_enum_err(i); - return result.isOk - ? ErrorEnum.values[result.union.ok] - : throw ResultOpaque._(result.union.err); + if (!result.isOk) { + throw ResultOpaque._(result.union.err); + } + return ErrorEnum.values[result.union.ok]; } // ignore: non_constant_identifier_names