diff --git a/packages/pigeon/lib/functional.dart b/packages/pigeon/lib/functional.dart index a7ab7d64170..9c50ce6bd2b 100644 --- a/packages/pigeon/lib/functional.dart +++ b/packages/pigeon/lib/functional.dart @@ -68,3 +68,10 @@ Iterable _count() sync* { /// All integers starting at zero. final Iterable wholeNumbers = _count(); + +/// Repeats an [item] [n] times. +Iterable repeat(T item, int n) sync* { + for (int i = 0; i < n; ++i) { + yield item; + } +} diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index c95b00cf361..355370395bf 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -318,6 +318,17 @@ String _flattenTypeArguments(List args) { return args.map(_javaTypeForDartType).join(', '); } +String _javaTypeForBuiltinGenericDartType( + TypeDeclaration type, + int numberTypeArguments, +) { + if (type.typeArguments.isEmpty) { + return '${type.baseName}<${repeat('Object', numberTypeArguments).join(', ')}>'; + } else { + return '${type.baseName}<${_flattenTypeArguments(type.typeArguments)}>'; + } +} + String? _javaTypeForBuiltinDartType(TypeDeclaration type) { const Map javaTypeForDartTypeMap = { 'bool': 'Boolean', @@ -328,16 +339,13 @@ String? _javaTypeForBuiltinDartType(TypeDeclaration type) { 'Int32List': 'int[]', 'Int64List': 'long[]', 'Float64List': 'double[]', - 'Map': 'Map', }; if (javaTypeForDartTypeMap.containsKey(type.baseName)) { return javaTypeForDartTypeMap[type.baseName]; } else if (type.baseName == 'List') { - if (type.typeArguments.isEmpty) { - return 'List'; - } else { - return 'List<${_flattenTypeArguments(type.typeArguments)}>'; - } + return _javaTypeForBuiltinGenericDartType(type, 1); + } else if (type.baseName == 'Map') { + return _javaTypeForBuiltinGenericDartType(type, 2); } else { return null; } diff --git a/packages/pigeon/test/functional_test.dart b/packages/pigeon/test/functional_test.dart index 7b2eb1fb533..1c2079ccae4 100644 --- a/packages/pigeon/test/functional_test.dart +++ b/packages/pigeon/test/functional_test.dart @@ -69,4 +69,12 @@ void main() { expect(result[1], 1); expect(result[2], 2); }); + + test('repeat', () { + final List result = repeat(123, 3).toList(); + expect(result.length, 3); + expect(result[0], 123); + expect(result[1], 123); + expect(result[2], 123); + }); } diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index 0935037fb35..3ed65902fbb 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -653,6 +653,35 @@ void main() { expect(code, contains('List field1;')); }); + test('generics - maps', () { + final Class klass = Class( + name: 'Foobar', + fields: [ + NamedType( + type: TypeDeclaration( + baseName: 'Map', + isNullable: true, + typeArguments: [ + TypeDeclaration(baseName: 'String', isNullable: true), + TypeDeclaration(baseName: 'String', isNullable: true), + ]), + name: 'field1', + offset: null), + ], + ); + final Root root = Root( + apis: [], + classes: [klass], + enums: [], + ); + final StringBuffer sink = StringBuffer(); + const JavaOptions javaOptions = JavaOptions(className: 'Messages'); + generateJava(javaOptions, root, sink); + final String code = sink.toString(); + expect(code, contains('class Foobar')); + expect(code, contains('Map field1;')); + }); + test('host generics argument', () { final Root root = Root( apis: [