Skip to content

Commit

Permalink
[ffigen][swift2objc] Some small fixes (#1777)
Browse files Browse the repository at this point in the history
  • Loading branch information
liamappelbe authored Dec 3, 2024
1 parent 3210a79 commit aa82b97
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 25 deletions.
9 changes: 8 additions & 1 deletion pkgs/ffigen/lib/ffigen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,12 @@
/// https://pub.dev/packages/ffigen for details.
library ffigen;

export 'src/config_provider.dart' show Config, YamlConfig;
export 'src/config_provider.dart'
show
Config,
DeclarationFilters,
ExternalVersions,
Language,
Versions,
YamlConfig;
export 'src/ffigen.dart' show FfiGen;
15 changes: 15 additions & 0 deletions pkgs/ffigen/lib/src/code_generator/pointer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,15 @@ class ObjCObjectPointer extends PointerType {

@override
String? generateRetain(String value) => 'objc_retain($value)';

@override
bool isSupertypeOf(Type other) {
other = other.typealiasType;
// id/Object* is a supertype of all ObjC objects and blocks.
return other is ObjCObjectPointer ||
other is ObjCInterface ||
other is ObjCBlock;
}
}

/// A pointer to an Objective C block.
Expand All @@ -168,4 +177,10 @@ class ObjCBlockPointer extends ObjCObjectPointer {

@override
String? generateRetain(String value) => 'objc_retainBlock($value)';

@override
bool isSupertypeOf(Type other) {
other = other.typealiasType;
return other is ObjCBlockPointer || other is ObjCBlock;
}
}
1 change: 1 addition & 0 deletions pkgs/ffigen/lib/src/config_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
library config_provider;

export 'config_provider/config.dart';
export 'config_provider/config_types.dart';
export 'config_provider/yaml_config.dart';
1 change: 0 additions & 1 deletion pkgs/ffigen/lib/src/header_parser/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import 'package:logging/logging.dart';
import '../code_generator.dart';
import '../code_generator/utils.dart';
import '../config_provider.dart';
import '../config_provider/config_types.dart';
import '../strings.dart' as strings;
import '../visitor/apply_config_filters.dart';
import '../visitor/ast.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ void _parseSuperType(clang_types.CXCursor cursor, ObjCInterface itf) {
kind: ObjCMethodKind.propertySetter,
isClassMethod: isClassMethod,
isOptional: isOptionalMethod,
returnType: NativeType(SupportedNativeType.voidType),
returnType: voidType,
family: null,
);
setter.params
Expand Down
4 changes: 3 additions & 1 deletion pkgs/ffigen/lib/src/visitor/fix_overridden_methods.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ class FixOverriddenMethodsVisitation extends Visitation {
final (root, rootMethod) = _findRootWithMethod(node, method);
// If method and rootMethod are the same kind, then there's nothing to do.
if ((method.kind == ObjCMethodKind.propertyGetter) ==
(rootMethod.kind == ObjCMethodKind.propertyGetter)) continue;
(rootMethod.kind == ObjCMethodKind.propertyGetter)) {
continue;
}
_convertAllSubtreeMethodsToProperties(root, rootMethod);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import 'dart:io';

import 'package:ffigen/ffigen.dart';
import 'package:ffigen/src/code_generator/utils.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';
Expand Down
36 changes: 28 additions & 8 deletions pkgs/ffigen/test/unit_tests/subtyping_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ void main() {
final uncle = makeInterface('Uncle', grandparent);
final child = makeInterface('Child', parent);

ObjCBlock makeBlock(Type returnType, List<Type> argTypes) => ObjCBlock(
returnType: returnType,
params: [
for (final t in argTypes) Parameter(type: t, objCConsumed: false),
],
returnsRetained: false,
builtInFunctions: builtInFunctions);

group('ObjCInterface', () {
test('subtype', () {
expect(parent.isSubtypeOf(parent), isTrue);
Expand Down Expand Up @@ -140,14 +148,6 @@ void main() {
});

group('ObjCBlock', () {
ObjCBlock makeBlock(Type returnType, List<Type> argTypes) => ObjCBlock(
returnType: returnType,
params: [
for (final t in argTypes) Parameter(type: t, objCConsumed: false),
],
returnsRetained: false,
builtInFunctions: builtInFunctions);

test('covariant returns', () {
// Return types are covariant. S Function() <: T Function() if S <: T.
final returnsParent = makeBlock(parent, []);
Expand Down Expand Up @@ -237,5 +237,25 @@ void main() {
expect(makeTypealias(parent).isSubtypeOf(child), isFalse);
expect(parent.isSubtypeOf(makeTypealias(child)), isFalse);
});

test('ObjCObjectPointer', () {
expect(ObjCObjectPointer().isSubtypeOf(ObjCObjectPointer()), isTrue);
expect(parent.isSubtypeOf(ObjCObjectPointer()), isTrue);
expect(ObjCObjectPointer().isSubtypeOf(parent), isFalse);

final block = makeBlock(voidType, []);
expect(block.isSubtypeOf(ObjCObjectPointer()), isTrue);
expect(ObjCObjectPointer().isSubtypeOf(block), isFalse);
});

test('ObjCBlockPointer', () {
expect(ObjCBlockPointer().isSubtypeOf(ObjCBlockPointer()), isTrue);
expect(parent.isSubtypeOf(ObjCBlockPointer()), isFalse);
expect(ObjCBlockPointer().isSubtypeOf(parent), isFalse);

final block = makeBlock(voidType, []);
expect(block.isSubtypeOf(ObjCBlockPointer()), isTrue);
expect(ObjCBlockPointer().isSubtypeOf(block), isFalse);
});
});
}
6 changes: 3 additions & 3 deletions pkgs/objective_c/lib/src/objective_c_bindings_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2362,7 +2362,7 @@ class NSItemProvider extends NSObject {

/// setSuggestedName:
set suggestedName(NSString? value) {
return _objc_msgSend_1jdvcbf(this.ref.pointer, _sel_setSuggestedName_,
_objc_msgSend_1jdvcbf(this.ref.pointer, _sel_setSuggestedName_,
value?.ref.pointer ?? ffi.nullptr);
}

Expand Down Expand Up @@ -3074,7 +3074,7 @@ class NSMutableData extends NSData {

/// setLength:
set length(int value) {
return _objc_msgSend_1i9r4xy(this.ref.pointer, _sel_setLength_, value);
_objc_msgSend_1i9r4xy(this.ref.pointer, _sel_setLength_, value);
}
}

Expand Down Expand Up @@ -6228,7 +6228,7 @@ class NSStream extends NSObject {

/// setDelegate:
set delegate(objc.ObjCObjectBase? value) {
return _objc_msgSend_1jdvcbf(
_objc_msgSend_1jdvcbf(
this.ref.pointer, _sel_setDelegate_, value?.ref.pointer ?? ffi.nullptr);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enum BuiltInDeclaration implements Declaration, ObjCAnnotatable {
swiftNSObject(id: 'c:objc(cs)NSObject', name: 'NSObject'),
swiftString(id: 's:SS', name: 'String'),
swiftInt(id: 's:Si', name: 'Int'),
swiftFloat(id: 's:Sf', name: 'Float'),
swiftDouble(id: 's:Sd', name: 'Double'),
swiftBool(id: 's:Sb', name: 'Bool'),
swiftVoid(id: 's:s4Voida', name: 'Void');
Expand All @@ -32,6 +33,7 @@ enum BuiltInDeclaration implements Declaration, ObjCAnnotatable {
final objectType = BuiltInDeclaration.swiftNSObject.asDeclaredType;
final stringType = BuiltInDeclaration.swiftString.asDeclaredType;
final intType = BuiltInDeclaration.swiftInt.asDeclaredType;
final floatType = BuiltInDeclaration.swiftFloat.asDeclaredType;
final doubleType = BuiltInDeclaration.swiftDouble.asDeclaredType;
final boolType = BuiltInDeclaration.swiftBool.asDeclaredType;
final voidType = BuiltInDeclaration.swiftVoid.asDeclaredType;
18 changes: 9 additions & 9 deletions pkgs/swift2objc/lib/src/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ class Config {
/// Specify where the wrapper swift file will be output.
final Uri outputFile;

/// Specify where the wrapper swift file will be output.
/// Text inserted into the [outputFile] before the generated output.
final String? preamble;

/// Specify where to output the intermidiate files (i.g the symbolgraph json).
/// If this is null, a teemp directory will be generated in the system temp
/// directory (using `Directory.systemTemp`) and then deleted.
/// Specifying a temp directory would prevent the tool from deleting the
/// intermediate files after generating the wrapper
/// intermediate files after generating the wrapper.
final Uri? tempDir;

const Config({
Expand All @@ -46,12 +46,12 @@ sealed class InputConfig {
Command? get symbolgraphCommand;
}

/// Used to generate a objc wrapper for one or more swift files
/// Used to generate a objc wrapper for one or more swift files.
class FilesInputConfig implements InputConfig {
/// The swift file(s) to generate a wrapper for
/// The swift file(s) to generate a wrapper for.
final List<Uri> files;

/// The name of the module files generated by `swiftc in `tempDir`
/// The name of the module files generated by `swiftc in `tempDir`.
final String generatedModuleName;

FilesInputConfig({
Expand All @@ -74,17 +74,17 @@ class FilesInputConfig implements InputConfig {
);
}

/// Used to generate a objc wrapper for a built-in swift module
/// Used to generate a objc wrapper for a built-in swift module.
/// (e.g, AVFoundation)
class ModuleInputConfig implements InputConfig {
/// The swift module to generate a wrapper for
/// The swift module to generate a wrapper for.
final String module;

/// The target to generate code for
/// The target to generate code for.
/// (e.g `x86_64-apple-ios17.0-simulator`)
final String target;

/// The sdk to compile against
/// The sdk to compile against.
/// (e.g `/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sd`)
final Uri sdk;

Expand Down

0 comments on commit aa82b97

Please sign in to comment.