blob: d93de90c6cd511dbc77cb9b7cd8049d848a8c13e [file] [log] [blame]
// Copyright (c) 2022, 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 '../context.dart';
import '../visitor/ast.dart';
import 'type.dart';
/// A library import which will be written as an import in the generated file.
class LibraryImport extends AstNode {
final String name;
final String _importPath;
final String? _importPathWhenImportedByPackageObjC;
const LibraryImport(
this.name,
this._importPath, {
String? importPathWhenImportedByPackageObjC,
}) : _importPathWhenImportedByPackageObjC =
importPathWhenImportedByPackageObjC;
@override
bool operator ==(Object other) {
return other is LibraryImport && name == other.name;
}
@override
int get hashCode => name.hashCode;
// The import path, which may be different if this library is being imported
// into package:objective_c's generated code.
String importPath(bool generateForPackageObjectiveC) {
if (!generateForPackageObjectiveC) return _importPath;
return _importPathWhenImportedByPackageObjC ?? _importPath;
}
@override
String toString() => '$name $_importPath';
@override
void visit(Visitation visitation) => visitation.visitLibraryImport(this);
}
/// An imported type which will be used in the generated code.
class ImportedType extends Type {
final LibraryImport libraryImport;
final String cType;
final String dartType;
final String nativeType;
final String? defaultValue;
/// Whether the [dartType] is an import from the [libraryImport].
final bool importedDartType;
ImportedType(
this.libraryImport,
this.cType,
this.dartType,
this.nativeType, {
this.defaultValue,
this.importedDartType = false,
});
@override
String getCType(Context context) =>
'${context.libs.prefix(libraryImport)}.$cType';
@override
String getFfiDartType(Context context) {
if (importedDartType) {
return '${context.libs.prefix(libraryImport)}.$dartType';
} else {
return cType == dartType ? getCType(context) : dartType;
}
}
@override
String getNativeType({String varName = ''}) => '$nativeType $varName';
@override
bool get sameFfiDartAndCType => cType == dartType;
@override
String toString() => '${libraryImport.name}.$cType';
@override
String? getDefaultValue(Context context) => defaultValue;
@override
void visit(Visitation visitation) => visitation.visitImportedType(this);
@override
void visitChildren(Visitor visitor) {
super.visitChildren(visitor);
visitor.visit(libraryImport);
}
}
/// An unchecked type similar to [ImportedType] which exists in the generated
/// binding itself.
class SelfImportedType extends Type {
final String cType;
final String dartType;
final String? defaultValue;
SelfImportedType(this.cType, this.dartType, [this.defaultValue]);
@override
String getCType(Context context) => cType;
@override
String getFfiDartType(Context context) => dartType;
@override
bool get sameFfiDartAndCType => cType == dartType;
@override
String toString() => cType;
}
const ffiImport = LibraryImport('ffi', 'dart:ffi');
const ffiPkgImport = LibraryImport('pkg_ffi', 'package:ffi/ffi.dart');
const objcPkgImport = LibraryImport(
'objc',
'package:objective_c/objective_c.dart',
importPathWhenImportedByPackageObjC: '../objective_c.dart',
);
const selfImport = LibraryImport('self', '');
final builtInLibraries = {
for (final l in [ffiImport, ffiPkgImport, objcPkgImport, selfImport])
l.name: l,
};
final voidType = ImportedType(ffiImport, 'Void', 'void', 'void');
final unsignedCharType = ImportedType(
ffiImport,
'UnsignedChar',
'int',
'unsigned char',
defaultValue: '0',
);
final signedCharType = ImportedType(
ffiImport,
'SignedChar',
'int',
'char',
defaultValue: '0',
);
final charType = ImportedType(
ffiImport,
'Char',
'int',
'char',
defaultValue: '0',
);
final unsignedShortType = ImportedType(
ffiImport,
'UnsignedShort',
'int',
'unsigned short',
defaultValue: '0',
);
final shortType = ImportedType(
ffiImport,
'Short',
'int',
'short',
defaultValue: '0',
);
final unsignedIntType = ImportedType(
ffiImport,
'UnsignedInt',
'int',
'unsigned',
defaultValue: '0',
);
final intType = ImportedType(ffiImport, 'Int', 'int', 'int', defaultValue: '0');
final unsignedLongType = ImportedType(
ffiImport,
'UnsignedLong',
'int',
'unsigned long',
defaultValue: '0',
);
final longType = ImportedType(
ffiImport,
'Long',
'int',
'long',
defaultValue: '0',
);
final unsignedLongLongType = ImportedType(
ffiImport,
'UnsignedLongLong',
'int',
'unsigned long long',
defaultValue: '0',
);
final longLongType = ImportedType(
ffiImport,
'LongLong',
'int',
'long long',
defaultValue: '0',
);
final floatType = ImportedType(
ffiImport,
'Float',
'double',
'float',
defaultValue: '0.0',
);
final doubleType = ImportedType(
ffiImport,
'Double',
'double',
'double',
defaultValue: '0.0',
);
final sizeType = ImportedType(
ffiImport,
'Size',
'int',
'size_t',
defaultValue: '0',
);
final wCharType = ImportedType(
ffiImport,
'WChar',
'int',
'wchar_t',
defaultValue: '0',
);
final objCObjectType = ImportedType(
objcPkgImport,
'ObjCObjectImpl',
'ObjCObjectImpl',
'void',
);
final objCSelType = ImportedType(
objcPkgImport,
'ObjCSelector',
'ObjCSelector',
'struct objc_selector',
);
final objCBlockType = ImportedType(
objcPkgImport,
'ObjCBlockImpl',
'ObjCBlockImpl',
'id',
);
final objCProtocolType = ImportedType(
objcPkgImport,
'ObjCProtocolImpl',
'ObjCProtocolImpl',
'void',
);
final objCContextType = ImportedType(
objcPkgImport,
'DOBJC_Context',
'DOBJC_Context',
'DOBJC_Context',
);