Skip to content
Open
Show file tree
Hide file tree
Changes from all 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