Skip to content

Commit 0924cb0

Browse files
authored
[ffigen] Throw NSErrors returned as out-params (#2663)
1 parent 4e674f4 commit 0924cb0

File tree

13 files changed

+2552
-2324
lines changed

13 files changed

+2552
-2324
lines changed

pkgs/ffigen/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
- __Breaking_change__: The name collision resolution system has been overhauled
2727
to fix various bugs, and make the renaming more consistent. As a result, in
2828
some cases different names may be chosen when resolving collisions.
29+
- __Breaking_change__: Detect the ObjC error raising pattern, where the last
30+
param is `NSError** error`, capture any error returned, and throw it as a Dart
31+
`NSErrorException`.
2932
- Fix for opaque dependencies for struct/union const arrays.
3033

3134
## 19.1.0

pkgs/ffigen/example/objective_c/avf_audio_bindings.dart

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -813,24 +813,24 @@ class AVAudioPlayer extends objc.NSObject {
813813

814814
/// alloc
815815
static AVAudioPlayer alloc() {
816-
final _ret = _objc_msgSend_151sglz(_class_AVAudioPlayer, _sel_alloc);
817-
return AVAudioPlayer.castFromPointer(_ret, retain: false, release: true);
816+
final $ret = _objc_msgSend_151sglz(_class_AVAudioPlayer, _sel_alloc);
817+
return AVAudioPlayer.castFromPointer($ret, retain: false, release: true);
818818
}
819819

820820
/// allocWithZone:
821821
static AVAudioPlayer allocWithZone(ffi.Pointer<objc.NSZone> zone) {
822-
final _ret = _objc_msgSend_1cwp428(
822+
final $ret = _objc_msgSend_1cwp428(
823823
_class_AVAudioPlayer,
824824
_sel_allocWithZone_,
825825
zone,
826826
);
827-
return AVAudioPlayer.castFromPointer(_ret, retain: false, release: true);
827+
return AVAudioPlayer.castFromPointer($ret, retain: false, release: true);
828828
}
829829

830830
/// new
831831
static AVAudioPlayer new$() {
832-
final _ret = _objc_msgSend_151sglz(_class_AVAudioPlayer, _sel_new);
833-
return AVAudioPlayer.castFromPointer(_ret, retain: false, release: true);
832+
final $ret = _objc_msgSend_151sglz(_class_AVAudioPlayer, _sel_new);
833+
return AVAudioPlayer.castFromPointer($ret, retain: false, release: true);
834834
}
835835

836836
/// Returns a new instance of AVAudioPlayer constructed with the default `new` method.
@@ -840,8 +840,8 @@ class AVAudioPlayer extends objc.NSObject {
840840
extension AVAudioPlayer$Methods on AVAudioPlayer {
841841
/// autorelease
842842
AVAudioPlayer autorelease() {
843-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_autorelease);
844-
return AVAudioPlayer.castFromPointer(_ret, retain: true, release: true);
843+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_autorelease);
844+
return AVAudioPlayer.castFromPointer($ret, retain: true, release: true);
845845
}
846846

847847
/// averagePowerForChannel:
@@ -871,13 +871,13 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
871871
iOS: (false, (7, 0, 0)),
872872
macOS: (true, null),
873873
);
874-
final _ret = _objc_msgSend_151sglz(
874+
final $ret = _objc_msgSend_151sglz(
875875
this.ref.pointer,
876876
_sel_channelAssignments,
877877
);
878-
return _ret.address == 0
878+
return $ret.address == 0
879879
? null
880-
: objc.NSArray.castFromPointer(_ret, retain: true, release: true);
880+
: objc.NSArray.castFromPointer($ret, retain: true, release: true);
881881
}
882882

883883
/// currentDevice
@@ -887,10 +887,10 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
887887
iOS: (true, null),
888888
macOS: (false, (10, 13, 0)),
889889
);
890-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_currentDevice);
891-
return _ret.address == 0
890+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_currentDevice);
891+
return $ret.address == 0
892892
? null
893-
: objc.NSString.castFromPointer(_ret, retain: true, release: true);
893+
: objc.NSString.castFromPointer($ret, retain: true, release: true);
894894
}
895895

896896
/// currentTime
@@ -912,10 +912,10 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
912912
iOS: (false, (2, 2, 0)),
913913
macOS: (false, (10, 7, 0)),
914914
);
915-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_data);
916-
return _ret.address == 0
915+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_data);
916+
return $ret.address == 0
917917
? null
918-
: objc.NSData.castFromPointer(_ret, retain: true, release: true);
918+
: objc.NSData.castFromPointer($ret, retain: true, release: true);
919919
}
920920

921921
/// delegate
@@ -925,11 +925,11 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
925925
iOS: (false, (2, 2, 0)),
926926
macOS: (false, (10, 7, 0)),
927927
);
928-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_delegate);
929-
return _ret.address == 0
928+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_delegate);
929+
return $ret.address == 0
930930
? null
931931
: AVAudioPlayerDelegate.castFromPointer(
932-
_ret,
932+
$ret,
933933
retain: true,
934934
release: true,
935935
);
@@ -976,8 +976,8 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
976976
iOS: (false, (10, 0, 0)),
977977
macOS: (false, (10, 12, 0)),
978978
);
979-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_format);
980-
return AVAudioFormat.castFromPointer(_ret, retain: true, release: true);
979+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_format);
980+
return AVAudioFormat.castFromPointer($ret, retain: true, release: true);
981981
}
982982

983983
/// init
@@ -987,11 +987,11 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
987987
iOS: (false, (2, 0, 0)),
988988
macOS: (false, (10, 0, 0)),
989989
);
990-
final _ret = _objc_msgSend_151sglz(
990+
final $ret = _objc_msgSend_151sglz(
991991
this.ref.retainAndReturnPointer(),
992992
_sel_init,
993993
);
994-
return AVAudioPlayer.castFromPointer(_ret, retain: false, release: true);
994+
return AVAudioPlayer.castFromPointer($ret, retain: false, release: true);
995995
}
996996

997997
/// initWithContentsOfURL:error:
@@ -1004,15 +1004,15 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
10041004
iOS: (false, (2, 2, 0)),
10051005
macOS: (false, (10, 7, 0)),
10061006
);
1007-
final _ret = _objc_msgSend_1lhpu4m(
1007+
final $ret = _objc_msgSend_1lhpu4m(
10081008
this.ref.retainAndReturnPointer(),
10091009
_sel_initWithContentsOfURL_error_,
10101010
url.ref.pointer,
10111011
error,
10121012
);
1013-
return _ret.address == 0
1013+
return $ret.address == 0
10141014
? null
1015-
: AVAudioPlayer.castFromPointer(_ret, retain: false, release: true);
1015+
: AVAudioPlayer.castFromPointer($ret, retain: false, release: true);
10161016
}
10171017

10181018
/// initWithContentsOfURL:fileTypeHint:error:
@@ -1026,16 +1026,16 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
10261026
iOS: (false, (7, 0, 0)),
10271027
macOS: (false, (10, 9, 0)),
10281028
);
1029-
final _ret = _objc_msgSend_1pnyuds(
1029+
final $ret = _objc_msgSend_1pnyuds(
10301030
this.ref.retainAndReturnPointer(),
10311031
_sel_initWithContentsOfURL_fileTypeHint_error_,
10321032
url.ref.pointer,
10331033
fileTypeHint?.ref.pointer ?? ffi.nullptr,
10341034
error,
10351035
);
1036-
return _ret.address == 0
1036+
return $ret.address == 0
10371037
? null
1038-
: AVAudioPlayer.castFromPointer(_ret, retain: false, release: true);
1038+
: AVAudioPlayer.castFromPointer($ret, retain: false, release: true);
10391039
}
10401040

10411041
/// initWithData:error:
@@ -1048,15 +1048,15 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
10481048
iOS: (false, (2, 2, 0)),
10491049
macOS: (false, (10, 7, 0)),
10501050
);
1051-
final _ret = _objc_msgSend_1lhpu4m(
1051+
final $ret = _objc_msgSend_1lhpu4m(
10521052
this.ref.retainAndReturnPointer(),
10531053
_sel_initWithData_error_,
10541054
data.ref.pointer,
10551055
error,
10561056
);
1057-
return _ret.address == 0
1057+
return $ret.address == 0
10581058
? null
1059-
: AVAudioPlayer.castFromPointer(_ret, retain: false, release: true);
1059+
: AVAudioPlayer.castFromPointer($ret, retain: false, release: true);
10601060
}
10611061

10621062
/// initWithData:fileTypeHint:error:
@@ -1070,16 +1070,16 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
10701070
iOS: (false, (7, 0, 0)),
10711071
macOS: (false, (10, 9, 0)),
10721072
);
1073-
final _ret = _objc_msgSend_1pnyuds(
1073+
final $ret = _objc_msgSend_1pnyuds(
10741074
this.ref.retainAndReturnPointer(),
10751075
_sel_initWithData_fileTypeHint_error_,
10761076
data.ref.pointer,
10771077
fileTypeHint?.ref.pointer ?? ffi.nullptr,
10781078
error,
10791079
);
1080-
return _ret.address == 0
1080+
return $ret.address == 0
10811081
? null
1082-
: AVAudioPlayer.castFromPointer(_ret, retain: false, release: true);
1082+
: AVAudioPlayer.castFromPointer($ret, retain: false, release: true);
10831083
}
10841084

10851085
/// intendedSpatialExperience
@@ -1089,12 +1089,12 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
10891089
iOS: (true, null),
10901090
macOS: (true, null),
10911091
);
1092-
final _ret = _objc_msgSend_151sglz(
1092+
final $ret = _objc_msgSend_151sglz(
10931093
this.ref.pointer,
10941094
_sel_intendedSpatialExperience,
10951095
);
10961096
return CASpatialAudioExperience.castFromPointer(
1097-
_ret,
1097+
$ret,
10981098
retain: true,
10991099
release: true,
11001100
);
@@ -1226,14 +1226,14 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
12261226

12271227
/// retain
12281228
AVAudioPlayer retain() {
1229-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_retain);
1230-
return AVAudioPlayer.castFromPointer(_ret, retain: true, release: true);
1229+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_retain);
1230+
return AVAudioPlayer.castFromPointer($ret, retain: true, release: true);
12311231
}
12321232

12331233
/// self
12341234
AVAudioPlayer self() {
1235-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_self);
1236-
return AVAudioPlayer.castFromPointer(_ret, retain: true, release: true);
1235+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_self);
1236+
return AVAudioPlayer.castFromPointer($ret, retain: true, release: true);
12371237
}
12381238

12391239
/// setChannelAssignments:
@@ -1384,8 +1384,8 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
13841384
iOS: (false, (4, 0, 0)),
13851385
macOS: (false, (10, 7, 0)),
13861386
);
1387-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_settings);
1388-
return objc.NSDictionary.castFromPointer(_ret, retain: true, release: true);
1387+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_settings);
1388+
return objc.NSDictionary.castFromPointer($ret, retain: true, release: true);
13891389
}
13901390

13911391
/// stop
@@ -1415,10 +1415,10 @@ extension AVAudioPlayer$Methods on AVAudioPlayer {
14151415
iOS: (false, (2, 2, 0)),
14161416
macOS: (false, (10, 7, 0)),
14171417
);
1418-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_url);
1419-
return _ret.address == 0
1418+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_url);
1419+
return $ret.address == 0
14201420
? null
1421-
: objc.NSURL.castFromPointer(_ret, retain: true, release: true);
1421+
: objc.NSURL.castFromPointer($ret, retain: true, release: true);
14221422
}
14231423

14241424
/// volume

pkgs/ffigen/example/swift/swift_api_bindings.dart

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -282,24 +282,24 @@ class SwiftClass extends objc.NSObject {
282282

283283
/// alloc
284284
static SwiftClass alloc() {
285-
final _ret = _objc_msgSend_151sglz(_class_SwiftClass, _sel_alloc);
286-
return SwiftClass.castFromPointer(_ret, retain: false, release: true);
285+
final $ret = _objc_msgSend_151sglz(_class_SwiftClass, _sel_alloc);
286+
return SwiftClass.castFromPointer($ret, retain: false, release: true);
287287
}
288288

289289
/// allocWithZone:
290290
static SwiftClass allocWithZone(ffi.Pointer<objc.NSZone> zone) {
291-
final _ret = _objc_msgSend_1cwp428(
291+
final $ret = _objc_msgSend_1cwp428(
292292
_class_SwiftClass,
293293
_sel_allocWithZone_,
294294
zone,
295295
);
296-
return SwiftClass.castFromPointer(_ret, retain: false, release: true);
296+
return SwiftClass.castFromPointer($ret, retain: false, release: true);
297297
}
298298

299299
/// new
300300
static SwiftClass new$() {
301-
final _ret = _objc_msgSend_151sglz(_class_SwiftClass, _sel_new);
302-
return SwiftClass.castFromPointer(_ret, retain: false, release: true);
301+
final $ret = _objc_msgSend_151sglz(_class_SwiftClass, _sel_new);
302+
return SwiftClass.castFromPointer($ret, retain: false, release: true);
303303
}
304304

305305
/// Returns a new instance of SwiftClass constructed with the default `new` method.
@@ -309,8 +309,8 @@ class SwiftClass extends objc.NSObject {
309309
extension SwiftClass$Methods on SwiftClass {
310310
/// autorelease
311311
SwiftClass autorelease() {
312-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_autorelease);
313-
return SwiftClass.castFromPointer(_ret, retain: true, release: true);
312+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_autorelease);
313+
return SwiftClass.castFromPointer($ret, retain: true, release: true);
314314
}
315315

316316
/// init
@@ -320,29 +320,29 @@ extension SwiftClass$Methods on SwiftClass {
320320
iOS: (false, (2, 0, 0)),
321321
macOS: (false, (10, 0, 0)),
322322
);
323-
final _ret = _objc_msgSend_151sglz(
323+
final $ret = _objc_msgSend_151sglz(
324324
this.ref.retainAndReturnPointer(),
325325
_sel_init,
326326
);
327-
return SwiftClass.castFromPointer(_ret, retain: false, release: true);
327+
return SwiftClass.castFromPointer($ret, retain: false, release: true);
328328
}
329329

330330
/// retain
331331
SwiftClass retain() {
332-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_retain);
333-
return SwiftClass.castFromPointer(_ret, retain: true, release: true);
332+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_retain);
333+
return SwiftClass.castFromPointer($ret, retain: true, release: true);
334334
}
335335

336336
/// sayHello
337337
objc.NSString sayHello() {
338-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_sayHello);
339-
return objc.NSString.castFromPointer(_ret, retain: true, release: true);
338+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_sayHello);
339+
return objc.NSString.castFromPointer($ret, retain: true, release: true);
340340
}
341341

342342
/// self
343343
SwiftClass self() {
344-
final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_self);
345-
return SwiftClass.castFromPointer(_ret, retain: true, release: true);
344+
final $ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_self);
345+
return SwiftClass.castFromPointer($ret, retain: true, release: true);
346346
}
347347

348348
/// setSomeField:

pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class ObjCBuiltInFunctions {
5555
static const unimplementedOptionalMethodException = ObjCImport(
5656
'UnimplementedOptionalMethodException',
5757
);
58+
static const nsErrorException = ObjCImport('NSErrorException');
5859
static const checkOsVersion = ObjCImport('checkOsVersionInternal');
5960

6061
// TODO(https://github.com/dart-lang/native/issues/1173): Ideally this check
@@ -70,6 +71,7 @@ class ObjCBuiltInFunctions {
7071
bool isBuiltInCategory(String name) =>
7172
!generateForPackageObjectiveC && objCBuiltInCategories.contains(name);
7273
static bool isNSObject(String name) => name == 'NSObject';
74+
static bool isNSError(String name) => name == 'NSError';
7375

7476
// We need to load a separate instance of objc_msgSend for each signature. If
7577
// the return type is a struct, we need to use objc_msgSend_stret instead, and

0 commit comments

Comments
 (0)