Support for inline arrays in structs (#206)
* Generates `Array` instead of workaround.
* Removes `array-workaround` config.
* Removes depreacted `llvm-lib` config.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 82b5807..5139d6f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+# 3.0.0-beta.0
+- Added support for inline arrays in `Struct`s.
+- Remove config key `array-workaround`.
+- Remove deprecated key `llvm-lib` from config, Use `llvm-path` instead.
+
# 2.5.0-beta.1
- Added support for `Packed` structs. Packed annotations are generated
automatically but can be overriden using `structs -> pack` config.
diff --git a/README.md b/README.md
index d8cac98..a008d37 100644
--- a/README.md
+++ b/README.md
@@ -253,18 +253,6 @@
</td>
</tr>
<tr>
- <td>array-workaround</td>
- <td>Should generate workaround for fixed arrays in Structs. See <a href="#array-workaround">Array Workaround</a><br>
- <b>Default: false</b>
- </td>
- <td>
-
-```yaml
-array-workaround: true
-```
- </td>
- </tr>
- <tr>
<td>comments</td>
<td>Extract documentation comments for declarations.<br>
The style and length of the comments recognized can be specified with the following options- <br>
@@ -402,80 +390,6 @@
</tbody>
</table>
-## Array-Workaround
-Fixed size array's in structs aren't currently supported by Dart. However we provide
-a workaround, using which array items can now be accessed using `[]` operator.
-
-Here's a C structure from libclang-
-```c
-typedef struct {
- unsigned long long data[3];
-} CXFileUniqueID;
-```
-The generated code is -
-```dart
-class CXFileUniqueID extends ffi.Struct {
- @ffi.Uint64()
- external int _unique_data_item_0;
- @ffi.Uint64()
- external int _unique_data_item_1;
- @ffi.Uint64()
- external int _unique_data_item_2;
-
- /// Helper for array `data`.
- ArrayHelper_CXFileUniqueID_data_level0 get data =>
- ArrayHelper_CXFileUniqueID_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXFileUniqueID`.
-class ArrayHelper_CXFileUniqueID_data_level0 {
- final CXFileUniqueID _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXFileUniqueID_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..${length} exclusive.');
- }
- }
-
- int operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- case 2:
- return _struct._unique_data_item_2;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, int value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- case 2:
- _struct._unique_data_item_2 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-```
-
## Limitations
1. Multi OS support for types such as long. [Issue #7](https://github.com/dart-lang/ffigen/issues/7)
diff --git a/example/libclang-example/generated_bindings.dart b/example/libclang-example/generated_bindings.dart
index cd366f3..71fa196 100644
--- a/example/libclang-example/generated_bindings.dart
+++ b/example/libclang-example/generated_bindings.dart
@@ -7928,64 +7928,8 @@
/// Uniquely identifies a CXFile, that refers to the same underlying file,
/// across an indexing session.
class CXFileUniqueID extends ffi.Struct {
- @ffi.Uint64()
- external int _unique_data_item_0;
- @ffi.Uint64()
- external int _unique_data_item_1;
- @ffi.Uint64()
- external int _unique_data_item_2;
-
- /// Helper for array `data`.
- ArrayHelper_CXFileUniqueID_data_level0 get data =>
- ArrayHelper_CXFileUniqueID_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXFileUniqueID`.
-class ArrayHelper_CXFileUniqueID_data_level0 {
- final CXFileUniqueID _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXFileUniqueID_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- int operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- case 2:
- return _struct._unique_data_item_2;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, int value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- case 2:
- _struct._unique_data_item_2 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([3])
+ external ffi.Array<ffi.Uint64> data;
}
/// Identifies a specific source location within a translation
@@ -7994,70 +7938,21 @@
/// Use clang_getExpansionLocation() or clang_getSpellingLocation()
/// to map a source location to a particular file, line, and column.
class CXSourceLocation extends ffi.Struct {
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
- /// Helper for array `ptr_data`.
- ArrayHelper_CXSourceLocation_ptr_data_level0 get ptr_data =>
- ArrayHelper_CXSourceLocation_ptr_data_level0(this, [2], 0, 0);
@ffi.Uint32()
external int int_data;
}
-/// Helper for array `ptr_data` in struct `CXSourceLocation`.
-class ArrayHelper_CXSourceLocation_ptr_data_level0 {
- final CXSourceLocation _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXSourceLocation_ptr_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_ptr_data_item_0;
- case 1:
- return _struct._unique_ptr_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_ptr_data_item_0 = value;
- break;
- case 1:
- _struct._unique_ptr_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// Identifies a half-open character range in the source code.
///
/// Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
/// starting and end locations from a source range, respectively.
class CXSourceRange extends ffi.Struct {
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
- /// Helper for array `ptr_data`.
- ArrayHelper_CXSourceRange_ptr_data_level0 get ptr_data =>
- ArrayHelper_CXSourceRange_ptr_data_level0(this, [2], 0, 0);
@ffi.Uint32()
external int begin_int_data;
@@ -8065,49 +7960,6 @@
external int end_int_data;
}
-/// Helper for array `ptr_data` in struct `CXSourceRange`.
-class ArrayHelper_CXSourceRange_ptr_data_level0 {
- final CXSourceRange _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXSourceRange_ptr_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_ptr_data_item_0;
- case 1:
- return _struct._unique_ptr_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_ptr_data_item_0 = value;
- break;
- case 1:
- _struct._unique_ptr_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// Identifies an array of ranges.
class CXSourceRangeList extends ffi.Struct {
/// The number of ranges in the \c ranges array.
@@ -8159,61 +8011,8 @@
@ffi.Int32()
external int xdata;
- external ffi.Pointer<ffi.Void> _unique_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_data_item_1;
- external ffi.Pointer<ffi.Void> _unique_data_item_2;
-
- /// Helper for array `data`.
- ArrayHelper_CXCursor_data_level0 get data =>
- ArrayHelper_CXCursor_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXCursor`.
-class ArrayHelper_CXCursor_data_level0 {
- final CXCursor _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXCursor_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- case 2:
- return _struct._unique_data_item_2;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- case 2:
- _struct._unique_data_item_2 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([3])
+ external ffi.Array<ffi.Pointer<ffi.Void>> data;
}
/// Describes the availability of a given entity on a particular platform, e.g.,
@@ -8382,127 +8181,18 @@
@ffi.Int32()
external int kind;
- external ffi.Pointer<ffi.Void> _unique_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_data_item_1;
-
- /// Helper for array `data`.
- ArrayHelper_CXType_data_level0 get data =>
- ArrayHelper_CXType_data_level0(this, [2], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXType`.
-class ArrayHelper_CXType_data_level0 {
- final CXType _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXType_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> data;
}
/// Describes a single preprocessing token.
class CXToken extends ffi.Struct {
- @ffi.Uint32()
- external int _unique_int_data_item_0;
- @ffi.Uint32()
- external int _unique_int_data_item_1;
- @ffi.Uint32()
- external int _unique_int_data_item_2;
- @ffi.Uint32()
- external int _unique_int_data_item_3;
+ @ffi.Array.multi([4])
+ external ffi.Array<ffi.Uint32> int_data;
- /// Helper for array `int_data`.
- ArrayHelper_CXToken_int_data_level0 get int_data =>
- ArrayHelper_CXToken_int_data_level0(this, [4], 0, 0);
external ffi.Pointer<ffi.Void> ptr_data;
}
-/// Helper for array `int_data` in struct `CXToken`.
-class ArrayHelper_CXToken_int_data_level0 {
- final CXToken _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXToken_int_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- int operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_int_data_item_0;
- case 1:
- return _struct._unique_int_data_item_1;
- case 2:
- return _struct._unique_int_data_item_2;
- case 3:
- return _struct._unique_int_data_item_3;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, int value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_int_data_item_0 = value;
- break;
- case 1:
- _struct._unique_int_data_item_1 = value;
- break;
- case 2:
- _struct._unique_int_data_item_2 = value;
- break;
- case 3:
- _struct._unique_int_data_item_3 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// A single result of code completion.
class CXCompletionResult extends ffi.Struct {
/// The kind of entity that this completion refers to.
@@ -8544,59 +8234,13 @@
/// Source location passed to index callbacks.
class CXIdxLoc extends ffi.Struct {
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
- /// Helper for array `ptr_data`.
- ArrayHelper_CXIdxLoc_ptr_data_level0 get ptr_data =>
- ArrayHelper_CXIdxLoc_ptr_data_level0(this, [2], 0, 0);
@ffi.Uint32()
external int int_data;
}
-/// Helper for array `ptr_data` in struct `CXIdxLoc`.
-class ArrayHelper_CXIdxLoc_ptr_data_level0 {
- final CXIdxLoc _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXIdxLoc_ptr_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_ptr_data_item_0;
- case 1:
- return _struct._unique_ptr_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_ptr_data_item_0 = value;
- break;
- case 1:
- _struct._unique_ptr_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// Data for ppIncludedFile callback.
class CXIdxIncludedFileInfo extends ffi.Struct {
/// Location of '#' in the \#include/\#import directive.
diff --git a/example/libclang-example/pubspec.yaml b/example/libclang-example/pubspec.yaml
index e048fe5..bf0695e 100644
--- a/example/libclang-example/pubspec.yaml
+++ b/example/libclang-example/pubspec.yaml
@@ -18,7 +18,8 @@
# sort: true
# This is required if LLVM can't be found in default locations by ffigen.
- # llvm-lib: '/usr/local/opt/llvm/lib'
+ # llvm-path:
+ # - '/usr/local/opt/llvm'
# Bash style Glob matching is also supported.
# TODO(11): Globs dont work on windows if they begin with '.' or '..'.
@@ -66,9 +67,6 @@
description: 'Holds bindings to LibClang.'
- # False by default.
- array-workaround: true
-
# Doc Comments for generated binings.
# Comments can be disabled by using comments: false
comments:
diff --git a/lib/src/README.md b/lib/src/README.md
index 7564006..2b20f84 100644
--- a/lib/src/README.md
+++ b/lib/src/README.md
@@ -22,7 +22,7 @@
- `--verbose`: Sets log level.
- `--config`: Specifies a config file.
- The internal modules are called by `ffigen.dart` in the following way:
-- `ffigen.dart` will try to find dynamic library in default locations. If that fails, the user must excplicitly specify location in ffigen's config under the key `llvm-lib`.
+- `ffigen.dart` will try to find dynamic library in default locations. If that fails, the user must excplicitly specify location in ffigen's config under the key `llvm-path`.
- It first creates a `Config` object from an input Yaml file. This is used by other modules.
- The `parse` method is then invoked to generate a `Library` object.
- Finally, the code is generated from the `Library` object to the specified file.
diff --git a/lib/src/code_generator/struc.dart b/lib/src/code_generator/struc.dart
index 37edfa0..8b87891 100644
--- a/lib/src/code_generator/struc.dart
+++ b/lib/src/code_generator/struc.dart
@@ -76,6 +76,13 @@
return array;
}
+ String _getInlineArrayTypeString(Type type, Writer w) {
+ if (type.broadType == BroadType.ConstantArray) {
+ return '${w.ffiLibraryPrefix}.Array<${_getInlineArrayTypeString(type.child!, w)}>';
+ }
+ return type.getCType(w);
+ }
+
List<Typedef>? _typedefDependencies;
@override
List<Typedef> getTypedefDependencies(Writer w) {
@@ -101,10 +108,6 @@
s.write(makeDartDoc(dartDoc!));
}
- final helpers = <ArrayHelper>[];
-
- final expandedArrayItemPrefix = getUniqueExpandedArrayItemPrefix();
-
/// Adding [enclosingClassName] because dart doesn't allow class member
/// to have the same name as the class.
final localUniqueNamer = UniqueNamer({enclosingClassName});
@@ -116,23 +119,15 @@
// Write class declaration.
s.write(
'class $enclosingClassName extends ${w.ffiLibraryPrefix}.${isOpaque ? 'Opaque' : 'Struct'}{\n');
+ const depth = ' ';
for (final m in members) {
final memberName = localUniqueNamer.makeUnique(m.name);
if (m.type.broadType == BroadType.ConstantArray) {
- // TODO(5): Remove array helpers when inline array support arives.
- final arrayHelper = ArrayHelper(
- helperClassGroupName:
- '${w.arrayHelperClassPrefix}_${enclosingClassName}_$memberName',
- elementType: m.type.getBaseArrayType(),
- dimensions: _getArrayDimensionLengths(m.type),
- name: memberName,
- structName: enclosingClassName,
- elementNamePrefix: '$expandedArrayItemPrefix${memberName}_item_',
- );
- s.write(arrayHelper.declarationString(w));
- helpers.add(arrayHelper);
+ s.write(
+ '$depth@${w.ffiLibraryPrefix}.Array.multi(${_getArrayDimensionLengths(m.type)})\n');
+ s.write(
+ '${depth}external ${_getInlineArrayTypeString(m.type, w)} $memberName;\n\n');
} else {
- const depth = ' ';
if (m.dartDoc != null) {
s.write(depth + '/// ');
s.writeAll(m.dartDoc!.split('\n'), '\n' + depth + '/// ');
@@ -146,28 +141,8 @@
}
s.write('}\n\n');
- for (final helper in helpers) {
- s.write(helper.helperClassString(w));
- }
-
return BindingString(type: BindingStringType.struc, string: s.toString());
}
-
- /// Gets a unique prefix in local namespace for expanded array items.
- String getUniqueExpandedArrayItemPrefix() {
- final base = '_unique';
- var expandedArrayItemPrefix = base;
- var suffixInt = 0;
- for (var i = 0; i < members.length; i++) {
- if (members[i].name.startsWith(expandedArrayItemPrefix)) {
- // Not a unique prefix, start over with a new suffix.
- i = -1;
- suffixInt++;
- expandedArrayItemPrefix = '$base$suffixInt';
- }
- }
- return expandedArrayItemPrefix + '_';
- }
}
class Member {
@@ -183,137 +158,3 @@
this.dartDoc,
}) : originalName = originalName ?? name;
}
-
-// Helper bindings for struct array.
-class ArrayHelper {
- final Type elementType;
- final List<int> dimensions;
- final String? structName;
-
- final String? name;
- final String helperClassGroupName;
- final String elementNamePrefix;
-
- int? _expandedArrayLength;
- int get expandedArrayLength {
- if (_expandedArrayLength != null) return _expandedArrayLength!;
-
- var arrayLength = 1;
- for (final i in dimensions) {
- arrayLength = arrayLength * i;
- }
- return arrayLength;
- }
-
- ArrayHelper({
- required this.elementType,
- required this.dimensions,
- required this.structName,
- required this.name,
- required this.helperClassGroupName,
- required this.elementNamePrefix,
- });
-
- /// Create declaration binding, added inside the struct binding.
- String declarationString(Writer w) {
- final s = StringBuffer();
- final arrayDartType = elementType.getDartType(w);
- final arrayCType = elementType.getCType(w);
-
- for (var i = 0; i < expandedArrayLength; i++) {
- if (elementType.isPrimitive) {
- s.write(' @$arrayCType()\n');
- }
- s.write(' external $arrayDartType $elementNamePrefix$i;\n');
- }
-
- s.write('/// Helper for array `$name`.\n');
- s.write(
- '${helperClassGroupName}_level0 get $name => ${helperClassGroupName}_level0(this, $dimensions, 0, 0);\n');
-
- return s.toString();
- }
-
- String helperClassString(Writer w) {
- final s = StringBuffer();
- final arrayType = elementType.getDartType(w);
- for (var dim = 0; dim < dimensions.length; dim++) {
- final helperClassName = '${helperClassGroupName}_level$dim';
- final structIdentifier = '_struct';
- final dimensionsIdentifier = 'dimensions';
- final levelIdentifier = 'level';
- final absoluteIndexIdentifier = '_absoluteIndex';
- final checkBoundsFunctionIdentifier = '_checkBounds';
- final legthIdentifier = 'length';
-
- s.write('/// Helper for array `$name` in struct `$structName`.\n');
-
- // Write class declaration.
- s.write('class $helperClassName{\n');
- s.write('final $structName $structIdentifier;\n');
- s.write('final List<int> $dimensionsIdentifier;\n');
- s.write('final int $levelIdentifier;\n');
- s.write('final int $absoluteIndexIdentifier;\n');
- s.write(
- 'int get $legthIdentifier => $dimensionsIdentifier[$levelIdentifier];\n');
-
- // Write class constructor.
- s.write(
- '$helperClassName(this.$structIdentifier, this.$dimensionsIdentifier, this.$levelIdentifier, this.$absoluteIndexIdentifier);\n');
-
- // Write checkBoundsFunction.
- s.write('''
- void $checkBoundsFunctionIdentifier(int index) {
- if (index >= $legthIdentifier || index < 0) {
- throw RangeError('Dimension \$$levelIdentifier: index not in range 0..\$$legthIdentifier exclusive.');
- }
- }
- ''');
- // If this isn't the last level.
- if (dim + 1 != dimensions.length) {
- // Override [] operator.
- s.write('''
- ${helperClassGroupName}_level${dim + 1} operator [](int index) {
- $checkBoundsFunctionIdentifier(index);
- var offset = index;
- for (var i = level + 1; i < $dimensionsIdentifier.length; i++) {
- offset *= $dimensionsIdentifier[i];
- }
- return ${helperClassGroupName}_level${dim + 1}(
- $structIdentifier, $dimensionsIdentifier, $levelIdentifier + 1, $absoluteIndexIdentifier + offset);
- }
-''');
- } else {
- // This is the last level, add switching logic here.
- // Override [] operator.
- s.write('$arrayType operator[](int index){\n');
- s.write('$checkBoundsFunctionIdentifier(index);\n');
- s.write('switch($absoluteIndexIdentifier+index){\n');
- for (var i = 0; i < expandedArrayLength; i++) {
- s.write('case $i:\n');
- s.write(' return $structIdentifier.$elementNamePrefix$i;\n');
- }
- s.write('default:\n');
- s.write(" throw Exception('Invalid Array Helper generated.');");
- s.write('}\n');
- s.write('}\n');
-
- // Override []= operator.
- s.write('void operator[]=(int index, $arrayType value){\n');
- s.write('$checkBoundsFunctionIdentifier(index);\n');
- s.write('switch($absoluteIndexIdentifier+index){\n');
- for (var i = 0; i < expandedArrayLength; i++) {
- s.write('case $i:\n');
- s.write(' $structIdentifier.$elementNamePrefix$i = value;\n');
- s.write(' break;\n');
- }
- s.write('default:\n');
- s.write(" throw Exception('Invalid Array Helper generated.');\n");
- s.write('}\n');
- s.write('}\n');
- }
- s.write('}\n');
- }
- return s.toString();
- }
-}
diff --git a/lib/src/config_provider/config.dart b/lib/src/config_provider/config.dart
index cacc7fa..e42ed46 100644
--- a/lib/src/config_provider/config.dart
+++ b/lib/src/config_provider/config.dart
@@ -84,13 +84,6 @@
StructPackingOverride get structPackingOverride => _structPackingOverride;
late StructPackingOverride _structPackingOverride;
- /// If tool should generate array workarounds.
- ///
- /// If false(default), structs with inline array members will have all its
- /// members removed.
- bool get arrayWorkaround => _arrayWorkaround;
- late bool _arrayWorkaround;
-
/// If dart bool should be generated for C booleans.
bool get dartBool => _dartBool;
late bool _dartBool;
@@ -185,24 +178,13 @@
/// Key: Name, Value: [Specification]
Map<List<String>, Specification> _getSpecs() {
return <List<String>, Specification>{
- //TODO: Deprecated, remove in next major update.
- [strings.llvmLib]: Specification<String>(
- requirement: Requirement.no,
- validator: llvmLibValidator,
- extractor: llvmLibExtractor,
- defaultValue: () => '',
- extractedResult: (dynamic result) {
- _libclangDylib = result as String;
- },
- ),
[strings.llvmPath]: Specification<String>(
requirement: Requirement.no,
validator: llvmPathValidator,
extractor: llvmPathExtractor,
defaultValue: () => findDylibAtDefaultLocations(),
extractedResult: (dynamic result) {
- // If this key wasn't already set by `llvm-lib` use this result.
- if (_libclangDylib.isEmpty) _libclangDylib = result as String;
+ _libclangDylib = result as String;
},
),
[strings.output]: Specification<String>(
@@ -348,13 +330,6 @@
extractedResult: (dynamic result) =>
_structPackingOverride = result as StructPackingOverride,
),
- [strings.arrayWorkaround]: Specification<bool>(
- requirement: Requirement.no,
- validator: booleanValidator,
- extractor: booleanExtractor,
- defaultValue: () => false,
- extractedResult: (dynamic result) => _arrayWorkaround = result as bool,
- ),
[strings.dartBool]: Specification<bool>(
requirement: Requirement.no,
validator: booleanValidator,
diff --git a/lib/src/config_provider/spec_utils.dart b/lib/src/config_provider/spec_utils.dart
index ff4a44a..a08d8c8 100644
--- a/lib/src/config_provider/spec_utils.dart
+++ b/lib/src/config_provider/spec_utils.dart
@@ -339,28 +339,6 @@
}
}
-String llvmLibExtractor(dynamic value) {
- // Extract libclang's dylib from this.
- final p = findLibclangDylib(value as String);
- if (p == null) {
- _logger.severe("Couldn't find ${strings.dylibFileName} at $value.");
- exit(1);
- } else {
- return p;
- }
-}
-
-bool llvmLibValidator(List<String> name, dynamic value) {
- _logger.warning(
- 'Deprecated ${strings.llvmLib}: please use ${strings.llvmPath} instead.');
- if (!checkType<String>(name, value) ||
- !Directory(value as String).existsSync()) {
- _logger.severe('Expected $name to be a valid folder Path.');
- return false;
- }
- return true;
-}
-
String llvmPathExtractor(dynamic value) {
// Extract libclang's dylib from user specified paths.
for (final path in (value as YamlList)) {
diff --git a/lib/src/header_parser/clang_bindings/clang_bindings.dart b/lib/src/header_parser/clang_bindings/clang_bindings.dart
index 2c69fa7..0525565 100644
--- a/lib/src/header_parser/clang_bindings/clang_bindings.dart
+++ b/lib/src/header_parser/clang_bindings/clang_bindings.dart
@@ -1195,70 +1195,21 @@
/// Use clang_getExpansionLocation() or clang_getSpellingLocation()
/// to map a source location to a particular file, line, and column.
class CXSourceLocation extends ffi.Struct {
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
- /// Helper for array `ptr_data`.
- ArrayHelper_CXSourceLocation_ptr_data_level0 get ptr_data =>
- ArrayHelper_CXSourceLocation_ptr_data_level0(this, [2], 0, 0);
@ffi.Uint32()
external int int_data;
}
-/// Helper for array `ptr_data` in struct `CXSourceLocation`.
-class ArrayHelper_CXSourceLocation_ptr_data_level0 {
- final CXSourceLocation _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXSourceLocation_ptr_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_ptr_data_item_0;
- case 1:
- return _struct._unique_ptr_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_ptr_data_item_0 = value;
- break;
- case 1:
- _struct._unique_ptr_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// Identifies a half-open character range in the source code.
///
/// Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the
/// starting and end locations from a source range, respectively.
class CXSourceRange extends ffi.Struct {
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
- /// Helper for array `ptr_data`.
- ArrayHelper_CXSourceRange_ptr_data_level0 get ptr_data =>
- ArrayHelper_CXSourceRange_ptr_data_level0(this, [2], 0, 0);
@ffi.Uint32()
external int begin_int_data;
@@ -1266,49 +1217,6 @@
external int end_int_data;
}
-/// Helper for array `ptr_data` in struct `CXSourceRange`.
-class ArrayHelper_CXSourceRange_ptr_data_level0 {
- final CXSourceRange _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXSourceRange_ptr_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_ptr_data_item_0;
- case 1:
- return _struct._unique_ptr_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_ptr_data_item_0 = value;
- break;
- case 1:
- _struct._unique_ptr_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// Options to control the display of diagnostics.
///
/// The values in this enum are meant to be combined to customize the
@@ -2292,61 +2200,8 @@
@ffi.Int32()
external int xdata;
- external ffi.Pointer<ffi.Void> _unique_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_data_item_1;
- external ffi.Pointer<ffi.Void> _unique_data_item_2;
-
- /// Helper for array `data`.
- ArrayHelper_CXCursor_data_level0 get data =>
- ArrayHelper_CXCursor_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXCursor`.
-class ArrayHelper_CXCursor_data_level0 {
- final CXCursor _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXCursor_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- case 2:
- return _struct._unique_data_item_2;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- case 2:
- _struct._unique_data_item_2 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([3])
+ external ffi.Array<ffi.Pointer<ffi.Void>> data;
}
/// Describes the kind of type
@@ -2484,55 +2339,8 @@
@ffi.Int32()
external int kind;
- external ffi.Pointer<ffi.Void> _unique_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_data_item_1;
-
- /// Helper for array `data`.
- ArrayHelper_CXType_data_level0 get data =>
- ArrayHelper_CXType_data_level0(this, [2], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXType`.
-class ArrayHelper_CXType_data_level0 {
- final CXType _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXType_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> data;
}
/// Describes how the traversal of the children of a particular
diff --git a/lib/src/header_parser/sub_parsers/structdecl_parser.dart b/lib/src/header_parser/sub_parsers/structdecl_parser.dart
index c27d841..e5970f4 100644
--- a/lib/src/header_parser/sub_parsers/structdecl_parser.dart
+++ b/lib/src/header_parser/sub_parsers/structdecl_parser.dart
@@ -21,7 +21,6 @@
Struc? struc;
bool unimplementedMemberType = false;
bool flexibleArrayMember = false;
- bool arrayMember = false;
bool bitFieldMember = false;
bool dartHandleMember = false;
bool incompleteStructMember = false;
@@ -29,7 +28,6 @@
bool get isInComplete =>
unimplementedMemberType ||
flexibleArrayMember ||
- (arrayMember && !config.arrayWorkaround) ||
bitFieldMember ||
(dartHandleMember && config.useDartHandle) ||
incompleteStructMember;
@@ -168,12 +166,7 @@
visitChildrenResultChecker(resultCode);
- if (_stack.top.arrayMember && !config.arrayWorkaround) {
- _logger.fine(
- '---- Removed Struct members, reason: struct has array members ${cursor.completeStringRepr()}');
- _logger.warning(
- 'Removed All Struct Members from: ${_stack.top.struc!.name}(${_stack.top.struc!.originalName}), Array members not supported');
- } else if (_stack.top.unimplementedMemberType) {
+ if (_stack.top.unimplementedMemberType) {
_logger.fine(
'---- Removed Struct members, reason: member with unimplementedtype ${cursor.completeStringRepr()}');
_logger.warning(
@@ -227,9 +220,6 @@
}
final mt = cursor.type().toCodeGenType();
- if (mt.broadType == BroadType.ConstantArray) {
- _stack.top.arrayMember = true;
- }
if (mt.broadType == BroadType.IncompleteArray) {
// TODO(68): Structs with flexible Array Members are not supported.
_stack.top.flexibleArrayMember = true;
diff --git a/lib/src/strings.dart b/lib/src/strings.dart
index 76ed940..0b5d2f1 100644
--- a/lib/src/strings.dart
+++ b/lib/src/strings.dart
@@ -22,7 +22,6 @@
return name;
}
-const llvmLib = 'llvm-lib';
const llvmPath = 'llvm-path';
/// Name of the parent folder of dynamic library `lib` or `bin` (on windows).
@@ -123,8 +122,6 @@
// Boolean flags.
const sort = 'sort';
const useSupportedTypedefs = 'use-supported-typedefs';
-const warnWhenRemoving = 'warn-when-removing';
-const arrayWorkaround = 'array-workaround';
const dartBool = 'dart-bool';
const useDartHandle = 'use-dart-handle';
diff --git a/pubspec.yaml b/pubspec.yaml
index e761291..15555a2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
name: ffigen
-version: 2.5.0-beta.1
+version: 3.0.0-beta.0
homepage: https://github.com/dart-lang/ffigen
description: Generator for FFI bindings, using LibClang to parse C header files.
diff --git a/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart b/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart
index 5e599fc..4556dfa 100644
--- a/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart
+++ b/test/code_generator_tests/expected_bindings/_expected_internal_conflict_resolution_bindings.dart
@@ -59,57 +59,8 @@
}
class _Test extends ffi.Struct {
- @ffi.Int8()
- external int _unique_array_item_0;
- @ffi.Int8()
- external int _unique_array_item_1;
-
- /// Helper for array `array`.
- ArrayHelper1__Test_array_level0 get array =>
- ArrayHelper1__Test_array_level0(this, [2], 0, 0);
-}
-
-/// Helper for array `array` in struct `_Test`.
-class ArrayHelper1__Test_array_level0 {
- final _Test _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper1__Test_array_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- int operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_array_item_0;
- case 1:
- return _struct._unique_array_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, int value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_array_item_0 = value;
- break;
- case 1:
- _struct._unique_array_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Int8> array;
}
class ArrayHelperPrefixCollisionTest extends ffi.Opaque {}
diff --git a/test/example_tests/libclang_example_test.dart b/test/example_tests/libclang_example_test.dart
index f385b00..deed803 100644
--- a/test/example_tests/libclang_example_test.dart
+++ b/test/example_tests/libclang_example_test.dart
@@ -43,7 +43,6 @@
${strings.name}: 'LibClang'
${strings.description}: 'Holds bindings to LibClang.'
-${strings.arrayWorkaround}: true
${strings.comments}:
${strings.style}: ${strings.doxygen}
${strings.length}: ${strings.full}
diff --git a/test/header_parser_tests/nested_parsing_test.dart b/test/header_parser_tests/nested_parsing_test.dart
index 978b365..4dc9427 100644
--- a/test/header_parser_tests/nested_parsing_test.dart
+++ b/test/header_parser_tests/nested_parsing_test.dart
@@ -23,7 +23,6 @@
${strings.name}: 'NativeLibrary'
${strings.description}: 'Nested Parsing Test'
${strings.output}: 'unused'
-${strings.arrayWorkaround}: true
${strings.headers}:
${strings.entryPoints}:
- 'test/header_parser_tests/nested_parsing.h'
diff --git a/test/large_integration_tests/_expected_libclang_bindings.dart b/test/large_integration_tests/_expected_libclang_bindings.dart
index 34c6633..be68fb5 100644
--- a/test/large_integration_tests/_expected_libclang_bindings.dart
+++ b/test/large_integration_tests/_expected_libclang_bindings.dart
@@ -5937,129 +5937,24 @@
/// Uniquely identifies a CXFile, that refers to the same underlying file,
/// across an indexing session.
class CXFileUniqueID extends ffi.Struct {
- @ffi.Uint64()
- external int _unique_data_item_0;
- @ffi.Uint64()
- external int _unique_data_item_1;
- @ffi.Uint64()
- external int _unique_data_item_2;
-
- /// Helper for array `data`.
- ArrayHelper_CXFileUniqueID_data_level0 get data =>
- ArrayHelper_CXFileUniqueID_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXFileUniqueID`.
-class ArrayHelper_CXFileUniqueID_data_level0 {
- final CXFileUniqueID _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXFileUniqueID_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- int operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- case 2:
- return _struct._unique_data_item_2;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, int value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- case 2:
- _struct._unique_data_item_2 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([3])
+ external ffi.Array<ffi.Uint64> data;
}
/// Identifies a specific source location within a translation unit.
class CXSourceLocation extends ffi.Struct {
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
- /// Helper for array `ptr_data`.
- ArrayHelper_CXSourceLocation_ptr_data_level0 get ptr_data =>
- ArrayHelper_CXSourceLocation_ptr_data_level0(this, [2], 0, 0);
@ffi.Uint32()
external int int_data;
}
-/// Helper for array `ptr_data` in struct `CXSourceLocation`.
-class ArrayHelper_CXSourceLocation_ptr_data_level0 {
- final CXSourceLocation _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXSourceLocation_ptr_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_ptr_data_item_0;
- case 1:
- return _struct._unique_ptr_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_ptr_data_item_0 = value;
- break;
- case 1:
- _struct._unique_ptr_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// Identifies a half-open character range in the source code.
class CXSourceRange extends ffi.Struct {
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
- /// Helper for array `ptr_data`.
- ArrayHelper_CXSourceRange_ptr_data_level0 get ptr_data =>
- ArrayHelper_CXSourceRange_ptr_data_level0(this, [2], 0, 0);
@ffi.Uint32()
external int begin_int_data;
@@ -6067,49 +5962,6 @@
external int end_int_data;
}
-/// Helper for array `ptr_data` in struct `CXSourceRange`.
-class ArrayHelper_CXSourceRange_ptr_data_level0 {
- final CXSourceRange _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXSourceRange_ptr_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_ptr_data_item_0;
- case 1:
- return _struct._unique_ptr_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_ptr_data_item_0 = value;
- break;
- case 1:
- _struct._unique_ptr_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// Identifies an array of ranges.
class CXSourceRangeList extends ffi.Struct {
/// The number of ranges in the ranges array.
@@ -6977,61 +6829,8 @@
@ffi.Int32()
external int xdata;
- external ffi.Pointer<ffi.Void> _unique_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_data_item_1;
- external ffi.Pointer<ffi.Void> _unique_data_item_2;
-
- /// Helper for array `data`.
- ArrayHelper_CXCursor_data_level0 get data =>
- ArrayHelper_CXCursor_data_level0(this, [3], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXCursor`.
-class ArrayHelper_CXCursor_data_level0 {
- final CXCursor _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXCursor_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- case 2:
- return _struct._unique_data_item_2;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- case 2:
- _struct._unique_data_item_2 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([3])
+ external ffi.Array<ffi.Pointer<ffi.Void>> data;
}
/// Describe the linkage of the entity referred to by a cursor.
@@ -7271,55 +7070,8 @@
@ffi.Int32()
external int kind;
- external ffi.Pointer<ffi.Void> _unique_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_data_item_1;
-
- /// Helper for array `data`.
- ArrayHelper_CXType_data_level0 get data =>
- ArrayHelper_CXType_data_level0(this, [2], 0, 0);
-}
-
-/// Helper for array `data` in struct `CXType`.
-class ArrayHelper_CXType_data_level0 {
- final CXType _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXType_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> data;
}
/// Describes the kind of a template argument.
@@ -7515,74 +7267,12 @@
/// Describes a single preprocessing token.
class CXToken extends ffi.Struct {
- @ffi.Uint32()
- external int _unique_int_data_item_0;
- @ffi.Uint32()
- external int _unique_int_data_item_1;
- @ffi.Uint32()
- external int _unique_int_data_item_2;
- @ffi.Uint32()
- external int _unique_int_data_item_3;
+ @ffi.Array.multi([4])
+ external ffi.Array<ffi.Uint32> int_data;
- /// Helper for array `int_data`.
- ArrayHelper_CXToken_int_data_level0 get int_data =>
- ArrayHelper_CXToken_int_data_level0(this, [4], 0, 0);
external ffi.Pointer<ffi.Void> ptr_data;
}
-/// Helper for array `int_data` in struct `CXToken`.
-class ArrayHelper_CXToken_int_data_level0 {
- final CXToken _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXToken_int_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- int operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_int_data_item_0;
- case 1:
- return _struct._unique_int_data_item_1;
- case 2:
- return _struct._unique_int_data_item_2;
- case 3:
- return _struct._unique_int_data_item_3;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, int value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_int_data_item_0 = value;
- break;
- case 1:
- _struct._unique_int_data_item_1 = value;
- break;
- case 2:
- _struct._unique_int_data_item_2 = value;
- break;
- case 3:
- _struct._unique_int_data_item_3 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// A single result of code completion.
class CXCompletionResult extends ffi.Struct {
/// The kind of entity that this completion refers to.
@@ -7829,59 +7519,13 @@
/// Source location passed to index callbacks.
class CXIdxLoc extends ffi.Struct {
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_0;
- external ffi.Pointer<ffi.Void> _unique_ptr_data_item_1;
+ @ffi.Array.multi([2])
+ external ffi.Array<ffi.Pointer<ffi.Void>> ptr_data;
- /// Helper for array `ptr_data`.
- ArrayHelper_CXIdxLoc_ptr_data_level0 get ptr_data =>
- ArrayHelper_CXIdxLoc_ptr_data_level0(this, [2], 0, 0);
@ffi.Uint32()
external int int_data;
}
-/// Helper for array `ptr_data` in struct `CXIdxLoc`.
-class ArrayHelper_CXIdxLoc_ptr_data_level0 {
- final CXIdxLoc _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_CXIdxLoc_ptr_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ffi.Pointer<ffi.Void> operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_ptr_data_item_0;
- case 1:
- return _struct._unique_ptr_data_item_1;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, ffi.Pointer<ffi.Void> value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_ptr_data_item_0 = value;
- break;
- case 1:
- _struct._unique_ptr_data_item_1 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-}
-
/// Data for ppIncludedFile callback.
class CXIdxIncludedFileInfo extends ffi.Struct {
/// Location of '#' in the #include/#import directive.
diff --git a/test/large_integration_tests/_expected_sqlite_bindings.dart b/test/large_integration_tests/_expected_sqlite_bindings.dart
index 3a7e50e..9580bd1 100644
--- a/test/large_integration_tests/_expected_sqlite_bindings.dart
+++ b/test/large_integration_tests/_expected_sqlite_bindings.dart
@@ -10061,379 +10061,8 @@
/// transaction that sees that historical version of the database rather than
/// the most recent version.
class sqlite3_snapshot extends ffi.Struct {
- @ffi.Uint8()
- external int _unique_hidden_item_0;
- @ffi.Uint8()
- external int _unique_hidden_item_1;
- @ffi.Uint8()
- external int _unique_hidden_item_2;
- @ffi.Uint8()
- external int _unique_hidden_item_3;
- @ffi.Uint8()
- external int _unique_hidden_item_4;
- @ffi.Uint8()
- external int _unique_hidden_item_5;
- @ffi.Uint8()
- external int _unique_hidden_item_6;
- @ffi.Uint8()
- external int _unique_hidden_item_7;
- @ffi.Uint8()
- external int _unique_hidden_item_8;
- @ffi.Uint8()
- external int _unique_hidden_item_9;
- @ffi.Uint8()
- external int _unique_hidden_item_10;
- @ffi.Uint8()
- external int _unique_hidden_item_11;
- @ffi.Uint8()
- external int _unique_hidden_item_12;
- @ffi.Uint8()
- external int _unique_hidden_item_13;
- @ffi.Uint8()
- external int _unique_hidden_item_14;
- @ffi.Uint8()
- external int _unique_hidden_item_15;
- @ffi.Uint8()
- external int _unique_hidden_item_16;
- @ffi.Uint8()
- external int _unique_hidden_item_17;
- @ffi.Uint8()
- external int _unique_hidden_item_18;
- @ffi.Uint8()
- external int _unique_hidden_item_19;
- @ffi.Uint8()
- external int _unique_hidden_item_20;
- @ffi.Uint8()
- external int _unique_hidden_item_21;
- @ffi.Uint8()
- external int _unique_hidden_item_22;
- @ffi.Uint8()
- external int _unique_hidden_item_23;
- @ffi.Uint8()
- external int _unique_hidden_item_24;
- @ffi.Uint8()
- external int _unique_hidden_item_25;
- @ffi.Uint8()
- external int _unique_hidden_item_26;
- @ffi.Uint8()
- external int _unique_hidden_item_27;
- @ffi.Uint8()
- external int _unique_hidden_item_28;
- @ffi.Uint8()
- external int _unique_hidden_item_29;
- @ffi.Uint8()
- external int _unique_hidden_item_30;
- @ffi.Uint8()
- external int _unique_hidden_item_31;
- @ffi.Uint8()
- external int _unique_hidden_item_32;
- @ffi.Uint8()
- external int _unique_hidden_item_33;
- @ffi.Uint8()
- external int _unique_hidden_item_34;
- @ffi.Uint8()
- external int _unique_hidden_item_35;
- @ffi.Uint8()
- external int _unique_hidden_item_36;
- @ffi.Uint8()
- external int _unique_hidden_item_37;
- @ffi.Uint8()
- external int _unique_hidden_item_38;
- @ffi.Uint8()
- external int _unique_hidden_item_39;
- @ffi.Uint8()
- external int _unique_hidden_item_40;
- @ffi.Uint8()
- external int _unique_hidden_item_41;
- @ffi.Uint8()
- external int _unique_hidden_item_42;
- @ffi.Uint8()
- external int _unique_hidden_item_43;
- @ffi.Uint8()
- external int _unique_hidden_item_44;
- @ffi.Uint8()
- external int _unique_hidden_item_45;
- @ffi.Uint8()
- external int _unique_hidden_item_46;
- @ffi.Uint8()
- external int _unique_hidden_item_47;
-
- /// Helper for array `hidden`.
- ArrayHelper_sqlite3_snapshot_hidden_level0 get hidden =>
- ArrayHelper_sqlite3_snapshot_hidden_level0(this, [48], 0, 0);
-}
-
-/// Helper for array `hidden` in struct `sqlite3_snapshot`.
-class ArrayHelper_sqlite3_snapshot_hidden_level0 {
- final sqlite3_snapshot _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_sqlite3_snapshot_hidden_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- int operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_hidden_item_0;
- case 1:
- return _struct._unique_hidden_item_1;
- case 2:
- return _struct._unique_hidden_item_2;
- case 3:
- return _struct._unique_hidden_item_3;
- case 4:
- return _struct._unique_hidden_item_4;
- case 5:
- return _struct._unique_hidden_item_5;
- case 6:
- return _struct._unique_hidden_item_6;
- case 7:
- return _struct._unique_hidden_item_7;
- case 8:
- return _struct._unique_hidden_item_8;
- case 9:
- return _struct._unique_hidden_item_9;
- case 10:
- return _struct._unique_hidden_item_10;
- case 11:
- return _struct._unique_hidden_item_11;
- case 12:
- return _struct._unique_hidden_item_12;
- case 13:
- return _struct._unique_hidden_item_13;
- case 14:
- return _struct._unique_hidden_item_14;
- case 15:
- return _struct._unique_hidden_item_15;
- case 16:
- return _struct._unique_hidden_item_16;
- case 17:
- return _struct._unique_hidden_item_17;
- case 18:
- return _struct._unique_hidden_item_18;
- case 19:
- return _struct._unique_hidden_item_19;
- case 20:
- return _struct._unique_hidden_item_20;
- case 21:
- return _struct._unique_hidden_item_21;
- case 22:
- return _struct._unique_hidden_item_22;
- case 23:
- return _struct._unique_hidden_item_23;
- case 24:
- return _struct._unique_hidden_item_24;
- case 25:
- return _struct._unique_hidden_item_25;
- case 26:
- return _struct._unique_hidden_item_26;
- case 27:
- return _struct._unique_hidden_item_27;
- case 28:
- return _struct._unique_hidden_item_28;
- case 29:
- return _struct._unique_hidden_item_29;
- case 30:
- return _struct._unique_hidden_item_30;
- case 31:
- return _struct._unique_hidden_item_31;
- case 32:
- return _struct._unique_hidden_item_32;
- case 33:
- return _struct._unique_hidden_item_33;
- case 34:
- return _struct._unique_hidden_item_34;
- case 35:
- return _struct._unique_hidden_item_35;
- case 36:
- return _struct._unique_hidden_item_36;
- case 37:
- return _struct._unique_hidden_item_37;
- case 38:
- return _struct._unique_hidden_item_38;
- case 39:
- return _struct._unique_hidden_item_39;
- case 40:
- return _struct._unique_hidden_item_40;
- case 41:
- return _struct._unique_hidden_item_41;
- case 42:
- return _struct._unique_hidden_item_42;
- case 43:
- return _struct._unique_hidden_item_43;
- case 44:
- return _struct._unique_hidden_item_44;
- case 45:
- return _struct._unique_hidden_item_45;
- case 46:
- return _struct._unique_hidden_item_46;
- case 47:
- return _struct._unique_hidden_item_47;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, int value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_hidden_item_0 = value;
- break;
- case 1:
- _struct._unique_hidden_item_1 = value;
- break;
- case 2:
- _struct._unique_hidden_item_2 = value;
- break;
- case 3:
- _struct._unique_hidden_item_3 = value;
- break;
- case 4:
- _struct._unique_hidden_item_4 = value;
- break;
- case 5:
- _struct._unique_hidden_item_5 = value;
- break;
- case 6:
- _struct._unique_hidden_item_6 = value;
- break;
- case 7:
- _struct._unique_hidden_item_7 = value;
- break;
- case 8:
- _struct._unique_hidden_item_8 = value;
- break;
- case 9:
- _struct._unique_hidden_item_9 = value;
- break;
- case 10:
- _struct._unique_hidden_item_10 = value;
- break;
- case 11:
- _struct._unique_hidden_item_11 = value;
- break;
- case 12:
- _struct._unique_hidden_item_12 = value;
- break;
- case 13:
- _struct._unique_hidden_item_13 = value;
- break;
- case 14:
- _struct._unique_hidden_item_14 = value;
- break;
- case 15:
- _struct._unique_hidden_item_15 = value;
- break;
- case 16:
- _struct._unique_hidden_item_16 = value;
- break;
- case 17:
- _struct._unique_hidden_item_17 = value;
- break;
- case 18:
- _struct._unique_hidden_item_18 = value;
- break;
- case 19:
- _struct._unique_hidden_item_19 = value;
- break;
- case 20:
- _struct._unique_hidden_item_20 = value;
- break;
- case 21:
- _struct._unique_hidden_item_21 = value;
- break;
- case 22:
- _struct._unique_hidden_item_22 = value;
- break;
- case 23:
- _struct._unique_hidden_item_23 = value;
- break;
- case 24:
- _struct._unique_hidden_item_24 = value;
- break;
- case 25:
- _struct._unique_hidden_item_25 = value;
- break;
- case 26:
- _struct._unique_hidden_item_26 = value;
- break;
- case 27:
- _struct._unique_hidden_item_27 = value;
- break;
- case 28:
- _struct._unique_hidden_item_28 = value;
- break;
- case 29:
- _struct._unique_hidden_item_29 = value;
- break;
- case 30:
- _struct._unique_hidden_item_30 = value;
- break;
- case 31:
- _struct._unique_hidden_item_31 = value;
- break;
- case 32:
- _struct._unique_hidden_item_32 = value;
- break;
- case 33:
- _struct._unique_hidden_item_33 = value;
- break;
- case 34:
- _struct._unique_hidden_item_34 = value;
- break;
- case 35:
- _struct._unique_hidden_item_35 = value;
- break;
- case 36:
- _struct._unique_hidden_item_36 = value;
- break;
- case 37:
- _struct._unique_hidden_item_37 = value;
- break;
- case 38:
- _struct._unique_hidden_item_38 = value;
- break;
- case 39:
- _struct._unique_hidden_item_39 = value;
- break;
- case 40:
- _struct._unique_hidden_item_40 = value;
- break;
- case 41:
- _struct._unique_hidden_item_41 = value;
- break;
- case 42:
- _struct._unique_hidden_item_42 = value;
- break;
- case 43:
- _struct._unique_hidden_item_43 = value;
- break;
- case 44:
- _struct._unique_hidden_item_44 = value;
- break;
- case 45:
- _struct._unique_hidden_item_45 = value;
- break;
- case 46:
- _struct._unique_hidden_item_46 = value;
- break;
- case 47:
- _struct._unique_hidden_item_47 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([48])
+ external ffi.Array<ffi.Uint8> hidden;
}
/// A pointer to a structure of the following type is passed as the first
diff --git a/test/large_integration_tests/large_test.dart b/test/large_integration_tests/large_test.dart
index 2815a1f..fc38fb3 100644
--- a/test/large_integration_tests/large_test.dart
+++ b/test/large_integration_tests/large_test.dart
@@ -23,7 +23,6 @@
${strings.description}: Bindings to LibClang.
${strings.output}: unused
${strings.compilerOpts}: -I${path.join('third_party', 'libclang', 'include')}
-${strings.arrayWorkaround}: true
${strings.comments}:
${strings.style}: ${strings.doxygen}
${strings.length}: ${strings.brief}
@@ -55,7 +54,6 @@
${strings.output}: unused
${strings.comments}:
${strings.length}: ${strings.full}
-${strings.arrayWorkaround}: true
${strings.headers}:
${strings.entryPoints}:
- third_party/cjson_library/cJSON.h
@@ -78,7 +76,6 @@
${strings.name}: SQLite
${strings.description}: Bindings to SQLite.
${strings.output}: unused
-${strings.arrayWorkaround}: true
${strings.comments}:
${strings.style}: ${strings.any}
${strings.length}: ${strings.full}
diff --git a/test/native_test/config.yaml b/test/native_test/config.yaml
index 6c7b239..d68a62f 100644
--- a/test/native_test/config.yaml
+++ b/test/native_test/config.yaml
@@ -14,6 +14,5 @@
- 'test/native_test/native_test.c'
include-directives:
- '**native_test.c'
-array-workaround: true
compiler-opts: '-Wno-nullability-completeness'
diff --git a/test/native_test/native_test.dart b/test/native_test/native_test.dart
index 5e90a0b..08e1475 100644
--- a/test/native_test/native_test.dart
+++ b/test/native_test/native_test.dart
@@ -91,19 +91,20 @@
test('double', () {
expect(bindings.Function1Double(0), 42.0);
});
- test('array-workaround: Order of access', () {
+ test('Array Test: Order of access', () {
final struct1 = bindings.getStruct1();
var expectedValue = 1;
- for (var i = 0; i < struct1.ref.data.dimensions[0]; i++) {
- for (var j = 0; j < struct1.ref.data.dimensions[1]; j++) {
- for (var k = 0; k < struct1.ref.data.dimensions[2]; k++) {
+ final dimensions = [3, 1, 2];
+ for (var i = 0; i < dimensions[0]; i++) {
+ for (var j = 0; j < dimensions[1]; j++) {
+ for (var k = 0; k < dimensions[2]; k++) {
expect(struct1.ref.data[i][j][k], expectedValue);
expectedValue++;
}
}
}
});
- test('array-workaround: Range Errors', () {
+ test('Array Workaround: Range Errors', () {
final struct1 = bindings.getStruct1();
// Index (get) above range.
expect(
diff --git a/test/native_test/native_test_bindings.dart b/test/native_test/native_test_bindings.dart
index f409db8..620771c 100644
--- a/test/native_test/native_test_bindings.dart
+++ b/test/native_test/native_test_bindings.dart
@@ -224,139 +224,8 @@
@ffi.Int8()
external int a;
- @ffi.Int32()
- external int _unique_data_item_0;
- @ffi.Int32()
- external int _unique_data_item_1;
- @ffi.Int32()
- external int _unique_data_item_2;
- @ffi.Int32()
- external int _unique_data_item_3;
- @ffi.Int32()
- external int _unique_data_item_4;
- @ffi.Int32()
- external int _unique_data_item_5;
-
- /// Helper for array `data`.
- ArrayHelper_Struct1_data_level0 get data =>
- ArrayHelper_Struct1_data_level0(this, [3, 1, 2], 0, 0);
-}
-
-/// Helper for array `data` in struct `Struct1`.
-class ArrayHelper_Struct1_data_level0 {
- final Struct1 _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_Struct1_data_level0(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ArrayHelper_Struct1_data_level1 operator [](int index) {
- _checkBounds(index);
- var offset = index;
- for (var i = level + 1; i < dimensions.length; i++) {
- offset *= dimensions[i];
- }
- return ArrayHelper_Struct1_data_level1(
- _struct, dimensions, level + 1, _absoluteIndex + offset);
- }
-}
-
-/// Helper for array `data` in struct `Struct1`.
-class ArrayHelper_Struct1_data_level1 {
- final Struct1 _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_Struct1_data_level1(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- ArrayHelper_Struct1_data_level2 operator [](int index) {
- _checkBounds(index);
- var offset = index;
- for (var i = level + 1; i < dimensions.length; i++) {
- offset *= dimensions[i];
- }
- return ArrayHelper_Struct1_data_level2(
- _struct, dimensions, level + 1, _absoluteIndex + offset);
- }
-}
-
-/// Helper for array `data` in struct `Struct1`.
-class ArrayHelper_Struct1_data_level2 {
- final Struct1 _struct;
- final List<int> dimensions;
- final int level;
- final int _absoluteIndex;
- int get length => dimensions[level];
- ArrayHelper_Struct1_data_level2(
- this._struct, this.dimensions, this.level, this._absoluteIndex);
- void _checkBounds(int index) {
- if (index >= length || index < 0) {
- throw RangeError(
- 'Dimension $level: index not in range 0..$length exclusive.');
- }
- }
-
- int operator [](int index) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- return _struct._unique_data_item_0;
- case 1:
- return _struct._unique_data_item_1;
- case 2:
- return _struct._unique_data_item_2;
- case 3:
- return _struct._unique_data_item_3;
- case 4:
- return _struct._unique_data_item_4;
- case 5:
- return _struct._unique_data_item_5;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
-
- void operator []=(int index, int value) {
- _checkBounds(index);
- switch (_absoluteIndex + index) {
- case 0:
- _struct._unique_data_item_0 = value;
- break;
- case 1:
- _struct._unique_data_item_1 = value;
- break;
- case 2:
- _struct._unique_data_item_2 = value;
- break;
- case 3:
- _struct._unique_data_item_3 = value;
- break;
- case 4:
- _struct._unique_data_item_4 = value;
- break;
- case 5:
- _struct._unique_data_item_5 = value;
- break;
- default:
- throw Exception('Invalid Array Helper generated.');
- }
- }
+ @ffi.Array.multi([3, 1, 2])
+ external ffi.Array<ffi.Array<ffi.Array<ffi.Int32>>> data;
}
class Struct3 extends ffi.Struct {
diff --git a/tool/libclang_config.yaml b/tool/libclang_config.yaml
index 87f6bb0..b6af5e1 100644
--- a/tool/libclang_config.yaml
+++ b/tool/libclang_config.yaml
@@ -23,7 +23,6 @@
- '**Index.h'
- '**CXString.h'
-array-workaround: true
preamble: |
// Part of the LLVM Project, under the Apache License v2.0 with LLVM
// Exceptions.