diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 014e640945d3..3467ac890e15 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,8 @@ +## 1.0.10 + +* [front-end] Made sure that explicit use of Object actually creates the codec + that can represent custom classes. + ## 1.0.9 * [dart] Fixed cast exception that can happen with primitive data types with diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 4bedecb2ecf7..aa1b9dad8a3e 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -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 = '1.0.9'; +const String pigeonVersion = '1.0.10'; /// Read all the content from [stdin] to a String. String readStdin() { @@ -351,13 +351,24 @@ Map> getReferencedTypes( return references.map; } +/// Returns true if the concrete type cannot be determined at compile-time. +bool _isConcreteTypeAmbiguous(TypeDeclaration type) { + return (type.baseName == 'List' && type.typeArguments.isEmpty) || + (type.baseName == 'Map' && type.typeArguments.isEmpty) || + type.baseName == 'Object'; +} + /// Given an [Api], return the enumerated classes that must exist in the codec /// where the enumeration should be the key used in the buffer. Iterable getCodecClasses(Api api, Root root) sync* { final Set enumNames = root.enums.map((Enum e) => e.name).toSet(); - final List sortedNames = getReferencedTypes([api], root.classes) - .keys - .map((TypeDeclaration e) => e.baseName) + final Map> referencedTypes = + getReferencedTypes([api], root.classes); + final Iterable allTypeNames = + referencedTypes.keys.any(_isConcreteTypeAmbiguous) + ? root.classes.map((Class aClass) => aClass.name) + : referencedTypes.keys.map((TypeDeclaration e) => e.baseName); + final List sortedNames = allTypeNames .where((String element) => element != 'void' && !validTypes.contains(element) && diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 0dbdd8b4a54b..04647a02a99a 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -2,7 +2,7 @@ name: pigeon description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. repository: https://github.com/flutter/packages/tree/master/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 1.0.9 # This must match the version in lib/generator_tools.dart +version: 1.0.10 # This must match the version in lib/generator_tools.dart environment: sdk: '>=2.12.0 <3.0.0' diff --git a/packages/pigeon/test/generator_tools_test.dart b/packages/pigeon/test/generator_tools_test.dart index b50dea6bf267..a2fa40262177 100644 --- a/packages/pigeon/test/generator_tools_test.dart +++ b/packages/pigeon/test/generator_tools_test.dart @@ -229,6 +229,46 @@ void main() { 1); }); + test('getCodecClasses: with Object', () { + final Root root = Root(apis: [ + Api( + name: 'Api1', + location: ApiLocation.flutter, + methods: [ + Method( + name: 'foo', + arguments: [ + NamedType( + name: 'x', + type: const TypeDeclaration( + isNullable: false, + baseName: 'List', + typeArguments: [ + TypeDeclaration(baseName: 'Object', isNullable: true) + ])), + ], + returnType: const TypeDeclaration.voidDeclaration(), + isAsynchronous: false, + ) + ], + ), + ], classes: [ + Class(name: 'Foo', fields: [ + NamedType( + name: 'bar', + type: const TypeDeclaration(baseName: 'int', isNullable: true)), + ]), + ], enums: []); + final List classes = + getCodecClasses(root.apis[0], root).toList(); + expect(classes.length, 1); + expect( + classes + .where((EnumeratedClass element) => element.name == 'Foo') + .length, + 1); + }); + test('getCodecClasses: unique entries', () { final Root root = Root(apis: [ Api(