diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md index 9a74d68dd6..8c1c7168a4 100644 --- a/pkgs/ffigen/CHANGELOG.md +++ b/pkgs/ffigen/CHANGELOG.md @@ -3,6 +3,16 @@ - Use package:objective_c 5.0.0 - Support transitive categories of built-in types: https://github.com/dart-lang/native/issues/1820 +- __Breaking change__: Maintain protocol conformance when translating from ObjC + to Dart. For example, ObjC's `id` is now translated to Dart's + `FooProtocol`. Generally this shouldn't be a breaking change for code that is + using protocols correctly, with a few caveats: + - For more advanced use cases that use `ObjCProtocolBuilder` directly, after + calling `build()` you will need to cast the generated object to the target + protocol: `FooProtocol.castFrom(protocolBuilder.build())`. + - Due to limitations in the Dart type system, only the first protocol of an + `id` is used: `id` becomes `FooProtocol`. The + `FooProtocol.castFrom` method can help work around issues this may cause. - Fix the handling of global arrays to remove the extra pointer reference. ## 16.1.0 diff --git a/pkgs/ffigen/lib/src/code_generator/imports.dart b/pkgs/ffigen/lib/src/code_generator/imports.dart index d442d68934..45708ae4c1 100644 --- a/pkgs/ffigen/lib/src/code_generator/imports.dart +++ b/pkgs/ffigen/lib/src/code_generator/imports.dart @@ -167,3 +167,5 @@ final objCSelType = ImportedType( objcPkgImport, 'ObjCSelector', 'ObjCSelector', 'struct objc_selector'); final objCBlockType = ImportedType(objcPkgImport, 'ObjCBlockImpl', 'ObjCBlockImpl', 'id'); +final objCProtocolType = + ImportedType(objcPkgImport, 'ObjCProtocol', 'ObjCProtocol', 'void'); diff --git a/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart b/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart index 49cdc4da43..b230bb49ef 100644 --- a/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart +++ b/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart @@ -130,6 +130,8 @@ class ObjCBuiltInFunctions { 'NSCoding': 'NSCoding', 'NSCopying': 'NSCopying', 'NSFastEnumeration': 'NSFastEnumeration', + 'NSItemProviderReading': 'NSItemProviderReading', + 'NSItemProviderWriting': 'NSItemProviderWriting', 'NSMutableCopying': 'NSMutableCopying', 'NSObject': 'NSObjectProtocol', 'NSSecureCoding': 'NSSecureCoding', diff --git a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart index 6825e1545a..6d62671009 100644 --- a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart +++ b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart @@ -73,17 +73,15 @@ class ObjCInterface extends BindingType with ObjCMethods { final rawObjType = PointerType(objCObjectType).getCType(w); final wrapObjType = ObjCBuiltInFunctions.objectBase.gen(w); - final superTypeIsInPkgObjc = superType == null; final protoImpl = protocols.isEmpty ? '' : 'implements ${protocols.map((p) => p.getDartType(w)).join(', ')} '; + final superCtor = superType == null ? 'super' : 'super.castFromPointer'; s.write(''' class $name extends ${superType?.getDartType(w) ?? wrapObjType} $protoImpl{ - $name._($rawObjType pointer, - {bool retain = false, bool release = false}) : - ${superTypeIsInPkgObjc ? 'super' : 'super.castFromPointer'} - (pointer, retain: retain, release: release); + $name._($rawObjType pointer, {bool retain = false, bool release = false}) : + $superCtor(pointer, retain: retain, release: release); /// Constructs a [$name] that points to the same underlying object as [other]. $name.castFrom($wrapObjType other) : diff --git a/pkgs/ffigen/lib/src/code_generator/objc_protocol.dart b/pkgs/ffigen/lib/src/code_generator/objc_protocol.dart index 57d6ede6e3..ebd138d45e 100644 --- a/pkgs/ffigen/lib/src/code_generator/objc_protocol.dart +++ b/pkgs/ffigen/lib/src/code_generator/objc_protocol.dart @@ -13,6 +13,8 @@ class ObjCProtocol extends BindingType with ObjCMethods { final superProtocols = []; final String lookupName; final ObjCInternalGlobal _protocolPointer; + late final ObjCInternalGlobal _conformsTo; + late final ObjCMsgSendFunc _conformsToMsgSend; // Filled by ListBindingsVisitation. bool generateAsStub = false; @@ -33,9 +35,18 @@ class ObjCProtocol extends BindingType with ObjCMethods { (Writer w) => '${ObjCBuiltInFunctions.getProtocol.gen(w)}("$lookupName")'), super( - name: name ?? - builtInFunctions.getBuiltInProtocolName(originalName) ?? - originalName); + name: builtInFunctions.getBuiltInProtocolName(originalName) ?? + name ?? + originalName) { + _conformsTo = builtInFunctions.getSelObject('conformsToProtocol:'); + _conformsToMsgSend = builtInFunctions.getMsgSendFunc(BooleanType(), [ + Parameter( + name: 'protocol', + type: PointerType(objCProtocolType), + objCConsumed: false, + ) + ]); + } @override bool get isObjCImport => @@ -52,6 +63,7 @@ class ObjCProtocol extends BindingType with ObjCMethods { ObjCBuiltInFunctions.protocolListenableMethod.gen(w); final protocolBuilder = ObjCBuiltInFunctions.protocolBuilder.gen(w); final objectBase = ObjCBuiltInFunctions.objectBase.gen(w); + final rawObjType = PointerType(objCObjectType).getCType(w); final getSignature = ObjCBuiltInFunctions.getProtocolMethodSignature.gen(w); final s = StringBuffer(); @@ -65,10 +77,23 @@ class ObjCProtocol extends BindingType with ObjCMethods { } s.write(makeDartDoc(dartDoc ?? originalName)); - final protoImpl = superProtocols.isEmpty - ? protocolBase - : superProtocols.map((p) => p.getDartType(w)).join(', '); - s.write('abstract interface class $name implements $protoImpl {'); + final sp = superProtocols.map((p) => p.getDartType(w)); + final impls = superProtocols.isEmpty ? '' : 'implements ${sp.join(', ')}'; + s.write(''' +interface class $name extends $protocolBase $impls{ + $name._($rawObjType pointer, {bool retain = false, bool release = false}) : + super(pointer, retain: retain, release: release); + + /// Constructs a [$name] that points to the same underlying object as [other]. + $name.castFrom($objectBase other) : + this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [$name] that wraps the given raw object pointer. + $name.castFromPointer($rawObjType other, + {bool retain = false, bool release = false}) : + this._(other, retain: retain, release: release); + +'''); if (!generateAsStub) { final buildArgs = []; @@ -150,10 +175,10 @@ class ObjCProtocol extends BindingType with ObjCMethods { final builders = ''' /// Builds an object that implements the $originalName protocol. To implement /// multiple protocols, use [addToBuilder] or [$protocolBuilder] directly. - static $objectBase implement($args) { + static $name implement($args) { final builder = $protocolBuilder(); $buildImplementations - return builder.build(); + return $name.castFrom(builder.build()); } /// Adds the implementation of the $originalName protocol to an existing @@ -169,10 +194,10 @@ class ObjCProtocol extends BindingType with ObjCMethods { /// Builds an object that implements the $originalName protocol. To implement /// multiple protocols, use [addToBuilder] or [$protocolBuilder] directly. All /// methods that can be implemented as listeners will be. - static $objectBase implementAsListener($args) { + static $name implementAsListener($args) { final builder = $protocolBuilder(); $buildListenerImplementations - return builder.build(); + return $name.castFrom(builder.build()); } /// Adds the implementation of the $originalName protocol to an existing @@ -185,10 +210,10 @@ class ObjCProtocol extends BindingType with ObjCMethods { /// Builds an object that implements the $originalName protocol. To implement /// multiple protocols, use [addToBuilder] or [$protocolBuilder] directly. All /// methods that can be implemented as blocking listeners will be. - static $objectBase implementAsBlocking($args) { + static $name implementAsBlocking($args) { final builder = $protocolBuilder(); $buildBlockingImplementations - return builder.build(); + return $name.castFrom(builder.build()); } /// Adds the implementation of the $originalName protocol to an existing @@ -201,6 +226,16 @@ class ObjCProtocol extends BindingType with ObjCMethods { } s.write(''' + /// Returns whether [obj] is an instance of [$name]. + static bool conformsTo($objectBase obj) { + return ${_conformsToMsgSend.invoke( + w, + 'obj.ref.pointer', + _conformsTo.name, + [_protocolPointer.name], + )}; + } + $builders $listenerBuilders $methodFields @@ -264,8 +299,7 @@ Protocol* _${wrapName}_$originalName(void) { return @protocol($originalName); } required bool objCRetain, String? objCEnclosingClass, }) => - ObjCInterface.generateConstructor( - '${w.objcPkgPrefix}.ObjCObjectBase', value, objCRetain); + ObjCInterface.generateConstructor(getDartType(w), value, objCRetain); @override String? generateRetain(String value) => @@ -305,6 +339,8 @@ Protocol* _${wrapName}_$originalName(void) { return @protocol($originalName); } super.visitChildren(visitor); visitor.visit(_protocolPointer); visitor.visitAll(superProtocols); + visitor.visit(_conformsTo); + visitor.visit(_conformsToMsgSend); visitMethods(visitor); } } diff --git a/pkgs/ffigen/lib/src/code_generator/pointer.dart b/pkgs/ffigen/lib/src/code_generator/pointer.dart index 98abd88d6a..a12282ac85 100644 --- a/pkgs/ffigen/lib/src/code_generator/pointer.dart +++ b/pkgs/ffigen/lib/src/code_generator/pointer.dart @@ -185,3 +185,51 @@ class ObjCBlockPointer extends ObjCObjectPointer { return other is ObjCBlockPointer || other is ObjCBlock; } } + +/// A pointer to an Objective C object with protocols. +class ObjCObjectPointerWithProtocols extends ObjCObjectPointer { + List protocols; + + ObjCObjectPointerWithProtocols(this.protocols) + : assert(protocols.isNotEmpty), + super._(); + + @override + String getDartType(Writer w) => protocols.first.getDartType(w); + + @override + bool isSupertypeOf(Type other) { + other = other.typealiasType; + if (other is ObjCObjectPointerWithProtocols) { + // The "correct" logic would be to return true if each of our protocols + // was a supertype of one of the other's protocols. But this method is + // designed to reflect the subtyping rules of the *Dart bindings*, not the + // ObjC types. So since the codegen just uses the first protocol, we do + // the same here. + return protocols.first.isSupertypeOf(other.protocols.first); + } + return false; + } + + @override + String toString() => 'id<${protocols.join(', ')}>'; + + @override + String cacheKey() => 'id<${protocols.map((p) => p.cacheKey()).join(', ')}>'; + + @override + String convertFfiDartTypeToDartType( + Writer w, + String value, { + required bool objCRetain, + String? objCEnclosingClass, + }) => + protocols.first.convertFfiDartTypeToDartType(w, value, + objCRetain: objCRetain, objCEnclosingClass: objCEnclosingClass); + + @override + void visitChildren(Visitor visitor) { + super.visitChildren(visitor); + visitor.visitAll(protocols); + } +} diff --git a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart index 7bedda292a..b0bdb8f866 100644 --- a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart +++ b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart @@ -954,6 +954,44 @@ class Clang { _clang_Type_getObjCObjectBaseTypePtr .asFunction(); + /// Retrieve the number of protocol references associated with an ObjC object/id. + /// + /// If the type is not an ObjC object, 0 is returned. + int clang_Type_getNumObjCProtocolRefs( + CXType T, + ) { + return _clang_Type_getNumObjCProtocolRefs( + T, + ); + } + + late final _clang_Type_getNumObjCProtocolRefsPtr = + _lookup>( + 'clang_Type_getNumObjCProtocolRefs'); + late final _clang_Type_getNumObjCProtocolRefs = + _clang_Type_getNumObjCProtocolRefsPtr.asFunction(); + + /// Retrieve the decl for a protocol reference for an ObjC object/id. + /// + /// If the type is not an ObjC object or there are not enough protocol + /// references, an invalid cursor is returned. + CXCursor clang_Type_getObjCProtocolDecl( + CXType T, + int i, + ) { + return _clang_Type_getObjCProtocolDecl( + T, + i, + ); + } + + late final _clang_Type_getObjCProtocolDeclPtr = + _lookup>( + 'clang_Type_getObjCProtocolDecl'); + late final _clang_Type_getObjCProtocolDecl = + _clang_Type_getObjCProtocolDeclPtr + .asFunction(); + /// Return 1 if the CXType is a variadic function type, and 0 otherwise. int clang_isFunctionTypeVariadic( CXType T, @@ -1546,8 +1584,25 @@ final class CXString extends ffi.Struct { external int private_flags; } +/// An "index" that consists of a set of translation units that would +/// typically be linked together into an executable or library. +typedef CXIndex = ffi.Pointer; + +final class CXTargetInfoImpl extends ffi.Opaque {} + +/// An opaque type representing target information for a given translation +/// unit. +typedef CXTargetInfo = ffi.Pointer; + final class CXTranslationUnitImpl extends ffi.Opaque {} +/// A single translation unit, which resides in an index. +typedef CXTranslationUnit = ffi.Pointer; + +/// Opaque pointer representing client data that will be passed through +/// to various callbacks and visitors. +typedef CXClientData = ffi.Pointer; + /// Provides the contents of a file that has not yet been saved to disk. /// /// Each CXUnsavedFile instance provides the name of a file on the @@ -1567,9 +1622,44 @@ final class CXUnsavedFile extends ffi.Struct { external int Length; } -/// An "index" that consists of a set of translation units that would -/// typically be linked together into an executable or library. -typedef CXIndex = ffi.Pointer; +/// Describes the availability of a particular entity, which indicates +/// whether the use of this entity will result in a warning or error due to +/// it being deprecated or unavailable. +sealed class CXAvailabilityKind { + /// The entity is available. + static const CXAvailability_Available = 0; + + /// The entity is available, but has been deprecated (and its use is + /// not recommended). + static const CXAvailability_Deprecated = 1; + + /// The entity is not available; any use of it will be an error. + static const CXAvailability_NotAvailable = 2; + + /// The entity is available, but not accessible; any use of it will be + /// an error. + static const CXAvailability_NotAccessible = 3; +} + +/// Describes a version number of the form major.minor.subminor. +final class CXVersion extends ffi.Struct { + /// The major version number, e.g., the '10' in '10.7.3'. A negative + /// value indicates that there is no version number at all. + @ffi.Int() + external int Major; + + /// The minor version number, e.g., the '7' in '10.7.3'. This value + /// will be negative if no minor version number was provided, e.g., for + /// version '10'. + @ffi.Int() + external int Minor; + + /// The subminor version number, e.g., the '3' in '10.7.3'. This value + /// will be negative if no minor or subminor version number was provided, + /// e.g., in version '10' or '10.7'. + @ffi.Int() + external int Subminor; +} /// A particular source file that is part of a translation unit. typedef CXFile = ffi.Pointer; @@ -1602,13 +1692,36 @@ final class CXSourceRange extends ffi.Struct { external int end_int_data; } -/// A single translation unit, which resides in an index. -typedef CXTranslationUnit = ffi.Pointer; +/// Describes the severity of a particular diagnostic. +sealed class CXDiagnosticSeverity { + /// A diagnostic that has been suppressed, e.g., by a command-line + /// option. + static const CXDiagnostic_Ignored = 0; + + /// This diagnostic is a note that should be attached to the + /// previous (non-note) diagnostic. + static const CXDiagnostic_Note = 1; + + /// This diagnostic indicates suspicious code that may not be + /// wrong. + static const CXDiagnostic_Warning = 2; + + /// This diagnostic indicates that the code is ill-formed. + static const CXDiagnostic_Error = 3; + + /// This diagnostic indicates that the code is ill-formed such + /// that future parser recovery is unlikely to produce useful + /// results. + static const CXDiagnostic_Fatal = 4; +} /// A single diagnostic, containing the diagnostic's severity, /// location, text, source ranges, and fix-it hints. typedef CXDiagnostic = ffi.Pointer; +/// A group of CXDiagnostics. +typedef CXDiagnosticSet = ffi.Pointer; + /// Options to control the display of diagnostics. /// /// The values in this enum are meant to be combined to customize the @@ -1663,29 +1776,6 @@ sealed class CXDiagnosticDisplayOptions { static const CXDiagnostic_DisplayCategoryName = 32; } -/// Describes the severity of a particular diagnostic. -sealed class CXDiagnosticSeverity { - /// A diagnostic that has been suppressed, e.g., by a command-line - /// option. - static const CXDiagnostic_Ignored = 0; - - /// This diagnostic is a note that should be attached to the - /// previous (non-note) diagnostic. - static const CXDiagnostic_Note = 1; - - /// This diagnostic indicates suspicious code that may not be - /// wrong. - static const CXDiagnostic_Warning = 2; - - /// This diagnostic indicates that the code is ill-formed. - static const CXDiagnostic_Error = 3; - - /// This diagnostic indicates that the code is ill-formed such - /// that future parser recovery is unlikely to produce useful - /// results. - static const CXDiagnostic_Fatal = 4; -} - /// Flags that control the creation of translation units. /// /// The enumerators in this enumeration type are meant to be bitwise @@ -2618,25 +2708,6 @@ final class CXCursor extends ffi.Struct { external ffi.Array> data; } -/// Describes the availability of a particular entity, which indicates -/// whether the use of this entity will result in a warning or error due to -/// it being deprecated or unavailable. -sealed class CXAvailabilityKind { - /// The entity is available. - static const CXAvailability_Available = 0; - - /// The entity is available, but has been deprecated (and its use is - /// not recommended). - static const CXAvailability_Deprecated = 1; - - /// The entity is not available; any use of it will be an error. - static const CXAvailability_NotAvailable = 2; - - /// The entity is available, but not accessible; any use of it will be - /// an error. - static const CXAvailability_NotAccessible = 3; -} - /// Describes the availability of a given entity on a particular platform, e.g., /// a particular class might only be available on Mac OS 10.7 or newer. final class CXPlatformAvailability extends ffi.Struct { @@ -2666,25 +2737,10 @@ final class CXPlatformAvailability extends ffi.Struct { external CXString Message; } -/// Describes a version number of the form major.minor.subminor. -final class CXVersion extends ffi.Struct { - /// The major version number, e.g., the '10' in '10.7.3'. A negative - /// value indicates that there is no version number at all. - @ffi.Int() - external int Major; - - /// The minor version number, e.g., the '7' in '10.7.3'. This value - /// will be negative if no minor version number was provided, e.g., for - /// version '10'. - @ffi.Int() - external int Minor; +final class CXCursorSetImpl extends ffi.Opaque {} - /// The subminor version number, e.g., the '3' in '10.7.3'. This value - /// will be negative if no minor or subminor version number was provided, - /// e.g., in version '10' or '10.7'. - @ffi.Int() - external int Subminor; -} +/// A fast container representing a set of CXCursors. +typedef CXCursorSet = ffi.Pointer; /// Describes the kind of type sealed class CXTypeKind { @@ -2899,6 +2955,11 @@ sealed class CXChildVisitResult { static const CXChildVisit_Recurse = 2; } +typedef CXCursorVisitorFunction = ffi.UnsignedInt Function( + CXCursor cursor, CXCursor parent, CXClientData client_data); +typedef DartCXCursorVisitorFunction = int Function( + CXCursor cursor, CXCursor parent, CXClientData client_data); + /// Visitor invoked for each cursor found by a traversal. /// /// This visitor function will be invoked for each cursor found by @@ -2911,14 +2972,10 @@ sealed class CXChildVisitResult { /// to direct clang_visitCursorChildren(). typedef CXCursorVisitor = ffi.Pointer>; -typedef CXCursorVisitorFunction = ffi.UnsignedInt Function( - CXCursor cursor, CXCursor parent, CXClientData client_data); -typedef DartCXCursorVisitorFunction = int Function( - CXCursor cursor, CXCursor parent, CXClientData client_data); -/// Opaque pointer representing client data that will be passed through -/// to various callbacks and visitors. -typedef CXClientData = ffi.Pointer; +/// Opaque pointer representing a policy that controls pretty printing +/// for \c clang_getCursorPrettyPrinted. +typedef CXPrintingPolicy = ffi.Pointer; /// Property attributes for a \c CXCursor_ObjCPropertyDecl. sealed class CXObjCPropertyAttrKind { @@ -2938,6 +2995,48 @@ sealed class CXObjCPropertyAttrKind { static const CXObjCPropertyAttr_class = 4096; } +/// \defgroup CINDEX_MODULE Module introspection +/// +/// The functions in this group provide access to information about modules. +/// +/// @{ +typedef CXModule = ffi.Pointer; + +/// A semantic string that describes a code-completion result. +/// +/// A semantic string that describes the formatting of a code-completion +/// result as a single "template" of text that should be inserted into the +/// source buffer when a particular code-completion result is selected. +/// Each semantic string is made up of some number of "chunks", each of which +/// contains some text along with a description of what that text means, e.g., +/// the name of the entity being referenced, whether the text chunk is part of +/// the template, or whether it is a "placeholder" that the user should replace +/// with actual code,of a specific kind. See \c CXCompletionChunkKind for a +/// description of the different kinds of chunks. +typedef CXCompletionString = ffi.Pointer; +typedef CXInclusionVisitorFunction = ffi.Void Function( + CXFile included_file, + ffi.Pointer inclusion_stack, + ffi.UnsignedInt include_len, + CXClientData client_data); +typedef DartCXInclusionVisitorFunction = void Function( + CXFile included_file, + ffi.Pointer inclusion_stack, + int include_len, + CXClientData client_data); + +/// Visitor invoked for each file in a translation unit +/// (used with clang_getInclusions()). +/// +/// This visitor function will be invoked by clang_getInclusions() for each +/// file included (either at the top-level or by \#include directives) within +/// a translation unit. The first argument is the file being included, and +/// the second and third arguments provide the inclusion stack. The +/// array is sorted in order of immediate inclusion. For example, +/// the first element refers to the location that included 'included_file'. +typedef CXInclusionVisitor + = ffi.Pointer>; + sealed class CXEvalResultKind { static const CXEval_Int = 1; static const CXEval_Float = 2; @@ -2951,6 +3050,51 @@ sealed class CXEvalResultKind { /// Evaluation result of a cursor typedef CXEvalResult = ffi.Pointer; +/// A remapping of original source files and their translated files. +typedef CXRemapping = ffi.Pointer; + +/// \defgroup CINDEX_HIGH Higher level API functions +/// +/// @{ +sealed class CXVisitorResult { + static const CXVisit_Break = 0; + static const CXVisit_Continue = 1; +} + +/// The client's data object that is associated with a CXFile. +typedef CXIdxClientFile = ffi.Pointer; + +/// The client's data object that is associated with a semantic entity. +typedef CXIdxClientEntity = ffi.Pointer; + +/// The client's data object that is associated with a semantic container +/// of entities. +typedef CXIdxClientContainer = ffi.Pointer; + +/// The client's data object that is associated with an AST file (PCH +/// or module). +typedef CXIdxClientASTFile = ffi.Pointer; + +/// An indexing action/session, to be applied to one or multiple +/// translation units. +typedef CXIndexAction = ffi.Pointer; +typedef CXFieldVisitorFunction = ffi.UnsignedInt Function( + CXCursor C, CXClientData client_data); +typedef DartCXFieldVisitorFunction = int Function( + CXCursor C, CXClientData client_data); + +/// Visitor invoked for each field found by a traversal. +/// +/// This visitor function will be invoked for each field found by +/// \c clang_Type_visitFields. Its first argument is the cursor being +/// visited, its second argument is the client data provided to +/// \c clang_Type_visitFields. +/// +/// The visitor should return one of the \c CXVisitorResult values +/// to direct \c clang_Type_visitFields. +typedef CXFieldVisitor + = ffi.Pointer>; + const int CINDEX_VERSION_MAJOR = 0; const int CINDEX_VERSION_MINOR = 59; diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcprotocoldecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcprotocoldecl_parser.dart index dde0a22c88..239937d732 100644 --- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcprotocoldecl_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcprotocoldecl_parser.dart @@ -29,6 +29,22 @@ ObjCProtocol? parseObjCProtocolDeclaration(clang_types.CXCursor cursor) { return cachedProtocol; } + // There's a strange shape in the AST for protocols seen in certain contexts, + // where instead of the AST looking like (decl -> methods/etc), it looks like + // (stubDecl --superProto-> decl -> methods/etc). If we try and parse the stub + // in this case, we'll be left with an empty protocol with itself as its super + // protocol. The USR is the same for both the stub and the real decl, so at + // least this case is easy to detect and fix. + final selfSuperCursor = cursor.findChildWhere((child) { + if (child.kind == clang_types.CXCursorKind.CXCursor_ObjCProtocolRef) { + return clang.clang_getCursorDefinition(child).usr() == usr; + } + return false; + }); + if (selfSuperCursor != null) { + cursor = clang.clang_getCursorDefinition(selfSuperCursor); + } + if (!isApiAvailable(cursor)) { _logger.info('Omitting deprecated protocol $name'); return null; diff --git a/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart b/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart index 42743fdfdf..78689b8d75 100644 --- a/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart +++ b/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart @@ -17,6 +17,7 @@ import '../sub_parsers/enumdecl_parser.dart'; import '../sub_parsers/function_type_param_parser.dart'; import '../sub_parsers/objc_block_parser.dart'; import '../sub_parsers/objcinterfacedecl_parser.dart'; +import '../sub_parsers/objcprotocoldecl_parser.dart'; import '../sub_parsers/typedefdecl_parser.dart'; import '../type_extractor/cxtypekindmap.dart'; import '../utils.dart'; @@ -55,6 +56,18 @@ Type getCodeGenType( if (s is ObjCInterface) { return s; } + final numProtocols = clang.clang_Type_getNumObjCProtocolRefs(pt); + if (numProtocols > 0) { + final protocols = []; + for (var i = 0; i < numProtocols; ++i) { + final pdecl = clang.clang_Type_getObjCProtocolDecl(pt, i); + final p = parseObjCProtocolDeclaration(pdecl); + if (p != null) protocols.add(p); + } + if (protocols.isNotEmpty) { + return ObjCObjectPointerWithProtocols(protocols); + } + } return PointerType(objCObjectType); case clang_types.CXTypeKind.CXType_ObjCId: case clang_types.CXTypeKind.CXType_ObjCTypeParam: diff --git a/pkgs/ffigen/lib/src/header_parser/utils.dart b/pkgs/ffigen/lib/src/header_parser/utils.dart index 42b22663c0..aca6912dd2 100644 --- a/pkgs/ffigen/lib/src/header_parser/utils.dart +++ b/pkgs/ffigen/lib/src/header_parser/utils.dart @@ -197,12 +197,13 @@ extension CXCursorExt on clang_types.CXCursor { return result == 0; } - /// Returns the first child with the given CXCursorKind, or null if there + /// Returns the first child where `predicate(child)` is true, or null if there /// isn't one. - clang_types.CXCursor? findChildWithKind(int kind) { + clang_types.CXCursor? findChildWhere( + bool Function(clang_types.CXCursor) predicate) { clang_types.CXCursor? result; visitChildrenMayBreak((child) { - if (child.kind == kind) { + if (predicate(child)) { result = child; return false; } @@ -211,6 +212,11 @@ extension CXCursorExt on clang_types.CXCursor { return result; } + /// Returns the first child with the given CXCursorKind, or null if there + /// isn't one. + clang_types.CXCursor? findChildWithKind(int kind) => + findChildWhere((child) => child.kind == kind); + /// Returns whether there is a child with the given CXCursorKind. bool hasChildWithKind(int kind) => findChildWithKind(kind) != null; diff --git a/pkgs/ffigen/test/native_objc_test/protocol_test.dart b/pkgs/ffigen/test/native_objc_test/protocol_test.dart index 1c74314311..f949d4887d 100644 --- a/pkgs/ffigen/test/native_objc_test/protocol_test.dart +++ b/pkgs/ffigen/test/native_objc_test/protocol_test.dart @@ -36,20 +36,27 @@ void main() { group('ObjC implementation', () { test('Method implementation', () { final protocolImpl = ObjCProtocolImpl.new1(); + final MyProtocol asMyProtocol = protocolImpl; + final SecondaryProtocol asSecondaryProtocol = protocolImpl; + final consumer = ProtocolConsumer.new1(); // Required instance method. - final result = consumer.callInstanceMethod_(protocolImpl); + final result = consumer.callInstanceMethod_(asMyProtocol); expect( result.toDartString(), 'ObjCProtocolImpl: Hello from ObjC: 3.14'); // Optional instance method. - final intResult = consumer.callOptionalMethod_(protocolImpl); + final intResult = consumer.callOptionalMethod_(asMyProtocol); expect(intResult, 579); // Required instance method from secondary protocol. - final otherIntResult = consumer.callOtherMethod_(protocolImpl); + final otherIntResult = consumer.callOtherMethod_(asSecondaryProtocol); expect(otherIntResult, 10); + + // Method using two protocols. + final twoMethodResult = consumer.callTwoMethods_(asMyProtocol); + expect(twoMethodResult, 579); }); test('Method implementation, invoke from Dart', () { @@ -109,7 +116,7 @@ void main() { test('Method implementation', () { final consumer = ProtocolConsumer.new1(); - final myProtocol = MyProtocol.implement( + final MyProtocol myProtocol = MyProtocol.implement( instanceMethod_withDouble_: (NSString s, double x) { return 'MyProtocol: ${s.toDartString()}: $x'.toNSString(); }, @@ -131,23 +138,35 @@ void main() { final consumer = ProtocolConsumer.new1(); final protocolBuilder = ObjCProtocolBuilder(); - MyProtocol.addToBuilder(protocolBuilder, - instanceMethod_withDouble_: (NSString s, double x) { - return 'ProtocolBuilder: ${s.toDartString()}: $x'.toNSString(); - }); + MyProtocol.addToBuilder( + protocolBuilder, + instanceMethod_withDouble_: (NSString s, double x) { + return 'ProtocolBuilder: ${s.toDartString()}: $x'.toNSString(); + }, + optionalMethod_: (SomeStruct s) { + return s.y - s.x; + }, + ); SecondaryProtocol.addToBuilder(protocolBuilder, otherMethod_b_c_d_: (int a, int b, int c, int d) { return a * b * c * d; }); final protocolImpl = protocolBuilder.build(); + final MyProtocol asMyProtocol = MyProtocol.castFrom(protocolImpl); + final SecondaryProtocol asSecondaryProtocol = + SecondaryProtocol.castFrom(protocolImpl); // Required instance method. - final result = consumer.callInstanceMethod_(protocolImpl); + final result = consumer.callInstanceMethod_(asMyProtocol); expect(result.toDartString(), 'ProtocolBuilder: Hello from ObjC: 3.14'); // Required instance method from secondary protocol. - final otherIntResult = consumer.callOtherMethod_(protocolImpl); + final otherIntResult = consumer.callOtherMethod_(asSecondaryProtocol); expect(otherIntResult, 24); + + // Method using two protocols. + final twoMethodResult = consumer.callTwoMethods_(asMyProtocol); + expect(twoMethodResult, 222000); }); test('Multiple protocol implementation using method fields', () { @@ -163,20 +182,23 @@ void main() { return a * b * c * d; }); final protocolImpl = protocolBuilder.build(); + final MyProtocol asMyProtocol = MyProtocol.castFrom(protocolImpl); + final SecondaryProtocol asSecondaryProtocol = + SecondaryProtocol.castFrom(protocolImpl); // Required instance method. - final result = consumer.callInstanceMethod_(protocolImpl); + final result = consumer.callInstanceMethod_(asMyProtocol); expect(result.toDartString(), 'ProtocolBuilder: Hello from ObjC: 3.14'); // Required instance method from secondary protocol. - final otherIntResult = consumer.callOtherMethod_(protocolImpl); + final otherIntResult = consumer.callOtherMethod_(asSecondaryProtocol); expect(otherIntResult, 24); }); test('Unimplemented method', () { final consumer = ProtocolConsumer.new1(); - final myProtocol = MyProtocol.implement( + final MyProtocol myProtocol = MyProtocol.implement( instanceMethod_withDouble_: (NSString s, double x) { throw UnimplementedError(); }, @@ -191,7 +213,7 @@ void main() { final consumer = ProtocolConsumer.new1(); final listenerCompleter = Completer(); - final myProtocol = MyProtocol.implementAsListener( + final MyProtocol myProtocol = MyProtocol.implementAsListener( instanceMethod_withDouble_: (NSString s, double x) { return 'MyProtocol: ${s.toDartString()}: $x'.toNSString(); }, @@ -235,17 +257,20 @@ void main() { return a * b * c * d; }); final protocolImpl = protocolBuilder.build(); + final MyProtocol asMyProtocol = MyProtocol.castFrom(protocolImpl); + final SecondaryProtocol asSecondaryProtocol = + SecondaryProtocol.castFrom(protocolImpl); // Required instance method. - final result = consumer.callInstanceMethod_(protocolImpl); + final result = consumer.callInstanceMethod_(asMyProtocol); expect(result.toDartString(), 'ProtocolBuilder: Hello from ObjC: 3.14'); // Required instance method from secondary protocol. - final otherIntResult = consumer.callOtherMethod_(protocolImpl); + final otherIntResult = consumer.callOtherMethod_(asSecondaryProtocol); expect(otherIntResult, 24); // Listener method. - consumer.callMethodOnRandomThread_(protocolImpl); + consumer.callMethodOnRandomThread_(asMyProtocol); expect(await listenerCompleter.future, 123); }); @@ -261,7 +286,7 @@ void main() { final consumer = ProtocolConsumer.new1(); final listenerCompleter = Completer(); - final myProtocol = MyProtocol.implementAsBlocking( + final MyProtocol myProtocol = MyProtocol.implementAsBlocking( instanceMethod_withDouble_: (NSString s, double x) { throw UnimplementedError(); }, @@ -302,13 +327,16 @@ void main() { return a * b * c * d; }); final protocolImpl = protocolBuilder.build(); + final MyProtocol asMyProtocol = MyProtocol.castFrom(protocolImpl); + final SecondaryProtocol asSecondaryProtocol = + SecondaryProtocol.castFrom(protocolImpl); // Required instance method from secondary protocol. - final otherIntResult = consumer.callOtherMethod_(protocolImpl); + final otherIntResult = consumer.callOtherMethod_(asSecondaryProtocol); expect(otherIntResult, 24); // Blocking method. - consumer.callBlockingMethodOnRandomThread_(protocolImpl); + consumer.callBlockingMethodOnRandomThread_(asMyProtocol); expect(await listenerCompleter.future, 98765); }); }); @@ -352,27 +380,35 @@ void main() { otherSel, otherSignature, otherBlock.ref.pointer.cast()); final proxy = DartProxy.newFromBuilder_(proxyBuilder); + final MyProtocol asMyProtocol = MyProtocol.castFrom(proxy); + final SecondaryProtocol asSecondaryProtocol = + SecondaryProtocol.castFrom(proxy); // Required instance method. - final result = consumer.callInstanceMethod_(proxy); + final result = consumer.callInstanceMethod_(asMyProtocol); expect(result.toDartString(), "DartProxy: Hello from ObjC: 3.14"); // Optional instance method. - final intResult = consumer.callOptionalMethod_(proxy); + final intResult = consumer.callOptionalMethod_(asMyProtocol); expect(intResult, 333); // Required instance method from secondary protocol. - final otherIntResult = consumer.callOtherMethod_(proxy); + final otherIntResult = consumer.callOtherMethod_(asSecondaryProtocol); expect(otherIntResult, 24); + + // Method using two protocols. + final twoMethodResult = consumer.callTwoMethods_(asMyProtocol); + expect(twoMethodResult, 222000); }); test('Unimplemented method', () { final proxyBuilder = DartProxyBuilder.new1(); final consumer = ProtocolConsumer.new1(); final proxy = DartProxy.newFromBuilder_(proxyBuilder); + final MyProtocol asMyProtocol = MyProtocol.castFrom(proxy); // Optional instance method, not implemented. - final intResult = consumer.callOptionalMethod_(proxy); + final intResult = consumer.callOptionalMethod_(asMyProtocol); expect(intResult, -999); }); @@ -389,9 +425,10 @@ void main() { }); final proxy = protocolBuilder.build(); + final MyProtocol asMyProtocol = MyProtocol.castFrom(proxy); for (int i = 0; i < 1000; ++i) { - consumer.callMethodOnRandomThread_(proxy); + consumer.callMethodOnRandomThread_(asMyProtocol); } await completer.future; expect(count, 1000); @@ -493,5 +530,14 @@ void main() { .implement(ObjCProtocolBuilder(), () => 123), throwsA(isA())); }); + + test('conformsTo', () { + final inst = ObjCProtocolImpl.new1(); + expect(NSObjectProtocol.conformsTo(inst), isTrue); + expect(MyProtocol.conformsTo(inst), isTrue); + expect(SecondaryProtocol.conformsTo(inst), isTrue); + expect(EmptyProtocol.conformsTo(inst), isFalse); + expect(UnusedProtocol.conformsTo(inst), isFalse); + }); }); } diff --git a/pkgs/ffigen/test/native_objc_test/protocol_test.h b/pkgs/ffigen/test/native_objc_test/protocol_test.h index 16fd66c11b..769d97d6aa 100644 --- a/pkgs/ffigen/test/native_objc_test/protocol_test.h +++ b/pkgs/ffigen/test/native_objc_test/protocol_test.h @@ -74,11 +74,12 @@ typedef struct { @interface ProtocolConsumer : NSObject -- (NSString*)callInstanceMethod:(id)protocol; +- (NSString*)callInstanceMethod:(id)protocol; - (int32_t)callOptionalMethod:(id)protocol; - (int32_t)callOtherMethod:(id)protocol; - (void)callMethodOnRandomThread:(id)protocol; - (void)callBlockingMethodOnRandomThread:(id)protocol; +- (int32_t)callTwoMethods:(id)protocol; @end diff --git a/pkgs/ffigen/test/native_objc_test/protocol_test.m b/pkgs/ffigen/test/native_objc_test/protocol_test.m index 975effc685..dcd55ad59e 100644 --- a/pkgs/ffigen/test/native_objc_test/protocol_test.m +++ b/pkgs/ffigen/test/native_objc_test/protocol_test.m @@ -9,7 +9,7 @@ #include "protocol_test.h" @implementation ProtocolConsumer : NSObject -- (NSString*)callInstanceMethod:(id)protocol { +- (NSString*)callInstanceMethod:(id)protocol { return [protocol instanceMethod:@"Hello from ObjC" withDouble:3.14]; } @@ -39,6 +39,12 @@ - (void)callBlockingMethodOnRandomThread:(id)protocol { [protocol voidMethod:x]; }); } + +- (int32_t)callTwoMethods:(id)protocol { + SomeStruct s = {123, 345}; + int32_t x = [protocol optionalMethod:s]; + return [protocol otherMethod:x b:1 c:10 d:100]; +} @end diff --git a/pkgs/ffigen/test/native_objc_test/transitive_test.dart b/pkgs/ffigen/test/native_objc_test/transitive_test.dart index 45b8b5eb82..62f7738ce5 100644 --- a/pkgs/ffigen/test/native_objc_test/transitive_test.dart +++ b/pkgs/ffigen/test/native_objc_test/transitive_test.dart @@ -148,14 +148,12 @@ void main() { test('included', () { bindings = generate(includeTransitiveObjCProtocols: true); - // TODO(https://github.com/dart-lang/native/issues/1462): Transitive - // protocols should be included. - expect(incProto('DoublyTransitiveProtocol'), Inclusion.omitted); - expect(incProto('TransitiveSuperProtocol'), Inclusion.omitted); - expect(incProto('TransitiveProtocol'), Inclusion.omitted); + expect(incProto('DoublyTransitiveProtocol'), Inclusion.included); + expect(incProto('TransitiveSuperProtocol'), Inclusion.included); + expect(incProto('TransitiveProtocol'), Inclusion.included); expect(incProto('SuperSuperProtocol'), Inclusion.included); - expect(incProto('DoublySuperTransitiveProtocol'), Inclusion.omitted); - expect(incProto('SuperTransitiveProtocol'), Inclusion.omitted); + expect(incProto('DoublySuperTransitiveProtocol'), Inclusion.included); + expect(incProto('SuperTransitiveProtocol'), Inclusion.included); expect(incProto('SuperProtocol'), Inclusion.included); expect(incProto('AnotherSuperProtocol'), Inclusion.included); expect(incProto('DirectlyIncludedProtocol'), Inclusion.included); @@ -163,15 +161,15 @@ void main() { expect(incProto('NotIncludedTransitiveProtocol'), Inclusion.omitted); expect(incProto('NotIncludedProtocol'), Inclusion.omitted); expect(incProto('SuperFromInterfaceProtocol'), Inclusion.included); - expect(incProto('TransitiveFromInterfaceProtocol'), Inclusion.omitted); + expect(incProto('TransitiveFromInterfaceProtocol'), Inclusion.included); expect(incItf('DirectlyIncludedWithProtocol'), Inclusion.included); - expect(bindings.contains('doubleProtoMethod'), isFalse); - expect(bindings.contains('transitiveSuperProtoMethod'), isFalse); - expect(bindings.contains('transitiveProtoMethod'), isFalse); + expect(bindings.contains('doubleProtoMethod'), isTrue); + expect(bindings.contains('transitiveSuperProtoMethod'), isTrue); + expect(bindings.contains('transitiveProtoMethod'), isTrue); expect(bindings.contains('superSuperProtoMethod'), isTrue); - expect(bindings.contains('doublySuperProtoMethod'), isFalse); - expect(bindings.contains('superTransitiveProtoMethod'), isFalse); + expect(bindings.contains('doublySuperProtoMethod'), isTrue); + expect(bindings.contains('superTransitiveProtoMethod'), isTrue); expect(bindings.contains('superProtoMethod'), isTrue); expect(bindings.contains('anotherSuperProtoMethod'), isTrue); expect(bindings.contains('directProtoMethod'), isTrue); @@ -179,8 +177,7 @@ void main() { expect(bindings.contains('notIncludedTransitiveProtoMethod'), isFalse); expect(bindings.contains('notIncludedProtoMethod'), isFalse); expect(bindings.contains('superFromInterfaceProtoMethod'), isTrue); - expect( - bindings.contains('transitiveFromInterfaceProtoMethod'), isFalse); + expect(bindings.contains('transitiveFromInterfaceProtoMethod'), isTrue); expect(bindings.contains('directlyIncludedWithProtoMethod'), isTrue); }); @@ -188,11 +185,11 @@ void main() { bindings = generate(includeTransitiveObjCProtocols: false); expect(incProto('DoublyTransitiveProtocol'), Inclusion.omitted); - expect(incProto('TransitiveSuperProtocol'), Inclusion.omitted); - expect(incProto('TransitiveProtocol'), Inclusion.omitted); + expect(incProto('TransitiveSuperProtocol'), Inclusion.stubbed); + expect(incProto('TransitiveProtocol'), Inclusion.stubbed); expect(incProto('SuperSuperProtocol'), Inclusion.stubbed); expect(incProto('DoublySuperTransitiveProtocol'), Inclusion.omitted); - expect(incProto('SuperTransitiveProtocol'), Inclusion.omitted); + expect(incProto('SuperTransitiveProtocol'), Inclusion.stubbed); expect(incProto('SuperProtocol'), Inclusion.stubbed); expect(incProto('AnotherSuperProtocol'), Inclusion.stubbed); expect(incProto('DirectlyIncludedProtocol'), Inclusion.included); @@ -200,7 +197,7 @@ void main() { expect(incProto('NotIncludedTransitiveProtocol'), Inclusion.omitted); expect(incProto('NotIncludedProtocol'), Inclusion.omitted); expect(incProto('SuperFromInterfaceProtocol'), Inclusion.stubbed); - expect(incProto('TransitiveFromInterfaceProtocol'), Inclusion.omitted); + expect(incProto('TransitiveFromInterfaceProtocol'), Inclusion.stubbed); expect(incItf('DirectlyIncludedWithProtocol'), Inclusion.included); expect(bindings.contains('doubleProtoMethod'), isFalse); diff --git a/pkgs/ffigen/test/unit_tests/subtyping_test.dart b/pkgs/ffigen/test/unit_tests/subtyping_test.dart index 3c23f7d047..59d26afe2a 100644 --- a/pkgs/ffigen/test/unit_tests/subtyping_test.dart +++ b/pkgs/ffigen/test/unit_tests/subtyping_test.dart @@ -41,8 +41,8 @@ void main() { final proto2 = makeProtocol('Proto2', []); final proto3 = makeProtocol('Proto3', []); final proto4 = makeProtocol('Proto4', []); - final protoSub1 = makeProtocol('ProtoS1', [proto1]); - final protoSub12 = makeProtocol('ProtoS12', [protoSub1, proto2]); + final protoSub1 = makeProtocol('ProtoSub1', [proto1]); + final protoSub12 = makeProtocol('ProtoSub12', [protoSub1, proto2]); final grandparent = makeInterface('Grandparent', null, [protoSub12]); final parent = makeInterface('Parent', grandparent, [protoSub1, proto3]); @@ -353,5 +353,35 @@ void main() { expect(block.isSubtypeOf(ObjCBlockPointer()), isTrue); expect(ObjCBlockPointer().isSubtypeOf(block), isFalse); }); + + test('ObjCObjectPointerWithProtocols', () { + final idP1 = ObjCObjectPointerWithProtocols([proto1]); + final idP2 = ObjCObjectPointerWithProtocols([proto2]); + final idP1P2 = ObjCObjectPointerWithProtocols([proto1, proto2]); + final idP2P1 = ObjCObjectPointerWithProtocols([proto2, proto1]); + final idPSub1 = ObjCObjectPointerWithProtocols([protoSub1]); + final idPSub12 = ObjCObjectPointerWithProtocols([protoSub12]); + + expect(idP1.isSubtypeOf(idP1), isTrue); + expect(idP1.isSubtypeOf(idP2), isFalse); + expect(idP2.isSubtypeOf(idP1), isFalse); + + expect(idP1P2.isSubtypeOf(idP1), isTrue); + expect(idP1.isSubtypeOf(idP1P2), isTrue); + expect(idP1P2.isSubtypeOf(idP2), isFalse); + expect(idP1P2.isSubtypeOf(idP2P1), isFalse); + expect(idP2P1.isSubtypeOf(idP2), isTrue); + expect(idP2.isSubtypeOf(idP2P1), isTrue); + + expect(idPSub1.isSubtypeOf(idP1), isTrue); + expect(idP1.isSubtypeOf(idPSub1), isFalse); + expect(idPSub12.isSubtypeOf(idP1), isTrue); + expect(idPSub12.isSubtypeOf(idP2), isTrue); + expect(idP1.isSubtypeOf(idPSub12), isFalse); + expect(idP2.isSubtypeOf(idPSub12), isFalse); + + expect(ObjCObjectPointer().isSubtypeOf(idP1), isFalse); + expect(idP1.isSubtypeOf(ObjCObjectPointer()), isTrue); + }); }); } diff --git a/pkgs/ffigen/tool/libclang_config.yaml b/pkgs/ffigen/tool/libclang_config.yaml index 4b305df54c..1efa9f783a 100644 --- a/pkgs/ffigen/tool/libclang_config.yaml +++ b/pkgs/ffigen/tool/libclang_config.yaml @@ -134,3 +134,5 @@ functions: - clang_Type_getModifiedType - clang_Location_isInSystemHeader - clang_getClangVersion + - clang_Type_getNumObjCProtocolRefs + - clang_Type_getObjCProtocolDecl diff --git a/pkgs/objective_c/ffigen_objc.yaml b/pkgs/objective_c/ffigen_objc.yaml index 8e4eecf801..835fc06221 100644 --- a/pkgs/objective_c/ffigen_objc.yaml +++ b/pkgs/objective_c/ffigen_objc.yaml @@ -72,6 +72,8 @@ objc-protocols: - NSCoding - NSCopying - NSFastEnumeration + - NSItemProviderReading + - NSItemProviderWriting - NSMutableCopying - NSObject - NSSecureCoding diff --git a/pkgs/objective_c/lib/objective_c.dart b/pkgs/objective_c/lib/objective_c.dart index c4f436d9b5..58d82a24f9 100644 --- a/pkgs/objective_c/lib/objective_c.dart +++ b/pkgs/objective_c/lib/objective_c.dart @@ -66,7 +66,9 @@ export 'src/objective_c_bindings_generated.dart' NSInvocation, NSItemProvider, NSItemProviderFileOptions, + NSItemProviderReading, NSItemProviderRepresentationVisibility, + NSItemProviderWriting, NSKeyValueChange, NSKeyValueObservingOptions, NSKeyValueSetMutationKind, diff --git a/pkgs/objective_c/lib/src/internal.dart b/pkgs/objective_c/lib/src/internal.dart index 7a348d70f2..e7851e0e2f 100644 --- a/pkgs/objective_c/lib/src/internal.dart +++ b/pkgs/objective_c/lib/src/internal.dart @@ -328,7 +328,9 @@ bool _isValidClass(ObjectPtr clazz) { } /// Only for use by ffigen bindings. -abstract interface class ObjCProtocolBase implements ObjCObjectBase {} +class ObjCProtocolBase extends ObjCObjectBase { + ObjCProtocolBase(super.ptr, {required super.retain, required super.release}); +} @pragma('vm:deeply-immutable') final class ObjCBlockRef extends _ObjCReference { diff --git a/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart b/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart index 3c3108b479..6fc737148d 100644 --- a/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart +++ b/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart @@ -892,16 +892,35 @@ class NSCoder extends objc.ObjCObjectBase { } /// NSCoding -abstract interface class NSCoding implements objc.ObjCProtocolBase { +interface class NSCoding extends objc.ObjCProtocolBase { + NSCoding._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSCoding] that points to the same underlying object as [other]. + NSCoding.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSCoding] that wraps the given raw object pointer. + NSCoding.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSCoding]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz( + obj.ref.pointer, _sel_conformsToProtocol_, _protocol_NSCoding); + } + /// Builds an object that implements the NSCoding protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. - static objc.ObjCObjectBase implement( + static NSCoding implement( {required void Function(NSCoder) encodeWithCoder_, required Dartinstancetype? Function(NSCoder) initWithCoder_}) { final builder = objc.ObjCProtocolBuilder(); NSCoding.encodeWithCoder_.implement(builder, encodeWithCoder_); NSCoding.initWithCoder_.implement(builder, initWithCoder_); - return builder.build(); + return NSCoding.castFrom(builder.build()); } /// Adds the implementation of the NSCoding protocol to an existing @@ -916,13 +935,13 @@ abstract interface class NSCoding implements objc.ObjCProtocolBase { /// Builds an object that implements the NSCoding protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. All /// methods that can be implemented as listeners will be. - static objc.ObjCObjectBase implementAsListener( + static NSCoding implementAsListener( {required void Function(NSCoder) encodeWithCoder_, required Dartinstancetype? Function(NSCoder) initWithCoder_}) { final builder = objc.ObjCProtocolBuilder(); NSCoding.encodeWithCoder_.implementAsListener(builder, encodeWithCoder_); NSCoding.initWithCoder_.implement(builder, initWithCoder_); - return builder.build(); + return NSCoding.castFrom(builder.build()); } /// Adds the implementation of the NSCoding protocol to an existing @@ -938,13 +957,13 @@ abstract interface class NSCoding implements objc.ObjCProtocolBase { /// Builds an object that implements the NSCoding protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. All /// methods that can be implemented as blocking listeners will be. - static objc.ObjCObjectBase implementAsBlocking( + static NSCoding implementAsBlocking( {required void Function(NSCoder) encodeWithCoder_, required Dartinstancetype? Function(NSCoder) initWithCoder_}) { final builder = objc.ObjCProtocolBuilder(); NSCoding.encodeWithCoder_.implementAsBlocking(builder, encodeWithCoder_); NSCoding.initWithCoder_.implement(builder, initWithCoder_); - return builder.build(); + return NSCoding.castFrom(builder.build()); } /// Adds the implementation of the NSCoding protocol to an existing @@ -1012,15 +1031,34 @@ enum NSComparisonResult { } /// NSCopying -abstract interface class NSCopying implements objc.ObjCProtocolBase { +interface class NSCopying extends objc.ObjCProtocolBase { + NSCopying._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSCopying] that points to the same underlying object as [other]. + NSCopying.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSCopying] that wraps the given raw object pointer. + NSCopying.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSCopying]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz( + obj.ref.pointer, _sel_conformsToProtocol_, _protocol_NSCopying); + } + /// Builds an object that implements the NSCopying protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. - static objc.ObjCObjectBase implement( + static NSCopying implement( {required objc.ObjCObjectBase Function(ffi.Pointer) copyWithZone_}) { final builder = objc.ObjCProtocolBuilder(); NSCopying.copyWithZone_.implement(builder, copyWithZone_); - return builder.build(); + return NSCopying.castFrom(builder.build()); } /// Adds the implementation of the NSCopying protocol to an existing @@ -1691,7 +1729,7 @@ class NSDictionary extends NSObject /// dictionaryWithObject:forKey: static NSDictionary dictionaryWithObject_forKey_( - objc.ObjCObjectBase object, objc.ObjCObjectBase key) { + objc.ObjCObjectBase object, NSCopying key) { final _ret = _objc_msgSend_15qeuct(_class_NSDictionary, _sel_dictionaryWithObject_forKey_, object.ref.pointer, key.ref.pointer); return NSDictionary.castFromPointer(_ret, retain: true, release: true); @@ -2785,8 +2823,7 @@ extension NSExtendedMutableDictionary on NSMutableDictionary { } /// setObject:forKeyedSubscript: - void setObject_forKeyedSubscript_( - objc.ObjCObjectBase? obj, objc.ObjCObjectBase key) { + void setObject_forKeyedSubscript_(objc.ObjCObjectBase? obj, NSCopying key) { _objc_msgSend_pfv6jd(this.ref.pointer, _sel_setObject_forKeyedSubscript_, obj?.ref.pointer ?? ffi.nullptr, key.ref.pointer); } @@ -3183,17 +3220,36 @@ extension NSExtendedSet on NSSet { } /// NSFastEnumeration -abstract interface class NSFastEnumeration implements objc.ObjCProtocolBase { +interface class NSFastEnumeration extends objc.ObjCProtocolBase { + NSFastEnumeration._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSFastEnumeration] that points to the same underlying object as [other]. + NSFastEnumeration.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSFastEnumeration] that wraps the given raw object pointer. + NSFastEnumeration.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSFastEnumeration]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz( + obj.ref.pointer, _sel_conformsToProtocol_, _protocol_NSFastEnumeration); + } + /// Builds an object that implements the NSFastEnumeration protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. - static objc.ObjCObjectBase implement( + static NSFastEnumeration implement( {required int Function(ffi.Pointer, ffi.Pointer>, int) countByEnumeratingWithState_objects_count_}) { final builder = objc.ObjCProtocolBuilder(); NSFastEnumeration.countByEnumeratingWithState_objects_count_ .implement(builder, countByEnumeratingWithState_objects_count_); - return builder.build(); + return NSFastEnumeration.castFrom(builder.build()); } /// Adds the implementation of the NSFastEnumeration protocol to an existing @@ -3597,7 +3653,7 @@ class NSItemProvider extends NSObject implements NSCopying { } /// canLoadObjectOfClass: - bool canLoadObjectOfClass_(objc.ObjCObjectBase aClass) { + bool canLoadObjectOfClass_(NSItemProviderReading aClass) { return _objc_msgSend_19nvye5( this.ref.pointer, _sel_canLoadObjectOfClass_, aClass.ref.pointer); } @@ -3636,7 +3692,7 @@ class NSItemProvider extends NSObject implements NSCopying { /// initWithItem:typeIdentifier: NSItemProvider initWithItem_typeIdentifier_( - objc.ObjCObjectBase? item, NSString? typeIdentifier) { + NSSecureCoding? item, NSString? typeIdentifier) { final _ret = _objc_msgSend_15qeuct( this.ref.retainAndReturnPointer(), _sel_initWithItem_typeIdentifier_, @@ -3646,7 +3702,7 @@ class NSItemProvider extends NSObject implements NSCopying { } /// initWithObject: - NSItemProvider initWithObject_(objc.ObjCObjectBase object) { + NSItemProvider initWithObject_(NSItemProviderWriting object) { final _ret = _objc_msgSend_1sotr3r(this.ref.retainAndReturnPointer(), _sel_initWithObject_, object.ref.pointer); return NSItemProvider.castFromPointer(_ret, retain: false, release: true); @@ -3667,7 +3723,7 @@ class NSItemProvider extends NSObject implements NSCopying { } /// registerObject:visibility: - void registerObject_visibility_(objc.ObjCObjectBase object, + void registerObject_visibility_(NSItemProviderWriting object, NSItemProviderRepresentationVisibility visibility) { _objc_msgSend_1k745tv(this.ref.pointer, _sel_registerObject_visibility_, object.ref.pointer, visibility.value); @@ -3728,6 +3784,43 @@ enum NSItemProviderFileOptions { }; } +/// NSItemProviderReading +interface class NSItemProviderReading extends objc.ObjCProtocolBase + implements NSObjectProtocol { + NSItemProviderReading._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSItemProviderReading] that points to the same underlying object as [other]. + NSItemProviderReading.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSItemProviderReading] that wraps the given raw object pointer. + NSItemProviderReading.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSItemProviderReading]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz(obj.ref.pointer, _sel_conformsToProtocol_, + _protocol_NSItemProviderReading); + } + + /// Builds an object that implements the NSItemProviderReading protocol. To implement + /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. + static NSItemProviderReading implement() { + final builder = objc.ObjCProtocolBuilder(); + + return NSItemProviderReading.castFrom(builder.build()); + } + + /// Adds the implementation of the NSItemProviderReading protocol to an existing + /// [objc.ObjCProtocolBuilder]. + static void addToBuilder( + objc.ObjCProtocolBuilder builder, + ) {} +} + enum NSItemProviderRepresentationVisibility { NSItemProviderRepresentationVisibilityAll(0), NSItemProviderRepresentationVisibilityTeam(1), @@ -3748,6 +3841,94 @@ enum NSItemProviderRepresentationVisibility { }; } +/// NSItemProviderWriting +interface class NSItemProviderWriting extends objc.ObjCProtocolBase + implements NSObjectProtocol { + NSItemProviderWriting._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSItemProviderWriting] that points to the same underlying object as [other]. + NSItemProviderWriting.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSItemProviderWriting] that wraps the given raw object pointer. + NSItemProviderWriting.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSItemProviderWriting]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz(obj.ref.pointer, _sel_conformsToProtocol_, + _protocol_NSItemProviderWriting); + } + + /// Builds an object that implements the NSItemProviderWriting protocol. To implement + /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. + static NSItemProviderWriting implement( + {NSItemProviderRepresentationVisibility Function(NSString)? + itemProviderVisibilityForRepresentationWithTypeIdentifier_, + NSArray Function()? writableTypeIdentifiersForItemProvider}) { + final builder = objc.ObjCProtocolBuilder(); + NSItemProviderWriting + .itemProviderVisibilityForRepresentationWithTypeIdentifier_ + .implement(builder, + itemProviderVisibilityForRepresentationWithTypeIdentifier_); + NSItemProviderWriting.writableTypeIdentifiersForItemProvider + .implement(builder, writableTypeIdentifiersForItemProvider); + return NSItemProviderWriting.castFrom(builder.build()); + } + + /// Adds the implementation of the NSItemProviderWriting protocol to an existing + /// [objc.ObjCProtocolBuilder]. + static void addToBuilder(objc.ObjCProtocolBuilder builder, + {NSItemProviderRepresentationVisibility Function(NSString)? + itemProviderVisibilityForRepresentationWithTypeIdentifier_, + NSArray Function()? writableTypeIdentifiersForItemProvider}) { + NSItemProviderWriting + .itemProviderVisibilityForRepresentationWithTypeIdentifier_ + .implement(builder, + itemProviderVisibilityForRepresentationWithTypeIdentifier_); + NSItemProviderWriting.writableTypeIdentifiersForItemProvider + .implement(builder, writableTypeIdentifiersForItemProvider); + } + + /// itemProviderVisibilityForRepresentationWithTypeIdentifier: + static final itemProviderVisibilityForRepresentationWithTypeIdentifier_ = + objc.ObjCProtocolMethod< + NSItemProviderRepresentationVisibility Function(NSString)>( + _protocol_NSItemProviderWriting, + _sel_itemProviderVisibilityForRepresentationWithTypeIdentifier_, + objc.getProtocolMethodSignature( + _protocol_NSItemProviderWriting, + _sel_itemProviderVisibilityForRepresentationWithTypeIdentifier_, + isRequired: false, + isInstanceMethod: true, + ), + (NSItemProviderRepresentationVisibility Function(NSString) func) => + ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString + .fromFunction( + (ffi.Pointer _, NSString arg1) => func(arg1)), + ); + + /// writableTypeIdentifiersForItemProvider + static final writableTypeIdentifiersForItemProvider = + objc.ObjCProtocolMethod( + _protocol_NSItemProviderWriting, + _sel_writableTypeIdentifiersForItemProvider, + objc.getProtocolMethodSignature( + _protocol_NSItemProviderWriting, + _sel_writableTypeIdentifiersForItemProvider, + isRequired: false, + isInstanceMethod: true, + ), + (NSArray Function() func) => ObjCBlock_NSArray_ffiVoid.fromFunction(( + ffi.Pointer _, + ) => + func()), + ); +} + enum NSKeyValueChange { NSKeyValueChangeSetting(1), NSKeyValueChangeInsertion(2), @@ -4090,16 +4271,35 @@ class NSMutableArray extends NSArray { } /// NSMutableCopying -abstract interface class NSMutableCopying implements objc.ObjCProtocolBase { +interface class NSMutableCopying extends objc.ObjCProtocolBase { + NSMutableCopying._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSMutableCopying] that points to the same underlying object as [other]. + NSMutableCopying.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSMutableCopying] that wraps the given raw object pointer. + NSMutableCopying.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSMutableCopying]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz( + obj.ref.pointer, _sel_conformsToProtocol_, _protocol_NSMutableCopying); + } + /// Builds an object that implements the NSMutableCopying protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. - static objc.ObjCObjectBase implement( + static NSMutableCopying implement( {required objc.ObjCObjectBase Function(ffi.Pointer) mutableCopyWithZone_}) { final builder = objc.ObjCProtocolBuilder(); NSMutableCopying.mutableCopyWithZone_ .implement(builder, mutableCopyWithZone_); - return builder.build(); + return NSMutableCopying.castFrom(builder.build()); } /// Adds the implementation of the NSMutableCopying protocol to an existing @@ -4519,7 +4719,7 @@ class NSMutableDictionary extends NSDictionary { /// dictionaryWithObject:forKey: static NSMutableDictionary dictionaryWithObject_forKey_( - objc.ObjCObjectBase object, objc.ObjCObjectBase key) { + objc.ObjCObjectBase object, NSCopying key) { final _ret = _objc_msgSend_15qeuct(_class_NSMutableDictionary, _sel_dictionaryWithObject_forKey_, object.ref.pointer, key.ref.pointer); return NSMutableDictionary.castFromPointer(_ret, @@ -4648,8 +4848,7 @@ class NSMutableDictionary extends NSDictionary { } /// setObject:forKey: - void setObject_forKey_( - objc.ObjCObjectBase anObject, objc.ObjCObjectBase aKey) { + void setObject_forKey_(objc.ObjCObjectBase anObject, NSCopying aKey) { _objc_msgSend_pfv6jd(this.ref.pointer, _sel_setObject_forKey_, anObject.ref.pointer, aKey.ref.pointer); } @@ -6584,10 +6783,29 @@ class NSObject extends objc.ObjCObjectBase implements NSObjectProtocol { } /// NSObject -abstract interface class NSObjectProtocol implements objc.ObjCProtocolBase { +interface class NSObjectProtocol extends objc.ObjCProtocolBase { + NSObjectProtocol._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSObjectProtocol] that points to the same underlying object as [other]. + NSObjectProtocol.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSObjectProtocol] that wraps the given raw object pointer. + NSObjectProtocol.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSObjectProtocol]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz( + obj.ref.pointer, _sel_conformsToProtocol_, _protocol_NSObject); + } + /// Builds an object that implements the NSObject protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. - static objc.ObjCObjectBase implement( + static NSObjectProtocol implement( {required objc.ObjCObjectBase Function() autorelease, required objc.ObjCObjectBase Function() class1, required bool Function(Protocol) conformsToProtocol_, @@ -6639,7 +6857,7 @@ abstract interface class NSObjectProtocol implements objc.ObjCProtocolBase { NSObjectProtocol.self1.implement(builder, self1); NSObjectProtocol.superclass.implement(builder, superclass); NSObjectProtocol.zone.implement(builder, zone); - return builder.build(); + return NSObjectProtocol.castFrom(builder.build()); } /// Adds the implementation of the NSObject protocol to an existing @@ -6700,7 +6918,7 @@ abstract interface class NSObjectProtocol implements objc.ObjCProtocolBase { /// Builds an object that implements the NSObject protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. All /// methods that can be implemented as listeners will be. - static objc.ObjCObjectBase implementAsListener( + static NSObjectProtocol implementAsListener( {required objc.ObjCObjectBase Function() autorelease, required objc.ObjCObjectBase Function() class1, required bool Function(Protocol) conformsToProtocol_, @@ -6752,7 +6970,7 @@ abstract interface class NSObjectProtocol implements objc.ObjCProtocolBase { NSObjectProtocol.self1.implement(builder, self1); NSObjectProtocol.superclass.implement(builder, superclass); NSObjectProtocol.zone.implement(builder, zone); - return builder.build(); + return NSObjectProtocol.castFrom(builder.build()); } /// Adds the implementation of the NSObject protocol to an existing @@ -6814,7 +7032,7 @@ abstract interface class NSObjectProtocol implements objc.ObjCProtocolBase { /// Builds an object that implements the NSObject protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. All /// methods that can be implemented as blocking listeners will be. - static objc.ObjCObjectBase implementAsBlocking( + static NSObjectProtocol implementAsBlocking( {required objc.ObjCObjectBase Function() autorelease, required objc.ObjCObjectBase Function() class1, required bool Function(Protocol) conformsToProtocol_, @@ -6866,7 +7084,7 @@ abstract interface class NSObjectProtocol implements objc.ObjCProtocolBase { NSObjectProtocol.self1.implement(builder, self1); NSObjectProtocol.superclass.implement(builder, superclass); NSObjectProtocol.zone.implement(builder, zone); - return builder.build(); + return NSObjectProtocol.castFrom(builder.build()); } /// Adds the implementation of the NSObject protocol to an existing @@ -8009,16 +8227,36 @@ class NSRunLoop extends objc.ObjCObjectBase { } /// NSSecureCoding -abstract interface class NSSecureCoding implements NSCoding { +interface class NSSecureCoding extends objc.ObjCProtocolBase + implements NSCoding { + NSSecureCoding._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSSecureCoding] that points to the same underlying object as [other]. + NSSecureCoding.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSSecureCoding] that wraps the given raw object pointer. + NSSecureCoding.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSSecureCoding]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz( + obj.ref.pointer, _sel_conformsToProtocol_, _protocol_NSSecureCoding); + } + /// Builds an object that implements the NSSecureCoding protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. - static objc.ObjCObjectBase implement( + static NSSecureCoding implement( {required void Function(NSCoder) encodeWithCoder_, required Dartinstancetype? Function(NSCoder) initWithCoder_}) { final builder = objc.ObjCProtocolBuilder(); NSSecureCoding.encodeWithCoder_.implement(builder, encodeWithCoder_); NSSecureCoding.initWithCoder_.implement(builder, initWithCoder_); - return builder.build(); + return NSSecureCoding.castFrom(builder.build()); } /// Adds the implementation of the NSSecureCoding protocol to an existing @@ -8033,14 +8271,14 @@ abstract interface class NSSecureCoding implements NSCoding { /// Builds an object that implements the NSSecureCoding protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. All /// methods that can be implemented as listeners will be. - static objc.ObjCObjectBase implementAsListener( + static NSSecureCoding implementAsListener( {required void Function(NSCoder) encodeWithCoder_, required Dartinstancetype? Function(NSCoder) initWithCoder_}) { final builder = objc.ObjCProtocolBuilder(); NSSecureCoding.encodeWithCoder_ .implementAsListener(builder, encodeWithCoder_); NSSecureCoding.initWithCoder_.implement(builder, initWithCoder_); - return builder.build(); + return NSSecureCoding.castFrom(builder.build()); } /// Adds the implementation of the NSSecureCoding protocol to an existing @@ -8057,14 +8295,14 @@ abstract interface class NSSecureCoding implements NSCoding { /// Builds an object that implements the NSSecureCoding protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. All /// methods that can be implemented as blocking listeners will be. - static objc.ObjCObjectBase implementAsBlocking( + static NSSecureCoding implementAsBlocking( {required void Function(NSCoder) encodeWithCoder_, required Dartinstancetype? Function(NSCoder) initWithCoder_}) { final builder = objc.ObjCProtocolBuilder(); NSSecureCoding.encodeWithCoder_ .implementAsBlocking(builder, encodeWithCoder_); NSSecureCoding.initWithCoder_.implement(builder, initWithCoder_); - return builder.build(); + return NSSecureCoding.castFrom(builder.build()); } /// Adds the implementation of the NSSecureCoding protocol to an existing @@ -8356,11 +8594,11 @@ class NSStream extends NSObject { } /// delegate - objc.ObjCObjectBase? get delegate { + NSStreamDelegate? get delegate { final _ret = _objc_msgSend_151sglz(this.ref.pointer, _sel_delegate); return _ret.address == 0 ? null - : objc.ObjCObjectBase(_ret, retain: true, release: true); + : NSStreamDelegate.castFromPointer(_ret, retain: true, release: true); } /// init @@ -8409,7 +8647,7 @@ class NSStream extends NSObject { } /// setDelegate: - set delegate(objc.ObjCObjectBase? value) { + set delegate(NSStreamDelegate? value) { _objc_msgSend_xtuoz7( this.ref.pointer, _sel_setDelegate_, value?.ref.pointer ?? ffi.nullptr); } @@ -8436,15 +8674,35 @@ class NSStream extends NSObject { } /// NSStreamDelegate -abstract interface class NSStreamDelegate implements NSObjectProtocol { +interface class NSStreamDelegate extends objc.ObjCProtocolBase + implements NSObjectProtocol { + NSStreamDelegate._(ffi.Pointer pointer, + {bool retain = false, bool release = false}) + : super(pointer, retain: retain, release: release); + + /// Constructs a [NSStreamDelegate] that points to the same underlying object as [other]. + NSStreamDelegate.castFrom(objc.ObjCObjectBase other) + : this._(other.ref.pointer, retain: true, release: true); + + /// Constructs a [NSStreamDelegate] that wraps the given raw object pointer. + NSStreamDelegate.castFromPointer(ffi.Pointer other, + {bool retain = false, bool release = false}) + : this._(other, retain: retain, release: release); + + /// Returns whether [obj] is an instance of [NSStreamDelegate]. + static bool conformsTo(objc.ObjCObjectBase obj) { + return _objc_msgSend_e3qsqz( + obj.ref.pointer, _sel_conformsToProtocol_, _protocol_NSStreamDelegate); + } + /// Builds an object that implements the NSStreamDelegate protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. - static objc.ObjCObjectBase implement( + static NSStreamDelegate implement( {void Function(NSStream, NSStreamEvent)? stream_handleEvent_}) { final builder = objc.ObjCProtocolBuilder(); NSStreamDelegate.stream_handleEvent_ .implement(builder, stream_handleEvent_); - return builder.build(); + return NSStreamDelegate.castFrom(builder.build()); } /// Adds the implementation of the NSStreamDelegate protocol to an existing @@ -8458,12 +8716,12 @@ abstract interface class NSStreamDelegate implements NSObjectProtocol { /// Builds an object that implements the NSStreamDelegate protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. All /// methods that can be implemented as listeners will be. - static objc.ObjCObjectBase implementAsListener( + static NSStreamDelegate implementAsListener( {void Function(NSStream, NSStreamEvent)? stream_handleEvent_}) { final builder = objc.ObjCProtocolBuilder(); NSStreamDelegate.stream_handleEvent_ .implementAsListener(builder, stream_handleEvent_); - return builder.build(); + return NSStreamDelegate.castFrom(builder.build()); } /// Adds the implementation of the NSStreamDelegate protocol to an existing @@ -8478,12 +8736,12 @@ abstract interface class NSStreamDelegate implements NSObjectProtocol { /// Builds an object that implements the NSStreamDelegate protocol. To implement /// multiple protocols, use [addToBuilder] or [objc.ObjCProtocolBuilder] directly. All /// methods that can be implemented as blocking listeners will be. - static objc.ObjCObjectBase implementAsBlocking( + static NSStreamDelegate implementAsBlocking( {void Function(NSStream, NSStreamEvent)? stream_handleEvent_}) { final builder = objc.ObjCProtocolBuilder(); NSStreamDelegate.stream_handleEvent_ .implementAsBlocking(builder, stream_handleEvent_); - return builder.build(); + return NSStreamDelegate.castFrom(builder.build()); } /// Adds the implementation of the NSStreamDelegate protocol to an existing @@ -10738,6 +10996,193 @@ class NSValue extends NSObject implements NSCopying, NSSecureCoding { final class NSZone extends ffi.Opaque {} +ffi.Pointer _ObjCBlock_NSArray_ffiVoid_fnPtrTrampoline( + ffi.Pointer block, ffi.Pointer arg0) => + block.ref.target + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer arg0)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer)>()(arg0); +ffi.Pointer _ObjCBlock_NSArray_ffiVoid_fnPtrCallable = + ffi.Pointer.fromFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>( + _ObjCBlock_NSArray_ffiVoid_fnPtrTrampoline) + .cast(); +ffi.Pointer _ObjCBlock_NSArray_ffiVoid_closureTrampoline( + ffi.Pointer block, ffi.Pointer arg0) => + (objc.getBlockClosure(block) as ffi.Pointer Function( + ffi.Pointer))(arg0); +ffi.Pointer _ObjCBlock_NSArray_ffiVoid_closureCallable = + ffi.Pointer.fromFunction< + ffi.Pointer Function( + ffi.Pointer, ffi.Pointer)>( + _ObjCBlock_NSArray_ffiVoid_closureTrampoline) + .cast(); + +/// Construction methods for `objc.ObjCBlock)>`. +abstract final class ObjCBlock_NSArray_ffiVoid { + /// Returns a block that wraps the given raw block pointer. + static objc.ObjCBlock)> + castFromPointer(ffi.Pointer pointer, + {bool retain = false, bool release = false}) => + objc.ObjCBlock)>(pointer, + retain: retain, release: release); + + /// Creates a block from a C function pointer. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + static objc.ObjCBlock)> fromFunctionPointer( + ffi.Pointer< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer arg0)>> + ptr) => + objc.ObjCBlock)>( + objc.newPointerBlock( + _ObjCBlock_NSArray_ffiVoid_fnPtrCallable, ptr.cast()), + retain: false, + release: true); + + /// Creates a block from a Dart function. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + static objc.ObjCBlock)> fromFunction( + NSArray Function(ffi.Pointer) fn) => + objc.ObjCBlock)>( + objc.newClosureBlock( + _ObjCBlock_NSArray_ffiVoid_closureCallable, + (ffi.Pointer arg0) => + fn(arg0).ref.retainAndAutorelease()), + retain: false, + release: true); +} + +/// Call operator for `objc.ObjCBlock)>`. +extension ObjCBlock_NSArray_ffiVoid_CallExtension + on objc.ObjCBlock)> { + NSArray call(ffi.Pointer arg0) => NSArray.castFromPointer( + ref.pointer.ref.invoke + .cast< + ffi.NativeFunction< + ffi.Pointer Function( + ffi.Pointer block, + ffi.Pointer arg0)>>() + .asFunction< + ffi.Pointer Function( + ffi.Pointer, + ffi.Pointer)>()(ref.pointer, arg0), + retain: true, + release: true); +} + +int _ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_fnPtrTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1) => + block.ref.target + .cast< + ffi.NativeFunction< + ffi.Long Function(ffi.Pointer arg0, + ffi.Pointer arg1)>>() + .asFunction< + int Function(ffi.Pointer, + ffi.Pointer)>()(arg0, arg1); +ffi.Pointer + _ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_fnPtrCallable = + ffi.Pointer.fromFunction< + ffi.Long Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>( + _ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_fnPtrTrampoline, + 0) + .cast(); +int _ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_closureTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1) => + (objc.getBlockClosure(block) as int Function( + ffi.Pointer, ffi.Pointer))(arg0, arg1); +ffi.Pointer + _ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_closureCallable = + ffi.Pointer.fromFunction< + ffi.Long Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>( + _ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_closureTrampoline, + 0) + .cast(); + +/// Construction methods for `objc.ObjCBlock, NSString)>`. +abstract final class ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString { + /// Returns a block that wraps the given raw block pointer. + static objc.ObjCBlock, NSString)> + castFromPointer(ffi.Pointer pointer, + {bool retain = false, bool release = false}) => + objc.ObjCBlock, NSString)>( + pointer, + retain: retain, + release: release); + + /// Creates a block from a C function pointer. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + static objc.ObjCBlock, NSString)> + fromFunctionPointer( + ffi.Pointer< + ffi.NativeFunction< + ffi.Long Function(ffi.Pointer arg0, + ffi.Pointer arg1)>> + ptr) => + objc.ObjCBlock, NSString)>( + objc.newPointerBlock(_ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_fnPtrCallable, ptr.cast()), + retain: false, + release: true); + + /// Creates a block from a Dart function. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + static objc.ObjCBlock, NSString)> fromFunction( + NSItemProviderRepresentationVisibility Function( + ffi.Pointer, NSString) + fn) => + objc.ObjCBlock, NSString)>( + objc.newClosureBlock( + _ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_closureCallable, + (ffi.Pointer arg0, ffi.Pointer arg1) => + fn(arg0, NSString.castFromPointer(arg1, retain: true, release: true)) + .value), + retain: false, + release: true); +} + +/// Call operator for `objc.ObjCBlock, NSString)>`. +extension ObjCBlock_NSItemProviderRepresentationVisibility_ffiVoid_NSString_CallExtension + on objc.ObjCBlock, NSString)> { + NSItemProviderRepresentationVisibility call( + ffi.Pointer arg0, NSString arg1) => + NSItemProviderRepresentationVisibility.fromValue(ref.pointer.ref.invoke + .cast< + ffi.NativeFunction< + ffi.Long Function( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1)>>() + .asFunction< + int Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>()( + ref.pointer, arg0, arg1.ref.pointer)); +} + ffi.Pointer _ObjCBlock_NSString_ffiVoid_fnPtrTrampoline( ffi.Pointer block, ffi.Pointer arg0) => block.ref.target @@ -11674,7 +12119,7 @@ abstract final class ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCO ffi.Pointer arg1, ffi.Pointer arg2) => fn( - ObjCBlock_ffiVoid_objcObjCObject_NSError.castFromPointer(arg0, retain: true, release: true), + ObjCBlock_ffiVoid_idNSSecureCoding_NSError.castFromPointer(arg0, retain: true, release: true), objc.ObjCObjectBase(arg1, retain: true, release: true), NSDictionary.castFromPointer(arg2, retain: true, release: true))), retain: false, @@ -11709,7 +12154,7 @@ abstract final class ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCO ffi.Pointer arg1, ffi.Pointer arg2) => fn( - ObjCBlock_ffiVoid_objcObjCObject_NSError.castFromPointer(arg0, + ObjCBlock_ffiVoid_idNSSecureCoding_NSError.castFromPointer(arg0, retain: false, release: true), objc.ObjCObjectBase(arg1, retain: false, release: true), NSDictionary.castFromPointer(arg2, @@ -11753,7 +12198,7 @@ abstract final class ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCO ffi.Pointer arg1, ffi.Pointer arg2) => fn( - ObjCBlock_ffiVoid_objcObjCObject_NSError.castFromPointer(arg0, + ObjCBlock_ffiVoid_idNSSecureCoding_NSError.castFromPointer(arg0, retain: false, release: true), objc.ObjCObjectBase(arg1, retain: false, release: true), NSDictionary.castFromPointer(arg2, @@ -11766,7 +12211,7 @@ abstract final class ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCO ffi.Pointer arg1, ffi.Pointer arg2) => fn( - ObjCBlock_ffiVoid_objcObjCObject_NSError.castFromPointer(arg0, + ObjCBlock_ffiVoid_idNSSecureCoding_NSError.castFromPointer(arg0, retain: false, release: true), objc.ObjCObjectBase(arg1, retain: false, release: true), NSDictionary.castFromPointer(arg2, @@ -12446,7 +12891,7 @@ extension ObjCBlock_ffiVoid_ffiVoid_NSStream_NSStreamEvent_CallExtension int)>()(ref.pointer, arg0, arg1.ref.pointer, arg2.value); } -void _ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrTrampoline( +void _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_fnPtrTrampoline( ffi.Pointer block, ffi.Pointer arg0, ffi.Pointer arg1) => @@ -12458,30 +12903,31 @@ void _ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrTrampoline( .asFunction< void Function(ffi.Pointer, ffi.Pointer)>()(arg0, arg1); -ffi.Pointer _ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrCallable = +ffi.Pointer + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_fnPtrCallable = ffi.Pointer.fromFunction< ffi.Void Function( ffi.Pointer, ffi.Pointer, ffi.Pointer)>( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrTrampoline) + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_fnPtrTrampoline) .cast(); -void _ObjCBlock_ffiVoid_objcObjCObject_NSError_closureTrampoline( +void _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_closureTrampoline( ffi.Pointer block, ffi.Pointer arg0, ffi.Pointer arg1) => (objc.getBlockClosure(block) as void Function(ffi.Pointer, ffi.Pointer))(arg0, arg1); ffi.Pointer - _ObjCBlock_ffiVoid_objcObjCObject_NSError_closureCallable = + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_closureCallable = ffi.Pointer.fromFunction< ffi.Void Function( ffi.Pointer, ffi.Pointer, ffi.Pointer)>( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_closureTrampoline) + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_closureTrampoline) .cast(); -void _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerTrampoline( +void _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_listenerTrampoline( ffi.Pointer block, ffi.Pointer arg0, ffi.Pointer arg1) { @@ -12493,15 +12939,15 @@ void _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerTrampoline( ffi.NativeCallable< ffi.Void Function(ffi.Pointer, ffi.Pointer, ffi.Pointer)> - _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerCallable = ffi + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_listenerCallable = ffi .NativeCallable< ffi.Void Function( ffi.Pointer, ffi.Pointer, ffi.Pointer)>.listener( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerTrampoline) + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_listenerTrampoline) ..keepIsolateAlive = false; -void _ObjCBlock_ffiVoid_objcObjCObject_NSError_blockingTrampoline( +void _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_blockingTrampoline( ffi.Pointer block, ffi.Pointer waiter, ffi.Pointer arg0, @@ -12522,14 +12968,14 @@ ffi.NativeCallable< ffi.Pointer, ffi.Pointer, ffi.Pointer)> - _ObjCBlock_ffiVoid_objcObjCObject_NSError_blockingCallable = ffi + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_blockingCallable = ffi .NativeCallable< ffi.Void Function( ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>.isolateLocal( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_blockingTrampoline) + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_blockingTrampoline) ..keepIsolateAlive = false; ffi.NativeCallable< ffi.Void Function( @@ -12537,18 +12983,18 @@ ffi.NativeCallable< ffi.Pointer, ffi.Pointer, ffi.Pointer)> - _ObjCBlock_ffiVoid_objcObjCObject_NSError_blockingListenerCallable = ffi + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_blockingListenerCallable = ffi .NativeCallable< ffi.Void Function( ffi.Pointer, ffi.Pointer, ffi.Pointer, ffi.Pointer)>.listener( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_blockingTrampoline) + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_blockingTrampoline) ..keepIsolateAlive = false; /// Construction methods for `objc.ObjCBlock?, NSError)>`. -abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { +abstract final class ObjCBlock_ffiVoid_idNSSecureCoding_NSError { /// Returns a block that wraps the given raw block pointer. static objc .ObjCBlock?, NSError)> @@ -12570,7 +13016,7 @@ abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { ffi.Pointer arg1)>> ptr) => objc.ObjCBlock?, NSError)>( - objc.newPointerBlock(_ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrCallable, ptr.cast()), + objc.newPointerBlock(_ObjCBlock_ffiVoid_idNSSecureCoding_NSError_fnPtrCallable, ptr.cast()), retain: false, release: true); @@ -12580,17 +13026,16 @@ abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { /// the isolate that registered it. Invoking the block on the wrong thread /// will result in a crash. static objc.ObjCBlock?, NSError)> fromFunction( - void Function(objc.ObjCObjectBase?, NSError) fn) => + void Function(NSSecureCoding?, NSError) fn) => objc.ObjCBlock?, NSError)>( objc.newClosureBlock( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_closureCallable, - (ffi.Pointer arg0, - ffi.Pointer arg1) => - fn( - arg0.address == 0 - ? null - : objc.ObjCObjectBase(arg0, retain: true, release: true), - NSError.castFromPointer(arg1, retain: true, release: true))), + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_closureCallable, + (ffi.Pointer arg0, ffi.Pointer arg1) => fn( + arg0.address == 0 + ? null + : NSSecureCoding.castFromPointer(arg0, + retain: true, release: true), + NSError.castFromPointer(arg1, retain: true, release: true))), retain: false, release: true); @@ -12605,9 +13050,9 @@ abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { /// blocks do not keep the isolate alive. static objc .ObjCBlock?, NSError)> - listener(void Function(objc.ObjCObjectBase?, NSError) fn) { + listener(void Function(NSSecureCoding?, NSError) fn) { final raw = objc.newClosureBlock( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerCallable + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_listenerCallable .nativeFunction .cast(), (ffi.Pointer arg0, @@ -12615,7 +13060,8 @@ abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { fn( arg0.address == 0 ? null - : objc.ObjCObjectBase(arg0, retain: false, release: true), + : NSSecureCoding.castFromPointer(arg0, + retain: false, release: true), NSError.castFromPointer(arg1, retain: false, release: true))); final wrapper = _ObjectiveCBindings_wrapListenerBlock_pfv6jd(raw); objc.objectRelease(raw.cast()); @@ -12635,9 +13081,9 @@ abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { /// indefinitely, or have other undefined behavior. static objc .ObjCBlock?, NSError)> - blocking(void Function(objc.ObjCObjectBase?, NSError) fn) { + blocking(void Function(NSSecureCoding?, NSError) fn) { final raw = objc.newClosureBlock( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_blockingCallable + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_blockingCallable .nativeFunction .cast(), (ffi.Pointer arg0, @@ -12645,10 +13091,11 @@ abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { fn( arg0.address == 0 ? null - : objc.ObjCObjectBase(arg0, retain: false, release: true), + : NSSecureCoding.castFromPointer(arg0, + retain: false, release: true), NSError.castFromPointer(arg1, retain: false, release: true))); final rawListener = objc.newClosureBlock( - _ObjCBlock_ffiVoid_objcObjCObject_NSError_blockingListenerCallable + _ObjCBlock_ffiVoid_idNSSecureCoding_NSError_blockingListenerCallable .nativeFunction .cast(), (ffi.Pointer arg0, @@ -12656,7 +13103,8 @@ abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { fn( arg0.address == 0 ? null - : objc.ObjCObjectBase(arg0, retain: false, release: true), + : NSSecureCoding.castFromPointer(arg0, + retain: false, release: true), NSError.castFromPointer(arg1, retain: false, release: true))); final wrapper = objc.wrapBlockingBlock( _ObjectiveCBindings_wrapBlockingBlock_pfv6jd, raw, rawListener); @@ -12669,9 +13117,9 @@ abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { } /// Call operator for `objc.ObjCBlock?, NSError)>`. -extension ObjCBlock_ffiVoid_objcObjCObject_NSError_CallExtension on objc +extension ObjCBlock_ffiVoid_idNSSecureCoding_NSError_CallExtension on objc .ObjCBlock?, NSError)> { - void call(objc.ObjCObjectBase? arg0, NSError arg1) => ref.pointer.ref.invoke + void call(NSSecureCoding? arg0, NSError arg1) => ref.pointer.ref.invoke .cast< ffi.NativeFunction< ffi.Void Function( @@ -13817,6 +14265,16 @@ final _objc_msgSend_16f0drb = objc.msgSendPointer .asFunction< ffi.Pointer Function(ffi.Pointer, ffi.Pointer, int)>(); +final _objc_msgSend_16fy0up = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Long Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + int Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(); final _objc_msgSend_17amj0z = objc.msgSendPointer .cast< ffi.NativeFunction< @@ -15110,6 +15568,16 @@ final _objc_msgSend_dv3z6r = objc.msgSendPointer bool, int, ffi.Pointer>)>(); +final _objc_msgSend_e3qsqz = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Bool Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + bool Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)>(); final _objc_msgSend_e9mncn = objc.msgSendPointer .cast< ffi.NativeFunction< @@ -15632,6 +16100,10 @@ final _objc_msgSend_zug4wi = objc.msgSendPointer late final _protocol_NSCoding = objc.getProtocol("NSCoding"); late final _protocol_NSCopying = objc.getProtocol("NSCopying"); late final _protocol_NSFastEnumeration = objc.getProtocol("NSFastEnumeration"); +late final _protocol_NSItemProviderReading = + objc.getProtocol("NSItemProviderReading"); +late final _protocol_NSItemProviderWriting = + objc.getProtocol("NSItemProviderWriting"); late final _protocol_NSMutableCopying = objc.getProtocol("NSMutableCopying"); late final _protocol_NSObject = objc.getProtocol("NSObject"); late final _protocol_NSSecureCoding = objc.getProtocol("NSSecureCoding"); @@ -16134,6 +16606,9 @@ late final _sel_isSubsetOfOrderedSet_ = objc.registerName("isSubsetOfOrderedSet:"); late final _sel_isSubsetOfSet_ = objc.registerName("isSubsetOfSet:"); late final _sel_isSupersetOfSet_ = objc.registerName("isSupersetOfSet:"); +late final _sel_itemProviderVisibilityForRepresentationWithTypeIdentifier_ = + objc.registerName( + "itemProviderVisibilityForRepresentationWithTypeIdentifier:"); late final _sel_keyEnumerator = objc.registerName("keyEnumerator"); late final _sel_keysSortedByValueUsingSelector_ = objc.registerName("keysSortedByValueUsingSelector:"); @@ -16538,6 +17013,8 @@ late final _sel_whitespaceAndNewlineCharacterSet = objc.registerName("whitespaceAndNewlineCharacterSet"); late final _sel_whitespaceCharacterSet = objc.registerName("whitespaceCharacterSet"); +late final _sel_writableTypeIdentifiersForItemProvider = + objc.registerName("writableTypeIdentifiersForItemProvider"); late final _sel_writeBookmarkData_toURL_options_error_ = objc.registerName("writeBookmarkData:toURL:options:error:"); late final _sel_writeToFile_atomically_ = diff --git a/pkgs/objective_c/src/objective_c_bindings_generated.m b/pkgs/objective_c/src/objective_c_bindings_generated.m index 2225913e04..6a1372a06b 100644 --- a/pkgs/objective_c/src/objective_c_bindings_generated.m +++ b/pkgs/objective_c/src/objective_c_bindings_generated.m @@ -16,6 +16,10 @@ Protocol* _ObjectiveCBindings_NSFastEnumeration(void) { return @protocol(NSFastEnumeration); } +Protocol* _ObjectiveCBindings_NSItemProviderReading(void) { return @protocol(NSItemProviderReading); } + +Protocol* _ObjectiveCBindings_NSItemProviderWriting(void) { return @protocol(NSItemProviderWriting); } + Protocol* _ObjectiveCBindings_NSMutableCopying(void) { return @protocol(NSMutableCopying); } Protocol* _ObjectiveCBindings_NSObject(void) { return @protocol(NSObject); } diff --git a/pkgs/objective_c/test/interface_lists_test.dart b/pkgs/objective_c/test/interface_lists_test.dart index 9a884ee52e..7c246d1542 100644 --- a/pkgs/objective_c/test/interface_lists_test.dart +++ b/pkgs/objective_c/test/interface_lists_test.dart @@ -163,7 +163,7 @@ void main() { }); test('All code genned protocols are included in the list', () { - final protocolNameRegExp = RegExp(r'^abstract interface class (\w+) '); + final protocolNameRegExp = RegExp(r'^interface class (\w+) '); final allProtocolNames = []; for (final line in File('lib/src/objective_c_bindings_generated.dart') .readAsLinesSync()) { diff --git a/pkgs/objective_c/test/ns_input_stream_test.dart b/pkgs/objective_c/test/ns_input_stream_test.dart index 40682a2aee..123dda3062 100644 --- a/pkgs/objective_c/test/ns_input_stream_test.dart +++ b/pkgs/objective_c/test/ns_input_stream_test.dart @@ -253,12 +253,10 @@ void main() { }); test('non-self delegate', () async { - final protoBuilder = ObjCProtocolBuilder(); final events = []; - NSStreamDelegate.addToBuilder(protoBuilder, + inputStream.delegate = NSStreamDelegate.implement( stream_handleEvent_: (stream, event) => events.add(event)); - inputStream.delegate = protoBuilder.build(); inputStream.stream_handleEvent_( inputStream, NSStreamEvent.NSStreamEventOpenCompleted); expect(events, [NSStreamEvent.NSStreamEventOpenCompleted]); @@ -298,7 +296,7 @@ void main() { [1, 2, 3], ]).toNSInputStream() as DartInputStreamAdapter; - inputStream.delegate = NSObject.new1(); + inputStream.delegate = NSStreamDelegate.castFrom(NSObject.new1()); expect(inputStream.delegate, isNot(inputStream)); final ptr = inputStream.ref.pointer;