diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md
index 6936f68117..b56a40671c 100644
--- a/pkgs/ffigen/CHANGELOG.md
+++ b/pkgs/ffigen/CHANGELOG.md
@@ -23,6 +23,8 @@
To silence the warning set config `silence-enum-warning` to `true`.
- Rename ObjC interface methods that clash with type names. Fixes
https://github.com/dart-lang/native/issues/1007.
+- Added support for implementing ObjC protocols from Dart. Use the
+ `objc-protocols` config option to generate bindings for a protocol.
## 12.0.0
diff --git a/pkgs/ffigen/README.md b/pkgs/ffigen/README.md
index 178e99fe02..0e924413a5 100644
--- a/pkgs/ffigen/README.md
+++ b/pkgs/ffigen/README.md
@@ -666,11 +666,12 @@ import:
- objc-interfaces
+ objc-interfaces
objc-protocols
|
- Filters for interface declarations. This option works the same as other
- declaration filters like `functions` and `structs`.
+ Filters for Objective C interface and protocol declarations. This option
+ works the same as other declaration filters like `functions` and
+ `structs`.
|
@@ -687,6 +688,10 @@ objc-interfaces:
rename:
# Removes '_' prefix from interface names.
'_(.*)': '$1'
+objc-protocols:
+ include:
+ # Generates bindings for a specific protocol.
+ - MyProtocol
```
|
@@ -694,10 +699,10 @@ objc-interfaces:
- objc-interfaces -> module
+ objc-interfaces -> module
objc-protocols -> module
|
- Adds a module prefix to the class name when loading the class
+ Adds a module prefix to the interface/protocol name when loading it
from the dylib. This is only relevent for ObjC headers that are generated
wrappers for a Swift library. See example/swift for more information.
|
diff --git a/pkgs/ffigen/ffigen.schema.json b/pkgs/ffigen/ffigen.schema.json
index 71311a85cd..6f565e583a 100644
--- a/pkgs/ffigen/ffigen.schema.json
+++ b/pkgs/ffigen/ffigen.schema.json
@@ -333,7 +333,28 @@
"$ref": "#/$defs/memberRename"
},
"module": {
- "$ref": "#/$defs/objcInterfaceModule"
+ "$ref": "#/$defs/objcModule"
+ }
+ }
+ },
+ "objc-protocols": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "include": {
+ "$ref": "#/$defs/fullMatchOrRegexpList"
+ },
+ "exclude": {
+ "$ref": "#/$defs/fullMatchOrRegexpList"
+ },
+ "rename": {
+ "$ref": "#/$defs/rename"
+ },
+ "member-rename": {
+ "$ref": "#/$defs/memberRename"
+ },
+ "module": {
+ "$ref": "#/$defs/objcModule"
}
}
},
@@ -495,7 +516,7 @@
"opaque"
]
},
- "objcInterfaceModule": {
+ "objcModule": {
"type": "object",
"patternProperties": {
".*": {
diff --git a/pkgs/ffigen/lib/src/code_generator.dart b/pkgs/ffigen/lib/src/code_generator.dart
index 5977439a03..d706b2d3f2 100644
--- a/pkgs/ffigen/lib/src/code_generator.dart
+++ b/pkgs/ffigen/lib/src/code_generator.dart
@@ -19,7 +19,9 @@ export 'code_generator/native_type.dart';
export 'code_generator/objc_block.dart';
export 'code_generator/objc_built_in_functions.dart';
export 'code_generator/objc_interface.dart';
+export 'code_generator/objc_methods.dart';
export 'code_generator/objc_nullable.dart';
+export 'code_generator/objc_protocol.dart';
export 'code_generator/pointer.dart';
export 'code_generator/struct.dart';
export 'code_generator/type.dart';
diff --git a/pkgs/ffigen/lib/src/code_generator/binding_string.dart b/pkgs/ffigen/lib/src/code_generator/binding_string.dart
index a77193a244..60d3820c9c 100644
--- a/pkgs/ffigen/lib/src/code_generator/binding_string.dart
+++ b/pkgs/ffigen/lib/src/code_generator/binding_string.dart
@@ -24,5 +24,6 @@ enum BindingStringType {
enum_,
typeDef,
objcInterface,
+ objcProtocol,
objcBlock,
}
diff --git a/pkgs/ffigen/lib/src/code_generator/compound.dart b/pkgs/ffigen/lib/src/code_generator/compound.dart
index d7c81e350a..b51b5b469a 100644
--- a/pkgs/ffigen/lib/src/code_generator/compound.dart
+++ b/pkgs/ffigen/lib/src/code_generator/compound.dart
@@ -34,6 +34,8 @@ abstract class Compound extends BindingType {
bool get isStruct => compoundType == CompoundType.struct;
bool get isUnion => compoundType == CompoundType.union;
+ ObjCBuiltInFunctions? objCBuiltInFunctions;
+
Compound({
super.usr,
super.originalName,
@@ -44,6 +46,7 @@ abstract class Compound extends BindingType {
super.dartDoc,
List? members,
super.isInternal,
+ this.objCBuiltInFunctions,
}) : members = members ?? [];
factory Compound.fromType({
@@ -55,6 +58,7 @@ abstract class Compound extends BindingType {
int? pack,
String? dartDoc,
List? members,
+ required ObjCBuiltInFunctions objCBuiltInFunctions,
}) {
switch (type) {
case CompoundType.struct:
@@ -66,6 +70,7 @@ abstract class Compound extends BindingType {
pack: pack,
dartDoc: dartDoc,
members: members,
+ objCBuiltInFunctions: objCBuiltInFunctions,
);
case CompoundType.union:
return Union(
@@ -76,6 +81,7 @@ abstract class Compound extends BindingType {
pack: pack,
dartDoc: dartDoc,
members: members,
+ objCBuiltInFunctions: objCBuiltInFunctions,
);
}
}
@@ -88,8 +94,17 @@ abstract class Compound extends BindingType {
return type.getCType(w);
}
+ bool get _isBuiltIn =>
+ objCBuiltInFunctions?.isBuiltInInterface(originalName) ?? false;
+
@override
BindingString toBindingString(Writer w) {
+ final bindingType =
+ isStruct ? BindingStringType.struct : BindingStringType.union;
+ if (_isBuiltIn) {
+ return BindingString(type: bindingType, string: '');
+ }
+
final s = StringBuffer();
final enclosingClassName = name;
if (dartDoc != null) {
@@ -135,14 +150,12 @@ abstract class Compound extends BindingType {
}
s.write('}\n\n');
- return BindingString(
- type: isStruct ? BindingStringType.struct : BindingStringType.union,
- string: s.toString());
+ return BindingString(type: bindingType, string: s.toString());
}
@override
void addDependencies(Set dependencies) {
- if (dependencies.contains(this)) return;
+ if (dependencies.contains(this) || _isBuiltIn) return;
dependencies.add(this);
for (final m in members) {
@@ -154,7 +167,7 @@ abstract class Compound extends BindingType {
bool get isIncompleteCompound => isIncomplete;
@override
- String getCType(Writer w) => name;
+ String getCType(Writer w) => _isBuiltIn ? '${w.objcPkgPrefix}.$name' : name;
@override
String getNativeType({String varName = ''}) => '$originalName $varName';
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_block.dart b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
index 42651b5db4..3c28f04429 100644
--- a/pkgs/ffigen/lib/src/code_generator/objc_block.dart
+++ b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
@@ -4,6 +4,7 @@
import 'package:ffigen/src/code_generator.dart';
import 'package:ffigen/src/config_provider/config_types.dart';
+import 'package:ffigen/src/header_parser/data.dart' show bindingsIndex;
import 'binding_string.dart';
import 'writer.dart';
@@ -11,19 +12,29 @@ import 'writer.dart';
class ObjCBlock extends BindingType {
final Type returnType;
final List argTypes;
-
Func? _wrapListenerBlock;
- ObjCBlock({
- required String usr,
+ factory ObjCBlock({
required Type returnType,
required List argTypes,
- }) : this._(
- usr: usr,
- name: _getBlockName(returnType, argTypes),
- returnType: returnType,
- argTypes: argTypes,
- );
+ }) {
+ final usr = _getBlockUsr(returnType, argTypes);
+
+ final oldBlock = bindingsIndex.getSeenObjCBlock(usr);
+ if (oldBlock != null) {
+ return oldBlock;
+ }
+
+ final block = ObjCBlock._(
+ usr: usr,
+ name: _getBlockName(returnType, argTypes),
+ returnType: returnType,
+ argTypes: argTypes,
+ );
+ bindingsIndex.addObjCBlockToSeen(usr, block);
+
+ return block;
+ }
ObjCBlock._({
required String super.usr,
@@ -42,6 +53,17 @@ class ObjCBlock extends BindingType {
type.toString().replaceAll(_illegalNameChar, '');
static final _illegalNameChar = RegExp(r'[^0-9a-zA-Z]');
+ static String _getBlockUsr(Type returnType, List argTypes) {
+ // Create a fake USR code for the block. This code is used to dedupe blocks
+ // with the same signature.
+ final usr = StringBuffer();
+ usr.write('objcBlock: ${returnType.cacheKey()}');
+ for (final type in argTypes) {
+ usr.write(' ${type.cacheKey()}');
+ }
+ return usr.toString();
+ }
+
bool get hasListener => returnType == voidType;
@override
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 b0876797de..f312609abe 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
@@ -22,8 +22,16 @@ class ObjCBuiltInFunctions {
static const newPointerBlock = ObjCImport('newPointerBlock');
static const newClosureBlock = ObjCImport('newClosureBlock');
static const getBlockClosure = ObjCImport('getBlockClosure');
+ static const getProtocolMethodSignature =
+ ObjCImport('getProtocolMethodSignature');
+ static const getProtocol = ObjCImport('getProtocol');
static const objectBase = ObjCImport('ObjCObjectBase');
static const blockBase = ObjCImport('ObjCBlockBase');
+ static const protocolMethod = ObjCImport('ObjCProtocolMethod');
+ static const protocolListenableMethod =
+ ObjCImport('ObjCProtocolListenableMethod');
+ static const protocolBuilder = ObjCImport('ObjCProtocolBuilder');
+ static const dartProxy = ObjCImport('DartProxy');
// Keep in sync with pkgs/objective_c/ffigen_objc.yaml.
static const builtInInterfaces = {
@@ -45,12 +53,12 @@ class ObjCBuiltInFunctions {
'NSMutableArray',
'NSMutableData',
'NSMutableDictionary',
+ 'NSMutableIndexSet',
'NSMutableSet',
'NSMutableString',
'NSNotification',
'NSNumber',
'NSObject',
- 'NSProgress',
'NSProxy',
'NSSet',
'NSString',
@@ -59,9 +67,18 @@ class ObjCBuiltInFunctions {
'NSValue',
'Protocol',
};
+ static const builtInCompounds = {
+ 'NSFastEnumerationState',
+ 'NSRange',
+ };
+ // TODO(https://github.com/dart-lang/native/issues/1173): Ideally this check
+ // would be based on more than just the name.
bool isBuiltInInterface(String name) =>
!generateForPackageObjectiveC && builtInInterfaces.contains(name);
+ bool isBuiltInCompound(String name) =>
+ !generateForPackageObjectiveC && builtInCompounds.contains(name);
+ bool isNSObject(String name) => name == 'NSObject';
// We need to load a separate instance of objc_msgSend for each signature. If
// the return type is a struct, we need to use objc_msgSend_stret instead, and
@@ -96,6 +113,12 @@ class ObjCBuiltInFunctions {
sel.addDependencies(dependencies);
}
}
+
+ static bool isInstanceType(Type type) {
+ if (type is ObjCInstanceType) return true;
+ final baseType = type.typealiasType;
+ return baseType is ObjCNullable && baseType.child is ObjCInstanceType;
+ }
}
/// A function, global variable, or helper type defined in package:objective_c.
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
index 39ac429bef..3344a110ee 100644
--- a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
+++ b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:ffigen/src/code_generator.dart';
-import 'package:logging/logging.dart';
import 'binding_string.dart';
import 'utils.dart';
@@ -34,19 +33,18 @@ const _excludedNSObjectClassMethods = {
'version',
};
-final _logger = Logger('ffigen.code_generator.objc_interface');
-
-class ObjCInterface extends BindingType {
+class ObjCInterface extends BindingType with ObjCMethods {
ObjCInterface? superType;
- final methods = {};
bool filled = false;
final String lookupName;
- final ObjCBuiltInFunctions builtInFunctions;
late final ObjCInternalGlobal _classObject;
late final ObjCInternalGlobal _isKindOfClass;
late final ObjCMsgSendFunc _isKindOfClassMsgSend;
+ @override
+ final ObjCBuiltInFunctions builtInFunctions;
+
ObjCInterface({
super.usr,
required String super.originalName,
@@ -57,7 +55,7 @@ class ObjCInterface extends BindingType {
}) : lookupName = lookupName ?? originalName,
super(name: name ?? originalName);
- bool get _isBuiltIn => builtInFunctions.isBuiltInInterface(name);
+ bool get _isBuiltIn => builtInFunctions.isBuiltInInterface(originalName);
@override
BindingString toBindingString(Writer w) {
@@ -75,9 +73,7 @@ class ObjCInterface extends BindingType {
}
final s = StringBuffer();
- if (dartDoc != null) {
- s.write(makeDartDoc(dartDoc!));
- }
+ s.write(makeDartDoc(dartDoc ?? originalName));
final uniqueNamer =
UniqueNamer({name, 'pointer'}, parent: w.topLevelUniqueNamer);
@@ -88,8 +84,7 @@ class ObjCInterface extends BindingType {
final superTypeIsInPkgObjc = superType == null;
// Class declaration.
- s.write('''
-class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
+ s.write('''class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
$name._($rawObjType pointer,
{bool retain = false, bool release = false}) :
${superTypeIsInPkgObjc ? 'super' : 'super.castFromPointer'}
@@ -117,9 +112,9 @@ class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
''');
// Methods.
- for (final m in methods.values) {
- final methodName = m._getDartMethodName(uniqueNamer);
- final isStatic = m.isClass;
+ for (final m in methods) {
+ final methodName = m.getDartMethodName(uniqueNamer);
+ final isStatic = m.isClassMethod;
final isStret = m.msgSend!.isStret;
var returnType = m.returnType;
@@ -130,10 +125,7 @@ class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
}
// The method declaration.
- if (m.dartDoc != null) {
- s.write(makeDartDoc(m.dartDoc!));
- }
-
+ s.write(makeDartDoc(m.dartDoc ?? m.originalName));
s.write(' ');
if (isStatic) {
s.write('static ');
@@ -157,9 +149,6 @@ class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
}
s.write(paramsToString(params, isStatic: true));
} else {
- if (superType?.methods[m.originalName]?.sameAs(m) ?? false) {
- s.write('@override\n ');
- }
switch (m.kind) {
case ObjCMethodKind.method:
// returnType methodName(...)
@@ -235,18 +224,15 @@ class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
_isKindOfClassMsgSend = builtInFunctions.getMsgSendFunc(
BooleanType(), [ObjCMethodParam(PointerType(objCObjectType), 'clazz')]);
- for (final m in methods.values) {
- m.addDependencies(dependencies, builtInFunctions);
- }
+ addMethodDependencies(dependencies, needMsgSend: true);
if (superType != null) {
superType!.addDependencies(dependencies);
_copyMethodsFromSuperType();
_fixNullabilityOfOverriddenMethods();
- }
- for (final m in methods.values) {
- m.addDependencies(dependencies, builtInFunctions);
+ // Add dependencies for any methods that were added.
+ addMethodDependencies(dependencies, needMsgSend: true);
}
builtInFunctions.addDependencies(dependencies);
@@ -258,11 +244,11 @@ class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
// - Methods that return instancetype, because the subclass's copy of the
// method needs to return the subclass, not the super class.
// Note: instancetype is only allowed as a return type, not an arg type.
- for (final m in superType!.methods.values) {
- if (m.isClass &&
+ for (final m in superType!.methods) {
+ if (m.isClassMethod &&
!_excludedNSObjectClassMethods.contains(m.originalName)) {
addMethod(m);
- } else if (_isInstanceType(m.returnType)) {
+ } else if (ObjCBuiltInFunctions.isInstanceType(m.returnType)) {
addMethod(m);
}
}
@@ -276,9 +262,11 @@ class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
// nullable, to avoid Dart compile errors.
var superType_ = superType;
while (superType_ != null) {
- for (final method in methods.values) {
- final superMethod = superType_.methods[method.originalName];
- if (superMethod != null && !superMethod.isClass && !method.isClass) {
+ for (final method in methods) {
+ final superMethod = superType_.getMethod(method.originalName);
+ if (superMethod != null &&
+ !superMethod.isClassMethod &&
+ !method.isClassMethod) {
if (superMethod.returnType.typealiasType is! ObjCNullable &&
method.returnType.typealiasType is ObjCNullable) {
superMethod.returnType = ObjCNullable(superMethod.returnType);
@@ -300,55 +288,6 @@ class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
}
}
- static bool _isInstanceType(Type type) {
- if (type is ObjCInstanceType) return true;
- final baseType = type.typealiasType;
- return baseType is ObjCNullable && baseType.child is ObjCInstanceType;
- }
-
- ObjCMethod _maybeReplaceMethod(ObjCMethod? oldMethod, ObjCMethod newMethod) {
- if (oldMethod == null) return newMethod;
-
- // Typically we ignore duplicate methods. However, property setters and
- // getters are duplicated in the AST. One copy is marked with
- // ObjCMethodKind.propertyGetter/Setter. The other copy is missing
- // important information, and is a plain old instanceMethod. So if the
- // existing method is an instanceMethod, and the new one is a property,
- // override it.
- if (newMethod.isProperty && !oldMethod.isProperty) {
- return newMethod;
- } else if (!newMethod.isProperty && oldMethod.isProperty) {
- // Don't override, but also skip the same method check below.
- return oldMethod;
- }
-
- // Check the duplicate is the same method.
- if (!newMethod.sameAs(oldMethod)) {
- _logger.severe('Duplicate methods with different signatures: '
- '$originalName.${newMethod.originalName}');
- return newMethod;
- }
-
- // There's a bug in some Apple APIs where an init method that should return
- // instancetype has a duplicate definition that instead returns id. In that
- // case, use the one that returns instancetype. Note that since instancetype
- // is an alias of id, the sameAs check above passes.
- if (_isInstanceType(newMethod.returnType) &&
- !_isInstanceType(oldMethod.returnType)) {
- return newMethod;
- } else if (!_isInstanceType(newMethod.returnType) &&
- _isInstanceType(oldMethod.returnType)) {
- return oldMethod;
- }
-
- return newMethod;
- }
-
- void addMethod(ObjCMethod method) {
- methods[method.originalName] =
- _maybeReplaceMethod(methods[method.originalName], method);
- }
-
@override
String getCType(Writer w) => PointerType(objCObjectType).getCType(w);
@@ -409,100 +348,3 @@ class $name extends ${superType?.getDartType(w) ?? wrapObjType} {
return type.getDartType(w);
}
}
-
-enum ObjCMethodKind {
- method,
- propertyGetter,
- propertySetter,
-}
-
-class ObjCProperty {
- final String originalName;
- String? dartName;
-
- ObjCProperty(this.originalName);
-}
-
-class ObjCMethod {
- final String? dartDoc;
- final String originalName;
- final ObjCProperty? property;
- Type returnType;
- final List params;
- final ObjCMethodKind kind;
- final bool isClass;
- bool returnsRetained = false;
- ObjCInternalGlobal? selObject;
- ObjCMsgSendFunc? msgSend;
-
- ObjCMethod({
- required this.originalName,
- this.property,
- this.dartDoc,
- required this.kind,
- required this.isClass,
- required this.returnType,
- List? params_,
- }) : params = params_ ?? [];
-
- bool get isProperty =>
- kind == ObjCMethodKind.propertyGetter ||
- kind == ObjCMethodKind.propertySetter;
-
- void addDependencies(
- Set dependencies, ObjCBuiltInFunctions builtInFunctions) {
- returnType.addDependencies(dependencies);
- for (final p in params) {
- p.type.addDependencies(dependencies);
- }
- selObject ??= builtInFunctions.getSelObject(originalName)
- ..addDependencies(dependencies);
- msgSend ??= builtInFunctions.getMsgSendFunc(returnType, params)
- ..addDependencies(dependencies);
- }
-
- String _getDartMethodName(UniqueNamer uniqueNamer) {
- if (property != null) {
- // A getter and a setter are allowed to have the same name, so we can't
- // just run the name through uniqueNamer. Instead they need to share
- // the dartName, which is run through uniqueNamer.
- if (property!.dartName == null) {
- property!.dartName = uniqueNamer.makeUnique(property!.originalName);
- }
- return property!.dartName!;
- }
- // Objective C methods can look like:
- // foo
- // foo:
- // foo:someArgName:
- // So replace all ':' with '_'.
- return uniqueNamer.makeUnique(originalName.replaceAll(":", "_"));
- }
-
- bool sameAs(ObjCMethod other) {
- if (originalName != other.originalName) return false;
- if (kind != other.kind) return false;
- if (isClass != other.isClass) return false;
- // msgSend is deduped by signature, so this check covers the signature.
- return msgSend == other.msgSend;
- }
-
- static final _copyRegExp = RegExp('[cC]opy');
- bool get isOwnedReturn =>
- returnsRetained ||
- originalName.startsWith('new') ||
- originalName.startsWith('alloc') ||
- originalName.contains(_copyRegExp);
-
- @override
- String toString() => '$returnType $originalName(${params.join(', ')})';
-}
-
-class ObjCMethodParam {
- Type type;
- final String name;
- ObjCMethodParam(this.type, this.name);
-
- @override
- String toString() => '$type $name';
-}
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_methods.dart b/pkgs/ffigen/lib/src/code_generator/objc_methods.dart
new file mode 100644
index 0000000000..1876e4bb6c
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/objc_methods.dart
@@ -0,0 +1,224 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:logging/logging.dart';
+
+import 'utils.dart';
+
+final _logger = Logger('ffigen.code_generator.objc_methods');
+
+mixin ObjCMethods {
+ final _methods = {};
+
+ Iterable get methods => _methods.values;
+ ObjCMethod? getMethod(String name) => _methods[name];
+
+ String get originalName;
+ ObjCBuiltInFunctions get builtInFunctions;
+
+ void addMethod(ObjCMethod method) {
+ if (_shouldIncludeMethod(method)) {
+ _methods[method.originalName] =
+ _maybeReplaceMethod(getMethod(method.originalName), method);
+ }
+ }
+
+ void addMethodDependencies(
+ Set dependencies, {
+ bool needMsgSend = false,
+ bool needProtocolBlock = false,
+ }) {
+ for (final m in methods) {
+ m.addDependencies(dependencies, builtInFunctions,
+ needMsgSend: needMsgSend, needProtocolBlock: needProtocolBlock);
+ }
+ }
+
+ ObjCMethod _maybeReplaceMethod(ObjCMethod? oldMethod, ObjCMethod newMethod) {
+ if (oldMethod == null) return newMethod;
+
+ // Typically we ignore duplicate methods. However, property setters and
+ // getters are duplicated in the AST. One copy is marked with
+ // ObjCMethodKind.propertyGetter/Setter. The other copy is missing
+ // important information, and is a plain old instanceMethod. So if the
+ // existing method is an instanceMethod, and the new one is a property,
+ // override it.
+ if (newMethod.isProperty && !oldMethod.isProperty) {
+ return newMethod;
+ } else if (!newMethod.isProperty && oldMethod.isProperty) {
+ // Don't override, but also skip the same method check below.
+ return oldMethod;
+ }
+
+ // Check the duplicate is the same method.
+ if (!newMethod.sameAs(oldMethod)) {
+ _logger.severe('Duplicate methods with different signatures: '
+ '$originalName.${newMethod.originalName}');
+ return newMethod;
+ }
+
+ // There's a bug in some Apple APIs where an init method that should return
+ // instancetype has a duplicate definition that instead returns id. In that
+ // case, use the one that returns instancetype. Note that since instancetype
+ // is an alias of id, the sameAs check above passes.
+ if (ObjCBuiltInFunctions.isInstanceType(newMethod.returnType) &&
+ !ObjCBuiltInFunctions.isInstanceType(oldMethod.returnType)) {
+ return newMethod;
+ } else if (!ObjCBuiltInFunctions.isInstanceType(newMethod.returnType) &&
+ ObjCBuiltInFunctions.isInstanceType(oldMethod.returnType)) {
+ return oldMethod;
+ }
+
+ return newMethod;
+ }
+
+ bool _shouldIncludeMethod(ObjCMethod method) =>
+ method.childTypes.every((Type t) {
+ t = t.typealiasType.baseType;
+
+ // Ignore methods with variadic args.
+ // TODO(https://github.com/dart-lang/native/issues/1192): Remove this.
+ if (t is Struct && t.originalName == '__va_list_tag') {
+ return false;
+ }
+
+ // Ignore methods with block args or rets when we're generating in
+ // package:objective_c.
+ // TODO(https://github.com/dart-lang/native/issues/1180): Remove this.
+ if (builtInFunctions.generateForPackageObjectiveC && t is ObjCBlock) {
+ return false;
+ }
+
+ return true;
+ });
+}
+
+enum ObjCMethodKind {
+ method,
+ propertyGetter,
+ propertySetter,
+}
+
+class ObjCProperty {
+ final String originalName;
+ String? dartName;
+
+ ObjCProperty(this.originalName);
+}
+
+class ObjCMethod {
+ final String? dartDoc;
+ final String originalName;
+ final ObjCProperty? property;
+ Type returnType;
+ final List params;
+ final ObjCMethodKind kind;
+ final bool isClassMethod;
+ final bool isOptional;
+ bool returnsRetained = false;
+ ObjCInternalGlobal? selObject;
+ ObjCMsgSendFunc? msgSend;
+ late ObjCBlock protocolBlock;
+
+ ObjCMethod({
+ required this.originalName,
+ this.property,
+ this.dartDoc,
+ required this.kind,
+ required this.isClassMethod,
+ required this.isOptional,
+ required this.returnType,
+ List? params_,
+ }) : params = params_ ?? [];
+
+ bool get isProperty =>
+ kind == ObjCMethodKind.propertyGetter ||
+ kind == ObjCMethodKind.propertySetter;
+ bool get isRequired => !isOptional;
+ bool get isInstanceMethod => !isClassMethod;
+
+ void addDependencies(
+ Set dependencies,
+ ObjCBuiltInFunctions builtInFunctions, {
+ bool needMsgSend = false,
+ bool needProtocolBlock = false,
+ }) {
+ returnType.addDependencies(dependencies);
+ for (final p in params) {
+ p.type.addDependencies(dependencies);
+ }
+ selObject ??= builtInFunctions.getSelObject(originalName)
+ ..addDependencies(dependencies);
+ if (needMsgSend) {
+ msgSend ??= builtInFunctions.getMsgSendFunc(returnType, params)
+ ..addDependencies(dependencies);
+ }
+ if (needProtocolBlock) {
+ final argTypes = [
+ // First arg of the protocol block is a void pointer that we ignore.
+ PointerType(voidType),
+ ...params.map((p) => p.type),
+ ];
+ protocolBlock = ObjCBlock(
+ returnType: returnType,
+ argTypes: argTypes,
+ )..addDependencies(dependencies);
+ }
+ }
+
+ String getDartMethodName(UniqueNamer uniqueNamer) {
+ if (property != null) {
+ // A getter and a setter are allowed to have the same name, so we can't
+ // just run the name through uniqueNamer. Instead they need to share
+ // the dartName, which is run through uniqueNamer.
+ if (property!.dartName == null) {
+ property!.dartName = uniqueNamer.makeUnique(property!.originalName);
+ }
+ return property!.dartName!;
+ }
+ // Objective C methods can look like:
+ // foo
+ // foo:
+ // foo:someArgName:
+ // So replace all ':' with '_'.
+ return uniqueNamer.makeUnique(originalName.replaceAll(":", "_"));
+ }
+
+ bool sameAs(ObjCMethod other) {
+ if (originalName != other.originalName) return false;
+ if (kind != other.kind) return false;
+ if (isClassMethod != other.isClassMethod) return false;
+ if (isOptional != other.isOptional) return false;
+ // msgSend is deduped by signature, so this check covers the signature.
+ return msgSend == other.msgSend;
+ }
+
+ static final _copyRegExp = RegExp('[cC]opy');
+ bool get isOwnedReturn =>
+ returnsRetained ||
+ originalName.startsWith('new') ||
+ originalName.startsWith('alloc') ||
+ originalName.contains(_copyRegExp);
+
+ Iterable get childTypes sync* {
+ yield returnType;
+ for (final p in params) {
+ yield p.type;
+ }
+ }
+
+ @override
+ String toString() =>
+ '${isOptional ? "@optional " : ""}$returnType $originalName(${params.join(', ')})';
+}
+
+class ObjCMethodParam {
+ Type type;
+ final String name;
+ ObjCMethodParam(this.type, this.name);
+
+ @override
+ String toString() => '$type $name';
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_protocol.dart b/pkgs/ffigen/lib/src/code_generator/objc_protocol.dart
new file mode 100644
index 0000000000..eec3b90482
--- /dev/null
+++ b/pkgs/ffigen/lib/src/code_generator/objc_protocol.dart
@@ -0,0 +1,167 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+
+import 'binding_string.dart';
+import 'utils.dart';
+import 'writer.dart';
+
+class ObjCProtocol extends NoLookUpBinding with ObjCMethods {
+ final superProtocols = [];
+ final String lookupName;
+ late final ObjCInternalGlobal _protocolPointer;
+
+ @override
+ final ObjCBuiltInFunctions builtInFunctions;
+
+ ObjCProtocol({
+ super.usr,
+ required String super.originalName,
+ String? name,
+ String? lookupName,
+ super.dartDoc,
+ required this.builtInFunctions,
+ }) : lookupName = lookupName ?? originalName,
+ super(name: name ?? originalName);
+
+ @override
+ BindingString toBindingString(Writer w) {
+ final protocolMethod = ObjCBuiltInFunctions.protocolMethod.gen(w);
+ final protocolListenableMethod =
+ ObjCBuiltInFunctions.protocolListenableMethod.gen(w);
+ final protocolBuilder = ObjCBuiltInFunctions.protocolBuilder.gen(w);
+ final objectBase = ObjCBuiltInFunctions.objectBase.gen(w);
+ final getSignature = ObjCBuiltInFunctions.getProtocolMethodSignature.gen(w);
+
+ final buildArgs = [];
+ final buildImplementations = StringBuffer();
+ final methodFields = StringBuffer();
+
+ final uniqueNamer = UniqueNamer({name, 'pointer'});
+
+ for (final method in methods) {
+ final methodName = method.getDartMethodName(uniqueNamer);
+ final fieldName = methodName;
+ final argName = methodName;
+ final block = method.protocolBlock;
+ final blockType = block.getDartType(w);
+ final methodCtor =
+ block.hasListener ? protocolListenableMethod : protocolMethod;
+
+ // The function type omits the first arg of the block, which is unused.
+ final func = FunctionType(returnType: block.returnType, parameters: [
+ for (int i = 1; i < block.argTypes.length; ++i)
+ Parameter(name: 'arg$i', type: block.argTypes[i]),
+ ]);
+ final funcType = func.getDartType(w, writeArgumentNames: false);
+
+ if (method.isOptional) {
+ buildArgs.add('$funcType? $argName');
+ } else {
+ buildArgs.add('required $funcType $argName');
+ }
+
+ final blockFirstArg = block.argTypes[0].getDartType(w);
+ final argsReceived = func.parameters
+ .map((p) => '${p.type.getDartType(w)} ${p.name}')
+ .join(', ');
+ final argsPassed = func.parameters.map((p) => p.name).join(', ');
+ final wrapper = '($blockFirstArg _, $argsReceived) => func($argsPassed)';
+
+ String listenerBuilder = '';
+ if (block.hasListener) {
+ listenerBuilder = '(Function func) => $blockType.listener($wrapper),';
+ }
+
+ buildImplementations.write('''
+ builder.implementMethod($name.$fieldName, $argName);''');
+
+ methodFields.write(makeDartDoc(method.dartDoc ?? method.originalName));
+ methodFields.write('''static final $fieldName = $methodCtor(
+ ${method.selObject!.name},
+ $getSignature(
+ ${_protocolPointer.name},
+ ${method.selObject!.name},
+ isRequired: ${method.isRequired},
+ isInstanceMethod: ${method.isInstanceMethod},
+ ),
+ (Function func) => func is $funcType,
+ (Function func) => $blockType.fromFunction($wrapper),
+ $listenerBuilder
+ );
+''');
+ }
+
+ final args = buildArgs.isEmpty ? '' : '{${buildArgs.join(', ')}}';
+ final mainString = '''
+${makeDartDoc(dartDoc ?? originalName)}abstract final class $name {
+ /// Builds an object that implements the $originalName protocol. To implement
+ /// multiple protocols, use [addToBuilder] or [$protocolBuilder] directly.
+ static $objectBase implement($args) {
+ final builder = $protocolBuilder();
+ $buildImplementations
+ return builder.build();
+ }
+
+ /// Adds the implementation of the $originalName protocol to an existing
+ /// [$protocolBuilder].
+ static void addToBuilder($protocolBuilder builder, $args) {
+ $buildImplementations
+ }
+
+ $methodFields
+}
+''';
+
+ return BindingString(
+ type: BindingStringType.objcProtocol, string: mainString);
+ }
+
+ @override
+ void addDependencies(Set dependencies) {
+ if (dependencies.contains(this)) return;
+ dependencies.add(this);
+
+ _protocolPointer = ObjCInternalGlobal(
+ '_protocol_$originalName',
+ (Writer w) =>
+ '${ObjCBuiltInFunctions.getProtocol.gen(w)}("$lookupName")')
+ ..addDependencies(dependencies);
+
+ for (final superProtocol in superProtocols) {
+ superProtocol.addDependencies(dependencies);
+ }
+
+ addMethodDependencies(dependencies, needProtocolBlock: true);
+
+ for (final superProtocol in superProtocols) {
+ _copyMethodsFromSuperType(superProtocol);
+ }
+
+ // Add dependencies for any methods that were added.
+ addMethodDependencies(dependencies, needProtocolBlock: true);
+ }
+
+ void _copyMethodsFromSuperType(ObjCProtocol superProtocol) {
+ if (builtInFunctions.isNSObject(superProtocol.originalName)) {
+ // When writing a protocol that doesn't inherit from any other protocols,
+ // it's typical to have it inherit from NSObject instead. But NSObject has
+ // heaps of methods that users are very unlikely to want to implement, so
+ // ignore it. If the user really wants to implement them they can use the
+ // ObjCProtocolBuilder.
+ return;
+ }
+
+ // Protocols have very different inheritance semantics than Dart classes.
+ // So copy across all the methods explicitly, rather than trying to use Dart
+ // inheritance to get them implicitly.
+ for (final method in superProtocol.methods) {
+ addMethod(method);
+ }
+ }
+
+ @override
+ String toString() => originalName;
+}
diff --git a/pkgs/ffigen/lib/src/code_generator/struct.dart b/pkgs/ffigen/lib/src/code_generator/struct.dart
index 7a95d67766..e5e61e8955 100644
--- a/pkgs/ffigen/lib/src/code_generator/struct.dart
+++ b/pkgs/ffigen/lib/src/code_generator/struct.dart
@@ -38,5 +38,6 @@ class Struct extends Compound {
super.dartDoc,
super.members,
super.isInternal,
+ super.objCBuiltInFunctions,
}) : super(compoundType: CompoundType.struct);
}
diff --git a/pkgs/ffigen/lib/src/code_generator/typealias.dart b/pkgs/ffigen/lib/src/code_generator/typealias.dart
index 6adf5c42d9..dbb09d728c 100644
--- a/pkgs/ffigen/lib/src/code_generator/typealias.dart
+++ b/pkgs/ffigen/lib/src/code_generator/typealias.dart
@@ -228,9 +228,15 @@ class ObjCInstanceType extends Typealias {
required bool objCRetain,
String? objCEnclosingClass,
}) =>
- // objCEnclosingClass must be present, because instancetype can only
- // occur inside a class.
- ObjCInterface.generateConstructor(objCEnclosingClass!, value, objCRetain);
+ objCEnclosingClass == null
+ ? super.convertFfiDartTypeToDartType(
+ w,
+ value,
+ objCRetain: objCRetain,
+ objCEnclosingClass: objCEnclosingClass,
+ )
+ : ObjCInterface.generateConstructor(
+ objCEnclosingClass, value, objCRetain);
@override
String getNativeType({String varName = ''}) => 'id $varName';
diff --git a/pkgs/ffigen/lib/src/code_generator/union.dart b/pkgs/ffigen/lib/src/code_generator/union.dart
index 65d9afbfe8..b627e4053c 100644
--- a/pkgs/ffigen/lib/src/code_generator/union.dart
+++ b/pkgs/ffigen/lib/src/code_generator/union.dart
@@ -36,5 +36,6 @@ class Union extends Compound {
super.pack,
super.dartDoc,
super.members,
+ super.objCBuiltInFunctions,
}) : super(compoundType: CompoundType.union);
}
diff --git a/pkgs/ffigen/lib/src/code_generator/utils.dart b/pkgs/ffigen/lib/src/code_generator/utils.dart
index 444782ba7a..ca58c5fba8 100644
--- a/pkgs/ffigen/lib/src/code_generator/utils.dart
+++ b/pkgs/ffigen/lib/src/code_generator/utils.dart
@@ -71,7 +71,8 @@ class UniqueNamer {
/// Converts [text] to a dart doc comment(`///`).
///
/// Comment is split on new lines only.
-String makeDartDoc(String text) {
+String makeDartDoc(String? text) {
+ if (text == null) return '';
final s = StringBuffer();
s.write('/// ');
s.writeAll(text.split('\n'), '\n/// ');
diff --git a/pkgs/ffigen/lib/src/config_provider/config.dart b/pkgs/ffigen/lib/src/config_provider/config.dart
index 26ec5587d8..9717c2e74c 100644
--- a/pkgs/ffigen/lib/src/config_provider/config.dart
+++ b/pkgs/ffigen/lib/src/config_provider/config.dart
@@ -97,6 +97,10 @@ class Config {
Declaration get objcInterfaces => _objcInterfaces;
late Declaration _objcInterfaces;
+ /// Declaration config for Objective C protocols.
+ Declaration get objcProtocols => _objcProtocols;
+ late Declaration _objcProtocols;
+
/// If enabled, the default behavior of all declaration filters is to exclude
/// everything, rather than include everything.
bool get excludeAllByDefault => _excludeAllByDefault;
@@ -160,8 +164,14 @@ class Config {
late StructPackingOverride _structPackingOverride;
/// Module prefixes for ObjC interfaces.
- ObjCModulePrefixer get objcModulePrefixer => _objcModulePrefixer;
- late ObjCModulePrefixer _objcModulePrefixer;
+ ObjCModulePrefixer get objcInterfaceModulePrefixer =>
+ _objcInterfaceModulePrefixer;
+ late ObjCModulePrefixer _objcInterfaceModulePrefixer;
+
+ /// Module prefixes for ObjC protocols.
+ ObjCModulePrefixer get objcProtocolModulePrefixer =>
+ _objcProtocolModulePrefixer;
+ late ObjCModulePrefixer _objcProtocolModulePrefixer;
/// Name of the wrapper class.
String get wrapperName => _wrapperName;
@@ -535,15 +545,35 @@ class Config {
..._memberRenameProperties(),
HeterogeneousMapEntry(
key: strings.objcModule,
- valueConfigSpec: _objcInterfaceModuleObject(),
+ valueConfigSpec: _objcModuleObject(),
defaultValue: (node) => ObjCModulePrefixer({}),
)
],
result: (node) {
_objcInterfaces = declarationConfigExtractor(
node.value as Map);
- _objcModulePrefixer = (node.value as Map)[strings.objcModule]
- as ObjCModulePrefixer;
+ _objcInterfaceModulePrefixer = (node.value
+ as Map)[strings.objcModule] as ObjCModulePrefixer;
+ },
+ )),
+ HeterogeneousMapEntry(
+ key: strings.objcProtocols,
+ valueConfigSpec: HeterogeneousMapConfigSpec(
+ entries: [
+ ..._includeExcludeProperties(),
+ ..._renameProperties(),
+ ..._memberRenameProperties(),
+ HeterogeneousMapEntry(
+ key: strings.objcModule,
+ valueConfigSpec: _objcModuleObject(),
+ defaultValue: (node) => ObjCModulePrefixer({}),
+ )
+ ],
+ result: (node) {
+ _objcProtocols = declarationConfigExtractor(
+ node.value as Map);
+ _objcProtocolModulePrefixer = (node.value
+ as Map)[strings.objcModule] as ObjCModulePrefixer;
},
)),
HeterogeneousMapEntry(
@@ -950,9 +980,9 @@ class Config {
);
}
- MapConfigSpec _objcInterfaceModuleObject() {
+ MapConfigSpec _objcModuleObject() {
return MapConfigSpec(
- schemaDefName: "objcInterfaceModule",
+ schemaDefName: "objcModule",
keyValueConfigSpecs: [
(keyRegexp: ".*", valueConfigSpec: StringConfigSpec()),
],
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 a25768939e..331b0c6d1b 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
@@ -1205,6 +1205,23 @@ class Clang {
_clang_Cursor_getObjCPropertySetterNamePtr
.asFunction();
+ /// Given a cursor that represents an Objective-C method or property
+ /// declaration, return non-zero if the declaration was affected by "\@optional".
+ /// Returns zero if the cursor is not such a declaration or it is "\@required".
+ int clang_Cursor_isObjCOptional(
+ CXCursor C,
+ ) {
+ return _clang_Cursor_isObjCOptional(
+ C,
+ );
+ }
+
+ late final _clang_Cursor_isObjCOptionalPtr =
+ _lookup>(
+ 'clang_Cursor_isObjCOptional');
+ late final _clang_Cursor_isObjCOptional =
+ _clang_Cursor_isObjCOptionalPtr.asFunction();
+
/// Given a cursor that represents a declaration, return the associated
/// comment's source range. The range may include multiple consecutive comments
/// with whitespace in between.
diff --git a/pkgs/ffigen/lib/src/header_parser/includer.dart b/pkgs/ffigen/lib/src/header_parser/includer.dart
index ebb7d3d598..e988fc65ef 100644
--- a/pkgs/ffigen/lib/src/header_parser/includer.dart
+++ b/pkgs/ffigen/lib/src/header_parser/includer.dart
@@ -75,6 +75,11 @@ bool shouldIncludeObjCInterface(String usr, String name) {
usr, name, bindingsIndex.isSeenType, config.objcInterfaces.shouldInclude);
}
+bool shouldIncludeObjCProtocol(String usr, String name) {
+ return _shouldIncludeDecl(usr, name, bindingsIndex.isSeenObjCProtocol,
+ config.objcProtocols.shouldInclude);
+}
+
/// True if a cursor should be included based on headers config, used on root
/// declarations.
bool shouldIncludeRootCursor(String sourceFile) {
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart
index 519d12c568..0ddc4daadd 100644
--- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/compounddecl_parser.dart
@@ -123,6 +123,7 @@ Compound? parseCompoundDeclaration(
name: incrementalNamer.name('Unnamed$className'),
usr: declUsr,
dartDoc: getCursorDocComment(cursor),
+ objCBuiltInFunctions: objCBuiltInFunctions,
);
} else {
_logger.finest('unnamed $className declaration');
@@ -137,6 +138,7 @@ Compound? parseCompoundDeclaration(
originalName: declName,
name: configDecl.renameUsingConfig(declName),
dartDoc: getCursorDocComment(cursor),
+ objCBuiltInFunctions: objCBuiltInFunctions,
);
}
return null;
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart
index 90ebb05c40..3eadcd254c 100644
--- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart
@@ -4,13 +4,10 @@
import 'package:ffigen/src/code_generator.dart';
import 'package:ffigen/src/header_parser/data.dart';
-import 'package:logging/logging.dart';
import '../clang_bindings/clang_bindings.dart' as clang_types;
import '../utils.dart';
-final _logger = Logger('ffigen.header_parser.objc_block_parser');
-
ObjCBlock parseObjCBlock(clang_types.CXType cxtype) {
final blk = clang.clang_getPointeeType(cxtype);
final returnType = clang.clang_getResultType(blk).toCodeGenType();
@@ -19,19 +16,7 @@ ObjCBlock parseObjCBlock(clang_types.CXType cxtype) {
for (int i = 0; i < numArgs; ++i) {
argTypes.add(clang.clang_getArgType(blk, i).toCodeGenType());
}
-
- // Create a fake USR code for the block. This code is used to dedupe blocks
- // with the same signature.
- var usr = 'objcBlock: ${returnType.cacheKey()}';
- for (final type in argTypes) {
- usr += ' ${type.cacheKey()}';
- }
-
- _logger.fine('++++ Adding ObjC block: '
- '${cxtype.completeStringRepr()}, syntheticUsr: $usr');
-
return ObjCBlock(
- usr: usr.toString(),
returnType: returnType,
argTypes: argTypes,
);
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
index 928cab1fbd..1d7fa1a84e 100644
--- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
@@ -34,7 +34,7 @@ Type? parseObjCInterfaceDeclaration(
usr: itfUsr,
originalName: name,
name: config.objcInterfaces.renameUsingConfig(name),
- lookupName: config.objcModulePrefixer.applyPrefix(name),
+ lookupName: config.objcInterfaceModulePrefixer.applyPrefix(name),
dartDoc: getCursorDocComment(cursor),
builtInFunctions: objCBuiltInFunctions,
);
@@ -116,12 +116,13 @@ void _parseProperty(clang_types.CXCursor cursor, ObjCInterface itf) {
final propertyAttributes =
clang.clang_Cursor_getObjCPropertyAttributes(cursor, 0);
- final isClass = propertyAttributes &
+ final isClassMethod = propertyAttributes &
clang_types.CXObjCPropertyAttrKind.CXObjCPropertyAttr_class >
0;
final isReadOnly = propertyAttributes &
clang_types.CXObjCPropertyAttrKind.CXObjCPropertyAttr_readonly >
0;
+ final isOptionalMethod = clang.clang_Cursor_isObjCOptional(cursor) != 0;
final property = ObjCProperty(fieldName);
@@ -135,7 +136,8 @@ void _parseProperty(clang_types.CXCursor cursor, ObjCInterface itf) {
property: property,
dartDoc: dartDoc,
kind: ObjCMethodKind.propertyGetter,
- isClass: isClass,
+ isClassMethod: isClassMethod,
+ isOptional: isOptionalMethod,
returnType: fieldType,
);
itf.addMethod(getter);
@@ -149,7 +151,8 @@ void _parseProperty(clang_types.CXCursor cursor, ObjCInterface itf) {
property: property,
dartDoc: dartDoc,
kind: ObjCMethodKind.propertySetter,
- isClass: isClass,
+ isClassMethod: isClassMethod,
+ isOptional: isOptionalMethod,
returnType: NativeType(SupportedNativeType.Void));
setter.params.add(ObjCMethodParam(fieldType, 'value'));
itf.addMethod(setter);
@@ -157,16 +160,17 @@ void _parseProperty(clang_types.CXCursor cursor, ObjCInterface itf) {
}
void _parseInterfaceMethod(clang_types.CXCursor cursor, ObjCInterface itf) {
- final method = _parseMethod(cursor, itf.originalName);
+ final method = parseObjCMethod(cursor, itf.originalName);
if (method != null) {
itf.addMethod(method);
}
}
-ObjCMethod? _parseMethod(clang_types.CXCursor cursor, String itfName) {
+ObjCMethod? parseObjCMethod(clang_types.CXCursor cursor, String itfName) {
final methodName = cursor.spelling();
final isClassMethod =
cursor.kind == clang_types.CXCursorKind.CXCursor_ObjCClassMethodDecl;
+ final isOptionalMethod = clang.clang_Cursor_isObjCOptional(cursor) != 0;
final returnType = clang.clang_getCursorResultType(cursor).toCodeGenType();
if (returnType.isIncompleteCompound) {
_logger.warning('Method "$methodName" in instance '
@@ -178,12 +182,12 @@ ObjCMethod? _parseMethod(clang_types.CXCursor cursor, String itfName) {
originalName: methodName,
dartDoc: getCursorDocComment(cursor),
kind: ObjCMethodKind.method,
- isClass: isClassMethod,
+ isClassMethod: isClassMethod,
+ isOptional: isOptionalMethod,
returnType: returnType,
);
_logger.fine(' > ${isClassMethod ? 'Class' : 'Instance'} method: '
'${method.originalName} ${cursor.completeStringRepr()}');
-
bool hasError = false;
cursor.visitChildren((child) {
switch (child.kind) {
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
new file mode 100644
index 0000000000..fa257ab2e1
--- /dev/null
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcprotocoldecl_parser.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:ffigen/src/code_generator.dart';
+import 'package:ffigen/src/header_parser/data.dart';
+import 'package:logging/logging.dart';
+
+import '../clang_bindings/clang_bindings.dart' as clang_types;
+import '../includer.dart';
+import '../utils.dart';
+import 'objcinterfacedecl_parser.dart';
+
+final _logger = Logger('ffigen.header_parser.objcprotocoldecl_parser');
+
+ObjCProtocol? parseObjCProtocolDeclaration(clang_types.CXCursor cursor,
+ {bool ignoreFilter = false}) {
+ if (cursor.kind != clang_types.CXCursorKind.CXCursor_ObjCProtocolDecl) {
+ return null;
+ }
+
+ final usr = cursor.usr();
+ final cachedProtocol = bindingsIndex.getSeenObjCProtocol(usr);
+ if (cachedProtocol != null) {
+ return cachedProtocol;
+ }
+
+ final name = cursor.spelling();
+
+ if (!ignoreFilter && !shouldIncludeObjCProtocol(usr, name)) {
+ return null;
+ }
+
+ _logger.fine('++++ Adding ObjC protocol: '
+ 'Name: $name, ${cursor.completeStringRepr()}');
+
+ final protocol = ObjCProtocol(
+ usr: usr,
+ originalName: name,
+ name: config.objcProtocols.renameUsingConfig(name),
+ lookupName: config.objcProtocolModulePrefixer.applyPrefix(name),
+ dartDoc: getCursorDocComment(cursor),
+ builtInFunctions: objCBuiltInFunctions,
+ );
+
+ // Make sure to add the protocol to the index before parsing the AST, to break
+ // cycles.
+ bindingsIndex.addObjCProtocolToSeen(usr, protocol);
+
+ cursor.visitChildren((child) {
+ switch (child.kind) {
+ case clang_types.CXCursorKind.CXCursor_ObjCProtocolRef:
+ final decl = clang.clang_getCursorDefinition(child);
+ _logger.fine(' > Super protocol: ${decl.completeStringRepr()}');
+ final superProtocol =
+ parseObjCProtocolDeclaration(decl, ignoreFilter: true);
+ if (superProtocol != null) {
+ protocol.superProtocols.add(superProtocol);
+ }
+ break;
+ case clang_types.CXCursorKind.CXCursor_ObjCInstanceMethodDecl:
+ case clang_types.CXCursorKind.CXCursor_ObjCClassMethodDecl:
+ final method = parseObjCMethod(child, name);
+ if (method != null) {
+ protocol.addMethod(method);
+ }
+ break;
+ }
+ });
+ return protocol;
+}
diff --git a/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart b/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart
index f8dc1cd7f1..038de4bc57 100644
--- a/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart
+++ b/pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart
@@ -5,6 +5,7 @@
import 'package:ffigen/src/code_generator.dart';
import 'package:ffigen/src/header_parser/sub_parsers/macro_parser.dart';
import 'package:ffigen/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart';
+import 'package:ffigen/src/header_parser/sub_parsers/objcprotocoldecl_parser.dart';
import 'package:ffigen/src/header_parser/sub_parsers/var_parser.dart';
import 'package:logging/logging.dart';
@@ -38,6 +39,9 @@ Set parseTranslationUnit(clang_types.CXCursor translationUnitCursor) {
case clang_types.CXCursorKind.CXCursor_ObjCCategoryDecl:
addToBindings(bindings, parseObjCCategoryDeclaration(cursor));
break;
+ case clang_types.CXCursorKind.CXCursor_ObjCProtocolDecl:
+ addToBindings(bindings, parseObjCProtocolDeclaration(cursor));
+ break;
case clang_types.CXCursorKind.CXCursor_MacroDefinition:
saveMacroDefinition(cursor);
break;
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 4736f9289c..22b6735bb5 100644
--- a/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart
+++ b/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart
@@ -68,7 +68,7 @@ Type getCodeGenType(
case clang_types.CXTypeKind.CXType_ObjCSel:
return PointerType(objCSelType);
case clang_types.CXTypeKind.CXType_BlockPointer:
- return _getOrCreateBlockType(cxtype);
+ return parseObjCBlock(cxtype);
}
}
@@ -171,17 +171,6 @@ Type getCodeGenType(
}
}
-Type _getOrCreateBlockType(clang_types.CXType cxtype) {
- final block = parseObjCBlock(cxtype);
- final key = block.usr;
- final oldBlock = bindingsIndex.getSeenObjCBlock(key);
- if (oldBlock != null) {
- return oldBlock;
- }
- bindingsIndex.addObjCBlockToSeen(key, block);
- return block;
-}
-
class _CreateTypeFromCursorResult {
final Type? type;
diff --git a/pkgs/ffigen/lib/src/header_parser/utils.dart b/pkgs/ffigen/lib/src/header_parser/utils.dart
index fbcc269a2b..2fd34f457a 100644
--- a/pkgs/ffigen/lib/src/header_parser/utils.dart
+++ b/pkgs/ffigen/lib/src/header_parser/utils.dart
@@ -437,6 +437,7 @@ class BindingsIndex {
final Map _macros = {};
final Map _globals = {};
final Map _objcBlocks = {};
+ final Map _objcProtocols = {};
/// Contains usr for typedefs which cannot be generated.
final Set _unsupportedTypealiases = {};
@@ -472,6 +473,10 @@ class BindingsIndex {
bool? getSeenHeaderStatus(String source) => _headerCache[source];
void addObjCBlockToSeen(String key, ObjCBlock t) => _objcBlocks[key] = t;
ObjCBlock? getSeenObjCBlock(String key) => _objcBlocks[key];
+ void addObjCProtocolToSeen(String usr, ObjCProtocol t) =>
+ _objcProtocols[usr] = t;
+ ObjCProtocol? getSeenObjCProtocol(String usr) => _objcProtocols[usr];
+ bool isSeenObjCProtocol(String usr) => _objcProtocols.containsKey(usr);
}
class CursorIndex {
diff --git a/pkgs/ffigen/lib/src/strings.dart b/pkgs/ffigen/lib/src/strings.dart
index 17f8add43f..f6a159c1ae 100644
--- a/pkgs/ffigen/lib/src/strings.dart
+++ b/pkgs/ffigen/lib/src/strings.dart
@@ -73,6 +73,7 @@ const globals = 'globals';
const macros = 'macros';
const typedefs = 'typedefs';
const objcInterfaces = 'objc-interfaces';
+const objcProtocols = 'objc-protocols';
const excludeAllByDefault = 'exclude-all-by-default';
const generateForPackageObjectiveC = 'generate-for-package-objective-c';
diff --git a/pkgs/ffigen/test/native_objc_test/protocol_config.yaml b/pkgs/ffigen/test/native_objc_test/protocol_config.yaml
index 121a293b2d..8bc5cd3c8d 100644
--- a/pkgs/ffigen/test/native_objc_test/protocol_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/protocol_config.yaml
@@ -8,18 +8,11 @@ objc-interfaces:
- ProtocolConsumer
- ObjCProtocolImpl
- ObjCProtocolImplMissingMethod
-typedefs:
+objc-protocols:
include:
- - InstanceMethodBlock
- - OptMethodBlock
- - VoidMethodBlock
- - OtherMethodBlock
-functions:
- include:
- - forceCodeGenOfInstanceMethodBlock
- - forceCodeGenOfOptMethodBlock
- - forceCodeGenOfVoidMethodBlock
- - forceCodeGenOfOtherMethodBlock
+ - EmptyProtocol
+ - MyProtocol
+ - SecondaryProtocol
headers:
entry-points:
- 'protocol_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/protocol_test.dart b/pkgs/ffigen/test/native_objc_test/protocol_test.dart
index d235cf8b17..947b837038 100644
--- a/pkgs/ffigen/test/native_objc_test/protocol_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/protocol_test.dart
@@ -16,6 +16,11 @@ import '../test_utils.dart';
import 'protocol_bindings.dart';
import 'util.dart';
+typedef InstanceMethodBlock = ObjCBlock_NSString_ffiVoid_NSString_ffiDouble;
+typedef OptionalMethodBlock = ObjCBlock_Int32_ffiVoid_SomeStruct;
+typedef VoidMethodBlock = ObjCBlock_ffiVoid_ffiVoid_Int32;
+typedef OtherMethodBlock = ObjCBlock_Int32_ffiVoid_Int32_Int32_Int32_Int32;
+
void main() {
group('protocol', () {
setUpAll(() {
@@ -30,28 +35,111 @@ void main() {
group('ObjC implementation', () {
test('Method implementation', () {
- final protoImpl = ObjCProtocolImpl.new1();
+ final protocolImpl = ObjCProtocolImpl.new1();
final consumer = ProtocolConsumer.new1();
// Required instance method.
- final result = consumer.callInstanceMethod_(protoImpl);
+ final result = consumer.callInstanceMethod_(protocolImpl);
expect(result.toString(), 'ObjCProtocolImpl: Hello from ObjC: 3.14');
// Optional instance method.
- final intResult = consumer.callOptionalMethod_(protoImpl);
+ final intResult = consumer.callOptionalMethod_(protocolImpl);
expect(intResult, 579);
// Required instance method from secondary protocol.
- final otherIntResult = consumer.callOtherMethod_(protoImpl);
+ final otherIntResult = consumer.callOtherMethod_(protocolImpl);
expect(otherIntResult, 10);
});
test('Unimplemented method', () {
- final protoImpl = ObjCProtocolImplMissingMethod.new1();
+ final protocolImpl = ObjCProtocolImplMissingMethod.new1();
final consumer = ProtocolConsumer.new1();
// Optional instance method, not implemented.
- final intResult = consumer.callOptionalMethod_(protoImpl);
+ final intResult = consumer.callOptionalMethod_(protocolImpl);
+ expect(intResult, -999);
+ });
+ });
+
+ group('Dart implementation using helpers', () {
+ test('Method implementation', () {
+ final consumer = ProtocolConsumer.new1();
+
+ final myProtocol = MyProtocol.implement(
+ instanceMethod_withDouble_: (NSString s, double x) {
+ return 'MyProtocol: $s: $x'.toNSString();
+ },
+ optionalMethod_: (SomeStruct s) {
+ return s.y - s.x;
+ },
+ );
+
+ // Required instance method.
+ final result = consumer.callInstanceMethod_(myProtocol);
+ expect(result.toString(), 'MyProtocol: Hello from ObjC: 3.14');
+
+ // Optional instance method.
+ final intResult = consumer.callOptionalMethod_(myProtocol);
+ expect(intResult, 333);
+ });
+
+ test('Multiple protocol implementation', () {
+ final consumer = ProtocolConsumer.new1();
+
+ final protocolBuilder = ObjCProtocolBuilder();
+ MyProtocol.addToBuilder(protocolBuilder,
+ instanceMethod_withDouble_: (NSString s, double x) {
+ return 'ProtocolBuilder: $s: $x'.toNSString();
+ });
+ SecondaryProtocol.addToBuilder(protocolBuilder,
+ otherMethod_b_c_d_: (int a, int b, int c, int d) {
+ return a * b * c * d;
+ });
+ final protocolImpl = protocolBuilder.build();
+
+ // Required instance method.
+ final result = consumer.callInstanceMethod_(protocolImpl);
+ expect(result.toString(), 'ProtocolBuilder: Hello from ObjC: 3.14');
+
+ // Required instance method from secondary protocol.
+ final otherIntResult = consumer.callOtherMethod_(protocolImpl);
+ expect(otherIntResult, 24);
+ });
+
+ test('Multiple protocol implementation using method fields', () {
+ final consumer = ProtocolConsumer.new1();
+
+ final protocolBuilder = ObjCProtocolBuilder();
+ protocolBuilder.implementMethod(MyProtocol.instanceMethod_withDouble_,
+ (NSString s, double x) {
+ return 'ProtocolBuilder: $s: $x'.toNSString();
+ });
+ protocolBuilder.implementMethod(SecondaryProtocol.otherMethod_b_c_d_,
+ (int a, int b, int c, int d) {
+ return a * b * c * d;
+ });
+ final protocolImpl = protocolBuilder.build();
+
+ // Required instance method.
+ final result = consumer.callInstanceMethod_(protocolImpl);
+ expect(result.toString(), 'ProtocolBuilder: Hello from ObjC: 3.14');
+
+ // Required instance method from secondary protocol.
+ final otherIntResult = consumer.callOtherMethod_(protocolImpl);
+ expect(otherIntResult, 24);
+ });
+
+ test('Unimplemented method', () {
+ final consumer = ProtocolConsumer.new1();
+
+ final myProtocol = MyProtocol.implement(
+ instanceMethod_withDouble_: (NSString s, double x) {
+ throw UnimplementedError();
+ },
+ );
+
+ // Optional instance method, not implemented.
+ final intResult = consumer.callOptionalMethod_(myProtocol);
expect(intResult, -999);
});
});
@@ -60,38 +148,39 @@ void main() {
test('Method implementation', () {
final proxyBuilder = DartProxyBuilder.new1();
final consumer = ProtocolConsumer.new1();
- final proto = getProtocol('MyProtocol');
- final secondProto = getProtocol('SecondaryProtocol');
+ final protocol = getProtocol('MyProtocol');
+ final secondProtocol = getProtocol('SecondaryProtocol');
final sel = registerName('instanceMethod:withDouble:');
- final signature = getProtocolMethodSignature(proto, sel,
- isRequired: true, isInstance: true);
- final block = DartInstanceMethodBlock.fromFunction(
+ final signature = getProtocolMethodSignature(protocol, sel,
+ isRequired: true, isInstanceMethod: true);
+ final block = InstanceMethodBlock.fromFunction(
(Pointer p, NSString s, double x) {
return 'DartProxy: $s: $x'.toNSString();
});
proxyBuilder.implementMethod_withSignature_andBlock_(
- sel, signature!, block.pointer.cast());
+ sel, signature, block.pointer.cast());
final optSel = registerName('optionalMethod:');
- final optSignature = getProtocolMethodSignature(proto, optSel,
- isRequired: false, isInstance: true);
+ final optSignature = getProtocolMethodSignature(protocol, optSel,
+ isRequired: false, isInstanceMethod: true);
final optBlock =
- DartOptMethodBlock.fromFunction((Pointer p, SomeStruct s) {
+ OptionalMethodBlock.fromFunction((Pointer p, SomeStruct s) {
return s.y - s.x;
});
proxyBuilder.implementMethod_withSignature_andBlock_(
- optSel, optSignature!, optBlock.pointer.cast());
+ optSel, optSignature, optBlock.pointer.cast());
final otherSel = registerName('otherMethod:b:c:d:');
- final otherSignature = getProtocolMethodSignature(secondProto, otherSel,
- isRequired: true, isInstance: true);
- final otherBlock = DartOtherMethodBlock.fromFunction(
+ final otherSignature = getProtocolMethodSignature(
+ secondProtocol, otherSel,
+ isRequired: true, isInstanceMethod: true);
+ final otherBlock = OtherMethodBlock.fromFunction(
(Pointer p, int a, int b, int c, int d) {
return a * b * c * d;
});
proxyBuilder.implementMethod_withSignature_andBlock_(
- otherSel, otherSignature!, otherBlock.pointer.cast());
+ otherSel, otherSignature, otherBlock.pointer.cast());
final proxy = DartProxy.newFromBuilder_(proxyBuilder);
@@ -119,24 +208,19 @@ void main() {
});
test('Threading stress test', () async {
- final proxyBuilder = DartProxyBuilder.new1();
final consumer = ProtocolConsumer.new1();
- final proto = getProtocol('MyProtocol');
final completer = Completer();
int count = 0;
- final sel = registerName('voidMethod:');
- final signature = getProtocolMethodSignature(proto, sel,
- isRequired: false, isInstance: true);
- final block = DartVoidMethodBlock.listener((Pointer p, int x) {
+ final protocolBuilder = ObjCProtocolBuilder();
+ protocolBuilder.implementMethodAsListener(MyProtocol.voidMethod_,
+ (int x) {
expect(x, 123);
++count;
if (count == 1000) completer.complete();
});
- proxyBuilder.implementMethod_withSignature_andBlock_(
- sel, signature!, block.pointer.cast());
- final proxy = DartProxy.newFromBuilder_(proxyBuilder);
+ final proxy = protocolBuilder.build();
for (int i = 0; i < 1000; ++i) {
consumer.callMethodOnRandomThread_(proxy);
@@ -147,15 +231,15 @@ void main() {
(DartProxy, Pointer) blockRefCountTestInner() {
final proxyBuilder = DartProxyBuilder.new1();
- final proto = getProtocol('MyProtocol');
+ final protocol = getProtocol('MyProtocol');
final sel = registerName('instanceMethod:withDouble:');
- final signature = getProtocolMethodSignature(proto, sel,
- isRequired: true, isInstance: true);
- final block = DartInstanceMethodBlock.fromFunction(
+ final signature = getProtocolMethodSignature(protocol, sel,
+ isRequired: true, isInstanceMethod: true);
+ final block = InstanceMethodBlock.fromFunction(
(Pointer p, NSString s, double x) => 'Hello'.toNSString());
proxyBuilder.implementMethod_withSignature_andBlock_(
- sel, signature!, block.pointer.cast());
+ sel, signature, block.pointer.cast());
final proxy = DartProxy.newFromBuilder_(proxyBuilder);
diff --git a/pkgs/ffigen/test/native_objc_test/protocol_test.m b/pkgs/ffigen/test/native_objc_test/protocol_test.m
index 3ea0521fb9..015d991a0b 100644
--- a/pkgs/ffigen/test/native_objc_test/protocol_test.m
+++ b/pkgs/ffigen/test/native_objc_test/protocol_test.m
@@ -13,11 +13,15 @@
int32_t y;
} SomeStruct;
-@protocol MyProtocol
+@protocol SuperProtocol
@required
- (NSString*)instanceMethod:(NSString*)s withDouble:(double)x;
+@end
+
+@protocol MyProtocol
+
@optional
- (int32_t)optionalMethod:(SomeStruct)s;
@@ -32,37 +36,43 @@ @protocol SecondaryProtocol
@required
- (int32_t)otherMethod:(int32_t)a b:(int32_t)b c:(int32_t)c d:(int32_t)d;
+@optional
+- (nullable instancetype)returnsInstanceType;
+
+@end
+
+@protocol EmptyProtocol
@end
@interface ProtocolConsumer : NSObject
-- (NSString*)callInstanceMethod:(id)proto;
-- (int32_t)callOptionalMethod:(id)proto;
-- (int32_t)callOtherMethod:(id)proto;
-- (void)callMethodOnRandomThread:(id)proto;
+- (NSString*)callInstanceMethod:(id)protocol;
+- (int32_t)callOptionalMethod:(id)protocol;
+- (int32_t)callOtherMethod:(id)protocol;
+- (void)callMethodOnRandomThread:(id)protocol;
@end
@implementation ProtocolConsumer : NSObject
-- (NSString*)callInstanceMethod:(id)proto {
- return [proto instanceMethod:@"Hello from ObjC" withDouble:3.14];
+- (NSString*)callInstanceMethod:(id)protocol {
+ return [protocol instanceMethod:@"Hello from ObjC" withDouble:3.14];
}
-- (int32_t)callOptionalMethod:(id)proto {
- if ([proto respondsToSelector:@selector(optionalMethod:)]) {
+- (int32_t)callOptionalMethod:(id)protocol {
+ if ([protocol respondsToSelector:@selector(optionalMethod:)]) {
SomeStruct s = {123, 456};
- return [proto optionalMethod:s];
+ return [protocol optionalMethod:s];
} else {
return -999;
}
}
-- (int32_t)callOtherMethod:(id)proto {
- return [proto otherMethod:1 b:2 c:3 d:4];
+- (int32_t)callOtherMethod:(id)protocol {
+ return [protocol otherMethod:1 b:2 c:3 d:4];
}
-- (void)callMethodOnRandomThread:(id)proto {
+- (void)callMethodOnRandomThread:(id)protocol {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
- [proto voidMethod:123];
+ [protocol voidMethod:123];
});
}
@end
@@ -95,14 +105,3 @@ - (NSString *)instanceMethod:(NSString *)s withDouble:(double)x {
return @"ObjCProtocolImplMissingMethod";
}
@end
-
-
-// TODO(https://github.com/dart-lang/native/issues/1040): Delete these.
-typedef NSString* (^InstanceMethodBlock)(void*, NSString*, double);
-void forceCodeGenOfInstanceMethodBlock(InstanceMethodBlock block);
-typedef int32_t (^OptMethodBlock)(void*, SomeStruct);
-void forceCodeGenOfOptMethodBlock(OptMethodBlock block);
-typedef void (^VoidMethodBlock)(void*, int32_t);
-void forceCodeGenOfVoidMethodBlock(VoidMethodBlock block);
-typedef int32_t (^OtherMethodBlock)(void*, int32_t a, int32_t b, int32_t c, int32_t d);
-void forceCodeGenOfOtherMethodBlock(OtherMethodBlock block);
diff --git a/pkgs/ffigen/tool/generate_json_schema.dart b/pkgs/ffigen/tool/generate_json_schema.dart
index 7a5a030c7b..99b1b9ef6e 100644
--- a/pkgs/ffigen/tool/generate_json_schema.dart
+++ b/pkgs/ffigen/tool/generate_json_schema.dart
@@ -4,7 +4,7 @@
// ================== GENERATING JSON SCHEMA =====================
// cd to project's root, and run -
-// dart generate_json_schema.dart
+// dart tool/generate_json_schema.dart
// ===============================================================
import 'dart:convert';
import 'dart:io';
diff --git a/pkgs/ffigen/tool/libclang_config.yaml b/pkgs/ffigen/tool/libclang_config.yaml
index 6f57c2fcc6..804d3861c4 100644
--- a/pkgs/ffigen/tool/libclang_config.yaml
+++ b/pkgs/ffigen/tool/libclang_config.yaml
@@ -123,6 +123,7 @@ functions:
- clang_Cursor_getObjCPropertyAttributes
- clang_Cursor_getObjCPropertyGetterName
- clang_Cursor_getObjCPropertySetterName
+ - clang_Cursor_isObjCOptional
- clang_Type_getNullability
- clang_Type_getModifiedType
- clang_Location_isInSystemHeader
diff --git a/pkgs/objective_c/CHANGELOG.md b/pkgs/objective_c/CHANGELOG.md
index daddf863d7..dd48b9582b 100644
--- a/pkgs/objective_c/CHANGELOG.md
+++ b/pkgs/objective_c/CHANGELOG.md
@@ -5,6 +5,11 @@
constructing `DartProxy`.
- Add some extensions methods for `NSMutableData`.
- Fix the `NSError` bindings so that they're not empty.
+- Add `ObjCProtocolBuilder`, which is an ergonomic wrapper around
+ `DartProxyBuilder`.
+- Add `ObjCProtocolMethod`, which contains all the information that
+ `ObjCProtocolBuilder` needs to implement a method. These objects are created
+ by the ffigen bindings for a protocol.
## 1.0.1
diff --git a/pkgs/objective_c/ffigen_objc.yaml b/pkgs/objective_c/ffigen_objc.yaml
index 4c23807208..672b8044a4 100644
--- a/pkgs/objective_c/ffigen_objc.yaml
+++ b/pkgs/objective_c/ffigen_objc.yaml
@@ -31,12 +31,12 @@ objc-interfaces:
- NSMutableArray
- NSMutableData
- NSMutableDictionary
+ - NSMutableIndexSet
- NSMutableSet
- NSMutableString
- NSNotification
- NSNumber
- NSObject
- - NSProgress
- NSProxy
- NSSet
- NSString
@@ -44,6 +44,12 @@ objc-interfaces:
- NSURLHandle
- NSValue
- Protocol
+structs:
+ include:
+ - _NSRange
+ - NSFastEnumerationState
+ rename:
+ _NSRange: NSRange
preamble: |
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
diff --git a/pkgs/objective_c/lib/objective_c.dart b/pkgs/objective_c/lib/objective_c.dart
index 86f4fdc5a1..99778f1e62 100644
--- a/pkgs/objective_c/lib/objective_c.dart
+++ b/pkgs/objective_c/lib/objective_c.dart
@@ -6,6 +6,7 @@ export 'src/internal.dart' hide blockHasRegisteredClosure;
export 'src/ns_data.dart';
export 'src/ns_mutable_data.dart';
export 'src/ns_string.dart';
+export 'src/protocol_builder.dart';
export 'src/c_bindings_generated.dart'
show
ObjCSelector,
@@ -37,13 +38,15 @@ export 'src/objective_c_bindings_generated.dart'
NSMutableArray,
NSMutableData,
NSMutableDictionary,
+ NSMutableIndexSet,
NSMutableSet,
NSMutableString,
+ NSFastEnumerationState,
NSNotification,
NSNumber,
NSObject,
- NSProgress,
NSProxy,
+ NSRange,
NSSet,
NSString,
NSURL,
diff --git a/pkgs/objective_c/lib/src/c_bindings_generated.dart b/pkgs/objective_c/lib/src/c_bindings_generated.dart
index 450ba5970f..e4ff5143a1 100644
--- a/pkgs/objective_c/lib/src/c_bindings_generated.dart
+++ b/pkgs/objective_c/lib/src/c_bindings_generated.dart
@@ -129,7 +129,7 @@ external ffi.Pointer getProtocol(
ffi.Bool,
ffi.Bool)>(symbol: "protocol_getMethodDescription", isLeaf: true)
external ObjCMethodDesc getMethodDescription(
- ffi.Pointer proto,
+ ffi.Pointer protocol,
ffi.Pointer sel,
bool isRequiredMethod,
bool isInstanceMethod,
diff --git a/pkgs/objective_c/lib/src/internal.dart b/pkgs/objective_c/lib/src/internal.dart
index 1549b4c64d..7ece5ae776 100644
--- a/pkgs/objective_c/lib/src/internal.dart
+++ b/pkgs/objective_c/lib/src/internal.dart
@@ -41,18 +41,23 @@ Pointer getProtocol(String name) {
}
/// Only for use by ffigen bindings.
-objc.NSMethodSignature? getProtocolMethodSignature(
+objc.NSMethodSignature getProtocolMethodSignature(
Pointer protocol,
Pointer sel, {
required bool isRequired,
- required bool isInstance,
+ required bool isInstanceMethod,
}) {
final sig =
- c.getMethodDescription(protocol, sel, isRequired, isInstance).types;
+ c.getMethodDescription(protocol, sel, isRequired, isInstanceMethod).types;
if (sig == nullptr) {
- return null;
+ throw Exception('Failed to load method of Objective-C protocol');
}
- return objc.NSMethodSignature.signatureWithObjCTypes_(sig);
+ final sigObj = objc.NSMethodSignature.signatureWithObjCTypes_(sig);
+ if (sigObj == null) {
+ throw Exception(
+ 'Failed to construct signature for Objective-C protocol method');
+ }
+ return sigObj;
}
/// Only for use by ffigen bindings.
@@ -280,6 +285,25 @@ Function getBlockClosure(Pointer block) {
return _blockClosureRegistry[id]!;
}
+/// Only for use by ffigen bindings.
+class ObjCProtocolMethod {
+ final Pointer sel;
+ final objc.NSMethodSignature signature;
+ final bool Function(Function) isCorrectFunctionType;
+ final ObjCBlockBase Function(Function) createBlock;
+
+ ObjCProtocolMethod(
+ this.sel, this.signature, this.isCorrectFunctionType, this.createBlock);
+}
+
+/// Only for use by ffigen bindings.
+class ObjCProtocolListenableMethod extends ObjCProtocolMethod {
+ final ObjCBlockBase Function(Function) createListenerBlock;
+
+ ObjCProtocolListenableMethod(super.sel, super.signature,
+ super.isCorrectFunctionType, super.createBlock, this.createListenerBlock);
+}
+
// Not exported by ../objective_c.dart, because they're only for testing.
bool blockHasRegisteredClosure(Pointer block) =>
_blockClosureRegistry.containsKey(block.ref.target.address);
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 527c2e4085..507dd03c06 100644
--- a/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart
+++ b/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart
@@ -19,6 +19,7 @@ import 'package:ffi/ffi.dart' as pkg_ffi;
import 'dart:ffi' as ffi;
import '../objective_c.dart' as objc;
+/// NSObject
class NSObject extends objc.ObjCObjectBase {
NSObject._(ffi.Pointer pointer,
{bool retain = false, bool release = false})
@@ -38,89 +39,107 @@ class NSObject extends objc.ObjCObjectBase {
return _objc_msgSend_0(obj.pointer, _sel_isKindOfClass_, _class_NSObject);
}
+ /// load
static void load() {
_objc_msgSend_1(_class_NSObject, _sel_load);
}
+ /// initialize
static void initialize() {
_objc_msgSend_1(_class_NSObject, _sel_initialize);
}
+ /// init
NSObject init() {
final _ret = _objc_msgSend_2(this.pointer, _sel_init);
return NSObject.castFromPointer(_ret, retain: true, release: true);
}
+ /// new
static NSObject new1() {
final _ret = _objc_msgSend_2(_class_NSObject, _sel_new);
return NSObject.castFromPointer(_ret, retain: false, release: true);
}
+ /// allocWithZone:
static NSObject allocWithZone_(ffi.Pointer<_NSZone> zone) {
final _ret = _objc_msgSend_3(_class_NSObject, _sel_allocWithZone_, zone);
return NSObject.castFromPointer(_ret, retain: false, release: true);
}
+ /// alloc
static NSObject alloc() {
final _ret = _objc_msgSend_2(_class_NSObject, _sel_alloc);
return NSObject.castFromPointer(_ret, retain: false, release: true);
}
+ /// dealloc
void dealloc() {
_objc_msgSend_1(this.pointer, _sel_dealloc);
}
+ /// finalize
void finalize() {
_objc_msgSend_1(this.pointer, _sel_finalize);
}
+ /// copy
objc.ObjCObjectBase copy() {
final _ret = _objc_msgSend_2(this.pointer, _sel_copy);
return objc.ObjCObjectBase(_ret, retain: false, release: true);
}
+ /// mutableCopy
objc.ObjCObjectBase mutableCopy() {
final _ret = _objc_msgSend_2(this.pointer, _sel_mutableCopy);
return objc.ObjCObjectBase(_ret, retain: false, release: true);
}
+ /// copyWithZone:
static objc.ObjCObjectBase copyWithZone_(ffi.Pointer<_NSZone> zone) {
final _ret = _objc_msgSend_3(_class_NSObject, _sel_copyWithZone_, zone);
return objc.ObjCObjectBase(_ret, retain: false, release: true);
}
+ /// mutableCopyWithZone:
static objc.ObjCObjectBase mutableCopyWithZone_(ffi.Pointer<_NSZone> zone) {
final _ret =
_objc_msgSend_3(_class_NSObject, _sel_mutableCopyWithZone_, zone);
return objc.ObjCObjectBase(_ret, retain: false, release: true);
}
+ /// instancesRespondToSelector:
static bool instancesRespondToSelector_(
ffi.Pointer aSelector) {
return _objc_msgSend_4(
_class_NSObject, _sel_instancesRespondToSelector_, aSelector);
}
+ /// conformsToProtocol:
static bool conformsToProtocol_(Protocol protocol) {
return _objc_msgSend_5(
_class_NSObject, _sel_conformsToProtocol_, protocol.pointer);
}
+ /// methodForSelector:
ffi.Pointer> methodForSelector_(
ffi.Pointer aSelector) {
return _objc_msgSend_6(this.pointer, _sel_methodForSelector_, aSelector);
}
+ /// instanceMethodForSelector:
static ffi.Pointer>
instanceMethodForSelector_(ffi.Pointer aSelector) {
return _objc_msgSend_6(
_class_NSObject, _sel_instanceMethodForSelector_, aSelector);
}
+ /// doesNotRecognizeSelector:
void doesNotRecognizeSelector_(ffi.Pointer aSelector) {
_objc_msgSend_7(this.pointer, _sel_doesNotRecognizeSelector_, aSelector);
}
+ /// forwardingTargetForSelector:
objc.ObjCObjectBase forwardingTargetForSelector_(
ffi.Pointer aSelector) {
final _ret = _objc_msgSend_8(
@@ -128,11 +147,13 @@ class NSObject extends objc.ObjCObjectBase {
return objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// forwardInvocation:
void forwardInvocation_(NSInvocation anInvocation) {
_objc_msgSend_9(
this.pointer, _sel_forwardInvocation_, anInvocation.pointer);
}
+ /// methodSignatureForSelector:
NSMethodSignature methodSignatureForSelector_(
ffi.Pointer aSelector) {
final _ret = _objc_msgSend_15(
@@ -140,6 +161,7 @@ class NSObject extends objc.ObjCObjectBase {
return NSMethodSignature.castFromPointer(_ret, retain: true, release: true);
}
+ /// instanceMethodSignatureForSelector:
static NSMethodSignature instanceMethodSignatureForSelector_(
ffi.Pointer aSelector) {
final _ret = _objc_msgSend_15(
@@ -147,64 +169,78 @@ class NSObject extends objc.ObjCObjectBase {
return NSMethodSignature.castFromPointer(_ret, retain: true, release: true);
}
+ /// allowsWeakReference
bool allowsWeakReference() {
return _objc_msgSend_13(this.pointer, _sel_allowsWeakReference);
}
+ /// retainWeakReference
bool retainWeakReference() {
return _objc_msgSend_13(this.pointer, _sel_retainWeakReference);
}
+ /// isSubclassOfClass:
static bool isSubclassOfClass_(objc.ObjCObjectBase aClass) {
return _objc_msgSend_0(
_class_NSObject, _sel_isSubclassOfClass_, aClass.pointer);
}
+ /// resolveClassMethod:
static bool resolveClassMethod_(ffi.Pointer sel) {
return _objc_msgSend_4(_class_NSObject, _sel_resolveClassMethod_, sel);
}
+ /// resolveInstanceMethod:
static bool resolveInstanceMethod_(ffi.Pointer sel) {
return _objc_msgSend_4(_class_NSObject, _sel_resolveInstanceMethod_, sel);
}
+ /// hash
static int hash() {
return _objc_msgSend_11(_class_NSObject, _sel_hash);
}
+ /// superclass
static objc.ObjCObjectBase superclass() {
final _ret = _objc_msgSend_2(_class_NSObject, _sel_superclass);
return objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// class
static objc.ObjCObjectBase class1() {
final _ret = _objc_msgSend_2(_class_NSObject, _sel_class);
return objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// description
static NSString description() {
final _ret = _objc_msgSend_35(_class_NSObject, _sel_description);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// debugDescription
static NSString debugDescription() {
final _ret = _objc_msgSend_35(_class_NSObject, _sel_debugDescription);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// version
static int version() {
return _objc_msgSend_79(_class_NSObject, _sel_version);
}
+ /// setVersion:
static void setVersion_(int aVersion) {
- _objc_msgSend_288(_class_NSObject, _sel_setVersion_, aVersion);
+ _objc_msgSend_247(_class_NSObject, _sel_setVersion_, aVersion);
}
+ /// classForCoder
objc.ObjCObjectBase get classForCoder {
final _ret = _objc_msgSend_2(this.pointer, _sel_classForCoder);
return objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// replacementObjectForCoder:
objc.ObjCObjectBase? replacementObjectForCoder_(NSCoder coder) {
final _ret = _objc_msgSend_17(
this.pointer, _sel_replacementObjectForCoder_, coder.pointer);
@@ -213,6 +249,7 @@ class NSObject extends objc.ObjCObjectBase {
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// awakeAfterUsingCoder:
objc.ObjCObjectBase? awakeAfterUsingCoder_(NSCoder coder) {
final _ret = _objc_msgSend_17(
this.pointer, _sel_awakeAfterUsingCoder_, coder.pointer);
@@ -221,15 +258,18 @@ class NSObject extends objc.ObjCObjectBase {
: objc.ObjCObjectBase(_ret, retain: false, release: true);
}
+ /// poseAsClass:
static void poseAsClass_(objc.ObjCObjectBase aClass) {
- _objc_msgSend_203(_class_NSObject, _sel_poseAsClass_, aClass.pointer);
+ _objc_msgSend_172(_class_NSObject, _sel_poseAsClass_, aClass.pointer);
}
+ /// autoContentAccessingProxy
objc.ObjCObjectBase get autoContentAccessingProxy {
final _ret = _objc_msgSend_2(this.pointer, _sel_autoContentAccessingProxy);
return objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// attemptRecoveryFromError:optionIndex:delegate:didRecoverSelector:contextInfo:
void
attemptRecoveryFromError_optionIndex_delegate_didRecoverSelector_contextInfo_(
NSError error,
@@ -237,7 +277,7 @@ class NSObject extends objc.ObjCObjectBase {
objc.ObjCObjectBase? delegate,
ffi.Pointer didRecoverSelector,
ffi.Pointer contextInfo) {
- _objc_msgSend_289(
+ _objc_msgSend_248(
this.pointer,
_sel_attemptRecoveryFromError_optionIndex_delegate_didRecoverSelector_contextInfo_,
error.pointer,
@@ -247,32 +287,37 @@ class NSObject extends objc.ObjCObjectBase {
contextInfo);
}
+ /// attemptRecoveryFromError:optionIndex:
bool attemptRecoveryFromError_optionIndex_(
NSError error, int recoveryOptionIndex) {
- return _objc_msgSend_290(
+ return _objc_msgSend_249(
this.pointer,
_sel_attemptRecoveryFromError_optionIndex_,
error.pointer,
recoveryOptionIndex);
}
+ /// URL:resourceDataDidBecomeAvailable:
void URL_resourceDataDidBecomeAvailable_(NSURL sender, NSData newBytes) {
- _objc_msgSend_291(this.pointer, _sel_URL_resourceDataDidBecomeAvailable_,
+ _objc_msgSend_250(this.pointer, _sel_URL_resourceDataDidBecomeAvailable_,
sender.pointer, newBytes.pointer);
}
+ /// URLResourceDidFinishLoading:
void URLResourceDidFinishLoading_(NSURL sender) {
- _objc_msgSend_292(
+ _objc_msgSend_251(
this.pointer, _sel_URLResourceDidFinishLoading_, sender.pointer);
}
+ /// URLResourceDidCancelLoading:
void URLResourceDidCancelLoading_(NSURL sender) {
- _objc_msgSend_292(
+ _objc_msgSend_251(
this.pointer, _sel_URLResourceDidCancelLoading_, sender.pointer);
}
+ /// URL:resourceDidFailLoadingWithReason:
void URL_resourceDidFailLoadingWithReason_(NSURL sender, NSString reason) {
- _objc_msgSend_293(this.pointer, _sel_URL_resourceDidFailLoadingWithReason_,
+ _objc_msgSend_252(this.pointer, _sel_URL_resourceDidFailLoadingWithReason_,
sender.pointer, reason.pointer);
}
}
@@ -333,6 +378,7 @@ final _objc_msgSend_4 = objc.msgSendPointer
bool Function(ffi.Pointer,
ffi.Pointer, ffi.Pointer)>();
+/// Protocol
class Protocol extends objc.ObjCObjectBase {
Protocol._(ffi.Pointer pointer,
{bool retain = false, bool release = false})
@@ -416,6 +462,7 @@ final _objc_msgSend_8 = objc.msgSendPointer
ffi.Pointer Function(ffi.Pointer,
ffi.Pointer, ffi.Pointer)>();
+/// NSInvocation
class NSInvocation extends objc.ObjCObjectBase {
NSInvocation._(ffi.Pointer pointer,
{bool retain = false, bool release = false})
@@ -450,6 +497,7 @@ final _objc_msgSend_9 = objc.msgSendPointer
void Function(ffi.Pointer,
ffi.Pointer, ffi.Pointer)>();
+/// NSMethodSignature
class NSMethodSignature extends NSObject {
NSMethodSignature._(ffi.Pointer pointer,
{bool retain = false, bool release = false})
@@ -470,6 +518,7 @@ class NSMethodSignature extends NSObject {
obj.pointer, _sel_isKindOfClass_, _class_NSMethodSignature);
}
+ /// signatureWithObjCTypes:
static NSMethodSignature? signatureWithObjCTypes_(
ffi.Pointer types) {
final _ret = _objc_msgSend_10(
@@ -479,42 +528,50 @@ class NSMethodSignature extends NSObject {
: NSMethodSignature.castFromPointer(_ret, retain: true, release: true);
}
+ /// numberOfArguments
int get numberOfArguments {
return _objc_msgSend_11(this.pointer, _sel_numberOfArguments);
}
+ /// getArgumentTypeAtIndex:
ffi.Pointer getArgumentTypeAtIndex_(int idx) {
return _objc_msgSend_12(this.pointer, _sel_getArgumentTypeAtIndex_, idx);
}
+ /// frameLength
int get frameLength {
return _objc_msgSend_11(this.pointer, _sel_frameLength);
}
+ /// isOneway
bool isOneway() {
return _objc_msgSend_13(this.pointer, _sel_isOneway);
}
+ /// methodReturnType
ffi.Pointer get methodReturnType {
return _objc_msgSend_14(this.pointer, _sel_methodReturnType);
}
+ /// methodReturnLength
int get methodReturnLength {
return _objc_msgSend_11(this.pointer, _sel_methodReturnLength);
}
- @override
+ /// init
NSMethodSignature init() {
final _ret = _objc_msgSend_2(this.pointer, _sel_init);
return NSMethodSignature.castFromPointer(_ret, retain: true, release: true);
}
+ /// new
static NSMethodSignature new1() {
final _ret = _objc_msgSend_2(_class_NSMethodSignature, _sel_new);
return NSMethodSignature.castFromPointer(_ret,
retain: false, release: true);
}
+ /// allocWithZone:
static NSMethodSignature allocWithZone_(ffi.Pointer<_NSZone> zone) {
final _ret =
_objc_msgSend_3(_class_NSMethodSignature, _sel_allocWithZone_, zone);
@@ -522,6 +579,7 @@ class NSMethodSignature extends NSObject {
retain: false, release: true);
}
+ /// alloc
static NSMethodSignature alloc() {
final _ret = _objc_msgSend_2(_class_NSMethodSignature, _sel_alloc);
return NSMethodSignature.castFromPointer(_ret,
@@ -603,6 +661,7 @@ late final _sel_hash = objc.registerName("hash");
late final _sel_superclass = objc.registerName("superclass");
late final _sel_class = objc.registerName("class");
+/// NSString
class NSString extends NSObject {
factory NSString(String str) {
final cstr = str.toNativeUtf16();
@@ -636,20 +695,23 @@ class NSString extends NSObject {
return _objc_msgSend_0(obj.pointer, _sel_isKindOfClass_, _class_NSString);
}
+ /// length
int get length {
return _objc_msgSend_11(this.pointer, _sel_length);
}
+ /// characterAtIndex:
int characterAtIndex_(int index) {
return _objc_msgSend_16(this.pointer, _sel_characterAtIndex_, index);
}
- @override
+ /// init
NSString init() {
final _ret = _objc_msgSend_2(this.pointer, _sel_init);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithCoder:
NSString? initWithCoder_(NSCoder coder) {
final _ret =
_objc_msgSend_17(this.pointer, _sel_initWithCoder_, coder.pointer);
@@ -658,108 +720,141 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// substringFromIndex:
NSString substringFromIndex_(int from) {
final _ret = _objc_msgSend_18(this.pointer, _sel_substringFromIndex_, from);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// substringToIndex:
NSString substringToIndex_(int to) {
final _ret = _objc_msgSend_18(this.pointer, _sel_substringToIndex_, to);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
- NSString substringWithRange_(_NSRange range) {
+ /// substringWithRange:
+ NSString substringWithRange_(NSRange range) {
final _ret =
_objc_msgSend_19(this.pointer, _sel_substringWithRange_, range);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// getCharacters:range:
void getCharacters_range_(
- ffi.Pointer buffer, _NSRange range) {
+ ffi.Pointer buffer, NSRange range) {
_objc_msgSend_20(this.pointer, _sel_getCharacters_range_, buffer, range);
}
- int compare_(NSString string) {
- return _objc_msgSend_21(this.pointer, _sel_compare_, string.pointer);
+ /// compare:
+ NSComparisonResult compare_(NSString string) {
+ final _ret = _objc_msgSend_21(this.pointer, _sel_compare_, string.pointer);
+ return NSComparisonResult.fromValue(_ret);
}
- int compare_options_(NSString string, int mask) {
- return _objc_msgSend_22(
- this.pointer, _sel_compare_options_, string.pointer, mask);
+ /// compare:options:
+ NSComparisonResult compare_options_(
+ NSString string, NSStringCompareOptions mask) {
+ final _ret = _objc_msgSend_22(
+ this.pointer, _sel_compare_options_, string.pointer, mask.value);
+ return NSComparisonResult.fromValue(_ret);
}
- int compare_options_range_(
- NSString string, int mask, _NSRange rangeOfReceiverToCompare) {
- return _objc_msgSend_23(this.pointer, _sel_compare_options_range_,
- string.pointer, mask, rangeOfReceiverToCompare);
+ /// compare:options:range:
+ NSComparisonResult compare_options_range_(NSString string,
+ NSStringCompareOptions mask, NSRange rangeOfReceiverToCompare) {
+ final _ret = _objc_msgSend_23(this.pointer, _sel_compare_options_range_,
+ string.pointer, mask.value, rangeOfReceiverToCompare);
+ return NSComparisonResult.fromValue(_ret);
}
- int compare_options_range_locale_(NSString string, int mask,
- _NSRange rangeOfReceiverToCompare, objc.ObjCObjectBase? locale) {
- return _objc_msgSend_24(
+ /// compare:options:range:locale:
+ NSComparisonResult compare_options_range_locale_(
+ NSString string,
+ NSStringCompareOptions mask,
+ NSRange rangeOfReceiverToCompare,
+ objc.ObjCObjectBase? locale) {
+ final _ret = _objc_msgSend_24(
this.pointer,
_sel_compare_options_range_locale_,
string.pointer,
- mask,
+ mask.value,
rangeOfReceiverToCompare,
locale?.pointer ?? ffi.nullptr);
+ return NSComparisonResult.fromValue(_ret);
}
- int caseInsensitiveCompare_(NSString string) {
- return _objc_msgSend_21(
+ /// caseInsensitiveCompare:
+ NSComparisonResult caseInsensitiveCompare_(NSString string) {
+ final _ret = _objc_msgSend_21(
this.pointer, _sel_caseInsensitiveCompare_, string.pointer);
+ return NSComparisonResult.fromValue(_ret);
}
- int localizedCompare_(NSString string) {
- return _objc_msgSend_21(
- this.pointer, _sel_localizedCompare_, string.pointer);
+ /// localizedCompare:
+ NSComparisonResult localizedCompare_(NSString string) {
+ final _ret =
+ _objc_msgSend_21(this.pointer, _sel_localizedCompare_, string.pointer);
+ return NSComparisonResult.fromValue(_ret);
}
- int localizedCaseInsensitiveCompare_(NSString string) {
- return _objc_msgSend_21(
+ /// localizedCaseInsensitiveCompare:
+ NSComparisonResult localizedCaseInsensitiveCompare_(NSString string) {
+ final _ret = _objc_msgSend_21(
this.pointer, _sel_localizedCaseInsensitiveCompare_, string.pointer);
+ return NSComparisonResult.fromValue(_ret);
}
- int localizedStandardCompare_(NSString string) {
- return _objc_msgSend_21(
+ /// localizedStandardCompare:
+ NSComparisonResult localizedStandardCompare_(NSString string) {
+ final _ret = _objc_msgSend_21(
this.pointer, _sel_localizedStandardCompare_, string.pointer);
+ return NSComparisonResult.fromValue(_ret);
}
+ /// isEqualToString:
bool isEqualToString_(NSString aString) {
return _objc_msgSend_25(
this.pointer, _sel_isEqualToString_, aString.pointer);
}
+ /// hasPrefix:
bool hasPrefix_(NSString str) {
return _objc_msgSend_25(this.pointer, _sel_hasPrefix_, str.pointer);
}
+ /// hasSuffix:
bool hasSuffix_(NSString str) {
return _objc_msgSend_25(this.pointer, _sel_hasSuffix_, str.pointer);
}
- NSString commonPrefixWithString_options_(NSString str, int mask) {
- final _ret = _objc_msgSend_26(
- this.pointer, _sel_commonPrefixWithString_options_, str.pointer, mask);
+ /// commonPrefixWithString:options:
+ NSString commonPrefixWithString_options_(
+ NSString str, NSStringCompareOptions mask) {
+ final _ret = _objc_msgSend_26(this.pointer,
+ _sel_commonPrefixWithString_options_, str.pointer, mask.value);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// containsString:
bool containsString_(NSString str) {
return _objc_msgSend_25(this.pointer, _sel_containsString_, str.pointer);
}
+ /// localizedCaseInsensitiveContainsString:
bool localizedCaseInsensitiveContainsString_(NSString str) {
return _objc_msgSend_25(this.pointer,
_sel_localizedCaseInsensitiveContainsString_, str.pointer);
}
+ /// localizedStandardContainsString:
bool localizedStandardContainsString_(NSString str) {
return _objc_msgSend_25(
this.pointer, _sel_localizedStandardContainsString_, str.pointer);
}
+ /// localizedStandardRangeOfString:
void localizedStandardRangeOfString_(
- ffi.Pointer<_NSRange> stret, NSString str) {
+ ffi.Pointer stret, NSString str) {
objc.useMsgSendVariants
? _objc_msgSend_27Stret(stret, this.pointer,
_sel_localizedStandardRangeOfString_, str.pointer)
@@ -767,7 +862,8 @@ class NSString extends NSObject {
this.pointer, _sel_localizedStandardRangeOfString_, str.pointer);
}
- void rangeOfString_(ffi.Pointer<_NSRange> stret, NSString searchString) {
+ /// rangeOfString:
+ void rangeOfString_(ffi.Pointer stret, NSString searchString) {
objc.useMsgSendVariants
? _objc_msgSend_27Stret(
stret, this.pointer, _sel_rangeOfString_, searchString.pointer)
@@ -775,38 +871,44 @@ class NSString extends NSObject {
this.pointer, _sel_rangeOfString_, searchString.pointer);
}
- void rangeOfString_options_(
- ffi.Pointer<_NSRange> stret, NSString searchString, int mask) {
+ /// rangeOfString:options:
+ void rangeOfString_options_(ffi.Pointer stret, NSString searchString,
+ NSStringCompareOptions mask) {
objc.useMsgSendVariants
? _objc_msgSend_28Stret(stret, this.pointer,
- _sel_rangeOfString_options_, searchString.pointer, mask)
+ _sel_rangeOfString_options_, searchString.pointer, mask.value)
: stret.ref = _objc_msgSend_28(this.pointer,
- _sel_rangeOfString_options_, searchString.pointer, mask);
+ _sel_rangeOfString_options_, searchString.pointer, mask.value);
}
- void rangeOfString_options_range_(ffi.Pointer<_NSRange> stret,
- NSString searchString, int mask, _NSRange rangeOfReceiverToSearch) {
+ /// rangeOfString:options:range:
+ void rangeOfString_options_range_(
+ ffi.Pointer stret,
+ NSString searchString,
+ NSStringCompareOptions mask,
+ NSRange rangeOfReceiverToSearch) {
objc.useMsgSendVariants
? _objc_msgSend_29Stret(
stret,
this.pointer,
_sel_rangeOfString_options_range_,
searchString.pointer,
- mask,
+ mask.value,
rangeOfReceiverToSearch)
: stret.ref = _objc_msgSend_29(
this.pointer,
_sel_rangeOfString_options_range_,
searchString.pointer,
- mask,
+ mask.value,
rangeOfReceiverToSearch);
}
+ /// rangeOfString:options:range:locale:
void rangeOfString_options_range_locale_(
- ffi.Pointer<_NSRange> stret,
+ ffi.Pointer stret,
NSString searchString,
- int mask,
- _NSRange rangeOfReceiverToSearch,
+ NSStringCompareOptions mask,
+ NSRange rangeOfReceiverToSearch,
NSLocale? locale) {
objc.useMsgSendVariants
? _objc_msgSend_30Stret(
@@ -814,184 +916,219 @@ class NSString extends NSObject {
this.pointer,
_sel_rangeOfString_options_range_locale_,
searchString.pointer,
- mask,
+ mask.value,
rangeOfReceiverToSearch,
locale?.pointer ?? ffi.nullptr)
: stret.ref = _objc_msgSend_30(
this.pointer,
_sel_rangeOfString_options_range_locale_,
searchString.pointer,
- mask,
+ mask.value,
rangeOfReceiverToSearch,
locale?.pointer ?? ffi.nullptr);
}
+ /// rangeOfCharacterFromSet:
void rangeOfCharacterFromSet_(
- ffi.Pointer<_NSRange> stret, NSCharacterSet searchSet) {
+ ffi.Pointer stret, NSCharacterSet searchSet) {
objc.useMsgSendVariants
- ? _objc_msgSend_234Stret(stret, this.pointer,
+ ? _objc_msgSend_201Stret(stret, this.pointer,
_sel_rangeOfCharacterFromSet_, searchSet.pointer)
- : stret.ref = _objc_msgSend_234(
+ : stret.ref = _objc_msgSend_201(
this.pointer, _sel_rangeOfCharacterFromSet_, searchSet.pointer);
}
- void rangeOfCharacterFromSet_options_(
- ffi.Pointer<_NSRange> stret, NSCharacterSet searchSet, int mask) {
+ /// rangeOfCharacterFromSet:options:
+ void rangeOfCharacterFromSet_options_(ffi.Pointer stret,
+ NSCharacterSet searchSet, NSStringCompareOptions mask) {
objc.useMsgSendVariants
- ? _objc_msgSend_235Stret(stret, this.pointer,
- _sel_rangeOfCharacterFromSet_options_, searchSet.pointer, mask)
- : stret.ref = _objc_msgSend_235(this.pointer,
- _sel_rangeOfCharacterFromSet_options_, searchSet.pointer, mask);
+ ? _objc_msgSend_202Stret(
+ stret,
+ this.pointer,
+ _sel_rangeOfCharacterFromSet_options_,
+ searchSet.pointer,
+ mask.value)
+ : stret.ref = _objc_msgSend_202(
+ this.pointer,
+ _sel_rangeOfCharacterFromSet_options_,
+ searchSet.pointer,
+ mask.value);
}
- void rangeOfCharacterFromSet_options_range_(ffi.Pointer<_NSRange> stret,
- NSCharacterSet searchSet, int mask, _NSRange rangeOfReceiverToSearch) {
+ /// rangeOfCharacterFromSet:options:range:
+ void rangeOfCharacterFromSet_options_range_(
+ ffi.Pointer stret,
+ NSCharacterSet searchSet,
+ NSStringCompareOptions mask,
+ NSRange rangeOfReceiverToSearch) {
objc.useMsgSendVariants
- ? _objc_msgSend_236Stret(
+ ? _objc_msgSend_203Stret(
stret,
this.pointer,
_sel_rangeOfCharacterFromSet_options_range_,
searchSet.pointer,
- mask,
+ mask.value,
rangeOfReceiverToSearch)
- : stret.ref = _objc_msgSend_236(
+ : stret.ref = _objc_msgSend_203(
this.pointer,
_sel_rangeOfCharacterFromSet_options_range_,
searchSet.pointer,
- mask,
+ mask.value,
rangeOfReceiverToSearch);
}
+ /// rangeOfComposedCharacterSequenceAtIndex:
void rangeOfComposedCharacterSequenceAtIndex_(
- ffi.Pointer<_NSRange> stret, int index) {
+ ffi.Pointer stret, int index) {
objc.useMsgSendVariants
- ? _objc_msgSend_237Stret(stret, this.pointer,
+ ? _objc_msgSend_204Stret(stret, this.pointer,
_sel_rangeOfComposedCharacterSequenceAtIndex_, index)
- : stret.ref = _objc_msgSend_237(
+ : stret.ref = _objc_msgSend_204(
this.pointer, _sel_rangeOfComposedCharacterSequenceAtIndex_, index);
}
+ /// rangeOfComposedCharacterSequencesForRange:
void rangeOfComposedCharacterSequencesForRange_(
- ffi.Pointer<_NSRange> stret, _NSRange range) {
+ ffi.Pointer stret, NSRange range) {
objc.useMsgSendVariants
- ? _objc_msgSend_238Stret(stret, this.pointer,
+ ? _objc_msgSend_205Stret(stret, this.pointer,
_sel_rangeOfComposedCharacterSequencesForRange_, range)
- : stret.ref = _objc_msgSend_238(this.pointer,
+ : stret.ref = _objc_msgSend_205(this.pointer,
_sel_rangeOfComposedCharacterSequencesForRange_, range);
}
+ /// stringByAppendingString:
NSString stringByAppendingString_(NSString aString) {
final _ret = _objc_msgSend_103(
this.pointer, _sel_stringByAppendingString_, aString.pointer);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByAppendingFormat:
NSString stringByAppendingFormat_(NSString format) {
final _ret = _objc_msgSend_103(
this.pointer, _sel_stringByAppendingFormat_, format.pointer);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// doubleValue
double get doubleValue {
return objc.useMsgSendVariants
? _objc_msgSend_83Fpret(this.pointer, _sel_doubleValue)
: _objc_msgSend_83(this.pointer, _sel_doubleValue);
}
+ /// floatValue
double get floatValue {
return objc.useMsgSendVariants
? _objc_msgSend_82Fpret(this.pointer, _sel_floatValue)
: _objc_msgSend_82(this.pointer, _sel_floatValue);
}
+ /// intValue
int get intValue {
return _objc_msgSend_77(this.pointer, _sel_intValue);
}
+ /// integerValue
int get integerValue {
return _objc_msgSend_79(this.pointer, _sel_integerValue);
}
+ /// longLongValue
int get longLongValue {
return _objc_msgSend_80(this.pointer, _sel_longLongValue);
}
+ /// boolValue
bool get boolValue {
return _objc_msgSend_13(this.pointer, _sel_boolValue);
}
+ /// uppercaseString
NSString get uppercaseString {
final _ret = _objc_msgSend_35(this.pointer, _sel_uppercaseString);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// lowercaseString
NSString get lowercaseString {
final _ret = _objc_msgSend_35(this.pointer, _sel_lowercaseString);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// capitalizedString
NSString get capitalizedString {
final _ret = _objc_msgSend_35(this.pointer, _sel_capitalizedString);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// localizedUppercaseString
NSString get localizedUppercaseString {
final _ret = _objc_msgSend_35(this.pointer, _sel_localizedUppercaseString);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// localizedLowercaseString
NSString get localizedLowercaseString {
final _ret = _objc_msgSend_35(this.pointer, _sel_localizedLowercaseString);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// localizedCapitalizedString
NSString get localizedCapitalizedString {
final _ret =
_objc_msgSend_35(this.pointer, _sel_localizedCapitalizedString);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// uppercaseStringWithLocale:
NSString uppercaseStringWithLocale_(NSLocale? locale) {
- final _ret = _objc_msgSend_239(this.pointer,
+ final _ret = _objc_msgSend_206(this.pointer,
_sel_uppercaseStringWithLocale_, locale?.pointer ?? ffi.nullptr);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// lowercaseStringWithLocale:
NSString lowercaseStringWithLocale_(NSLocale? locale) {
- final _ret = _objc_msgSend_239(this.pointer,
+ final _ret = _objc_msgSend_206(this.pointer,
_sel_lowercaseStringWithLocale_, locale?.pointer ?? ffi.nullptr);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// capitalizedStringWithLocale:
NSString capitalizedStringWithLocale_(NSLocale? locale) {
- final _ret = _objc_msgSend_239(this.pointer,
+ final _ret = _objc_msgSend_206(this.pointer,
_sel_capitalizedStringWithLocale_, locale?.pointer ?? ffi.nullptr);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// getLineStart:end:contentsEnd:forRange:
void getLineStart_end_contentsEnd_forRange_(
ffi.Pointer startPtr,
ffi.Pointer lineEndPtr,
ffi.Pointer contentsEndPtr,
- _NSRange range) {
- _objc_msgSend_240(this.pointer, _sel_getLineStart_end_contentsEnd_forRange_,
+ NSRange range) {
+ _objc_msgSend_207(this.pointer, _sel_getLineStart_end_contentsEnd_forRange_,
startPtr, lineEndPtr, contentsEndPtr, range);
}
- void lineRangeForRange_(ffi.Pointer<_NSRange> stret, _NSRange range) {
+ /// lineRangeForRange:
+ void lineRangeForRange_(ffi.Pointer stret, NSRange range) {
objc.useMsgSendVariants
- ? _objc_msgSend_238Stret(
+ ? _objc_msgSend_205Stret(
stret, this.pointer, _sel_lineRangeForRange_, range)
: stret.ref =
- _objc_msgSend_238(this.pointer, _sel_lineRangeForRange_, range);
+ _objc_msgSend_205(this.pointer, _sel_lineRangeForRange_, range);
}
+ /// getParagraphStart:end:contentsEnd:forRange:
void getParagraphStart_end_contentsEnd_forRange_(
ffi.Pointer startPtr,
ffi.Pointer parEndPtr,
ffi.Pointer contentsEndPtr,
- _NSRange range) {
- _objc_msgSend_240(
+ NSRange range) {
+ _objc_msgSend_207(
this.pointer,
_sel_getParagraphStart_end_contentsEnd_forRange_,
startPtr,
@@ -1000,161 +1137,169 @@ class NSString extends NSObject {
range);
}
- void paragraphRangeForRange_(ffi.Pointer<_NSRange> stret, _NSRange range) {
+ /// paragraphRangeForRange:
+ void paragraphRangeForRange_(ffi.Pointer stret, NSRange range) {
objc.useMsgSendVariants
- ? _objc_msgSend_238Stret(
+ ? _objc_msgSend_205Stret(
stret, this.pointer, _sel_paragraphRangeForRange_, range)
- : stret.ref = _objc_msgSend_238(
+ : stret.ref = _objc_msgSend_205(
this.pointer, _sel_paragraphRangeForRange_, range);
}
- void enumerateSubstringsInRange_options_usingBlock_(_NSRange range, int opts,
- ObjCBlock_ffiVoid_NSString_NSRange_NSRange_bool block) {
- _objc_msgSend_241(
- this.pointer,
- _sel_enumerateSubstringsInRange_options_usingBlock_,
- range,
- opts,
- block.pointer);
- }
-
- void enumerateLinesUsingBlock_(ObjCBlock_ffiVoid_NSString_bool block) {
- _objc_msgSend_242(
- this.pointer, _sel_enumerateLinesUsingBlock_, block.pointer);
- }
-
+ /// UTF8String
ffi.Pointer get UTF8String {
return _objc_msgSend_14(this.pointer, _sel_UTF8String);
}
+ /// fastestEncoding
int get fastestEncoding {
return _objc_msgSend_11(this.pointer, _sel_fastestEncoding);
}
+ /// smallestEncoding
int get smallestEncoding {
return _objc_msgSend_11(this.pointer, _sel_smallestEncoding);
}
+ /// dataUsingEncoding:allowLossyConversion:
NSData? dataUsingEncoding_allowLossyConversion_(int encoding, bool lossy) {
- final _ret = _objc_msgSend_243(this.pointer,
+ final _ret = _objc_msgSend_208(this.pointer,
_sel_dataUsingEncoding_allowLossyConversion_, encoding, lossy);
return _ret.address == 0
? null
: NSData.castFromPointer(_ret, retain: true, release: true);
}
+ /// dataUsingEncoding:
NSData? dataUsingEncoding_(int encoding) {
final _ret =
- _objc_msgSend_244(this.pointer, _sel_dataUsingEncoding_, encoding);
+ _objc_msgSend_209(this.pointer, _sel_dataUsingEncoding_, encoding);
return _ret.address == 0
? null
: NSData.castFromPointer(_ret, retain: true, release: true);
}
+ /// canBeConvertedToEncoding:
bool canBeConvertedToEncoding_(int encoding) {
return _objc_msgSend_123(
this.pointer, _sel_canBeConvertedToEncoding_, encoding);
}
+ /// cStringUsingEncoding:
ffi.Pointer cStringUsingEncoding_(int encoding) {
return _objc_msgSend_12(this.pointer, _sel_cStringUsingEncoding_, encoding);
}
+ /// getCString:maxLength:encoding:
bool getCString_maxLength_encoding_(
ffi.Pointer buffer, int maxBufferCount, int encoding) {
- return _objc_msgSend_245(this.pointer, _sel_getCString_maxLength_encoding_,
+ return _objc_msgSend_210(this.pointer, _sel_getCString_maxLength_encoding_,
buffer, maxBufferCount, encoding);
}
+ /// getBytes:maxLength:usedLength:encoding:options:range:remainingRange:
bool getBytes_maxLength_usedLength_encoding_options_range_remainingRange_(
ffi.Pointer buffer,
int maxBufferCount,
ffi.Pointer usedBufferCount,
int encoding,
- int options,
- _NSRange range,
- ffi.Pointer<_NSRange> leftover) {
- return _objc_msgSend_246(
+ NSStringEncodingConversionOptions options,
+ NSRange range,
+ ffi.Pointer leftover) {
+ return _objc_msgSend_211(
this.pointer,
_sel_getBytes_maxLength_usedLength_encoding_options_range_remainingRange_,
buffer,
maxBufferCount,
usedBufferCount,
encoding,
- options,
+ options.value,
range,
leftover);
}
+ /// maximumLengthOfBytesUsingEncoding:
int maximumLengthOfBytesUsingEncoding_(int enc) {
return _objc_msgSend_120(
this.pointer, _sel_maximumLengthOfBytesUsingEncoding_, enc);
}
+ /// lengthOfBytesUsingEncoding:
int lengthOfBytesUsingEncoding_(int enc) {
return _objc_msgSend_120(
this.pointer, _sel_lengthOfBytesUsingEncoding_, enc);
}
+ /// availableStringEncodings
static ffi.Pointer getAvailableStringEncodings() {
- return _objc_msgSend_247(_class_NSString, _sel_availableStringEncodings);
+ return _objc_msgSend_212(_class_NSString, _sel_availableStringEncodings);
}
+ /// localizedNameOfStringEncoding:
static NSString localizedNameOfStringEncoding_(int encoding) {
final _ret = _objc_msgSend_18(
_class_NSString, _sel_localizedNameOfStringEncoding_, encoding);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// defaultCStringEncoding
static int getDefaultCStringEncoding() {
return _objc_msgSend_11(_class_NSString, _sel_defaultCStringEncoding);
}
+ /// decomposedStringWithCanonicalMapping
NSString get decomposedStringWithCanonicalMapping {
final _ret = _objc_msgSend_35(
this.pointer, _sel_decomposedStringWithCanonicalMapping);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// precomposedStringWithCanonicalMapping
NSString get precomposedStringWithCanonicalMapping {
final _ret = _objc_msgSend_35(
this.pointer, _sel_precomposedStringWithCanonicalMapping);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// decomposedStringWithCompatibilityMapping
NSString get decomposedStringWithCompatibilityMapping {
final _ret = _objc_msgSend_35(
this.pointer, _sel_decomposedStringWithCompatibilityMapping);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// precomposedStringWithCompatibilityMapping
NSString get precomposedStringWithCompatibilityMapping {
final _ret = _objc_msgSend_35(
this.pointer, _sel_precomposedStringWithCompatibilityMapping);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// componentsSeparatedByString:
NSArray componentsSeparatedByString_(NSString separator) {
- final _ret = _objc_msgSend_248(
+ final _ret = _objc_msgSend_213(
this.pointer, _sel_componentsSeparatedByString_, separator.pointer);
return NSArray.castFromPointer(_ret, retain: true, release: true);
}
+ /// componentsSeparatedByCharactersInSet:
NSArray componentsSeparatedByCharactersInSet_(NSCharacterSet separator) {
- final _ret = _objc_msgSend_249(this.pointer,
+ final _ret = _objc_msgSend_214(this.pointer,
_sel_componentsSeparatedByCharactersInSet_, separator.pointer);
return NSArray.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByTrimmingCharactersInSet:
NSString stringByTrimmingCharactersInSet_(NSCharacterSet set) {
- final _ret = _objc_msgSend_250(
+ final _ret = _objc_msgSend_215(
this.pointer, _sel_stringByTrimmingCharactersInSet_, set.pointer);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByPaddingToLength:withString:startingAtIndex:
NSString stringByPaddingToLength_withString_startingAtIndex_(
int newLength, NSString padString, int padIndex) {
- final _ret = _objc_msgSend_251(
+ final _ret = _objc_msgSend_216(
this.pointer,
_sel_stringByPaddingToLength_withString_startingAtIndex_,
newLength,
@@ -1163,33 +1308,37 @@ class NSString extends NSObject {
return NSString.castFromPointer(_ret, retain: true, release: true);
}
- NSString stringByFoldingWithOptions_locale_(int options, NSLocale? locale) {
- final _ret = _objc_msgSend_252(
+ /// stringByFoldingWithOptions:locale:
+ NSString stringByFoldingWithOptions_locale_(
+ NSStringCompareOptions options, NSLocale? locale) {
+ final _ret = _objc_msgSend_217(
this.pointer,
_sel_stringByFoldingWithOptions_locale_,
- options,
+ options.value,
locale?.pointer ?? ffi.nullptr);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByReplacingOccurrencesOfString:withString:options:range:
NSString stringByReplacingOccurrencesOfString_withString_options_range_(
NSString target,
NSString replacement,
- int options,
- _NSRange searchRange) {
- final _ret = _objc_msgSend_253(
+ NSStringCompareOptions options,
+ NSRange searchRange) {
+ final _ret = _objc_msgSend_218(
this.pointer,
_sel_stringByReplacingOccurrencesOfString_withString_options_range_,
target.pointer,
replacement.pointer,
- options,
+ options.value,
searchRange);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByReplacingOccurrencesOfString:withString:
NSString stringByReplacingOccurrencesOfString_withString_(
NSString target, NSString replacement) {
- final _ret = _objc_msgSend_254(
+ final _ret = _objc_msgSend_219(
this.pointer,
_sel_stringByReplacingOccurrencesOfString_withString_,
target.pointer,
@@ -1197,9 +1346,10 @@ class NSString extends NSObject {
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByReplacingCharactersInRange:withString:
NSString stringByReplacingCharactersInRange_withString_(
- _NSRange range, NSString replacement) {
- final _ret = _objc_msgSend_255(
+ NSRange range, NSString replacement) {
+ final _ret = _objc_msgSend_220(
this.pointer,
_sel_stringByReplacingCharactersInRange_withString_,
range,
@@ -1207,18 +1357,20 @@ class NSString extends NSObject {
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByApplyingTransform:reverse:
NSString? stringByApplyingTransform_reverse_(
NSString transform, bool reverse) {
- final _ret = _objc_msgSend_256(this.pointer,
+ final _ret = _objc_msgSend_221(this.pointer,
_sel_stringByApplyingTransform_reverse_, transform.pointer, reverse);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// writeToURL:atomically:encoding:error:
bool writeToURL_atomically_encoding_error_(NSURL url, bool useAuxiliaryFile,
int enc, ffi.Pointer> error) {
- return _objc_msgSend_257(
+ return _objc_msgSend_222(
this.pointer,
_sel_writeToURL_atomically_encoding_error_,
url.pointer,
@@ -1227,12 +1379,13 @@ class NSString extends NSObject {
error);
}
+ /// writeToFile:atomically:encoding:error:
bool writeToFile_atomically_encoding_error_(
NSString path,
bool useAuxiliaryFile,
int enc,
ffi.Pointer> error) {
- return _objc_msgSend_258(
+ return _objc_msgSend_223(
this.pointer,
_sel_writeToFile_atomically_encoding_error_,
path.pointer,
@@ -1241,18 +1394,21 @@ class NSString extends NSObject {
error);
}
+ /// description
NSString get description {
final _ret = _objc_msgSend_35(this.pointer, _sel_description);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// hash
int get hash {
return _objc_msgSend_11(this.pointer, _sel_hash);
}
+ /// initWithCharactersNoCopy:length:freeWhenDone:
NSString initWithCharactersNoCopy_length_freeWhenDone_(
ffi.Pointer characters, int length, bool freeBuffer) {
- final _ret = _objc_msgSend_259(
+ final _ret = _objc_msgSend_224(
this.pointer,
_sel_initWithCharactersNoCopy_length_freeWhenDone_,
characters,
@@ -1261,76 +1417,51 @@ class NSString extends NSObject {
return NSString.castFromPointer(_ret, retain: false, release: true);
}
- NSString initWithCharactersNoCopy_length_deallocator_(
- ffi.Pointer chars,
- int len,
- ObjCBlock_ffiVoid_ffiUnsignedShort_ffiUnsignedLong? deallocator) {
- final _ret = _objc_msgSend_260(
- this.pointer,
- _sel_initWithCharactersNoCopy_length_deallocator_,
- chars,
- len,
- deallocator?.pointer ?? ffi.nullptr);
- return NSString.castFromPointer(_ret, retain: false, release: true);
- }
-
+ /// initWithCharacters:length:
NSString initWithCharacters_length_(
ffi.Pointer characters, int length) {
- final _ret = _objc_msgSend_261(
+ final _ret = _objc_msgSend_225(
this.pointer, _sel_initWithCharacters_length_, characters, length);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithUTF8String:
NSString? initWithUTF8String_(ffi.Pointer nullTerminatedCString) {
- final _ret = _objc_msgSend_262(
+ final _ret = _objc_msgSend_226(
this.pointer, _sel_initWithUTF8String_, nullTerminatedCString);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithString:
NSString initWithString_(NSString aString) {
final _ret =
_objc_msgSend_45(this.pointer, _sel_initWithString_, aString.pointer);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithFormat:
NSString initWithFormat_(NSString format) {
final _ret =
_objc_msgSend_45(this.pointer, _sel_initWithFormat_, format.pointer);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
- NSString initWithFormat_arguments_(
- NSString format, ffi.Pointer<__va_list_tag> argList) {
- final _ret = _objc_msgSend_263(
- this.pointer, _sel_initWithFormat_arguments_, format.pointer, argList);
- return NSString.castFromPointer(_ret, retain: true, release: true);
- }
-
+ /// initWithFormat:locale:
NSString initWithFormat_locale_(
NSString format, objc.ObjCObjectBase? locale) {
- final _ret = _objc_msgSend_264(this.pointer, _sel_initWithFormat_locale_,
+ final _ret = _objc_msgSend_227(this.pointer, _sel_initWithFormat_locale_,
format.pointer, locale?.pointer ?? ffi.nullptr);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
- NSString initWithFormat_locale_arguments_(NSString format,
- objc.ObjCObjectBase? locale, ffi.Pointer<__va_list_tag> argList) {
- final _ret = _objc_msgSend_265(
- this.pointer,
- _sel_initWithFormat_locale_arguments_,
- format.pointer,
- locale?.pointer ?? ffi.nullptr,
- argList);
- return NSString.castFromPointer(_ret, retain: true, release: true);
- }
-
+ /// initWithValidatedFormat:validFormatSpecifiers:error:
NSString? initWithValidatedFormat_validFormatSpecifiers_error_(
NSString format,
NSString validFormatSpecifiers,
ffi.Pointer> error) {
- final _ret = _objc_msgSend_266(
+ final _ret = _objc_msgSend_228(
this.pointer,
_sel_initWithValidatedFormat_validFormatSpecifiers_error_,
format.pointer,
@@ -1341,12 +1472,13 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithValidatedFormat:validFormatSpecifiers:locale:error:
NSString? initWithValidatedFormat_validFormatSpecifiers_locale_error_(
NSString format,
NSString validFormatSpecifiers,
objc.ObjCObjectBase? locale,
ffi.Pointer> error) {
- final _ret = _objc_msgSend_267(
+ final _ret = _objc_msgSend_229(
this.pointer,
_sel_initWithValidatedFormat_validFormatSpecifiers_locale_error_,
format.pointer,
@@ -1358,63 +1490,29 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
- NSString? initWithValidatedFormat_validFormatSpecifiers_arguments_error_(
- NSString format,
- NSString validFormatSpecifiers,
- ffi.Pointer<__va_list_tag> argList,
- ffi.Pointer> error) {
- final _ret = _objc_msgSend_268(
- this.pointer,
- _sel_initWithValidatedFormat_validFormatSpecifiers_arguments_error_,
- format.pointer,
- validFormatSpecifiers.pointer,
- argList,
- error);
- return _ret.address == 0
- ? null
- : NSString.castFromPointer(_ret, retain: true, release: true);
- }
-
- NSString?
- initWithValidatedFormat_validFormatSpecifiers_locale_arguments_error_(
- NSString format,
- NSString validFormatSpecifiers,
- objc.ObjCObjectBase? locale,
- ffi.Pointer<__va_list_tag> argList,
- ffi.Pointer> error) {
- final _ret = _objc_msgSend_269(
- this.pointer,
- _sel_initWithValidatedFormat_validFormatSpecifiers_locale_arguments_error_,
- format.pointer,
- validFormatSpecifiers.pointer,
- locale?.pointer ?? ffi.nullptr,
- argList,
- error);
- return _ret.address == 0
- ? null
- : NSString.castFromPointer(_ret, retain: true, release: true);
- }
-
+ /// initWithData:encoding:
NSString? initWithData_encoding_(NSData data, int encoding) {
- final _ret = _objc_msgSend_270(
+ final _ret = _objc_msgSend_230(
this.pointer, _sel_initWithData_encoding_, data.pointer, encoding);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithBytes:length:encoding:
NSString? initWithBytes_length_encoding_(
ffi.Pointer bytes, int len, int encoding) {
- final _ret = _objc_msgSend_271(this.pointer,
+ final _ret = _objc_msgSend_231(this.pointer,
_sel_initWithBytes_length_encoding_, bytes, len, encoding);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithBytesNoCopy:length:encoding:freeWhenDone:
NSString? initWithBytesNoCopy_length_encoding_freeWhenDone_(
ffi.Pointer bytes, int len, int encoding, bool freeBuffer) {
- final _ret = _objc_msgSend_272(
+ final _ret = _objc_msgSend_232(
this.pointer,
_sel_initWithBytesNoCopy_length_encoding_freeWhenDone_,
bytes,
@@ -1426,67 +1524,57 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: false, release: true);
}
- NSString? initWithBytesNoCopy_length_encoding_deallocator_(
- ffi.Pointer bytes,
- int len,
- int encoding,
- ObjCBlock_ffiVoid_ffiVoid_ffiUnsignedLong? deallocator) {
- final _ret = _objc_msgSend_273(
- this.pointer,
- _sel_initWithBytesNoCopy_length_encoding_deallocator_,
- bytes,
- len,
- encoding,
- deallocator?.pointer ?? ffi.nullptr);
- return _ret.address == 0
- ? null
- : NSString.castFromPointer(_ret, retain: false, release: true);
- }
-
+ /// string
static NSString string() {
final _ret = _objc_msgSend_2(_class_NSString, _sel_string);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithString:
static NSString stringWithString_(NSString string) {
final _ret = _objc_msgSend_45(
_class_NSString, _sel_stringWithString_, string.pointer);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithCharacters:length:
static NSString stringWithCharacters_length_(
ffi.Pointer characters, int length) {
- final _ret = _objc_msgSend_261(
+ final _ret = _objc_msgSend_225(
_class_NSString, _sel_stringWithCharacters_length_, characters, length);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithUTF8String:
static NSString? stringWithUTF8String_(
ffi.Pointer nullTerminatedCString) {
- final _ret = _objc_msgSend_262(
+ final _ret = _objc_msgSend_226(
_class_NSString, _sel_stringWithUTF8String_, nullTerminatedCString);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithFormat:
static NSString stringWithFormat_(NSString format) {
final _ret = _objc_msgSend_45(
_class_NSString, _sel_stringWithFormat_, format.pointer);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// localizedStringWithFormat:
static NSString localizedStringWithFormat_(NSString format) {
final _ret = _objc_msgSend_45(
_class_NSString, _sel_localizedStringWithFormat_, format.pointer);
return NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithValidatedFormat:validFormatSpecifiers:error:
static NSString? stringWithValidatedFormat_validFormatSpecifiers_error_(
NSString format,
NSString validFormatSpecifiers,
ffi.Pointer> error) {
- final _ret = _objc_msgSend_266(
+ final _ret = _objc_msgSend_228(
_class_NSString,
_sel_stringWithValidatedFormat_validFormatSpecifiers_error_,
format.pointer,
@@ -1497,12 +1585,13 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// localizedStringWithValidatedFormat:validFormatSpecifiers:error:
static NSString?
localizedStringWithValidatedFormat_validFormatSpecifiers_error_(
NSString format,
NSString validFormatSpecifiers,
ffi.Pointer> error) {
- final _ret = _objc_msgSend_266(
+ final _ret = _objc_msgSend_228(
_class_NSString,
_sel_localizedStringWithValidatedFormat_validFormatSpecifiers_error_,
format.pointer,
@@ -1513,54 +1602,60 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithCString:encoding:
NSString? initWithCString_encoding_(
ffi.Pointer nullTerminatedCString, int encoding) {
- final _ret = _objc_msgSend_274(this.pointer, _sel_initWithCString_encoding_,
+ final _ret = _objc_msgSend_233(this.pointer, _sel_initWithCString_encoding_,
nullTerminatedCString, encoding);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithCString:encoding:
static NSString? stringWithCString_encoding_(
ffi.Pointer cString, int enc) {
- final _ret = _objc_msgSend_274(
+ final _ret = _objc_msgSend_233(
_class_NSString, _sel_stringWithCString_encoding_, cString, enc);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithContentsOfURL:encoding:error:
NSString? initWithContentsOfURL_encoding_error_(
NSURL url, int enc, ffi.Pointer> error) {
- final _ret = _objc_msgSend_275(this.pointer,
+ final _ret = _objc_msgSend_234(this.pointer,
_sel_initWithContentsOfURL_encoding_error_, url.pointer, enc, error);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithContentsOfFile:encoding:error:
NSString? initWithContentsOfFile_encoding_error_(
NSString path, int enc, ffi.Pointer> error) {
- final _ret = _objc_msgSend_276(this.pointer,
+ final _ret = _objc_msgSend_235(this.pointer,
_sel_initWithContentsOfFile_encoding_error_, path.pointer, enc, error);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithContentsOfURL:encoding:error:
static NSString? stringWithContentsOfURL_encoding_error_(
NSURL url, int enc, ffi.Pointer> error) {
- final _ret = _objc_msgSend_275(_class_NSString,
+ final _ret = _objc_msgSend_234(_class_NSString,
_sel_stringWithContentsOfURL_encoding_error_, url.pointer, enc, error);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithContentsOfFile:encoding:error:
static NSString? stringWithContentsOfFile_encoding_error_(
NSString path, int enc, ffi.Pointer> error) {
- final _ret = _objc_msgSend_276(
+ final _ret = _objc_msgSend_235(
_class_NSString,
_sel_stringWithContentsOfFile_encoding_error_,
path.pointer,
@@ -1571,11 +1666,12 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithContentsOfURL:usedEncoding:error:
NSString? initWithContentsOfURL_usedEncoding_error_(
NSURL url,
ffi.Pointer enc,
ffi.Pointer> error) {
- final _ret = _objc_msgSend_277(
+ final _ret = _objc_msgSend_236(
this.pointer,
_sel_initWithContentsOfURL_usedEncoding_error_,
url.pointer,
@@ -1586,11 +1682,12 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// initWithContentsOfFile:usedEncoding:error:
NSString? initWithContentsOfFile_usedEncoding_error_(
NSString path,
ffi.Pointer enc,
ffi.Pointer> error) {
- final _ret = _objc_msgSend_278(
+ final _ret = _objc_msgSend_237(
this.pointer,
_sel_initWithContentsOfFile_usedEncoding_error_,
path.pointer,
@@ -1601,11 +1698,12 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithContentsOfURL:usedEncoding:error:
static NSString? stringWithContentsOfURL_usedEncoding_error_(
NSURL url,
ffi.Pointer enc,
ffi.Pointer> error) {
- final _ret = _objc_msgSend_277(
+ final _ret = _objc_msgSend_236(
_class_NSString,
_sel_stringWithContentsOfURL_usedEncoding_error_,
url.pointer,
@@ -1616,11 +1714,12 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringWithContentsOfFile:usedEncoding:error:
static NSString? stringWithContentsOfFile_usedEncoding_error_(
NSString path,
ffi.Pointer enc,
ffi.Pointer> error) {
- final _ret = _objc_msgSend_278(
+ final _ret = _objc_msgSend_237(
_class_NSString,
_sel_stringWithContentsOfFile_usedEncoding_error_,
path.pointer,
@@ -1631,13 +1730,14 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringEncodingForData:encodingOptions:convertedString:usedLossyConversion:
static int
stringEncodingForData_encodingOptions_convertedString_usedLossyConversion_(
NSData data,
NSDictionary? opts,
ffi.Pointer> string,
ffi.Pointer usedLossyConversion) {
- return _objc_msgSend_279(
+ return _objc_msgSend_238(
_class_NSString,
_sel_stringEncodingForData_encodingOptions_convertedString_usedLossyConversion_,
data.pointer,
@@ -1646,43 +1746,51 @@ class NSString extends NSObject {
usedLossyConversion);
}
+ /// propertyList
objc.ObjCObjectBase propertyList() {
final _ret = _objc_msgSend_2(this.pointer, _sel_propertyList);
return objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// propertyListFromStringsFileFormat
NSDictionary? propertyListFromStringsFileFormat() {
final _ret =
- _objc_msgSend_280(this.pointer, _sel_propertyListFromStringsFileFormat);
+ _objc_msgSend_239(this.pointer, _sel_propertyListFromStringsFileFormat);
return _ret.address == 0
? null
: NSDictionary.castFromPointer(_ret, retain: true, release: true);
}
+ /// cString
ffi.Pointer cString() {
return _objc_msgSend_14(this.pointer, _sel_cString);
}
+ /// lossyCString
ffi.Pointer lossyCString() {
return _objc_msgSend_14(this.pointer, _sel_lossyCString);
}
+ /// cStringLength
int cStringLength() {
return _objc_msgSend_11(this.pointer, _sel_cStringLength);
}
+ /// getCString:
void getCString_(ffi.Pointer bytes) {
- _objc_msgSend_281(this.pointer, _sel_getCString_, bytes);
+ _objc_msgSend_240(this.pointer, _sel_getCString_, bytes);
}
+ /// getCString:maxLength:
void getCString_maxLength_(ffi.Pointer bytes, int maxLength) {
- _objc_msgSend_282(
+ _objc_msgSend_241(
this.pointer, _sel_getCString_maxLength_, bytes, maxLength);
}
+ /// getCString:maxLength:range:remainingRange:
void getCString_maxLength_range_remainingRange_(ffi.Pointer bytes,
- int maxLength, _NSRange aRange, ffi.Pointer<_NSRange> leftoverRange) {
- _objc_msgSend_283(
+ int maxLength, NSRange aRange, ffi.Pointer leftoverRange) {
+ _objc_msgSend_242(
this.pointer,
_sel_getCString_maxLength_range_remainingRange_,
bytes,
@@ -1691,16 +1799,19 @@ class NSString extends NSObject {
leftoverRange);
}
+ /// writeToFile:atomically:
bool writeToFile_atomically_(NSString path, bool useAuxiliaryFile) {
return _objc_msgSend_40(this.pointer, _sel_writeToFile_atomically_,
path.pointer, useAuxiliaryFile);
}
+ /// writeToURL:atomically:
bool writeToURL_atomically_(NSURL url, bool atomically) {
- return _objc_msgSend_160(
+ return _objc_msgSend_135(
this.pointer, _sel_writeToURL_atomically_, url.pointer, atomically);
}
+ /// initWithContentsOfFile:
objc.ObjCObjectBase? initWithContentsOfFile_(NSString path) {
final _ret = _objc_msgSend_52(
this.pointer, _sel_initWithContentsOfFile_, path.pointer);
@@ -1709,14 +1820,16 @@ class NSString extends NSObject {
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// initWithContentsOfURL:
objc.ObjCObjectBase? initWithContentsOfURL_(NSURL url) {
- final _ret = _objc_msgSend_219(
+ final _ret = _objc_msgSend_187(
this.pointer, _sel_initWithContentsOfURL_, url.pointer);
return _ret.address == 0
? null
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// stringWithContentsOfFile:
static objc.ObjCObjectBase? stringWithContentsOfFile_(NSString path) {
final _ret = _objc_msgSend_52(
_class_NSString, _sel_stringWithContentsOfFile_, path.pointer);
@@ -1725,17 +1838,19 @@ class NSString extends NSObject {
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// stringWithContentsOfURL:
static objc.ObjCObjectBase? stringWithContentsOfURL_(NSURL url) {
- final _ret = _objc_msgSend_219(
+ final _ret = _objc_msgSend_187(
_class_NSString, _sel_stringWithContentsOfURL_, url.pointer);
return _ret.address == 0
? null
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// initWithCStringNoCopy:length:freeWhenDone:
objc.ObjCObjectBase? initWithCStringNoCopy_length_freeWhenDone_(
ffi.Pointer bytes, int length, bool freeBuffer) {
- final _ret = _objc_msgSend_284(
+ final _ret = _objc_msgSend_243(
this.pointer,
_sel_initWithCStringNoCopy_length_freeWhenDone_,
bytes,
@@ -1746,46 +1861,52 @@ class NSString extends NSObject {
: objc.ObjCObjectBase(_ret, retain: false, release: true);
}
+ /// initWithCString:length:
objc.ObjCObjectBase? initWithCString_length_(
ffi.Pointer bytes, int length) {
- final _ret = _objc_msgSend_274(
+ final _ret = _objc_msgSend_233(
this.pointer, _sel_initWithCString_length_, bytes, length);
return _ret.address == 0
? null
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// initWithCString:
objc.ObjCObjectBase? initWithCString_(ffi.Pointer bytes) {
- final _ret = _objc_msgSend_262(this.pointer, _sel_initWithCString_, bytes);
+ final _ret = _objc_msgSend_226(this.pointer, _sel_initWithCString_, bytes);
return _ret.address == 0
? null
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// stringWithCString:length:
static objc.ObjCObjectBase? stringWithCString_length_(
ffi.Pointer bytes, int length) {
- final _ret = _objc_msgSend_274(
+ final _ret = _objc_msgSend_233(
_class_NSString, _sel_stringWithCString_length_, bytes, length);
return _ret.address == 0
? null
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// stringWithCString:
static objc.ObjCObjectBase? stringWithCString_(ffi.Pointer bytes) {
final _ret =
- _objc_msgSend_262(_class_NSString, _sel_stringWithCString_, bytes);
+ _objc_msgSend_226(_class_NSString, _sel_stringWithCString_, bytes);
return _ret.address == 0
? null
: objc.ObjCObjectBase(_ret, retain: true, release: true);
}
+ /// getCharacters:
void getCharacters_(ffi.Pointer buffer) {
- _objc_msgSend_285(this.pointer, _sel_getCharacters_, buffer);
+ _objc_msgSend_244(this.pointer, _sel_getCharacters_, buffer);
}
+ /// stringByAddingPercentEncodingWithAllowedCharacters:
NSString? stringByAddingPercentEncodingWithAllowedCharacters_(
NSCharacterSet allowedCharacters) {
- final _ret = _objc_msgSend_286(
+ final _ret = _objc_msgSend_245(
this.pointer,
_sel_stringByAddingPercentEncodingWithAllowedCharacters_,
allowedCharacters.pointer);
@@ -1794,6 +1915,7 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByRemovingPercentEncoding
NSString? get stringByRemovingPercentEncoding {
final _ret =
_objc_msgSend_58(this.pointer, _sel_stringByRemovingPercentEncoding);
@@ -1802,32 +1924,37 @@ class NSString extends NSObject {
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByAddingPercentEscapesUsingEncoding:
NSString? stringByAddingPercentEscapesUsingEncoding_(int enc) {
- final _ret = _objc_msgSend_287(
+ final _ret = _objc_msgSend_246(
this.pointer, _sel_stringByAddingPercentEscapesUsingEncoding_, enc);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// stringByReplacingPercentEscapesUsingEncoding:
NSString? stringByReplacingPercentEscapesUsingEncoding_(int enc) {
- final _ret = _objc_msgSend_287(
+ final _ret = _objc_msgSend_246(
this.pointer, _sel_stringByReplacingPercentEscapesUsingEncoding_, enc);
return _ret.address == 0
? null
: NSString.castFromPointer(_ret, retain: true, release: true);
}
+ /// new
static NSString new1() {
final _ret = _objc_msgSend_2(_class_NSString, _sel_new);
return NSString.castFromPointer(_ret, retain: false, release: true);
}
+ /// allocWithZone:
static NSString allocWithZone_(ffi.Pointer<_NSZone> zone) {
final _ret = _objc_msgSend_3(_class_NSString, _sel_allocWithZone_, zone);
return NSString.castFromPointer(_ret, retain: false, release: true);
}
+ /// alloc
static NSString alloc() {
final _ret = _objc_msgSend_2(_class_NSString, _sel_alloc);
return NSString.castFromPointer(_ret, retain: false, release: true);
@@ -1846,6 +1973,7 @@ final _objc_msgSend_16 = objc.msgSendPointer
int Function(ffi.Pointer,
ffi.Pointer, int)>();
+/// NSCoder
class NSCoder extends objc.ObjCObjectBase {
NSCoder._(ffi.Pointer pointer,
{bool retain = false, bool release = false})
@@ -1889,7 +2017,7 @@ final _objc_msgSend_18 = objc.msgSendPointer
ffi.Pointer, int)>();
late final _sel_substringToIndex_ = objc.registerName("substringToIndex:");
-final class _NSRange extends ffi.Struct {
+final class NSRange extends ffi.Struct {
@ffi.UnsignedLong()
external int location;
@@ -1902,10 +2030,10 @@ final _objc_msgSend_19 = objc.msgSendPointer
.cast<
ffi.NativeFunction<
ffi.Pointer Function(ffi.Pointer,
- ffi.Pointer, _NSRange)>>()
+ ffi.Pointer, NSRange)>>()
.asFunction<
ffi.Pointer Function(ffi.Pointer,
- ffi.Pointer, _NSRange)>();
+ ffi.Pointer, NSRange)>();
late final _sel_getCharacters_range_ =
objc.registerName("getCharacters:range:");
final _objc_msgSend_20 = objc.msgSendPointer
@@ -1915,25 +2043,36 @@ final _objc_msgSend_20 = objc.msgSendPointer
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- _NSRange)>>()
+ NSRange)>>()
.asFunction<
void Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- _NSRange)>();
-
-abstract class NSComparisonResult {
- static const int NSOrderedAscending = -1;
- static const int NSOrderedSame = 0;
- static const int NSOrderedDescending = 1;
+ NSRange)>();
+
+enum NSComparisonResult {
+ NSOrderedAscending(-1),
+ NSOrderedSame(0),
+ NSOrderedDescending(1);
+
+ final int value;
+ const NSComparisonResult(this.value);
+
+ static NSComparisonResult fromValue(int value) => switch (value) {
+ -1 => NSOrderedAscending,
+ 0 => NSOrderedSame,
+ 1 => NSOrderedDescending,
+ _ =>
+ throw ArgumentError("Unknown value for NSComparisonResult: $value"),
+ };
}
late final _sel_compare_ = objc.registerName("compare:");
final _objc_msgSend_21 = objc.msgSendPointer
.cast<
ffi.NativeFunction<
- ffi.Int32 Function(
+ ffi.Long Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer)>>()
@@ -1941,27 +2080,44 @@ final _objc_msgSend_21 = objc.msgSendPointer
int Function(ffi.Pointer,
ffi.Pointer, ffi.Pointer)>();
-abstract class NSStringCompareOptions {
- static const int NSCaseInsensitiveSearch = 1;
- static const int NSLiteralSearch = 2;
- static const int NSBackwardsSearch = 4;
- static const int NSAnchoredSearch = 8;
- static const int NSNumericSearch = 64;
- static const int NSDiacriticInsensitiveSearch = 128;
- static const int NSWidthInsensitiveSearch = 256;
- static const int NSForcedOrderingSearch = 512;
- static const int NSRegularExpressionSearch = 1024;
+enum NSStringCompareOptions {
+ NSCaseInsensitiveSearch(1),
+ NSLiteralSearch(2),
+ NSBackwardsSearch(4),
+ NSAnchoredSearch(8),
+ NSNumericSearch(64),
+ NSDiacriticInsensitiveSearch(128),
+ NSWidthInsensitiveSearch(256),
+ NSForcedOrderingSearch(512),
+ NSRegularExpressionSearch(1024);
+
+ final int value;
+ const NSStringCompareOptions(this.value);
+
+ static NSStringCompareOptions fromValue(int value) => switch (value) {
+ 1 => NSCaseInsensitiveSearch,
+ 2 => NSLiteralSearch,
+ 4 => NSBackwardsSearch,
+ 8 => NSAnchoredSearch,
+ 64 => NSNumericSearch,
+ 128 => NSDiacriticInsensitiveSearch,
+ 256 => NSWidthInsensitiveSearch,
+ 512 => NSForcedOrderingSearch,
+ 1024 => NSRegularExpressionSearch,
+ _ => throw ArgumentError(
+ "Unknown value for NSStringCompareOptions: $value"),
+ };
}
late final _sel_compare_options_ = objc.registerName("compare:options:");
final _objc_msgSend_22 = objc.msgSendPointer
.cast<
ffi.NativeFunction<
- ffi.Int32 Function(
+ ffi.Long Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- ffi.Int32)>>()
+ ffi.UnsignedLong)>>()
.asFunction<
int Function(
ffi.Pointer,
@@ -1973,30 +2129,30 @@ late final _sel_compare_options_range_ =
final _objc_msgSend_23 = objc.msgSendPointer
.cast<
ffi.NativeFunction<
- ffi.Int32 Function(
+ ffi.Long Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- ffi.Int32,
- _NSRange)>>()
+ ffi.UnsignedLong,
+ NSRange)>>()
.asFunction<
int Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
int,
- _NSRange)>();
+ NSRange)>();
late final _sel_compare_options_range_locale_ =
objc.registerName("compare:options:range:locale:");
final _objc_msgSend_24 = objc.msgSendPointer
.cast<
ffi.NativeFunction<
- ffi.Int32 Function(
+ ffi.Long Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- ffi.Int32,
- _NSRange,
+ ffi.UnsignedLong,
+ NSRange,
ffi.Pointer)>>()
.asFunction<
int Function(
@@ -2004,7 +2160,7 @@ final _objc_msgSend_24 = objc.msgSendPointer
ffi.Pointer,
ffi.Pointer,
int,
- _NSRange,
+ NSRange,
ffi.Pointer)>();
late final _sel_caseInsensitiveCompare_ =
objc.registerName("caseInsensitiveCompare:");
@@ -2035,7 +2191,7 @@ final _objc_msgSend_26 = objc.msgSendPointer
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- ffi.Int32)>>()
+ ffi.UnsignedLong)>>()
.asFunction<
ffi.Pointer Function(
ffi.Pointer,
@@ -2052,23 +2208,23 @@ late final _sel_localizedStandardRangeOfString_ =
final _objc_msgSend_27 = objc.msgSendPointer
.cast<
ffi.NativeFunction<
- _NSRange Function(
+ NSRange Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer)>>()
.asFunction<
- _NSRange Function(ffi.Pointer,
+ NSRange Function(ffi.Pointer,
ffi.Pointer, ffi.Pointer)>();
final _objc_msgSend_27Stret = objc.msgSendStretPointer
.cast<
ffi.NativeFunction<
ffi.Void Function(
- ffi.Pointer<_NSRange>,
+ ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
ffi.Pointer)>>()
.asFunction<
- void Function(ffi.Pointer<_NSRange>, ffi.Pointer,
+ void Function(ffi.Pointer, ffi.Pointer,
ffi.Pointer, ffi.Pointer)>();
late final _sel_rangeOfString_ = objc.registerName("rangeOfString:");
late final _sel_rangeOfString_options_ =
@@ -2076,13 +2232,13 @@ late final _sel_rangeOfString_options_ =
final _objc_msgSend_28 = objc.msgSendPointer
.cast<
ffi.NativeFunction<
- _NSRange Function(
+ NSRange Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- ffi.Int32)>>()
+ ffi.UnsignedLong)>>()
.asFunction<
- _NSRange Function(
+ NSRange Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
@@ -2091,14 +2247,14 @@ final _objc_msgSend_28Stret = objc.msgSendStretPointer
.cast<
ffi.NativeFunction<
ffi.Void Function(
- ffi.Pointer<_NSRange>,
+ ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- ffi.Int32)>>()
+ ffi.UnsignedLong)>>()
.asFunction<
void Function(
- ffi.Pointer<_NSRange>,
+ ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
@@ -2108,38 +2264,39 @@ late final _sel_rangeOfString_options_range_ =
final _objc_msgSend_29 = objc.msgSendPointer
.cast<
ffi.NativeFunction<
- _NSRange Function(
+ NSRange Function(
ffi.Pointer,
ffi.Pointer,
ffi.Pointer,
- ffi.Int32,
- _NSRange)>>()
+ ffi.UnsignedLong,
+ NSRange)>>()
.asFunction<
- _NSRange Function(
+ NSRange Function(
ffi.Pointer,
ffi.Pointer