Skip to content

Commit

Permalink
[ffigen] Fix bug in NSRange import (#1602)
Browse files Browse the repository at this point in the history
  • Loading branch information
liamappelbe authored Sep 29, 2024
1 parent 1aae9da commit 963155d
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 11 deletions.
2 changes: 2 additions & 0 deletions pkgs/ffigen/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
ObjC but before the invocation was received by Dart:
https://github.com/dart-lang/native/issues/1571
- `sort:` config option now affects ObjC interface/protocol methods.
- Fix a bug where `NSRange` was not being imported from package:objective_c:
https://github.com/dart-lang/native/issues/1180

## 14.0.1

Expand Down
8 changes: 6 additions & 2 deletions pkgs/ffigen/lib/src/code_generator/compound.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ abstract class Compound extends BindingType {
}

bool get _isBuiltIn =>
objCBuiltInFunctions?.isBuiltInCompound(originalName) ?? false;
objCBuiltInFunctions?.getBuiltInCompoundName(originalName) != null;

@override
BindingString toBindingString(Writer w) {
Expand Down Expand Up @@ -188,7 +188,11 @@ abstract class Compound extends BindingType {
bool get isIncompleteCompound => isIncomplete;

@override
String getCType(Writer w) => _isBuiltIn ? '${w.objcPkgPrefix}.$name' : name;
String getCType(Writer w) {
final builtInName =
objCBuiltInFunctions?.getBuiltInCompoundName(originalName);
return builtInName != null ? '${w.objcPkgPrefix}.$builtInName' : name;
}

@override
String getNativeType({String varName = ''}) => '$nativeType $varName';
Expand Down
18 changes: 9 additions & 9 deletions pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ObjCBuiltInFunctions {
ObjCImport('UnimplementedOptionalMethodException');

// Keep in sync with pkgs/objective_c/ffigen_objc.yaml.
static const builtInInterfaces = {
static const _builtInInterfaces = {
'DartProxy',
'DartProxyBuilder',
'NSArray',
Expand Down Expand Up @@ -78,11 +78,11 @@ class ObjCBuiltInFunctions {
'NSValue',
'Protocol',
};
static const builtInCompounds = {
'NSFastEnumerationState',
'NSRange',
static const _builtInCompounds = {
'NSFastEnumerationState': 'NSFastEnumerationState',
'_NSRange': 'NSRange',
};
static const builtInEnums = {
static const _builtInEnums = {
'NSBinarySearchingOptions',
'NSComparisonResult',
'NSDataBase64DecodingOptions',
Expand Down Expand Up @@ -110,11 +110,11 @@ class ObjCBuiltInFunctions {
// TODO(https://github.com/dart-lang/native/issues/1173): Ideally this check
// would be based on more than just the name.
bool isBuiltInInterface(String name) =>
!generateForPackageObjectiveC && builtInInterfaces.contains(name);
bool isBuiltInCompound(String name) =>
!generateForPackageObjectiveC && builtInCompounds.contains(name);
!generateForPackageObjectiveC && _builtInInterfaces.contains(name);
String? getBuiltInCompoundName(String name) =>
generateForPackageObjectiveC ? null : _builtInCompounds[name];
bool isBuiltInEnum(String name) =>
!generateForPackageObjectiveC && builtInEnums.contains(name);
!generateForPackageObjectiveC && _builtInEnums.contains(name);
bool isNSObject(String name) => name == 'NSObject';

// We need to load a separate instance of objc_msgSend for each signature. If
Expand Down
44 changes: 44 additions & 0 deletions pkgs/ffigen/test/native_objc_test/ns_range_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Objective C support is only available on mac.
@TestOn('mac-os')

import 'dart:ffi';
import 'dart:io';

import 'package:ffi/ffi.dart';
import 'package:ffigen/ffigen.dart';
import 'package:ffigen/src/config_provider/config.dart';
import 'package:ffigen/src/config_provider/config_types.dart';
import 'package:logging/logging.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart';
import '../test_utils.dart';
import 'util.dart';

void main() {
group('NSRange', () {
late final String bindings;
setUpAll(() {
final config = Config(
wrapperName: 'NSRangeTestObjCLibrary',
language: Language.objc,
output: Uri.file('test/native_objc_test/ns_range_bindings.dart'),
entryPoints: [Uri.file('test/native_objc_test/ns_range_test.m')],
formatOutput: false,
objcInterfaces: DeclarationFilters.include({'SFTranscriptionSegment'}),
);
FfiGen(logLevel: Level.SEVERE).run(config);
bindings = File('test/native_objc_test/ns_range_bindings.dart')
.readAsStringSync();
});

test('interfaces', () {
// Regression test for https://github.com/dart-lang/native/issues/1180.
expect(bindings.split('\n'),
isNot(contains(matches(RegExp(r'class.*NSRange.*Struct')))));
});
});
}
5 changes: 5 additions & 0 deletions pkgs/ffigen/test/native_objc_test/ns_range_test.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#import <Speech/Speech.h>

0 comments on commit 963155d

Please sign in to comment.