Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion pkgs/code_assets/test/code_assets/config_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ void main() async {
late Uri fakeVcVars;

setUp(() async {
final tempUri = Directory.systemTemp.uri;
final tempUri =
(await Directory.systemTemp.createTemp('code assets config temp '))
.uri;
outFile = tempUri.resolve('output.json');
outputDirectoryShared = tempUri.resolve('out_shared1/');
packageName = 'my_package';
Expand Down
3 changes: 2 additions & 1 deletion pkgs/code_assets/test/code_assets/validation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ void main() {
late Uri packageRootUri;

setUp(() async {
tempUri = (await Directory.systemTemp.createTemp()).uri;
tempUri =
(await Directory.systemTemp.createTemp('code assets temp ')).uri;
outDirUri = tempUri.resolve('out/');
await Directory.fromUri(outDirUri).create();
outDirSharedUri = tempUri.resolve('out_shared/');
Expand Down
3 changes: 2 additions & 1 deletion pkgs/data_assets/test/data_assets/validation_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ void main() {
late Uri packageRootUri;

setUp(() async {
tempUri = (await Directory.systemTemp.createTemp()).uri;
tempUri =
(await Directory.systemTemp.createTemp('data assets temp ')).uri;
outDirUri = tempUri.resolve('out/');
await Directory.fromUri(outDirUri).create();
outDirSharedUri = tempUri.resolve('out_shared/');
Expand Down
Binary file added pkgs/ffigen/analyze.txt
Binary file not shown.
8 changes: 7 additions & 1 deletion pkgs/ffigen/lib/src/code_generator/binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// 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 '../config_provider/config_types.dart' show Declaration;
import '../config_provider/declaration.dart';
import '../visitor/ast.dart';
import 'binding_string.dart';
import 'scope.dart';
Expand Down Expand Up @@ -90,6 +90,10 @@ abstract class LookUpBinding extends Binding {
bool get loadFromNativeAsset;
}



// ... existing code ...

/// Base class for bindings which don't look up symbols in dynamic library.
abstract class NoLookUpBinding extends Binding {
NoLookUpBinding({
Expand All @@ -106,3 +110,5 @@ abstract class NoLookUpBinding extends Binding {
@override
void visit(Visitation visitation) => visitation.visitNoLookUpBinding(this);
}


31 changes: 27 additions & 4 deletions pkgs/ffigen/lib/src/code_generator/objc_block.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,16 @@
// 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 '../code_generator.dart';
import 'binding.dart';
import 'func.dart';
import 'func_type.dart';
import 'objc_built_in_functions.dart';
import 'objc_interface.dart';
import 'objc_protocol.dart';
import 'pointer.dart';
import 'type.dart';
import '../context.dart';
import '../header_parser/sub_parsers/api_availability.dart';
import '../strings.dart' as strings;
import '../visitor/ast.dart';

Expand Down Expand Up @@ -447,7 +455,7 @@ ref.pointer.ref.invoke.cast<${_helper.trampNatFnCType}>()
return '''

typedef ${returnType.getNativeType()} (^$listenerName)($declArgStr);
__attribute__((visibility("default"))) __attribute__((used))
__attribute__((visibility("default"))) __attribute__((used)) ${availability.attribute}
$listenerName $listenerWrapper($listenerName block) NS_RETURNS_RETAINED {
return ^void($argStr) {
${generateRetain('block')};
Expand All @@ -456,7 +464,7 @@ $listenerName $listenerWrapper($listenerName block) NS_RETURNS_RETAINED {
}

typedef ${returnType.getNativeType()} (^$blockingName)($blockingArgStr);
__attribute__((visibility("default"))) __attribute__((used))
__attribute__((visibility("default"))) __attribute__((used)) ${availability.attribute}
$listenerName $blockingWrapper(
$blockingName block, $blockingName listenerBlock,
DOBJC_Context* ctx) NS_RETURNS_RETAINED {
Expand Down Expand Up @@ -498,13 +506,28 @@ $listenerName $blockingWrapper(
return '''

typedef $ret (^$block)($argRecv);
__attribute__((visibility("default"))) __attribute__((used))
__attribute__((visibility("default"))) __attribute__((used)) ${availability.attribute}
$ret $fnName(id target, $argRecv) {
return $blkGetter($argPass);
}
''';
}

@override
ApiAvailability get availability {
var avail = _getAvailability(returnType);
for (final p in params) {
avail = ApiAvailability.union(avail, _getAvailability(p.type));
}
return avail;
}

ApiAvailability _getAvailability(Type t) {
if (t is ObjCInterface) return t.apiAvailability;
if (t is ObjCBlock) return t.availability;
return ApiAvailability(externalVersions: null);
}

@override
String getCType(Context context) =>
PointerType(objCBlockType).getCType(context);
Expand Down
3 changes: 3 additions & 0 deletions pkgs/ffigen/lib/src/code_generator/objc_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ class ObjCInterface extends BindingType with ObjCMethods, HasLocalScope {

bool get unavailable => apiAvailability.availability == Availability.none;

@override
ApiAvailability get availability => apiAvailability;

@override
BindingString toBindingString(Writer w) {
final context = w.context;
Expand Down
144 changes: 144 additions & 0 deletions pkgs/ffigen/lib/src/code_generator/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ abstract class Type extends AstNode {
/// as getFfiDartType. For ObjC bindings this refers to the wrapper object.
String getDartType(Context context) => getFfiDartType(context);



/// Returns the type to be used if this type appears in an ObjC block
/// signature. By default it's the same as [getCType]. But for some types
/// that's not enough to distinguish them (eg all ObjC objects have a C type
Expand Down Expand Up @@ -246,6 +248,10 @@ abstract class BindingType extends NoLookUpBinding implements Type {
void visit(Visitation visitation) => visitation.visitBindingType(this);
}





/// Represents an unimplemented type. Used as a marker, so that declarations
/// having these can exclude them.
class UnimplementedType extends Type {
Expand All @@ -258,3 +264,141 @@ class UnimplementedType extends Type {
@override
bool get sameFfiDartAndCType => true;
}

/// Represents the `void` type.
final voidType = NativeType(SupportedNativeType.voidType);

/// Represents the `char` type.
final charType = NativeType(SupportedNativeType.char);

/// Represents the `signed char` type.
final signedCharType = NativeType(SupportedNativeType.int8);

/// Represents the `unsigned char` type.
final unsignedCharType = NativeType(SupportedNativeType.uint8);

/// Represents the `short` type.
final shortType = NativeType(SupportedNativeType.int16);

/// Represents the `unsigned short` type.
final unsignedShortType = NativeType(SupportedNativeType.uint16);

/// Represents the `int` type.
final intType = NativeType(SupportedNativeType.int32);

/// Represents the `unsigned int` type.
final unsignedIntType = NativeType(SupportedNativeType.uint32);

/// Represents the `long` type.
final longType = NativeType(SupportedNativeType.int64);

/// Represents the `unsigned long` type.
final unsignedLongType = NativeType(SupportedNativeType.uint64);

/// Represents the `long long` type.
final longLongType = NativeType(SupportedNativeType.int64);

/// Represents the `unsigned long long` type.
final unsignedLongLongType = NativeType(SupportedNativeType.uint64);

/// Represents the `float` type.
final floatType = NativeType(SupportedNativeType.float);

/// Represents the `double` type.
final doubleType = NativeType(SupportedNativeType.double);

/// Represents the `size_t` type.
final sizeType = NativeType(SupportedNativeType.intPtr);

/// Represents the `wchar_t` type.
final wCharType = NativeType(SupportedNativeType.int32);

/// Represents the `intptr_t` type.
final intPtrType = NativeType(SupportedNativeType.intPtr);

/// Represents the `uintptr_t` type.
final uintPtrType = NativeType(SupportedNativeType.uintPtr);

/// Represents the `id` type.
final objCObjectType = ObjCObjectType();

/// Represents the `void (^)(void)` type.
///
/// This is used as a placeholder for any block type.
final objCBlockType = ObjCBlockType();

class ObjCObjectType extends Type {
const ObjCObjectType();

@override
String getCType(Context context) =>
ObjCBuiltInFunctions.objectBase.gen(context);

@override
String getFfiDartType(Context context) => getCType(context);

@override
String getNativeType({String varName = ''}) => 'id $varName';

@override
bool get sameFfiDartAndCType => true;

@override
String toString() => 'id';

@override
String cacheKey() => 'id';

@override
bool get sameDartAndFfiDartType => true;

@override
bool get sameDartAndCType => true;

@override
String convertDartTypeToFfiDartType(Context context, String value, {required bool objCRetain, required bool objCAutorelease}) => value;

@override
String convertFfiDartTypeToDartType(Context context, String value, {required bool objCRetain, String? objCEnclosingClass}) => value;

@override
String? generateRetain(String value) => null;
}

class ObjCBlockType extends Type {
const ObjCBlockType();

@override
String getCType(Context context) =>
ObjCBuiltInFunctions.blockType.gen(context);

@override
String getFfiDartType(Context context) => getCType(context);

@override
String getNativeType({String varName = ''}) => 'void (^$varName)(void)';

@override
bool get sameFfiDartAndCType => true;

@override
String toString() => 'Block';

@override
String cacheKey() => 'Block';

@override
bool get sameDartAndFfiDartType => true;

@override
bool get sameDartAndCType => true;

@override
String convertDartTypeToFfiDartType(Context context, String value, {required bool objCRetain, required bool objCAutorelease}) => value;

@override
String convertFfiDartTypeToDartType(Context context, String value, {required bool objCRetain, String? objCEnclosingClass}) => value;

@override
String? generateRetain(String value) => null;
}
6 changes: 4 additions & 2 deletions pkgs/ffigen/lib/src/config_provider/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ final class Declarations {

/// A function to pass to [rename] that doesn't rename the declaration.
static String useOriginalName(Declaration declaration) =>
declaration.originalName;
declaration.originalName ?? '';

/// A function to pass to [rename] that applies a rename map.
///
Expand All @@ -220,7 +220,9 @@ final class Declarations {
Map<String, String> renames,
) =>
(Declaration declaration) =>
renames[declaration.originalName] ?? declaration.originalName;
declaration.originalName == null
? ''
: (renames[declaration.originalName!] ?? declaration.originalName!);

/// Returns a new name for the member of the declaration, to replace its
/// `originalName`.
Expand Down
54 changes: 18 additions & 36 deletions pkgs/ffigen/lib/src/config_provider/config_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import 'package:quiver/pattern.dart' as quiver;

import '../code_generator.dart';
import 'config.dart';
import 'declaration.dart';
import 'path_finder.dart';

export 'package:pub_semver/pub_semver.dart' show Version;
Expand Down Expand Up @@ -128,23 +129,33 @@ final class YamlDeclarationFilters {

/// Applies renaming and returns the result.
String rename(Declaration declaration) =>
_renamer.rename(declaration.originalName);
declaration.originalName == null
? ''
: _renamer.rename(declaration.originalName!);

/// Applies member renaming and returns the result.
String renameMember(Declaration declaration, String member) =>
_memberRenamer.rename(declaration.originalName, member);
declaration.originalName == null
? member
: _memberRenamer.rename(declaration.originalName!, member);

/// Checks if a name is allowed by a filter.
bool shouldInclude(Declaration declaration) =>
_includer.shouldInclude(declaration.originalName, excludeAllByDefault);
declaration.originalName == null
? false
: _includer.shouldInclude(declaration.originalName!, excludeAllByDefault);

/// Checks if the symbol address should be included for this name.
bool shouldIncludeSymbolAddress(Declaration declaration) =>
_symbolAddressIncluder.shouldInclude(declaration.originalName);
declaration.originalName == null
? false
: _symbolAddressIncluder.shouldInclude(declaration.originalName!);

/// Checks if a member is allowed by a filter.
bool shouldIncludeMember(Declaration declaration, String member) =>
_memberIncluder.shouldInclude(declaration.originalName, member);
declaration.originalName == null
? true
: _memberIncluder.shouldInclude(declaration.originalName!, member);

Declarations configAdapter() {
return Declarations(
Expand Down Expand Up @@ -467,34 +478,5 @@ class PackingValue {
}

/// A declaration, such as a function or a class.
class Declaration {
/// A unique identifier for the declaration.
///
/// USR stands for Unified Symbol Resolution. It is an ID generated by clang
/// that is designed to be unique, and stable across compilations, but not
/// human readable.
///
/// It's usually easiest to filter the declaration by the [originalName]. But
/// the name alone might not be unique. If you have two different declarations
/// with the same [originalName], log their [usr]s, and use that to make your
/// filtering more specific.
final String usr;

/// The original name of the declaration in source code, before any renaming.
final String originalName;

Declaration({required this.usr, required this.originalName});
}

class ExternalVersions {
final Versions? ios;
final Versions? macos;
const ExternalVersions({this.ios, this.macos});
}

class Versions {
final Version? min;
final Version? max;

const Versions({this.min, this.max});
}
export 'declaration.dart';
export 'external_versions.dart';
Loading
Loading