Skip to content

Commit

Permalink
[pigeon] fixed bug where the codec didn't contain all types when "Obj…
Browse files Browse the repository at this point in the history
…ect" is used. (flutter#510)

* [pigeon] fixed bug where the codec didn't contain all types when "Object" is used.

* stuarts feedback
  • Loading branch information
gaaclarke authored Nov 11, 2021
1 parent b1fdbab commit 2459d63
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 5 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 @@
## 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
Expand Down
19 changes: 15 additions & 4 deletions 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 = '1.0.9';
const String pigeonVersion = '1.0.10';

/// Read all the content from [stdin] to a String.
String readStdin() {
Expand Down Expand Up @@ -351,13 +351,24 @@ Map<TypeDeclaration, List<int>> 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<EnumeratedClass> getCodecClasses(Api api, Root root) sync* {
final Set<String> enumNames = root.enums.map((Enum e) => e.name).toSet();
final List<String> sortedNames = getReferencedTypes(<Api>[api], root.classes)
.keys
.map((TypeDeclaration e) => e.baseName)
final Map<TypeDeclaration, List<int>> referencedTypes =
getReferencedTypes(<Api>[api], root.classes);
final Iterable<String> allTypeNames =
referencedTypes.keys.any(_isConcreteTypeAmbiguous)
? root.classes.map((Class aClass) => aClass.name)
: referencedTypes.keys.map((TypeDeclaration e) => e.baseName);
final List<String> sortedNames = allTypeNames
.where((String element) =>
element != 'void' &&
!validTypes.contains(element) &&
Expand Down
2 changes: 1 addition & 1 deletion packages/pigeon/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
40 changes: 40 additions & 0 deletions packages/pigeon/test/generator_tools_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,46 @@ void main() {
1);
});

test('getCodecClasses: with Object', () {
final Root root = Root(apis: <Api>[
Api(
name: 'Api1',
location: ApiLocation.flutter,
methods: <Method>[
Method(
name: 'foo',
arguments: <NamedType>[
NamedType(
name: 'x',
type: const TypeDeclaration(
isNullable: false,
baseName: 'List',
typeArguments: <TypeDeclaration>[
TypeDeclaration(baseName: 'Object', isNullable: true)
])),
],
returnType: const TypeDeclaration.voidDeclaration(),
isAsynchronous: false,
)
],
),
], classes: <Class>[
Class(name: 'Foo', fields: <NamedType>[
NamedType(
name: 'bar',
type: const TypeDeclaration(baseName: 'int', isNullable: true)),
]),
], enums: <Enum>[]);
final List<EnumeratedClass> 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>[
Api(
Expand Down

0 comments on commit 2459d63

Please sign in to comment.