Skip to content

Commit

Permalink
[pigeon] Fixed decoding code for null-safe classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
gaaclarke committed Feb 22, 2021
1 parent f17b20a commit 6a36235
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 6 deletions.
5 changes: 5 additions & 0 deletions packages/pigeon/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.1.21

* Fixed decode method on generated Flutter classes that use null-safety and have
null values.

## 0.1.20

* Implemented `@async` HostApi's for iOS.
Expand Down
8 changes: 4 additions & 4 deletions packages/pigeon/lib/dart_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ void _writeFlutterApi(
String _addGenericTypes(String dataType, String nullTag) {
switch (dataType) {
case 'List':
return 'List<Object$nullTag>';
return 'List<Object$nullTag>$nullTag';
case 'Map':
return 'Map<Object$nullTag, Object$nullTag>';
return 'Map<Object$nullTag, Object$nullTag>$nullTag';
default:
return dataType;
return '$dataType$nullTag';
}
}

Expand Down Expand Up @@ -212,7 +212,7 @@ void generateDart(DartOptions opt, Root root, StringSink sink) {
indent.scoped('{', '}', () {
for (Field field in klass.fields) {
final String datatype =
'${_addGenericTypes(field.dataType, nullTag)}$nullTag';
'${_addGenericTypes(field.dataType, nullTag)}';
indent.writeln('$datatype ${field.name};');
}
if (klass.fields.isNotEmpty) {
Expand Down
2 changes: 1 addition & 1 deletion packages/pigeon/lib/generator_tools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import 'dart:mirrors';
import 'ast.dart';

/// The current version of pigeon. This must match the version in pubspec.yaml.
const String pigeonVersion = '0.1.20';
const String pigeonVersion = '0.1.21';

/// Read all the content from [stdin] to a String.
String readStdin() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/

# Web related
lib/generated_plugin_registrant.dart

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
revision: 6db3d61ed4a58ba89140d7fe1fd294b598cc29c5
channel: master

project_type: app
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# flutter_unit_tests

Unit test scaffold for null safe Flutter projects.
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// Autogenerated from Pigeon (v0.1.21), do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import
// @dart = 2.12
import 'dart:async';
import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;

import 'package:flutter/services.dart';

class SearchReply {
String? result;
String? error;

Object encode() {
final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
pigeonMap['result'] = result;
pigeonMap['error'] = error;
return pigeonMap;
}

static SearchReply decode(Object message) {
final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
return SearchReply()
..result = pigeonMap['result'] as String?
..error = pigeonMap['error'] as String?;
}
}

class SearchRequest {
String? query;
int? anInt;
bool? aBool;

Object encode() {
final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
pigeonMap['query'] = query;
pigeonMap['anInt'] = anInt;
pigeonMap['aBool'] = aBool;
return pigeonMap;
}

static SearchRequest decode(Object message) {
final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
return SearchRequest()
..query = pigeonMap['query'] as String?
..anInt = pigeonMap['anInt'] as int?
..aBool = pigeonMap['aBool'] as bool?;
}
}

class Nested {
SearchRequest? request;

Object encode() {
final Map<Object?, Object?> pigeonMap = <Object?, Object?>{};
pigeonMap['request'] = request == null ? null : request!.encode();
return pigeonMap;
}

static Nested decode(Object message) {
final Map<Object?, Object?> pigeonMap = message as Map<Object?, Object?>;
return Nested()
..request = pigeonMap['request'] != null
? SearchRequest.decode(pigeonMap['request']!)
: null;
}
}

abstract class FlutterSearchApi {
SearchReply search(SearchRequest arg);
static void setup(FlutterSearchApi? api) {
{
const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.FlutterSearchApi.search', StandardMessageCodec());
if (api == null) {
channel.setMessageHandler(null);
} else {
channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.FlutterSearchApi.search was null. Expected SearchRequest.');
final SearchRequest input = SearchRequest.decode(message!);
final SearchReply output = api.search(input);
return output.encode();
});
}
}
}
}

class NestedApi {
Future<SearchReply> search(Nested arg) async {
final Object encoded = arg.encode();
const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.NestedApi.search', StandardMessageCodec());
final Map<Object?, Object?>? replyMap =
await channel.send(encoded) as Map<Object?, Object?>?;
if (replyMap == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
details: null,
);
} else if (replyMap['error'] != null) {
final Map<Object?, Object?> error =
replyMap['error'] as Map<Object?, Object?>;
throw PlatformException(
code: error['code'] as String,
message: error['message'] as String?,
details: error['details'],
);
} else {
return SearchReply.decode(replyMap['result']!);
}
}
}

class Api {
Future<void> initialize() async {
const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.Api.initialize', StandardMessageCodec());
final Map<Object?, Object?>? replyMap =
await channel.send(null) as Map<Object?, Object?>?;
if (replyMap == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
details: null,
);
} else if (replyMap['error'] != null) {
final Map<Object?, Object?> error =
replyMap['error'] as Map<Object?, Object?>;
throw PlatformException(
code: error['code'] as String,
message: error['message'] as String?,
details: error['details'],
);
} else {
// noop
}
}

Future<SearchReply> search(SearchRequest arg) async {
final Object encoded = arg.encode();
const BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.Api.search', StandardMessageCodec());
final Map<Object?, Object?>? replyMap =
await channel.send(encoded) as Map<Object?, Object?>?;
if (replyMap == null) {
throw PlatformException(
code: 'channel-error',
message: 'Unable to establish connection on channel.',
details: null,
);
} else if (replyMap['error'] != null) {
final Map<Object?, Object?> error =
replyMap['error'] as Map<Object?, Object?>;
throw PlatformException(
code: error['code'] as String,
message: error['message'] as String?,
details: error['details'],
);
} else {
return SearchReply.decode(replyMap['result']!);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: flutter_unit_tests
description: Unit test scaffold for null safe Flutter projects.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"

dependencies:
flutter:
sdk: flutter

dev_dependencies:
flutter_test:
sdk: flutter

flutter:
uses-material-design: true
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2020 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter_unit_tests/null_safe_pigeon.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
test('with values filled', () {
final SearchReply reply = SearchReply()
..result = 'foo'
..error = 'bar';
final Object encoded = reply.encode();
final SearchReply decoded = SearchReply.decode(encoded);
expect(reply.result, decoded.result);
expect(reply.error, decoded.error);
});

test('with null value', () {
final SearchReply reply = SearchReply()
..result = 'foo'
..error = null;
final Object encoded = reply.encode();
final SearchReply decoded = SearchReply.decode(encoded);
expect(reply.result, decoded.result);
expect(reply.error, decoded.error);
});
}
2 changes: 1 addition & 1 deletion packages/pigeon/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: pigeon
version: 0.1.20 # This must match the version in lib/generator_tools.dart
version: 0.1.21 # This must match the version in lib/generator_tools.dart
description: Code generator tool to make communication between Flutter and the host platform type-safe and easier.
homepage: https://github.com/flutter/packages/tree/master/packages/pigeon
dependencies:
Expand Down
13 changes: 13 additions & 0 deletions packages/pigeon/run_tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,19 @@ pub run test test/
###############################################################################
pub run pigeon 1> /dev/null

###############################################################################
# Run unit tests on generated Dart code.
###############################################################################
pushd $PWD
pub run pigeon \
--input pigeons/message.dart \
--dart_null_safety \
--dart_out platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
cd platform_tests/flutter_null_safe_unit_tests
flutter pub get
flutter test test/null_safe_test.dart
popd

###############################################################################
# Mock handler flutter tests.
###############################################################################
Expand Down

0 comments on commit 6a36235

Please sign in to comment.