Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Various small fixes
  • Loading branch information
stuartmorgan-g committed Jan 19, 2024
commit b5aee8fc2022cf8cce8d987a88ffb34994a93fe8
34 changes: 22 additions & 12 deletions packages/pigeon/lib/swift_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,14 @@ class SwiftGenerator extends StructuredGenerator<SwiftOptions> {
required String dartPackageName,
}) {
indent.writeln('import Foundation');
indent.newln();
indent.format('''
#if os(iOS)
import Flutter
import Flutter
#elseif os(macOS)
import FlutterMacOS
import FlutterMacOS
#else
#error("Unsupported platform.")
#error("Unsupported platform.")
#endif''');
}

Expand Down Expand Up @@ -160,6 +161,9 @@ import FlutterMacOS
indent.addScoped('{', '}', () {
indent.write('return ');
indent.addScoped('[', ']', () {
// Follow swift-format style, which is to use a trailing comma unless
// there is only one element.
final String separator = classDefinition.fields.length > 1 ? ',' : '';
for (final NamedType field
in getFieldsInSerializationOrder(classDefinition)) {
String toWriteValue = '';
Expand All @@ -173,7 +177,7 @@ import FlutterMacOS
toWriteValue = field.name;
}

indent.writeln('$toWriteValue,');
indent.writeln('$toWriteValue$separator');
}
});
});
Expand Down Expand Up @@ -294,7 +298,7 @@ import FlutterMacOS
indent.write('class ${api.name}: ${api.name}Protocol ');
indent.addScoped('{', '}', () {
indent.writeln('private let binaryMessenger: FlutterBinaryMessenger');
indent.write('init(binaryMessenger: FlutterBinaryMessenger)');
indent.write('init(binaryMessenger: FlutterBinaryMessenger) ');
indent.addScoped('{', '}', () {
indent.writeln('self.binaryMessenger = binaryMessenger');
});
Expand Down Expand Up @@ -333,7 +337,7 @@ import FlutterMacOS
'completion(.failure(createConnectionError(withChannelName:channelName)))');
indent.writeln('return');
});
indent.writeScoped('if (listResponse.count > 1) {', '} ', () {
indent.writeScoped('if listResponse.count > 1 {', '} ', () {
indent.writeln('let code: String = listResponse[0] as! String');
indent.writeln(
'let message: String? = nilOrValue(listResponse[1])');
Expand All @@ -343,7 +347,7 @@ import FlutterMacOS
'completion(.failure(FlutterError(code: code, message: message, details: details)));');
}, addTrailingNewline: false);
if (!func.returnType.isNullable && !func.returnType.isVoid) {
indent.addScoped('else if (listResponse[0] == nil) {', '} ', () {
indent.addScoped('else if listResponse[0] == nil {', '} ', () {
indent.writeln(
'completion(.failure(FlutterError(code: "null-error", message: "Flutter api returned null value for non-null return value.", details: "")))');
}, addTrailingNewline: false);
Expand Down Expand Up @@ -495,8 +499,14 @@ import FlutterMacOS
});
}
final String tryStatement = method.isAsynchronous ? '' : 'try ';
// Empty parens are not required when calling a method whose only
// argument is a trailing closure.
final String argumentString =
methodArgument.isEmpty && method.isAsynchronous
? ''
: '(${methodArgument.join(', ')})';
final String call =
'${tryStatement}api.${components.name}(${methodArgument.join(', ')})';
'${tryStatement}api.${components.name}$argumentString';
if (method.isAsynchronous) {
final String resultName =
method.returnType.isVoid ? 'nil' : 'res';
Expand All @@ -506,7 +516,7 @@ import FlutterMacOS

indent.addScoped('{ result in', '}', () {
indent.write('switch result ');
indent.addScoped('{', '}', () {
indent.addScoped('{', '}', nestCount: 0, () {
final String nullsafe =
method.returnType.isNullable ? '?' : '';
final String enumTag =
Expand Down Expand Up @@ -573,7 +583,7 @@ import FlutterMacOS
indent.write('override func readValue(ofType type: UInt8) -> Any? ');
indent.addScoped('{', '}', () {
indent.write('switch type ');
indent.addScoped('{', '}', () {
indent.addScoped('{', '}', nestCount: 0, () {
for (final EnumeratedClass customClass
in getCodecClasses(api, root)) {
indent.writeln('case ${customClass.enumeration}:');
Expand Down Expand Up @@ -764,14 +774,14 @@ import FlutterMacOS
indent.addScoped('[', ']', () {
indent.writeln('flutterError.code,');
indent.writeln('flutterError.message,');
indent.writeln('flutterError.details');
indent.writeln('flutterError.details,');
});
});
indent.write('return ');
indent.addScoped('[', ']', () {
indent.writeln(r'"\(error)",');
indent.writeln(r'"\(type(of: error))",');
indent.writeln(r'"Stacktrace: \(Thread.callStackSymbols)"');
indent.writeln(r'"Stacktrace: \(Thread.callStackSymbols)",');
});
});
}
Expand Down
17 changes: 17 additions & 0 deletions packages/pigeon/test/swift_generator_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ void main() {
expect(code, contains('var field1: Int64? = nil'));
expect(code, contains('static func fromList(_ list: [Any?]) -> Foobar?'));
expect(code, contains('func toList() -> [Any?]'));
expect(code, isNot(contains('if (')));
});

test('gen one enum', () {
Expand Down Expand Up @@ -80,6 +81,7 @@ void main() {
expect(code, contains('enum Foobar: Int'));
expect(code, contains(' case one = 0'));
expect(code, contains(' case two = 1'));
expect(code, isNot(contains('if (')));
});

test('primitive enum host', () {
Expand Down Expand Up @@ -116,6 +118,7 @@ void main() {
final String code = sink.toString();
expect(code, contains('enum Foo: Int'));
expect(code, contains('let fooArg = Foo(rawValue: args[0] as! Int)!'));
expect(code, isNot(contains('if (')));
});

test('gen one host api', () {
Expand Down Expand Up @@ -170,6 +173,7 @@ void main() {
expect(code, contains('protocol Api'));
expect(code, matches('func doSomething.*Input.*Output'));
expect(code, contains('doSomethingChannel.setMessageHandler'));
expect(code, isNot(contains('if (')));
});

test('all the simple datatypes header', () {
Expand Down Expand Up @@ -298,6 +302,7 @@ void main() {
expect(code, contains('class Api'));
expect(code, contains('init(binaryMessenger: FlutterBinaryMessenger)'));
expect(code, matches('func doSomething.*Input.*Output'));
expect(code, isNot(contains('if (')));
});

test('gen host void api', () {
Expand Down Expand Up @@ -339,6 +344,7 @@ void main() {
final String code = sink.toString();
expect(code, isNot(matches('.*doSomething(.*) ->')));
expect(code, matches('doSomething(.*)'));
expect(code, isNot(contains('if (')));
});

test('gen flutter void return api', () {
Expand Down Expand Up @@ -381,6 +387,7 @@ void main() {
expect(code,
contains('completion: @escaping (Result<Void, FlutterError>) -> Void'));
expect(code, contains('completion(.success(Void()))'));
expect(code, isNot(contains('if (')));
});

test('gen host void argument api', () {
Expand Down Expand Up @@ -419,6 +426,7 @@ void main() {
expect(code, contains('func doSomething() throws -> Output'));
expect(code, contains('let result = try api.doSomething()'));
expect(code, contains('reply(wrapResult(result))'));
expect(code, isNot(contains('if (')));
});

test('gen flutter void argument api', () {
Expand Down Expand Up @@ -459,6 +467,7 @@ void main() {
contains(
'func doSomething(completion: @escaping (Result<Output, FlutterError>) -> Void)'));
expect(code, contains('channel.sendMessage(nil'));
expect(code, isNot(contains('if (')));
});

test('gen list', () {
Expand All @@ -484,6 +493,7 @@ void main() {
final String code = sink.toString();
expect(code, contains('struct Foobar'));
expect(code, contains('var field1: [Any?]? = nil'));
expect(code, isNot(contains('if (')));
});

test('gen map', () {
Expand All @@ -509,6 +519,7 @@ void main() {
final String code = sink.toString();
expect(code, contains('struct Foobar'));
expect(code, contains('var field1: [AnyHashable: Any?]? = nil'));
expect(code, isNot(contains('if (')));
});

test('gen nested', () {
Expand Down Expand Up @@ -556,6 +567,9 @@ void main() {
expect(code, contains('static func fromList(_ list: [Any?]) -> Outer?'));
expect(code, contains('nested = Nested.fromList(nestedList)'));
expect(code, contains('func toList() -> [Any?]'));
expect(code, isNot(contains('if (')));
// Single-element list serializations should not have a trailing comma.
expect(code, matches(RegExp(r'return \[\s*data\s*]')));
});

test('gen one async Host Api', () {
Expand Down Expand Up @@ -611,6 +625,7 @@ void main() {
expect(code, contains('protocol Api'));
expect(code, contains('api.doSomething(arg: argArg) { result in'));
expect(code, contains('reply(wrapResult(res))'));
expect(code, isNot(contains('if (')));
});

test('gen one async Flutter Api', () {
Expand Down Expand Up @@ -665,6 +680,7 @@ void main() {
final String code = sink.toString();
expect(code, contains('class Api'));
expect(code, matches('func doSomething.*Input.*completion.*Output.*Void'));
expect(code, isNot(contains('if (')));
});

test('gen one enum class', () {
Expand Down Expand Up @@ -705,6 +721,7 @@ void main() {
expect(code, contains('enum Enum1: Int'));
expect(code, contains('case one = 0'));
expect(code, contains('case two = 1'));
expect(code, isNot(contains('if (')));
});

Iterable<String> makeIterable(String string) sync* {
Expand Down