Skip to content

Commit 9a3793c

Browse files
committed
- cleaned up objc generation
- added ability to generate mock handlers - added pigeon.dart
1 parent c41258e commit 9a3793c

32 files changed

+416
-42
lines changed

packages/pigeon/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 0.1.0
2+
3+
* Added pigeon.dart.
4+
* Fixed some Obj-C linter problems.
5+
* Added the ability to generate a mock handler in Dart.
6+
17
## 0.1.0-experimental.11
28

39
* Fixed setting an api to null in Java.

packages/pigeon/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ doesn't need to worry about conflicting versions of Pigeon.
4444

4545
### Rules for defining your communication interface
4646

47-
1) The file should contain no methods or function definitions.
47+
1) The file should contain no method or function definitions.
4848
1) Datatypes are defined as classes with fields of the supported datatypes (see
4949
the supported Datatypes section).
5050
1) Api's should be defined as an `abstract class` with either `HostApi()` or
5151
`FlutterApi()` as metadata. The former being for procedures that are defined
5252
on the host platform and the latter for procedures that are defined in Dart.
5353
1) Method declarations on the Api classes should have one argument and a return
54-
value whose types are defined in the file.
54+
value whose types are defined in the file or be `void`.
5555

5656
## Example
5757

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1+
arguments=
2+
auto.sync=false
3+
build.scans.enabled=false
4+
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
15
connection.project.dir=
26
eclipse.preferences.version=1
7+
gradle.user.home=
8+
java.home=/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home
9+
jvm.arguments=
10+
offline.mode=false
11+
override.workspace.settings=true
12+
show.console.view=true
13+
show.executions.view=true
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<classpath>
3-
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-10/"/>
3+
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
44
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
55
<classpathentry kind="output" path="bin/default"/>
66
</classpath>

packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Autogenerated from Pigeon (v0.1.0-experimental.11), do not edit directly.
1+
// Autogenerated from Pigeon (v0.1.0), do not edit directly.
22
// See also: https://pub.dev/packages/pigeon
33
#import <Foundation/Foundation.h>
44
@protocol FlutterBinaryMessenger;
@@ -31,15 +31,17 @@ NS_ASSUME_NONNULL_BEGIN
3131
- (void)search:(ACSearchRequest *)input completion:(void (^)(ACSearchReply *, NSError *))completion;
3232
@end
3333
@protocol ACNestedApi
34-
- (ACSearchReply *)search:(ACNested *)input error:(FlutterError *_Nullable *_Nonnull)error;
34+
- (nullable ACSearchReply *)search:(ACNested *)input error:(FlutterError *_Nullable *_Nonnull)error;
3535
@end
3636

37-
extern void ACNestedApiSetup(id<FlutterBinaryMessenger> binaryMessenger, id<ACNestedApi> api);
37+
extern void ACNestedApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
38+
id<ACNestedApi> _Nullable api);
3839

3940
@protocol ACApi
40-
- (ACSearchReply *)search:(ACSearchRequest *)input error:(FlutterError *_Nullable *_Nonnull)error;
41+
- (nullable ACSearchReply *)search:(ACSearchRequest *)input
42+
error:(FlutterError *_Nullable *_Nonnull)error;
4143
@end
4244

43-
extern void ACApiSetup(id<FlutterBinaryMessenger> binaryMessenger, id<ACApi> api);
45+
extern void ACApiSetup(id<FlutterBinaryMessenger> binaryMessenger, id<ACApi> _Nullable api);
4446

4547
NS_ASSUME_NONNULL_END

packages/pigeon/e2e_tests/test_objc/ios/Runner/dartle.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Autogenerated from Pigeon (v0.1.0-experimental.11), do not edit directly.
1+
// Autogenerated from Pigeon (v0.1.0), do not edit directly.
22
// See also: https://pub.dev/packages/pigeon
33
#import "dartle.h"
44
#import <Flutter/Flutter.h>

packages/pigeon/e2e_tests/test_objc/lib/dartle.dart

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Autogenerated from Pigeon (v0.1.0-experimental.11), do not edit directly.
1+
// Autogenerated from Pigeon (v0.1.0), do not edit directly.
22
// See also: https://pub.dev/packages/pigeon
33
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import
44
import 'dart:async';
@@ -128,3 +128,20 @@ class Api {
128128
}
129129
}
130130
}
131+
132+
abstract class MockApi {
133+
SearchReply search(SearchRequest arg);
134+
}
135+
136+
void MockApiSetup(MockApi api) {
137+
{
138+
const BasicMessageChannel<dynamic> channel = BasicMessageChannel<dynamic>(
139+
'dev.flutter.pigeon.Api.search', StandardMessageCodec());
140+
channel.setMockMessageHandler((dynamic message) async {
141+
final Map<dynamic, dynamic> mapMessage = message as Map<dynamic, dynamic>;
142+
final SearchRequest input = SearchRequest._fromMap(mapMessage);
143+
final SearchReply output = api.search(input);
144+
return <dynamic, dynamic>{'result': output._toMap()};
145+
});
146+
}
147+
}

packages/pigeon/example/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
## message.dart
44

55
```dart
6-
import 'package:pigeon/pigeon_lib.dart';
6+
import 'package:pigeon/pigeon.dart';
77
88
class SearchRequest {
99
String query;

packages/pigeon/lib/ast.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Method extends Node {
3232
/// Represents a collection of [Method]s that are hosted ona given [location].
3333
class Api extends Node {
3434
/// Parametric constructor for [Api].
35-
Api({this.name, this.location, this.methods});
35+
Api({this.name, this.location, this.methods, this.mockDartHandler});
3636

3737
/// The name of the API.
3838
String name;
@@ -42,6 +42,9 @@ class Api extends Node {
4242

4343
/// List of methods inside the API.
4444
List<Method> methods;
45+
46+
/// The name of the Dart mock interface to generate to help with testing.
47+
String mockDartHandler;
4548
}
4649

4750
/// Represents a field on a [Class].

packages/pigeon/lib/dart_generator.dart

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ if (replyMap == null) {
6060
indent.writeln('');
6161
}
6262

63-
void _writeFlutterApi(Indent indent, Api api) {
63+
void _writeFlutterApi(Indent indent, Api api,
64+
{String Function(Method) channelNameFunc, bool isMockHandler = false}) {
6465
assert(api.location == ApiLocation.flutter);
6566
indent.write('abstract class ${api.name} ');
6667
indent.scoped('{', '}', () {
@@ -79,11 +80,16 @@ void _writeFlutterApi(Indent indent, Api api) {
7980
indent.writeln('const BasicMessageChannel<dynamic> channel =');
8081
indent.inc();
8182
indent.inc();
83+
final String channelName = channelNameFunc == null
84+
? makeChannelName(api, func)
85+
: channelNameFunc(func);
8286
indent.writeln(
83-
'BasicMessageChannel<dynamic>(\'${makeChannelName(api, func)}\', StandardMessageCodec());');
87+
'BasicMessageChannel<dynamic>(\'$channelName\', StandardMessageCodec());');
8488
indent.dec();
8589
indent.dec();
86-
indent.write('channel.setMessageHandler((dynamic message) async ');
90+
final String messageHandlerSetter =
91+
isMockHandler ? 'setMockMessageHandler' : 'setMessageHandler';
92+
indent.write('channel.$messageHandlerSetter((dynamic message) async ');
8793
indent.scoped('{', '});', () {
8894
final String argType = func.argType;
8995
final String returnType = func.returnType;
@@ -99,9 +105,16 @@ void _writeFlutterApi(Indent indent, Api api) {
99105
}
100106
if (returnType == 'void') {
101107
indent.writeln('$call;');
108+
if (isMockHandler) {
109+
indent.writeln('return <dynamic, dynamic>{};');
110+
}
102111
} else {
103112
indent.writeln('final $returnType output = $call;');
104-
indent.writeln('return output._toMap();');
113+
const String returnExpresion = 'output._toMap()';
114+
final String returnStatement = isMockHandler
115+
? 'return <dynamic, dynamic>{\'${Keys.result}\': $returnExpresion};'
116+
: 'return $returnExpresion;';
117+
indent.writeln(returnStatement);
105118
}
106119
});
107120
});
@@ -166,6 +179,15 @@ void generateDart(Root root, StringSink sink) {
166179
for (Api api in root.apis) {
167180
if (api.location == ApiLocation.host) {
168181
_writeHostApi(indent, api);
182+
if (api.mockDartHandler != null) {
183+
final Api mockApi = Api(
184+
name: api.mockDartHandler,
185+
methods: api.methods,
186+
location: ApiLocation.flutter);
187+
_writeFlutterApi(indent, mockApi,
188+
channelNameFunc: (Method func) => makeChannelName(api, func),
189+
isMockHandler: true);
190+
}
169191
} else if (api.location == ApiLocation.flutter) {
170192
_writeFlutterApi(indent, api);
171193
}

0 commit comments

Comments
 (0)