From df851d59441d8dec12456dc6aad1099cb8c77b69 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 20 Dec 2022 21:29:39 -0800 Subject: [PATCH 01/87] Rename generator class to Adapter --- packages/pigeon/lib/pigeon_lib.dart | 143 ++++++++++++++-------------- 1 file changed, 72 insertions(+), 71 deletions(-) diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 5da91c4a7c5..a8348ea7474 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -355,18 +355,19 @@ IOSink? _openSink(String? output) { return sink; } -/// A generator that will write code to a sink based on the contents of [PigeonOptions]. -abstract class Generator { - /// Returns an [IOSink] instance to be written to if the [Generator] should - /// generate. If it returns `null`, the [Generator] will be skipped. +/// An adapter that will call a generator to write code to a sink +/// based on the contents of [PigeonOptions]. +abstract class Adapter { + /// Returns an [IOSink] instance to be written to if the [Adapter] should + /// generate. If it returns `null`, the [Adapter] will be skipped. IOSink? shouldGenerate(PigeonOptions options); /// Write the generated code described in [root] to [sink] using the /// [options]. void generate(StringSink sink, PigeonOptions options, Root root); - /// Generates errors that would only be appropriate for this [Generator]. For - /// example, maybe a certain feature isn't implemented in a [Generator] yet. + /// Generates errors that would only be appropriate for this [Adapter]. For + /// example, maybe a certain feature isn't implemented in a [Adapter] yet. List validate(PigeonOptions options, Root root); } @@ -378,10 +379,10 @@ DartOptions _dartOptionsWithCopyrightHeader( copyrightHeader != null ? _lineReader(copyrightHeader) : null)); } -/// A [Generator] that generates the AST. -class AstGenerator implements Generator { - /// Constructor for [AstGenerator]. - const AstGenerator(); +/// A [Adapter] that generates the AST. +class AstAdapter implements Adapter { + /// Constructor for [AstAdapter]. + const AstAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -395,10 +396,10 @@ class AstGenerator implements Generator { List validate(PigeonOptions options, Root root) => []; } -/// A [Generator] that generates Dart source code. -class DartGenerator implements Generator { - /// Constructor for [DartGenerator]. - const DartGenerator(); +/// A [Adapter] that generates Dart source code. +class DartAdapter implements Adapter { + /// Constructor for [DartAdapter]. + const DartAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -414,10 +415,10 @@ class DartGenerator implements Generator { List validate(PigeonOptions options, Root root) => []; } -/// A [Generator] that generates Dart test source code. -class DartTestGenerator implements Generator { - /// Constructor for [DartTestGenerator]. - const DartTestGenerator(); +/// A [Adapter] that generates Dart test source code. +class DartTestAdapter implements Adapter { + /// Constructor for [DartTestAdapter]. + const DartTestAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -445,10 +446,10 @@ class DartTestGenerator implements Generator { List validate(PigeonOptions options, Root root) => []; } -/// A [Generator] that generates Objective-C header code. -class ObjcHeaderGenerator implements Generator { - /// Constructor for [ObjcHeaderGenerator]. - const ObjcHeaderGenerator(); +/// A [Adapter] that generates Objective-C header code. +class ObjcHeaderAdapter implements Adapter { + /// Constructor for [ObjcHeaderAdapter]. + const ObjcHeaderAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -469,10 +470,10 @@ class ObjcHeaderGenerator implements Generator { validateObjc(options.objcOptions!, root); } -/// A [Generator] that generates Objective-C source code. -class ObjcSourceGenerator implements Generator { - /// Constructor for [ObjcSourceGenerator]. - const ObjcSourceGenerator(); +/// A [Adapter] that generates Objective-C source code. +class ObjcSourceAdapter implements Adapter { + /// Constructor for [ObjcSourceAdapter]. + const ObjcSourceAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -492,10 +493,10 @@ class ObjcSourceGenerator implements Generator { List validate(PigeonOptions options, Root root) => []; } -/// A [Generator] that generates Java source code. -class JavaGenerator implements Generator { - /// Constructor for [JavaGenerator]. - const JavaGenerator(); +/// A [Adapter] that generates Java source code. +class JavaAdapter implements Adapter { + /// Constructor for [JavaAdapter]. + const JavaAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -516,10 +517,10 @@ class JavaGenerator implements Generator { List validate(PigeonOptions options, Root root) => []; } -/// A [Generator] that generates Swift source code. -class SwiftGenerator implements Generator { - /// Constructor for [SwiftGenerator]. - const SwiftGenerator(); +/// A [Adapter] that generates Swift source code. +class SwiftAdapter implements Adapter { + /// Constructor for [SwiftAdapter]. + const SwiftAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -538,10 +539,10 @@ class SwiftGenerator implements Generator { List validate(PigeonOptions options, Root root) => []; } -/// A [Generator] that generates C++ header code. -class CppHeaderGenerator implements Generator { - /// Constructor for [CppHeaderGenerator]. - const CppHeaderGenerator(); +/// A [Adapter] that generates C++ header code. +class CppHeaderAdapter implements Adapter { + /// Constructor for [CppHeaderAdapter]. + const CppHeaderAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -563,10 +564,10 @@ class CppHeaderGenerator implements Generator { validateCpp(options.cppOptions!, root); } -/// A [Generator] that generates C++ source code. -class CppSourceGenerator implements Generator { - /// Constructor for [CppSourceGenerator]. - const CppSourceGenerator(); +/// A [Adapter] that generates C++ source code. +class CppSourceAdapter implements Adapter { + /// Constructor for [CppSourceAdapter]. + const CppSourceAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -586,10 +587,10 @@ class CppSourceGenerator implements Generator { List validate(PigeonOptions options, Root root) => []; } -/// A [Generator] that generates Kotlin source code. -class KotlinGenerator implements Generator { - /// Constructor for [KotlinGenerator]. - const KotlinGenerator(); +/// A [Adapter] that generates Kotlin source code. +class KotlinAdapter implements Adapter { + /// Constructor for [KotlinAdapter]. + const KotlinAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -1331,37 +1332,37 @@ ${_argParser.usage}'''; } /// The 'main' entrypoint used by the command-line tool. [args] are the - /// command-line arguments. The optional parameter [generators] allows you to + /// command-line arguments. The optional parameter [adapters] allows you to /// customize the generators that pigeon will use. The optional parameter /// [sdkPath] allows you to specify the Dart SDK path. static Future run(List args, - {List? generators, String? sdkPath}) { + {List? adapters, String? sdkPath}) { final PigeonOptions options = Pigeon.parseArgs(args); - return runWithOptions(options, generators: generators, sdkPath: sdkPath); + return runWithOptions(options, adapters: adapters, sdkPath: sdkPath); } /// The 'main' entrypoint used by external packages. [options] is - /// used when running the code generator. The optional parameter [generators] allows you to + /// used when running the code generator. The optional parameter [adapters] allows you to /// customize the generators that pigeon will use. The optional parameter /// [sdkPath] allows you to specify the Dart SDK path. static Future runWithOptions(PigeonOptions options, - {List? generators, String? sdkPath}) async { + {List? adapters, String? sdkPath}) async { final Pigeon pigeon = Pigeon.setup(); if (options.debugGenerators ?? false) { generator_tools.debugGenerators = true; } - final List safeGenerators = generators ?? - [ - const DartGenerator(), - const JavaGenerator(), - const SwiftGenerator(), - const KotlinGenerator(), - const CppHeaderGenerator(), - const CppSourceGenerator(), - const DartTestGenerator(), - const ObjcHeaderGenerator(), - const ObjcSourceGenerator(), - const AstGenerator(), + final List safeAdapters = adapters ?? + [ + const DartAdapter(), + const JavaAdapter(), + const SwiftAdapter(), + const KotlinAdapter(), + const CppHeaderAdapter(), + const CppSourceAdapter(), + const DartTestAdapter(), + const ObjcHeaderAdapter(), + const ObjcSourceAdapter(), + const AstAdapter(), ]; _executeConfigurePigeon(options); @@ -1383,12 +1384,12 @@ ${_argParser.usage}'''; } } - for (final Generator generator in safeGenerators) { - final IOSink? sink = generator.shouldGenerate(options); + for (final Adapter adapter in safeAdapters) { + final IOSink? sink = adapter.shouldGenerate(options); if (sink != null) { - final List generatorErrors = - generator.validate(options, parseResults.root); - errors.addAll(generatorErrors); + final List adapterErrors = + adapter.validate(options, parseResults.root); + errors.addAll(adapterErrors); await releaseSink(sink); } } @@ -1425,10 +1426,10 @@ ${_argParser.usage}'''; CppOptions(header: path.basename(options.cppHeaderOut!))))); } - for (final Generator generator in safeGenerators) { - final IOSink? sink = generator.shouldGenerate(options); + for (final Adapter adapter in safeAdapters) { + final IOSink? sink = adapter.shouldGenerate(options); if (sink != null) { - generator.generate(sink, options, parseResults.root); + adapter.generate(sink, options, parseResults.root); await sink.flush(); await releaseSink(sink); } From e40d679b8bacd7af8b6d913d3c5e5d96462be2da Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 20 Dec 2022 21:30:01 -0800 Subject: [PATCH 02/87] create new generator class and dart subclass --- packages/pigeon/lib/dart_generator.dart | 17 +++++++++++++++ packages/pigeon/lib/generator.dart | 29 +++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 packages/pigeon/lib/generator.dart diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 85956ced69e..c9c672a661d 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -9,6 +9,7 @@ import 'package:yaml/yaml.dart' as yaml; import 'ast.dart'; import 'functional.dart'; +import 'generator.dart'; import 'generator_tools.dart'; /// Documentation comment open symbol. @@ -55,6 +56,22 @@ class DartOptions { } } +/// Class that manages all coe generation. +class DartGenerator extends Generator { + /// Instantiates a Generator. + DartGenerator({ + required DartOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates files for specified language with specified [languageOptions] + @override + void generate() { + // + } +} + String _escapeForDartSingleQuotedString(String raw) { return raw .replaceAll(r'\', r'\\') diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart new file mode 100644 index 00000000000..f45c113a7b6 --- /dev/null +++ b/packages/pigeon/lib/generator.dart @@ -0,0 +1,29 @@ +// Copyright 2013 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 'ast.dart'; + +/// A Super class of generator classes. +/// +/// This is meant to provide structure and direction for future generator work. +abstract class Generator { + /// Instantiates a Generator. + const Generator({ + required this.languageOptions, + required this.root, + required this.sink, + }); + + /// + final T languageOptions; + + /// + final Root root; + + /// + final StringSink sink; + + /// Generates files for specified language with specified [languageOptions] + void generate(); +} From 8c4e2a0a2b888f924638ba65d6e0a581836ee604 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 11:57:23 -0800 Subject: [PATCH 03/87] cpp and dart test gen --- packages/pigeon/lib/dart_generator.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index c9c672a661d..f9042b148ac 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -56,16 +56,16 @@ class DartOptions { } } -/// Class that manages all coe generation. +/// Class that manages all Dart code generation. class DartGenerator extends Generator { - /// Instantiates a Generator. + /// Instantiates a Dart Generator. DartGenerator({ required DartOptions languageOptions, required Root root, required StringSink sink, }) : super(languageOptions: languageOptions, root: root, sink: sink); - /// Generates files for specified language with specified [languageOptions] + /// Generates Dart files with specified [DartOptions] @override void generate() { // From bcdbdbcaf089550dac5c14b1c66e6ef5b6838b69 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 11:58:03 -0800 Subject: [PATCH 04/87] added files --- packages/pigeon/lib/cpp_generator.dart | 33 +++++++++++++++++++++++++ packages/pigeon/lib/dart_generator.dart | 16 ++++++++++++ packages/pigeon/lib/pigeon_lib.dart | 20 +++++++-------- 3 files changed, 59 insertions(+), 10 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 744f6e9ffce..584d4792ff2 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -4,6 +4,7 @@ import 'ast.dart'; import 'functional.dart'; +import 'generator.dart'; import 'generator_tools.dart'; import 'pigeon_lib.dart' show Error; @@ -64,6 +65,38 @@ class CppOptions { } } +/// Class that manages all Cpp header code generation. +class CppHeaderGenerator extends Generator { + /// Instantiates a Cpp Generator. + CppHeaderGenerator({ + required CppOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates Cpp header files with specified [CppOptions] + @override + void generate() { + // + } +} + +/// Class that manages all Cpp code generation. +class CppSourceGenerator extends Generator { + /// Instantiates a Cpp Generator. + CppSourceGenerator({ + required CppOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates Cpp files with specified [CppOptions] + @override + void generate() { + // + } +} + String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; const String _pointerPrefix = 'pointer'; diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index f9042b148ac..4ddbe9056ef 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -72,6 +72,22 @@ class DartGenerator extends Generator { } } +/// Class that manages all Dart code generation. +class DartTestGenerator extends Generator { + /// Instantiates a Dart Generator. + DartTestGenerator({ + required DartOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates Dart files with specified [DartOptions] + @override + void generate() { + // + } +} + String _escapeForDartSingleQuotedString(String raw) { return raw .replaceAll(r'\', r'\\') diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index a8348ea7474..5bab11a01bb 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -379,7 +379,7 @@ DartOptions _dartOptionsWithCopyrightHeader( copyrightHeader != null ? _lineReader(copyrightHeader) : null)); } -/// A [Adapter] that generates the AST. +/// An [Adapter] that generates the AST. class AstAdapter implements Adapter { /// Constructor for [AstAdapter]. const AstAdapter(); @@ -396,7 +396,7 @@ class AstAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// A [Adapter] that generates Dart source code. +/// An [Adapter] that generates Dart source code. class DartAdapter implements Adapter { /// Constructor for [DartAdapter]. const DartAdapter(); @@ -415,7 +415,7 @@ class DartAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// A [Adapter] that generates Dart test source code. +/// An [Adapter] that generates Dart test source code. class DartTestAdapter implements Adapter { /// Constructor for [DartTestAdapter]. const DartTestAdapter(); @@ -446,7 +446,7 @@ class DartTestAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// A [Adapter] that generates Objective-C header code. +/// An [Adapter] that generates Objective-C header code. class ObjcHeaderAdapter implements Adapter { /// Constructor for [ObjcHeaderAdapter]. const ObjcHeaderAdapter(); @@ -470,7 +470,7 @@ class ObjcHeaderAdapter implements Adapter { validateObjc(options.objcOptions!, root); } -/// A [Adapter] that generates Objective-C source code. +/// An [Adapter] that generates Objective-C source code. class ObjcSourceAdapter implements Adapter { /// Constructor for [ObjcSourceAdapter]. const ObjcSourceAdapter(); @@ -493,7 +493,7 @@ class ObjcSourceAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// A [Adapter] that generates Java source code. +/// An [Adapter] that generates Java source code. class JavaAdapter implements Adapter { /// Constructor for [JavaAdapter]. const JavaAdapter(); @@ -517,7 +517,7 @@ class JavaAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// A [Adapter] that generates Swift source code. +/// An [Adapter] that generates Swift source code. class SwiftAdapter implements Adapter { /// Constructor for [SwiftAdapter]. const SwiftAdapter(); @@ -539,7 +539,7 @@ class SwiftAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// A [Adapter] that generates C++ header code. +/// An [Adapter] that generates C++ header code. class CppHeaderAdapter implements Adapter { /// Constructor for [CppHeaderAdapter]. const CppHeaderAdapter(); @@ -564,7 +564,7 @@ class CppHeaderAdapter implements Adapter { validateCpp(options.cppOptions!, root); } -/// A [Adapter] that generates C++ source code. +/// An [Adapter] that generates C++ source code. class CppSourceAdapter implements Adapter { /// Constructor for [CppSourceAdapter]. const CppSourceAdapter(); @@ -587,7 +587,7 @@ class CppSourceAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// A [Adapter] that generates Kotlin source code. +/// An [Adapter] that generates Kotlin source code. class KotlinAdapter implements Adapter { /// Constructor for [KotlinAdapter]. const KotlinAdapter(); From 31bb7019a1065d505ee4ab34dca147cf2c7e0df7 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 12:09:44 -0800 Subject: [PATCH 05/87] Adds Generator class to all generators --- packages/pigeon/lib/java_generator.dart | 17 ++++++++++++ packages/pigeon/lib/kotlin_generator.dart | 17 ++++++++++++ packages/pigeon/lib/objc_generator.dart | 33 +++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index c52d976cfdf..e77c11da941 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -4,6 +4,7 @@ import 'ast.dart'; import 'functional.dart'; +import 'generator.dart'; import 'generator_tools.dart'; import 'pigeon_lib.dart' show TaskQueueType; @@ -84,6 +85,22 @@ class JavaOptions { } } +/// Class that manages all Java code generation. +class JavaGenerator extends Generator { + /// Instantiates a Java Generator. + JavaGenerator({ + required JavaOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates Java files with specified [JavaOptions] + @override + void generate() { + // + } +} + /// Calculates the name of the codec that will be generated for [api]. String _getCodecName(Api api) => '${api.name}Codec'; diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 1f52d3d22c3..371987d70af 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -4,6 +4,7 @@ import 'ast.dart'; import 'functional.dart'; +import 'generator.dart'; import 'generator_tools.dart'; import 'pigeon_lib.dart' show TaskQueueType; @@ -64,6 +65,22 @@ class KotlinOptions { } } +/// Class that manages all Kotlin code generation. +class KotlinGenerator extends Generator { + /// Instantiates a Kotlin Generator. + KotlinGenerator({ + required KotlinOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates Kotlin files with specified [KotlinOptions] + @override + void generate() { + // + } +} + /// Calculates the name of the codec that will be generated for [api]. String _getCodecName(Api api) => '${api.name}Codec'; diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index e8de7c1154c..e1e5815bcaa 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -4,6 +4,7 @@ import 'ast.dart'; import 'functional.dart'; +import 'generator.dart'; import 'generator_tools.dart'; import 'pigeon_lib.dart' show Error, TaskQueueType; @@ -63,6 +64,38 @@ class ObjcOptions { } } +/// Class that manages all Objc header code generation. +class ObjcHeaderGenerator extends Generator { + /// Instantiates a Objc Generator. + ObjcHeaderGenerator({ + required ObjcOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates Objc header files with specified [ObjcOptions] + @override + void generate() { + // + } +} + +/// Class that manages all Objc code generation. +class ObjcSourceGenerator extends Generator { + /// Instantiates a Objc Generator. + ObjcSourceGenerator({ + required ObjcOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates Objc files with specified [ObjcOptions] + @override + void generate() { + // + } +} + /// Calculates the ObjC class name, possibly prefixed. String _className(String? prefix, String className) { if (prefix != null) { From 06315ce0c5c32aa4a9ae948014669e06c040c1e6 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 12:16:34 -0800 Subject: [PATCH 06/87] adds swift --- packages/pigeon/lib/swift_generator.dart | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 3736506c1e7..8db09cf96bc 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -4,6 +4,7 @@ import 'ast.dart'; import 'functional.dart'; +import 'generator.dart'; import 'generator_tools.dart'; /// Documentation comment open symbol. @@ -47,6 +48,22 @@ class SwiftOptions { } } +/// Class that manages all Swift code generation. +class SwiftGenerator extends Generator { + /// Instantiates a Swift Generator. + SwiftGenerator({ + required SwiftOptions languageOptions, + required Root root, + required StringSink sink, + }) : super(languageOptions: languageOptions, root: root, sink: sink); + + /// Generates Swift files with specified [SwiftOptions] + @override + void generate() { + // + } +} + /// Calculates the name of the codec that will be generated for [api]. String _getCodecName(Api api) => '${api.name}Codec'; From 5675c646717296c9a0444f8714c5fb258ce39d06 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 12:25:11 -0800 Subject: [PATCH 07/87] Updates tests to use new Adapter naming scheme --- packages/pigeon/test/pigeon_lib_test.dart | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 4a121e7e9e0..411643f679f 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -9,8 +9,8 @@ import 'package:pigeon/ast.dart'; import 'package:pigeon/pigeon_lib.dart'; import 'package:test/test.dart'; -class _ValidatorGenerator implements Generator { - _ValidatorGenerator(this.sink); +class _ValidatorAdapter implements Adapter { + _ValidatorAdapter(this.sink); bool didCallValidate = false; final IOSink? sink; @@ -397,9 +397,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const DartGenerator dartGenerator = DartGenerator(); + const DartAdapter dartAdapter = DartAdapter(); final StringBuffer buffer = StringBuffer(); - dartGenerator.generate(buffer, options, root); + dartAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -407,9 +407,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( javaOut: 'Foo.java', copyrightHeader: './copyright_header.txt'); - const JavaGenerator javaGenerator = JavaGenerator(); + const JavaAdapter javaAdapter = JavaAdapter(); final StringBuffer buffer = StringBuffer(); - javaGenerator.generate(buffer, options, root); + javaAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -417,9 +417,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const ObjcHeaderGenerator objcHeaderGenerator = ObjcHeaderGenerator(); + const ObjcHeaderAdapter objcHeaderAdapter = ObjcHeaderAdapter(); final StringBuffer buffer = StringBuffer(); - objcHeaderGenerator.generate(buffer, options, root); + objcHeaderAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -427,9 +427,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const ObjcSourceGenerator objcSourceGenerator = ObjcSourceGenerator(); + const ObjcSourceAdapter objcSourceAdapter = ObjcSourceAdapter(); final StringBuffer buffer = StringBuffer(); - objcSourceGenerator.generate(buffer, options, root); + objcSourceAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -437,9 +437,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( swiftOut: 'Foo.swift', copyrightHeader: './copyright_header.txt'); - const SwiftGenerator swiftGenerator = SwiftGenerator(); + const SwiftAdapter swiftAdapter = SwiftAdapter(); final StringBuffer buffer = StringBuffer(); - swiftGenerator.generate(buffer, options, root); + swiftAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -447,9 +447,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( cppHeaderOut: 'Foo.h', copyrightHeader: './copyright_header.txt'); - const CppHeaderGenerator cppHeaderGenerator = CppHeaderGenerator(); + const CppHeaderAdapter cppHeaderAdapter = CppHeaderAdapter(); final StringBuffer buffer = StringBuffer(); - cppHeaderGenerator.generate(buffer, options, root); + cppHeaderAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -457,9 +457,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const CppSourceGenerator cppSourceGenerator = CppSourceGenerator(); + const CppSourceAdapter cppSourceAdapter = CppSourceAdapter(); final StringBuffer buffer = StringBuffer(); - cppSourceGenerator.generate(buffer, options, root); + cppSourceAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -929,9 +929,9 @@ abstract class Api { dartTestOut: 'stdout', dartOut: 'stdout', ); - const DartTestGenerator dartGenerator = DartTestGenerator(); + const DartTestAdapter dartAdapter = DartTestAdapter(); final StringBuffer buffer = StringBuffer(); - dartGenerator.generate(buffer, options, root); + dartAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -1187,9 +1187,9 @@ abstract class Api { test('generator validation', () async { final Completer completer = Completer(); withTempFile('foo.dart', (File input) async { - final _ValidatorGenerator generator = _ValidatorGenerator(stdout); + final _ValidatorAdapter generator = _ValidatorAdapter(stdout); final int result = await Pigeon.run(['--input', input.path], - generators: [generator]); + adapters: [generator]); expect(generator.didCallValidate, isTrue); expect(result, isNot(0)); completer.complete(); @@ -1200,10 +1200,10 @@ abstract class Api { test('generator validation skipped', () async { final Completer completer = Completer(); withTempFile('foo.dart', (File input) async { - final _ValidatorGenerator generator = _ValidatorGenerator(null); + final _ValidatorAdapter generator = _ValidatorAdapter(null); final int result = await Pigeon.run( ['--input', input.path, '--dart_out', 'foo.dart'], - generators: [generator]); + adapters: [generator]); expect(generator.didCallValidate, isFalse); expect(result, equals(0)); completer.complete(); @@ -1214,10 +1214,10 @@ abstract class Api { test('run with PigeonOptions', () async { final Completer completer = Completer(); withTempFile('foo.dart', (File input) async { - final _ValidatorGenerator generator = _ValidatorGenerator(null); + final _ValidatorAdapter generator = _ValidatorAdapter(null); final int result = await Pigeon.runWithOptions( PigeonOptions(input: input.path, dartOut: 'foo.dart'), - generators: [generator]); + adapters: [generator]); expect(generator.didCallValidate, isFalse); expect(result, equals(0)); completer.complete(); From a319b481ddd797f22e49ac04f434e3153cf36627 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 12:55:30 -0800 Subject: [PATCH 08/87] Dart generate methods --- packages/pigeon/lib/dart_generator.dart | 18 ++++++++++++++++-- packages/pigeon/lib/pigeon_lib.dart | 18 ++++++++++-------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 4ddbe9056ef..0a5f310d233 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -68,7 +68,7 @@ class DartGenerator extends Generator { /// Generates Dart files with specified [DartOptions] @override void generate() { - // + generateDart(languageOptions, root, sink); } } @@ -79,12 +79,26 @@ class DartTestGenerator extends Generator { required DartOptions languageOptions, required Root root, required StringSink sink, + required this.dartOutPath, + required this.testOutPath, }) : super(languageOptions: languageOptions, root: root, sink: sink); + /// Path to output generated Dart file. + String dartOutPath; + + /// Path to output generated Test file. + String testOutPath; + /// Generates Dart files with specified [DartOptions] @override void generate() { - // + generateTestDart( + languageOptions, + root, + sink, + dartOutPath: dartOutPath, + testOutPath: testOutPath, + ); } } diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 5bab11a01bb..0bb11c18d43 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -405,7 +405,9 @@ class DartAdapter implements Adapter { void generate(StringSink sink, PigeonOptions options, Root root) { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader); - generateDart(dartOptionsWithHeader, root, sink); + final DartGenerator generator = DartGenerator( + languageOptions: dartOptionsWithHeader, root: root, sink: sink); + generator.generate(); } @override @@ -424,13 +426,13 @@ class DartTestAdapter implements Adapter { void generate(StringSink sink, PigeonOptions options, Root root) { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader); - generateTestDart( - dartOptionsWithHeader, - root, - sink, - dartOutPath: options.dartOut!, - testOutPath: options.dartTestOut!, - ); + final DartTestGenerator testGenerator = DartTestGenerator( + languageOptions: dartOptionsWithHeader, + root: root, + sink: sink, + dartOutPath: options.dartOut!, + testOutPath: options.dartTestOut!); + testGenerator.generate(); } @override From 6d7405d7a118bb687bcf02ce7cbc9b83488a3226 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 13:07:37 -0800 Subject: [PATCH 09/87] convert all generate functions to use new method --- packages/pigeon/lib/cpp_generator.dart | 8 ++++-- packages/pigeon/lib/java_generator.dart | 2 +- packages/pigeon/lib/kotlin_generator.dart | 2 +- packages/pigeon/lib/objc_generator.dart | 4 +-- packages/pigeon/lib/pigeon_lib.dart | 32 +++++++++++++++++------ packages/pigeon/lib/swift_generator.dart | 2 +- 6 files changed, 35 insertions(+), 15 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 584d4792ff2..dccb6d8602d 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -72,12 +72,16 @@ class CppHeaderGenerator extends Generator { required CppOptions languageOptions, required Root root, required StringSink sink, + required this.path, }) : super(languageOptions: languageOptions, root: root, sink: sink); + /// Path to output generated Cpp Header file. + String path; + /// Generates Cpp header files with specified [CppOptions] @override void generate() { - // + generateCppHeader(path, languageOptions, root, sink); } } @@ -93,7 +97,7 @@ class CppSourceGenerator extends Generator { /// Generates Cpp files with specified [CppOptions] @override void generate() { - // + generateCppSource(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index e77c11da941..5bc65d32a8a 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -97,7 +97,7 @@ class JavaGenerator extends Generator { /// Generates Java files with specified [JavaOptions] @override void generate() { - // + generateJava(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 371987d70af..584b45a8535 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -77,7 +77,7 @@ class KotlinGenerator extends Generator { /// Generates Kotlin files with specified [KotlinOptions] @override void generate() { - // + generateKotlin(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index e1e5815bcaa..417189d7a60 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -76,7 +76,7 @@ class ObjcHeaderGenerator extends Generator { /// Generates Objc header files with specified [ObjcOptions] @override void generate() { - // + generateObjcHeader(languageOptions, root, sink); } } @@ -92,7 +92,7 @@ class ObjcSourceGenerator extends Generator { /// Generates Objc files with specified [ObjcOptions] @override void generate() { - // + generateObjcSource(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 0bb11c18d43..45bb47009c5 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -460,7 +460,9 @@ class ObjcHeaderAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - generateObjcHeader(objcOptionsWithHeader, root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator( + languageOptions: objcOptionsWithHeader, root: root, sink: sink); + generator.generate(); } @override @@ -484,7 +486,9 @@ class ObjcSourceAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - generateObjcSource(objcOptionsWithHeader, root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator( + languageOptions: objcOptionsWithHeader, root: root, sink: sink); + generator.generate(); } @override @@ -509,7 +513,9 @@ class JavaAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = + JavaGenerator(languageOptions: javaOptions, root: root, sink: sink); + generator.generate(); } @override @@ -531,7 +537,9 @@ class SwiftAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = + SwiftGenerator(languageOptions: swiftOptions, root: root, sink: sink); + generator.generate(); } @override @@ -553,8 +561,12 @@ class CppHeaderAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - generateCppHeader(path.basenameWithoutExtension(options.cppHeaderOut!), - cppOptionsWithHeader, root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator( + languageOptions: cppOptionsWithHeader, + root: root, + sink: sink, + path: path.basenameWithoutExtension(options.cppHeaderOut!)); + generator.generate(); } @override @@ -578,7 +590,9 @@ class CppSourceAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - generateCppSource(cppOptionsWithHeader, root, sink); + final CppSourceGenerator generator = CppSourceGenerator( + languageOptions: cppOptionsWithHeader, root: root, sink: sink); + generator.generate(); } @override @@ -602,7 +616,9 @@ class KotlinAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = + KotlinGenerator(languageOptions: kotlinOptions, root: root, sink: sink); + generator.generate(); } @override diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 8db09cf96bc..3853d87b686 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -60,7 +60,7 @@ class SwiftGenerator extends Generator { /// Generates Swift files with specified [SwiftOptions] @override void generate() { - // + generateSwift(languageOptions, root, sink); } } From 1e59fef259017c0e4f113cd8adbd63511febff89 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 13:14:45 -0800 Subject: [PATCH 10/87] chagngelog --- packages/pigeon/CHANGELOG.md | 4 ++++ packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index e0278c5731d..6e6688e0d85 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.2.16 + +* Creates new Generator classes for each language. + ## 4.2.15 * Relocates generator classes. (Reverted) diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 6624a1dc8ec..ea522eaa04d 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '4.2.15'; +const String pigeonVersion = '4.2.16'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index e9c9d6b4901..886f56a6ea0 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 4.2.15 # This must match the version in lib/generator_tools.dart +version: 4.2.16 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" From 0964cd32dedc3b3208f5280e64658d635215936e Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 14:23:38 -0800 Subject: [PATCH 11/87] remove Generator class fields --- packages/pigeon/lib/cpp_generator.dart | 15 ++----- packages/pigeon/lib/dart_generator.dart | 15 ++----- packages/pigeon/lib/generator.dart | 17 +------- packages/pigeon/lib/java_generator.dart | 8 +--- packages/pigeon/lib/kotlin_generator.dart | 8 +--- packages/pigeon/lib/objc_generator.dart | 16 ++----- packages/pigeon/lib/pigeon_lib.dart | 52 +++++++++-------------- packages/pigeon/lib/swift_generator.dart | 8 +--- 8 files changed, 41 insertions(+), 98 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index d46028a279c..cb3c23e21bc 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -69,18 +69,15 @@ class CppOptions { class CppHeaderGenerator extends Generator { /// Instantiates a Cpp Generator. CppHeaderGenerator({ - required CppOptions languageOptions, - required Root root, - required StringSink sink, required this.path, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + }); /// Path to output generated Cpp Header file. String path; /// Generates Cpp header files with specified [CppOptions] @override - void generate() { + void generate(CppOptions languageOptions, Root root, StringSink sink) { generateCppHeader(path, languageOptions, root, sink); } } @@ -88,15 +85,11 @@ class CppHeaderGenerator extends Generator { /// Class that manages all Cpp code generation. class CppSourceGenerator extends Generator { /// Instantiates a Cpp Generator. - CppSourceGenerator({ - required CppOptions languageOptions, - required Root root, - required StringSink sink, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + CppSourceGenerator(); /// Generates Cpp files with specified [CppOptions] @override - void generate() { + void generate(CppOptions languageOptions, Root root, StringSink sink) { generateCppSource(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 0a5f310d233..13cfb1ecff2 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -59,15 +59,11 @@ class DartOptions { /// Class that manages all Dart code generation. class DartGenerator extends Generator { /// Instantiates a Dart Generator. - DartGenerator({ - required DartOptions languageOptions, - required Root root, - required StringSink sink, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + DartGenerator(); /// Generates Dart files with specified [DartOptions] @override - void generate() { + void generate(DartOptions languageOptions, Root root, StringSink sink) { generateDart(languageOptions, root, sink); } } @@ -76,12 +72,9 @@ class DartGenerator extends Generator { class DartTestGenerator extends Generator { /// Instantiates a Dart Generator. DartTestGenerator({ - required DartOptions languageOptions, - required Root root, - required StringSink sink, required this.dartOutPath, required this.testOutPath, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + }); /// Path to output generated Dart file. String dartOutPath; @@ -91,7 +84,7 @@ class DartTestGenerator extends Generator { /// Generates Dart files with specified [DartOptions] @override - void generate() { + void generate(DartOptions languageOptions, Root root, StringSink sink) { generateTestDart( languageOptions, root, diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index f45c113a7b6..0979627b3ac 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -9,21 +9,8 @@ import 'ast.dart'; /// This is meant to provide structure and direction for future generator work. abstract class Generator { /// Instantiates a Generator. - const Generator({ - required this.languageOptions, - required this.root, - required this.sink, - }); - - /// - final T languageOptions; - - /// - final Root root; - - /// - final StringSink sink; + const Generator(); /// Generates files for specified language with specified [languageOptions] - void generate(); + void generate(T languageOptions, Root root, StringSink sink); } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 5bc65d32a8a..00293bfc0e8 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -88,15 +88,11 @@ class JavaOptions { /// Class that manages all Java code generation. class JavaGenerator extends Generator { /// Instantiates a Java Generator. - JavaGenerator({ - required JavaOptions languageOptions, - required Root root, - required StringSink sink, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + JavaGenerator(); /// Generates Java files with specified [JavaOptions] @override - void generate() { + void generate(JavaOptions languageOptions, Root root, StringSink sink) { generateJava(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 584b45a8535..99690a4ac92 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -68,15 +68,11 @@ class KotlinOptions { /// Class that manages all Kotlin code generation. class KotlinGenerator extends Generator { /// Instantiates a Kotlin Generator. - KotlinGenerator({ - required KotlinOptions languageOptions, - required Root root, - required StringSink sink, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + KotlinGenerator(); /// Generates Kotlin files with specified [KotlinOptions] @override - void generate() { + void generate(KotlinOptions languageOptions, Root root, StringSink sink) { generateKotlin(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 417189d7a60..0d376e1a582 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -67,15 +67,11 @@ class ObjcOptions { /// Class that manages all Objc header code generation. class ObjcHeaderGenerator extends Generator { /// Instantiates a Objc Generator. - ObjcHeaderGenerator({ - required ObjcOptions languageOptions, - required Root root, - required StringSink sink, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + ObjcHeaderGenerator(); /// Generates Objc header files with specified [ObjcOptions] @override - void generate() { + void generate(ObjcOptions languageOptions, Root root, StringSink sink) { generateObjcHeader(languageOptions, root, sink); } } @@ -83,15 +79,11 @@ class ObjcHeaderGenerator extends Generator { /// Class that manages all Objc code generation. class ObjcSourceGenerator extends Generator { /// Instantiates a Objc Generator. - ObjcSourceGenerator({ - required ObjcOptions languageOptions, - required Root root, - required StringSink sink, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + ObjcSourceGenerator(); /// Generates Objc files with specified [ObjcOptions] @override - void generate() { + void generate(ObjcOptions languageOptions, Root root, StringSink sink) { generateObjcSource(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 45bb47009c5..65718a4ff46 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -405,9 +405,8 @@ class DartAdapter implements Adapter { void generate(StringSink sink, PigeonOptions options, Root root) { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader); - final DartGenerator generator = DartGenerator( - languageOptions: dartOptionsWithHeader, root: root, sink: sink); - generator.generate(); + final DartGenerator generator = DartGenerator(); + generator.generate(dartOptionsWithHeader, root, sink); } @override @@ -427,12 +426,12 @@ class DartTestAdapter implements Adapter { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader); final DartTestGenerator testGenerator = DartTestGenerator( - languageOptions: dartOptionsWithHeader, - root: root, - sink: sink, - dartOutPath: options.dartOut!, - testOutPath: options.dartTestOut!); - testGenerator.generate(); + dartOutPath: options.dartOut!, testOutPath: options.dartTestOut!); + testGenerator.generate( + dartOptionsWithHeader, + root, + sink, + ); } @override @@ -460,9 +459,8 @@ class ObjcHeaderAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator( - languageOptions: objcOptionsWithHeader, root: root, sink: sink); - generator.generate(); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(objcOptionsWithHeader, root, sink); } @override @@ -486,9 +484,8 @@ class ObjcSourceAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final ObjcSourceGenerator generator = ObjcSourceGenerator( - languageOptions: objcOptionsWithHeader, root: root, sink: sink); - generator.generate(); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(objcOptionsWithHeader, root, sink); } @override @@ -513,9 +510,8 @@ class JavaAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final JavaGenerator generator = - JavaGenerator(languageOptions: javaOptions, root: root, sink: sink); - generator.generate(); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); } @override @@ -537,9 +533,8 @@ class SwiftAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final SwiftGenerator generator = - SwiftGenerator(languageOptions: swiftOptions, root: root, sink: sink); - generator.generate(); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); } @override @@ -562,11 +557,8 @@ class CppHeaderAdapter implements Adapter { ? _lineReader(options.copyrightHeader!) : null)); final CppHeaderGenerator generator = CppHeaderGenerator( - languageOptions: cppOptionsWithHeader, - root: root, - sink: sink, path: path.basenameWithoutExtension(options.cppHeaderOut!)); - generator.generate(); + generator.generate(cppOptionsWithHeader, root, sink); } @override @@ -590,9 +582,8 @@ class CppSourceAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final CppSourceGenerator generator = CppSourceGenerator( - languageOptions: cppOptionsWithHeader, root: root, sink: sink); - generator.generate(); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(cppOptionsWithHeader, root, sink); } @override @@ -616,9 +607,8 @@ class KotlinAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final KotlinGenerator generator = - KotlinGenerator(languageOptions: kotlinOptions, root: root, sink: sink); - generator.generate(); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); } @override diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 3853d87b686..b25931c03e3 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -51,15 +51,11 @@ class SwiftOptions { /// Class that manages all Swift code generation. class SwiftGenerator extends Generator { /// Instantiates a Swift Generator. - SwiftGenerator({ - required SwiftOptions languageOptions, - required Root root, - required StringSink sink, - }) : super(languageOptions: languageOptions, root: root, sink: sink); + SwiftGenerator(); /// Generates Swift files with specified [SwiftOptions] @override - void generate() { + void generate(SwiftOptions languageOptions, Root root, StringSink sink) { generateSwift(languageOptions, root, sink); } } From f589da4c3f875040a59713e2e86b6955ab3c06a1 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 21 Dec 2022 23:01:58 -0800 Subject: [PATCH 12/87] move paths to options --- packages/pigeon/lib/cpp_generator.dart | 28 ++++------ packages/pigeon/lib/dart_generator.dart | 73 ++++++++++++++++++++----- packages/pigeon/lib/pigeon_lib.dart | 29 ++++++++-- 3 files changed, 93 insertions(+), 37 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index cb3c23e21bc..6bc120bc2d3 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -21,11 +21,8 @@ const String _defaultCodecSerializer = 'flutter::StandardCodecSerializer'; /// Options that control how C++ code will be generated. class CppOptions { /// Creates a [CppOptions] object - const CppOptions({ - this.header, - this.namespace, - this.copyrightHeader, - }); + const CppOptions( + {this.header, this.namespace, this.copyrightHeader, this.cppHeaderOut}); /// The path to the header that will get placed in the source filed (example: /// "foo.h"). @@ -37,14 +34,17 @@ class CppOptions { /// A copyright header that will get prepended to generated code. final Iterable? copyrightHeader; + /// + final String? cppHeaderOut; + /// Creates a [CppOptions] from a Map representation where: /// `x = CppOptions.fromMap(x.toMap())`. static CppOptions fromMap(Map map) { return CppOptions( - header: map['header'] as String?, - namespace: map['namespace'] as String?, - copyrightHeader: map['copyrightHeader'] as Iterable?, - ); + header: map['header'] as String?, + namespace: map['namespace'] as String?, + copyrightHeader: map['copyrightHeader'] as Iterable?, + cppHeaderOut: map['cppHeaderOut'] as String?); } /// Converts a [CppOptions] to a Map representation where: @@ -68,17 +68,13 @@ class CppOptions { /// Class that manages all Cpp header code generation. class CppHeaderGenerator extends Generator { /// Instantiates a Cpp Generator. - CppHeaderGenerator({ - required this.path, - }); - - /// Path to output generated Cpp Header file. - String path; + CppHeaderGenerator(); /// Generates Cpp header files with specified [CppOptions] @override void generate(CppOptions languageOptions, Root root, StringSink sink) { - generateCppHeader(path, languageOptions, root, sink); + generateCppHeader( + languageOptions.cppHeaderOut, languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 13cfb1ecff2..64ef93b2f21 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -56,6 +56,57 @@ class DartOptions { } } +/// Options that control how Dart test code will be generated. +class DartTestOptions { + /// Constructor for DartOptions. + DartTestOptions({ + this.copyrightHeader, + required this.dartOutPath, + required this.testOutPath, + }); + + /// A copyright header that will get prepended to generated code. + final Iterable? copyrightHeader; + + /// Path to output generated Dart file. + String dartOutPath; + + /// Path to output generated Test file. + String testOutPath; + + /// Creates a [DartOptions] from a Map representation where: + /// `x = DartOptions.fromMap(x.toMap())`. + static DartTestOptions fromMap(Map map) { + final Iterable? copyrightHeader = + map['copyrightHeader'] as Iterable?; + return DartTestOptions( + dartOutPath: map['dartOutPath']! as String, + testOutPath: map['testOutPath']! as String, + copyrightHeader: copyrightHeader?.cast(), + ); + } + + /// Converts a [DartOptions] to a Map representation where: + /// `x = DartOptions.fromMap(x.toMap())`. + Map toMap() { + final Map result = { + if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!, + }; + return result; + } + + /// Overrides any non-null parameters from [options] into this to make a new + /// [DartOptions]. + DartTestOptions merge(DartTestOptions options) { + return DartTestOptions.fromMap(mergeMaps(toMap(), options.toMap())); + } + + /// Converts DartTestOptions to DartOptions and returns it. + DartOptions toDartOptions() { + return DartOptions(copyrightHeader: copyrightHeader); + } +} + /// Class that manages all Dart code generation. class DartGenerator extends Generator { /// Instantiates a Dart Generator. @@ -69,28 +120,20 @@ class DartGenerator extends Generator { } /// Class that manages all Dart code generation. -class DartTestGenerator extends Generator { +class DartTestGenerator extends Generator { /// Instantiates a Dart Generator. - DartTestGenerator({ - required this.dartOutPath, - required this.testOutPath, - }); - - /// Path to output generated Dart file. - String dartOutPath; - - /// Path to output generated Test file. - String testOutPath; + DartTestGenerator(); /// Generates Dart files with specified [DartOptions] @override - void generate(DartOptions languageOptions, Root root, StringSink sink) { + void generate(DartTestOptions languageOptions, Root root, StringSink sink) { + final DartOptions dartOptions = languageOptions.toDartOptions(); generateTestDart( - languageOptions, + dartOptions, root, sink, - dartOutPath: dartOutPath, - testOutPath: testOutPath, + dartOutPath: languageOptions.dartOutPath, + testOutPath: languageOptions.testOutPath, ); } } diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 65718a4ff46..94cfd55f2ff 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -379,6 +379,19 @@ DartOptions _dartOptionsWithCopyrightHeader( copyrightHeader != null ? _lineReader(copyrightHeader) : null)); } +DartTestOptions _dartTestOptionsWithCopyrightHeader(DartOptions? dartOptions, + String? copyrightHeader, String dartOutPath, String testOutPath) { + final Iterable? parsedCopyrightHeader = dartOptions != null + ? dartOptions.copyrightHeader + : copyrightHeader != null + ? _lineReader(copyrightHeader) + : null; + return DartTestOptions( + dartOutPath: dartOutPath, + testOutPath: testOutPath, + copyrightHeader: parsedCopyrightHeader); +} + /// An [Adapter] that generates the AST. class AstAdapter implements Adapter { /// Constructor for [AstAdapter]. @@ -423,10 +436,14 @@ class DartTestAdapter implements Adapter { @override void generate(StringSink sink, PigeonOptions options, Root root) { - final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( - options.dartOptions, options.copyrightHeader); - final DartTestGenerator testGenerator = DartTestGenerator( - dartOutPath: options.dartOut!, testOutPath: options.dartTestOut!); + final DartTestOptions dartOptionsWithHeader = + _dartTestOptionsWithCopyrightHeader( + options.dartOptions, + options.copyrightHeader, + options.dartOut!, + options.dartTestOut!, + ); + final DartTestGenerator testGenerator = DartTestGenerator(); testGenerator.generate( dartOptionsWithHeader, root, @@ -553,11 +570,11 @@ class CppHeaderAdapter implements Adapter { void generate(StringSink sink, PigeonOptions options, Root root) { final CppOptions cppOptions = options.cppOptions ?? const CppOptions(); final CppOptions cppOptionsWithHeader = cppOptions.merge(CppOptions( + cppHeaderOut: path.basenameWithoutExtension(options.cppHeaderOut!), copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final CppHeaderGenerator generator = CppHeaderGenerator( - path: path.basenameWithoutExtension(options.cppHeaderOut!)); + final CppHeaderGenerator generator = CppHeaderGenerator(); generator.generate(cppOptionsWithHeader, root, sink); } From 637679dc0c02c7078deee8d5ce9ff2a58713efcd Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 08:24:58 -0800 Subject: [PATCH 13/87] remove dartTestOptions --- packages/pigeon/lib/dart_generator.dart | 80 +++++-------------- packages/pigeon/lib/pigeon_lib.dart | 20 ++--- packages/pigeon/test/dart_generator_test.dart | 80 +++++++++---------- packages/pigeon/tool/shared/generation.dart | 2 +- 4 files changed, 69 insertions(+), 113 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 64ef93b2f21..604becc9c30 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -25,64 +25,30 @@ const String _standardMessageCodec = 'StandardMessageCodec'; /// Options that control how Dart code will be generated. class DartOptions { /// Constructor for DartOptions. - const DartOptions({this.copyrightHeader}); - - /// A copyright header that will get prepended to generated code. - final Iterable? copyrightHeader; - - /// Creates a [DartOptions] from a Map representation where: - /// `x = DartOptions.fromMap(x.toMap())`. - static DartOptions fromMap(Map map) { - final Iterable? copyrightHeader = - map['copyrightHeader'] as Iterable?; - return DartOptions( - copyrightHeader: copyrightHeader?.cast(), - ); - } - - /// Converts a [DartOptions] to a Map representation where: - /// `x = DartOptions.fromMap(x.toMap())`. - Map toMap() { - final Map result = { - if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!, - }; - return result; - } - - /// Overrides any non-null parameters from [options] into this to make a new - /// [DartOptions]. - DartOptions merge(DartOptions options) { - return DartOptions.fromMap(mergeMaps(toMap(), options.toMap())); - } -} - -/// Options that control how Dart test code will be generated. -class DartTestOptions { - /// Constructor for DartOptions. - DartTestOptions({ + DartOptions({ this.copyrightHeader, - required this.dartOutPath, - required this.testOutPath, + this.dartOutPath, + this.testOutPath, }); /// A copyright header that will get prepended to generated code. final Iterable? copyrightHeader; - /// Path to output generated Dart file. - String dartOutPath; + /// Path to output generated Dart file for tests. + String? dartOutPath; - /// Path to output generated Test file. - String testOutPath; + /// Path to output generated Test file for tests. + String? testOutPath; /// Creates a [DartOptions] from a Map representation where: /// `x = DartOptions.fromMap(x.toMap())`. - static DartTestOptions fromMap(Map map) { + static DartOptions fromMap(Map map) { final Iterable? copyrightHeader = map['copyrightHeader'] as Iterable?; - return DartTestOptions( - dartOutPath: map['dartOutPath']! as String, - testOutPath: map['testOutPath']! as String, + return DartOptions( copyrightHeader: copyrightHeader?.cast(), + dartOutPath: map['dartOutPath'] as String?, + testOutPath: map['testOutPath'] as String?, ); } @@ -91,19 +57,16 @@ class DartTestOptions { Map toMap() { final Map result = { if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!, + if (dartOutPath != null) 'dartOutPath': dartOutPath!, + if (testOutPath != null) 'testOutPath': testOutPath!, }; return result; } /// Overrides any non-null parameters from [options] into this to make a new /// [DartOptions]. - DartTestOptions merge(DartTestOptions options) { - return DartTestOptions.fromMap(mergeMaps(toMap(), options.toMap())); - } - - /// Converts DartTestOptions to DartOptions and returns it. - DartOptions toDartOptions() { - return DartOptions(copyrightHeader: copyrightHeader); + DartOptions merge(DartOptions options) { + return DartOptions.fromMap(mergeMaps(toMap(), options.toMap())); } } @@ -120,20 +83,21 @@ class DartGenerator extends Generator { } /// Class that manages all Dart code generation. -class DartTestGenerator extends Generator { +class DartTestGenerator extends Generator { /// Instantiates a Dart Generator. DartTestGenerator(); /// Generates Dart files with specified [DartOptions] @override - void generate(DartTestOptions languageOptions, Root root, StringSink sink) { - final DartOptions dartOptions = languageOptions.toDartOptions(); + void generate(DartOptions languageOptions, Root root, StringSink sink) { + final String dartOutPath = languageOptions.dartOutPath ?? ''; + final String testOutPath = languageOptions.testOutPath ?? ''; generateTestDart( - dartOptions, + languageOptions, root, sink, - dartOutPath: languageOptions.dartOutPath, - testOutPath: languageOptions.testOutPath, + dartOutPath: dartOutPath, + testOutPath: testOutPath, ); } } diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 94cfd55f2ff..e630a09c438 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -372,21 +372,14 @@ abstract class Adapter { } DartOptions _dartOptionsWithCopyrightHeader( - DartOptions? dartOptions, String? copyrightHeader) { - dartOptions = dartOptions ?? const DartOptions(); - return dartOptions.merge(DartOptions( - copyrightHeader: - copyrightHeader != null ? _lineReader(copyrightHeader) : null)); -} - -DartTestOptions _dartTestOptionsWithCopyrightHeader(DartOptions? dartOptions, - String? copyrightHeader, String dartOutPath, String testOutPath) { + DartOptions? dartOptions, String? copyrightHeader, + [String? dartOutPath, String? testOutPath]) { final Iterable? parsedCopyrightHeader = dartOptions != null ? dartOptions.copyrightHeader : copyrightHeader != null ? _lineReader(copyrightHeader) : null; - return DartTestOptions( + return DartOptions( dartOutPath: dartOutPath, testOutPath: testOutPath, copyrightHeader: parsedCopyrightHeader); @@ -436,12 +429,11 @@ class DartTestAdapter implements Adapter { @override void generate(StringSink sink, PigeonOptions options, Root root) { - final DartTestOptions dartOptionsWithHeader = - _dartTestOptionsWithCopyrightHeader( + final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader, - options.dartOut!, - options.dartTestOut!, + options.dartOut, + options.dartTestOut, ); final DartTestGenerator testGenerator = DartTestGenerator(); testGenerator.generate( diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index bf359ddfe43..38442ccd358 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -29,7 +29,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' dataType1? field1;')); @@ -49,7 +49,7 @@ void main() { enums: [anEnum], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum Foobar')); expect(code, contains(' one,')); @@ -92,7 +92,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('Future doSomething(Input arg_input)')); @@ -118,7 +118,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('Future add(int arg_x, int arg_y)')); @@ -145,7 +145,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('int add(int x, int y)')); @@ -182,7 +182,7 @@ void main() { ) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -224,7 +224,7 @@ void main() { ) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -276,7 +276,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('abstract class Api')); expect(code, contains('static void setup(Api')); @@ -310,7 +310,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doSomething')); expect(code, contains('return;')); @@ -343,7 +343,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); // The next line verifies that we're not setting a variable to the value of "doSomething", but // ignores the line where we assert the value of the argument isn't null, since on that line @@ -373,7 +373,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('output.*=.*doSomething[(][)]')); expect(code, contains('Output doSomething();')); @@ -415,7 +415,7 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum1?.index,')); expect(code, contains('? Enum.values[result[0]! as int]')); @@ -442,7 +442,7 @@ void main() { ]) ]); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum Foo {')); expect(code, contains('Future bar(Foo? arg_foo) async')); @@ -485,7 +485,7 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum1.index,')); expect(code, contains('enum1: Enum.values[result[0]! as int]')); @@ -512,7 +512,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('channel.send[(]null[)]')); }); @@ -570,7 +570,7 @@ void main() { ], enums: []); final StringBuffer mainCodeSink = StringBuffer(); final StringBuffer testCodeSink = StringBuffer(); - generateDart(const DartOptions(), root, mainCodeSink); + generateDart(DartOptions(), root, mainCodeSink); final String mainCode = mainCodeSink.toString(); expect(mainCode, isNot(contains(r"import 'fo\'o.dart';"))); expect(mainCode, contains('class Api {')); @@ -579,7 +579,7 @@ void main() { expect(mainCode, isNot(contains("'${Keys.result}': output"))); expect(mainCode, isNot(contains('return [];'))); generateTestDart( - const DartOptions(), + DartOptions(), root, testCodeSink, dartOutPath: "fo'o.dart", @@ -631,7 +631,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('abstract class Api')); expect(code, contains('Future doSomething(Input arg0);')); @@ -675,7 +675,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.s*doSomething'))); expect(code, contains('await api.doSomething(')); @@ -719,7 +719,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, matches('Output.*doSomething.*Input')); @@ -747,7 +747,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('channel.send[(]null[)]')); }); @@ -788,7 +788,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' List? field1;')); @@ -815,7 +815,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' Map? field1;')); @@ -844,7 +844,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doit(List arg')); }); @@ -872,7 +872,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doit(List arg')); }); @@ -896,7 +896,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future> doit(')); expect(code, @@ -931,7 +931,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('List doit(')); expect( @@ -958,7 +958,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit()')); expect(code, contains('return (replyList[0] as int?);')); @@ -983,7 +983,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future?> doit()')); expect(code, @@ -1008,7 +1008,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit()')); expect(code, contains('return (replyList[0] as int?);')); @@ -1031,7 +1031,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('int? doit();')); expect(code, contains('final int? output = api.doit();')); @@ -1055,7 +1055,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit();')); expect(code, contains('final int? output = await api.doit();')); @@ -1078,7 +1078,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -1107,7 +1107,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit(int? arg_foo) async {')); }); @@ -1133,7 +1133,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('void doit(int? foo);')); }); @@ -1151,7 +1151,7 @@ name: foobar Root(classes: [], apis: [], enums: []); final StringBuffer sink = StringBuffer(); generateTestDart( - const DartOptions(), + DartOptions(), root, sink, dartOutPath: path.join(foo.path, 'bar.dart'), @@ -1238,7 +1238,7 @@ name: foobar ], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('///$comment')); @@ -1273,7 +1273,7 @@ name: foobar enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('extends StandardMessageCodec'))); expect(code, contains('StandardMessageCodec')); @@ -1316,7 +1316,7 @@ name: foobar ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(const DartOptions(), root, sink); + generateDart(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('extends StandardMessageCodec')); }); @@ -1355,7 +1355,7 @@ name: foobar ); final StringBuffer sink = StringBuffer(); generateTestDart( - const DartOptions(), + DartOptions(), root, sink, dartOutPath: 'code.dart', diff --git a/packages/pigeon/tool/shared/generation.dart b/packages/pigeon/tool/shared/generation.dart index 01efa09c8f5..3e6ced166f8 100644 --- a/packages/pigeon/tool/shared/generation.dart +++ b/packages/pigeon/tool/shared/generation.dart @@ -168,7 +168,7 @@ Future runPigeon({ copyrightHeader: './copyright_header.txt', dartOut: dartOut, dartTestOut: dartTestOut, - dartOptions: const DartOptions(), + dartOptions: DartOptions(), cppHeaderOut: cppHeaderOut, cppSourceOut: cppSourceOut, cppOptions: CppOptions(namespace: cppNamespace), From af5e0e63da9f2e8e39d2a0a6873fb467e1d9dfde Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 09:56:36 -0800 Subject: [PATCH 14/87] Moves write header to generator class method --- packages/pigeon/lib/cpp_generator.dart | 49 ++++++++++++---- packages/pigeon/lib/dart_generator.dart | 53 +++++++++++------ packages/pigeon/lib/generator.dart | 20 ++++++- packages/pigeon/lib/java_generator.dart | 34 +++++++---- packages/pigeon/lib/kotlin_generator.dart | 34 +++++++---- packages/pigeon/lib/objc_generator.dart | 69 +++++++++++++++-------- packages/pigeon/lib/swift_generator.dart | 33 +++++++---- 7 files changed, 202 insertions(+), 90 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 6bc120bc2d3..689dbfed950 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -73,8 +73,17 @@ class CppHeaderGenerator extends Generator { /// Generates Cpp header files with specified [CppOptions] @override void generate(CppOptions languageOptions, Root root, StringSink sink) { + final Indent indent = Indent(sink); + + writeFileHeaders(languageOptions, root, sink, indent); generateCppHeader( - languageOptions.cppHeaderOut, languageOptions, root, sink); + languageOptions.cppHeaderOut, languageOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + CppOptions languageOptions, Root root, StringSink sink, Indent indent) { + writeCppHeaderHeader(languageOptions, root, sink, indent); } } @@ -86,7 +95,16 @@ class CppSourceGenerator extends Generator { /// Generates Cpp files with specified [CppOptions] @override void generate(CppOptions languageOptions, Root root, StringSink sink) { - generateCppSource(languageOptions, root, sink); + final Indent indent = Indent(sink); + + writeFileHeaders(languageOptions, root, sink, indent); + generateCppSource(languageOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + CppOptions languageOptions, Root root, StringSink sink, Indent indent) { + writeCppSourceHeader(languageOptions, root, sink, indent); } } @@ -1035,14 +1053,18 @@ void _writeSystemHeaderIncludeBlock(Indent indent, List headers) { } } -/// Generates the ".h" file for the AST represented by [root] to [sink] with the -/// provided [options] and [headerFileName]. -void generateCppHeader( - String? headerFileName, CppOptions options, Root root, StringSink sink) { - final Indent indent = Indent(sink); +/// Writes Cpp header file header to sink. +void writeCppHeaderHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); } +} + +/// Generates the ".h" file for the AST represented by [root] to [sink] with the +/// provided [options] and [headerFileName]. +void generateCppHeader(String? headerFileName, CppOptions options, Root root, + StringSink sink, Indent indent) { indent.writeln('$_commentPrefix $generatedCodeWarning'); indent.writeln('$_commentPrefix $seeAlsoWarning'); indent.addln(''); @@ -1126,13 +1148,18 @@ void generateCppHeader( indent.writeln('#endif // $guardName'); } -/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateCppSource(CppOptions options, Root root, StringSink sink) { - final Indent indent = Indent(sink); +/// Writes Cpp source file header to sink. +void writeCppSourceHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); } +} + +/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the +/// provided [options]. +void generateCppSource( + CppOptions options, Root root, StringSink sink, Indent indent) { indent.writeln('$_commentPrefix $generatedCodeWarning'); indent.writeln('$_commentPrefix $seeAlsoWarning'); indent.addln(''); diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 604becc9c30..90b31c7b419 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -78,7 +78,16 @@ class DartGenerator extends Generator { /// Generates Dart files with specified [DartOptions] @override void generate(DartOptions languageOptions, Root root, StringSink sink) { - generateDart(languageOptions, root, sink); + final Indent indent = Indent(sink); + + writeFileHeaders(languageOptions, root, sink, indent); + generateDart(languageOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + DartOptions languageOptions, Root root, StringSink sink, Indent indent) { + writeHeader(languageOptions, root, sink, indent); } } @@ -90,16 +99,27 @@ class DartTestGenerator extends Generator { /// Generates Dart files with specified [DartOptions] @override void generate(DartOptions languageOptions, Root root, StringSink sink) { + final Indent indent = Indent(sink); + final String dartOutPath = languageOptions.dartOutPath ?? ''; final String testOutPath = languageOptions.testOutPath ?? ''; + + writeFileHeaders(languageOptions, root, sink, indent); generateTestDart( languageOptions, root, sink, + indent, dartOutPath: dartOutPath, testOutPath: testOutPath, ); } + + @override + void writeFileHeaders( + DartOptions languageOptions, Root root, StringSink sink, Indent indent) { + writeHeader(languageOptions, root, sink, indent); + } } String _escapeForDartSingleQuotedString(String raw) { @@ -502,25 +522,25 @@ String _addGenericTypesNullable(TypeDeclaration type) { return type.isNullable ? '$genericdType?' : genericdType; } +/// Writes file header to sink. +void writeHeader(DartOptions opt, Root root, StringSink sink, Indent indent) { + if (opt.copyrightHeader != null) { + addLines(indent, opt.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.writeln( + '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import', + ); +} + /// Generates Dart source code for the given AST represented by [root], /// outputting the code to [sink]. -void generateDart(DartOptions opt, Root root, StringSink sink) { +void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) { final List customClassNames = root.classes.map((Class x) => x.name).toList(); final List customEnumNames = root.enums.map((Enum x) => x.name).toList(); - final Indent indent = Indent(sink); - - void writeHeader() { - if (opt.copyrightHeader != null) { - addLines(indent, opt.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.writeln( - '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import', - ); - } void writeEnums() { for (final Enum anEnum in root.enums) { @@ -679,7 +699,6 @@ $resultAt != null } } - writeHeader(); writeImports(); writeEnums(); for (final Class klass in root.classes) { @@ -748,11 +767,11 @@ String _posixify(String inputPath) { void generateTestDart( DartOptions opt, Root root, - StringSink sink, { + StringSink sink, + Indent indent, { required String dartOutPath, required String testOutPath, }) { - final Indent indent = Indent(sink); if (opt.copyrightHeader != null) { addLines(indent, opt.copyrightHeader!, linePrefix: '// '); } diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 0979627b3ac..61b3587c3cf 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'ast.dart'; +import 'generator_tools.dart'; /// A Super class of generator classes. /// @@ -12,5 +13,22 @@ abstract class Generator { const Generator(); /// Generates files for specified language with specified [languageOptions] - void generate(T languageOptions, Root root, StringSink sink); + /// + /// This method, when overridden, should follow a generic structure that is currently: + /// 1. Create Indent + /// 2. Write File Headers + /// 3. Generate File + void generate( + T languageOptions, + Root root, + StringSink sink, + ); + + /// Adds specified file headers. + void writeFileHeaders( + T languageOptions, + Root root, + StringSink sink, + Indent indent, + ); } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 00293bfc0e8..310125937da 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -93,7 +93,16 @@ class JavaGenerator extends Generator { /// Generates Java files with specified [JavaOptions] @override void generate(JavaOptions languageOptions, Root root, StringSink sink) { - generateJava(languageOptions, root, sink); + final Indent indent = Indent(sink); + + writeFileHeaders(languageOptions, root, sink, indent); + generateJava(languageOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + JavaOptions languageOptions, Root root, StringSink sink, Indent indent) { + writeHeader(languageOptions, root, sink, indent); } } @@ -534,22 +543,24 @@ String _castObject( } } +/// Writes file header to sink. +void writeHeader( + JavaOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); +} + /// Generates the ".java" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateJava(JavaOptions options, Root root, StringSink sink) { +void generateJava( + JavaOptions options, Root root, StringSink sink, Indent indent) { final Set rootClassNameSet = root.classes.map((Class x) => x.name).toSet(); final Set rootEnumNameSet = root.enums.map((Enum x) => x.name).toSet(); - final Indent indent = Indent(sink); - - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - } void writeImports() { indent.writeln('import android.util.Log;'); @@ -764,7 +775,6 @@ void generateJava(JavaOptions options, Root root, StringSink sink) { }'''); } - writeHeader(); indent.addln(''); if (options.package != null) { indent.writeln('package ${options.package};'); diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 99690a4ac92..abdf83aa74f 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -73,7 +73,16 @@ class KotlinGenerator extends Generator { /// Generates Kotlin files with specified [KotlinOptions] @override void generate(KotlinOptions languageOptions, Root root, StringSink sink) { - generateKotlin(languageOptions, root, sink); + final Indent indent = Indent(sink); + + writeFileHeaders(languageOptions, root, sink, indent); + generateKotlin(languageOptions, root, sink, indent); + } + + @override + void writeFileHeaders(KotlinOptions languageOptions, Root root, + StringSink sink, Indent indent) { + writeHeader(languageOptions, root, sink, indent); } } @@ -447,28 +456,30 @@ String _nullsafeKotlinTypeForDartType(TypeDeclaration type) { return '${_kotlinTypeForDartType(type)}$nullSafe'; } +/// Writes file header to sink. +void writeHeader( + KotlinOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); +} + /// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateKotlin(KotlinOptions options, Root root, StringSink sink) { +void generateKotlin( + KotlinOptions options, Root root, StringSink sink, Indent indent) { final Set rootClassNameSet = root.classes.map((Class x) => x.name).toSet(); final Set rootEnumNameSet = root.enums.map((Enum x) => x.name).toSet(); - final Indent indent = Indent(sink); HostDatatype getHostDatatype(NamedType field) { return getFieldHostDatatype(field, root.classes, root.enums, (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); } - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - } - void writeImports() { indent.writeln('import android.util.Log'); indent.writeln('import io.flutter.plugin.common.BasicMessageChannel'); @@ -663,7 +674,6 @@ void generateKotlin(KotlinOptions options, Root root, StringSink sink) { }); } - writeHeader(); indent.addln(''); if (options.package != null) { indent.writeln('package ${options.package}'); diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 0d376e1a582..5b59377a8dd 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -72,7 +72,16 @@ class ObjcHeaderGenerator extends Generator { /// Generates Objc header files with specified [ObjcOptions] @override void generate(ObjcOptions languageOptions, Root root, StringSink sink) { - generateObjcHeader(languageOptions, root, sink); + final Indent indent = Indent(sink); + + writeFileHeaders(languageOptions, root, sink, indent); + generateObjcHeader(languageOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + ObjcOptions languageOptions, Root root, StringSink sink, Indent indent) { + writeObjcHeaderHeader(languageOptions, root, sink, indent); } } @@ -84,7 +93,16 @@ class ObjcSourceGenerator extends Generator { /// Generates Objc files with specified [ObjcOptions] @override void generate(ObjcOptions languageOptions, Root root, StringSink sink) { - generateObjcSource(languageOptions, root, sink); + final Indent indent = Indent(sink); + + writeObjcSourceHeader(languageOptions, root, sink, indent); + generateObjcSource(languageOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + ObjcOptions languageOptions, Root root, StringSink sink, Indent indent) { + writeObjcSourceHeader(languageOptions, root, sink, indent); } } @@ -555,19 +573,20 @@ void _writeFlutterApiDeclaration( indent.writeln('@end'); } -/// Generates the ".h" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateObjcHeader(ObjcOptions options, Root root, StringSink sink) { - final Indent indent = Indent(sink); - - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); +/// Writes Objc header file header to sink. +void writeObjcHeaderHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); +} +/// Generates the ".h" file for the AST represented by [root] to [sink] with the +/// provided [options]. +void generateObjcHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { void writeImports() { indent.writeln('#import '); } @@ -596,7 +615,6 @@ void generateObjcHeader(ObjcOptions options, Root root, StringSink sink) { }); } - writeHeader(); writeImports(); writeForwardDeclarations(); indent.writeln(''); @@ -898,22 +916,24 @@ void _writeFlutterApiSource( indent.writeln('@end'); } +/// Writes Objc Source file header to sink. +void writeObjcSourceHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); +} + /// Generates the ".m" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateObjcSource(ObjcOptions options, Root root, StringSink sink) { - final Indent indent = Indent(sink); +void generateObjcSource( + ObjcOptions options, Root root, StringSink sink, Indent indent) { final List classNames = root.classes.map((Class x) => x.name).toList(); final List enumNames = root.enums.map((Enum x) => x.name).toList(); - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - } - void writeImports() { indent.writeln('#import "${options.header}"'); indent.writeln('#import '); @@ -1030,7 +1050,6 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { } } - writeHeader(); writeImports(); indent.writeln(''); writeArcEnforcer(); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index b25931c03e3..8ea5ed88065 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -56,7 +56,15 @@ class SwiftGenerator extends Generator { /// Generates Swift files with specified [SwiftOptions] @override void generate(SwiftOptions languageOptions, Root root, StringSink sink) { - generateSwift(languageOptions, root, sink); + final Indent indent = Indent(sink); + writeFileHeaders(languageOptions, root, sink, indent); + generateSwift(languageOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + SwiftOptions languageOptions, Root root, StringSink sink, Indent indent) { + writeHeader(languageOptions, root, sink, indent); } } @@ -442,28 +450,30 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { return '${_swiftTypeForDartType(type)}$nullSafe'; } +/// Writes file header to sink. +void writeHeader( + SwiftOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); +} + /// Generates the ".swift" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateSwift(SwiftOptions options, Root root, StringSink sink) { +void generateSwift( + SwiftOptions options, Root root, StringSink sink, Indent indent) { final Set rootClassNameSet = root.classes.map((Class x) => x.name).toSet(); final Set rootEnumNameSet = root.enums.map((Enum x) => x.name).toSet(); - final Indent indent = Indent(sink); HostDatatype getHostDatatype(NamedType field) { return getFieldHostDatatype(field, root.classes, root.enums, (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); } - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - } - void writeImports() { indent.writeln('import Foundation'); indent.format(''' @@ -632,7 +642,6 @@ import FlutterMacOS }); } - writeHeader(); indent.addln(''); writeImports(); indent.addln(''); From ae817ad221d8f05293e97536904ae24816466cf8 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 09:56:48 -0800 Subject: [PATCH 15/87] Updates tests to use new generator class --- packages/pigeon/test/cpp_generator_test.dart | 81 ++++-- packages/pigeon/test/dart_generator_test.dart | 153 ++++++---- packages/pigeon/test/java_generator_test.dart | 117 +++++--- .../pigeon/test/kotlin_generator_test.dart | 99 ++++--- packages/pigeon/test/objc_generator_test.dart | 261 +++++++++++------- .../pigeon/test/swift_generator_test.dart | 99 ++++--- 6 files changed, 528 insertions(+), 282 deletions(-) diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index d089b0a4480..4e4a3a1a354 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -45,7 +45,8 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Input')); expect(code, contains('class Output')); @@ -53,7 +54,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Input::Input()')); expect(code, contains('Output::Output')); @@ -101,7 +103,8 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Method name and argument names should be adjusted. expect(code, contains(' DoSomething(const Input& some_input)')); @@ -116,7 +119,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('pointer_input_field')); expect(code, contains('Output::output_field()')); @@ -144,7 +148,8 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect( @@ -184,7 +189,8 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect( @@ -238,14 +244,16 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('){'))); expect(code, isNot(contains('const{'))); } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('){'))); expect(code, isNot(contains('const{'))); @@ -271,7 +279,8 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains(''' #include @@ -286,7 +295,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(header: 'a_header.h'), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(header: 'a_header.h'), root, sink); final String code = sink.toString(); expect(code, contains(''' #include "a_header.h" @@ -322,14 +332,16 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(namespace: 'foo'), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(namespace: 'foo'), root, sink); final String code = sink.toString(); expect(code, contains('namespace foo {')); expect(code, contains('} // namespace foo')); } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(namespace: 'foo'), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(namespace: 'foo'), root, sink); final String code = sink.toString(); expect(code, contains('namespace foo {')); expect(code, contains('} // namespace foo')); @@ -390,7 +402,8 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Getters should return const pointers. expect(code, contains('const bool* nullable_bool()')); @@ -422,7 +435,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Getters extract optionals. expect(code, @@ -521,7 +535,8 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // POD getters should return copies references. expect(code, contains('bool non_nullable_bool()')); @@ -546,7 +561,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Getters just return the value. expect(code, contains('return non_nullable_bool_;')); @@ -644,7 +660,8 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect( code, contains('ErrorOr> ReturnNullableBool()')); @@ -749,7 +766,8 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('ErrorOr ReturnBool()')); expect(code, contains('ErrorOr ReturnInt()')); @@ -825,7 +843,8 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -838,7 +857,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Most types should just use get_if, since the parameter is a pointer, // and get_if will automatically handle null values (since a null @@ -943,7 +963,8 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -956,7 +977,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Most types should extract references. Since the type is non-nullable, // there's only one possible type. @@ -1010,7 +1032,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // A bare 'auto' here would create a copy, not a reference, which is // ineffecient. @@ -1122,7 +1145,8 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateCppHeader('foo', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(cppHeaderOut: 'foo'), root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('//$comment')); @@ -1157,7 +1181,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : public flutter::StandardCodecSerializer'))); }); @@ -1199,7 +1224,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + final CppHeaderGenerator generator = CppHeaderGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains(' : public flutter::StandardCodecSerializer')); }); @@ -1268,7 +1294,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppSourceGenerator generator = CppSourceGenerator(); + generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('reply(wrap'))); expect(code, contains('reply(flutter::EncodableValue(')); diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index 38442ccd358..5eb9bdd9fc6 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -29,7 +29,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' dataType1? field1;')); @@ -49,7 +50,8 @@ void main() { enums: [anEnum], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum Foobar')); expect(code, contains(' one,')); @@ -92,7 +94,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('Future doSomething(Input arg_input)')); @@ -118,7 +121,8 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('Future add(int arg_x, int arg_y)')); @@ -145,7 +149,8 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('int add(int x, int y)')); @@ -182,7 +187,8 @@ void main() { ) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -224,7 +230,8 @@ void main() { ) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -276,7 +283,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('abstract class Api')); expect(code, contains('static void setup(Api')); @@ -310,7 +318,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doSomething')); expect(code, contains('return;')); @@ -343,7 +352,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); // The next line verifies that we're not setting a variable to the value of "doSomething", but // ignores the line where we assert the value of the argument isn't null, since on that line @@ -373,7 +383,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('output.*=.*doSomething[(][)]')); expect(code, contains('Output doSomething();')); @@ -415,7 +426,8 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum1?.index,')); expect(code, contains('? Enum.values[result[0]! as int]')); @@ -442,7 +454,8 @@ void main() { ]) ]); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum Foo {')); expect(code, contains('Future bar(Foo? arg_foo) async')); @@ -485,7 +498,8 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum1.index,')); expect(code, contains('enum1: Enum.values[result[0]! as int]')); @@ -512,7 +526,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('channel.send[(]null[)]')); }); @@ -570,7 +585,8 @@ void main() { ], enums: []); final StringBuffer mainCodeSink = StringBuffer(); final StringBuffer testCodeSink = StringBuffer(); - generateDart(DartOptions(), root, mainCodeSink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, mainCodeSink); final String mainCode = mainCodeSink.toString(); expect(mainCode, isNot(contains(r"import 'fo\'o.dart';"))); expect(mainCode, contains('class Api {')); @@ -578,12 +594,15 @@ void main() { expect(mainCode, isNot(contains('.ApiMock.doSomething'))); expect(mainCode, isNot(contains("'${Keys.result}': output"))); expect(mainCode, isNot(contains('return [];'))); - generateTestDart( - DartOptions(), + + final DartTestGenerator testGenerator = DartTestGenerator(); + testGenerator.generate( + DartOptions( + dartOutPath: "fo'o.dart", + testOutPath: 'test.dart', + ), root, testCodeSink, - dartOutPath: "fo'o.dart", - testOutPath: 'test.dart', ); final String testCode = testCodeSink.toString(); expect(testCode, contains(r"import 'fo\'o.dart';")); @@ -631,7 +650,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('abstract class Api')); expect(code, contains('Future doSomething(Input arg0);')); @@ -675,7 +695,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.s*doSomething'))); expect(code, contains('await api.doSomething(')); @@ -719,7 +740,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, matches('Output.*doSomething.*Input')); @@ -747,7 +769,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('channel.send[(]null[)]')); }); @@ -759,11 +782,10 @@ void main() { test('header', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateDart( - DartOptions(copyrightHeader: makeIterable('hello world')), - root, - sink, - ); + + final DartGenerator generator = DartGenerator(); + generator.generate( + DartOptions(copyrightHeader: makeIterable('hello world')), root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -788,7 +810,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' List? field1;')); @@ -815,7 +838,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' Map? field1;')); @@ -844,7 +868,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doit(List arg')); }); @@ -872,7 +897,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doit(List arg')); }); @@ -896,7 +922,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future> doit(')); expect(code, @@ -931,7 +958,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('List doit(')); expect( @@ -958,7 +986,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit()')); expect(code, contains('return (replyList[0] as int?);')); @@ -983,7 +1012,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future?> doit()')); expect(code, @@ -1008,7 +1038,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit()')); expect(code, contains('return (replyList[0] as int?);')); @@ -1031,7 +1062,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('int? doit();')); expect(code, contains('final int? output = api.doit();')); @@ -1055,7 +1087,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit();')); expect(code, contains('final int? output = await api.doit();')); @@ -1078,7 +1111,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -1107,7 +1141,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit(int? arg_foo) async {')); }); @@ -1133,7 +1168,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('void doit(int? foo);')); }); @@ -1150,12 +1186,14 @@ name: foobar final Root root = Root(classes: [], apis: [], enums: []); final StringBuffer sink = StringBuffer(); - generateTestDart( - DartOptions(), + final DartTestGenerator testGenerator = DartTestGenerator(); + testGenerator.generate( + DartOptions( + dartOutPath: path.join(foo.path, 'bar.dart'), + testOutPath: path.join(tempDir.path, 'test', 'bar_test.dart'), + ), root, sink, - dartOutPath: path.join(foo.path, 'bar.dart'), - testOutPath: path.join(tempDir.path, 'test', 'bar_test.dart'), ); final String code = sink.toString(); expect(code, contains("import 'package:foobar/foo/bar.dart';")); @@ -1238,7 +1276,8 @@ name: foobar ], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('///$comment')); @@ -1273,7 +1312,8 @@ name: foobar enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('extends StandardMessageCodec'))); expect(code, contains('StandardMessageCodec')); @@ -1316,7 +1356,8 @@ name: foobar ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('extends StandardMessageCodec')); }); @@ -1354,13 +1395,17 @@ name: foobar ], ); final StringBuffer sink = StringBuffer(); - generateTestDart( - DartOptions(), + + final DartTestGenerator testGenerator = DartTestGenerator(); + testGenerator.generate( + DartOptions( + dartOutPath: 'code.dart', + testOutPath: 'test.dart', + ), root, sink, - dartOutPath: 'code.dart', - testOutPath: 'test.dart', ); + final String testCode = sink.toString(); expect( testCode, diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index bfcea98cfe2..f2a25288754 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -27,7 +27,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public class Messages')); expect(code, contains('public static class Foobar')); @@ -55,7 +56,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Foobar')); expect(code, contains(' ONE(0),')); @@ -86,7 +88,8 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages', package: 'com.google.foobar'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('package com.google.foobar;')); expect(code, contains('ArrayList toList()')); @@ -129,7 +132,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public interface Api')); expect(code, matches('Output.*doSomething.*Input')); @@ -200,7 +204,8 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('private @Nullable Boolean aBool;')); expect(code, contains('private @Nullable Long aInt;')); @@ -249,7 +254,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Api')); expect(code, matches('doSomething.*Input.*Output')); @@ -283,7 +289,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.*doSomething'))); expect(code, contains('doSomething(')); @@ -317,7 +324,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Reply')); expect(code, contains('callback.reply(null)')); @@ -345,7 +353,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Output doSomething()')); expect(code, contains('api.doSomething()')); @@ -373,7 +382,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doSomething(Reply')); expect(code, contains('channel.send(null')); @@ -392,7 +402,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Foobar')); expect(code, contains('private @Nullable List field1;')); @@ -411,7 +422,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Foobar')); expect(code, contains('private @Nullable Map field1;')); @@ -447,7 +459,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public class Messages')); expect(code, contains('public static class Outer')); @@ -498,7 +511,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public interface Api')); expect(code, contains('public interface Result {')); @@ -549,7 +563,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Api')); expect(code, matches('doSomething.*Input.*Output')); @@ -582,7 +597,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Enum1')); expect(code, contains(' ONE(0),')); @@ -621,7 +637,8 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Foo')); expect( @@ -641,7 +658,8 @@ void main() { className: 'Messages', copyrightHeader: makeIterable('hello world'), ); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -667,7 +685,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains('List field1;')); @@ -695,7 +714,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains('Map field1;')); @@ -725,7 +745,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(@NonNull List arg')); }); @@ -754,7 +775,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(@NonNull List arg')); }); @@ -779,7 +801,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('List doit(')); expect(code, contains('List output =')); @@ -805,7 +828,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(Reply> callback)')); expect(code, contains('List output =')); @@ -828,7 +852,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(Reply callback)')); expect( @@ -858,7 +883,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Messages')); expect(code, contains('Long add(@NonNull Long x, @NonNull Long y)')); @@ -889,7 +915,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Api'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Object xArg = args.get(0)')); }); @@ -915,7 +942,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Messages')); expect(code, contains('BasicMessageChannel channel')); @@ -947,7 +975,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( code, @@ -973,7 +1002,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('@Nullable Long doit();')); }); @@ -997,7 +1027,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); // Java doesn't accept nullability annotations in type arguments. expect(code, contains('Result')); @@ -1025,7 +1056,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains(' void doit(@Nullable Long foo);')); }); @@ -1052,7 +1084,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1083,7 +1116,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1108,7 +1142,8 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages', useGeneratedAnnotation: true); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('@javax.annotation.Generated("dev.flutter.pigeon")')); }); @@ -1125,7 +1160,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains('@javax.annotation.Generated("dev.flutter.pigeon")'))); @@ -1207,7 +1243,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { // This regex finds the comment only between the open and close comment block @@ -1247,7 +1284,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(' extends StandardMessageCodec'))); expect(code, contains('StandardMessageCodec')); @@ -1291,7 +1329,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains(' extends StandardMessageCodec')); }); diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 4653410837e..96056c1b1b1 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -27,7 +27,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar (')); expect(code, contains('val field1: Long? = null')); @@ -50,7 +51,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Foobar(val raw: Int) {')); expect(code, contains('ONE(0)')); @@ -78,7 +80,8 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Foo(val raw: Int) {')); expect(code, contains('val fooArg = Foo.ofRaw(args[0] as Int)')); @@ -124,7 +127,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('interface Api')); expect(code, contains('fun doSomething(input: Input): Output')); @@ -213,7 +217,8 @@ void main() { final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val aBool: Boolean? = null')); expect(code, contains('val aInt: Long? = null')); @@ -265,7 +270,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api(private val binaryMessenger: BinaryMessenger)')); @@ -302,7 +308,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('.*doSomething(.*) ->'))); expect(code, matches('doSomething(.*)')); @@ -338,7 +345,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('callback: () -> Unit')); expect(code, contains('callback()')); @@ -367,7 +375,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doSomething(): Output')); expect(code, contains('wrapped = listOf(api.doSomething())')); @@ -398,7 +407,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doSomething(callback: (Output) -> Unit)')); expect(code, contains('channel.send(null)')); @@ -418,7 +428,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); expect(code, contains('val field1: List? = null')); @@ -438,7 +449,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); expect(code, contains('val field1: Map? = null')); @@ -476,7 +488,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Outer')); expect(code, contains('data class Nested')); @@ -529,7 +542,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('interface Api')); expect(code, contains('api.doSomething(argArg) {')); @@ -577,7 +591,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, matches('fun doSomething.*Input.*callback.*Output.*Unit')); @@ -610,7 +625,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Enum1(val raw: Int)')); expect(code, contains('ONE(0)')); @@ -627,7 +643,8 @@ void main() { final KotlinOptions kotlinOptions = KotlinOptions( copyrightHeader: makeIterable('hello world'), ); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -654,7 +671,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); expect(code, contains('val field1: List')); @@ -683,7 +701,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); expect(code, contains('val field1: Map')); @@ -714,7 +733,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(arg: List')); }); @@ -744,7 +764,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(argArg: List')); }); @@ -769,7 +790,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(): List')); expect(code, contains('wrapped = listOf(api.doit())')); @@ -796,7 +818,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(callback: (List) -> Unit')); expect(code, contains('val result = it as List')); @@ -824,7 +847,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun add(x: Long, y: Long): Long')); expect(code, contains('val args = message as List')); @@ -861,7 +885,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val channel = BasicMessageChannel')); expect(code, contains('val result = it as Long')); @@ -889,7 +914,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(): Long?')); }); @@ -913,7 +939,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(callback: (Long?) -> Unit')); }); @@ -940,7 +967,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect( code, @@ -970,7 +998,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(fooArg: Long?, callback: () -> Unit')); }); @@ -1005,7 +1034,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val input: String\n')); }); @@ -1086,7 +1116,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { // This regex finds the comment only between the open and close comment block @@ -1126,7 +1157,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : StandardMessageCodec() '))); expect(code, contains('StandardMessageCodec')); @@ -1170,7 +1202,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains(' : StandardMessageCodec() ')); }); diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index cf83029338e..cc33903df77 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -17,7 +17,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, matches('@property.*NSString.*field1')); @@ -32,7 +33,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Foobar')); @@ -49,7 +51,8 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, Enum1) {')); expect(code, contains(' Enum1One = 0,')); @@ -67,7 +70,8 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(prefix: 'PREFIX'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(header: 'PREFIX'), root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, PREFIXEnum1) {')); expect(code, contains(' PREFIXEnum1One = 0,')); @@ -103,7 +107,8 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Foobar')); @@ -135,13 +140,15 @@ void main() { final StringBuffer sink = StringBuffer(); const ObjcOptions options = ObjcOptions(header: 'foo.h', prefix: 'AC'); { - generateObjcHeader(options, root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(options, root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, ACFoo)')); expect(code, contains(':(ACFoo)foo error:')); } { - generateObjcSource(options, root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -204,7 +211,8 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@property(nonatomic, assign) Enum1 enum1')); }); @@ -236,7 +244,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Input')); expect(code, contains('@interface Output')); @@ -275,7 +284,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Input')); @@ -322,7 +332,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, contains('@class FlutterStandardTypedData;')); @@ -350,7 +361,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@implementation Foobar')); expect(code, @@ -371,7 +383,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@property(nonatomic, strong, nullable) Input * nested;')); @@ -391,7 +404,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect( code, @@ -410,7 +424,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(prefix: 'ABC'), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('@interface ABCFoobar')); }); @@ -424,7 +439,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(prefix: 'ABC'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('@implementation ABCFoobar')); }); @@ -458,7 +474,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(prefix: 'ABC'), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, matches('property.*ABCInput')); expect(code, matches('ABCNested.*doSomething.*ABCInput')); @@ -494,7 +511,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(prefix: 'ABC'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('ABCInput fromList')); expect(code, matches(r'ABCInput.*=.*args.*0.*\;')); @@ -530,7 +548,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@interface Api : NSObject')); expect( @@ -569,7 +588,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@implementation Api')); expect(code, matches('void.*doSomething.*Input.*Output.*{')); @@ -598,8 +618,10 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + final String code = sink.toString(); expect(code, contains('(void)doSomething:')); }); @@ -627,7 +649,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.*doSomething'))); @@ -658,7 +681,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('completion:(void(^)(NSError *_Nullable))')); @@ -687,7 +711,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('completion:(void(^)(NSError *_Nullable))')); @@ -711,7 +736,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, matches('ABCOutput.*doSomethingWithError:[(]FlutterError')); @@ -734,7 +760,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, matches('output.*=.*api doSomethingWithError:&error')); @@ -757,7 +784,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -783,7 +811,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -802,7 +831,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, matches('@property.*NSArray.*field1')); @@ -817,7 +847,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, matches('@property.*NSDictionary.*field1')); @@ -838,7 +869,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect( @@ -867,7 +899,8 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('(NSDictionary *)foo')); }); @@ -901,7 +934,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -940,7 +974,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -967,7 +1002,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -987,7 +1023,8 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1026,7 +1063,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1064,7 +1102,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1084,7 +1123,8 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1111,7 +1151,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1127,14 +1168,14 @@ void main() { test('source copyright', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - ObjcOptions( - header: 'foo.h', - prefix: 'ABC', - copyrightHeader: makeIterable('hello world')), - root, - sink, - ); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( + ObjcOptions( + header: 'foo.h', + prefix: 'ABC', + copyrightHeader: makeIterable('hello world')), + root, + sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -1142,14 +1183,14 @@ void main() { test('header copyright', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - ObjcOptions( - header: 'foo.h', - prefix: 'ABC', - copyrightHeader: makeIterable('hello world')), - root, - sink, - ); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( + ObjcOptions( + header: 'foo.h', + prefix: 'ABC', + copyrightHeader: makeIterable('hello world')), + root, + sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -1174,7 +1215,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('NSArray * field1')); @@ -1204,14 +1246,16 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1245,14 +1289,16 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); @@ -1289,7 +1335,8 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *> *)arg')); @@ -1316,7 +1363,8 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1324,7 +1372,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('NSArray *output =')); @@ -1351,7 +1400,8 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1359,7 +1409,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1388,7 +1439,8 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1398,7 +1450,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('NSArray *args = message;')); @@ -1433,7 +1486,8 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1443,7 +1497,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('NSArray *args = message;')); @@ -1476,7 +1531,8 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1486,7 +1542,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); expect( @@ -1530,15 +1587,18 @@ void main() { final Root divideRoot = getDivideRoot(ApiLocation.host); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*error.*;')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); + final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*error.*;')); } @@ -1548,21 +1608,18 @@ void main() { final Root divideRoot = getDivideRoot(ApiLocation.flutter); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), - divideRoot, - sink, - ); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate( + const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*completion.*;')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), - divideRoot, - sink, - ); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate( + const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); + final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*completion.*{')); } @@ -1577,7 +1634,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, contains('@property(nonatomic, copy) NSString * field1')); @@ -1600,7 +1658,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -1625,7 +1684,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, matches(r'doitWithCompletion.*NSNumber \*_Nullable')); }); @@ -1647,7 +1707,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, matches(r'nullable NSNumber.*doitWithError')); }); @@ -1674,13 +1735,15 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doitFoo:(nullable NSNumber *)foo')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('NSNumber *arg_foo = GetNullableObjectAtIndex(args, 0);')); @@ -1709,13 +1772,15 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doitFoo:(nullable NSNumber *)foo')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('- (void)doitFoo:(nullable NSNumber *)arg_foo')); } @@ -1739,7 +1804,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -1823,7 +1889,8 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('///$comment')); @@ -1858,7 +1925,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : FlutterStandardReader'))); }); @@ -1900,7 +1968,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); + generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains(' : FlutterStandardReader')); }); diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index 74c8aad15ca..305ca203fe7 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -26,7 +26,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: Int32? = nil')); @@ -49,7 +50,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Foobar: Int')); expect(code, contains(' case one = 0')); @@ -77,7 +79,8 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Foo: Int')); expect(code, contains('let fooArg = Foo(rawValue: args[0] as! Int)!')); @@ -120,7 +123,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('protocol Api')); expect(code, matches('func doSomething.*Input.*Output')); @@ -183,7 +187,8 @@ void main() { final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('var aBool: Bool? = nil')); expect(code, contains('var aInt: Int32? = nil')); @@ -232,7 +237,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('init(binaryMessenger: FlutterBinaryMessenger)')); @@ -267,7 +273,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('.*doSomething(.*) ->'))); expect(code, matches('doSomething(.*)')); @@ -301,7 +308,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('completion: @escaping () -> Void')); expect(code, contains('completion()')); @@ -329,7 +337,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doSomething() -> Output')); expect(code, contains('let result = api.doSomething()')); @@ -358,7 +367,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doSomething(completion: @escaping (Output) -> Void)')); @@ -378,7 +388,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: [Any?]? = nil')); @@ -397,7 +408,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: [AnyHashable: Any?]? = nil')); @@ -433,7 +445,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Outer')); expect(code, contains('struct Nested')); @@ -481,7 +494,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('protocol Api')); expect(code, contains('api.doSomething(arg: argArg) { result in')); @@ -526,7 +540,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, matches('func doSomething.*Input.*completion.*Output.*Void')); @@ -558,7 +573,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Enum1: Int')); expect(code, contains('case one = 0')); @@ -575,7 +591,8 @@ void main() { final SwiftOptions swiftOptions = SwiftOptions( copyrightHeader: makeIterable('hello world'), ); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -601,7 +618,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: [Int32?]')); @@ -629,7 +647,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: [String?: String?]')); @@ -659,7 +678,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(arg: [Int32?]')); }); @@ -688,7 +708,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(arg argArg: [Int32?]')); }); @@ -713,7 +734,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit() -> [Int32?]')); expect(code, contains('let result = api.doit()')); @@ -740,7 +762,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect( code, contains('func doit(completion: @escaping ([Int32?]) -> Void')); @@ -769,7 +792,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func add(x: Int32, y: Int32) -> Int32')); expect(code, contains('let args = message as! [Any?]')); @@ -800,7 +824,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('let channel = FlutterBasicMessageChannel')); expect(code, contains('let result = response as! Int32')); @@ -830,7 +855,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit() -> Int32?')); }); @@ -854,7 +880,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(completion: @escaping (Int32?) -> Void')); }); @@ -881,7 +908,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('let fooArg = args[0] as? Int32')); }); @@ -908,7 +936,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect( code, @@ -944,7 +973,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('var input: String\n')); }); @@ -1025,7 +1055,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('///$comment')); @@ -1061,7 +1092,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(': FlutterStandardReader '))); }); @@ -1104,7 +1136,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains(': FlutterStandardReader ')); }); From 5cecc211da254395eaa37c8f93af91da617a3626 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 10:16:00 -0800 Subject: [PATCH 16/87] source -> header --- packages/pigeon/test/objc_generator_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index cc33903df77..7b01154ce82 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -107,7 +107,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); From 99f25b5e0f57db7a29c24749a83815987eac471c Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 10:16:30 -0800 Subject: [PATCH 17/87] correct options --- packages/pigeon/test/objc_generator_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index 7b01154ce82..480fe2deff6 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -148,7 +148,7 @@ void main() { } { final ObjcSourceGenerator generator = ObjcSourceGenerator(); - generator.generate(const ObjcOptions(), root, sink); + generator.generate(options, root, sink); final String code = sink.toString(); expect( code, From 16df2079a618b4bbdc1076d741fe9ddcb3dbecbc Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 10:19:50 -0800 Subject: [PATCH 18/87] header -> source --- packages/pigeon/test/objc_generator_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index 480fe2deff6..d447000b4f7 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -107,7 +107,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcSourceGenerator generator = ObjcSourceGenerator(); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); From 049c6be959d2c0403515b8e1b58d27c6ae41f30b Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 10:23:37 -0800 Subject: [PATCH 19/87] header -> prefix, source -> header --- packages/pigeon/test/objc_generator_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index d447000b4f7..981b5fb6c29 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -70,8 +70,8 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); - generator.generate(const ObjcOptions(header: 'PREFIX'), root, sink); + final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + generator.generate(const ObjcOptions(prefix: 'PREFIX'), root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, PREFIXEnum1) {')); expect(code, contains(' PREFIXEnum1One = 0,')); From a2dcb1c1c0cdee8761199abb6264d1b005623c92 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 10:27:28 -0800 Subject: [PATCH 20/87] remove headers from generateTestDart --- packages/pigeon/lib/dart_generator.dart | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 90b31c7b419..76092aa759d 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -118,7 +118,7 @@ class DartTestGenerator extends Generator { @override void writeFileHeaders( DartOptions languageOptions, Root root, StringSink sink, Indent indent) { - writeHeader(languageOptions, root, sink, indent); + writeTestHeader(languageOptions, root, sink, indent); } } @@ -760,6 +760,20 @@ String _posixify(String inputPath) { return context.fromUri(path.toUri(path.absolute(inputPath))); } +/// Writes file header to sink. +void writeTestHeader( + DartOptions opt, Root root, StringSink sink, Indent indent) { + if (opt.copyrightHeader != null) { + addLines(indent, opt.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.writeln( + '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import', + ); + indent.writeln('// ignore_for_file: avoid_relative_lib_imports'); +} + /// Generates Dart source code for test support libraries based on the given AST /// represented by [root], outputting the code to [sink]. [dartOutPath] is the /// path of the generated dart code to be tested. [testOutPath] is where the @@ -772,15 +786,6 @@ void generateTestDart( required String dartOutPath, required String testOutPath, }) { - if (opt.copyrightHeader != null) { - addLines(indent, opt.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.writeln( - '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import', - ); - indent.writeln('// ignore_for_file: avoid_relative_lib_imports'); indent.writeln("import 'dart:async';"); indent.writeln( "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", From e4c78f58dc71b2a6708680f5efc9ebc1e66f75cc Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 22 Dec 2022 10:33:42 -0800 Subject: [PATCH 21/87] changelog --- packages/pigeon/CHANGELOG.md | 4 ++++ packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 6e6688e0d85..2ea828e27ff 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.2.17 + +* Adds writeHeaders method to Generator classes and updates tests to use new Generators. + ## 4.2.16 * Creates new Generator classes for each language. diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index ea522eaa04d..ef503c869b8 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '4.2.16'; +const String pigeonVersion = '4.2.17'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 886f56a6ea0..f77ac58c371 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 4.2.16 # This must match the version in lib/generator_tools.dart +version: 4.2.17 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" From 68a23e20dcb2392a57cf706fba61c688c6bce9e9 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 09:12:28 -0800 Subject: [PATCH 22/87] Nits and combines source and header generators --- packages/pigeon/lib/cpp_generator.dart | 35 ++++++++++++------------ packages/pigeon/lib/generator.dart | 7 ++--- packages/pigeon/lib/generator_tools.dart | 9 ++++++ packages/pigeon/lib/objc_generator.dart | 23 ++++++---------- packages/pigeon/lib/pigeon_lib.dart | 8 +++--- 5 files changed, 41 insertions(+), 41 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 6bc120bc2d3..5912f6e98ed 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -21,8 +21,12 @@ const String _defaultCodecSerializer = 'flutter::StandardCodecSerializer'; /// Options that control how C++ code will be generated. class CppOptions { /// Creates a [CppOptions] object - const CppOptions( - {this.header, this.namespace, this.copyrightHeader, this.cppHeaderOut}); + const CppOptions({ + this.header, + this.namespace, + this.copyrightHeader, + this.cppHeaderOut, + }); /// The path to the header that will get placed in the source filed (example: /// "foo.h"). @@ -34,7 +38,7 @@ class CppOptions { /// A copyright header that will get prepended to generated code. final Iterable? copyrightHeader; - /// + /// The path to the output header file location. final String? cppHeaderOut; /// Creates a [CppOptions] from a Map representation where: @@ -66,27 +70,22 @@ class CppOptions { } /// Class that manages all Cpp header code generation. -class CppHeaderGenerator extends Generator { +class CppGenerator extends Generator { /// Instantiates a Cpp Generator. - CppHeaderGenerator(); + CppGenerator(this.fileType); - /// Generates Cpp header files with specified [CppOptions] - @override - void generate(CppOptions languageOptions, Root root, StringSink sink) { - generateCppHeader( - languageOptions.cppHeaderOut, languageOptions, root, sink); - } -} - -/// Class that manages all Cpp code generation. -class CppSourceGenerator extends Generator { - /// Instantiates a Cpp Generator. - CppSourceGenerator(); + /// Specifies which file type (header or source) will be generated. + FileType fileType; /// Generates Cpp files with specified [CppOptions] @override void generate(CppOptions languageOptions, Root root, StringSink sink) { - generateCppSource(languageOptions, root, sink); + if (fileType == FileType.header) { + generateCppHeader( + languageOptions.cppHeaderOut, languageOptions, root, sink); + } else { + generateCppSource(languageOptions, root, sink); + } } } diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 0979627b3ac..02667e4a5c9 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -4,13 +4,10 @@ import 'ast.dart'; -/// A Super class of generator classes. +/// A superclass of generator classes. /// -/// This is meant to provide structure and direction for future generator work. +/// This provides the structure that is common across generators for different languages. abstract class Generator { - /// Instantiates a Generator. - const Generator(); - /// Generates files for specified language with specified [languageOptions] void generate(T languageOptions, Root root, StringSink sink); } diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index ea522eaa04d..65f9c4b7a42 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -497,3 +497,12 @@ Iterable getFieldsInSerializationOrder(Class klass) { // This returns the fields in the order they are declared in the pigeon file. return klass.fields; } + +/// Enum to specify which file will be generated for multi-file generators +enum FileType { + /// header file. + header, + + /// source file. + source, +} diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 0d376e1a582..2ef59abdf4a 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -65,26 +65,21 @@ class ObjcOptions { } /// Class that manages all Objc header code generation. -class ObjcHeaderGenerator extends Generator { +class ObjcGenerator extends Generator { /// Instantiates a Objc Generator. - ObjcHeaderGenerator(); + ObjcGenerator(this.fileType); - /// Generates Objc header files with specified [ObjcOptions] - @override - void generate(ObjcOptions languageOptions, Root root, StringSink sink) { - generateObjcHeader(languageOptions, root, sink); - } -} - -/// Class that manages all Objc code generation. -class ObjcSourceGenerator extends Generator { - /// Instantiates a Objc Generator. - ObjcSourceGenerator(); + /// Specifies which file type (header or source) will be generated. + FileType fileType; /// Generates Objc files with specified [ObjcOptions] @override void generate(ObjcOptions languageOptions, Root root, StringSink sink) { - generateObjcSource(languageOptions, root, sink); + if (fileType == FileType.header) { + generateObjcHeader(languageOptions, root, sink); + } else { + generateObjcSource(languageOptions, root, sink); + } } } diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index e630a09c438..c5fa3264bc6 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -468,7 +468,7 @@ class ObjcHeaderAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(objcOptionsWithHeader, root, sink); } @@ -493,7 +493,7 @@ class ObjcSourceAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(objcOptionsWithHeader, root, sink); } @@ -566,7 +566,7 @@ class CppHeaderAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(cppOptionsWithHeader, root, sink); } @@ -591,7 +591,7 @@ class CppSourceAdapter implements Adapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(cppOptionsWithHeader, root, sink); } From 67282cf045f5ee0b565de848373e0280dad0ea13 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 09:14:27 -0800 Subject: [PATCH 23/87] renames Adapter to GeneratorAdapter --- packages/pigeon/lib/pigeon_lib.dart | 122 +++++++++++----------- packages/pigeon/test/pigeon_lib_test.dart | 56 +++++----- 2 files changed, 93 insertions(+), 85 deletions(-) diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index c5fa3264bc6..7ad64df5e0c 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -357,17 +357,17 @@ IOSink? _openSink(String? output) { /// An adapter that will call a generator to write code to a sink /// based on the contents of [PigeonOptions]. -abstract class Adapter { - /// Returns an [IOSink] instance to be written to if the [Adapter] should - /// generate. If it returns `null`, the [Adapter] will be skipped. +abstract class GeneratorAdapter { + /// Returns an [IOSink] instance to be written to if the [GeneratorAdapter] should + /// generate. If it returns `null`, the [GeneratorAdapter] will be skipped. IOSink? shouldGenerate(PigeonOptions options); /// Write the generated code described in [root] to [sink] using the /// [options]. void generate(StringSink sink, PigeonOptions options, Root root); - /// Generates errors that would only be appropriate for this [Adapter]. For - /// example, maybe a certain feature isn't implemented in a [Adapter] yet. + /// Generates errors that would only be appropriate for this [GeneratorAdapter]. For + /// example, maybe a certain feature isn't implemented in a [GeneratorAdapter] yet. List validate(PigeonOptions options, Root root); } @@ -385,10 +385,10 @@ DartOptions _dartOptionsWithCopyrightHeader( copyrightHeader: parsedCopyrightHeader); } -/// An [Adapter] that generates the AST. -class AstAdapter implements Adapter { - /// Constructor for [AstAdapter]. - const AstAdapter(); +/// An [GeneratorAdapter] that generates the AST. +class AstGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [AstGeneratorAdapter]. + const AstGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -402,10 +402,10 @@ class AstAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// An [Adapter] that generates Dart source code. -class DartAdapter implements Adapter { - /// Constructor for [DartAdapter]. - const DartAdapter(); +/// An [GeneratorAdapter] that generates Dart source code. +class DartGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [DartGeneratorAdapter]. + const DartGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -422,10 +422,10 @@ class DartAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// An [Adapter] that generates Dart test source code. -class DartTestAdapter implements Adapter { - /// Constructor for [DartTestAdapter]. - const DartTestAdapter(); +/// An [GeneratorAdapter] that generates Dart test source code. +class DartTestGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [DartTestGeneratorAdapter]. + const DartTestGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -456,10 +456,10 @@ class DartTestAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// An [Adapter] that generates Objective-C header code. -class ObjcHeaderAdapter implements Adapter { - /// Constructor for [ObjcHeaderAdapter]. - const ObjcHeaderAdapter(); +/// An [GeneratorAdapter] that generates Objective-C header code. +class ObjcHeaderGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [ObjcHeaderGeneratorAdapter]. + const ObjcHeaderGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -481,10 +481,10 @@ class ObjcHeaderAdapter implements Adapter { validateObjc(options.objcOptions!, root); } -/// An [Adapter] that generates Objective-C source code. -class ObjcSourceAdapter implements Adapter { - /// Constructor for [ObjcSourceAdapter]. - const ObjcSourceAdapter(); +/// An [GeneratorAdapter] that generates Objective-C source code. +class ObjcSourceGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [ObjcSourceGeneratorAdapter]. + const ObjcSourceGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -505,10 +505,10 @@ class ObjcSourceAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// An [Adapter] that generates Java source code. -class JavaAdapter implements Adapter { - /// Constructor for [JavaAdapter]. - const JavaAdapter(); +/// An [GeneratorAdapter] that generates Java source code. +class JavaGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [JavaGeneratorAdapter]. + const JavaGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -530,10 +530,10 @@ class JavaAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// An [Adapter] that generates Swift source code. -class SwiftAdapter implements Adapter { - /// Constructor for [SwiftAdapter]. - const SwiftAdapter(); +/// An [GeneratorAdapter] that generates Swift source code. +class SwiftGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [SwiftGeneratorAdapter]. + const SwiftGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -553,10 +553,10 @@ class SwiftAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// An [Adapter] that generates C++ header code. -class CppHeaderAdapter implements Adapter { - /// Constructor for [CppHeaderAdapter]. - const CppHeaderAdapter(); +/// An [GeneratorAdapter] that generates C++ header code. +class CppHeaderGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [CppHeaderGeneratorAdapter]. + const CppHeaderGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -579,10 +579,10 @@ class CppHeaderAdapter implements Adapter { validateCpp(options.cppOptions!, root); } -/// An [Adapter] that generates C++ source code. -class CppSourceAdapter implements Adapter { - /// Constructor for [CppSourceAdapter]. - const CppSourceAdapter(); +/// An [GeneratorAdapter] that generates C++ source code. +class CppSourceGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [CppSourceGeneratorAdapter]. + const CppSourceGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -603,10 +603,10 @@ class CppSourceAdapter implements Adapter { List validate(PigeonOptions options, Root root) => []; } -/// An [Adapter] that generates Kotlin source code. -class KotlinAdapter implements Adapter { - /// Constructor for [KotlinAdapter]. - const KotlinAdapter(); +/// An [GeneratorAdapter] that generates Kotlin source code. +class KotlinGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [KotlinGeneratorAdapter]. + const KotlinGeneratorAdapter(); @override void generate(StringSink sink, PigeonOptions options, Root root) { @@ -1353,7 +1353,7 @@ ${_argParser.usage}'''; /// customize the generators that pigeon will use. The optional parameter /// [sdkPath] allows you to specify the Dart SDK path. static Future run(List args, - {List? adapters, String? sdkPath}) { + {List? adapters, String? sdkPath}) { final PigeonOptions options = Pigeon.parseArgs(args); return runWithOptions(options, adapters: adapters, sdkPath: sdkPath); } @@ -1363,23 +1363,23 @@ ${_argParser.usage}'''; /// customize the generators that pigeon will use. The optional parameter /// [sdkPath] allows you to specify the Dart SDK path. static Future runWithOptions(PigeonOptions options, - {List? adapters, String? sdkPath}) async { + {List? adapters, String? sdkPath}) async { final Pigeon pigeon = Pigeon.setup(); if (options.debugGenerators ?? false) { generator_tools.debugGenerators = true; } - final List safeAdapters = adapters ?? - [ - const DartAdapter(), - const JavaAdapter(), - const SwiftAdapter(), - const KotlinAdapter(), - const CppHeaderAdapter(), - const CppSourceAdapter(), - const DartTestAdapter(), - const ObjcHeaderAdapter(), - const ObjcSourceAdapter(), - const AstAdapter(), + final List safeGeneratorAdapters = adapters ?? + [ + const DartGeneratorAdapter(), + const JavaGeneratorAdapter(), + const SwiftGeneratorAdapter(), + const KotlinGeneratorAdapter(), + const CppHeaderGeneratorAdapter(), + const CppSourceGeneratorAdapter(), + const DartTestGeneratorAdapter(), + const ObjcHeaderGeneratorAdapter(), + const ObjcSourceGeneratorAdapter(), + const AstGeneratorAdapter(), ]; _executeConfigurePigeon(options); @@ -1401,7 +1401,7 @@ ${_argParser.usage}'''; } } - for (final Adapter adapter in safeAdapters) { + for (final GeneratorAdapter adapter in safeGeneratorAdapters) { final IOSink? sink = adapter.shouldGenerate(options); if (sink != null) { final List adapterErrors = @@ -1443,7 +1443,7 @@ ${_argParser.usage}'''; CppOptions(header: path.basename(options.cppHeaderOut!))))); } - for (final Adapter adapter in safeAdapters) { + for (final GeneratorAdapter adapter in safeGeneratorAdapters) { final IOSink? sink = adapter.shouldGenerate(options); if (sink != null) { adapter.generate(sink, options, parseResults.root); diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 411643f679f..8d06f78cecc 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -9,8 +9,8 @@ import 'package:pigeon/ast.dart'; import 'package:pigeon/pigeon_lib.dart'; import 'package:test/test.dart'; -class _ValidatorAdapter implements Adapter { - _ValidatorAdapter(this.sink); +class _ValidatorGeneratorAdapter implements GeneratorAdapter { + _ValidatorGeneratorAdapter(this.sink); bool didCallValidate = false; final IOSink? sink; @@ -397,9 +397,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const DartAdapter dartAdapter = DartAdapter(); + const DartGeneratorAdapter dartGeneratorAdapter = DartGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - dartAdapter.generate(buffer, options, root); + dartGeneratorAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -407,9 +407,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( javaOut: 'Foo.java', copyrightHeader: './copyright_header.txt'); - const JavaAdapter javaAdapter = JavaAdapter(); + const JavaGeneratorAdapter javaGeneratorAdapter = JavaGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - javaAdapter.generate(buffer, options, root); + javaGeneratorAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -417,9 +417,10 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const ObjcHeaderAdapter objcHeaderAdapter = ObjcHeaderAdapter(); + const ObjcHeaderGeneratorAdapter objcHeaderGeneratorAdapter = + ObjcHeaderGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - objcHeaderAdapter.generate(buffer, options, root); + objcHeaderGeneratorAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -427,9 +428,10 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const ObjcSourceAdapter objcSourceAdapter = ObjcSourceAdapter(); + const ObjcSourceGeneratorAdapter objcSourceGeneratorAdapter = + ObjcSourceGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - objcSourceAdapter.generate(buffer, options, root); + objcSourceGeneratorAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -437,9 +439,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( swiftOut: 'Foo.swift', copyrightHeader: './copyright_header.txt'); - const SwiftAdapter swiftAdapter = SwiftAdapter(); + const SwiftGeneratorAdapter swiftGeneratorAdapter = SwiftGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - swiftAdapter.generate(buffer, options, root); + swiftGeneratorAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -447,9 +449,10 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( cppHeaderOut: 'Foo.h', copyrightHeader: './copyright_header.txt'); - const CppHeaderAdapter cppHeaderAdapter = CppHeaderAdapter(); + const CppHeaderGeneratorAdapter cppHeaderGeneratorAdapter = + CppHeaderGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - cppHeaderAdapter.generate(buffer, options, root); + cppHeaderGeneratorAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -457,9 +460,10 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const CppSourceAdapter cppSourceAdapter = CppSourceAdapter(); + const CppSourceGeneratorAdapter cppSourceGeneratorAdapter = + CppSourceGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - cppSourceAdapter.generate(buffer, options, root); + cppSourceGeneratorAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -929,9 +933,10 @@ abstract class Api { dartTestOut: 'stdout', dartOut: 'stdout', ); - const DartTestAdapter dartAdapter = DartTestAdapter(); + const DartTestGeneratorAdapter dartGeneratorAdapter = + DartTestGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - dartAdapter.generate(buffer, options, root); + dartGeneratorAdapter.generate(buffer, options, root); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -1187,9 +1192,10 @@ abstract class Api { test('generator validation', () async { final Completer completer = Completer(); withTempFile('foo.dart', (File input) async { - final _ValidatorAdapter generator = _ValidatorAdapter(stdout); + final _ValidatorGeneratorAdapter generator = + _ValidatorGeneratorAdapter(stdout); final int result = await Pigeon.run(['--input', input.path], - adapters: [generator]); + adapters: [generator]); expect(generator.didCallValidate, isTrue); expect(result, isNot(0)); completer.complete(); @@ -1200,10 +1206,11 @@ abstract class Api { test('generator validation skipped', () async { final Completer completer = Completer(); withTempFile('foo.dart', (File input) async { - final _ValidatorAdapter generator = _ValidatorAdapter(null); + final _ValidatorGeneratorAdapter generator = + _ValidatorGeneratorAdapter(null); final int result = await Pigeon.run( ['--input', input.path, '--dart_out', 'foo.dart'], - adapters: [generator]); + adapters: [generator]); expect(generator.didCallValidate, isFalse); expect(result, equals(0)); completer.complete(); @@ -1214,10 +1221,11 @@ abstract class Api { test('run with PigeonOptions', () async { final Completer completer = Completer(); withTempFile('foo.dart', (File input) async { - final _ValidatorAdapter generator = _ValidatorAdapter(null); + final _ValidatorGeneratorAdapter generator = + _ValidatorGeneratorAdapter(null); final int result = await Pigeon.runWithOptions( PigeonOptions(input: input.path, dartOut: 'foo.dart'), - adapters: [generator]); + adapters: [generator]); expect(generator.didCallValidate, isFalse); expect(result, equals(0)); completer.complete(); From d08606caca00e0bc2b48f08a8d820493e6e8b2dc Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 09:17:15 -0800 Subject: [PATCH 24/87] Update version number for breaking changes --- packages/pigeon/CHANGELOG.md | 2 +- packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 6e6688e0d85..30a5cbfe6df 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,4 +1,4 @@ -## 4.2.16 +## 5.0.0 * Creates new Generator classes for each language. diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 65f9c4b7a42..89188846af9 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '4.2.16'; +const String pigeonVersion = '5.0.0'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 886f56a6ea0..e4ada89edd1 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 4.2.16 # This must match the version in lib/generator_tools.dart +version: 5.0.0 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" From 90fcb67c67e15222e8fca60d8c7598674c04a6dd Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 09:24:36 -0800 Subject: [PATCH 25/87] nits --- packages/pigeon/lib/cpp_generator.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 5912f6e98ed..632de008f0e 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -45,10 +45,11 @@ class CppOptions { /// `x = CppOptions.fromMap(x.toMap())`. static CppOptions fromMap(Map map) { return CppOptions( - header: map['header'] as String?, - namespace: map['namespace'] as String?, - copyrightHeader: map['copyrightHeader'] as Iterable?, - cppHeaderOut: map['cppHeaderOut'] as String?); + header: map['header'] as String?, + namespace: map['namespace'] as String?, + copyrightHeader: map['copyrightHeader'] as Iterable?, + cppHeaderOut: map['cppHeaderOut'] as String?, + ); } /// Converts a [CppOptions] to a Map representation where: From ea0ec6c702e1b2b8b1685d4568bd47970dc68ddf Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 09:29:55 -0800 Subject: [PATCH 26/87] more personal nits --- packages/pigeon/lib/cpp_generator.dart | 2 +- packages/pigeon/lib/objc_generator.dart | 2 +- packages/pigeon/lib/pigeon_lib.dart | 27 +++++++++++++------------ 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 632de008f0e..4bf5f0c868b 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -72,7 +72,7 @@ class CppOptions { /// Class that manages all Cpp header code generation. class CppGenerator extends Generator { - /// Instantiates a Cpp Generator. + /// Instantiates a Cpp Generator for the specified file type. CppGenerator(this.fileType); /// Specifies which file type (header or source) will be generated. diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 2ef59abdf4a..48d512d65c1 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -66,7 +66,7 @@ class ObjcOptions { /// Class that manages all Objc header code generation. class ObjcGenerator extends Generator { - /// Instantiates a Objc Generator. + /// Instantiates a Objc Generator for the specified file type. ObjcGenerator(this.fileType); /// Specifies which file type (header or source) will be generated. diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 7ad64df5e0c..8871fe1f732 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -380,12 +380,13 @@ DartOptions _dartOptionsWithCopyrightHeader( ? _lineReader(copyrightHeader) : null; return DartOptions( - dartOutPath: dartOutPath, - testOutPath: testOutPath, - copyrightHeader: parsedCopyrightHeader); + dartOutPath: dartOutPath, + testOutPath: testOutPath, + copyrightHeader: parsedCopyrightHeader, + ); } -/// An [GeneratorAdapter] that generates the AST. +/// A [GeneratorAdapter] that generates the AST. class AstGeneratorAdapter implements GeneratorAdapter { /// Constructor for [AstGeneratorAdapter]. const AstGeneratorAdapter(); @@ -402,7 +403,7 @@ class AstGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } -/// An [GeneratorAdapter] that generates Dart source code. +/// A [GeneratorAdapter] that generates Dart source code. class DartGeneratorAdapter implements GeneratorAdapter { /// Constructor for [DartGeneratorAdapter]. const DartGeneratorAdapter(); @@ -422,7 +423,7 @@ class DartGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } -/// An [GeneratorAdapter] that generates Dart test source code. +/// A [GeneratorAdapter] that generates Dart test source code. class DartTestGeneratorAdapter implements GeneratorAdapter { /// Constructor for [DartTestGeneratorAdapter]. const DartTestGeneratorAdapter(); @@ -456,7 +457,7 @@ class DartTestGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } -/// An [GeneratorAdapter] that generates Objective-C header code. +/// A [GeneratorAdapter] that generates Objective-C header code. class ObjcHeaderGeneratorAdapter implements GeneratorAdapter { /// Constructor for [ObjcHeaderGeneratorAdapter]. const ObjcHeaderGeneratorAdapter(); @@ -481,7 +482,7 @@ class ObjcHeaderGeneratorAdapter implements GeneratorAdapter { validateObjc(options.objcOptions!, root); } -/// An [GeneratorAdapter] that generates Objective-C source code. +/// A [GeneratorAdapter] that generates Objective-C source code. class ObjcSourceGeneratorAdapter implements GeneratorAdapter { /// Constructor for [ObjcSourceGeneratorAdapter]. const ObjcSourceGeneratorAdapter(); @@ -505,7 +506,7 @@ class ObjcSourceGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } -/// An [GeneratorAdapter] that generates Java source code. +/// A [GeneratorAdapter] that generates Java source code. class JavaGeneratorAdapter implements GeneratorAdapter { /// Constructor for [JavaGeneratorAdapter]. const JavaGeneratorAdapter(); @@ -530,7 +531,7 @@ class JavaGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } -/// An [GeneratorAdapter] that generates Swift source code. +/// A [GeneratorAdapter] that generates Swift source code. class SwiftGeneratorAdapter implements GeneratorAdapter { /// Constructor for [SwiftGeneratorAdapter]. const SwiftGeneratorAdapter(); @@ -553,7 +554,7 @@ class SwiftGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } -/// An [GeneratorAdapter] that generates C++ header code. +/// A [GeneratorAdapter] that generates C++ header code. class CppHeaderGeneratorAdapter implements GeneratorAdapter { /// Constructor for [CppHeaderGeneratorAdapter]. const CppHeaderGeneratorAdapter(); @@ -579,7 +580,7 @@ class CppHeaderGeneratorAdapter implements GeneratorAdapter { validateCpp(options.cppOptions!, root); } -/// An [GeneratorAdapter] that generates C++ source code. +/// A [GeneratorAdapter] that generates C++ source code. class CppSourceGeneratorAdapter implements GeneratorAdapter { /// Constructor for [CppSourceGeneratorAdapter]. const CppSourceGeneratorAdapter(); @@ -603,7 +604,7 @@ class CppSourceGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } -/// An [GeneratorAdapter] that generates Kotlin source code. +/// A [GeneratorAdapter] that generates Kotlin source code. class KotlinGeneratorAdapter implements GeneratorAdapter { /// Constructor for [KotlinGeneratorAdapter]. const KotlinGeneratorAdapter(); From d5c5f1fca7d22e806251877b1fd974c248352edc Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 09:48:50 -0800 Subject: [PATCH 27/87] update tests to match new merged generators --- packages/pigeon/test/cpp_generator_test.dart | 55 +++---- packages/pigeon/test/objc_generator_test.dart | 149 +++++++++--------- 2 files changed, 103 insertions(+), 101 deletions(-) diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index 4e4a3a1a354..ead8b73e202 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -4,6 +4,7 @@ import 'package:pigeon/ast.dart'; import 'package:pigeon/cpp_generator.dart'; +import 'package:pigeon/generator_tools.dart'; import 'package:pigeon/pigeon.dart' show Error; import 'package:test/test.dart'; @@ -45,7 +46,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Input')); @@ -54,7 +55,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Input::Input()')); @@ -103,7 +104,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Method name and argument names should be adjusted. @@ -119,7 +120,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('pointer_input_field')); @@ -148,7 +149,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); @@ -189,7 +190,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); @@ -244,7 +245,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('){'))); @@ -252,7 +253,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('){'))); @@ -279,7 +280,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains(''' @@ -295,7 +296,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(header: 'a_header.h'), root, sink); final String code = sink.toString(); expect(code, contains(''' @@ -332,7 +333,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(namespace: 'foo'), root, sink); final String code = sink.toString(); expect(code, contains('namespace foo {')); @@ -340,7 +341,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(namespace: 'foo'), root, sink); final String code = sink.toString(); expect(code, contains('namespace foo {')); @@ -402,7 +403,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Getters should return const pointers. @@ -435,7 +436,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Getters extract optionals. @@ -535,7 +536,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // POD getters should return copies references. @@ -561,7 +562,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Getters just return the value. @@ -660,7 +661,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect( @@ -766,7 +767,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('ErrorOr ReturnBool()')); @@ -843,7 +844,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect( @@ -857,7 +858,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Most types should just use get_if, since the parameter is a pointer, @@ -963,7 +964,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect( @@ -977,7 +978,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // Most types should extract references. Since the type is non-nullable, @@ -1032,7 +1033,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); // A bare 'auto' here would create a copy, not a reference, which is @@ -1145,7 +1146,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(cppHeaderOut: 'foo'), root, sink); final String code = sink.toString(); for (final String comment in comments) { @@ -1181,7 +1182,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : public flutter::StandardCodecSerializer'))); @@ -1224,7 +1225,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final CppHeaderGenerator generator = CppHeaderGenerator(); + final CppGenerator generator = CppGenerator(FileType.header); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains(' : public flutter::StandardCodecSerializer')); @@ -1294,7 +1295,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final CppSourceGenerator generator = CppSourceGenerator(); + final CppGenerator generator = CppGenerator(FileType.source); generator.generate(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('reply(wrap'))); diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index 981b5fb6c29..d978f477051 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:pigeon/ast.dart'; +import 'package:pigeon/generator_tools.dart'; import 'package:pigeon/objc_generator.dart'; import 'package:pigeon/pigeon_lib.dart'; import 'package:test/test.dart'; @@ -17,7 +18,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); @@ -33,7 +34,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); @@ -51,7 +52,7 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, Enum1) {')); @@ -70,7 +71,7 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(prefix: 'PREFIX'), root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, PREFIXEnum1) {')); @@ -107,7 +108,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); @@ -140,14 +141,14 @@ void main() { final StringBuffer sink = StringBuffer(); const ObjcOptions options = ObjcOptions(header: 'foo.h', prefix: 'AC'); { - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(options, root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, ACFoo)')); expect(code, contains(':(ACFoo)foo error:')); } { - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(options, root, sink); final String code = sink.toString(); expect( @@ -211,7 +212,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@property(nonatomic, assign) Enum1 enum1')); @@ -244,7 +245,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Input')); @@ -284,7 +285,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); @@ -332,7 +333,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); @@ -361,7 +362,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@implementation Foobar')); @@ -383,7 +384,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, @@ -404,7 +405,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect( @@ -424,7 +425,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('@interface ABCFoobar')); @@ -439,7 +440,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('@implementation ABCFoobar')); @@ -474,7 +475,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, matches('property.*ABCInput')); @@ -511,7 +512,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(prefix: 'ABC'), root, sink); final String code = sink.toString(); expect(code, contains('ABCInput fromList')); @@ -548,7 +549,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@interface Api : NSObject')); @@ -588,7 +589,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(header: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@implementation Api')); @@ -618,7 +619,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); @@ -649,7 +650,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -681,7 +682,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -711,7 +712,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -736,7 +737,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -760,7 +761,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -784,7 +785,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -811,7 +812,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -831,7 +832,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); @@ -847,7 +848,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); @@ -869,7 +870,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); @@ -899,7 +900,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('(NSDictionary *)foo')); @@ -934,7 +935,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -974,7 +975,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1002,7 +1003,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1023,7 +1024,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1063,7 +1064,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1102,7 +1103,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1123,7 +1124,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1151,7 +1152,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1168,7 +1169,7 @@ void main() { test('source copyright', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( ObjcOptions( header: 'foo.h', @@ -1183,7 +1184,7 @@ void main() { test('header copyright', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( ObjcOptions( header: 'foo.h', @@ -1215,7 +1216,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1246,7 +1247,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1254,7 +1255,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1289,7 +1290,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1297,7 +1298,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1335,7 +1336,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1363,7 +1364,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1372,7 +1373,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1400,7 +1401,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1409,7 +1410,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1439,7 +1440,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1450,7 +1451,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1486,7 +1487,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1497,7 +1498,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1531,7 +1532,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1542,7 +1543,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); final String code = sink.toString(); @@ -1587,7 +1588,7 @@ void main() { final Root divideRoot = getDivideRoot(ApiLocation.host); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); final String code = sink.toString(); @@ -1595,7 +1596,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); @@ -1608,7 +1609,7 @@ void main() { final Root divideRoot = getDivideRoot(ApiLocation.flutter); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); final String code = sink.toString(); @@ -1616,7 +1617,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate( const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); @@ -1634,7 +1635,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); @@ -1658,7 +1659,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect( @@ -1684,7 +1685,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, matches(r'doitWithCompletion.*NSNumber \*_Nullable')); @@ -1707,7 +1708,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, matches(r'nullable NSNumber.*doitWithError')); @@ -1735,14 +1736,14 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doitFoo:(nullable NSNumber *)foo')); } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, @@ -1772,14 +1773,14 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doitFoo:(nullable NSNumber *)foo')); } { final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains('- (void)doitFoo:(nullable NSNumber *)arg_foo')); @@ -1804,7 +1805,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect( @@ -1889,7 +1890,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final ObjcHeaderGenerator generator = ObjcHeaderGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.header); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); for (final String comment in comments) { @@ -1925,7 +1926,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : FlutterStandardReader'))); @@ -1968,7 +1969,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcSourceGenerator generator = ObjcSourceGenerator(); + final ObjcGenerator generator = ObjcGenerator(FileType.source); generator.generate(const ObjcOptions(), root, sink); final String code = sink.toString(); expect(code, contains(' : FlutterStandardReader')); From 6856812a09573e40884d27c72cb6abe1db9eca8d Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 14:29:27 -0800 Subject: [PATCH 28/87] cleaner header methods --- packages/pigeon/lib/cpp_generator.dart | 17 ++++++++--------- packages/pigeon/lib/dart_generator.dart | 1 + packages/pigeon/lib/java_generator.dart | 2 +- packages/pigeon/lib/kotlin_generator.dart | 2 +- packages/pigeon/lib/objc_generator.dart | 2 ++ packages/pigeon/lib/swift_generator.dart | 2 +- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 1c339726915..df0a188e573 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -1054,15 +1054,15 @@ void writeCppHeaderHeader( if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); } + indent.writeln('$_commentPrefix $generatedCodeWarning'); + indent.writeln('$_commentPrefix $seeAlsoWarning'); + indent.addln(''); } /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options] and [headerFileName]. void generateCppHeader(String? headerFileName, CppOptions options, Root root, StringSink sink, Indent indent) { - indent.writeln('$_commentPrefix $generatedCodeWarning'); - indent.writeln('$_commentPrefix $seeAlsoWarning'); - indent.addln(''); final String guardName = _getGuardName(headerFileName, options.namespace); indent.writeln('#ifndef $guardName'); indent.writeln('#define $guardName'); @@ -1149,18 +1149,17 @@ void writeCppSourceHeader( if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); } -} - -/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateCppSource( - CppOptions options, Root root, StringSink sink, Indent indent) { indent.writeln('$_commentPrefix $generatedCodeWarning'); indent.writeln('$_commentPrefix $seeAlsoWarning'); indent.addln(''); indent.addln('#undef _HAS_EXCEPTIONS'); indent.addln(''); +} +/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the +/// provided [options]. +void generateCppSource( + CppOptions options, Root root, StringSink sink, Indent indent) { indent.writeln('#include "${options.header}"'); indent.addln(''); _writeSystemHeaderIncludeBlock(indent, [ diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 76092aa759d..e0ce71c3830 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -532,6 +532,7 @@ void writeHeader(DartOptions opt, Root root, StringSink sink, Indent indent) { indent.writeln( '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import', ); + indent.addln(''); } /// Generates Dart source code for the given AST represented by [root], diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 310125937da..2feb511a846 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -551,6 +551,7 @@ void writeHeader( } indent.writeln('// $generatedCodeWarning'); indent.writeln('// $seeAlsoWarning'); + indent.addln(''); } /// Generates the ".java" file for the AST represented by [root] to [sink] with the @@ -775,7 +776,6 @@ void generateJava( }'''); } - indent.addln(''); if (options.package != null) { indent.writeln('package ${options.package};'); } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index abdf83aa74f..9cb43bc295f 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -464,6 +464,7 @@ void writeHeader( } indent.writeln('// $generatedCodeWarning'); indent.writeln('// $seeAlsoWarning'); + indent.addln(''); } /// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the @@ -674,7 +675,6 @@ void generateKotlin( }); } - indent.addln(''); if (options.package != null) { indent.writeln('package ${options.package}'); } diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 56a19a52cdf..9866b4ce910 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -572,6 +572,7 @@ void writeObjcHeaderHeader( } indent.writeln('// $generatedCodeWarning'); indent.writeln('// $seeAlsoWarning'); + indent.addln(''); } /// Generates the ".h" file for the AST represented by [root] to [sink] with the @@ -915,6 +916,7 @@ void writeObjcSourceHeader( } indent.writeln('// $generatedCodeWarning'); indent.writeln('// $seeAlsoWarning'); + indent.addln(''); } /// Generates the ".m" file for the AST represented by [root] to [sink] with the diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 8ea5ed88065..489f44b660f 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -458,6 +458,7 @@ void writeHeader( } indent.writeln('// $generatedCodeWarning'); indent.writeln('// $seeAlsoWarning'); + indent.addln(''); } /// Generates the ".swift" file for the AST represented by [root] to [sink] with the @@ -642,7 +643,6 @@ import FlutterMacOS }); } - indent.addln(''); writeImports(); indent.addln(''); indent.writeln('$_docCommentPrefix Generated class from Pigeon.'); From 6206bad51e327c8fde4354d97a3bdb36127cf935 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 14:41:13 -0800 Subject: [PATCH 29/87] Fixes dart header bug --- packages/pigeon/lib/pigeon_lib.dart | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 8871fe1f732..467ade2bd0c 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -374,16 +374,12 @@ abstract class GeneratorAdapter { DartOptions _dartOptionsWithCopyrightHeader( DartOptions? dartOptions, String? copyrightHeader, [String? dartOutPath, String? testOutPath]) { - final Iterable? parsedCopyrightHeader = dartOptions != null - ? dartOptions.copyrightHeader - : copyrightHeader != null - ? _lineReader(copyrightHeader) - : null; - return DartOptions( - dartOutPath: dartOutPath, - testOutPath: testOutPath, - copyrightHeader: parsedCopyrightHeader, - ); + dartOptions = dartOptions ?? DartOptions(); + return dartOptions.merge(DartOptions( + dartOutPath: dartOutPath, + testOutPath: testOutPath, + copyrightHeader: + copyrightHeader != null ? _lineReader(copyrightHeader) : null)); } /// A [GeneratorAdapter] that generates the AST. From 7c3d35cf1f974ab2c815492cb505f1de79d37a60 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 14:49:05 -0800 Subject: [PATCH 30/87] add gen files for clarity --- .../mock_handler_tester/test/message.dart | 2 +- .../pigeon/mock_handler_tester/test/test.dart | 2 +- .../CoreTests.java | 2 +- .../ios/Classes/CoreTests.gen.h | 2 +- .../ios/Classes/CoreTests.gen.m | 2 +- .../lib/core_tests.gen.dart | 2 +- .../lib/multiple_arity.gen.dart | 2 +- .../lib/non_null_fields.gen.dart | 2 +- .../lib/null_fields.gen.dart | 2 +- .../lib/null_safe_pigeon.dart | 2 +- .../lib/nullable_returns.gen.dart | 2 +- .../lib/primitive.dart | 2 +- .../lib/src/generated/core_tests.gen.dart | 2 +- .../com/example/test_plugin/CoreTests.gen.kt | 2 +- .../ios/Classes/CoreTests.gen.swift | 2 +- .../macos/Classes/CoreTests.gen.swift | 2 +- .../windows/pigeon/core_tests.gen.cpp | 81 ++++++++++--------- .../windows/pigeon/core_tests.gen.h | 8 +- 18 files changed, 65 insertions(+), 56 deletions(-) diff --git a/packages/pigeon/mock_handler_tester/test/message.dart b/packages/pigeon/mock_handler_tester/test/message.dart index f64aa5dc142..4f6c9d14457 100644 --- a/packages/pigeon/mock_handler_tester/test/message.dart +++ b/packages/pigeon/mock_handler_tester/test/message.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.11), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/mock_handler_tester/test/test.dart b/packages/pigeon/mock_handler_tester/test/test.dart index d0ecdc5d205..9b97826b605 100644 --- a/packages/pigeon/mock_handler_tester/test/test.dart +++ b/packages/pigeon/mock_handler_tester/test/test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.11), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, unnecessary_import // ignore_for_file: avoid_relative_lib_imports diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index 9c0256252ea..2d81d4b59f1 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon package com.example.alternate_language_test_plugin; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index 80a40d52c85..dcdee87c5d9 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #import @protocol FlutterBinaryMessenger; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index adb33d0bdf9..bcdd86394a6 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "CoreTests.gen.h" #import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart index 4ff2bc07562..ee79a4b1a27 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart index a3145679319..e92ab29cebd 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.11), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart index 0dafa689085..1ff71bfa346 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.11), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart index 94c9b86a8a5..88f4611e746 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.11), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart index f376a13a932..13fe926bcf1 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.11), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart index e88028363d8..be1979c8adf 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.11), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart index 178e3154578..36a569e4f46 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.11), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index 4ff2bc07562..ee79a4b1a27 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index bcd41b05492..c1add054eaf 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon package com.example.test_plugin diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index 385b507191a..c9850b70d36 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index 385b507191a..c9850b70d36 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp index 990732ca635..f0d5929ce4a 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS @@ -576,7 +576,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -597,7 +597,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_everything_arg = args.at(0); if (encodable_everything_arg.IsNull()) { - reply(WrapError("everything_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("everything_arg unexpectedly null."))); return; } const auto& everything_arg = std::any_cast( @@ -613,7 +614,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -653,7 +654,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -680,7 +681,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -700,7 +701,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_an_int_arg = args.at(0); if (encodable_an_int_arg.IsNull()) { - reply(WrapError("an_int_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("an_int_arg unexpectedly null."))); return; } const int64_t an_int_arg = encodable_an_int_arg.LongValue(); @@ -714,7 +716,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -735,7 +737,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_a_double_arg = args.at(0); if (encodable_a_double_arg.IsNull()) { - reply(WrapError("a_double_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("a_double_arg unexpectedly null."))); return; } const auto& a_double_arg = @@ -750,7 +753,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -770,7 +773,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_a_bool_arg = args.at(0); if (encodable_a_bool_arg.IsNull()) { - reply(WrapError("a_bool_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("a_bool_arg unexpectedly null."))); return; } const auto& a_bool_arg = std::get(encodable_a_bool_arg); @@ -784,7 +788,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -805,7 +809,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_a_string_arg = args.at(0); if (encodable_a_string_arg.IsNull()) { - reply(WrapError("a_string_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("a_string_arg unexpectedly null."))); return; } const auto& a_string_arg = @@ -820,7 +825,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -841,7 +846,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_a_uint8_list_arg = args.at(0); if (encodable_a_uint8_list_arg.IsNull()) { - reply(WrapError("a_uint8_list_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("a_uint8_list_arg unexpectedly null."))); return; } const auto& a_uint8_list_arg = @@ -857,7 +863,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -878,7 +884,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_wrapper_arg = args.at(0); if (encodable_wrapper_arg.IsNull()) { - reply(WrapError("wrapper_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("wrapper_arg unexpectedly null."))); return; } const auto& wrapper_arg = @@ -901,7 +908,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -934,7 +941,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -980,7 +987,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -1024,7 +1031,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -1062,7 +1069,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -1100,7 +1107,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -1138,7 +1145,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -1177,7 +1184,7 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); @@ -1201,11 +1208,11 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } else { wrapped.push_back(flutter::EncodableValue()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); } }); } else { @@ -1227,7 +1234,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_a_string_arg = args.at(0); if (encodable_a_string_arg.IsNull()) { - reply(WrapError("a_string_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("a_string_arg unexpectedly null."))); return; } const auto& a_string_arg = @@ -1241,11 +1249,11 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, wrapped.push_back(flutter::EncodableValue( std::move(output).TakeValue())); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); } }); } else { @@ -1271,11 +1279,11 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, } else { wrapped.push_back(flutter::EncodableValue()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); } }); } else { @@ -1297,7 +1305,8 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, const auto& args = std::get(message); const auto& encodable_a_string_arg = args.at(0); if (encodable_a_string_arg.IsNull()) { - reply(WrapError("a_string_arg unexpectedly null.")); + reply(flutter::EncodableValue( + WrapError("a_string_arg unexpectedly null."))); return; } const auto& a_string_arg = @@ -1311,11 +1320,11 @@ void HostIntegrationCoreApi::SetUp(flutter::BinaryMessenger* binary_messenger, wrapped.push_back(flutter::EncodableValue( std::move(output).TakeValue())); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); } }); } else { @@ -1500,7 +1509,7 @@ void HostTrivialApi::SetUp(flutter::BinaryMessenger* binary_messenger, } catch (const std::exception& exception) { wrapped = WrapError(exception.what()); } - reply(wrapped); + reply(flutter::EncodableValue(std::move(wrapped))); }); } else { channel->SetMessageHandler(nullptr); diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index 5100fdb753d..a2ea204b578 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.12), do not edit directly. +// Autogenerated from Pigeon (v5.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon -#ifndef PIGEON_CORE_TESTS_GEN_CORE_TESTS_PIGEONTEST_H_ -#define PIGEON_CORE_TESTS_GEN_CORE_TESTS_PIGEONTEST_H_ +#ifndef PIGEON_CORE_TESTS_PIGEONTEST_H_ +#define PIGEON_CORE_TESTS_PIGEONTEST_H_ #include #include #include @@ -406,4 +406,4 @@ class HostTrivialApi { HostTrivialApi() = default; }; } // namespace core_tests_pigeontest -#endif // PIGEON_CORE_TESTS_GEN_CORE_TESTS_PIGEONTEST_H_ +#endif // PIGEON_CORE_TESTS_PIGEONTEST_H_ From 8bf2dfbd484af7718d7d0621da2995ecc5cc9ece Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 16:09:57 -0800 Subject: [PATCH 31/87] better field naming --- packages/pigeon/lib/cpp_generator.dart | 23 ++++++------ packages/pigeon/lib/dart_generator.dart | 20 +++++------ packages/pigeon/lib/pigeon_lib.dart | 8 ++--- packages/pigeon/test/cpp_generator_test.dart | 35 ++++++++++--------- packages/pigeon/test/dart_generator_test.dart | 6 ++-- 5 files changed, 46 insertions(+), 46 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 4bf5f0c868b..225b8e9ca7b 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -22,15 +22,15 @@ const String _defaultCodecSerializer = 'flutter::StandardCodecSerializer'; class CppOptions { /// Creates a [CppOptions] object const CppOptions({ - this.header, + this.headerIncludePath, this.namespace, this.copyrightHeader, - this.cppHeaderOut, + this.headerOutPath, }); /// The path to the header that will get placed in the source filed (example: /// "foo.h"). - final String? header; + final String? headerIncludePath; /// The namespace where the generated class will live. final String? namespace; @@ -39,16 +39,16 @@ class CppOptions { final Iterable? copyrightHeader; /// The path to the output header file location. - final String? cppHeaderOut; + final String? headerOutPath; /// Creates a [CppOptions] from a Map representation where: /// `x = CppOptions.fromMap(x.toMap())`. static CppOptions fromMap(Map map) { return CppOptions( - header: map['header'] as String?, + headerIncludePath: map['header'] as String?, namespace: map['namespace'] as String?, copyrightHeader: map['copyrightHeader'] as Iterable?, - cppHeaderOut: map['cppHeaderOut'] as String?, + headerOutPath: map['cppHeaderOut'] as String?, ); } @@ -56,7 +56,7 @@ class CppOptions { /// `x = CppOptions.fromMap(x.toMap())`. Map toMap() { final Map result = { - if (header != null) 'header': header!, + if (headerIncludePath != null) 'header': headerIncludePath!, if (namespace != null) 'namespace': namespace!, if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!, }; @@ -82,8 +82,7 @@ class CppGenerator extends Generator { @override void generate(CppOptions languageOptions, Root root, StringSink sink) { if (fileType == FileType.header) { - generateCppHeader( - languageOptions.cppHeaderOut, languageOptions, root, sink); + generateCppHeader(languageOptions, root, sink); } else { generateCppSource(languageOptions, root, sink); } @@ -1037,8 +1036,8 @@ void _writeSystemHeaderIncludeBlock(Indent indent, List headers) { /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options] and [headerFileName]. -void generateCppHeader( - String? headerFileName, CppOptions options, Root root, StringSink sink) { +void generateCppHeader(CppOptions options, Root root, StringSink sink) { + final String? headerFileName = options.headerOutPath; final Indent indent = Indent(sink); if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); @@ -1139,7 +1138,7 @@ void generateCppSource(CppOptions options, Root root, StringSink sink) { indent.addln('#undef _HAS_EXCEPTIONS'); indent.addln(''); - indent.writeln('#include "${options.header}"'); + indent.writeln('#include "${options.headerIncludePath}"'); indent.addln(''); _writeSystemHeaderIncludeBlock(indent, [ 'flutter/basic_message_channel.h', diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 604becc9c30..6d4b005d764 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -27,7 +27,7 @@ class DartOptions { /// Constructor for DartOptions. DartOptions({ this.copyrightHeader, - this.dartOutPath, + this.sourceOutPath, this.testOutPath, }); @@ -35,7 +35,7 @@ class DartOptions { final Iterable? copyrightHeader; /// Path to output generated Dart file for tests. - String? dartOutPath; + String? sourceOutPath; /// Path to output generated Test file for tests. String? testOutPath; @@ -47,7 +47,7 @@ class DartOptions { map['copyrightHeader'] as Iterable?; return DartOptions( copyrightHeader: copyrightHeader?.cast(), - dartOutPath: map['dartOutPath'] as String?, + sourceOutPath: map['sourceOutPath'] as String?, testOutPath: map['testOutPath'] as String?, ); } @@ -57,7 +57,7 @@ class DartOptions { Map toMap() { final Map result = { if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!, - if (dartOutPath != null) 'dartOutPath': dartOutPath!, + if (sourceOutPath != null) 'sourceOutPath': sourceOutPath!, if (testOutPath != null) 'testOutPath': testOutPath!, }; return result; @@ -90,13 +90,13 @@ class DartTestGenerator extends Generator { /// Generates Dart files with specified [DartOptions] @override void generate(DartOptions languageOptions, Root root, StringSink sink) { - final String dartOutPath = languageOptions.dartOutPath ?? ''; + final String sourceOutPath = languageOptions.sourceOutPath ?? ''; final String testOutPath = languageOptions.testOutPath ?? ''; generateTestDart( languageOptions, root, sink, - dartOutPath: dartOutPath, + sourceOutPath: sourceOutPath, testOutPath: testOutPath, ); } @@ -742,14 +742,14 @@ String _posixify(String inputPath) { } /// Generates Dart source code for test support libraries based on the given AST -/// represented by [root], outputting the code to [sink]. [dartOutPath] is the +/// represented by [root], outputting the code to [sink]. [sourceOutPath] is the /// path of the generated dart code to be tested. [testOutPath] is where the /// test code will be generated. void generateTestDart( DartOptions opt, Root root, StringSink sink, { - required String dartOutPath, + required String sourceOutPath, required String testOutPath, }) { final Indent indent = Indent(sink); @@ -773,10 +773,10 @@ void generateTestDart( indent.writeln(''); final String relativeDartPath = path.Context(style: path.Style.posix).relative( - _posixify(dartOutPath), + _posixify(sourceOutPath), from: _posixify(path.dirname(testOutPath)), ); - late final String? packageName = _deducePackageName(dartOutPath); + late final String? packageName = _deducePackageName(sourceOutPath); if (!relativeDartPath.contains('/lib/') || packageName == null) { // If we can't figure out the package name or the relative path doesn't // include a 'lib' directory, try relative path import which only works in diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 467ade2bd0c..327ce27c08b 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -376,7 +376,7 @@ DartOptions _dartOptionsWithCopyrightHeader( [String? dartOutPath, String? testOutPath]) { dartOptions = dartOptions ?? DartOptions(); return dartOptions.merge(DartOptions( - dartOutPath: dartOutPath, + sourceOutPath: dartOutPath, testOutPath: testOutPath, copyrightHeader: copyrightHeader != null ? _lineReader(copyrightHeader) : null)); @@ -559,7 +559,7 @@ class CppHeaderGeneratorAdapter implements GeneratorAdapter { void generate(StringSink sink, PigeonOptions options, Root root) { final CppOptions cppOptions = options.cppOptions ?? const CppOptions(); final CppOptions cppOptionsWithHeader = cppOptions.merge(CppOptions( - cppHeaderOut: path.basenameWithoutExtension(options.cppHeaderOut!), + headerOutPath: path.basenameWithoutExtension(options.cppHeaderOut!), copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); @@ -1436,8 +1436,8 @@ ${_argParser.usage}'''; if (options.cppHeaderOut != null) { options = options.merge(PigeonOptions( - cppOptions: options.cppOptions!.merge( - CppOptions(header: path.basename(options.cppHeaderOut!))))); + cppOptions: options.cppOptions!.merge(CppOptions( + headerIncludePath: path.basename(options.cppHeaderOut!))))); } for (final GeneratorAdapter adapter in safeGeneratorAdapters) { diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index d089b0a4480..39d6bedd8f5 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -45,7 +45,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Input')); expect(code, contains('class Output')); @@ -101,7 +101,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); // Method name and argument names should be adjusted. expect(code, contains(' DoSomething(const Input& some_input)')); @@ -144,7 +144,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect( @@ -184,7 +184,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect( @@ -238,7 +238,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('){'))); expect(code, isNot(contains('const{'))); @@ -271,7 +271,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains(''' #include @@ -286,7 +286,8 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(header: 'a_header.h'), root, sink); + generateCppSource( + const CppOptions(headerIncludePath: 'a_header.h'), root, sink); final String code = sink.toString(); expect(code, contains(''' #include "a_header.h" @@ -322,7 +323,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(namespace: 'foo'), root, sink); + generateCppHeader(const CppOptions(namespace: 'foo'), root, sink); final String code = sink.toString(); expect(code, contains('namespace foo {')); expect(code, contains('} // namespace foo')); @@ -390,7 +391,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); // Getters should return const pointers. expect(code, contains('const bool* nullable_bool()')); @@ -521,7 +522,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); // POD getters should return copies references. expect(code, contains('bool non_nullable_bool()')); @@ -644,7 +645,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect( code, contains('ErrorOr> ReturnNullableBool()')); @@ -749,7 +750,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains('ErrorOr ReturnBool()')); expect(code, contains('ErrorOr ReturnInt()')); @@ -825,7 +826,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -943,7 +944,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -1122,7 +1123,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateCppHeader('foo', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(headerIncludePath: 'foo'), root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('//$comment')); @@ -1157,7 +1158,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : public flutter::StandardCodecSerializer'))); }); @@ -1199,7 +1200,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateCppHeader('', const CppOptions(), root, sink); + generateCppHeader(const CppOptions(), root, sink); final String code = sink.toString(); expect(code, contains(' : public flutter::StandardCodecSerializer')); }); diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index 38442ccd358..c77e5d89e37 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -582,7 +582,7 @@ void main() { DartOptions(), root, testCodeSink, - dartOutPath: "fo'o.dart", + sourceOutPath: "fo'o.dart", testOutPath: 'test.dart', ); final String testCode = testCodeSink.toString(); @@ -1154,7 +1154,7 @@ name: foobar DartOptions(), root, sink, - dartOutPath: path.join(foo.path, 'bar.dart'), + sourceOutPath: path.join(foo.path, 'bar.dart'), testOutPath: path.join(tempDir.path, 'test', 'bar_test.dart'), ); final String code = sink.toString(); @@ -1358,7 +1358,7 @@ name: foobar DartOptions(), root, sink, - dartOutPath: 'code.dart', + sourceOutPath: 'code.dart', testOutPath: 'test.dart', ); final String testCode = sink.toString(); From 8c6abf2d240e184422a8864547934a06a90fb683 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 16:18:24 -0800 Subject: [PATCH 32/87] better field naming --- packages/pigeon/lib/objc_generator.dart | 10 +- packages/pigeon/lib/pigeon_lib.dart | 4 +- packages/pigeon/test/objc_generator_test.dart | 179 +++++++++++++----- 3 files changed, 136 insertions(+), 57 deletions(-) diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 48d512d65c1..a3cf3a7da2a 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -19,14 +19,14 @@ const DocumentCommentSpecification _docCommentSpec = class ObjcOptions { /// Parametric constructor for ObjcOptions. const ObjcOptions({ - this.header, + this.headerIncludePath, this.prefix, this.copyrightHeader, }); /// The path to the header that will get placed in the source filed (example: /// "foo.h"). - final String? header; + final String? headerIncludePath; /// Prefix that will be appended before all generated classes and protocols. final String? prefix; @@ -40,7 +40,7 @@ class ObjcOptions { final Iterable? copyrightHeader = map['copyrightHeader'] as Iterable?; return ObjcOptions( - header: map['header'] as String?, + headerIncludePath: map['header'] as String?, prefix: map['prefix'] as String?, copyrightHeader: copyrightHeader?.cast(), ); @@ -50,7 +50,7 @@ class ObjcOptions { /// `x = ObjcOptions.fromMap(x.toMap())`. Map toMap() { final Map result = { - if (header != null) 'header': header!, + if (headerIncludePath != null) 'header': headerIncludePath!, if (prefix != null) 'prefix': prefix!, if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!, }; @@ -910,7 +910,7 @@ void generateObjcSource(ObjcOptions options, Root root, StringSink sink) { } void writeImports() { - indent.writeln('#import "${options.header}"'); + indent.writeln('#import "${options.headerIncludePath}"'); indent.writeln('#import '); } diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 327ce27c08b..46ac932694a 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -1430,8 +1430,8 @@ ${_argParser.usage}'''; if (options.objcHeaderOut != null) { options = options.merge(PigeonOptions( - objcOptions: options.objcOptions!.merge( - ObjcOptions(header: path.basename(options.objcHeaderOut!))))); + objcOptions: options.objcOptions!.merge(ObjcOptions( + headerIncludePath: path.basename(options.objcHeaderOut!))))); } if (options.cppHeaderOut != null) { diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index cf83029338e..aeb2db68e26 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -32,7 +32,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcSource( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Foobar')); @@ -103,7 +104,8 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcSource( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Foobar')); @@ -133,7 +135,8 @@ void main() { ]) ]); final StringBuffer sink = StringBuffer(); - const ObjcOptions options = ObjcOptions(header: 'foo.h', prefix: 'AC'); + const ObjcOptions options = + ObjcOptions(headerIncludePath: 'foo.h', prefix: 'AC'); { generateObjcHeader(options, root, sink); final String code = sink.toString(); @@ -169,7 +172,7 @@ void main() { EnumMember(name: 'two'), ]) ]); - const ObjcOptions options = ObjcOptions(header: 'foo.h'); + const ObjcOptions options = ObjcOptions(headerIncludePath: 'foo.h'); final List errors = validateObjc(options, root); expect(errors.length, 1); expect(errors[0].message, contains('Nullable enum')); @@ -204,7 +207,8 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcHeader( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@property(nonatomic, assign) Enum1 enum1')); }); @@ -275,7 +279,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcSource( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Input')); @@ -322,7 +327,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcHeader( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, contains('@class FlutterStandardTypedData;')); @@ -350,7 +356,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcSource( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@implementation Foobar')); expect(code, @@ -371,7 +378,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcHeader( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@property(nonatomic, strong, nullable) Input * nested;')); @@ -391,7 +399,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcSource( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect( code, @@ -530,7 +539,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcHeader( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@interface Api : NSObject')); expect( @@ -569,7 +579,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink); + generateObjcSource( + const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); final String code = sink.toString(); expect(code, contains('@implementation Api')); expect(code, matches('void.*doSomething.*Input.*Output.*{')); @@ -599,7 +610,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('(void)doSomething:')); }); @@ -628,7 +641,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, isNot(matches('=.*doSomething'))); expect(code, matches('[.*doSomething:.*]')); @@ -659,7 +674,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('completion:(void(^)(NSError *_Nullable))')); }); @@ -688,7 +705,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('completion:(void(^)(NSError *_Nullable))')); expect(code, contains('completion(nil)')); @@ -712,7 +731,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, matches('ABCOutput.*doSomethingWithError:[(]FlutterError')); }); @@ -735,7 +756,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, matches('output.*=.*api doSomethingWithError:&error')); }); @@ -758,7 +781,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -784,7 +809,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -902,7 +929,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -941,7 +970,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -968,7 +999,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -988,7 +1021,9 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1027,7 +1062,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1065,7 +1102,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1085,7 +1124,9 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1112,7 +1153,9 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1129,7 +1172,7 @@ void main() { final StringBuffer sink = StringBuffer(); generateObjcSource( ObjcOptions( - header: 'foo.h', + headerIncludePath: 'foo.h', prefix: 'ABC', copyrightHeader: makeIterable('hello world')), root, @@ -1144,7 +1187,7 @@ void main() { final StringBuffer sink = StringBuffer(); generateObjcHeader( ObjcOptions( - header: 'foo.h', + headerIncludePath: 'foo.h', prefix: 'ABC', copyrightHeader: makeIterable('hello world')), root, @@ -1175,7 +1218,9 @@ void main() { ); final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('NSArray * field1')); }); @@ -1205,14 +1250,18 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); } { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1246,14 +1295,18 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); } { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); } @@ -1290,7 +1343,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *> *)arg')); } @@ -1317,7 +1372,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, contains('- (nullable NSArray *)doitWithError:')); @@ -1325,7 +1382,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('NSArray *output =')); } @@ -1352,7 +1411,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, contains('doitWithCompletion:(void(^)(NSArray *')); @@ -1360,7 +1421,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, contains('doitWithCompletion:(void(^)(NSArray *')); @@ -1389,7 +1452,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1399,7 +1464,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('NSArray *args = message;')); expect(code, @@ -1434,7 +1501,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1444,7 +1513,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect(code, contains('NSArray *args = message;')); expect(code, @@ -1477,7 +1548,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1487,7 +1560,9 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), root, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + root, + sink); final String code = sink.toString(); expect( code, @@ -1531,14 +1606,18 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + divideRoot, + sink); final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*error.*;')); } { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), divideRoot, sink); + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + divideRoot, + sink); final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*error.*;')); } @@ -1549,7 +1628,7 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcHeader( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), divideRoot, sink, ); @@ -1559,7 +1638,7 @@ void main() { { final StringBuffer sink = StringBuffer(); generateObjcSource( - const ObjcOptions(header: 'foo.h', prefix: 'ABC'), + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), divideRoot, sink, ); From 93a5d1bf619e53f558c1444995a83db867098f23 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 16:23:53 -0800 Subject: [PATCH 33/87] removed unneeded dart test generator --- packages/pigeon/lib/dart_generator.dart | 11 ++--------- packages/pigeon/lib/pigeon_lib.dart | 4 ++-- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 6d4b005d764..dca3c0fcd57 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -80,16 +80,9 @@ class DartGenerator extends Generator { void generate(DartOptions languageOptions, Root root, StringSink sink) { generateDart(languageOptions, root, sink); } -} - -/// Class that manages all Dart code generation. -class DartTestGenerator extends Generator { - /// Instantiates a Dart Generator. - DartTestGenerator(); - /// Generates Dart files with specified [DartOptions] - @override - void generate(DartOptions languageOptions, Root root, StringSink sink) { + /// Generates Dart files for testing with specified [DartOptions] + void generateTest(DartOptions languageOptions, Root root, StringSink sink) { final String sourceOutPath = languageOptions.sourceOutPath ?? ''; final String testOutPath = languageOptions.testOutPath ?? ''; generateTestDart( diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 46ac932694a..bfde7735b43 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -432,8 +432,8 @@ class DartTestGeneratorAdapter implements GeneratorAdapter { options.dartOut, options.dartTestOut, ); - final DartTestGenerator testGenerator = DartTestGenerator(); - testGenerator.generate( + final DartGenerator testGenerator = DartGenerator(); + testGenerator.generateTest( dartOptionsWithHeader, root, sink, From 710d1a1f2bc05a00da447684f0cd13921353d3f6 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 27 Dec 2022 16:29:24 -0800 Subject: [PATCH 34/87] Add filetype to generator --- packages/pigeon/lib/cpp_generator.dart | 8 +++----- packages/pigeon/lib/dart_generator.dart | 3 ++- packages/pigeon/lib/generator.dart | 4 +++- packages/pigeon/lib/java_generator.dart | 3 ++- packages/pigeon/lib/kotlin_generator.dart | 3 ++- packages/pigeon/lib/objc_generator.dart | 8 +++----- packages/pigeon/lib/pigeon_lib.dart | 24 +++++++++++------------ packages/pigeon/lib/swift_generator.dart | 3 ++- 8 files changed, 29 insertions(+), 27 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 225b8e9ca7b..ff7239efd2d 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -73,14 +73,12 @@ class CppOptions { /// Class that manages all Cpp header code generation. class CppGenerator extends Generator { /// Instantiates a Cpp Generator for the specified file type. - CppGenerator(this.fileType); - - /// Specifies which file type (header or source) will be generated. - FileType fileType; + CppGenerator(); /// Generates Cpp files with specified [CppOptions] @override - void generate(CppOptions languageOptions, Root root, StringSink sink) { + void generate(CppOptions languageOptions, Root root, StringSink sink, + FileType fileType) { if (fileType == FileType.header) { generateCppHeader(languageOptions, root, sink); } else { diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index dca3c0fcd57..f450d2ddeaa 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -77,7 +77,8 @@ class DartGenerator extends Generator { /// Generates Dart files with specified [DartOptions] @override - void generate(DartOptions languageOptions, Root root, StringSink sink) { + void generate( + DartOptions languageOptions, Root root, StringSink sink, FileType _) { generateDart(languageOptions, root, sink); } diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 02667e4a5c9..6cf63113a1f 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -3,11 +3,13 @@ // found in the LICENSE file. import 'ast.dart'; +import 'generator_tools.dart'; /// A superclass of generator classes. /// /// This provides the structure that is common across generators for different languages. abstract class Generator { /// Generates files for specified language with specified [languageOptions] - void generate(T languageOptions, Root root, StringSink sink); + void generate( + T languageOptions, Root root, StringSink sink, FileType fileType); } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 00293bfc0e8..e7b2ebcaf18 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -92,7 +92,8 @@ class JavaGenerator extends Generator { /// Generates Java files with specified [JavaOptions] @override - void generate(JavaOptions languageOptions, Root root, StringSink sink) { + void generate( + JavaOptions languageOptions, Root root, StringSink sink, FileType _) { generateJava(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 99690a4ac92..a570da4674b 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -72,7 +72,8 @@ class KotlinGenerator extends Generator { /// Generates Kotlin files with specified [KotlinOptions] @override - void generate(KotlinOptions languageOptions, Root root, StringSink sink) { + void generate( + KotlinOptions languageOptions, Root root, StringSink sink, FileType _) { generateKotlin(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index a3cf3a7da2a..4576ed6a66c 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -67,14 +67,12 @@ class ObjcOptions { /// Class that manages all Objc header code generation. class ObjcGenerator extends Generator { /// Instantiates a Objc Generator for the specified file type. - ObjcGenerator(this.fileType); - - /// Specifies which file type (header or source) will be generated. - FileType fileType; + ObjcGenerator(); /// Generates Objc files with specified [ObjcOptions] @override - void generate(ObjcOptions languageOptions, Root root, StringSink sink) { + void generate(ObjcOptions languageOptions, Root root, StringSink sink, + FileType fileType) { if (fileType == FileType.header) { generateObjcHeader(languageOptions, root, sink); } else { diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index bfde7735b43..0311d31e714 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -409,7 +409,7 @@ class DartGeneratorAdapter implements GeneratorAdapter { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader); final DartGenerator generator = DartGenerator(); - generator.generate(dartOptionsWithHeader, root, sink); + generator.generate(dartOptionsWithHeader, root, sink, FileType.source); } @override @@ -465,8 +465,8 @@ class ObjcHeaderGeneratorAdapter implements GeneratorAdapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final ObjcGenerator generator = ObjcGenerator(FileType.header); - generator.generate(objcOptionsWithHeader, root, sink); + final ObjcGenerator generator = ObjcGenerator(); + generator.generate(objcOptionsWithHeader, root, sink, FileType.header); } @override @@ -490,8 +490,8 @@ class ObjcSourceGeneratorAdapter implements GeneratorAdapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final ObjcGenerator generator = ObjcGenerator(FileType.source); - generator.generate(objcOptionsWithHeader, root, sink); + final ObjcGenerator generator = ObjcGenerator(); + generator.generate(objcOptionsWithHeader, root, sink, FileType.source); } @override @@ -517,7 +517,7 @@ class JavaGeneratorAdapter implements GeneratorAdapter { ? _lineReader(options.copyrightHeader!) : null)); final JavaGenerator generator = JavaGenerator(); - generator.generate(javaOptions, root, sink); + generator.generate(javaOptions, root, sink, FileType.source); } @override @@ -540,7 +540,7 @@ class SwiftGeneratorAdapter implements GeneratorAdapter { ? _lineReader(options.copyrightHeader!) : null)); final SwiftGenerator generator = SwiftGenerator(); - generator.generate(swiftOptions, root, sink); + generator.generate(swiftOptions, root, sink, FileType.source); } @override @@ -563,8 +563,8 @@ class CppHeaderGeneratorAdapter implements GeneratorAdapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final CppGenerator generator = CppGenerator(FileType.header); - generator.generate(cppOptionsWithHeader, root, sink); + final CppGenerator generator = CppGenerator(); + generator.generate(cppOptionsWithHeader, root, sink, FileType.header); } @override @@ -588,8 +588,8 @@ class CppSourceGeneratorAdapter implements GeneratorAdapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final CppGenerator generator = CppGenerator(FileType.source); - generator.generate(cppOptionsWithHeader, root, sink); + final CppGenerator generator = CppGenerator(); + generator.generate(cppOptionsWithHeader, root, sink, FileType.source); } @override @@ -614,7 +614,7 @@ class KotlinGeneratorAdapter implements GeneratorAdapter { ? _lineReader(options.copyrightHeader!) : null)); final KotlinGenerator generator = KotlinGenerator(); - generator.generate(kotlinOptions, root, sink); + generator.generate(kotlinOptions, root, sink, FileType.source); } @override diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index b25931c03e3..45c15341116 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -55,7 +55,8 @@ class SwiftGenerator extends Generator { /// Generates Swift files with specified [SwiftOptions] @override - void generate(SwiftOptions languageOptions, Root root, StringSink sink) { + void generate( + SwiftOptions languageOptions, Root root, StringSink sink, FileType _) { generateSwift(languageOptions, root, sink); } } From d189d11ad0dfd028252607a3d8399d9cd51d5d53 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 28 Dec 2022 23:04:36 -0800 Subject: [PATCH 35/87] Adds filetype as field to generatorAdapters --- packages/pigeon/lib/cpp_generator.dart | 2 +- packages/pigeon/lib/objc_generator.dart | 2 +- packages/pigeon/lib/pigeon_lib.dart | 213 +++++++++++----------- packages/pigeon/test/pigeon_lib_test.dart | 49 ++--- 4 files changed, 139 insertions(+), 127 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index ff7239efd2d..fbb90b39483 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -72,7 +72,7 @@ class CppOptions { /// Class that manages all Cpp header code generation. class CppGenerator extends Generator { - /// Instantiates a Cpp Generator for the specified file type. + /// Instantiates a Cpp Generator. CppGenerator(); /// Generates Cpp files with specified [CppOptions] diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 4576ed6a66c..110625414a2 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -66,7 +66,7 @@ class ObjcOptions { /// Class that manages all Objc header code generation. class ObjcGenerator extends Generator { - /// Instantiates a Objc Generator for the specified file type. + /// Instantiates a Objc Generator. ObjcGenerator(); /// Generates Objc files with specified [ObjcOptions] diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 0311d31e714..4e949ec3dd3 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -358,13 +358,21 @@ IOSink? _openSink(String? output) { /// An adapter that will call a generator to write code to a sink /// based on the contents of [PigeonOptions]. abstract class GeneratorAdapter { + /// Constructor for [GeneratorAdapter] + GeneratorAdapter(this.fileTypeList); + + /// A list of [FileType] + /// Used to tell the generator method which type of file to create. + List fileTypeList; + /// Returns an [IOSink] instance to be written to if the [GeneratorAdapter] should /// generate. If it returns `null`, the [GeneratorAdapter] will be skipped. - IOSink? shouldGenerate(PigeonOptions options); + IOSink? shouldGenerate(PigeonOptions options, FileType fileType); /// Write the generated code described in [root] to [sink] using the /// [options]. - void generate(StringSink sink, PigeonOptions options, Root root); + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType); /// Generates errors that would only be appropriate for this [GeneratorAdapter]. For /// example, maybe a certain feature isn't implemented in a [GeneratorAdapter] yet. @@ -385,15 +393,20 @@ DartOptions _dartOptionsWithCopyrightHeader( /// A [GeneratorAdapter] that generates the AST. class AstGeneratorAdapter implements GeneratorAdapter { /// Constructor for [AstGeneratorAdapter]. - const AstGeneratorAdapter(); + AstGeneratorAdapter(); + + @override + List fileTypeList = const [FileType.source]; @override - void generate(StringSink sink, PigeonOptions options, Root root) { + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { generateAst(root, sink); } @override - IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.astOut); + IOSink? shouldGenerate(PigeonOptions options, FileType _) => + _openSink(options.astOut); @override List validate(PigeonOptions options, Root root) => []; @@ -402,18 +415,23 @@ class AstGeneratorAdapter implements GeneratorAdapter { /// A [GeneratorAdapter] that generates Dart source code. class DartGeneratorAdapter implements GeneratorAdapter { /// Constructor for [DartGeneratorAdapter]. - const DartGeneratorAdapter(); + DartGeneratorAdapter(); @override - void generate(StringSink sink, PigeonOptions options, Root root) { + List fileTypeList = const [FileType.source]; + + @override + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader); final DartGenerator generator = DartGenerator(); - generator.generate(dartOptionsWithHeader, root, sink, FileType.source); + generator.generate(dartOptionsWithHeader, root, sink, fileType); } @override - IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.dartOut); + IOSink? shouldGenerate(PigeonOptions options, FileType _) => + _openSink(options.dartOut); @override List validate(PigeonOptions options, Root root) => []; @@ -422,10 +440,14 @@ class DartGeneratorAdapter implements GeneratorAdapter { /// A [GeneratorAdapter] that generates Dart test source code. class DartTestGeneratorAdapter implements GeneratorAdapter { /// Constructor for [DartTestGeneratorAdapter]. - const DartTestGeneratorAdapter(); + DartTestGeneratorAdapter(); @override - void generate(StringSink sink, PigeonOptions options, Root root) { + List fileTypeList = const [FileType.source]; + + @override + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader, @@ -441,7 +463,7 @@ class DartTestGeneratorAdapter implements GeneratorAdapter { } @override - IOSink? shouldGenerate(PigeonOptions options) { + IOSink? shouldGenerate(PigeonOptions options, FileType _) { if (options.dartTestOut != null) { return _openSink(options.dartTestOut); } else { @@ -453,50 +475,35 @@ class DartTestGeneratorAdapter implements GeneratorAdapter { List validate(PigeonOptions options, Root root) => []; } -/// A [GeneratorAdapter] that generates Objective-C header code. -class ObjcHeaderGeneratorAdapter implements GeneratorAdapter { - /// Constructor for [ObjcHeaderGeneratorAdapter]. - const ObjcHeaderGeneratorAdapter(); - - @override - void generate(StringSink sink, PigeonOptions options, Root root) { - final ObjcOptions objcOptions = options.objcOptions ?? const ObjcOptions(); - final ObjcOptions objcOptionsWithHeader = objcOptions.merge(ObjcOptions( - copyrightHeader: options.copyrightHeader != null - ? _lineReader(options.copyrightHeader!) - : null)); - final ObjcGenerator generator = ObjcGenerator(); - generator.generate(objcOptionsWithHeader, root, sink, FileType.header); - } - - @override - IOSink? shouldGenerate(PigeonOptions options) => - _openSink(options.objcHeaderOut); +/// A [GeneratorAdapter] that generates Objective-C code. +class ObjcGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [ObjcGeneratorAdapter]. + ObjcGeneratorAdapter( + {this.fileTypeList = const [FileType.header, FileType.source]}); @override - List validate(PigeonOptions options, Root root) => - validateObjc(options.objcOptions!, root); -} - -/// A [GeneratorAdapter] that generates Objective-C source code. -class ObjcSourceGeneratorAdapter implements GeneratorAdapter { - /// Constructor for [ObjcSourceGeneratorAdapter]. - const ObjcSourceGeneratorAdapter(); + List fileTypeList; @override - void generate(StringSink sink, PigeonOptions options, Root root) { + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { final ObjcOptions objcOptions = options.objcOptions ?? const ObjcOptions(); final ObjcOptions objcOptionsWithHeader = objcOptions.merge(ObjcOptions( copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); final ObjcGenerator generator = ObjcGenerator(); - generator.generate(objcOptionsWithHeader, root, sink, FileType.source); + generator.generate(objcOptionsWithHeader, root, sink, fileType); } @override - IOSink? shouldGenerate(PigeonOptions options) => - _openSink(options.objcSourceOut); + IOSink? shouldGenerate(PigeonOptions options, FileType fileType) { + if (fileType == FileType.source) { + return _openSink(options.objcSourceOut); + } else { + return _openSink(options.objcHeaderOut); + } + } @override List validate(PigeonOptions options, Root root) => []; @@ -505,10 +512,14 @@ class ObjcSourceGeneratorAdapter implements GeneratorAdapter { /// A [GeneratorAdapter] that generates Java source code. class JavaGeneratorAdapter implements GeneratorAdapter { /// Constructor for [JavaGeneratorAdapter]. - const JavaGeneratorAdapter(); + JavaGeneratorAdapter(); + + @override + List fileTypeList = const [FileType.source]; @override - void generate(StringSink sink, PigeonOptions options, Root root) { + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { JavaOptions javaOptions = options.javaOptions ?? const JavaOptions(); javaOptions = javaOptions.merge(JavaOptions( className: javaOptions.className ?? @@ -517,11 +528,12 @@ class JavaGeneratorAdapter implements GeneratorAdapter { ? _lineReader(options.copyrightHeader!) : null)); final JavaGenerator generator = JavaGenerator(); - generator.generate(javaOptions, root, sink, FileType.source); + generator.generate(javaOptions, root, sink, fileType); } @override - IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.javaOut); + IOSink? shouldGenerate(PigeonOptions options, FileType _) => + _openSink(options.javaOut); @override List validate(PigeonOptions options, Root root) => []; @@ -530,71 +542,60 @@ class JavaGeneratorAdapter implements GeneratorAdapter { /// A [GeneratorAdapter] that generates Swift source code. class SwiftGeneratorAdapter implements GeneratorAdapter { /// Constructor for [SwiftGeneratorAdapter]. - const SwiftGeneratorAdapter(); + SwiftGeneratorAdapter(); @override - void generate(StringSink sink, PigeonOptions options, Root root) { + List fileTypeList = const [FileType.source]; + + @override + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { SwiftOptions swiftOptions = options.swiftOptions ?? const SwiftOptions(); swiftOptions = swiftOptions.merge(SwiftOptions( copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); final SwiftGenerator generator = SwiftGenerator(); - generator.generate(swiftOptions, root, sink, FileType.source); + generator.generate(swiftOptions, root, sink, fileType); } @override - IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.swiftOut); + IOSink? shouldGenerate(PigeonOptions options, FileType _) => + _openSink(options.swiftOut); @override List validate(PigeonOptions options, Root root) => []; } -/// A [GeneratorAdapter] that generates C++ header code. -class CppHeaderGeneratorAdapter implements GeneratorAdapter { - /// Constructor for [CppHeaderGeneratorAdapter]. - const CppHeaderGeneratorAdapter(); - - @override - void generate(StringSink sink, PigeonOptions options, Root root) { - final CppOptions cppOptions = options.cppOptions ?? const CppOptions(); - final CppOptions cppOptionsWithHeader = cppOptions.merge(CppOptions( - headerOutPath: path.basenameWithoutExtension(options.cppHeaderOut!), - copyrightHeader: options.copyrightHeader != null - ? _lineReader(options.copyrightHeader!) - : null)); - final CppGenerator generator = CppGenerator(); - generator.generate(cppOptionsWithHeader, root, sink, FileType.header); - } - - @override - IOSink? shouldGenerate(PigeonOptions options) => - _openSink(options.cppHeaderOut); +/// A [GeneratorAdapter] that generates C++ source code. +class CppGeneratorAdapter implements GeneratorAdapter { + /// Constructor for [CppGeneratorAdapter]. + CppGeneratorAdapter( + {this.fileTypeList = const [FileType.header, FileType.source]}); @override - List validate(PigeonOptions options, Root root) => - validateCpp(options.cppOptions!, root); -} - -/// A [GeneratorAdapter] that generates C++ source code. -class CppSourceGeneratorAdapter implements GeneratorAdapter { - /// Constructor for [CppSourceGeneratorAdapter]. - const CppSourceGeneratorAdapter(); + List fileTypeList; @override - void generate(StringSink sink, PigeonOptions options, Root root) { + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { final CppOptions cppOptions = options.cppOptions ?? const CppOptions(); final CppOptions cppOptionsWithHeader = cppOptions.merge(CppOptions( copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); final CppGenerator generator = CppGenerator(); - generator.generate(cppOptionsWithHeader, root, sink, FileType.source); + generator.generate(cppOptionsWithHeader, root, sink, fileType); } @override - IOSink? shouldGenerate(PigeonOptions options) => - _openSink(options.cppSourceOut); + IOSink? shouldGenerate(PigeonOptions options, FileType fileType) { + if (fileType == FileType.source) { + return _openSink(options.cppSourceOut); + } else { + return _openSink(options.cppHeaderOut); + } + } @override List validate(PigeonOptions options, Root root) => []; @@ -603,10 +604,15 @@ class CppSourceGeneratorAdapter implements GeneratorAdapter { /// A [GeneratorAdapter] that generates Kotlin source code. class KotlinGeneratorAdapter implements GeneratorAdapter { /// Constructor for [KotlinGeneratorAdapter]. - const KotlinGeneratorAdapter(); + KotlinGeneratorAdapter( + {this.fileTypeList = const [FileType.source]}); + + @override + List fileTypeList; @override - void generate(StringSink sink, PigeonOptions options, Root root) { + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) { KotlinOptions kotlinOptions = options.kotlinOptions ?? const KotlinOptions(); kotlinOptions = kotlinOptions.merge(KotlinOptions( @@ -614,11 +620,12 @@ class KotlinGeneratorAdapter implements GeneratorAdapter { ? _lineReader(options.copyrightHeader!) : null)); final KotlinGenerator generator = KotlinGenerator(); - generator.generate(kotlinOptions, root, sink, FileType.source); + generator.generate(kotlinOptions, root, sink, fileType); } @override - IOSink? shouldGenerate(PigeonOptions options) => _openSink(options.kotlinOut); + IOSink? shouldGenerate(PigeonOptions options, FileType _) => + _openSink(options.kotlinOut); @override List validate(PigeonOptions options, Root root) => []; @@ -1367,16 +1374,14 @@ ${_argParser.usage}'''; } final List safeGeneratorAdapters = adapters ?? [ - const DartGeneratorAdapter(), - const JavaGeneratorAdapter(), - const SwiftGeneratorAdapter(), - const KotlinGeneratorAdapter(), - const CppHeaderGeneratorAdapter(), - const CppSourceGeneratorAdapter(), - const DartTestGeneratorAdapter(), - const ObjcHeaderGeneratorAdapter(), - const ObjcSourceGeneratorAdapter(), - const AstGeneratorAdapter(), + DartGeneratorAdapter(), + JavaGeneratorAdapter(), + SwiftGeneratorAdapter(), + KotlinGeneratorAdapter(), + CppGeneratorAdapter(), + DartTestGeneratorAdapter(), + ObjcGeneratorAdapter(), + AstGeneratorAdapter(), ]; _executeConfigurePigeon(options); @@ -1399,7 +1404,7 @@ ${_argParser.usage}'''; } for (final GeneratorAdapter adapter in safeGeneratorAdapters) { - final IOSink? sink = adapter.shouldGenerate(options); + final IOSink? sink = adapter.shouldGenerate(options, FileType.source); if (sink != null) { final List adapterErrors = adapter.validate(options, parseResults.root); @@ -1441,11 +1446,13 @@ ${_argParser.usage}'''; } for (final GeneratorAdapter adapter in safeGeneratorAdapters) { - final IOSink? sink = adapter.shouldGenerate(options); - if (sink != null) { - adapter.generate(sink, options, parseResults.root); - await sink.flush(); - await releaseSink(sink); + for (final FileType fileType in adapter.fileTypeList) { + final IOSink? sink = adapter.shouldGenerate(options, fileType); + if (sink != null) { + adapter.generate(sink, options, parseResults.root, fileType); + await sink.flush(); + await releaseSink(sink); + } } } diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 8d06f78cecc..1ff074d3a0f 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -6,20 +6,26 @@ import 'dart:async'; import 'dart:io'; import 'package:pigeon/ast.dart'; +import 'package:pigeon/generator_tools.dart'; import 'package:pigeon/pigeon_lib.dart'; import 'package:test/test.dart'; class _ValidatorGeneratorAdapter implements GeneratorAdapter { _ValidatorGeneratorAdapter(this.sink); + + @override + List fileTypeList = const [FileType.source]; + bool didCallValidate = false; final IOSink? sink; @override - void generate(StringSink sink, PigeonOptions options, Root root) {} + void generate( + StringSink sink, PigeonOptions options, Root root, FileType fileType) {} @override - IOSink? shouldGenerate(PigeonOptions options) => sink; + IOSink? shouldGenerate(PigeonOptions options, FileType _) => sink; @override List validate(PigeonOptions options, Root root) { @@ -397,9 +403,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const DartGeneratorAdapter dartGeneratorAdapter = DartGeneratorAdapter(); + final DartGeneratorAdapter dartGeneratorAdapter = DartGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - dartGeneratorAdapter.generate(buffer, options, root); + dartGeneratorAdapter.generate(buffer, options, root, FileType.source); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -407,9 +413,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( javaOut: 'Foo.java', copyrightHeader: './copyright_header.txt'); - const JavaGeneratorAdapter javaGeneratorAdapter = JavaGeneratorAdapter(); + final JavaGeneratorAdapter javaGeneratorAdapter = JavaGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - javaGeneratorAdapter.generate(buffer, options, root); + javaGeneratorAdapter.generate(buffer, options, root, FileType.source); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -417,10 +423,10 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const ObjcHeaderGeneratorAdapter objcHeaderGeneratorAdapter = - ObjcHeaderGeneratorAdapter(); + final ObjcGeneratorAdapter objcHeaderGeneratorAdapter = + ObjcGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - objcHeaderGeneratorAdapter.generate(buffer, options, root); + objcHeaderGeneratorAdapter.generate(buffer, options, root, FileType.header); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -428,10 +434,10 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const ObjcSourceGeneratorAdapter objcSourceGeneratorAdapter = - ObjcSourceGeneratorAdapter(); + final ObjcGeneratorAdapter objcSourceGeneratorAdapter = + ObjcGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - objcSourceGeneratorAdapter.generate(buffer, options, root); + objcSourceGeneratorAdapter.generate(buffer, options, root, FileType.source); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -439,9 +445,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( swiftOut: 'Foo.swift', copyrightHeader: './copyright_header.txt'); - const SwiftGeneratorAdapter swiftGeneratorAdapter = SwiftGeneratorAdapter(); + final SwiftGeneratorAdapter swiftGeneratorAdapter = SwiftGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - swiftGeneratorAdapter.generate(buffer, options, root); + swiftGeneratorAdapter.generate(buffer, options, root, FileType.source); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -449,10 +455,9 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions( cppHeaderOut: 'Foo.h', copyrightHeader: './copyright_header.txt'); - const CppHeaderGeneratorAdapter cppHeaderGeneratorAdapter = - CppHeaderGeneratorAdapter(); + final CppGeneratorAdapter cppHeaderGeneratorAdapter = CppGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - cppHeaderGeneratorAdapter.generate(buffer, options, root); + cppHeaderGeneratorAdapter.generate(buffer, options, root, FileType.header); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -460,10 +465,10 @@ abstract class NestorApi { final Root root = Root(apis: [], classes: [], enums: []); const PigeonOptions options = PigeonOptions(copyrightHeader: './copyright_header.txt'); - const CppSourceGeneratorAdapter cppSourceGeneratorAdapter = - CppSourceGeneratorAdapter(); + final CppGeneratorAdapter cppSourceGeneratorAdapter = + CppGeneratorAdapter(fileTypeList: [FileType.source]); final StringBuffer buffer = StringBuffer(); - cppSourceGeneratorAdapter.generate(buffer, options, root); + cppSourceGeneratorAdapter.generate(buffer, options, root, FileType.source); expect(buffer.toString(), startsWith('// Copyright 2013')); }); @@ -933,10 +938,10 @@ abstract class Api { dartTestOut: 'stdout', dartOut: 'stdout', ); - const DartTestGeneratorAdapter dartGeneratorAdapter = + final DartTestGeneratorAdapter dartGeneratorAdapter = DartTestGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - dartGeneratorAdapter.generate(buffer, options, root); + dartGeneratorAdapter.generate(buffer, options, root, FileType.source); expect(buffer.toString(), startsWith('// Copyright 2013')); }); From 859c6cbb7aee800113817348d40a1ebe095ad3ba Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 29 Dec 2022 11:53:04 -0800 Subject: [PATCH 36/87] merge --- packages/pigeon/lib/dart_generator.dart | 1 + packages/pigeon/mock_handler_tester/test/message.dart | 3 ++- packages/pigeon/mock_handler_tester/test/test.dart | 2 +- .../example/alternate_language_test_plugin/CoreTests.java | 2 +- .../ios/Classes/CoreTests.gen.h | 3 ++- .../ios/Classes/CoreTests.gen.m | 3 ++- .../flutter_null_safe_unit_tests/lib/core_tests.gen.dart | 3 ++- .../lib/multiple_arity.gen.dart | 3 ++- .../lib/non_null_fields.gen.dart | 3 ++- .../flutter_null_safe_unit_tests/lib/null_fields.gen.dart | 3 ++- .../lib/null_safe_pigeon.dart | 3 ++- .../lib/nullable_returns.gen.dart | 3 ++- .../flutter_null_safe_unit_tests/lib/primitive.dart | 3 ++- .../lib/src/generated/core_tests.gen.dart | 3 ++- .../main/kotlin/com/example/test_plugin/CoreTests.gen.kt | 2 +- .../test_plugin/ios/Classes/CoreTests.gen.swift | 2 +- .../test_plugin/macos/Classes/CoreTests.gen.swift | 2 +- .../test_plugin/windows/pigeon/core_tests.gen.cpp | 2 +- .../test_plugin/windows/pigeon/core_tests.gen.h | 8 ++++---- packages/pigeon/test/pigeon_lib_test.dart | 4 ++-- 20 files changed, 35 insertions(+), 23 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 9c6e1360e23..ae17374e18e 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -96,6 +96,7 @@ class DartGenerator extends Generator { final Indent indent = Indent(sink); final String sourceOutPath = languageOptions.sourceOutPath ?? ''; final String testOutPath = languageOptions.testOutPath ?? ''; + writeTestHeader(languageOptions, root, sink, indent); generateTestDart( languageOptions, root, diff --git a/packages/pigeon/mock_handler_tester/test/message.dart b/packages/pigeon/mock_handler_tester/test/message.dart index 4f6c9d14457..94024e73bc7 100644 --- a/packages/pigeon/mock_handler_tester/test/message.dart +++ b/packages/pigeon/mock_handler_tester/test/message.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/mock_handler_tester/test/test.dart b/packages/pigeon/mock_handler_tester/test/test.dart index 9b97826b605..e1644f13686 100644 --- a/packages/pigeon/mock_handler_tester/test/test.dart +++ b/packages/pigeon/mock_handler_tester/test/test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, unnecessary_import // ignore_for_file: avoid_relative_lib_imports diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index 2d81d4b59f1..a6d28a36db7 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon package com.example.alternate_language_test_plugin; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index dcdee87c5d9..3e921d36aee 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon + #import @protocol FlutterBinaryMessenger; @protocol FlutterMessageCodec; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index bcdd86394a6..3fb7d4b98d5 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon + #import "CoreTests.gen.h" #import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart index ee79a4b1a27..49d7d40d13a 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart index e92ab29cebd..4bed42b32dd 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart index 1ff71bfa346..5d4cbd0096e 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart index 88f4611e746..0d151dc54e4 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart index 13fe926bcf1..820749f7bef 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart index be1979c8adf..a050c155e05 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart index 36a569e4f46..a5e4e6b318f 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index ee79a4b1a27..49d7d40d13a 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index c1add054eaf..d5c9882ba12 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon package com.example.test_plugin diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index c9850b70d36..b21cbd5fbc0 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index c9850b70d36..b21cbd5fbc0 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp index f0d5929ce4a..2b46028b18e 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index a2ea204b578..fca12d2ec92 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon -#ifndef PIGEON_CORE_TESTS_PIGEONTEST_H_ -#define PIGEON_CORE_TESTS_PIGEONTEST_H_ +#ifndef PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ +#define PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ #include #include #include @@ -406,4 +406,4 @@ class HostTrivialApi { HostTrivialApi() = default; }; } // namespace core_tests_pigeontest -#endif // PIGEON_CORE_TESTS_PIGEONTEST_H_ +#endif // PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 1ff074d3a0f..d7201bb688b 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -938,10 +938,10 @@ abstract class Api { dartTestOut: 'stdout', dartOut: 'stdout', ); - final DartTestGeneratorAdapter dartGeneratorAdapter = + final DartTestGeneratorAdapter dartTestGeneratorAdapter = DartTestGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - dartGeneratorAdapter.generate(buffer, options, root, FileType.source); + dartTestGeneratorAdapter.generate(buffer, options, root, FileType.source); expect(buffer.toString(), startsWith('// Copyright 2013')); }); From 6dff8cbae4489240c2d4fc2f75c801a06e5e6b80 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 29 Dec 2022 12:17:46 -0800 Subject: [PATCH 37/87] analyze --- packages/pigeon/lib/cpp_generator.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index b291e9aea19..65fa011722c 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:io'; - import 'ast.dart'; import 'functional.dart'; import 'generator.dart'; From c17c1e4d6e58af11f8735622b95567a7f5003497 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 29 Dec 2022 12:48:36 -0800 Subject: [PATCH 38/87] add import method --- packages/pigeon/lib/dart_generator.dart | 31 +++++++++++++++---------- packages/pigeon/lib/generator.dart | 12 +++++++++- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index ae17374e18e..ce7b5631448 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -82,6 +82,7 @@ class DartGenerator extends Generator { final Indent indent = Indent(sink); writeFileHeaders(languageOptions, root, sink, indent, fileType); + writeFileImports(languageOptions, root, sink, indent, fileType); generateDart(languageOptions, root, sink, indent); } @@ -91,6 +92,12 @@ class DartGenerator extends Generator { writeHeader(languageOptions, root, sink, indent); } + @override + void writeFileImports(DartOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + writeImports(languageOptions, root, sink, indent); + } + /// Generates Dart files for testing with specified [DartOptions] void generateTest(DartOptions languageOptions, Root root, StringSink sink) { final Indent indent = Indent(sink); @@ -553,6 +560,18 @@ void writeHeader(DartOptions opt, Root root, StringSink sink, Indent indent) { indent.addln(''); } +/// Writes file imports to sink. +void writeImports(DartOptions opt, Root root, StringSink sink, Indent indent) { + indent.writeln("import 'dart:async';"); + indent.writeln( + "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", + ); + indent.addln(''); + indent.writeln( + "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); + indent.writeln("import 'package:flutter/services.dart';"); +} + /// Generates Dart source code for the given AST represented by [root], /// outputting the code to [sink]. void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) { @@ -577,17 +596,6 @@ void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) { } } - void writeImports() { - indent.writeln("import 'dart:async';"); - indent.writeln( - "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", - ); - indent.addln(''); - indent.writeln( - "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); - indent.writeln("import 'package:flutter/services.dart';"); - } - void writeDataClass(Class klass) { void writeConstructor() { indent.write(klass.name); @@ -718,7 +726,6 @@ $resultAt != null } } - writeImports(); writeEnums(); for (final Class klass in root.classes) { indent.writeln(''); diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 9f4b835bb3c..86fa40fbbc5 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -14,7 +14,8 @@ abstract class Generator { /// This method, when overridden, should follow a generic structure that is currently: /// 1. Create Indent /// 2. Write File Headers - /// 3. Generate File + /// 3. Write Imports + /// 4. Generate File void generate( T languageOptions, Root root, @@ -30,4 +31,13 @@ abstract class Generator { Indent indent, FileType fileType, ); + + /// Adds specified imports. + void writeFileImports( + T languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + ); } From d9f116ff4ea9a4417cb9e051f4478acd08b8e24e Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 29 Dec 2022 12:56:38 -0800 Subject: [PATCH 39/87] re-remove DartTestGenerator --- packages/pigeon/lib/dart_generator.dart | 32 ----------- packages/pigeon/test/dart_generator_test.dart | 54 +++++++++---------- 2 files changed, 27 insertions(+), 59 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index ae17374e18e..25d505c8dff 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -108,38 +108,6 @@ class DartGenerator extends Generator { } } -/// Class that manages all Dart code generation. -class DartTestGenerator extends Generator { - /// Instantiates a Dart Generator. - DartTestGenerator(); - - /// Generates Dart files with specified [DartOptions] - @override - void generate(DartOptions languageOptions, Root root, StringSink sink, - FileType fileType) { - final Indent indent = Indent(sink); - - final String sourceOutPath = languageOptions.sourceOutPath ?? ''; - final String testOutPath = languageOptions.testOutPath ?? ''; - - writeFileHeaders(languageOptions, root, sink, indent, fileType); - generateTestDart( - languageOptions, - root, - sink, - indent, - sourceOutPath: sourceOutPath, - testOutPath: testOutPath, - ); - } - - @override - void writeFileHeaders(DartOptions languageOptions, Root root, StringSink sink, - Indent indent, FileType fileType) { - writeTestHeader(languageOptions, root, sink, indent); - } -} - String _escapeForDartSingleQuotedString(String raw) { return raw .replaceAll(r'\', r'\\') diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index c8d5f3af04c..31ff53a92cc 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -595,15 +595,15 @@ void main() { expect(mainCode, isNot(contains("'${Keys.result}': output"))); expect(mainCode, isNot(contains('return [];'))); - final DartTestGenerator testGenerator = DartTestGenerator(); - testGenerator.generate( - DartOptions( - sourceOutPath: "fo'o.dart", - testOutPath: 'test.dart', - ), - root, - testCodeSink, - FileType.source); + final DartGenerator testGenerator = DartGenerator(); + testGenerator.generateTest( + DartOptions( + sourceOutPath: "fo'o.dart", + testOutPath: 'test.dart', + ), + root, + testCodeSink, + ); final String testCode = testCodeSink.toString(); expect(testCode, contains(r"import 'fo\'o.dart';")); expect(testCode, isNot(contains('class Api {'))); @@ -1189,15 +1189,15 @@ name: foobar final Root root = Root(classes: [], apis: [], enums: []); final StringBuffer sink = StringBuffer(); - final DartTestGenerator testGenerator = DartTestGenerator(); - testGenerator.generate( - DartOptions( - sourceOutPath: path.join(foo.path, 'bar.dart'), - testOutPath: path.join(tempDir.path, 'test', 'bar_test.dart'), - ), - root, - sink, - FileType.source); + final DartGenerator testGenerator = DartGenerator(); + testGenerator.generateTest( + DartOptions( + sourceOutPath: path.join(foo.path, 'bar.dart'), + testOutPath: path.join(tempDir.path, 'test', 'bar_test.dart'), + ), + root, + sink, + ); final String code = sink.toString(); expect(code, contains("import 'package:foobar/foo/bar.dart';")); } finally { @@ -1399,15 +1399,15 @@ name: foobar ); final StringBuffer sink = StringBuffer(); - final DartTestGenerator testGenerator = DartTestGenerator(); - testGenerator.generate( - DartOptions( - sourceOutPath: 'code.dart', - testOutPath: 'test.dart', - ), - root, - sink, - FileType.source); + final DartGenerator testGenerator = DartGenerator(); + testGenerator.generateTest( + DartOptions( + sourceOutPath: 'code.dart', + testOutPath: 'test.dart', + ), + root, + sink, + ); final String testCode = sink.toString(); expect( From e57de98a9d752efcf2c91ed565edcb24ab3c490e Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 29 Dec 2022 13:48:01 -0800 Subject: [PATCH 40/87] Moves imports to new method --- packages/pigeon/lib/cpp_generator.dart | 39 ++++++++--- packages/pigeon/lib/dart_generator.dart | 24 ++++--- packages/pigeon/lib/java_generator.dart | 55 ++++++++------- packages/pigeon/lib/kotlin_generator.dart | 40 ++++++----- packages/pigeon/lib/objc_generator.dart | 68 +++++++++++-------- packages/pigeon/lib/swift_generator.dart | 38 +++++++---- .../ios/Classes/CoreTests.gen.h | 1 + .../windows/pigeon/core_tests.gen.h | 1 + 8 files changed, 162 insertions(+), 104 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 65fa011722c..e41a9480129 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -80,11 +80,11 @@ class CppGenerator extends Generator { void generate(CppOptions languageOptions, Root root, StringSink sink, FileType fileType) { final Indent indent = Indent(sink); + writeFileHeaders(languageOptions, root, sink, indent, fileType); + writeFileImports(languageOptions, root, sink, indent, fileType); if (fileType == FileType.header) { - writeFileHeaders(languageOptions, root, sink, indent, fileType); generateCppHeader(languageOptions, root, sink, indent); } else { - writeFileHeaders(languageOptions, root, sink, indent, fileType); generateCppSource(languageOptions, root, sink, indent); } } @@ -98,6 +98,16 @@ class CppGenerator extends Generator { writeCppSourceHeader(languageOptions, root, sink, indent); } } + + @override + void writeFileImports(CppOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + if (fileType == FileType.header) { + writeCppHeaderImports(languageOptions, root, sink, indent); + } else { + writeCppSourceImports(languageOptions, root, sink, indent); + } + } } String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; @@ -1056,9 +1066,8 @@ void writeCppHeaderHeader( indent.addln(''); } -/// Generates the ".h" file for the AST represented by [root] to [sink] with the -/// provided [options] and [headerFileName]. -void generateCppHeader( +/// Writes Cpp header file imports to sink. +void writeCppHeaderImports( CppOptions options, Root root, StringSink sink, Indent indent) { final String guardName = _getGuardName(options.headerIncludePath, options.namespace); @@ -1078,11 +1087,16 @@ void generateCppHeader( 'optional', ]); indent.addln(''); - if (options.namespace != null) { indent.writeln('namespace ${options.namespace} {'); } + indent.addln(''); +} +/// Generates the ".h" file for the AST represented by [root] to [sink] with the +/// provided [options] and [headerFileName]. +void generateCppHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { // When generating for a Pigeon unit test, add a test fixture friend class to // allow unit testing private methods, since testing serialization via public // methods is essentially an end-to-end test. @@ -1137,7 +1151,8 @@ void generateCppHeader( if (options.namespace != null) { indent.writeln('} // namespace ${options.namespace}'); } - + final String guardName = + _getGuardName(options.headerIncludePath, options.namespace); indent.writeln('#endif // $guardName'); } @@ -1154,9 +1169,8 @@ void writeCppSourceHeader( indent.addln(''); } -/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateCppSource( +/// Writes Cpp source file imports to sink. +void writeCppSourceImports( CppOptions options, Root root, StringSink sink, Indent indent) { indent.writeln('#include "${options.headerIncludePath}"'); indent.addln(''); @@ -1177,7 +1191,12 @@ void generateCppSource( if (options.namespace != null) { indent.writeln('namespace ${options.namespace} {'); } +} +/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the +/// provided [options]. +void generateCppSource( + CppOptions options, Root root, StringSink sink, Indent indent) { for (final Class klass in root.classes) { _writeDataClassImplementation(indent, klass, root); } diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 506b7e55158..6d233121de6 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -104,6 +104,7 @@ class DartGenerator extends Generator { final String sourceOutPath = languageOptions.sourceOutPath ?? ''; final String testOutPath = languageOptions.testOutPath ?? ''; writeTestHeader(languageOptions, root, sink, indent); + writeTestImports(languageOptions, root, sink, indent); generateTestDart( languageOptions, root, @@ -768,6 +769,20 @@ void writeTestHeader( indent.writeln('// ignore_for_file: avoid_relative_lib_imports'); } +/// Writes file imports to sink. +void writeTestImports( + DartOptions opt, Root root, StringSink sink, Indent indent) { + indent.writeln("import 'dart:async';"); + indent.writeln( + "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", + ); + indent.writeln( + "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); + indent.writeln("import 'package:flutter/services.dart';"); + indent.writeln("import 'package:flutter_test/flutter_test.dart';"); + indent.writeln(''); +} + /// Generates Dart source code for test support libraries based on the given AST /// represented by [root], outputting the code to [sink]. [dartOutPath] is the /// path of the generated dart code to be tested. [testOutPath] is where the @@ -780,15 +795,6 @@ void generateTestDart( required String sourceOutPath, required String testOutPath, }) { - indent.writeln("import 'dart:async';"); - indent.writeln( - "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", - ); - indent.writeln( - "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); - indent.writeln("import 'package:flutter/services.dart';"); - indent.writeln("import 'package:flutter_test/flutter_test.dart';"); - indent.writeln(''); final String relativeDartPath = path.Context(style: path.Style.posix).relative( _posixify(sourceOutPath), diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 3e89aa0b190..89ca7daba33 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -97,6 +97,7 @@ class JavaGenerator extends Generator { final Indent indent = Indent(sink); writeFileHeaders(languageOptions, root, sink, indent, fileType); + writeFileImports(languageOptions, root, sink, indent, fileType); generateJava(languageOptions, root, sink, indent); } @@ -105,6 +106,12 @@ class JavaGenerator extends Generator { Indent indent, FileType fileType) { writeHeader(languageOptions, root, sink, indent); } + + @override + void writeFileImports(JavaOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + writeImports(languageOptions, root, sink, indent); + } } /// Calculates the name of the codec that will be generated for [api]. @@ -555,6 +562,30 @@ void writeHeader( indent.addln(''); } +/// Writes file imports to sink. +void writeImports( + JavaOptions options, Root root, StringSink sink, Indent indent) { + if (options.package != null) { + indent.writeln('package ${options.package};'); + } + indent.writeln('import android.util.Log;'); + indent.writeln('import androidx.annotation.NonNull;'); + indent.writeln('import androidx.annotation.Nullable;'); + indent.writeln('import io.flutter.plugin.common.BasicMessageChannel;'); + indent.writeln('import io.flutter.plugin.common.BinaryMessenger;'); + indent.writeln('import io.flutter.plugin.common.MessageCodec;'); + indent.writeln('import io.flutter.plugin.common.StandardMessageCodec;'); + indent.writeln('import java.io.ByteArrayOutputStream;'); + indent.writeln('import java.nio.ByteBuffer;'); + indent.writeln('import java.util.Arrays;'); + indent.writeln('import java.util.ArrayList;'); + indent.writeln('import java.util.Collections;'); + indent.writeln('import java.util.List;'); + indent.writeln('import java.util.Map;'); + indent.writeln('import java.util.HashMap;'); + indent.addln(''); +} + /// Generates the ".java" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateJava( @@ -564,24 +595,6 @@ void generateJava( final Set rootEnumNameSet = root.enums.map((Enum x) => x.name).toSet(); - void writeImports() { - indent.writeln('import android.util.Log;'); - indent.writeln('import androidx.annotation.NonNull;'); - indent.writeln('import androidx.annotation.Nullable;'); - indent.writeln('import io.flutter.plugin.common.BasicMessageChannel;'); - indent.writeln('import io.flutter.plugin.common.BinaryMessenger;'); - indent.writeln('import io.flutter.plugin.common.MessageCodec;'); - indent.writeln('import io.flutter.plugin.common.StandardMessageCodec;'); - indent.writeln('import java.io.ByteArrayOutputStream;'); - indent.writeln('import java.nio.ByteBuffer;'); - indent.writeln('import java.util.Arrays;'); - indent.writeln('import java.util.ArrayList;'); - indent.writeln('import java.util.Collections;'); - indent.writeln('import java.util.List;'); - indent.writeln('import java.util.Map;'); - indent.writeln('import java.util.HashMap;'); - } - String camelToSnake(String camelCase) { final RegExp regex = RegExp('([a-z])([A-Z]+)'); return camelCase @@ -777,12 +790,6 @@ void generateJava( }'''); } - if (options.package != null) { - indent.writeln('package ${options.package};'); - } - indent.addln(''); - writeImports(); - indent.addln(''); indent.writeln( '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); indent.writeln( diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 3ee47a29cd1..ed4af8e4413 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -77,6 +77,7 @@ class KotlinGenerator extends Generator { final Indent indent = Indent(sink); writeFileHeaders(languageOptions, root, sink, indent, fileType); + writeFileImports(languageOptions, root, sink, indent, fileType); generateKotlin(languageOptions, root, sink, indent); } @@ -85,6 +86,12 @@ class KotlinGenerator extends Generator { StringSink sink, Indent indent, FileType fileType) { writeHeader(languageOptions, root, sink, indent); } + + @override + void writeFileImports(KotlinOptions languageOptions, Root root, + StringSink sink, Indent indent, FileType fileType) { + writeImports(languageOptions, root, sink, indent); + } } /// Calculates the name of the codec that will be generated for [api]. @@ -468,6 +475,23 @@ void writeHeader( indent.addln(''); } +/// Writes file imports to sink. +void writeImports( + KotlinOptions options, Root root, StringSink sink, Indent indent) { + if (options.package != null) { + indent.writeln('package ${options.package}'); + } + indent.addln(''); + indent.writeln('import android.util.Log'); + indent.writeln('import io.flutter.plugin.common.BasicMessageChannel'); + indent.writeln('import io.flutter.plugin.common.BinaryMessenger'); + indent.writeln('import io.flutter.plugin.common.MessageCodec'); + indent.writeln('import io.flutter.plugin.common.StandardMessageCodec'); + indent.writeln('import java.io.ByteArrayOutputStream'); + indent.writeln('import java.nio.ByteBuffer'); + indent.addln(''); +} + /// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateKotlin( @@ -482,16 +506,6 @@ void generateKotlin( (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); } - void writeImports() { - indent.writeln('import android.util.Log'); - indent.writeln('import io.flutter.plugin.common.BasicMessageChannel'); - indent.writeln('import io.flutter.plugin.common.BinaryMessenger'); - indent.writeln('import io.flutter.plugin.common.MessageCodec'); - indent.writeln('import io.flutter.plugin.common.StandardMessageCodec'); - indent.writeln('import java.io.ByteArrayOutputStream'); - indent.writeln('import java.nio.ByteBuffer'); - } - void writeEnum(Enum anEnum) { addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -676,12 +690,6 @@ void generateKotlin( }); } - if (options.package != null) { - indent.writeln('package ${options.package}'); - } - indent.addln(''); - writeImports(); - indent.addln(''); indent.writeln('/** Generated class from Pigeon. */'); for (final Enum anEnum in root.enums) { indent.writeln(''); diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 68b4d63f064..b1f2cff6fac 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -75,11 +75,11 @@ class ObjcGenerator extends Generator { FileType fileType) { final Indent indent = Indent(sink); + writeFileHeaders(languageOptions, root, sink, indent, fileType); + writeFileImports(languageOptions, root, sink, indent, fileType); if (fileType == FileType.header) { - writeFileHeaders(languageOptions, root, sink, indent, fileType); generateObjcHeader(languageOptions, root, sink, indent); } else { - writeFileHeaders(languageOptions, root, sink, indent, fileType); generateObjcSource(languageOptions, root, sink, indent); } } @@ -93,6 +93,16 @@ class ObjcGenerator extends Generator { writeObjcSourceHeader(languageOptions, root, sink, indent); } } + + @override + void writeFileImports(ObjcOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + if (fileType == FileType.header) { + writeObjcHeaderImports(languageOptions, root, sink, indent); + } else { + writeObjcSourceImports(languageOptions, root, sink, indent); + } + } } /// Calculates the ObjC class name, possibly prefixed. @@ -573,21 +583,23 @@ void writeObjcHeaderHeader( indent.addln(''); } +/// Writes Objc header file imports to sink. +void writeObjcHeaderImports( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + indent.writeln('#import '); + indent.addln(''); + + indent.writeln('@protocol FlutterBinaryMessenger;'); + indent.writeln('@protocol FlutterMessageCodec;'); + indent.writeln('@class FlutterError;'); + indent.writeln('@class FlutterStandardTypedData;'); + indent.addln(''); +} + /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateObjcHeader( ObjcOptions options, Root root, StringSink sink, Indent indent) { - void writeImports() { - indent.writeln('#import '); - } - - void writeForwardDeclarations() { - indent.writeln('@protocol FlutterBinaryMessenger;'); - indent.writeln('@protocol FlutterMessageCodec;'); - indent.writeln('@class FlutterError;'); - indent.writeln('@class FlutterStandardTypedData;'); - } - void writeEnum(Enum anEnum) { final String enumName = _className(options.prefix, anEnum.name); addDocumentationComments( @@ -605,8 +617,6 @@ void generateObjcHeader( }); } - writeImports(); - writeForwardDeclarations(); indent.writeln(''); indent.writeln('NS_ASSUME_NONNULL_BEGIN'); @@ -917,6 +927,19 @@ void writeObjcSourceHeader( indent.addln(''); } +/// Writes Objc source file imports to sink. +void writeObjcSourceImports( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + indent.writeln('#import "${options.headerIncludePath}"'); + indent.writeln('#import '); + indent.addln(''); + + indent.writeln('#if !__has_feature(objc_arc)'); + indent.writeln('#error File requires ARC to be enabled.'); + indent.writeln('#endif'); + indent.addln(''); +} + /// Generates the ".m" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateObjcSource( @@ -925,17 +948,6 @@ void generateObjcSource( root.classes.map((Class x) => x.name).toList(); final List enumNames = root.enums.map((Enum x) => x.name).toList(); - void writeImports() { - indent.writeln('#import "${options.headerIncludePath}"'); - indent.writeln('#import '); - } - - void writeArcEnforcer() { - indent.writeln('#if !__has_feature(objc_arc)'); - indent.writeln('#error File requires ARC to be enabled.'); - indent.writeln('#endif'); - } - void writeHelperFunctions() { indent.format(''' static NSArray *wrapResult(id result, FlutterError *error) { @@ -1041,10 +1053,6 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { } } - writeImports(); - indent.writeln(''); - writeArcEnforcer(); - indent.addln(''); writeHelperFunctions(); indent.addln(''); root.classes.forEach(writeDataClassExtension); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 76093450f66..38311dc614d 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -59,6 +59,7 @@ class SwiftGenerator extends Generator { FileType fileType) { final Indent indent = Indent(sink); writeFileHeaders(languageOptions, root, sink, indent, fileType); + writeFileImports(languageOptions, root, sink, indent, fileType); generateSwift(languageOptions, root, sink, indent); } @@ -67,6 +68,12 @@ class SwiftGenerator extends Generator { StringSink sink, Indent indent, FileType fileType) { writeHeader(languageOptions, root, sink, indent); } + + @override + void writeFileImports(SwiftOptions languageOptions, Root root, + StringSink sink, Indent indent, FileType fileType) { + writeImports(languageOptions, root, sink, indent); + } } /// Calculates the name of the codec that will be generated for [api]. @@ -462,6 +469,22 @@ void writeHeader( indent.addln(''); } +/// Writes file header to sink. +void writeImports( + SwiftOptions options, Root root, StringSink sink, Indent indent) { + indent.writeln('import Foundation'); + indent.format(''' +#if os(iOS) +import Flutter +#elseif os(macOS) +import FlutterMacOS +#else +#error("Unsupported platform.") +#endif +'''); + indent.writeln(''); +} + /// Generates the ".swift" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateSwift( @@ -476,19 +499,6 @@ void generateSwift( (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); } - void writeImports() { - indent.writeln('import Foundation'); - indent.format(''' -#if os(iOS) -import Flutter -#elseif os(macOS) -import FlutterMacOS -#else -#error("Unsupported platform.") -#endif -'''); - } - void writeEnum(Enum anEnum) { addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -644,8 +654,6 @@ import FlutterMacOS }); } - writeImports(); - indent.addln(''); indent.writeln('$_docCommentPrefix Generated class from Pigeon.'); for (final Enum anEnum in root.enums) { indent.writeln(''); diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index 3e921d36aee..5e235e67567 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -6,6 +6,7 @@ // See also: https://pub.dev/packages/pigeon #import + @protocol FlutterBinaryMessenger; @protocol FlutterMessageCodec; @class FlutterError; diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index fca12d2ec92..aa954c0de5e 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -17,6 +17,7 @@ #include namespace core_tests_pigeontest { + class CoreTestsTest; // Generated class from Pigeon. From fc63d50ed664a698ee3efd271d196516657c968e Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 30 Dec 2022 12:57:22 -0800 Subject: [PATCH 41/87] adds writeEnum method to generator class --- packages/pigeon/lib/cpp_generator.dart | 62 ++++--- packages/pigeon/lib/dart_generator.dart | 88 +++++----- packages/pigeon/lib/generator.dart | 18 +- packages/pigeon/lib/java_generator.dart | 195 +++++++++++----------- packages/pigeon/lib/kotlin_generator.dart | 127 +++++++------- packages/pigeon/lib/swift_generator.dart | 97 +++++------ 6 files changed, 290 insertions(+), 297 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index e41a9480129..78a7a1ffabd 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -80,8 +80,17 @@ class CppGenerator extends Generator { void generate(CppOptions languageOptions, Root root, StringSink sink, FileType fileType) { final Indent indent = Indent(sink); - writeFileHeaders(languageOptions, root, sink, indent, fileType); - writeFileImports(languageOptions, root, sink, indent, fileType); + writeHeaders(languageOptions, root, sink, indent, fileType); + writeImports(languageOptions, root, sink, indent, fileType); + + indent.writeln('$_commentPrefix Generated class from Pigeon.'); + + for (final Enum anEnum in root.enums) { + writeEnum(languageOptions, root, sink, indent, fileType, anEnum); + } + + indent.addln(''); + if (fileType == FileType.header) { generateCppHeader(languageOptions, root, sink, indent); } else { @@ -90,7 +99,7 @@ class CppGenerator extends Generator { } @override - void writeFileHeaders(CppOptions languageOptions, Root root, StringSink sink, + void writeHeaders(CppOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { if (fileType == FileType.header) { writeCppHeaderHeader(languageOptions, root, sink, indent); @@ -100,7 +109,7 @@ class CppGenerator extends Generator { } @override - void writeFileImports(CppOptions languageOptions, Root root, StringSink sink, + void writeImports(CppOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { if (fileType == FileType.header) { writeCppHeaderImports(languageOptions, root, sink, indent); @@ -108,6 +117,14 @@ class CppGenerator extends Generator { writeCppSourceImports(languageOptions, root, sink, indent); } } + + @override + void writeEnum(CppOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Enum anEnum) { + if (fileType == FileType.header) { + writeCppHeaderEnum(languageOptions, root, sink, indent, anEnum); + } + } } String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; @@ -1093,6 +1110,23 @@ void writeCppHeaderImports( indent.addln(''); } +/// Writes Cpp header enum to sink. +void writeCppHeaderEnum(CppOptions options, Root root, StringSink sink, + Indent indent, Enum anEnum) { + indent.writeln(''); + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + indent.write('enum class ${anEnum.name} '); + indent.scoped('{', '};', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + indent.writeln( + '${member.name} = $index${index == anEnum.members.length - 1 ? '' : ','}'); + }); + }); +} + /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options] and [headerFileName]. void generateCppHeader( @@ -1107,26 +1141,6 @@ void generateCppHeader( indent.writeln('class $testFixtureClass;'); } - indent.addln(''); - indent.writeln('$_commentPrefix Generated class from Pigeon.'); - - for (final Enum anEnum in root.enums) { - indent.writeln(''); - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - indent.write('enum class ${anEnum.name} '); - indent.scoped('{', '};', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - indent.writeln( - '${member.name} = $index${index == anEnum.members.length - 1 ? '' : ','}'); - }); - }); - } - - indent.addln(''); - _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); for (final Class klass in root.classes) { diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 6d233121de6..08223d010a8 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -81,21 +81,55 @@ class DartGenerator extends Generator { FileType fileType) { final Indent indent = Indent(sink); - writeFileHeaders(languageOptions, root, sink, indent, fileType); - writeFileImports(languageOptions, root, sink, indent, fileType); + writeHeaders(languageOptions, root, sink, indent, fileType); + writeImports(languageOptions, root, sink, indent, fileType); + for (final Enum anEnum in root.enums) { + writeEnum(languageOptions, root, sink, indent, fileType, anEnum); + } generateDart(languageOptions, root, sink, indent); } @override - void writeFileHeaders(DartOptions languageOptions, Root root, StringSink sink, + void writeHeaders(DartOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { - writeHeader(languageOptions, root, sink, indent); + if (languageOptions.copyrightHeader != null) { + addLines(indent, languageOptions.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.writeln( + '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import', + ); + indent.addln(''); } @override - void writeFileImports(DartOptions languageOptions, Root root, StringSink sink, + void writeImports(DartOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { - writeImports(languageOptions, root, sink, indent); + indent.writeln("import 'dart:async';"); + indent.writeln( + "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", + ); + indent.addln(''); + indent.writeln( + "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); + indent.writeln("import 'package:flutter/services.dart';"); + } + + @override + void writeEnum(DartOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Enum anEnum) { + indent.writeln(''); + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + indent.write('enum ${anEnum.name} '); + indent.scoped('{', '}', () { + for (final EnumMember member in anEnum.members) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + indent.writeln('${member.name},'); + } + }); } /// Generates Dart files for testing with specified [DartOptions] @@ -516,31 +550,6 @@ String _addGenericTypesNullable(TypeDeclaration type) { return type.isNullable ? '$genericdType?' : genericdType; } -/// Writes file header to sink. -void writeHeader(DartOptions opt, Root root, StringSink sink, Indent indent) { - if (opt.copyrightHeader != null) { - addLines(indent, opt.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.writeln( - '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import', - ); - indent.addln(''); -} - -/// Writes file imports to sink. -void writeImports(DartOptions opt, Root root, StringSink sink, Indent indent) { - indent.writeln("import 'dart:async';"); - indent.writeln( - "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", - ); - indent.addln(''); - indent.writeln( - "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); - indent.writeln("import 'package:flutter/services.dart';"); -} - /// Generates Dart source code for the given AST represented by [root], /// outputting the code to [sink]. void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) { @@ -549,22 +558,6 @@ void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) { final List customEnumNames = root.enums.map((Enum x) => x.name).toList(); - void writeEnums() { - for (final Enum anEnum in root.enums) { - indent.writeln(''); - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - indent.write('enum ${anEnum.name} '); - indent.scoped('{', '}', () { - for (final EnumMember member in anEnum.members) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - indent.writeln('${member.name},'); - } - }); - } - } - void writeDataClass(Class klass) { void writeConstructor() { indent.write(klass.name); @@ -695,7 +688,6 @@ $resultAt != null } } - writeEnums(); for (final Class klass in root.classes) { indent.writeln(''); writeDataClass(klass); diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 86fa40fbbc5..c7fcd06d51a 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -23,8 +23,8 @@ abstract class Generator { FileType fileType, ); - /// Adds specified file headers. - void writeFileHeaders( + /// Adds specified headers to file. + void writeHeaders( T languageOptions, Root root, StringSink sink, @@ -32,12 +32,22 @@ abstract class Generator { FileType fileType, ); - /// Adds specified imports. - void writeFileImports( + /// Adds specified imports to file. + void writeImports( T languageOptions, Root root, StringSink sink, Indent indent, FileType fileType, ); + + /// Writes single Enum to file. + void writeEnum( + T languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Enum anEnum, + ); } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 89ca7daba33..d488c3425ae 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -96,21 +96,94 @@ class JavaGenerator extends Generator { FileType fileType) { final Indent indent = Indent(sink); - writeFileHeaders(languageOptions, root, sink, indent, fileType); - writeFileImports(languageOptions, root, sink, indent, fileType); - generateJava(languageOptions, root, sink, indent); + writeHeaders(languageOptions, root, sink, indent, fileType); + writeImports(languageOptions, root, sink, indent, fileType); + writeMainClass(languageOptions, root, sink, indent, fileType); } @override - void writeFileHeaders(JavaOptions languageOptions, Root root, StringSink sink, + void writeHeaders(JavaOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { - writeHeader(languageOptions, root, sink, indent); + if (languageOptions.copyrightHeader != null) { + addLines(indent, languageOptions.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); } @override - void writeFileImports(JavaOptions languageOptions, Root root, StringSink sink, + void writeImports(JavaOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { - writeImports(languageOptions, root, sink, indent); + if (languageOptions.package != null) { + indent.writeln('package ${languageOptions.package};'); + } + indent.writeln('import android.util.Log;'); + indent.writeln('import androidx.annotation.NonNull;'); + indent.writeln('import androidx.annotation.Nullable;'); + indent.writeln('import io.flutter.plugin.common.BasicMessageChannel;'); + indent.writeln('import io.flutter.plugin.common.BinaryMessenger;'); + indent.writeln('import io.flutter.plugin.common.MessageCodec;'); + indent.writeln('import io.flutter.plugin.common.StandardMessageCodec;'); + indent.writeln('import java.io.ByteArrayOutputStream;'); + indent.writeln('import java.nio.ByteBuffer;'); + indent.writeln('import java.util.Arrays;'); + indent.writeln('import java.util.ArrayList;'); + indent.writeln('import java.util.Collections;'); + indent.writeln('import java.util.List;'); + indent.writeln('import java.util.Map;'); + indent.writeln('import java.util.HashMap;'); + indent.addln(''); + } + + @override + void writeEnum(JavaOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Enum anEnum) { + String camelToSnake(String camelCase) { + final RegExp regex = RegExp('([a-z])([A-Z]+)'); + return camelCase + .replaceAllMapped(regex, (Match m) => '${m[1]}_${m[2]}') + .toUpperCase(); + } + + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + + indent.write('public enum ${anEnum.name} '); + indent.scoped('{', '}', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + indent.writeln( + '${camelToSnake(member.name)}($index)${index == anEnum.members.length - 1 ? ';' : ','}'); + }); + indent.writeln(''); + indent.writeln('private final int index;'); + indent.write('private ${anEnum.name}(final int index) '); + indent.scoped('{', '}', () { + indent.writeln('this.index = index;'); + }); + }); + } + + /// Writes main class to sink. wraps enums, apis, and classes. + void writeMainClass(JavaOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + indent.writeln( + '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); + indent.writeln( + '@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})'); + if (languageOptions.useGeneratedAnnotation ?? false) { + indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); + } + indent.write('public class ${languageOptions.className!} '); + indent.scoped('{', '}', () { + for (final Enum anEnum in root.enums) { + indent.writeln(''); + writeEnum(languageOptions, root, sink, indent, fileType, anEnum); + } + generateJava(languageOptions, root, sink, indent); + }); } } @@ -551,41 +624,6 @@ String _castObject( } } -/// Writes file header to sink. -void writeHeader( - JavaOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.addln(''); -} - -/// Writes file imports to sink. -void writeImports( - JavaOptions options, Root root, StringSink sink, Indent indent) { - if (options.package != null) { - indent.writeln('package ${options.package};'); - } - indent.writeln('import android.util.Log;'); - indent.writeln('import androidx.annotation.NonNull;'); - indent.writeln('import androidx.annotation.Nullable;'); - indent.writeln('import io.flutter.plugin.common.BasicMessageChannel;'); - indent.writeln('import io.flutter.plugin.common.BinaryMessenger;'); - indent.writeln('import io.flutter.plugin.common.MessageCodec;'); - indent.writeln('import io.flutter.plugin.common.StandardMessageCodec;'); - indent.writeln('import java.io.ByteArrayOutputStream;'); - indent.writeln('import java.nio.ByteBuffer;'); - indent.writeln('import java.util.Arrays;'); - indent.writeln('import java.util.ArrayList;'); - indent.writeln('import java.util.Collections;'); - indent.writeln('import java.util.List;'); - indent.writeln('import java.util.Map;'); - indent.writeln('import java.util.HashMap;'); - indent.addln(''); -} - /// Generates the ".java" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateJava( @@ -595,34 +633,6 @@ void generateJava( final Set rootEnumNameSet = root.enums.map((Enum x) => x.name).toSet(); - String camelToSnake(String camelCase) { - final RegExp regex = RegExp('([a-z])([A-Z]+)'); - return camelCase - .replaceAllMapped(regex, (Match m) => '${m[1]}_${m[2]}') - .toUpperCase(); - } - - void writeEnum(Enum anEnum) { - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - - indent.write('public enum ${anEnum.name} '); - indent.scoped('{', '}', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - indent.writeln( - '${camelToSnake(member.name)}($index)${index == anEnum.members.length - 1 ? ';' : ','}'); - }); - indent.writeln(''); - indent.writeln('private final int index;'); - indent.write('private ${anEnum.name}(final int index) '); - indent.scoped('{', '}', () { - indent.writeln('this.index = index;'); - }); - }); - } - void writeDataClass(Class klass) { void writeField(NamedType field) { final HostDatatype hostDatatype = getFieldHostDatatype( @@ -790,40 +800,25 @@ void generateJava( }'''); } - indent.writeln( - '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); - indent.writeln( - '@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})'); - if (options.useGeneratedAnnotation ?? false) { - indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); + for (final Class klass in root.classes) { + indent.addln(''); + writeDataClass(klass); } - indent.write('public class ${options.className!} '); - indent.scoped('{', '}', () { - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(anEnum); - } - for (final Class klass in root.classes) { - indent.addln(''); - writeDataClass(klass); - } + if (root.apis.any((Api api) => + api.location == ApiLocation.host && + api.methods.any((Method it) => it.isAsynchronous))) { + indent.addln(''); + writeResultInterface(); + } - if (root.apis.any((Api api) => - api.location == ApiLocation.host && - api.methods.any((Method it) => it.isAsynchronous))) { + for (final Api api in root.apis) { + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(indent, api, root); indent.addln(''); - writeResultInterface(); - } - - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(indent, api, root); - indent.addln(''); - } - writeApi(api); } + writeApi(api); + } - writeWrapError(); - }); + writeWrapError(); } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index ed4af8e4413..71ca87bb00f 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -76,21 +76,71 @@ class KotlinGenerator extends Generator { FileType fileType) { final Indent indent = Indent(sink); - writeFileHeaders(languageOptions, root, sink, indent, fileType); - writeFileImports(languageOptions, root, sink, indent, fileType); + writeHeaders(languageOptions, root, sink, indent, fileType); + writeImports(languageOptions, root, sink, indent, fileType); + indent.writeln('/** Generated class from Pigeon. */'); + for (final Enum anEnum in root.enums) { + indent.writeln(''); + writeEnum(languageOptions, root, sink, indent, fileType, anEnum); + } generateKotlin(languageOptions, root, sink, indent); } @override - void writeFileHeaders(KotlinOptions languageOptions, Root root, - StringSink sink, Indent indent, FileType fileType) { - writeHeader(languageOptions, root, sink, indent); + void writeHeaders(KotlinOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + if (languageOptions.copyrightHeader != null) { + addLines(indent, languageOptions.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); } @override - void writeFileImports(KotlinOptions languageOptions, Root root, - StringSink sink, Indent indent, FileType fileType) { - writeImports(languageOptions, root, sink, indent); + void writeImports(KotlinOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + if (languageOptions.package != null) { + indent.writeln('package ${languageOptions.package}'); + } + indent.addln(''); + indent.writeln('import android.util.Log'); + indent.writeln('import io.flutter.plugin.common.BasicMessageChannel'); + indent.writeln('import io.flutter.plugin.common.BinaryMessenger'); + indent.writeln('import io.flutter.plugin.common.MessageCodec'); + indent.writeln('import io.flutter.plugin.common.StandardMessageCodec'); + indent.writeln('import java.io.ByteArrayOutputStream'); + indent.writeln('import java.nio.ByteBuffer'); + indent.addln(''); + } + + @override + void writeEnum(KotlinOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Enum anEnum) { + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + indent.write('enum class ${anEnum.name}(val raw: Int) '); + indent.scoped('{', '}', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + indent.write('${member.name.toUpperCase()}($index)'); + if (index != anEnum.members.length - 1) { + indent.addln(','); + } else { + indent.addln(';'); + } + }); + + indent.writeln(''); + indent.write('companion object '); + indent.scoped('{', '}', () { + indent.write('fun ofRaw(raw: Int): ${anEnum.name}? '); + indent.scoped('{', '}', () { + indent.writeln('return values().firstOrNull { it.raw == raw }'); + }); + }); + }); } } @@ -464,34 +514,6 @@ String _nullsafeKotlinTypeForDartType(TypeDeclaration type) { return '${_kotlinTypeForDartType(type)}$nullSafe'; } -/// Writes file header to sink. -void writeHeader( - KotlinOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.addln(''); -} - -/// Writes file imports to sink. -void writeImports( - KotlinOptions options, Root root, StringSink sink, Indent indent) { - if (options.package != null) { - indent.writeln('package ${options.package}'); - } - indent.addln(''); - indent.writeln('import android.util.Log'); - indent.writeln('import io.flutter.plugin.common.BasicMessageChannel'); - indent.writeln('import io.flutter.plugin.common.BinaryMessenger'); - indent.writeln('import io.flutter.plugin.common.MessageCodec'); - indent.writeln('import io.flutter.plugin.common.StandardMessageCodec'); - indent.writeln('import java.io.ByteArrayOutputStream'); - indent.writeln('import java.nio.ByteBuffer'); - indent.addln(''); -} - /// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateKotlin( @@ -506,33 +528,6 @@ void generateKotlin( (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); } - void writeEnum(Enum anEnum) { - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - indent.write('enum class ${anEnum.name}(val raw: Int) '); - indent.scoped('{', '}', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - indent.write('${member.name.toUpperCase()}($index)'); - if (index != anEnum.members.length - 1) { - indent.addln(','); - } else { - indent.addln(';'); - } - }); - - indent.writeln(''); - indent.write('companion object '); - indent.scoped('{', '}', () { - indent.write('fun ofRaw(raw: Int): ${anEnum.name}? '); - indent.scoped('{', '}', () { - indent.writeln('return values().firstOrNull { it.raw == raw }'); - }); - }); - }); - } - void writeDataClass(Class klass) { void writeField(NamedType field) { addDocumentationComments( @@ -690,12 +685,6 @@ void generateKotlin( }); } - indent.writeln('/** Generated class from Pigeon. */'); - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(anEnum); - } - for (final Class klass in root.classes) { indent.addln(''); writeDataClass(klass); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 38311dc614d..9f362fa4aef 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -58,21 +58,57 @@ class SwiftGenerator extends Generator { void generate(SwiftOptions languageOptions, Root root, StringSink sink, FileType fileType) { final Indent indent = Indent(sink); - writeFileHeaders(languageOptions, root, sink, indent, fileType); - writeFileImports(languageOptions, root, sink, indent, fileType); + writeHeaders(languageOptions, root, sink, indent, fileType); + writeImports(languageOptions, root, sink, indent, fileType); + indent.writeln('$_docCommentPrefix Generated class from Pigeon.'); + for (final Enum anEnum in root.enums) { + indent.writeln(''); + writeEnum(languageOptions, root, sink, indent, fileType, anEnum); + } generateSwift(languageOptions, root, sink, indent); } @override - void writeFileHeaders(SwiftOptions languageOptions, Root root, - StringSink sink, Indent indent, FileType fileType) { - writeHeader(languageOptions, root, sink, indent); + void writeHeaders(SwiftOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + if (languageOptions.copyrightHeader != null) { + addLines(indent, languageOptions.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); + } + + @override + void writeImports(SwiftOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType) { + indent.writeln('import Foundation'); + indent.format(''' +#if os(iOS) +import Flutter +#elseif os(macOS) +import FlutterMacOS +#else +#error("Unsupported platform.") +#endif +'''); + indent.writeln(''); } @override - void writeFileImports(SwiftOptions languageOptions, Root root, - StringSink sink, Indent indent, FileType fileType) { - writeImports(languageOptions, root, sink, indent); + void writeEnum(SwiftOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Enum anEnum) { + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + + indent.write('enum ${anEnum.name}: Int '); + indent.scoped('{', '}', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + indent.writeln('case ${_camelCase(member.name)} = $index'); + }); + }); } } @@ -458,32 +494,9 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { return '${_swiftTypeForDartType(type)}$nullSafe'; } -/// Writes file header to sink. -void writeHeader( - SwiftOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.addln(''); -} - /// Writes file header to sink. void writeImports( - SwiftOptions options, Root root, StringSink sink, Indent indent) { - indent.writeln('import Foundation'); - indent.format(''' -#if os(iOS) -import Flutter -#elseif os(macOS) -import FlutterMacOS -#else -#error("Unsupported platform.") -#endif -'''); - indent.writeln(''); -} + SwiftOptions options, Root root, StringSink sink, Indent indent) {} /// Generates the ".swift" file for the AST represented by [root] to [sink] with the /// provided [options]. @@ -499,20 +512,6 @@ void generateSwift( (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); } - void writeEnum(Enum anEnum) { - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - - indent.write('enum ${anEnum.name}: Int '); - indent.scoped('{', '}', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - indent.writeln('case ${_camelCase(member.name)} = $index'); - }); - }); - } - void writeDataClass(Class klass) { void writeField(NamedType field) { addDocumentationComments( @@ -654,12 +653,6 @@ void generateSwift( }); } - indent.writeln('$_docCommentPrefix Generated class from Pigeon.'); - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(anEnum); - } - for (final Class klass in root.classes) { indent.addln(''); writeDataClass(klass); From 29decb9c934378483137aacc74a0189ee4515f58 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 30 Dec 2022 13:12:33 -0800 Subject: [PATCH 42/87] nits --- packages/pigeon/lib/cpp_generator.dart | 2 +- packages/pigeon/lib/dart_generator.dart | 2 +- packages/pigeon/lib/pigeon_lib.dart | 23 ++++++++++++----------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index fbb90b39483..d5cce4c5744 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -70,7 +70,7 @@ class CppOptions { } } -/// Class that manages all Cpp header code generation. +/// Class that manages all Cpp code generation. class CppGenerator extends Generator { /// Instantiates a Cpp Generator. CppGenerator(); diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index f450d2ddeaa..5a38061ec8e 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -34,7 +34,7 @@ class DartOptions { /// A copyright header that will get prepended to generated code. final Iterable? copyrightHeader; - /// Path to output generated Dart file for tests. + /// Path to output generated Dart file. String? sourceOutPath; /// Path to output generated Test file for tests. diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 4e949ec3dd3..d54f64d3bf0 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -361,27 +361,28 @@ abstract class GeneratorAdapter { /// Constructor for [GeneratorAdapter] GeneratorAdapter(this.fileTypeList); - /// A list of [FileType] - /// Used to tell the generator method which type of file to create. + /// A list of file types the generator should create. List fileTypeList; - /// Returns an [IOSink] instance to be written to if the [GeneratorAdapter] should - /// generate. If it returns `null`, the [GeneratorAdapter] will be skipped. + /// Returns an [IOSink] instance to be written to + /// if the [GeneratorAdapter] should generate. + /// + /// If it returns `null`, the [GeneratorAdapter] will be skipped. IOSink? shouldGenerate(PigeonOptions options, FileType fileType); - /// Write the generated code described in [root] to [sink] using the - /// [options]. + /// Write the generated code described in [root] to [sink] using the [options]. void generate( StringSink sink, PigeonOptions options, Root root, FileType fileType); - /// Generates errors that would only be appropriate for this [GeneratorAdapter]. For - /// example, maybe a certain feature isn't implemented in a [GeneratorAdapter] yet. + /// Generates errors that would only be appropriate for this [GeneratorAdapter]. + /// + /// For example, if a certain feature isn't implemented in a [GeneratorAdapter] yet. List validate(PigeonOptions options, Root root); } DartOptions _dartOptionsWithCopyrightHeader( DartOptions? dartOptions, String? copyrightHeader, - [String? dartOutPath, String? testOutPath]) { + {String? dartOutPath, String? testOutPath}) { dartOptions = dartOptions ?? DartOptions(); return dartOptions.merge(DartOptions( sourceOutPath: dartOutPath, @@ -451,8 +452,8 @@ class DartTestGeneratorAdapter implements GeneratorAdapter { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader, - options.dartOut, - options.dartTestOut, + dartOutPath: options.dartOut, + testOutPath: options.dartTestOut, ); final DartGenerator testGenerator = DartGenerator(); testGenerator.generateTest( From b7abbe402c2c0a0588ec65311aab65fd9eecd4c0 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Mon, 2 Jan 2023 23:33:08 -0800 Subject: [PATCH 43/87] assert --- packages/pigeon/lib/dart_generator.dart | 5 +++-- packages/pigeon/lib/java_generator.dart | 5 +++-- packages/pigeon/lib/kotlin_generator.dart | 5 +++-- packages/pigeon/lib/swift_generator.dart | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 5a38061ec8e..852b3cfa08c 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -77,8 +77,9 @@ class DartGenerator extends Generator { /// Generates Dart files with specified [DartOptions] @override - void generate( - DartOptions languageOptions, Root root, StringSink sink, FileType _) { + void generate(DartOptions languageOptions, Root root, StringSink sink, + FileType fileType) { + assert(fileType == FileType.source); generateDart(languageOptions, root, sink); } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index e7b2ebcaf18..d62612db23d 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -92,8 +92,9 @@ class JavaGenerator extends Generator { /// Generates Java files with specified [JavaOptions] @override - void generate( - JavaOptions languageOptions, Root root, StringSink sink, FileType _) { + void generate(JavaOptions languageOptions, Root root, StringSink sink, + FileType fileType) { + assert(fileType == FileType.source); generateJava(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index a570da4674b..07855c226b1 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -72,8 +72,9 @@ class KotlinGenerator extends Generator { /// Generates Kotlin files with specified [KotlinOptions] @override - void generate( - KotlinOptions languageOptions, Root root, StringSink sink, FileType _) { + void generate(KotlinOptions languageOptions, Root root, StringSink sink, + FileType fileType) { + assert(fileType == FileType.source); generateKotlin(languageOptions, root, sink); } } diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 45c15341116..6a278344d00 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -55,8 +55,9 @@ class SwiftGenerator extends Generator { /// Generates Swift files with specified [SwiftOptions] @override - void generate( - SwiftOptions languageOptions, Root root, StringSink sink, FileType _) { + void generate(SwiftOptions languageOptions, Root root, StringSink sink, + FileType fileType) { + assert(fileType == FileType.source); generateSwift(languageOptions, root, sink); } } From 2508a81b2185912c157c49fa0ec9d94a367a1ad1 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 3 Jan 2023 00:33:23 -0800 Subject: [PATCH 44/87] objc enum --- packages/pigeon/lib/objc_generator.dart | 69 ++++++++++++++----------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index b1f2cff6fac..bd229cf1fa1 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -75,9 +75,16 @@ class ObjcGenerator extends Generator { FileType fileType) { final Indent indent = Indent(sink); - writeFileHeaders(languageOptions, root, sink, indent, fileType); - writeFileImports(languageOptions, root, sink, indent, fileType); + writeHeaders(languageOptions, root, sink, indent, fileType); + writeImports(languageOptions, root, sink, indent, fileType); if (fileType == FileType.header) { + indent.writeln('NS_ASSUME_NONNULL_BEGIN'); + + for (final Enum anEnum in root.enums) { + indent.writeln(''); + writeEnum(languageOptions, root, sink, indent, fileType, anEnum); + } + indent.writeln(''); generateObjcHeader(languageOptions, root, sink, indent); } else { generateObjcSource(languageOptions, root, sink, indent); @@ -85,7 +92,7 @@ class ObjcGenerator extends Generator { } @override - void writeFileHeaders(ObjcOptions languageOptions, Root root, StringSink sink, + void writeHeaders(ObjcOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { if (fileType == FileType.header) { writeObjcHeaderHeader(languageOptions, root, sink, indent); @@ -95,7 +102,7 @@ class ObjcGenerator extends Generator { } @override - void writeFileImports(ObjcOptions languageOptions, Root root, StringSink sink, + void writeImports(ObjcOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { if (fileType == FileType.header) { writeObjcHeaderImports(languageOptions, root, sink, indent); @@ -103,6 +110,14 @@ class ObjcGenerator extends Generator { writeObjcSourceImports(languageOptions, root, sink, indent); } } + + @override + void writeEnum(ObjcOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Enum anEnum) { + if (fileType == FileType.header) { + writeObjcHeaderEnum(languageOptions, root, sink, indent, anEnum); + } + } } /// Calculates the ObjC class name, possibly prefixed. @@ -596,37 +611,29 @@ void writeObjcHeaderImports( indent.addln(''); } +/// Writes single Objc header enum. +void writeObjcHeaderEnum(ObjcOptions options, Root root, StringSink sink, + Indent indent, Enum anEnum) { + final String enumName = _className(options.prefix, anEnum.name); + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + + indent.write('typedef NS_ENUM(NSUInteger, $enumName) '); + indent.scoped('{', '};', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + // Capitalized first letter to ensure Swift compatibility + indent.writeln( + '$enumName${member.name[0].toUpperCase()}${member.name.substring(1)} = $index,'); + }); + }); +} + /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateObjcHeader( ObjcOptions options, Root root, StringSink sink, Indent indent) { - void writeEnum(Enum anEnum) { - final String enumName = _className(options.prefix, anEnum.name); - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - - indent.write('typedef NS_ENUM(NSUInteger, $enumName) '); - indent.scoped('{', '};', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - // Capitalized first letter to ensure Swift compatibility - indent.writeln( - '$enumName${member.name[0].toUpperCase()}${member.name.substring(1)} = $index,'); - }); - }); - } - - indent.writeln(''); - - indent.writeln('NS_ASSUME_NONNULL_BEGIN'); - - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(anEnum); - } - indent.writeln(''); - for (final Class klass in root.classes) { indent.writeln('@class ${_className(options.prefix, klass.name)};'); } From e4ac916e28252ca86f5255d6daa8bfd856bf5488 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 3 Jan 2023 01:50:47 -0800 Subject: [PATCH 45/87] fix code order issues --- packages/pigeon/lib/cpp_generator.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 2cb1cc03c73..da3ba128307 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -83,8 +83,6 @@ class CppGenerator extends Generator { writeHeaders(languageOptions, root, sink, indent, fileType); writeImports(languageOptions, root, sink, indent, fileType); - indent.writeln('$_commentPrefix Generated class from Pigeon.'); - for (final Enum anEnum in root.enums) { writeEnum(languageOptions, root, sink, indent, fileType, anEnum); } @@ -1108,6 +1106,13 @@ void writeCppHeaderImports( indent.writeln('namespace ${options.namespace} {'); } indent.addln(''); + if (options.namespace?.endsWith('_pigeontest') ?? false) { + final String testFixtureClass = + '${_pascalCaseFromSnakeCase(options.namespace!.replaceAll('_pigeontest', ''))}Test'; + indent.writeln('class $testFixtureClass;'); + } + indent.addln(''); + indent.writeln('$_commentPrefix Generated class from Pigeon.'); } /// Writes Cpp header enum to sink. @@ -1138,7 +1143,6 @@ void generateCppHeader( if (options.namespace?.endsWith('_pigeontest') ?? false) { testFixtureClass = '${_pascalCaseFromSnakeCase(options.namespace!.replaceAll('_pigeontest', ''))}Test'; - indent.writeln('class $testFixtureClass;'); } _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); From f1a4924144cd13b7644d3b086d0437b80048ad04 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 3 Jan 2023 23:18:35 -0800 Subject: [PATCH 46/87] add writeDataClass method --- packages/pigeon/lib/dart_generator.dart | 316 +++++++++++++----------- packages/pigeon/lib/generator.dart | 50 +++- 2 files changed, 218 insertions(+), 148 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index c3f0e9e9250..f6ec330b7d7 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -84,9 +84,16 @@ class DartGenerator extends Generator { writeHeaders(languageOptions, root, sink, indent, fileType); writeImports(languageOptions, root, sink, indent, fileType); + for (final Enum anEnum in root.enums) { writeEnum(languageOptions, root, sink, indent, fileType, anEnum); } + + for (final Class klass in root.classes) { + indent.writeln(''); + writeDataClass(languageOptions, root, sink, indent, fileType, klass); + } + generateDart(languageOptions, root, sink, indent); } @@ -133,24 +140,174 @@ class DartGenerator extends Generator { }); } - /// Generates Dart files for testing with specified [DartOptions] - void generateTest(DartOptions languageOptions, Root root, StringSink sink) { - final Indent indent = Indent(sink); - final String sourceOutPath = languageOptions.sourceOutPath ?? ''; - final String testOutPath = languageOptions.testOutPath ?? ''; - writeTestHeader(languageOptions, root, sink, indent); - writeTestImports(languageOptions, root, sink, indent); - generateTestDart( - languageOptions, - root, - sink, - indent, - sourceOutPath: sourceOutPath, - testOutPath: testOutPath, + @override + void writeDataClass(DartOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Class klass) { + final List customClassNames = + root.classes.map((Class x) => x.name).toList(); + final List customEnumNames = + root.enums.map((Enum x) => x.name).toList(); + void writeConstructor() { + indent.write(klass.name); + indent.scoped('({', '});', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final String required = field.type.isNullable ? '' : 'required '; + indent.writeln('${required}this.${field.name},'); + } + }); + } + + addDocumentationComments( + indent, klass.documentationComments, _docCommentSpec); + + indent.write('class ${klass.name} '); + indent.scoped('{', '}', () { + writeConstructor(); + indent.addln(''); + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + + final String datatype = _addGenericTypesNullable(field.type); + indent.writeln('$datatype ${field.name};'); + indent.writeln(''); + } + writeEncode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + indent.writeln(''); + writeDecode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + }); + } + + @override + void writeEncode( + DartOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + List customClassNames, + List customEnumNames, + ) { + indent.write('Object encode() '); + indent.scoped('{', '}', () { + indent.write( + 'return ', + ); + indent.scoped('[', '];', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final String conditional = field.type.isNullable ? '?' : ''; + if (customClassNames.contains(field.type.baseName)) { + indent.writeln( + '${field.name}$conditional.encode(),', + ); + } else if (customEnumNames.contains(field.type.baseName)) { + indent.writeln( + '${field.name}$conditional.index,', + ); + } else { + indent.writeln('${field.name},'); + } + } + }); + }); + } + + @override + void writeDecode( + DartOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + List customClassNames, + List customEnumNames, + ) { + void writeValueDecode(NamedType field, int index) { + final String resultAt = 'result[$index]'; + if (customClassNames.contains(field.type.baseName)) { + final String nonNullValue = + '${field.type.baseName}.decode($resultAt! as List)'; + indent.format( + field.type.isNullable + ? ''' +$resultAt != null +\t\t? $nonNullValue +\t\t: null''' + : nonNullValue, + leadingSpace: false, + trailingNewline: false); + } else if (customEnumNames.contains(field.type.baseName)) { + final String nonNullValue = + '${field.type.baseName}.values[$resultAt! as int]'; + indent.format( + field.type.isNullable + ? ''' +$resultAt != null +\t\t? $nonNullValue +\t\t: null''' + : nonNullValue, + leadingSpace: false, + trailingNewline: false); + } else if (field.type.typeArguments.isNotEmpty) { + final String genericType = _makeGenericTypeArguments(field.type); + final String castCall = _makeGenericCastCall(field.type); + final String castCallPrefix = field.type.isNullable ? '?' : '!'; + indent.add( + '($resultAt as $genericType?)$castCallPrefix$castCall', + ); + } else { + final String genericdType = _addGenericTypesNullable(field.type); + if (field.type.isNullable) { + indent.add( + '$resultAt as $genericdType', + ); + } else { + indent.add( + '$resultAt! as $genericdType', + ); + } + } + } + + indent.write( + 'static ${klass.name} decode(Object result) ', ); + indent.scoped('{', '}', () { + indent.writeln('result as List;'); + indent.write('return ${klass.name}'); + indent.scoped('(', ');', () { + enumerate(getFieldsInSerializationOrder(klass), + (int index, final NamedType field) { + indent.write('${field.name}: '); + writeValueDecode(field, index); + indent.addln(','); + }); + }); + }); } } +/// Generates Dart files for testing with specified [DartOptions] +void generateTest(DartOptions languageOptions, Root root, StringSink sink) { + final Indent indent = Indent(sink); + final String sourceOutPath = languageOptions.sourceOutPath ?? ''; + final String testOutPath = languageOptions.testOutPath ?? ''; + writeTestHeader(languageOptions, root, sink, indent); + writeTestImports(languageOptions, root, sink, indent); + generateTestDart( + languageOptions, + root, + sink, + indent, + sourceOutPath: sourceOutPath, + testOutPath: testOutPath, + ); +} + String _escapeForDartSingleQuotedString(String raw) { return raw .replaceAll(r'\', r'\\') @@ -554,133 +711,6 @@ String _addGenericTypesNullable(TypeDeclaration type) { /// Generates Dart source code for the given AST represented by [root], /// outputting the code to [sink]. void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) { - final List customClassNames = - root.classes.map((Class x) => x.name).toList(); - final List customEnumNames = - root.enums.map((Enum x) => x.name).toList(); - - void writeDataClass(Class klass) { - void writeConstructor() { - indent.write(klass.name); - indent.scoped('({', '});', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final String required = field.type.isNullable ? '' : 'required '; - indent.writeln('${required}this.${field.name},'); - } - }); - } - - void writeEncode() { - indent.write('Object encode() '); - indent.scoped('{', '}', () { - indent.write( - 'return ', - ); - indent.scoped('[', '];', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final String conditional = field.type.isNullable ? '?' : ''; - if (customClassNames.contains(field.type.baseName)) { - indent.writeln( - '${field.name}$conditional.encode(),', - ); - } else if (customEnumNames.contains(field.type.baseName)) { - indent.writeln( - '${field.name}$conditional.index,', - ); - } else { - indent.writeln('${field.name},'); - } - } - }); - }); - } - - void writeDecode() { - void writeValueDecode(NamedType field, int index) { - final String resultAt = 'result[$index]'; - if (customClassNames.contains(field.type.baseName)) { - final String nonNullValue = - '${field.type.baseName}.decode($resultAt! as List)'; - indent.format( - field.type.isNullable - ? ''' -$resultAt != null -\t\t? $nonNullValue -\t\t: null''' - : nonNullValue, - leadingSpace: false, - trailingNewline: false); - } else if (customEnumNames.contains(field.type.baseName)) { - final String nonNullValue = - '${field.type.baseName}.values[$resultAt! as int]'; - indent.format( - field.type.isNullable - ? ''' -$resultAt != null -\t\t? $nonNullValue -\t\t: null''' - : nonNullValue, - leadingSpace: false, - trailingNewline: false); - } else if (field.type.typeArguments.isNotEmpty) { - final String genericType = _makeGenericTypeArguments(field.type); - final String castCall = _makeGenericCastCall(field.type); - final String castCallPrefix = field.type.isNullable ? '?' : '!'; - indent.add( - '($resultAt as $genericType?)$castCallPrefix$castCall', - ); - } else { - final String genericdType = _addGenericTypesNullable(field.type); - if (field.type.isNullable) { - indent.add( - '$resultAt as $genericdType', - ); - } else { - indent.add( - '$resultAt! as $genericdType', - ); - } - } - } - - indent.write( - 'static ${klass.name} decode(Object result) ', - ); - indent.scoped('{', '}', () { - indent.writeln('result as List;'); - indent.write('return ${klass.name}'); - indent.scoped('(', ');', () { - enumerate(getFieldsInSerializationOrder(klass), - (int index, final NamedType field) { - indent.write('${field.name}: '); - writeValueDecode(field, index); - indent.addln(','); - }); - }); - }); - } - - addDocumentationComments( - indent, klass.documentationComments, _docCommentSpec); - - indent.write('class ${klass.name} '); - indent.scoped('{', '}', () { - writeConstructor(); - indent.addln(''); - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - - final String datatype = _addGenericTypesNullable(field.type); - indent.writeln('$datatype ${field.name};'); - indent.writeln(''); - } - writeEncode(); - indent.writeln(''); - writeDecode(); - }); - } - void writeApi(Api api) { if (api.location == ApiLocation.host) { _writeHostApi(opt, indent, api, root); @@ -689,10 +719,6 @@ $resultAt != null } } - for (final Class klass in root.classes) { - indent.writeln(''); - writeDataClass(klass); - } for (final Api api in root.apis) { indent.writeln(''); writeApi(api); diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index c7fcd06d51a..d64fd67b92a 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -9,13 +9,15 @@ import 'generator_tools.dart'; /// /// This provides the structure that is common across generators for different languages. abstract class Generator { - /// Generates files for specified language with specified [languageOptions] + /// Generates files for the specified language with specified [languageOptions] /// /// This method, when overridden, should follow a generic structure that is currently: /// 1. Create Indent /// 2. Write File Headers /// 3. Write Imports - /// 4. Generate File + /// 4. Write Enums + /// 5. Write Data Classes + /// 6. Write Apis void generate( T languageOptions, Root root, @@ -41,7 +43,7 @@ abstract class Generator { FileType fileType, ); - /// Writes single Enum to file. + /// Writes a single Enum to file. void writeEnum( T languageOptions, Root root, @@ -50,4 +52,46 @@ abstract class Generator { FileType fileType, Enum anEnum, ); + + /// Writes a single data class to file. + void writeDataClass( + T languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + ); + + /// Writes a single class encode method to file. + void writeEncode( + T languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + List customClassNames, + List customEnumNames, + ); + + /// Writes a single class decode method to file. + void writeDecode( + T languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + List customClassNames, + List customEnumNames, + ); + + // /// Writes a single Flutter Api to file. + // void writeFlutterApi(T languageOptions, Root root, StringSink sink, + // Indent indent, FileType fileType, Api api,); + + // /// Writes a single Host Api to file. + // void writeHostApi(T languageOptions, Root root, StringSink sink, + // Indent indent, FileType fileType, Api api,); } From 6e51c031546c2c05d945b2467e8c68bb87120227 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 3 Jan 2023 23:42:01 -0800 Subject: [PATCH 47/87] remove writeMainClass from java --- packages/pigeon/lib/java_generator.dart | 36 +++++++++++-------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 7a94aa98be7..db64956842e 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -99,7 +99,21 @@ class JavaGenerator extends Generator { writeHeaders(languageOptions, root, sink, indent, fileType); writeImports(languageOptions, root, sink, indent, fileType); - writeMainClass(languageOptions, root, sink, indent, fileType); + indent.writeln( + '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); + indent.writeln( + '@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})'); + if (languageOptions.useGeneratedAnnotation ?? false) { + indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); + } + indent.write('public class ${languageOptions.className!} '); + indent.scoped('{', '}', () { + for (final Enum anEnum in root.enums) { + indent.writeln(''); + writeEnum(languageOptions, root, sink, indent, fileType, anEnum); + } + generateJava(languageOptions, root, sink, indent); + }); } @override @@ -166,26 +180,6 @@ class JavaGenerator extends Generator { }); }); } - - /// Writes main class to sink. wraps enums, apis, and classes. - void writeMainClass(JavaOptions languageOptions, Root root, StringSink sink, - Indent indent, FileType fileType) { - indent.writeln( - '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); - indent.writeln( - '@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})'); - if (languageOptions.useGeneratedAnnotation ?? false) { - indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); - } - indent.write('public class ${languageOptions.className!} '); - indent.scoped('{', '}', () { - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(languageOptions, root, sink, indent, fileType, anEnum); - } - generateJava(languageOptions, root, sink, indent); - }); - } } /// Calculates the name of the codec that will be generated for [api]. From 6041fd7d7a11a4faca112e6fa73860f50166e2a3 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 4 Jan 2023 13:18:53 -0800 Subject: [PATCH 48/87] java + kotlin --- packages/pigeon/lib/dart_generator.dart | 24 +- packages/pigeon/lib/generator.dart | 12 +- packages/pigeon/lib/java_generator.dart | 327 ++++++++++++---------- packages/pigeon/lib/kotlin_generator.dart | 310 ++++++++++---------- 4 files changed, 361 insertions(+), 312 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index f6ec330b7d7..fbc86f54869 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -143,10 +143,10 @@ class DartGenerator extends Generator { @override void writeDataClass(DartOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType, Class klass) { - final List customClassNames = - root.classes.map((Class x) => x.name).toList(); - final List customEnumNames = - root.enums.map((Enum x) => x.name).toList(); + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); void writeConstructor() { indent.write(klass.name); indent.scoped('({', '});', () { @@ -172,24 +172,24 @@ class DartGenerator extends Generator { indent.writeln('$datatype ${field.name};'); indent.writeln(''); } - writeEncode(languageOptions, root, sink, indent, fileType, klass, + writeClassEncode(languageOptions, root, sink, indent, fileType, klass, customClassNames, customEnumNames); indent.writeln(''); - writeDecode(languageOptions, root, sink, indent, fileType, klass, + writeClassDecode(languageOptions, root, sink, indent, fileType, klass, customClassNames, customEnumNames); }); } @override - void writeEncode( + void writeClassEncode( DartOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType, Class klass, - List customClassNames, - List customEnumNames, + Set customClassNames, + Set customEnumNames, ) { indent.write('Object encode() '); indent.scoped('{', '}', () { @@ -216,15 +216,15 @@ class DartGenerator extends Generator { } @override - void writeDecode( + void writeClassDecode( DartOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType, Class klass, - List customClassNames, - List customEnumNames, + Set customClassNames, + Set customEnumNames, ) { void writeValueDecode(NamedType field, int index) { final String resultAt = 'result[$index]'; diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index d64fd67b92a..a44cb934b4f 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -64,27 +64,27 @@ abstract class Generator { ); /// Writes a single class encode method to file. - void writeEncode( + void writeClassEncode( T languageOptions, Root root, StringSink sink, Indent indent, FileType fileType, Class klass, - List customClassNames, - List customEnumNames, + Set customClassNames, + Set customEnumNames, ); /// Writes a single class decode method to file. - void writeDecode( + void writeClassDecode( T languageOptions, Root root, StringSink sink, Indent indent, FileType fileType, Class klass, - List customClassNames, - List customEnumNames, + Set customClassNames, + Set customEnumNames, ); // /// Writes a single Flutter Api to file. diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index db64956842e..eb41ed10899 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -112,6 +112,10 @@ class JavaGenerator extends Generator { indent.writeln(''); writeEnum(languageOptions, root, sink, indent, fileType, anEnum); } + for (final Class klass in root.classes) { + indent.addln(''); + writeDataClass(languageOptions, root, sink, indent, fileType, klass); + } generateJava(languageOptions, root, sink, indent); }); } @@ -180,6 +184,179 @@ class JavaGenerator extends Generator { }); }); } + + @override + void writeDataClass(JavaOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + + const List generatedMessages = [ + ' Generated class from Pigeon that represents data sent in messages.' + ]; + addDocumentationComments( + indent, klass.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); + + indent.write('public static class ${klass.name} '); + indent.scoped('{', '}', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + _writeClassField(languageOptions, root, sink, indent, fileType, field); + indent.addln(''); + } + + if (getFieldsInSerializationOrder(klass) + .map((NamedType e) => !e.type.isNullable) + .any((bool e) => e)) { + indent.writeln( + '${_docCommentPrefix}Constructor is private to enforce null safety; use Builder.$_docCommentSuffix'); + indent.writeln('private ${klass.name}() {}'); + } + + _writeClassBuilder(languageOptions, root, sink, indent, fileType, klass); + writeClassEncode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + writeClassDecode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + }); + } + + void _writeClassField(JavaOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, NamedType field) { + final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, + root.enums, (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); + final String nullability = field.type.isNullable ? '@Nullable' : '@NonNull'; + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + + indent.writeln( + 'private $nullability ${hostDatatype.datatype} ${field.name};'); + indent.writeln( + 'public $nullability ${hostDatatype.datatype} ${_makeGetter(field)}() { return ${field.name}; }'); + indent.writeScoped( + 'public void ${_makeSetter(field)}($nullability ${hostDatatype.datatype} setterArg) {', + '}', () { + if (!field.type.isNullable) { + indent.writeScoped('if (setterArg == null) {', '}', () { + indent.writeln( + 'throw new IllegalStateException("Nonnull field \\"${field.name}\\" is null.");'); + }); + } + indent.writeln('this.${field.name} = setterArg;'); + }); + } + + void _writeClassBuilder( + JavaOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + ) { + indent.write('public static final class Builder '); + indent.scoped('{', '}', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + root.classes, + root.enums, + (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); + final String nullability = + field.type.isNullable ? '@Nullable' : '@NonNull'; + indent.writeln( + 'private @Nullable ${hostDatatype.datatype} ${field.name};'); + indent.writeScoped( + 'public @NonNull Builder ${_makeSetter(field)}($nullability ${hostDatatype.datatype} setterArg) {', + '}', () { + indent.writeln('this.${field.name} = setterArg;'); + indent.writeln('return this;'); + }); + } + indent.write('public @NonNull ${klass.name} build() '); + indent.scoped('{', '}', () { + const String returnVal = 'pigeonReturn'; + indent.writeln('${klass.name} $returnVal = new ${klass.name}();'); + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + indent.writeln('$returnVal.${_makeSetter(field)}(${field.name});'); + } + indent.writeln('return $returnVal;'); + }); + }); + } + + @override + void writeClassEncode( + JavaOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + indent.write('@NonNull ArrayList toList() '); + indent.scoped('{', '}', () { + indent.writeln( + 'ArrayList toListResult = new ArrayList(${klass.fields.length});'); + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + root.classes, + root.enums, + (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); + String toWriteValue = ''; + final String fieldName = field.name; + if (!hostDatatype.isBuiltin && + customClassNames.contains(field.type.baseName)) { + toWriteValue = '($fieldName == null) ? null : $fieldName.toList()'; + } else if (!hostDatatype.isBuiltin && + customEnumNames.contains(field.type.baseName)) { + toWriteValue = '$fieldName == null ? null : $fieldName.index'; + } else { + toWriteValue = field.name; + } + indent.writeln('toListResult.add($toWriteValue);'); + } + indent.writeln('return toListResult;'); + }); + } + + @override + void writeClassDecode( + JavaOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + indent.write( + 'static @NonNull ${klass.name} fromList(@NonNull ArrayList list) '); + indent.scoped('{', '}', () { + const String result = 'pigeonResult'; + indent.writeln('${klass.name} $result = new ${klass.name}();'); + enumerate(getFieldsInSerializationOrder(klass), + (int index, final NamedType field) { + final String fieldVariable = field.name; + final String setter = _makeSetter(field); + indent.writeln('Object $fieldVariable = list.get($index);'); + if (customEnumNames.contains(field.type.baseName)) { + indent.writeln( + '$result.$setter(${_intToEnum(fieldVariable, field.type.baseName)});'); + } else { + indent.writeln( + '$result.$setter(${_castObject(field, root.classes, root.enums, fieldVariable)});'); + } + }); + indent.writeln('return $result;'); + }); + } } /// Calculates the name of the codec that will be generated for [api]. @@ -623,151 +800,6 @@ String _castObject( /// provided [options]. void generateJava( JavaOptions options, Root root, StringSink sink, Indent indent) { - final Set rootClassNameSet = - root.classes.map((Class x) => x.name).toSet(); - final Set rootEnumNameSet = - root.enums.map((Enum x) => x.name).toSet(); - - void writeDataClass(Class klass) { - void writeField(NamedType field) { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - root.classes, - root.enums, - (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); - final String nullability = - field.type.isNullable ? '@Nullable' : '@NonNull'; - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - - indent.writeln( - 'private $nullability ${hostDatatype.datatype} ${field.name};'); - indent.writeln( - 'public $nullability ${hostDatatype.datatype} ${_makeGetter(field)}() { return ${field.name}; }'); - indent.writeScoped( - 'public void ${_makeSetter(field)}($nullability ${hostDatatype.datatype} setterArg) {', - '}', () { - if (!field.type.isNullable) { - indent.writeScoped('if (setterArg == null) {', '}', () { - indent.writeln( - 'throw new IllegalStateException("Nonnull field \\"${field.name}\\" is null.");'); - }); - } - indent.writeln('this.${field.name} = setterArg;'); - }); - } - - void writeToList() { - indent.write('@NonNull ArrayList toList() '); - indent.scoped('{', '}', () { - indent.writeln( - 'ArrayList toListResult = new ArrayList(${klass.fields.length});'); - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - root.classes, - root.enums, - (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); - String toWriteValue = ''; - final String fieldName = field.name; - if (!hostDatatype.isBuiltin && - rootClassNameSet.contains(field.type.baseName)) { - toWriteValue = '($fieldName == null) ? null : $fieldName.toList()'; - } else if (!hostDatatype.isBuiltin && - rootEnumNameSet.contains(field.type.baseName)) { - toWriteValue = '$fieldName == null ? null : $fieldName.index'; - } else { - toWriteValue = field.name; - } - indent.writeln('toListResult.add($toWriteValue);'); - } - indent.writeln('return toListResult;'); - }); - } - - void writeFromList() { - indent.write( - 'static @NonNull ${klass.name} fromList(@NonNull ArrayList list) '); - indent.scoped('{', '}', () { - const String result = 'pigeonResult'; - indent.writeln('${klass.name} $result = new ${klass.name}();'); - enumerate(getFieldsInSerializationOrder(klass), - (int index, final NamedType field) { - final String fieldVariable = field.name; - final String setter = _makeSetter(field); - indent.writeln('Object $fieldVariable = list.get($index);'); - if (rootEnumNameSet.contains(field.type.baseName)) { - indent.writeln( - '$result.$setter(${_intToEnum(fieldVariable, field.type.baseName)});'); - } else { - indent.writeln( - '$result.$setter(${_castObject(field, root.classes, root.enums, fieldVariable)});'); - } - }); - indent.writeln('return $result;'); - }); - } - - void writeBuilder() { - indent.write('public static final class Builder '); - indent.scoped('{', '}', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - root.classes, - root.enums, - (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); - final String nullability = - field.type.isNullable ? '@Nullable' : '@NonNull'; - indent.writeln( - 'private @Nullable ${hostDatatype.datatype} ${field.name};'); - indent.writeScoped( - 'public @NonNull Builder ${_makeSetter(field)}($nullability ${hostDatatype.datatype} setterArg) {', - '}', () { - indent.writeln('this.${field.name} = setterArg;'); - indent.writeln('return this;'); - }); - } - indent.write('public @NonNull ${klass.name} build() '); - indent.scoped('{', '}', () { - const String returnVal = 'pigeonReturn'; - indent.writeln('${klass.name} $returnVal = new ${klass.name}();'); - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - indent.writeln('$returnVal.${_makeSetter(field)}(${field.name});'); - } - indent.writeln('return $returnVal;'); - }); - }); - } - - const List generatedMessages = [ - ' Generated class from Pigeon that represents data sent in messages.' - ]; - addDocumentationComments( - indent, klass.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - - indent.write('public static class ${klass.name} '); - indent.scoped('{', '}', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - writeField(field); - indent.addln(''); - } - - if (getFieldsInSerializationOrder(klass) - .map((NamedType e) => !e.type.isNullable) - .any((bool e) => e)) { - indent.writeln( - '${_docCommentPrefix}Constructor is private to enforce null safety; use Builder.$_docCommentSuffix'); - indent.writeln('private ${klass.name}() {}'); - } - - writeBuilder(); - writeToList(); - writeFromList(); - }); - } - void writeResultInterface() { indent.write('public interface Result '); indent.scoped('{', '}', () { @@ -795,11 +827,6 @@ void generateJava( }'''); } - for (final Class klass in root.classes) { - indent.addln(''); - writeDataClass(klass); - } - if (root.apis.any((Api api) => api.location == ApiLocation.host && api.methods.any((Method it) => it.isAsynchronous))) { diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index f16e46d1e8f..34df75ddda0 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -84,6 +84,10 @@ class KotlinGenerator extends Generator { indent.writeln(''); writeEnum(languageOptions, root, sink, indent, fileType, anEnum); } + for (final Class klass in root.classes) { + indent.addln(''); + writeDataClass(languageOptions, root, sink, indent, fileType, klass); + } generateKotlin(languageOptions, root, sink, indent); } @@ -143,6 +147,168 @@ class KotlinGenerator extends Generator { }); }); } + + @override + void writeDataClass(KotlinOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + void writeField(NamedType field) { + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + indent.write( + 'val ${field.name}: ${_nullsafeKotlinTypeForDartType(field.type)}'); + final String defaultNil = field.type.isNullable ? ' = null' : ''; + indent.add(defaultNil); + } + + const List generatedMessages = [ + ' Generated class from Pigeon that represents data sent in messages.' + ]; + addDocumentationComments( + indent, klass.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); + + indent.write('data class ${klass.name} '); + indent.scoped('(', '', () { + for (final NamedType element in getFieldsInSerializationOrder(klass)) { + writeField(element); + if (getFieldsInSerializationOrder(klass).last != element) { + indent.addln(','); + } else { + indent.addln(''); + } + } + }); + + indent.scoped(') {', '}', () { + writeClassDecode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + writeClassEncode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + }); + } + + @override + void writeClassEncode( + KotlinOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + indent.write('fun toList(): List '); + indent.scoped('{', '}', () { + indent.write('return listOf'); + indent.scoped('(', ')', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final HostDatatype hostDatatype = _getHostDatatype(root, field); + String toWriteValue = ''; + final String fieldName = field.name; + if (!hostDatatype.isBuiltin && + customClassNames.contains(field.type.baseName)) { + toWriteValue = '$fieldName?.toList()'; + } else if (!hostDatatype.isBuiltin && + customEnumNames.contains(field.type.baseName)) { + toWriteValue = '$fieldName?.raw'; + } else { + toWriteValue = fieldName; + } + indent.writeln('$toWriteValue,'); + } + }); + }); + } + + @override + void writeClassDecode( + KotlinOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + final String className = klass.name; + + indent.write('companion object '); + indent.scoped('{', '}', () { + indent.writeln('@Suppress("UNCHECKED_CAST")'); + indent.write('fun fromList(list: List): $className '); + + indent.scoped('{', '}', () { + enumerate(getFieldsInSerializationOrder(klass), + (int index, final NamedType field) { + final HostDatatype hostDatatype = _getHostDatatype(root, field); + + // The StandardMessageCodec can give us [Integer, Long] for + // a Dart 'int'. To keep things simple we just use 64bit + // longs in Pigeon with Kotlin. + final bool isInt = field.type.baseName == 'int'; + + final String listValue = 'list[$index]'; + final String fieldType = _kotlinTypeForDartType(field.type); + + if (field.type.isNullable) { + if (!hostDatatype.isBuiltin && + customClassNames.contains(field.type.baseName)) { + indent.write('val ${field.name}: $fieldType? = '); + indent.add('($listValue as? List)?.let '); + indent.scoped('{', '}', () { + indent.writeln('$fieldType.fromList(it)'); + }); + } else if (!hostDatatype.isBuiltin && + customEnumNames.contains(field.type.baseName)) { + indent.write('val ${field.name}: $fieldType? = '); + indent.add('($listValue as? Int)?.let '); + indent.scoped('{', '}', () { + indent.writeln('$fieldType.ofRaw(it)'); + }); + } else if (isInt) { + indent.write('val ${field.name} = $listValue'); + indent.addln( + '.let { if (it is Int) it.toLong() else it as? Long }'); + } else { + indent.writeln('val ${field.name} = $listValue as? $fieldType'); + } + } else { + if (!hostDatatype.isBuiltin && + customClassNames.contains(field.type.baseName)) { + indent.writeln( + 'val ${field.name} = $fieldType.fromList($listValue as List)'); + } else if (!hostDatatype.isBuiltin && + customEnumNames.contains(field.type.baseName)) { + indent.write( + 'val ${field.name} = $fieldType.ofRaw($listValue as Int)!!'); + } else { + indent.writeln('val ${field.name} = $listValue as $fieldType'); + } + } + }); + + indent.writeln(''); + indent.write('return $className('); + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final String comma = + getFieldsInSerializationOrder(klass).last == field ? '' : ', '; + indent.add('${field.name}$comma'); + } + indent.addln(')'); + }); + }); + } + + HostDatatype _getHostDatatype(Root root, NamedType field) { + return getFieldHostDatatype(field, root.classes, root.enums, + (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); + } } /// Calculates the name of the codec that will be generated for [api]. @@ -519,145 +685,6 @@ String _nullsafeKotlinTypeForDartType(TypeDeclaration type) { /// provided [options]. void generateKotlin( KotlinOptions options, Root root, StringSink sink, Indent indent) { - final Set rootClassNameSet = - root.classes.map((Class x) => x.name).toSet(); - final Set rootEnumNameSet = - root.enums.map((Enum x) => x.name).toSet(); - - HostDatatype getHostDatatype(NamedType field) { - return getFieldHostDatatype(field, root.classes, root.enums, - (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); - } - - void writeDataClass(Class klass) { - void writeField(NamedType field) { - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - indent.write( - 'val ${field.name}: ${_nullsafeKotlinTypeForDartType(field.type)}'); - final String defaultNil = field.type.isNullable ? ' = null' : ''; - indent.add(defaultNil); - } - - void writeToList() { - indent.write('fun toList(): List '); - indent.scoped('{', '}', () { - indent.write('return listOf'); - indent.scoped('(', ')', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getHostDatatype(field); - String toWriteValue = ''; - final String fieldName = field.name; - if (!hostDatatype.isBuiltin && - rootClassNameSet.contains(field.type.baseName)) { - toWriteValue = '$fieldName?.toList()'; - } else if (!hostDatatype.isBuiltin && - rootEnumNameSet.contains(field.type.baseName)) { - toWriteValue = '$fieldName?.raw'; - } else { - toWriteValue = fieldName; - } - indent.writeln('$toWriteValue,'); - } - }); - }); - } - - void writeFromList() { - final String className = klass.name; - - indent.write('companion object '); - indent.scoped('{', '}', () { - indent.writeln('@Suppress("UNCHECKED_CAST")'); - indent.write('fun fromList(list: List): $className '); - - indent.scoped('{', '}', () { - enumerate(getFieldsInSerializationOrder(klass), - (int index, final NamedType field) { - final HostDatatype hostDatatype = getHostDatatype(field); - - // The StandardMessageCodec can give us [Integer, Long] for - // a Dart 'int'. To keep things simple we just use 64bit - // longs in Pigeon with Kotlin. - final bool isInt = field.type.baseName == 'int'; - - final String listValue = 'list[$index]'; - final String fieldType = _kotlinTypeForDartType(field.type); - - if (field.type.isNullable) { - if (!hostDatatype.isBuiltin && - rootClassNameSet.contains(field.type.baseName)) { - indent.write('val ${field.name}: $fieldType? = '); - indent.add('($listValue as? List)?.let '); - indent.scoped('{', '}', () { - indent.writeln('$fieldType.fromList(it)'); - }); - } else if (!hostDatatype.isBuiltin && - rootEnumNameSet.contains(field.type.baseName)) { - indent.write('val ${field.name}: $fieldType? = '); - indent.add('($listValue as? Int)?.let '); - indent.scoped('{', '}', () { - indent.writeln('$fieldType.ofRaw(it)'); - }); - } else if (isInt) { - indent.write('val ${field.name} = $listValue'); - indent.addln( - '.let { if (it is Int) it.toLong() else it as? Long }'); - } else { - indent.writeln('val ${field.name} = $listValue as? $fieldType'); - } - } else { - if (!hostDatatype.isBuiltin && - rootClassNameSet.contains(field.type.baseName)) { - indent.writeln( - 'val ${field.name} = $fieldType.fromList($listValue as List)'); - } else if (!hostDatatype.isBuiltin && - rootEnumNameSet.contains(field.type.baseName)) { - indent.write( - 'val ${field.name} = $fieldType.ofRaw($listValue as Int)!!'); - } else { - indent.writeln('val ${field.name} = $listValue as $fieldType'); - } - } - }); - - indent.writeln(''); - indent.write('return $className('); - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final String comma = - getFieldsInSerializationOrder(klass).last == field ? '' : ', '; - indent.add('${field.name}$comma'); - } - indent.addln(')'); - }); - }); - } - - const List generatedMessages = [ - ' Generated class from Pigeon that represents data sent in messages.' - ]; - addDocumentationComments( - indent, klass.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - - indent.write('data class ${klass.name} '); - indent.scoped('(', '', () { - for (final NamedType element in getFieldsInSerializationOrder(klass)) { - writeField(element); - if (getFieldsInSerializationOrder(klass).last != element) { - indent.addln(','); - } else { - indent.addln(''); - } - } - }); - - indent.scoped(') {', '}', () { - writeFromList(); - writeToList(); - }); - } - void writeApi(Api api) { if (api.location == ApiLocation.host) { _writeHostApi(indent, api, root); @@ -686,11 +713,6 @@ void generateKotlin( }); } - for (final Class klass in root.classes) { - indent.addln(''); - writeDataClass(klass); - } - if (root.apis.any((Api api) => api.location == ApiLocation.host && api.methods.any((Method it) => it.isAsynchronous))) { From b0b55a4ee0b58802ffebca67c2f010e86763ac88 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 4 Jan 2023 13:19:24 -0800 Subject: [PATCH 49/87] remove dead code --- packages/pigeon/lib/swift_generator.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 1df15574fe0..b9c026c2f51 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -495,10 +495,6 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { return '${_swiftTypeForDartType(type)}$nullSafe'; } -/// Writes file header to sink. -void writeImports( - SwiftOptions options, Root root, StringSink sink, Indent indent) {} - /// Generates the ".swift" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateSwift( From 3e2857d208476c1d040ec444447f2db5ba785404 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 4 Jan 2023 13:29:44 -0800 Subject: [PATCH 50/87] swift --- packages/pigeon/lib/kotlin_generator.dart | 19 +- packages/pigeon/lib/swift_generator.dart | 282 ++++++++++++---------- 2 files changed, 163 insertions(+), 138 deletions(-) diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 34df75ddda0..f3710179f7a 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -155,14 +155,6 @@ class KotlinGenerator extends Generator { root.classes.map((Class x) => x.name).toSet(); final Set customEnumNames = root.enums.map((Enum x) => x.name).toSet(); - void writeField(NamedType field) { - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - indent.write( - 'val ${field.name}: ${_nullsafeKotlinTypeForDartType(field.type)}'); - final String defaultNil = field.type.isNullable ? ' = null' : ''; - indent.add(defaultNil); - } const List generatedMessages = [ ' Generated class from Pigeon that represents data sent in messages.' @@ -174,7 +166,7 @@ class KotlinGenerator extends Generator { indent.write('data class ${klass.name} '); indent.scoped('(', '', () { for (final NamedType element in getFieldsInSerializationOrder(klass)) { - writeField(element); + _writeClassField(indent, element); if (getFieldsInSerializationOrder(klass).last != element) { indent.addln(','); } else { @@ -305,6 +297,15 @@ class KotlinGenerator extends Generator { }); } + void _writeClassField(Indent indent, NamedType field) { + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + indent.write( + 'val ${field.name}: ${_nullsafeKotlinTypeForDartType(field.type)}'); + final String defaultNil = field.type.isNullable ? ' = null' : ''; + indent.add(defaultNil); + } + HostDatatype _getHostDatatype(Root root, NamedType field) { return getFieldHostDatatype(field, root.classes, root.enums, (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index b9c026c2f51..bfd7dab1009 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -66,6 +66,10 @@ class SwiftGenerator extends Generator { indent.writeln(''); writeEnum(languageOptions, root, sink, indent, fileType, anEnum); } + for (final Class klass in root.classes) { + indent.addln(''); + writeDataClass(languageOptions, root, sink, indent, fileType, klass); + } generateSwift(languageOptions, root, sink, indent); } @@ -111,6 +115,155 @@ import FlutterMacOS }); }); } + + @override + void writeDataClass(SwiftOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + + const List generatedComments = [ + ' Generated class from Pigeon that represents data sent in messages.' + ]; + addDocumentationComments( + indent, klass.documentationComments, _docCommentSpec, + generatorComments: generatedComments); + + indent.write('struct ${klass.name} '); + indent.scoped('{', '}', () { + getFieldsInSerializationOrder(klass).forEach((NamedType field) { + _writeClassField(indent, field); + }); + + indent.writeln(''); + writeClassDecode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + writeClassEncode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + }); + } + + void _writeClassField(Indent indent, NamedType field) { + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + + indent.write( + 'var ${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}'); + final String defaultNil = field.type.isNullable ? ' = nil' : ''; + indent.addln(defaultNil); + } + + @override + void writeClassEncode( + SwiftOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + indent.write('func toList() -> [Any?] '); + indent.scoped('{', '}', () { + indent.write('return '); + indent.scoped('[', ']', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final HostDatatype hostDatatype = _getHostDatatype(root, field); + String toWriteValue = ''; + final String fieldName = field.name; + final String nullsafe = field.type.isNullable ? '?' : ''; + if (!hostDatatype.isBuiltin && + customClassNames.contains(field.type.baseName)) { + toWriteValue = '$fieldName$nullsafe.toList()'; + } else if (!hostDatatype.isBuiltin && + customEnumNames.contains(field.type.baseName)) { + toWriteValue = '$fieldName$nullsafe.rawValue'; + } else { + toWriteValue = field.name; + } + + indent.writeln('$toWriteValue,'); + } + }); + }); + } + + @override + void writeClassDecode( + SwiftOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + final String className = klass.name; + indent.write('static func fromList(_ list: [Any?]) -> $className? '); + + indent.scoped('{', '}', () { + enumerate(getFieldsInSerializationOrder(klass), + (int index, final NamedType field) { + final HostDatatype hostDatatype = _getHostDatatype(root, field); + + final String listValue = 'list[$index]'; + final String fieldType = _swiftTypeForDartType(field.type); + + if (field.type.isNullable) { + if (!hostDatatype.isBuiltin && + customClassNames.contains(field.type.baseName)) { + indent.writeln('var ${field.name}: $fieldType? = nil'); + indent.write('if let ${field.name}List = $listValue as? [Any?] '); + indent.scoped('{', '}', () { + indent.writeln( + '${field.name} = $fieldType.fromList(${field.name}List)'); + }); + } else if (!hostDatatype.isBuiltin && + customEnumNames.contains(field.type.baseName)) { + indent.writeln('var ${field.name}: $fieldType? = nil'); + indent.write('if let ${field.name}RawValue = $listValue as? Int '); + indent.scoped('{', '}', () { + indent.writeln( + '${field.name} = $fieldType(rawValue: ${field.name}RawValue)'); + }); + } else { + indent.writeln('let ${field.name} = $listValue as? $fieldType '); + } + } else { + if (!hostDatatype.isBuiltin && + customClassNames.contains(field.type.baseName)) { + indent.writeln( + 'let ${field.name} = $fieldType.fromList($listValue as! [Any?])!'); + } else if (!hostDatatype.isBuiltin && + customEnumNames.contains(field.type.baseName)) { + indent.writeln( + 'let ${field.name} = $fieldType(rawValue: $listValue as! Int)!'); + } else { + indent.writeln('let ${field.name} = $listValue as! $fieldType'); + } + } + }); + + indent.writeln(''); + indent.write('return '); + indent.scoped('$className(', ')', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final String comma = + getFieldsInSerializationOrder(klass).last == field ? '' : ','; + indent.writeln('${field.name}: ${field.name}$comma'); + } + }); + }); + } + + HostDatatype _getHostDatatype(Root root, NamedType field) { + return getFieldHostDatatype(field, root.classes, root.enums, + (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); + } } /// Calculates the name of the codec that will be generated for [api]. @@ -499,130 +652,6 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { /// provided [options]. void generateSwift( SwiftOptions options, Root root, StringSink sink, Indent indent) { - final Set rootClassNameSet = - root.classes.map((Class x) => x.name).toSet(); - final Set rootEnumNameSet = - root.enums.map((Enum x) => x.name).toSet(); - - HostDatatype getHostDatatype(NamedType field) { - return getFieldHostDatatype(field, root.classes, root.enums, - (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); - } - - void writeDataClass(Class klass) { - void writeField(NamedType field) { - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - - indent.write( - 'var ${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}'); - final String defaultNil = field.type.isNullable ? ' = nil' : ''; - indent.addln(defaultNil); - } - - void writeToList() { - indent.write('func toList() -> [Any?] '); - indent.scoped('{', '}', () { - indent.write('return '); - indent.scoped('[', ']', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getHostDatatype(field); - String toWriteValue = ''; - final String fieldName = field.name; - final String nullsafe = field.type.isNullable ? '?' : ''; - if (!hostDatatype.isBuiltin && - rootClassNameSet.contains(field.type.baseName)) { - toWriteValue = '$fieldName$nullsafe.toList()'; - } else if (!hostDatatype.isBuiltin && - rootEnumNameSet.contains(field.type.baseName)) { - toWriteValue = '$fieldName$nullsafe.rawValue'; - } else { - toWriteValue = field.name; - } - - indent.writeln('$toWriteValue,'); - } - }); - }); - } - - void writeFromList() { - final String className = klass.name; - indent.write('static func fromList(_ list: [Any?]) -> $className? '); - - indent.scoped('{', '}', () { - enumerate(getFieldsInSerializationOrder(klass), - (int index, final NamedType field) { - final HostDatatype hostDatatype = getHostDatatype(field); - - final String listValue = 'list[$index]'; - final String fieldType = _swiftTypeForDartType(field.type); - - if (field.type.isNullable) { - if (!hostDatatype.isBuiltin && - rootClassNameSet.contains(field.type.baseName)) { - indent.writeln('var ${field.name}: $fieldType? = nil'); - indent.write('if let ${field.name}List = $listValue as? [Any?] '); - indent.scoped('{', '}', () { - indent.writeln( - '${field.name} = $fieldType.fromList(${field.name}List)'); - }); - } else if (!hostDatatype.isBuiltin && - rootEnumNameSet.contains(field.type.baseName)) { - indent.writeln('var ${field.name}: $fieldType? = nil'); - indent - .write('if let ${field.name}RawValue = $listValue as? Int '); - indent.scoped('{', '}', () { - indent.writeln( - '${field.name} = $fieldType(rawValue: ${field.name}RawValue)'); - }); - } else { - indent.writeln('let ${field.name} = $listValue as? $fieldType '); - } - } else { - if (!hostDatatype.isBuiltin && - rootClassNameSet.contains(field.type.baseName)) { - indent.writeln( - 'let ${field.name} = $fieldType.fromList($listValue as! [Any?])!'); - } else if (!hostDatatype.isBuiltin && - rootEnumNameSet.contains(field.type.baseName)) { - indent.writeln( - 'let ${field.name} = $fieldType(rawValue: $listValue as! Int)!'); - } else { - indent.writeln('let ${field.name} = $listValue as! $fieldType'); - } - } - }); - - indent.writeln(''); - indent.write('return '); - indent.scoped('$className(', ')', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final String comma = - getFieldsInSerializationOrder(klass).last == field ? '' : ','; - indent.writeln('${field.name}: ${field.name}$comma'); - } - }); - }); - } - - const List generatedComments = [ - ' Generated class from Pigeon that represents data sent in messages.' - ]; - addDocumentationComments( - indent, klass.documentationComments, _docCommentSpec, - generatorComments: generatedComments); - - indent.write('struct ${klass.name} '); - indent.scoped('{', '}', () { - getFieldsInSerializationOrder(klass).forEach(writeField); - - indent.writeln(''); - writeFromList(); - writeToList(); - }); - } - void writeApi(Api api, Root root) { if (api.location == ApiLocation.host) { _writeHostApi(indent, api, root); @@ -650,11 +679,6 @@ void generateSwift( }); } - for (final Class klass in root.classes) { - indent.addln(''); - writeDataClass(klass); - } - if (root.apis.any((Api api) => api.location == ApiLocation.host && api.methods.any((Method it) => it.isAsynchronous))) { From 3b51c03e01926e6ee8ea7c5da3454adc6e75a0f7 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 4 Jan 2023 13:31:10 -0800 Subject: [PATCH 51/87] fix dart test error --- packages/pigeon/lib/dart_generator.dart | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index fbc86f54869..a5a2b1cdffa 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -289,23 +289,23 @@ $resultAt != null }); }); } -} -/// Generates Dart files for testing with specified [DartOptions] -void generateTest(DartOptions languageOptions, Root root, StringSink sink) { - final Indent indent = Indent(sink); - final String sourceOutPath = languageOptions.sourceOutPath ?? ''; - final String testOutPath = languageOptions.testOutPath ?? ''; - writeTestHeader(languageOptions, root, sink, indent); - writeTestImports(languageOptions, root, sink, indent); - generateTestDart( - languageOptions, - root, - sink, - indent, - sourceOutPath: sourceOutPath, - testOutPath: testOutPath, - ); + /// Generates Dart files for testing with specified [DartOptions] + void generateTest(DartOptions languageOptions, Root root, StringSink sink) { + final Indent indent = Indent(sink); + final String sourceOutPath = languageOptions.sourceOutPath ?? ''; + final String testOutPath = languageOptions.testOutPath ?? ''; + writeTestHeader(languageOptions, root, sink, indent); + writeTestImports(languageOptions, root, sink, indent); + generateTestDart( + languageOptions, + root, + sink, + indent, + sourceOutPath: sourceOutPath, + testOutPath: testOutPath, + ); + } } String _escapeForDartSingleQuotedString(String raw) { From f0503dc023720bf3c46e43da99faf330d5ed070d Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 4 Jan 2023 14:43:13 -0800 Subject: [PATCH 52/87] cpp + objc --- packages/pigeon/lib/cpp_generator.dart | 88 ++++-- packages/pigeon/lib/objc_generator.dart | 355 +++++++++++++++--------- 2 files changed, 277 insertions(+), 166 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index da3ba128307..05f7c25306c 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -88,7 +88,12 @@ class CppGenerator extends Generator { } indent.addln(''); - + if (fileType == FileType.header) { + _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); + } + for (final Class klass in root.classes) { + writeDataClass(languageOptions, root, sink, indent, fileType, klass); + } if (fileType == FileType.header) { generateCppHeader(languageOptions, root, sink, indent); } else { @@ -123,6 +128,53 @@ class CppGenerator extends Generator { writeCppHeaderEnum(languageOptions, root, sink, indent, anEnum); } } + + @override + void writeDataClass(CppOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Class klass) { + if (fileType == FileType.header) { + // When generating for a Pigeon unit test, add a test fixture friend class to + // allow unit testing private methods, since testing serialization via public + // methods is essentially an end-to-end test. + String? testFixtureClass; + if (languageOptions.namespace?.endsWith('_pigeontest') ?? false) { + testFixtureClass = + '${_pascalCaseFromSnakeCase(languageOptions.namespace!.replaceAll('_pigeontest', ''))}Test'; + } + _writeCppHeaderDataClass(languageOptions, root, sink, indent, klass, + testFriend: testFixtureClass); + } else { + _writeCppSourceDataClass(languageOptions, root, sink, indent, klass); + } + } + + @override + void writeClassEncode( + CppOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + // Left blank until functions fully converted to methods. + } + + @override + void writeClassDecode( + CppOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + // Left blank until functions fully converted to methods. + } } String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; @@ -251,9 +303,10 @@ $friendLines /// Writes the declaration for the custom class [klass]. /// -/// See [_writeDataClassImplementation] for the corresponding declaration. +/// See [_writeCppSourceDataClass] for the corresponding declaration. /// This is intended to be added to the header. -void _writeDataClassDeclaration(Indent indent, Class klass, Root root, +void _writeCppHeaderDataClass(CppOptions languageOptions, Root root, + StringSink sink, Indent indent, Class klass, {String? testFriend}) { indent.addln(''); @@ -328,9 +381,10 @@ void _writeDataClassDeclaration(Indent indent, Class klass, Root root, /// Writes the implementation for the custom class [klass]. /// -/// See [_writeDataClassDeclaration] for the corresponding declaration. +/// See [_writeCppHeaderDataClass] for the corresponding declaration. /// This is intended to be added to the implementation file. -void _writeDataClassImplementation(Indent indent, Class klass, Root root) { +void _writeCppSourceDataClass(CppOptions languageOptions, Root root, + StringSink sink, Indent indent, Class klass) { final Set rootClassNameSet = root.classes.map((Class x) => x.name).toSet(); final Set rootEnumNameSet = @@ -369,7 +423,7 @@ void _writeDataClassImplementation(Indent indent, Class klass, Root root) { '{ return $returnExpression; }'); indent.writeln(makeSetter(hostDatatype)); if (hostDatatype.isNullable) { - // Write the non-nullable variant; see _writeDataClassDeclaration. + // Write the non-nullable variant; see _writeCppHeaderDataClass. final HostDatatype nonNullType = _nonNullableType(hostDatatype); indent.writeln(makeSetter(nonNullType)); } @@ -1136,24 +1190,6 @@ void writeCppHeaderEnum(CppOptions options, Root root, StringSink sink, /// provided [options] and [headerFileName]. void generateCppHeader( CppOptions options, Root root, StringSink sink, Indent indent) { - // When generating for a Pigeon unit test, add a test fixture friend class to - // allow unit testing private methods, since testing serialization via public - // methods is essentially an end-to-end test. - String? testFixtureClass; - if (options.namespace?.endsWith('_pigeontest') ?? false) { - testFixtureClass = - '${_pascalCaseFromSnakeCase(options.namespace!.replaceAll('_pigeontest', ''))}Test'; - } - - _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); - - for (final Class klass in root.classes) { - _writeDataClassDeclaration(indent, klass, root, - // Add a hook for unit testing data classes when using the namespace - // used by pigeon tests. - testFriend: testFixtureClass); - } - for (final Api api in root.apis) { if (getCodecClasses(api, root).isNotEmpty) { _writeCodecHeader(indent, api, root); @@ -1215,10 +1251,6 @@ void writeCppSourceImports( /// provided [options]. void generateCppSource( CppOptions options, Root root, StringSink sink, Indent indent) { - for (final Class klass in root.classes) { - _writeDataClassImplementation(indent, klass, root); - } - for (final Api api in root.apis) { if (getCodecClasses(api, root).isNotEmpty) { _writeCodecSource(indent, api, root); diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index bd229cf1fa1..1d2421f51af 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -85,6 +85,25 @@ class ObjcGenerator extends Generator { writeEnum(languageOptions, root, sink, indent, fileType, anEnum); } indent.writeln(''); + for (final Class klass in root.classes) { + indent.writeln( + '@class ${_className(languageOptions.prefix, klass.name)};'); + } + } else if (fileType == FileType.source) { + _writeObjcSourceHelperFunctions(indent); + indent.addln(''); + + for (final Class klass in root.classes) { + _writeObjcSourceDataClassExtension(languageOptions, indent, klass); + } + indent.writeln(''); + } + + for (final Class klass in root.classes) { + writeDataClass(languageOptions, root, sink, indent, fileType, klass); + } + + if (fileType == FileType.header) { generateObjcHeader(languageOptions, root, sink, indent); } else { generateObjcSource(languageOptions, root, sink, indent); @@ -118,6 +137,46 @@ class ObjcGenerator extends Generator { writeObjcHeaderEnum(languageOptions, root, sink, indent, anEnum); } } + + @override + void writeDataClass(ObjcOptions languageOptions, Root root, StringSink sink, + Indent indent, FileType fileType, Class klass) { + if (fileType == FileType.header) { + _writeObjcHeaderDataClass(languageOptions, root, sink, indent, klass); + } else { + _writeObjcSourceDataClassImplementation( + languageOptions, root, sink, indent, klass); + indent.writeln(''); + } + } + + @override + void writeClassEncode( + ObjcOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + // Left blank until functions fully converted to methods. + } + + @override + void writeClassDecode( + ObjcOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + FileType fileType, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + // Left blank until functions fully converted to methods. + } } /// Calculates the ObjC class name, possibly prefixed. @@ -221,7 +280,7 @@ bool _isNullable(HostDatatype hostDatatype, TypeDeclaration type) => /// Example '+ (instancetype)makeWithFoo:(NSString *)foo' void _writeInitializerDeclaration(Indent indent, Class klass, List classes, List enums, String? prefix) { - final List enumNames = enums.map((Enum x) => x.name).toList(); + final List customEnumNames = enums.map((Enum x) => x.name).toList(); indent.write('+ (instancetype)makeWith'); bool isFirst = true; indent.nest(2, () { @@ -239,7 +298,7 @@ void _writeInitializerDeclaration(Indent indent, Class klass, classes, enums, (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), - customResolver: enumNames.contains(field.type.baseName) + customResolver: customEnumNames.contains(field.type.baseName) ? (String x) => _className(prefix, x) : (String x) => '${_className(prefix, x)} *'); final String nullable = @@ -255,50 +314,52 @@ void _writeInitializerDeclaration(Indent indent, Class klass, /// @interface Foo : NSObject /// @property (nonatomic, copy) NSString *bar; /// @end -void _writeClassDeclarations( - Indent indent, List classes, List enums, String? prefix) { - final List enumNames = enums.map((Enum x) => x.name).toList(); - for (final Class klass in classes) { - addDocumentationComments( - indent, klass.documentationComments, _docCommentSpec); +void _writeObjcHeaderDataClass(ObjcOptions languageOptions, Root root, + StringSink sink, Indent indent, Class klass) { + final List classes = root.classes; + final List enums = root.enums; + final String? prefix = languageOptions.prefix; + final List customEnumNames = enums.map((Enum x) => x.name).toList(); - indent.writeln('@interface ${_className(prefix, klass.name)} : NSObject'); - if (getFieldsInSerializationOrder(klass).isNotEmpty) { - if (getFieldsInSerializationOrder(klass) - .map((NamedType e) => !e.type.isNullable) - .any((bool e) => e)) { - indent.writeln( - '$_docCommentPrefix `init` unavailable to enforce nonnull fields, see the `make` class method.'); - indent.writeln('- (instancetype)init NS_UNAVAILABLE;'); - } - _writeInitializerDeclaration(indent, klass, classes, enums, prefix); - indent.addln(';'); - } - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - classes, - enums, - (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), - customResolver: enumNames.contains(field.type.baseName) - ? (String x) => _className(prefix, x) - : (String x) => '${_className(prefix, x)} *'); - late final String propertyType; - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - if (enumNames.contains(field.type.baseName)) { - propertyType = 'assign'; - } else { - propertyType = _propertyTypeForDartType(field); - } - final String nullability = - _isNullable(hostDatatype, field.type) ? ', nullable' : ''; + addDocumentationComments( + indent, klass.documentationComments, _docCommentSpec); + + indent.writeln('@interface ${_className(prefix, klass.name)} : NSObject'); + if (getFieldsInSerializationOrder(klass).isNotEmpty) { + if (getFieldsInSerializationOrder(klass) + .map((NamedType e) => !e.type.isNullable) + .any((bool e) => e)) { indent.writeln( - '@property(nonatomic, $propertyType$nullability) ${hostDatatype.datatype} ${field.name};'); + '$_docCommentPrefix `init` unavailable to enforce nonnull fields, see the `make` class method.'); + indent.writeln('- (instancetype)init NS_UNAVAILABLE;'); } - indent.writeln('@end'); - indent.writeln(''); + _writeInitializerDeclaration(indent, klass, classes, enums, prefix); + indent.addln(';'); } + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + classes, + enums, + (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), + customResolver: customEnumNames.contains(field.type.baseName) + ? (String x) => _className(prefix, x) + : (String x) => '${_className(prefix, x)} *'); + late final String propertyType; + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + if (customEnumNames.contains(field.type.baseName)) { + propertyType = 'assign'; + } else { + propertyType = _propertyTypeForDartType(field); + } + final String nullability = + _isNullable(hostDatatype, field.type) ? ', nullable' : ''; + indent.writeln( + '@property(nonatomic, $propertyType$nullability) ${hostDatatype.datatype} ${field.name};'); + } + indent.writeln('@end'); + indent.writeln(''); } /// Generates the name of the codec that will be generated. @@ -634,14 +695,8 @@ void writeObjcHeaderEnum(ObjcOptions options, Root root, StringSink sink, /// provided [options]. void generateObjcHeader( ObjcOptions options, Root root, StringSink sink, Indent indent) { - for (final Class klass in root.classes) { - indent.writeln('@class ${_className(options.prefix, klass.name)};'); - } - indent.writeln(''); - _writeClassDeclarations(indent, root.classes, root.enums, options.prefix); - for (final Api api in root.apis) { indent.writeln( '$_docCommentPrefix The codec used by ${_className(options.prefix, api.name)}.'); @@ -658,9 +713,9 @@ void generateObjcHeader( indent.writeln('NS_ASSUME_NONNULL_END'); } -String _listGetter(List classNames, String list, NamedType field, +String _listGetter(Set customClassNames, String list, NamedType field, int index, String? prefix) { - if (classNames.contains(field.type.baseName)) { + if (customClassNames.contains(field.type.baseName)) { String className = field.type.baseName; if (prefix != null) { className = '$prefix$className'; @@ -671,11 +726,11 @@ String _listGetter(List classNames, String list, NamedType field, } } -String _arrayValue( - List classNames, List enumNames, NamedType field) { - if (classNames.contains(field.type.baseName)) { +String _arrayValue(Set customClassNames, Set customEnumNames, + NamedType field) { + if (customClassNames.contains(field.type.baseName)) { return '(self.${field.name} ? [self.${field.name} toList] : [NSNull null])'; - } else if (enumNames.contains(field.type.baseName)) { + } else if (customEnumNames.contains(field.type.baseName)) { return '@(self.${field.name})'; } else { return '(self.${field.name} ?: [NSNull null])'; @@ -947,23 +1002,15 @@ void writeObjcSourceImports( indent.addln(''); } -/// Generates the ".m" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateObjcSource( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - final List classNames = - root.classes.map((Class x) => x.name).toList(); - final List enumNames = root.enums.map((Enum x) => x.name).toList(); - - void writeHelperFunctions() { - indent.format(''' +void _writeObjcSourceHelperFunctions(Indent indent) { + indent.format(''' static NSArray *wrapResult(id result, FlutterError *error) { \tif (error) { \t\treturn @[ error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] ]; \t} \treturn @[ result ?: [NSNull null] ]; }'''); - indent.format(''' + indent.format(''' static id GetNullableObject(NSDictionary* dict, id key) { \tid result = dict[key]; \treturn (result == [NSNull null]) ? nil : result; @@ -973,78 +1020,118 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { \treturn (result == [NSNull null]) ? nil : result; } '''); - } - - void writeDataClassExtension(Class klass) { - final String className = _className(options.prefix, klass.name); - indent.writeln('@interface $className ()'); - indent.writeln('+ ($className *)fromList:(NSArray *)list;'); - indent - .writeln('+ (nullable $className *)nullableFromList:(NSArray *)list;'); - indent.writeln('- (NSArray *)toList;'); - indent.writeln('@end'); - } +} - void writeDataClassImplementation(Class klass) { - final String className = _className(options.prefix, klass.name); - void writeInitializer() { - _writeInitializerDeclaration( - indent, klass, root.classes, root.enums, options.prefix); - indent.writeScoped(' {', '}', () { - const String result = 'pigeonResult'; - indent.writeln('$className* $result = [[$className alloc] init];'); - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - indent.writeln('$result.${field.name} = ${field.name};'); - } - indent.writeln('return $result;'); - }); - } +void _writeObjcSourceDataClassExtension( + ObjcOptions languageOptions, Indent indent, Class klass) { + final String className = _className(languageOptions.prefix, klass.name); + indent.writeln('@interface $className ()'); + indent.writeln('+ ($className *)fromList:(NSArray *)list;'); + indent.writeln('+ (nullable $className *)nullableFromList:(NSArray *)list;'); + indent.writeln('- (NSArray *)toList;'); + indent.writeln('@end'); +} - void writeFromList() { - indent.write('+ ($className *)fromList:(NSArray *)list '); - indent.scoped('{', '}', () { - const String resultName = 'pigeonResult'; - indent.writeln('$className *$resultName = [[$className alloc] init];'); - enumerate(getFieldsInSerializationOrder(klass), - (int index, final NamedType field) { - if (enumNames.contains(field.type.baseName)) { - indent.writeln( - '$resultName.${field.name} = [${_listGetter(classNames, 'list', field, index, options.prefix)} integerValue];'); - } else { - indent.writeln( - '$resultName.${field.name} = ${_listGetter(classNames, 'list', field, index, options.prefix)};'); - if (!field.type.isNullable) { - indent - .writeln('NSAssert($resultName.${field.name} != nil, @"");'); - } - } - }); - indent.writeln('return $resultName;'); - }); +void _writeObjcSourceDataClassImplementation(ObjcOptions options, Root root, + StringSink sink, Indent indent, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + final String className = _className(options.prefix, klass.name); + + indent.writeln('@implementation $className'); + _writeInitializer(options, root, sink, indent, klass, customClassNames, + customEnumNames, className); + _writeClassDecode(options, root, sink, indent, klass, customClassNames, + customEnumNames, className); + _writeClassEncode(options, root, sink, indent, klass, customClassNames, + customEnumNames, className); + indent.writeln('@end'); +} - indent.writeln( - '+ (nullable $className *)nullableFromList:(NSArray *)list { return (list) ? [$className fromList:list] : nil; }'); +void _writeInitializer( + ObjcOptions options, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + String className, +) { + _writeInitializerDeclaration( + indent, klass, root.classes, root.enums, options.prefix); + indent.writeScoped(' {', '}', () { + const String result = 'pigeonResult'; + indent.writeln('$className* $result = [[$className alloc] init];'); + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + indent.writeln('$result.${field.name} = ${field.name};'); } + indent.writeln('return $result;'); + }); +} - void writeToList() { - indent.write('- (NSArray *)toList '); - indent.scoped('{', '}', () { - indent.write('return'); - indent.scoped(' @[', '];', () { - for (final NamedType field in klass.fields) { - indent.writeln('${_arrayValue(classNames, enumNames, field)},'); - } - }); - }); - } +void _writeClassDecode( + ObjcOptions options, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + String className, +) { + indent.write('+ ($className *)fromList:(NSArray *)list '); + indent.scoped('{', '}', () { + const String resultName = 'pigeonResult'; + indent.writeln('$className *$resultName = [[$className alloc] init];'); + enumerate(getFieldsInSerializationOrder(klass), + (int index, final NamedType field) { + if (customEnumNames.contains(field.type.baseName)) { + indent.writeln( + '$resultName.${field.name} = [${_listGetter(customClassNames, 'list', field, index, options.prefix)} integerValue];'); + } else { + indent.writeln( + '$resultName.${field.name} = ${_listGetter(customClassNames, 'list', field, index, options.prefix)};'); + if (!field.type.isNullable) { + indent.writeln('NSAssert($resultName.${field.name} != nil, @"");'); + } + } + }); + indent.writeln('return $resultName;'); + }); - indent.writeln('@implementation $className'); - writeInitializer(); - writeFromList(); - writeToList(); - indent.writeln('@end'); - } + indent.writeln( + '+ (nullable $className *)nullableFromList:(NSArray *)list { return (list) ? [$className fromList:list] : nil; }'); +} +void _writeClassEncode( + ObjcOptions options, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + String className, +) { + indent.write('- (NSArray *)toList '); + indent.scoped('{', '}', () { + indent.write('return'); + indent.scoped(' @[', '];', () { + for (final NamedType field in klass.fields) { + indent.writeln( + '${_arrayValue(customClassNames, customEnumNames, field)},'); + } + }); + }); +} + +/// Generates the ".m" file for the AST represented by [root] to [sink] with the +/// provided [options]. +void generateObjcSource( + ObjcOptions options, Root root, StringSink sink, Indent indent) { void writeApi(Api api) { final String codecName = _getCodecName(options.prefix, api.name); if (getCodecClasses(api, root).isNotEmpty) { @@ -1060,14 +1147,6 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { } } - writeHelperFunctions(); - indent.addln(''); - root.classes.forEach(writeDataClassExtension); - indent.writeln(''); - for (final Class klass in root.classes) { - writeDataClassImplementation(klass); - indent.writeln(''); - } root.apis.forEach(writeApi); } From f5cd262b3d7f536c90532bdc2cd70204b9d14923 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 4 Jan 2023 15:42:40 -0800 Subject: [PATCH 53/87] objc + cpp --- packages/pigeon/lib/cpp_generator.dart | 158 ++++++++++++++---------- packages/pigeon/lib/objc_generator.dart | 15 ++- 2 files changed, 108 insertions(+), 65 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 05f7c25306c..cb1fd35dc74 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -159,7 +159,8 @@ class CppGenerator extends Generator { Set customClassNames, Set customEnumNames, ) { - // Left blank until functions fully converted to methods. + _writeCppSourceClassEncode(languageOptions, root, sink, indent, klass, + customClassNames, customEnumNames); } @override @@ -173,7 +174,8 @@ class CppGenerator extends Generator { Set customClassNames, Set customEnumNames, ) { - // Left blank until functions fully converted to methods. + _writeCppSourceClassDecode(languageOptions, root, sink, indent, klass, + customClassNames, customEnumNames); } } @@ -379,59 +381,15 @@ void _writeCppHeaderDataClass(CppOptions languageOptions, Root root, indent.writeln(''); } -/// Writes the implementation for the custom class [klass]. -/// -/// See [_writeCppHeaderDataClass] for the corresponding declaration. -/// This is intended to be added to the implementation file. -void _writeCppSourceDataClass(CppOptions languageOptions, Root root, - StringSink sink, Indent indent, Class klass) { - final Set rootClassNameSet = - root.classes.map((Class x) => x.name).toSet(); - final Set rootEnumNameSet = - root.enums.map((Enum x) => x.name).toSet(); - - indent.addln(''); - indent.writeln('$_commentPrefix ${klass.name}'); - indent.addln(''); - - // Getters and setters. - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, - root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - final String instanceVariableName = _makeInstanceVariableName(field); - final String qualifiedGetterName = - '${klass.name}::${_makeGetterName(field)}'; - final String qualifiedSetterName = - '${klass.name}::${_makeSetterName(field)}'; - final String returnExpression = hostDatatype.isNullable - ? '$instanceVariableName ? &(*$instanceVariableName) : nullptr' - : instanceVariableName; - - // Generates the string for a setter treating the type as [type], to allow - // generating multiple setter variants. - String makeSetter(HostDatatype type) { - const String setterArgumentName = 'value_arg'; - final String valueExpression = type.isNullable - ? '$setterArgumentName ? ${_valueType(type)}(*$setterArgumentName) : std::nullopt' - : setterArgumentName; - return 'void $qualifiedSetterName(${_unownedArgumentType(type)} $setterArgumentName) ' - '{ $instanceVariableName = $valueExpression; }'; - } - - indent.writeln( - '${_getterReturnType(hostDatatype)} $qualifiedGetterName() const ' - '{ return $returnExpression; }'); - indent.writeln(makeSetter(hostDatatype)); - if (hostDatatype.isNullable) { - // Write the non-nullable variant; see _writeCppHeaderDataClass. - final HostDatatype nonNullType = _nonNullableType(hostDatatype); - indent.writeln(makeSetter(nonNullType)); - } - - indent.addln(''); - } - - // Serialization. +void _writeCppSourceClassEncode( + CppOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, +) { indent .write('flutter::EncodableList ${klass.name}::ToEncodableList() const '); indent.scoped('{', '}', () { @@ -447,12 +405,12 @@ void _writeCppSourceDataClass(CppOptions languageOptions, Root root, String encodableValue = ''; if (!hostDatatype.isBuiltin && - rootClassNameSet.contains(field.type.baseName)) { + customClassNames.contains(field.type.baseName)) { final String operator = field.type.isNullable ? '->' : '.'; encodableValue = 'flutter::EncodableValue($instanceVariable${operator}ToEncodableList())'; } else if (!hostDatatype.isBuiltin && - rootEnumNameSet.contains(field.type.baseName)) { + customEnumNames.contains(field.type.baseName)) { final String nonNullValue = field.type.isNullable ? '(*$instanceVariable)' : instanceVariable; encodableValue = 'flutter::EncodableValue((int)$nonNullValue)'; @@ -472,12 +430,17 @@ void _writeCppSourceDataClass(CppOptions languageOptions, Root root, }); }); indent.addln(''); +} - // Default constructor. - indent.writeln('${klass.name}::${klass.name}() {}'); - indent.addln(''); - - // Deserialization. +void _writeCppSourceClassDecode( + CppOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, +) { indent.write( '${klass.name}::${klass.name}(const flutter::EncodableList& list) '); indent.scoped('{', '}', () { @@ -489,7 +452,7 @@ void _writeCppSourceDataClass(CppOptions languageOptions, Root root, final String encodableFieldName = '${_encodablePrefix}_${_makeVariableName(field)}'; indent.writeln('auto& $encodableFieldName = list[$index];'); - if (rootEnumNameSet.contains(field.type.baseName)) { + if (customEnumNames.contains(field.type.baseName)) { indent.writeln( 'if (const int32_t* $pointerFieldName = std::get_if(&$encodableFieldName))\t$instanceVariableName = (${field.type.baseName})*$pointerFieldName;'); } else { @@ -527,6 +490,75 @@ else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodabl indent.addln(''); } +void _writeCppSourceClassField(CppOptions languageOptions, Root root, + StringSink sink, Indent indent, Class klass, NamedType field) { + final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, + root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + final String instanceVariableName = _makeInstanceVariableName(field); + final String qualifiedGetterName = '${klass.name}::${_makeGetterName(field)}'; + final String qualifiedSetterName = '${klass.name}::${_makeSetterName(field)}'; + final String returnExpression = hostDatatype.isNullable + ? '$instanceVariableName ? &(*$instanceVariableName) : nullptr' + : instanceVariableName; + + // Generates the string for a setter treating the type as [type], to allow + // generating multiple setter variants. + String makeSetter(HostDatatype type) { + const String setterArgumentName = 'value_arg'; + final String valueExpression = type.isNullable + ? '$setterArgumentName ? ${_valueType(type)}(*$setterArgumentName) : std::nullopt' + : setterArgumentName; + return 'void $qualifiedSetterName(${_unownedArgumentType(type)} $setterArgumentName) ' + '{ $instanceVariableName = $valueExpression; }'; + } + + indent.writeln( + '${_getterReturnType(hostDatatype)} $qualifiedGetterName() const ' + '{ return $returnExpression; }'); + indent.writeln(makeSetter(hostDatatype)); + if (hostDatatype.isNullable) { + // Write the non-nullable variant; see _writeCppHeaderDataClass. + final HostDatatype nonNullType = _nonNullableType(hostDatatype); + indent.writeln(makeSetter(nonNullType)); + } + + indent.addln(''); +} + +/// Writes the implementation for the custom class [klass]. +/// +/// See [_writeCppHeaderDataClass] for the corresponding declaration. +/// This is intended to be added to the implementation file. +void _writeCppSourceDataClass(CppOptions languageOptions, Root root, + StringSink sink, Indent indent, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + + indent.addln(''); + indent.writeln('$_commentPrefix ${klass.name}'); + indent.addln(''); + + // Getters and setters. + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + _writeCppSourceClassField( + languageOptions, root, sink, indent, klass, field); + } + + // Serialization. + _writeCppSourceClassEncode(languageOptions, root, sink, indent, klass, + customClassNames, customEnumNames); + + // Default constructor. + indent.writeln('${klass.name}::${klass.name}() {}'); + indent.addln(''); + + // Deserialization. + _writeCppSourceClassDecode(languageOptions, root, sink, indent, klass, + customClassNames, customEnumNames); +} + void _writeHostApiHeader(Indent indent, Api api, Root root) { assert(api.location == ApiLocation.host); diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 1d2421f51af..32552eaa447 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -89,6 +89,7 @@ class ObjcGenerator extends Generator { indent.writeln( '@class ${_className(languageOptions.prefix, klass.name)};'); } + indent.addln(''); } else if (fileType == FileType.source) { _writeObjcSourceHelperFunctions(indent); indent.addln(''); @@ -161,7 +162,12 @@ class ObjcGenerator extends Generator { Set customClassNames, Set customEnumNames, ) { - // Left blank until functions fully converted to methods. + if (fileType == FileType.source) { + final String className = _className(languageOptions.prefix, klass.name); + + _writeClassEncode(languageOptions, root, sink, indent, klass, + customClassNames, customEnumNames, className); + } } @override @@ -175,7 +181,12 @@ class ObjcGenerator extends Generator { Set customClassNames, Set customEnumNames, ) { - // Left blank until functions fully converted to methods. + if (fileType == FileType.source) { + final String className = _className(languageOptions.prefix, klass.name); + + _writeClassDecode(languageOptions, root, sink, indent, klass, + customClassNames, customEnumNames, className); + } } } From b68557b58862925cf8a1a50925734046f3445677 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 4 Jan 2023 18:25:35 -0800 Subject: [PATCH 54/87] Move all migrated methods into class --- packages/pigeon/lib/cpp_generator.dart | 717 ++++++++++++------------ packages/pigeon/lib/objc_generator.dart | 508 ++++++++--------- 2 files changed, 618 insertions(+), 607 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index cb1fd35dc74..3f94ab2396d 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -144,7 +144,8 @@ class CppGenerator extends Generator { _writeCppHeaderDataClass(languageOptions, root, sink, indent, klass, testFriend: testFixtureClass); } else { - _writeCppSourceDataClass(languageOptions, root, sink, indent, klass); + _writeCppSourceDataClass( + languageOptions, root, sink, indent, fileType, klass); } } @@ -177,6 +178,365 @@ class CppGenerator extends Generator { _writeCppSourceClassDecode(languageOptions, root, sink, indent, klass, customClassNames, customEnumNames); } + + /// Writes the declaration for the custom class [klass]. + /// + /// See [_writeCppSourceDataClass] for the corresponding declaration. + /// This is intended to be added to the header. + void _writeCppHeaderDataClass(CppOptions languageOptions, Root root, + StringSink sink, Indent indent, Class klass, + {String? testFriend}) { + indent.addln(''); + + const List generatedMessages = [ + ' Generated class from Pigeon that represents data sent in messages.' + ]; + + addDocumentationComments( + indent, klass.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); + + indent.write('class ${klass.name} '); + indent.scoped('{', '};', () { + indent.scoped(' public:', '', () { + indent.writeln('${klass.name}();'); + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + final HostDatatype baseDatatype = getFieldHostDatatype( + field, + root.classes, + root.enums, + (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + indent.writeln( + '${_getterReturnType(baseDatatype)} ${_makeGetterName(field)}() const;'); + indent.writeln( + 'void ${_makeSetterName(field)}(${_unownedArgumentType(baseDatatype)} value_arg);'); + if (field.type.isNullable) { + // Add a second setter that takes the non-nullable version of the + // argument for convenience, since setting literal values with the + // pointer version is non-trivial. + final HostDatatype nonNullType = _nonNullableType(baseDatatype); + indent.writeln( + 'void ${_makeSetterName(field)}(${_unownedArgumentType(nonNullType)} value_arg);'); + } + indent.addln(''); + } + }); + + indent.scoped(' private:', '', () { + indent.writeln('${klass.name}(const flutter::EncodableList& list);'); + indent.writeln('flutter::EncodableList ToEncodableList() const;'); + for (final Class friend in root.classes) { + if (friend != klass && + friend.fields.any( + (NamedType element) => element.type.baseName == klass.name)) { + indent.writeln('friend class ${friend.name};'); + } + } + for (final Api api in root.apis) { + // TODO(gaaclarke): Find a way to be more precise with our + // friendships. + indent.writeln('friend class ${api.name};'); + indent.writeln('friend class ${_getCodecSerializerName(api)};'); + } + if (testFriend != null) { + indent.writeln('friend class $testFriend;'); + } + + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + root.classes, + root.enums, + (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + indent.writeln( + '${_valueType(hostDatatype)} ${_makeInstanceVariableName(field)};'); + } + }); + }, nestCount: 0); + indent.writeln(''); + } + + void _writeCppSourceClassEncode( + CppOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + indent.write( + 'flutter::EncodableList ${klass.name}::ToEncodableList() const '); + indent.scoped('{', '}', () { + indent.scoped('return flutter::EncodableList{', '};', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + root.classes, + root.enums, + (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + + final String instanceVariable = _makeInstanceVariableName(field); + + String encodableValue = ''; + if (!hostDatatype.isBuiltin && + customClassNames.contains(field.type.baseName)) { + final String operator = field.type.isNullable ? '->' : '.'; + encodableValue = + 'flutter::EncodableValue($instanceVariable${operator}ToEncodableList())'; + } else if (!hostDatatype.isBuiltin && + customEnumNames.contains(field.type.baseName)) { + final String nonNullValue = field.type.isNullable + ? '(*$instanceVariable)' + : instanceVariable; + encodableValue = 'flutter::EncodableValue((int)$nonNullValue)'; + } else { + final String operator = field.type.isNullable ? '*' : ''; + encodableValue = + 'flutter::EncodableValue($operator$instanceVariable)'; + } + + if (field.type.isNullable) { + encodableValue = + '$instanceVariable ? $encodableValue : flutter::EncodableValue()'; + } + + indent.writeln('$encodableValue,'); + } + }); + }); + indent.addln(''); + } + + void _writeCppSourceClassDecode( + CppOptions languageOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + indent.write( + '${klass.name}::${klass.name}(const flutter::EncodableList& list) '); + indent.scoped('{', '}', () { + enumerate(getFieldsInSerializationOrder(klass), + (int index, final NamedType field) { + final String instanceVariableName = _makeInstanceVariableName(field); + final String pointerFieldName = + '${_pointerPrefix}_${_makeVariableName(field)}'; + final String encodableFieldName = + '${_encodablePrefix}_${_makeVariableName(field)}'; + indent.writeln('auto& $encodableFieldName = list[$index];'); + if (customEnumNames.contains(field.type.baseName)) { + indent.writeln( + 'if (const int32_t* $pointerFieldName = std::get_if(&$encodableFieldName))\t$instanceVariableName = (${field.type.baseName})*$pointerFieldName;'); + } else { + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + root.classes, + root.enums, + (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + if (field.type.baseName == 'int') { + indent.format(''' +if (const int32_t* $pointerFieldName = std::get_if(&$encodableFieldName)) +\t$instanceVariableName = *$pointerFieldName; +else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodableFieldName)) +\t$instanceVariableName = *${pointerFieldName}_64;'''); + } else if (!hostDatatype.isBuiltin && + root.classes + .map((Class x) => x.name) + .contains(field.type.baseName)) { + indent.write( + 'if (const flutter::EncodableList* $pointerFieldName = std::get_if(&$encodableFieldName)) '); + indent.scoped('{', '}', () { + indent.writeln( + '$instanceVariableName = ${hostDatatype.datatype}(*$pointerFieldName);'); + }); + } else { + indent.write( + 'if (const ${hostDatatype.datatype}* $pointerFieldName = std::get_if<${hostDatatype.datatype}>(&$encodableFieldName)) '); + indent.scoped('{', '}', () { + indent.writeln('$instanceVariableName = *$pointerFieldName;'); + }); + } + } + }); + }); + indent.addln(''); + } + + void _writeCppSourceClassField(CppOptions languageOptions, Root root, + StringSink sink, Indent indent, Class klass, NamedType field) { + final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, + root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + final String instanceVariableName = _makeInstanceVariableName(field); + final String qualifiedGetterName = + '${klass.name}::${_makeGetterName(field)}'; + final String qualifiedSetterName = + '${klass.name}::${_makeSetterName(field)}'; + final String returnExpression = hostDatatype.isNullable + ? '$instanceVariableName ? &(*$instanceVariableName) : nullptr' + : instanceVariableName; + + // Generates the string for a setter treating the type as [type], to allow + // generating multiple setter variants. + String makeSetter(HostDatatype type) { + const String setterArgumentName = 'value_arg'; + final String valueExpression = type.isNullable + ? '$setterArgumentName ? ${_valueType(type)}(*$setterArgumentName) : std::nullopt' + : setterArgumentName; + return 'void $qualifiedSetterName(${_unownedArgumentType(type)} $setterArgumentName) ' + '{ $instanceVariableName = $valueExpression; }'; + } + + indent.writeln( + '${_getterReturnType(hostDatatype)} $qualifiedGetterName() const ' + '{ return $returnExpression; }'); + indent.writeln(makeSetter(hostDatatype)); + if (hostDatatype.isNullable) { + // Write the non-nullable variant; see _writeCppHeaderDataClass. + final HostDatatype nonNullType = _nonNullableType(hostDatatype); + indent.writeln(makeSetter(nonNullType)); + } + + indent.addln(''); + } + + /// Writes the implementation for the custom class [klass]. + /// + /// See [_writeCppHeaderDataClass] for the corresponding declaration. + /// This is intended to be added to the implementation file. + void _writeCppSourceDataClass(CppOptions languageOptions, Root root, + StringSink sink, Indent indent, FileType fileType, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + + indent.addln(''); + indent.writeln('$_commentPrefix ${klass.name}'); + indent.addln(''); + + // Getters and setters. + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + _writeCppSourceClassField( + languageOptions, root, sink, indent, klass, field); + } + + // Serialization. + writeClassEncode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + + // Default constructor. + indent.writeln('${klass.name}::${klass.name}() {}'); + indent.addln(''); + + // Deserialization. + writeClassDecode(languageOptions, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + } + + /// Writes Cpp header file header to sink. + void writeCppHeaderHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('$_commentPrefix $generatedCodeWarning'); + indent.writeln('$_commentPrefix $seeAlsoWarning'); + indent.addln(''); + } + + /// Writes Cpp header file imports to sink. + void writeCppHeaderImports( + CppOptions options, Root root, StringSink sink, Indent indent) { + final String guardName = + _getGuardName(options.headerIncludePath, options.namespace); + indent.writeln('#ifndef $guardName'); + indent.writeln('#define $guardName'); + + _writeSystemHeaderIncludeBlock(indent, [ + 'flutter/basic_message_channel.h', + 'flutter/binary_messenger.h', + 'flutter/encodable_value.h', + 'flutter/standard_message_codec.h', + ]); + indent.addln(''); + _writeSystemHeaderIncludeBlock(indent, [ + 'map', + 'string', + 'optional', + ]); + indent.addln(''); + if (options.namespace != null) { + indent.writeln('namespace ${options.namespace} {'); + } + indent.addln(''); + if (options.namespace?.endsWith('_pigeontest') ?? false) { + final String testFixtureClass = + '${_pascalCaseFromSnakeCase(options.namespace!.replaceAll('_pigeontest', ''))}Test'; + indent.writeln('class $testFixtureClass;'); + } + indent.addln(''); + indent.writeln('$_commentPrefix Generated class from Pigeon.'); + } + + /// Writes Cpp header enum to sink. + void writeCppHeaderEnum(CppOptions options, Root root, StringSink sink, + Indent indent, Enum anEnum) { + indent.writeln(''); + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + indent.write('enum class ${anEnum.name} '); + indent.scoped('{', '};', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + indent.writeln( + '${member.name} = $index${index == anEnum.members.length - 1 ? '' : ','}'); + }); + }); + } + + /// Writes Cpp source file header to sink. + void writeCppSourceHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('$_commentPrefix $generatedCodeWarning'); + indent.writeln('$_commentPrefix $seeAlsoWarning'); + indent.addln(''); + indent.addln('#undef _HAS_EXCEPTIONS'); + indent.addln(''); + } + + /// Writes Cpp source file imports to sink. + void writeCppSourceImports( + CppOptions options, Root root, StringSink sink, Indent indent) { + indent.writeln('#include "${options.headerIncludePath}"'); + indent.addln(''); + _writeSystemHeaderIncludeBlock(indent, [ + 'flutter/basic_message_channel.h', + 'flutter/binary_messenger.h', + 'flutter/encodable_value.h', + 'flutter/standard_message_codec.h', + ]); + indent.addln(''); + _writeSystemHeaderIncludeBlock(indent, [ + 'map', + 'string', + 'optional', + ]); + indent.addln(''); + + if (options.namespace != null) { + indent.writeln('namespace ${options.namespace} {'); + } + } } String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; @@ -303,262 +663,6 @@ $friendLines '''); } -/// Writes the declaration for the custom class [klass]. -/// -/// See [_writeCppSourceDataClass] for the corresponding declaration. -/// This is intended to be added to the header. -void _writeCppHeaderDataClass(CppOptions languageOptions, Root root, - StringSink sink, Indent indent, Class klass, - {String? testFriend}) { - indent.addln(''); - - const List generatedMessages = [ - ' Generated class from Pigeon that represents data sent in messages.' - ]; - - addDocumentationComments(indent, klass.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - - indent.write('class ${klass.name} '); - indent.scoped('{', '};', () { - indent.scoped(' public:', '', () { - indent.writeln('${klass.name}();'); - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - final HostDatatype baseDatatype = getFieldHostDatatype( - field, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - indent.writeln( - '${_getterReturnType(baseDatatype)} ${_makeGetterName(field)}() const;'); - indent.writeln( - 'void ${_makeSetterName(field)}(${_unownedArgumentType(baseDatatype)} value_arg);'); - if (field.type.isNullable) { - // Add a second setter that takes the non-nullable version of the - // argument for convenience, since setting literal values with the - // pointer version is non-trivial. - final HostDatatype nonNullType = _nonNullableType(baseDatatype); - indent.writeln( - 'void ${_makeSetterName(field)}(${_unownedArgumentType(nonNullType)} value_arg);'); - } - indent.addln(''); - } - }); - - indent.scoped(' private:', '', () { - indent.writeln('${klass.name}(const flutter::EncodableList& list);'); - indent.writeln('flutter::EncodableList ToEncodableList() const;'); - for (final Class friend in root.classes) { - if (friend != klass && - friend.fields.any( - (NamedType element) => element.type.baseName == klass.name)) { - indent.writeln('friend class ${friend.name};'); - } - } - for (final Api api in root.apis) { - // TODO(gaaclarke): Find a way to be more precise with our - // friendships. - indent.writeln('friend class ${api.name};'); - indent.writeln('friend class ${_getCodecSerializerName(api)};'); - } - if (testFriend != null) { - indent.writeln('friend class $testFriend;'); - } - - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - indent.writeln( - '${_valueType(hostDatatype)} ${_makeInstanceVariableName(field)};'); - } - }); - }, nestCount: 0); - indent.writeln(''); -} - -void _writeCppSourceClassEncode( - CppOptions languageOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, -) { - indent - .write('flutter::EncodableList ${klass.name}::ToEncodableList() const '); - indent.scoped('{', '}', () { - indent.scoped('return flutter::EncodableList{', '};', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - - final String instanceVariable = _makeInstanceVariableName(field); - - String encodableValue = ''; - if (!hostDatatype.isBuiltin && - customClassNames.contains(field.type.baseName)) { - final String operator = field.type.isNullable ? '->' : '.'; - encodableValue = - 'flutter::EncodableValue($instanceVariable${operator}ToEncodableList())'; - } else if (!hostDatatype.isBuiltin && - customEnumNames.contains(field.type.baseName)) { - final String nonNullValue = - field.type.isNullable ? '(*$instanceVariable)' : instanceVariable; - encodableValue = 'flutter::EncodableValue((int)$nonNullValue)'; - } else { - final String operator = field.type.isNullable ? '*' : ''; - encodableValue = - 'flutter::EncodableValue($operator$instanceVariable)'; - } - - if (field.type.isNullable) { - encodableValue = - '$instanceVariable ? $encodableValue : flutter::EncodableValue()'; - } - - indent.writeln('$encodableValue,'); - } - }); - }); - indent.addln(''); -} - -void _writeCppSourceClassDecode( - CppOptions languageOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, -) { - indent.write( - '${klass.name}::${klass.name}(const flutter::EncodableList& list) '); - indent.scoped('{', '}', () { - enumerate(getFieldsInSerializationOrder(klass), - (int index, final NamedType field) { - final String instanceVariableName = _makeInstanceVariableName(field); - final String pointerFieldName = - '${_pointerPrefix}_${_makeVariableName(field)}'; - final String encodableFieldName = - '${_encodablePrefix}_${_makeVariableName(field)}'; - indent.writeln('auto& $encodableFieldName = list[$index];'); - if (customEnumNames.contains(field.type.baseName)) { - indent.writeln( - 'if (const int32_t* $pointerFieldName = std::get_if(&$encodableFieldName))\t$instanceVariableName = (${field.type.baseName})*$pointerFieldName;'); - } else { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - if (field.type.baseName == 'int') { - indent.format(''' -if (const int32_t* $pointerFieldName = std::get_if(&$encodableFieldName)) -\t$instanceVariableName = *$pointerFieldName; -else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodableFieldName)) -\t$instanceVariableName = *${pointerFieldName}_64;'''); - } else if (!hostDatatype.isBuiltin && - root.classes - .map((Class x) => x.name) - .contains(field.type.baseName)) { - indent.write( - 'if (const flutter::EncodableList* $pointerFieldName = std::get_if(&$encodableFieldName)) '); - indent.scoped('{', '}', () { - indent.writeln( - '$instanceVariableName = ${hostDatatype.datatype}(*$pointerFieldName);'); - }); - } else { - indent.write( - 'if (const ${hostDatatype.datatype}* $pointerFieldName = std::get_if<${hostDatatype.datatype}>(&$encodableFieldName)) '); - indent.scoped('{', '}', () { - indent.writeln('$instanceVariableName = *$pointerFieldName;'); - }); - } - } - }); - }); - indent.addln(''); -} - -void _writeCppSourceClassField(CppOptions languageOptions, Root root, - StringSink sink, Indent indent, Class klass, NamedType field) { - final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, - root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - final String instanceVariableName = _makeInstanceVariableName(field); - final String qualifiedGetterName = '${klass.name}::${_makeGetterName(field)}'; - final String qualifiedSetterName = '${klass.name}::${_makeSetterName(field)}'; - final String returnExpression = hostDatatype.isNullable - ? '$instanceVariableName ? &(*$instanceVariableName) : nullptr' - : instanceVariableName; - - // Generates the string for a setter treating the type as [type], to allow - // generating multiple setter variants. - String makeSetter(HostDatatype type) { - const String setterArgumentName = 'value_arg'; - final String valueExpression = type.isNullable - ? '$setterArgumentName ? ${_valueType(type)}(*$setterArgumentName) : std::nullopt' - : setterArgumentName; - return 'void $qualifiedSetterName(${_unownedArgumentType(type)} $setterArgumentName) ' - '{ $instanceVariableName = $valueExpression; }'; - } - - indent.writeln( - '${_getterReturnType(hostDatatype)} $qualifiedGetterName() const ' - '{ return $returnExpression; }'); - indent.writeln(makeSetter(hostDatatype)); - if (hostDatatype.isNullable) { - // Write the non-nullable variant; see _writeCppHeaderDataClass. - final HostDatatype nonNullType = _nonNullableType(hostDatatype); - indent.writeln(makeSetter(nonNullType)); - } - - indent.addln(''); -} - -/// Writes the implementation for the custom class [klass]. -/// -/// See [_writeCppHeaderDataClass] for the corresponding declaration. -/// This is intended to be added to the implementation file. -void _writeCppSourceDataClass(CppOptions languageOptions, Root root, - StringSink sink, Indent indent, Class klass) { - final Set customClassNames = - root.classes.map((Class x) => x.name).toSet(); - final Set customEnumNames = - root.enums.map((Enum x) => x.name).toSet(); - - indent.addln(''); - indent.writeln('$_commentPrefix ${klass.name}'); - indent.addln(''); - - // Getters and setters. - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - _writeCppSourceClassField( - languageOptions, root, sink, indent, klass, field); - } - - // Serialization. - _writeCppSourceClassEncode(languageOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - - // Default constructor. - indent.writeln('${klass.name}::${klass.name}() {}'); - indent.addln(''); - - // Deserialization. - _writeCppSourceClassDecode(languageOptions, root, sink, indent, klass, - customClassNames, customEnumNames); -} - void _writeHostApiHeader(Indent indent, Api api, Root root) { assert(api.location == ApiLocation.host); @@ -1156,68 +1260,6 @@ void _writeSystemHeaderIncludeBlock(Indent indent, List headers) { } } -/// Writes Cpp header file header to sink. -void writeCppHeaderHeader( - CppOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('$_commentPrefix $generatedCodeWarning'); - indent.writeln('$_commentPrefix $seeAlsoWarning'); - indent.addln(''); -} - -/// Writes Cpp header file imports to sink. -void writeCppHeaderImports( - CppOptions options, Root root, StringSink sink, Indent indent) { - final String guardName = - _getGuardName(options.headerIncludePath, options.namespace); - indent.writeln('#ifndef $guardName'); - indent.writeln('#define $guardName'); - - _writeSystemHeaderIncludeBlock(indent, [ - 'flutter/basic_message_channel.h', - 'flutter/binary_messenger.h', - 'flutter/encodable_value.h', - 'flutter/standard_message_codec.h', - ]); - indent.addln(''); - _writeSystemHeaderIncludeBlock(indent, [ - 'map', - 'string', - 'optional', - ]); - indent.addln(''); - if (options.namespace != null) { - indent.writeln('namespace ${options.namespace} {'); - } - indent.addln(''); - if (options.namespace?.endsWith('_pigeontest') ?? false) { - final String testFixtureClass = - '${_pascalCaseFromSnakeCase(options.namespace!.replaceAll('_pigeontest', ''))}Test'; - indent.writeln('class $testFixtureClass;'); - } - indent.addln(''); - indent.writeln('$_commentPrefix Generated class from Pigeon.'); -} - -/// Writes Cpp header enum to sink. -void writeCppHeaderEnum(CppOptions options, Root root, StringSink sink, - Indent indent, Enum anEnum) { - indent.writeln(''); - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - indent.write('enum class ${anEnum.name} '); - indent.scoped('{', '};', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - indent.writeln( - '${member.name} = $index${index == anEnum.members.length - 1 ? '' : ','}'); - }); - }); -} - /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options] and [headerFileName]. void generateCppHeader( @@ -1242,43 +1284,6 @@ void generateCppHeader( indent.writeln('#endif // $guardName'); } -/// Writes Cpp source file header to sink. -void writeCppSourceHeader( - CppOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('$_commentPrefix $generatedCodeWarning'); - indent.writeln('$_commentPrefix $seeAlsoWarning'); - indent.addln(''); - indent.addln('#undef _HAS_EXCEPTIONS'); - indent.addln(''); -} - -/// Writes Cpp source file imports to sink. -void writeCppSourceImports( - CppOptions options, Root root, StringSink sink, Indent indent) { - indent.writeln('#include "${options.headerIncludePath}"'); - indent.addln(''); - _writeSystemHeaderIncludeBlock(indent, [ - 'flutter/basic_message_channel.h', - 'flutter/binary_messenger.h', - 'flutter/encodable_value.h', - 'flutter/standard_message_codec.h', - ]); - indent.addln(''); - _writeSystemHeaderIncludeBlock(indent, [ - 'map', - 'string', - 'optional', - ]); - indent.addln(''); - - if (options.namespace != null) { - indent.writeln('namespace ${options.namespace} {'); - } -} - /// Generates the ".cpp" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateCppSource( diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 32552eaa447..3cf8021c002 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -146,7 +146,7 @@ class ObjcGenerator extends Generator { _writeObjcHeaderDataClass(languageOptions, root, sink, indent, klass); } else { _writeObjcSourceDataClassImplementation( - languageOptions, root, sink, indent, klass); + languageOptions, root, sink, indent, fileType, klass); indent.writeln(''); } } @@ -165,7 +165,7 @@ class ObjcGenerator extends Generator { if (fileType == FileType.source) { final String className = _className(languageOptions.prefix, klass.name); - _writeClassEncode(languageOptions, root, sink, indent, klass, + _writeObjcSourceClassEncode(languageOptions, root, sink, indent, klass, customClassNames, customEnumNames, className); } } @@ -184,10 +184,263 @@ class ObjcGenerator extends Generator { if (fileType == FileType.source) { final String className = _className(languageOptions.prefix, klass.name); - _writeClassDecode(languageOptions, root, sink, indent, klass, + _writeObjcSourceClassDecode(languageOptions, root, sink, indent, klass, customClassNames, customEnumNames, className); } } + + // Header File Methods. + + /// Writes the class declaration for a data class. + /// + /// Example: + /// @interface Foo : NSObject + /// @property (nonatomic, copy) NSString *bar; + /// @end + void _writeObjcHeaderDataClass(ObjcOptions languageOptions, Root root, + StringSink sink, Indent indent, Class klass) { + final List classes = root.classes; + final List enums = root.enums; + final String? prefix = languageOptions.prefix; + final List customEnumNames = enums.map((Enum x) => x.name).toList(); + + addDocumentationComments( + indent, klass.documentationComments, _docCommentSpec); + + indent.writeln('@interface ${_className(prefix, klass.name)} : NSObject'); + if (getFieldsInSerializationOrder(klass).isNotEmpty) { + if (getFieldsInSerializationOrder(klass) + .map((NamedType e) => !e.type.isNullable) + .any((bool e) => e)) { + indent.writeln( + '$_docCommentPrefix `init` unavailable to enforce nonnull fields, see the `make` class method.'); + indent.writeln('- (instancetype)init NS_UNAVAILABLE;'); + } + _writeObjcSourceClassInitializerDeclaration( + indent, klass, classes, enums, prefix); + indent.addln(';'); + } + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + classes, + enums, + (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), + customResolver: customEnumNames.contains(field.type.baseName) + ? (String x) => _className(prefix, x) + : (String x) => '${_className(prefix, x)} *'); + late final String propertyType; + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + if (customEnumNames.contains(field.type.baseName)) { + propertyType = 'assign'; + } else { + propertyType = _propertyTypeForDartType(field); + } + final String nullability = + _isNullable(hostDatatype, field.type) ? ', nullable' : ''; + indent.writeln( + '@property(nonatomic, $propertyType$nullability) ${hostDatatype.datatype} ${field.name};'); + } + indent.writeln('@end'); + indent.writeln(''); + } + + /// Writes Objc header file header to sink. + void writeObjcHeaderHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); + } + + /// Writes Objc header file imports to sink. + void writeObjcHeaderImports( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + indent.writeln('#import '); + indent.addln(''); + + indent.writeln('@protocol FlutterBinaryMessenger;'); + indent.writeln('@protocol FlutterMessageCodec;'); + indent.writeln('@class FlutterError;'); + indent.writeln('@class FlutterStandardTypedData;'); + indent.addln(''); + } + + /// Writes single Objc header enum. + void writeObjcHeaderEnum(ObjcOptions options, Root root, StringSink sink, + Indent indent, Enum anEnum) { + final String enumName = _className(options.prefix, anEnum.name); + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + + indent.write('typedef NS_ENUM(NSUInteger, $enumName) '); + indent.scoped('{', '};', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + // Capitalized first letter to ensure Swift compatibility + indent.writeln( + '$enumName${member.name[0].toUpperCase()}${member.name.substring(1)} = $index,'); + }); + }); + } + + // Source File Methods. + + /// Writes Objc Source file header to sink. + void writeObjcSourceHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); + } + + /// Writes Objc source file imports to sink. + void writeObjcSourceImports( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + indent.writeln('#import "${options.headerIncludePath}"'); + indent.writeln('#import '); + indent.addln(''); + + indent.writeln('#if !__has_feature(objc_arc)'); + indent.writeln('#error File requires ARC to be enabled.'); + indent.writeln('#endif'); + indent.addln(''); + } + + void _writeObjcSourceHelperFunctions(Indent indent) { + indent.format(''' +static NSArray *wrapResult(id result, FlutterError *error) { +\tif (error) { +\t\treturn @[ error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] ]; +\t} +\treturn @[ result ?: [NSNull null] ]; +}'''); + indent.format(''' +static id GetNullableObject(NSDictionary* dict, id key) { +\tid result = dict[key]; +\treturn (result == [NSNull null]) ? nil : result; +} +static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { +\tid result = array[key]; +\treturn (result == [NSNull null]) ? nil : result; +} +'''); + } + + void _writeObjcSourceDataClassExtension( + ObjcOptions languageOptions, Indent indent, Class klass) { + final String className = _className(languageOptions.prefix, klass.name); + indent.writeln('@interface $className ()'); + indent.writeln('+ ($className *)fromList:(NSArray *)list;'); + indent + .writeln('+ (nullable $className *)nullableFromList:(NSArray *)list;'); + indent.writeln('- (NSArray *)toList;'); + indent.writeln('@end'); + } + + void _writeObjcSourceDataClassImplementation(ObjcOptions options, Root root, + StringSink sink, Indent indent, FileType fileType, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + final String className = _className(options.prefix, klass.name); + + indent.writeln('@implementation $className'); + _writeObjcSourceClassInitializer(options, root, sink, indent, klass, + customClassNames, customEnumNames, className); + writeClassDecode(options, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + writeClassEncode(options, root, sink, indent, fileType, klass, + customClassNames, customEnumNames); + indent.writeln('@end'); + } + + void _writeObjcSourceClassInitializer( + ObjcOptions options, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + String className, + ) { + _writeObjcSourceClassInitializerDeclaration( + indent, klass, root.classes, root.enums, options.prefix); + indent.writeScoped(' {', '}', () { + const String result = 'pigeonResult'; + indent.writeln('$className* $result = [[$className alloc] init];'); + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + indent.writeln('$result.${field.name} = ${field.name};'); + } + indent.writeln('return $result;'); + }); + } + + void _writeObjcSourceClassDecode( + ObjcOptions options, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + String className, + ) { + indent.write('+ ($className *)fromList:(NSArray *)list '); + indent.scoped('{', '}', () { + const String resultName = 'pigeonResult'; + indent.writeln('$className *$resultName = [[$className alloc] init];'); + enumerate(getFieldsInSerializationOrder(klass), + (int index, final NamedType field) { + if (customEnumNames.contains(field.type.baseName)) { + indent.writeln( + '$resultName.${field.name} = [${_listGetter(customClassNames, 'list', field, index, options.prefix)} integerValue];'); + } else { + indent.writeln( + '$resultName.${field.name} = ${_listGetter(customClassNames, 'list', field, index, options.prefix)};'); + if (!field.type.isNullable) { + indent.writeln('NSAssert($resultName.${field.name} != nil, @"");'); + } + } + }); + indent.writeln('return $resultName;'); + }); + + indent.writeln( + '+ (nullable $className *)nullableFromList:(NSArray *)list { return (list) ? [$className fromList:list] : nil; }'); + } + + void _writeObjcSourceClassEncode( + ObjcOptions options, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + String className, + ) { + indent.write('- (NSArray *)toList '); + indent.scoped('{', '}', () { + indent.write('return'); + indent.scoped(' @[', '];', () { + for (final NamedType field in klass.fields) { + indent.writeln( + '${_arrayValue(customClassNames, customEnumNames, field)},'); + } + }); + }); + } } /// Calculates the ObjC class name, possibly prefixed. @@ -289,7 +542,7 @@ bool _isNullable(HostDatatype hostDatatype, TypeDeclaration type) => /// Writes the method declaration for the initializer. /// /// Example '+ (instancetype)makeWithFoo:(NSString *)foo' -void _writeInitializerDeclaration(Indent indent, Class klass, +void _writeObjcSourceClassInitializerDeclaration(Indent indent, Class klass, List classes, List enums, String? prefix) { final List customEnumNames = enums.map((Enum x) => x.name).toList(); indent.write('+ (instancetype)makeWith'); @@ -319,60 +572,6 @@ void _writeInitializerDeclaration(Indent indent, Class klass, }); } -/// Writes the class declaration for a data class. -/// -/// Example: -/// @interface Foo : NSObject -/// @property (nonatomic, copy) NSString *bar; -/// @end -void _writeObjcHeaderDataClass(ObjcOptions languageOptions, Root root, - StringSink sink, Indent indent, Class klass) { - final List classes = root.classes; - final List enums = root.enums; - final String? prefix = languageOptions.prefix; - final List customEnumNames = enums.map((Enum x) => x.name).toList(); - - addDocumentationComments( - indent, klass.documentationComments, _docCommentSpec); - - indent.writeln('@interface ${_className(prefix, klass.name)} : NSObject'); - if (getFieldsInSerializationOrder(klass).isNotEmpty) { - if (getFieldsInSerializationOrder(klass) - .map((NamedType e) => !e.type.isNullable) - .any((bool e) => e)) { - indent.writeln( - '$_docCommentPrefix `init` unavailable to enforce nonnull fields, see the `make` class method.'); - indent.writeln('- (instancetype)init NS_UNAVAILABLE;'); - } - _writeInitializerDeclaration(indent, klass, classes, enums, prefix); - indent.addln(';'); - } - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - classes, - enums, - (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), - customResolver: customEnumNames.contains(field.type.baseName) - ? (String x) => _className(prefix, x) - : (String x) => '${_className(prefix, x)} *'); - late final String propertyType; - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - if (customEnumNames.contains(field.type.baseName)) { - propertyType = 'assign'; - } else { - propertyType = _propertyTypeForDartType(field); - } - final String nullability = - _isNullable(hostDatatype, field.type) ? ', nullable' : ''; - indent.writeln( - '@property(nonatomic, $propertyType$nullability) ${hostDatatype.datatype} ${field.name};'); - } - indent.writeln('@end'); - indent.writeln(''); -} - /// Generates the name of the codec that will be generated. String _getCodecName(String? prefix, String className) => '${_className(prefix, className)}Codec'; @@ -659,49 +858,6 @@ void _writeFlutterApiDeclaration( indent.writeln('@end'); } -/// Writes Objc header file header to sink. -void writeObjcHeaderHeader( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.addln(''); -} - -/// Writes Objc header file imports to sink. -void writeObjcHeaderImports( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - indent.writeln('#import '); - indent.addln(''); - - indent.writeln('@protocol FlutterBinaryMessenger;'); - indent.writeln('@protocol FlutterMessageCodec;'); - indent.writeln('@class FlutterError;'); - indent.writeln('@class FlutterStandardTypedData;'); - indent.addln(''); -} - -/// Writes single Objc header enum. -void writeObjcHeaderEnum(ObjcOptions options, Root root, StringSink sink, - Indent indent, Enum anEnum) { - final String enumName = _className(options.prefix, anEnum.name); - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - - indent.write('typedef NS_ENUM(NSUInteger, $enumName) '); - indent.scoped('{', '};', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - // Capitalized first letter to ensure Swift compatibility - indent.writeln( - '$enumName${member.name[0].toUpperCase()}${member.name.substring(1)} = $index,'); - }); - }); -} - /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateObjcHeader( @@ -989,156 +1145,6 @@ void _writeFlutterApiSource( indent.writeln('@end'); } -/// Writes Objc Source file header to sink. -void writeObjcSourceHeader( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.addln(''); -} - -/// Writes Objc source file imports to sink. -void writeObjcSourceImports( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - indent.writeln('#import "${options.headerIncludePath}"'); - indent.writeln('#import '); - indent.addln(''); - - indent.writeln('#if !__has_feature(objc_arc)'); - indent.writeln('#error File requires ARC to be enabled.'); - indent.writeln('#endif'); - indent.addln(''); -} - -void _writeObjcSourceHelperFunctions(Indent indent) { - indent.format(''' -static NSArray *wrapResult(id result, FlutterError *error) { -\tif (error) { -\t\treturn @[ error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] ]; -\t} -\treturn @[ result ?: [NSNull null] ]; -}'''); - indent.format(''' -static id GetNullableObject(NSDictionary* dict, id key) { -\tid result = dict[key]; -\treturn (result == [NSNull null]) ? nil : result; -} -static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { -\tid result = array[key]; -\treturn (result == [NSNull null]) ? nil : result; -} -'''); -} - -void _writeObjcSourceDataClassExtension( - ObjcOptions languageOptions, Indent indent, Class klass) { - final String className = _className(languageOptions.prefix, klass.name); - indent.writeln('@interface $className ()'); - indent.writeln('+ ($className *)fromList:(NSArray *)list;'); - indent.writeln('+ (nullable $className *)nullableFromList:(NSArray *)list;'); - indent.writeln('- (NSArray *)toList;'); - indent.writeln('@end'); -} - -void _writeObjcSourceDataClassImplementation(ObjcOptions options, Root root, - StringSink sink, Indent indent, Class klass) { - final Set customClassNames = - root.classes.map((Class x) => x.name).toSet(); - final Set customEnumNames = - root.enums.map((Enum x) => x.name).toSet(); - final String className = _className(options.prefix, klass.name); - - indent.writeln('@implementation $className'); - _writeInitializer(options, root, sink, indent, klass, customClassNames, - customEnumNames, className); - _writeClassDecode(options, root, sink, indent, klass, customClassNames, - customEnumNames, className); - _writeClassEncode(options, root, sink, indent, klass, customClassNames, - customEnumNames, className); - indent.writeln('@end'); -} - -void _writeInitializer( - ObjcOptions options, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - String className, -) { - _writeInitializerDeclaration( - indent, klass, root.classes, root.enums, options.prefix); - indent.writeScoped(' {', '}', () { - const String result = 'pigeonResult'; - indent.writeln('$className* $result = [[$className alloc] init];'); - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - indent.writeln('$result.${field.name} = ${field.name};'); - } - indent.writeln('return $result;'); - }); -} - -void _writeClassDecode( - ObjcOptions options, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - String className, -) { - indent.write('+ ($className *)fromList:(NSArray *)list '); - indent.scoped('{', '}', () { - const String resultName = 'pigeonResult'; - indent.writeln('$className *$resultName = [[$className alloc] init];'); - enumerate(getFieldsInSerializationOrder(klass), - (int index, final NamedType field) { - if (customEnumNames.contains(field.type.baseName)) { - indent.writeln( - '$resultName.${field.name} = [${_listGetter(customClassNames, 'list', field, index, options.prefix)} integerValue];'); - } else { - indent.writeln( - '$resultName.${field.name} = ${_listGetter(customClassNames, 'list', field, index, options.prefix)};'); - if (!field.type.isNullable) { - indent.writeln('NSAssert($resultName.${field.name} != nil, @"");'); - } - } - }); - indent.writeln('return $resultName;'); - }); - - indent.writeln( - '+ (nullable $className *)nullableFromList:(NSArray *)list { return (list) ? [$className fromList:list] : nil; }'); -} - -void _writeClassEncode( - ObjcOptions options, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - String className, -) { - indent.write('- (NSArray *)toList '); - indent.scoped('{', '}', () { - indent.write('return'); - indent.scoped(' @[', '];', () { - for (final NamedType field in klass.fields) { - indent.writeln( - '${_arrayValue(customClassNames, customEnumNames, field)},'); - } - }); - }); -} - /// Generates the ".m" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateObjcSource( From 9664a066c47ce2548cac349a13ce2daa573724da Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 13:00:43 -0800 Subject: [PATCH 55/87] Creates writeHeader method on Generator classes --- packages/pigeon/CHANGELOG.md | 4 + packages/pigeon/lib/cpp_generator.dart | 56 +- packages/pigeon/lib/dart_generator.dart | 75 +- packages/pigeon/lib/generator.dart | 22 +- packages/pigeon/lib/generator_tools.dart | 4 +- packages/pigeon/lib/java_generator.dart | 40 +- packages/pigeon/lib/kotlin_generator.dart | 44 +- packages/pigeon/lib/objc_generator.dart | 76 +- packages/pigeon/lib/pigeon_lib.dart | 6 +- packages/pigeon/lib/swift_generator.dart | 39 +- .../mock_handler_tester/test/message.dart | 3 +- .../pigeon/mock_handler_tester/test/test.dart | 2 +- .../CoreTests.java | 2 +- .../ios/Classes/CoreTests.gen.h | 3 +- .../ios/Classes/CoreTests.gen.m | 3 +- .../lib/core_tests.gen.dart | 3 +- .../lib/multiple_arity.gen.dart | 3 +- .../lib/non_null_fields.gen.dart | 3 +- .../lib/null_fields.gen.dart | 3 +- .../lib/null_safe_pigeon.dart | 3 +- .../lib/nullable_returns.gen.dart | 3 +- .../lib/primitive.dart | 3 +- .../lib/src/generated/core_tests.gen.dart | 3 +- .../com/example/test_plugin/CoreTests.gen.kt | 2 +- .../ios/Classes/CoreTests.gen.swift | 2 +- .../macos/Classes/CoreTests.gen.swift | 2 +- .../windows/pigeon/core_tests.gen.cpp | 2 +- .../windows/pigeon/core_tests.gen.h | 8 +- packages/pigeon/pubspec.yaml | 2 +- packages/pigeon/test/cpp_generator_test.dart | 222 +++++- packages/pigeon/test/dart_generator_test.dart | 148 ++-- packages/pigeon/test/java_generator_test.dart | 117 ++- .../pigeon/test/kotlin_generator_test.dart | 99 ++- packages/pigeon/test/objc_generator_test.dart | 749 +++++++++++++----- packages/pigeon/test/pigeon_lib_test.dart | 4 +- .../pigeon/test/swift_generator_test.dart | 99 ++- 36 files changed, 1323 insertions(+), 536 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 2af203239b6..394a84a7f80 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.0.1 + +* Adds writeHeaders method to Generator classes and updates tests to use new Generators. + ## 5.0.0 * Creates new Generator classes for each language. diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index cddefacfc79..82fb8bf62b7 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -75,16 +75,33 @@ class CppGenerator extends Generator> { /// Instantiates a Cpp Generator. CppGenerator(); - /// Generates Cpp files with specified [OutputFileOptions] + /// Generates Cpp header files with specified [CppOptions] @override - void generate(OutputFileOptions languageOptions, Root root, + void generate(OutputFileOptions generatorOptions, Root root, StringSink sink) { - final FileType fileType = languageOptions.fileType; + final FileType fileType = generatorOptions.fileType; assert(fileType == FileType.header || fileType == FileType.source); + + final Indent indent = Indent(sink); if (fileType == FileType.header) { - generateCppHeader(languageOptions.languageOptions, root, sink); + writeFileHeaders(generatorOptions, root, sink, indent); + generateCppHeader(generatorOptions.languageOptions, root, sink, indent); } else { - generateCppSource(languageOptions.languageOptions, root, sink); + writeFileHeaders(generatorOptions, root, sink, indent); + generateCppSource(generatorOptions.languageOptions, root, sink, indent); + } + } + + @override + void writeFileHeaders(OutputFileOptions generatorOptions, + Root root, StringSink sink, Indent indent) { + final FileType fileType = generatorOptions.fileType; + if (fileType == FileType.header) { + writeCppHeaderHeader( + generatorOptions.languageOptions, root, sink, indent); + } else { + writeCppSourceHeader( + generatorOptions.languageOptions, root, sink, indent); } } } @@ -1049,18 +1066,23 @@ void _writeSystemHeaderIncludeBlock(Indent indent, List headers) { } } -/// Generates the ".h" file for the AST represented by [root] to [sink] with the -/// provided [options] and [headerFileName]. -void generateCppHeader(CppOptions options, Root root, StringSink sink) { - final String? headerFileName = options.headerOutPath; - final Indent indent = Indent(sink); +/// Writes Cpp header file header to sink. +void writeCppHeaderHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); } indent.writeln('$_commentPrefix $generatedCodeWarning'); indent.writeln('$_commentPrefix $seeAlsoWarning'); indent.addln(''); - final String guardName = _getGuardName(headerFileName, options.namespace); +} + +/// Generates the ".h" file for the AST represented by [root] to [sink] with the +/// provided [options] and [headerFileName]. +void generateCppHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { + final String guardName = + _getGuardName(options.headerIncludePath, options.namespace); indent.writeln('#ifndef $guardName'); indent.writeln('#define $guardName'); @@ -1140,10 +1162,9 @@ void generateCppHeader(CppOptions options, Root root, StringSink sink) { indent.writeln('#endif // $guardName'); } -/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateCppSource(CppOptions options, Root root, StringSink sink) { - final Indent indent = Indent(sink); +/// Writes Cpp source file header to sink. +void writeCppSourceHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); } @@ -1152,7 +1173,12 @@ void generateCppSource(CppOptions options, Root root, StringSink sink) { indent.addln(''); indent.addln('#undef _HAS_EXCEPTIONS'); indent.addln(''); +} +/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the +/// provided [options]. +void generateCppSource( + CppOptions options, Root root, StringSink sink, Indent indent) { indent.writeln('#include "${options.headerIncludePath}"'); indent.addln(''); _writeSystemHeaderIncludeBlock(indent, [ diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index e6f685052f1..daf4171754b 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -77,20 +77,30 @@ class DartGenerator extends Generator { /// Generates Dart files with specified [DartOptions] @override - void generate(DartOptions languageOptions, Root root, StringSink sink, - {FileType fileType = FileType.na}) { - assert(fileType == FileType.na); - generateDart(languageOptions, root, sink); + void generate(DartOptions generatorOptions, Root root, StringSink sink) { + final Indent indent = Indent(sink); + + writeFileHeaders(generatorOptions, root, sink, indent); + generateDart(generatorOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + DartOptions generatorOptions, Root root, StringSink sink, Indent indent) { + writeHeader(generatorOptions, root, sink, indent); } /// Generates Dart files for testing with specified [DartOptions] void generateTest(DartOptions languageOptions, Root root, StringSink sink) { + final Indent indent = Indent(sink); final String sourceOutPath = languageOptions.sourceOutPath ?? ''; final String testOutPath = languageOptions.testOutPath ?? ''; + writeTestHeader(languageOptions, root, sink, indent); generateTestDart( languageOptions, root, sink, + indent, sourceOutPath: sourceOutPath, testOutPath: testOutPath, ); @@ -501,25 +511,26 @@ String _addGenericTypesNullable(TypeDeclaration type) { return type.isNullable ? '$genericdType?' : genericdType; } +/// Writes file header to sink. +void writeHeader(DartOptions opt, Root root, StringSink sink, Indent indent) { + if (opt.copyrightHeader != null) { + addLines(indent, opt.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.writeln( + '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import', + ); + indent.addln(''); +} + /// Generates Dart source code for the given AST represented by [root], /// outputting the code to [sink]. -void generateDart(DartOptions opt, Root root, StringSink sink) { +void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) { final List customClassNames = root.classes.map((Class x) => x.name).toList(); final List customEnumNames = root.enums.map((Enum x) => x.name).toList(); - final Indent indent = Indent(sink); - - void writeHeader() { - if (opt.copyrightHeader != null) { - addLines(indent, opt.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.writeln( - '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import', - ); - } void writeEnums() { for (final Enum anEnum in root.enums) { @@ -678,7 +689,6 @@ $resultAt != null } } - writeHeader(); writeImports(); writeEnums(); for (final Class klass in root.classes) { @@ -740,18 +750,9 @@ String _posixify(String inputPath) { return context.fromUri(path.toUri(path.absolute(inputPath))); } -/// Generates Dart source code for test support libraries based on the given AST -/// represented by [root], outputting the code to [sink]. [sourceOutPath] is the -/// path of the generated dart code to be tested. [testOutPath] is where the -/// test code will be generated. -void generateTestDart( - DartOptions opt, - Root root, - StringSink sink, { - required String sourceOutPath, - required String testOutPath, -}) { - final Indent indent = Indent(sink); +/// Writes file header to sink. +void writeTestHeader( + DartOptions opt, Root root, StringSink sink, Indent indent) { if (opt.copyrightHeader != null) { addLines(indent, opt.copyrightHeader!, linePrefix: '// '); } @@ -761,6 +762,20 @@ void generateTestDart( '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import', ); indent.writeln('// ignore_for_file: avoid_relative_lib_imports'); +} + +/// Generates Dart source code for test support libraries based on the given AST +/// represented by [root], outputting the code to [sink]. [dartOutPath] is the +/// path of the generated dart code to be tested. [testOutPath] is where the +/// test code will be generated. +void generateTestDart( + DartOptions opt, + Root root, + StringSink sink, + Indent indent, { + required String sourceOutPath, + required String testOutPath, +}) { indent.writeln("import 'dart:async';"); indent.writeln( "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 02667e4a5c9..473e1a3e46f 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -3,11 +3,29 @@ // found in the LICENSE file. import 'ast.dart'; +import 'generator_tools.dart'; /// A superclass of generator classes. /// /// This provides the structure that is common across generators for different languages. abstract class Generator { - /// Generates files for specified language with specified [languageOptions] - void generate(T languageOptions, Root root, StringSink sink); + /// Generates files for specified language with specified [generatorOptions] + /// + /// This method, when overridden, should follow a generic structure that is currently: + /// 1. Create Indent + /// 2. Write File Headers + /// 3. Generate File + void generate( + T generatorOptions, + Root root, + StringSink sink, + ); + + /// Adds specified file headers. + void writeFileHeaders( + T generatorOptions, + Root root, + StringSink sink, + Indent indent, + ); } diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index b1ee06b01e8..577bf8216de 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '5.0.0'; +const String pigeonVersion = '5.0.1'; /// Read all the content from [stdin] to a String. String readStdin() { @@ -510,7 +510,7 @@ enum FileType { na, } -/// Options for [Generator]'s that have multiple output file types. +/// Options for [Generator]s that have multiple output file types. /// /// Specifies which file to write as well as wraps all language options. class OutputFileOptions { diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index daca63876d2..6a18fba04aa 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -92,10 +92,17 @@ class JavaGenerator extends Generator { /// Generates Java files with specified [JavaOptions] @override - void generate(JavaOptions languageOptions, Root root, StringSink sink, - {FileType fileType = FileType.na}) { - assert(fileType == FileType.na); - generateJava(languageOptions, root, sink); + void generate(JavaOptions generatorOptions, Root root, StringSink sink) { + final Indent indent = Indent(sink); + + writeFileHeaders(generatorOptions, root, sink, indent); + generateJava(generatorOptions, root, sink, indent); + } + + @override + void writeFileHeaders( + JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + writeHeader(generatorOptions, root, sink, indent); } } @@ -536,22 +543,25 @@ String _castObject( } } +/// Writes file header to sink. +void writeHeader( + JavaOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); +} + /// Generates the ".java" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateJava(JavaOptions options, Root root, StringSink sink) { +void generateJava( + JavaOptions options, Root root, StringSink sink, Indent indent) { final Set rootClassNameSet = root.classes.map((Class x) => x.name).toSet(); final Set rootEnumNameSet = root.enums.map((Enum x) => x.name).toSet(); - final Indent indent = Indent(sink); - - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - } void writeImports() { indent.writeln('import android.util.Log;'); @@ -766,8 +776,6 @@ void generateJava(JavaOptions options, Root root, StringSink sink) { }'''); } - writeHeader(); - indent.addln(''); if (options.package != null) { indent.writeln('package ${options.package};'); } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 18e08c7398a..eed3e6da387 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -72,10 +72,21 @@ class KotlinGenerator extends Generator { /// Generates Kotlin files with specified [KotlinOptions] @override - void generate(KotlinOptions languageOptions, Root root, StringSink sink, - {FileType fileType = FileType.na}) { - assert(fileType == FileType.na); - generateKotlin(languageOptions, root, sink); + void generate( + KotlinOptions generatorOptions, + Root root, + StringSink sink, + ) { + final Indent indent = Indent(sink); + + writeFileHeaders(generatorOptions, root, sink, indent); + generateKotlin(generatorOptions, root, sink, indent); + } + + @override + void writeFileHeaders(KotlinOptions generatorOptions, Root root, + StringSink sink, Indent indent) { + writeHeader(generatorOptions, root, sink, indent); } } @@ -449,28 +460,31 @@ String _nullsafeKotlinTypeForDartType(TypeDeclaration type) { return '${_kotlinTypeForDartType(type)}$nullSafe'; } +/// Writes file header to sink. +void writeHeader( + KotlinOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); +} + /// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateKotlin(KotlinOptions options, Root root, StringSink sink) { +void generateKotlin( + KotlinOptions options, Root root, StringSink sink, Indent indent) { final Set rootClassNameSet = root.classes.map((Class x) => x.name).toSet(); final Set rootEnumNameSet = root.enums.map((Enum x) => x.name).toSet(); - final Indent indent = Indent(sink); HostDatatype getHostDatatype(NamedType field) { return getFieldHostDatatype(field, root.classes, root.enums, (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); } - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - } - void writeImports() { indent.writeln('import android.util.Log'); indent.writeln('import io.flutter.plugin.common.BasicMessageChannel'); @@ -665,8 +679,6 @@ void generateKotlin(KotlinOptions options, Root root, StringSink sink) { }); } - writeHeader(); - indent.addln(''); if (options.package != null) { indent.writeln('package ${options.package}'); } diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 3d7e3a64da2..33922019d2c 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -69,17 +69,32 @@ class ObjcGenerator extends Generator> { /// Instantiates a Objc Generator. ObjcGenerator(); - /// Generates Objc files with specified [OutputFileOptions] + /// Generates Objc header files with specified [ObjcOptions] @override - void generate(OutputFileOptions languageOptions, Root root, + void generate(OutputFileOptions generatorOptions, Root root, StringSink sink) { - final FileType fileType = languageOptions.fileType; - assert(fileType == FileType.header || fileType == FileType.source); + final FileType fileType = generatorOptions.fileType; + final Indent indent = Indent(sink); if (fileType == FileType.header) { - generateObjcHeader(languageOptions.languageOptions, root, sink); + writeFileHeaders(generatorOptions, root, sink, indent); + generateObjcHeader(generatorOptions.languageOptions, root, sink, indent); } else { - generateObjcSource(languageOptions.languageOptions, root, sink); + writeFileHeaders(generatorOptions, root, sink, indent); + generateObjcSource(generatorOptions.languageOptions, root, sink, indent); + } + } + + @override + void writeFileHeaders(OutputFileOptions generatorOptions, + Root root, StringSink sink, Indent indent) { + final FileType fileType = generatorOptions.fileType; + if (fileType == FileType.header) { + writeObjcHeaderHeader( + generatorOptions.languageOptions, root, sink, indent); + } else { + writeObjcSourceHeader( + generatorOptions.languageOptions, root, sink, indent); } } } @@ -551,19 +566,21 @@ void _writeFlutterApiDeclaration( indent.writeln('@end'); } -/// Generates the ".h" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateObjcHeader(ObjcOptions options, Root root, StringSink sink) { - final Indent indent = Indent(sink); - - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); +/// Writes Objc header file header to sink. +void writeObjcHeaderHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); +} +/// Generates the ".h" file for the AST represented by [root] to [sink] with the +/// provided [options]. +void generateObjcHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { void writeImports() { indent.writeln('#import '); } @@ -592,7 +609,6 @@ void generateObjcHeader(ObjcOptions options, Root root, StringSink sink) { }); } - writeHeader(); writeImports(); writeForwardDeclarations(); indent.writeln(''); @@ -894,22 +910,25 @@ void _writeFlutterApiSource( indent.writeln('@end'); } +/// Writes Objc Source file header to sink. +void writeObjcSourceHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); +} + /// Generates the ".m" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateObjcSource(ObjcOptions options, Root root, StringSink sink) { - final Indent indent = Indent(sink); +void generateObjcSource( + ObjcOptions options, Root root, StringSink sink, Indent indent) { final List classNames = root.classes.map((Class x) => x.name).toList(); final List enumNames = root.enums.map((Enum x) => x.name).toList(); - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - } - void writeImports() { indent.writeln('#import "${options.headerIncludePath}"'); indent.writeln('#import '); @@ -1026,7 +1045,6 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { } } - writeHeader(); writeImports(); indent.writeln(''); writeArcEnforcer(); diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 5082dd19e8e..40f3fee3048 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -456,11 +456,7 @@ class DartTestGeneratorAdapter implements GeneratorAdapter { testOutPath: options.dartTestOut, ); final DartGenerator testGenerator = DartGenerator(); - testGenerator.generateTest( - dartOptionsWithHeader, - root, - sink, - ); + testGenerator.generateTest(dartOptionsWithHeader, root, sink); } @override diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 77fff7e2fac..44532e91f15 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -55,10 +55,16 @@ class SwiftGenerator extends Generator { /// Generates Swift files with specified [SwiftOptions] @override - void generate(SwiftOptions languageOptions, Root root, StringSink sink, - {FileType fileType = FileType.na}) { - assert(fileType == FileType.na); - generateSwift(languageOptions, root, sink); + void generate(SwiftOptions generatorOptions, Root root, StringSink sink) { + final Indent indent = Indent(sink); + writeFileHeaders(generatorOptions, root, sink, indent); + generateSwift(generatorOptions, root, sink, indent); + } + + @override + void writeFileHeaders(SwiftOptions generatorOptions, Root root, + StringSink sink, Indent indent) { + writeHeader(generatorOptions, root, sink, indent); } } @@ -447,28 +453,31 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { return '${_swiftTypeForDartType(type)}$nullSafe'; } +/// Writes file header to sink. +void writeHeader( + SwiftOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); +} + /// Generates the ".swift" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateSwift(SwiftOptions options, Root root, StringSink sink) { +void generateSwift( + SwiftOptions options, Root root, StringSink sink, Indent indent) { final Set rootClassNameSet = root.classes.map((Class x) => x.name).toSet(); final Set rootEnumNameSet = root.enums.map((Enum x) => x.name).toSet(); - final Indent indent = Indent(sink); HostDatatype getHostDatatype(NamedType field) { return getFieldHostDatatype(field, root.classes, root.enums, (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); } - void writeHeader() { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - } - void writeImports() { indent.writeln('import Foundation'); indent.format(''' @@ -637,8 +646,6 @@ import FlutterMacOS }); } - writeHeader(); - indent.addln(''); writeImports(); indent.addln(''); indent.writeln('$_docCommentPrefix Generated class from Pigeon.'); diff --git a/packages/pigeon/mock_handler_tester/test/message.dart b/packages/pigeon/mock_handler_tester/test/message.dart index 4f6c9d14457..94024e73bc7 100644 --- a/packages/pigeon/mock_handler_tester/test/message.dart +++ b/packages/pigeon/mock_handler_tester/test/message.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/mock_handler_tester/test/test.dart b/packages/pigeon/mock_handler_tester/test/test.dart index 9b97826b605..e1644f13686 100644 --- a/packages/pigeon/mock_handler_tester/test/test.dart +++ b/packages/pigeon/mock_handler_tester/test/test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, unnecessary_import // ignore_for_file: avoid_relative_lib_imports diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index 95b0e2a9509..ea8e343c37f 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon package com.example.alternate_language_test_plugin; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index 1def5e7af69..5a0de3c68c9 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon + #import @protocol FlutterBinaryMessenger; @protocol FlutterMessageCodec; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index 244b1e236c5..2ed0bd7d9e4 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon + #import "CoreTests.gen.h" #import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart index fe0fe3335ea..c9dee303f5d 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart index e92ab29cebd..4bed42b32dd 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart index 1ff71bfa346..5d4cbd0096e 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart index 88f4611e746..0d151dc54e4 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart index 13fe926bcf1..820749f7bef 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart index be1979c8adf..a050c155e05 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart index 36a569e4f46..a5e4e6b318f 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index fe0fe3335ea..c9dee303f5d 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + import 'dart:async'; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index 61a957c8b55..17d7e9ffeb9 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon package com.example.test_plugin diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index 844e541a562..bcf93bcfcc8 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index 844e541a562..bcf93bcfcc8 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp index 110c75e358d..ea282cff0b6 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index 527a0ff45c8..be5c851721c 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.0), do not edit directly. +// Autogenerated from Pigeon (v5.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon -#ifndef PIGEON_CORE_TESTS_PIGEONTEST_H_ -#define PIGEON_CORE_TESTS_PIGEONTEST_H_ +#ifndef PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ +#define PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ #include #include #include @@ -412,4 +412,4 @@ class HostTrivialApi { HostTrivialApi() = default; }; } // namespace core_tests_pigeontest -#endif // PIGEON_CORE_TESTS_PIGEONTEST_H_ +#endif // PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index e4ada89edd1..f2a5a9a6639 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 5.0.0 # This must match the version in lib/generator_tools.dart +version: 5.0.1 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index 172ce2ea3fe..bbed3a40c88 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -4,6 +4,7 @@ import 'package:pigeon/ast.dart'; import 'package:pigeon/cpp_generator.dart'; +import 'package:pigeon/generator_tools.dart'; import 'package:pigeon/pigeon.dart' show Error; import 'package:test/test.dart'; @@ -45,7 +46,13 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Input')); expect(code, contains('class Output')); @@ -53,7 +60,13 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('Input::Input()')); expect(code, contains('Output::Output')); @@ -101,7 +114,13 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); // Method name and argument names should be adjusted. expect(code, contains(' DoSomething(const Input& some_input)')); @@ -116,7 +135,13 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('pointer_input_field')); expect(code, contains('Output::output_field()')); @@ -144,7 +169,17 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate( + generatorOptions, + root, + sink, + ); final String code = sink.toString(); expect( @@ -184,7 +219,13 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( @@ -238,14 +279,26 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains('){'))); expect(code, isNot(contains('const{'))); } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains('){'))); expect(code, isNot(contains('const{'))); @@ -271,7 +324,13 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains(''' #include @@ -286,8 +345,13 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource( - const CppOptions(headerIncludePath: 'a_header.h'), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(headerIncludePath: 'a_header.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains(''' #include "a_header.h" @@ -323,14 +387,26 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(namespace: 'foo'), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(namespace: 'foo'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('namespace foo {')); expect(code, contains('} // namespace foo')); } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(namespace: 'foo'), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(namespace: 'foo'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('namespace foo {')); expect(code, contains('} // namespace foo')); @@ -391,7 +467,13 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); // Getters should return const pointers. expect(code, contains('const bool* nullable_bool()')); @@ -423,7 +505,13 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); // Getters extract optionals. expect(code, @@ -522,7 +610,13 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); // POD getters should return copies references. expect(code, contains('bool non_nullable_bool()')); @@ -547,7 +641,13 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); // Getters just return the value. expect(code, contains('return non_nullable_bool_;')); @@ -645,7 +745,13 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, contains('ErrorOr> ReturnNullableBool()')); @@ -750,7 +856,13 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('ErrorOr ReturnBool()')); expect(code, contains('ErrorOr ReturnInt()')); @@ -832,7 +944,13 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -846,7 +964,13 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); // Most types should just use get_if, since the parameter is a pointer, // and get_if will automatically handle null values (since a null @@ -963,7 +1087,13 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -977,7 +1107,13 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); // Most types should extract references. Since the type is non-nullable, // there's only one possible type. @@ -1037,7 +1173,13 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); // A bare 'auto' here would create a copy, not a reference, which is // ineffecient. @@ -1149,7 +1291,13 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(headerIncludePath: 'foo'), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(headerIncludePath: 'foo'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('//$comment')); @@ -1184,7 +1332,13 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : public flutter::StandardCodecSerializer'))); }); @@ -1226,7 +1380,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateCppHeader(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains(' : public flutter::StandardCodecSerializer')); }); @@ -1295,7 +1455,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateCppSource(const CppOptions(), root, sink); + final CppGenerator generator = CppGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const CppOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains('reply(wrap'))); expect(code, contains('reply(flutter::EncodableValue(')); diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index c77e5d89e37..15ce9e09ac4 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -29,7 +29,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' dataType1? field1;')); @@ -49,7 +50,8 @@ void main() { enums: [anEnum], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum Foobar')); expect(code, contains(' one,')); @@ -92,7 +94,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('Future doSomething(Input arg_input)')); @@ -118,7 +121,8 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('Future add(int arg_x, int arg_y)')); @@ -145,7 +149,8 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('int add(int x, int y)')); @@ -182,7 +187,8 @@ void main() { ) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -224,7 +230,8 @@ void main() { ) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -276,7 +283,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('abstract class Api')); expect(code, contains('static void setup(Api')); @@ -310,7 +318,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doSomething')); expect(code, contains('return;')); @@ -343,7 +352,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); // The next line verifies that we're not setting a variable to the value of "doSomething", but // ignores the line where we assert the value of the argument isn't null, since on that line @@ -373,7 +383,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('output.*=.*doSomething[(][)]')); expect(code, contains('Output doSomething();')); @@ -415,7 +426,8 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum1?.index,')); expect(code, contains('? Enum.values[result[0]! as int]')); @@ -442,7 +454,8 @@ void main() { ]) ]); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum Foo {')); expect(code, contains('Future bar(Foo? arg_foo) async')); @@ -485,7 +498,8 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum1.index,')); expect(code, contains('enum1: Enum.values[result[0]! as int]')); @@ -512,7 +526,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('channel.send[(]null[)]')); }); @@ -570,7 +585,8 @@ void main() { ], enums: []); final StringBuffer mainCodeSink = StringBuffer(); final StringBuffer testCodeSink = StringBuffer(); - generateDart(DartOptions(), root, mainCodeSink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, mainCodeSink); final String mainCode = mainCodeSink.toString(); expect(mainCode, isNot(contains(r"import 'fo\'o.dart';"))); expect(mainCode, contains('class Api {')); @@ -578,12 +594,15 @@ void main() { expect(mainCode, isNot(contains('.ApiMock.doSomething'))); expect(mainCode, isNot(contains("'${Keys.result}': output"))); expect(mainCode, isNot(contains('return [];'))); - generateTestDart( - DartOptions(), + + final DartGenerator testGenerator = DartGenerator(); + testGenerator.generateTest( + DartOptions( + sourceOutPath: "fo'o.dart", + testOutPath: 'test.dart', + ), root, testCodeSink, - sourceOutPath: "fo'o.dart", - testOutPath: 'test.dart', ); final String testCode = testCodeSink.toString(); expect(testCode, contains(r"import 'fo\'o.dart';")); @@ -631,7 +650,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('abstract class Api')); expect(code, contains('Future doSomething(Input arg0);')); @@ -675,7 +695,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.s*doSomething'))); expect(code, contains('await api.doSomething(')); @@ -719,7 +740,8 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, matches('Output.*doSomething.*Input')); @@ -747,7 +769,8 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('channel.send[(]null[)]')); }); @@ -759,7 +782,9 @@ void main() { test('header', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateDart( + + final DartGenerator generator = DartGenerator(); + generator.generate( DartOptions(copyrightHeader: makeIterable('hello world')), root, sink, @@ -788,7 +813,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' List? field1;')); @@ -815,7 +841,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains(' Map? field1;')); @@ -844,7 +871,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doit(List arg')); }); @@ -872,7 +900,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doit(List arg')); }); @@ -896,7 +925,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future> doit(')); expect(code, @@ -931,7 +961,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('List doit(')); expect( @@ -958,7 +989,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit()')); expect(code, contains('return (replyList[0] as int?);')); @@ -983,7 +1015,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future?> doit()')); expect(code, @@ -1008,7 +1041,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit()')); expect(code, contains('return (replyList[0] as int?);')); @@ -1031,7 +1065,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('int? doit();')); expect(code, contains('final int? output = api.doit();')); @@ -1055,7 +1090,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit();')); expect(code, contains('final int? output = await api.doit();')); @@ -1078,7 +1114,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( code, @@ -1107,7 +1144,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit(int? arg_foo) async {')); }); @@ -1133,7 +1171,8 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('void doit(int? foo);')); }); @@ -1150,12 +1189,14 @@ name: foobar final Root root = Root(classes: [], apis: [], enums: []); final StringBuffer sink = StringBuffer(); - generateTestDart( - DartOptions(), + final DartGenerator testGenerator = DartGenerator(); + testGenerator.generateTest( + DartOptions( + sourceOutPath: path.join(foo.path, 'bar.dart'), + testOutPath: path.join(tempDir.path, 'test', 'bar_test.dart'), + ), root, sink, - sourceOutPath: path.join(foo.path, 'bar.dart'), - testOutPath: path.join(tempDir.path, 'test', 'bar_test.dart'), ); final String code = sink.toString(); expect(code, contains("import 'package:foobar/foo/bar.dart';")); @@ -1238,7 +1279,8 @@ name: foobar ], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('///$comment')); @@ -1273,7 +1315,8 @@ name: foobar enums: [], ); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('extends StandardMessageCodec'))); expect(code, contains('StandardMessageCodec')); @@ -1316,7 +1359,8 @@ name: foobar ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateDart(DartOptions(), root, sink); + final DartGenerator generator = DartGenerator(); + generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('extends StandardMessageCodec')); }); @@ -1354,13 +1398,17 @@ name: foobar ], ); final StringBuffer sink = StringBuffer(); - generateTestDart( - DartOptions(), + + final DartGenerator testGenerator = DartGenerator(); + testGenerator.generateTest( + DartOptions( + sourceOutPath: 'code.dart', + testOutPath: 'test.dart', + ), root, sink, - sourceOutPath: 'code.dart', - testOutPath: 'test.dart', ); + final String testCode = sink.toString(); expect( testCode, diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index bfcea98cfe2..f2a25288754 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -27,7 +27,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public class Messages')); expect(code, contains('public static class Foobar')); @@ -55,7 +56,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Foobar')); expect(code, contains(' ONE(0),')); @@ -86,7 +88,8 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages', package: 'com.google.foobar'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('package com.google.foobar;')); expect(code, contains('ArrayList toList()')); @@ -129,7 +132,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public interface Api')); expect(code, matches('Output.*doSomething.*Input')); @@ -200,7 +204,8 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('private @Nullable Boolean aBool;')); expect(code, contains('private @Nullable Long aInt;')); @@ -249,7 +254,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Api')); expect(code, matches('doSomething.*Input.*Output')); @@ -283,7 +289,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.*doSomething'))); expect(code, contains('doSomething(')); @@ -317,7 +324,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Reply')); expect(code, contains('callback.reply(null)')); @@ -345,7 +353,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Output doSomething()')); expect(code, contains('api.doSomething()')); @@ -373,7 +382,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doSomething(Reply')); expect(code, contains('channel.send(null')); @@ -392,7 +402,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Foobar')); expect(code, contains('private @Nullable List field1;')); @@ -411,7 +422,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Foobar')); expect(code, contains('private @Nullable Map field1;')); @@ -447,7 +459,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public class Messages')); expect(code, contains('public static class Outer')); @@ -498,7 +511,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public interface Api')); expect(code, contains('public interface Result {')); @@ -549,7 +563,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Api')); expect(code, matches('doSomething.*Input.*Output')); @@ -582,7 +597,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Enum1')); expect(code, contains(' ONE(0),')); @@ -621,7 +637,8 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Foo')); expect( @@ -641,7 +658,8 @@ void main() { className: 'Messages', copyrightHeader: makeIterable('hello world'), ); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -667,7 +685,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains('List field1;')); @@ -695,7 +714,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); expect(code, contains('Map field1;')); @@ -725,7 +745,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(@NonNull List arg')); }); @@ -754,7 +775,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(@NonNull List arg')); }); @@ -779,7 +801,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('List doit(')); expect(code, contains('List output =')); @@ -805,7 +828,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(Reply> callback)')); expect(code, contains('List output =')); @@ -828,7 +852,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(Reply callback)')); expect( @@ -858,7 +883,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Messages')); expect(code, contains('Long add(@NonNull Long x, @NonNull Long y)')); @@ -889,7 +915,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Api'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Object xArg = args.get(0)')); }); @@ -915,7 +942,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Messages')); expect(code, contains('BasicMessageChannel channel')); @@ -947,7 +975,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( code, @@ -973,7 +1002,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('@Nullable Long doit();')); }); @@ -997,7 +1027,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); // Java doesn't accept nullability annotations in type arguments. expect(code, contains('Result')); @@ -1025,7 +1056,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains(' void doit(@Nullable Long foo);')); }); @@ -1052,7 +1084,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1083,7 +1116,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1108,7 +1142,8 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages', useGeneratedAnnotation: true); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('@javax.annotation.Generated("dev.flutter.pigeon")')); }); @@ -1125,7 +1160,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains('@javax.annotation.Generated("dev.flutter.pigeon")'))); @@ -1207,7 +1243,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { // This regex finds the comment only between the open and close comment block @@ -1247,7 +1284,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(' extends StandardMessageCodec'))); expect(code, contains('StandardMessageCodec')); @@ -1291,7 +1329,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - generateJava(javaOptions, root, sink); + final JavaGenerator generator = JavaGenerator(); + generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains(' extends StandardMessageCodec')); }); diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 4653410837e..96056c1b1b1 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -27,7 +27,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar (')); expect(code, contains('val field1: Long? = null')); @@ -50,7 +51,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Foobar(val raw: Int) {')); expect(code, contains('ONE(0)')); @@ -78,7 +80,8 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Foo(val raw: Int) {')); expect(code, contains('val fooArg = Foo.ofRaw(args[0] as Int)')); @@ -124,7 +127,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('interface Api')); expect(code, contains('fun doSomething(input: Input): Output')); @@ -213,7 +217,8 @@ void main() { final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val aBool: Boolean? = null')); expect(code, contains('val aInt: Long? = null')); @@ -265,7 +270,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api(private val binaryMessenger: BinaryMessenger)')); @@ -302,7 +308,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('.*doSomething(.*) ->'))); expect(code, matches('doSomething(.*)')); @@ -338,7 +345,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('callback: () -> Unit')); expect(code, contains('callback()')); @@ -367,7 +375,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doSomething(): Output')); expect(code, contains('wrapped = listOf(api.doSomething())')); @@ -398,7 +407,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doSomething(callback: (Output) -> Unit)')); expect(code, contains('channel.send(null)')); @@ -418,7 +428,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); expect(code, contains('val field1: List? = null')); @@ -438,7 +449,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); expect(code, contains('val field1: Map? = null')); @@ -476,7 +488,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Outer')); expect(code, contains('data class Nested')); @@ -529,7 +542,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('interface Api')); expect(code, contains('api.doSomething(argArg) {')); @@ -577,7 +591,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, matches('fun doSomething.*Input.*callback.*Output.*Unit')); @@ -610,7 +625,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Enum1(val raw: Int)')); expect(code, contains('ONE(0)')); @@ -627,7 +643,8 @@ void main() { final KotlinOptions kotlinOptions = KotlinOptions( copyrightHeader: makeIterable('hello world'), ); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -654,7 +671,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); expect(code, contains('val field1: List')); @@ -683,7 +701,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); expect(code, contains('val field1: Map')); @@ -714,7 +733,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(arg: List')); }); @@ -744,7 +764,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(argArg: List')); }); @@ -769,7 +790,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(): List')); expect(code, contains('wrapped = listOf(api.doit())')); @@ -796,7 +818,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(callback: (List) -> Unit')); expect(code, contains('val result = it as List')); @@ -824,7 +847,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun add(x: Long, y: Long): Long')); expect(code, contains('val args = message as List')); @@ -861,7 +885,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val channel = BasicMessageChannel')); expect(code, contains('val result = it as Long')); @@ -889,7 +914,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(): Long?')); }); @@ -913,7 +939,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(callback: (Long?) -> Unit')); }); @@ -940,7 +967,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect( code, @@ -970,7 +998,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(fooArg: Long?, callback: () -> Unit')); }); @@ -1005,7 +1034,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val input: String\n')); }); @@ -1086,7 +1116,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { // This regex finds the comment only between the open and close comment block @@ -1126,7 +1157,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : StandardMessageCodec() '))); expect(code, contains('StandardMessageCodec')); @@ -1170,7 +1202,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - generateKotlin(kotlinOptions, root, sink); + final KotlinGenerator generator = KotlinGenerator(); + generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains(' : StandardMessageCodec() ')); }); diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index aeb2db68e26..c6b45fd4d43 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:pigeon/ast.dart'; +import 'package:pigeon/generator_tools.dart'; import 'package:pigeon/objc_generator.dart'; import 'package:pigeon/pigeon_lib.dart'; import 'package:test/test.dart'; @@ -17,7 +18,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, matches('@property.*NSString.*field1')); @@ -32,8 +39,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Foobar')); @@ -50,7 +62,13 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, Enum1) {')); expect(code, contains(' Enum1One = 0,')); @@ -68,7 +86,13 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(prefix: 'PREFIX'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(prefix: 'PREFIX'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, PREFIXEnum1) {')); expect(code, contains(' PREFIXEnum1One = 0,')); @@ -104,8 +128,13 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Foobar')); @@ -138,13 +167,25 @@ void main() { const ObjcOptions options = ObjcOptions(headerIncludePath: 'foo.h', prefix: 'AC'); { - generateObjcHeader(options, root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: options, + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('typedef NS_ENUM(NSUInteger, ACFoo)')); expect(code, contains(':(ACFoo)foo error:')); } { - generateObjcSource(options, root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: options, + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -207,8 +248,13 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@property(nonatomic, assign) Enum1 enum1')); }); @@ -240,7 +286,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface Input')); expect(code, contains('@interface Output')); @@ -279,8 +331,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('#import "foo.h"')); expect(code, contains('@implementation Input')); @@ -327,8 +384,13 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, contains('@class FlutterStandardTypedData;')); @@ -356,8 +418,13 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@implementation Foobar')); expect(code, @@ -378,8 +445,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@property(nonatomic, strong, nullable) Input * nested;')); @@ -399,8 +471,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -419,7 +496,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(prefix: 'ABC'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface ABCFoobar')); }); @@ -433,7 +516,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(prefix: 'ABC'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@implementation ABCFoobar')); }); @@ -467,7 +556,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(prefix: 'ABC'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, matches('property.*ABCInput')); expect(code, matches('ABCNested.*doSomething.*ABCInput')); @@ -503,7 +598,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(prefix: 'ABC'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('ABCInput fromList')); expect(code, matches(r'ABCInput.*=.*args.*0.*\;')); @@ -539,8 +640,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface Api : NSObject')); expect( @@ -579,8 +685,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h'), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(headerIncludePath: 'foo.h'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@implementation Api')); expect(code, matches('void.*doSomething.*Input.*Output.*{')); @@ -609,10 +720,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('(void)doSomething:')); }); @@ -640,10 +755,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.*doSomething'))); expect(code, matches('[.*doSomething:.*]')); @@ -673,10 +792,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('completion:(void(^)(NSError *_Nullable))')); }); @@ -704,10 +827,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('completion:(void(^)(NSError *_Nullable))')); expect(code, contains('completion(nil)')); @@ -730,10 +857,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, matches('ABCOutput.*doSomethingWithError:[(]FlutterError')); }); @@ -755,10 +886,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, matches('output.*=.*api doSomethingWithError:&error')); }); @@ -780,10 +915,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -808,10 +947,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -829,7 +972,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, matches('@property.*NSArray.*field1')); @@ -844,7 +993,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, matches('@property.*NSDictionary.*field1')); @@ -865,7 +1020,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect( @@ -894,7 +1055,13 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('(NSDictionary *)foo')); }); @@ -928,10 +1095,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -969,10 +1140,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -998,10 +1173,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1020,10 +1199,14 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1061,10 +1244,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1101,10 +1288,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1123,10 +1314,14 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1152,10 +1347,14 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1170,14 +1369,16 @@ void main() { test('source copyright', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource( - ObjcOptions( + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: ObjcOptions( headerIncludePath: 'foo.h', prefix: 'ABC', copyrightHeader: makeIterable('hello world')), - root, - sink, ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -1185,14 +1386,16 @@ void main() { test('header copyright', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - ObjcOptions( + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: ObjcOptions( headerIncludePath: 'foo.h', prefix: 'ABC', copyrightHeader: makeIterable('hello world')), - root, - sink, ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -1217,10 +1420,14 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('NSArray * field1')); }); @@ -1249,19 +1456,27 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1294,19 +1509,27 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *)arg')); } @@ -1342,10 +1565,14 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('doitArg:(NSArray *> *)arg')); } @@ -1371,20 +1598,28 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, contains('- (nullable NSArray *)doitWithError:')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('NSArray *output =')); } @@ -1410,20 +1645,28 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, contains('doitWithCompletion:(void(^)(NSArray *')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, contains('doitWithCompletion:(void(^)(NSArray *')); @@ -1451,10 +1694,14 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1463,10 +1710,14 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('NSArray *args = message;')); expect(code, @@ -1500,10 +1751,14 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1512,10 +1767,14 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('NSArray *args = message;')); expect(code, @@ -1547,10 +1806,14 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1559,10 +1822,14 @@ void main() { } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - root, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1605,19 +1872,27 @@ void main() { final Root divideRoot = getDivideRoot(ApiLocation.host); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - divideRoot, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, divideRoot, sink); final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*error.*;')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - divideRoot, - sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), + ); + generator.generate(generatorOptions, divideRoot, sink); final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*error.*;')); } @@ -1627,21 +1902,27 @@ void main() { final Root divideRoot = getDivideRoot(ApiLocation.flutter); { final StringBuffer sink = StringBuffer(); - generateObjcHeader( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - divideRoot, - sink, + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), ); + generator.generate(generatorOptions, divideRoot, sink); final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*completion.*;')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource( - const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), - divideRoot, - sink, + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: + const ObjcOptions(headerIncludePath: 'foo.h', prefix: 'ABC'), ); + generator.generate(generatorOptions, divideRoot, sink); final String code = sink.toString(); expect(code, matches('divideValue:.*by:.*completion.*{')); } @@ -1656,7 +1937,13 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('@interface Foobar')); expect(code, contains('@property(nonatomic, copy) NSString * field1')); @@ -1679,7 +1966,13 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1704,7 +1997,13 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, matches(r'doitWithCompletion.*NSNumber \*_Nullable')); }); @@ -1726,7 +2025,13 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, matches(r'nullable NSNumber.*doitWithError')); }); @@ -1753,13 +2058,25 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('doitFoo:(nullable NSNumber *)foo')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('NSNumber *arg_foo = GetNullableObjectAtIndex(args, 0);')); @@ -1788,13 +2105,25 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('doitFoo:(nullable NSNumber *)foo')); } { final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains('- (void)doitFoo:(nullable NSNumber *)arg_foo')); } @@ -1818,7 +2147,13 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect( code, @@ -1902,7 +2237,13 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - generateObjcHeader(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.header, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('///$comment')); @@ -1937,7 +2278,13 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : FlutterStandardReader'))); }); @@ -1979,7 +2326,13 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - generateObjcSource(const ObjcOptions(), root, sink); + final ObjcGenerator generator = ObjcGenerator(); + final OutputFileOptions generatorOptions = + OutputFileOptions( + fileType: FileType.source, + languageOptions: const ObjcOptions(), + ); + generator.generate(generatorOptions, root, sink); final String code = sink.toString(); expect(code, contains(' : FlutterStandardReader')); }); diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 64c4af7b5ab..3d5c706bf41 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -938,10 +938,10 @@ abstract class Api { dartTestOut: 'stdout', dartOut: 'stdout', ); - final DartTestGeneratorAdapter dartGeneratorAdapter = + final DartTestGeneratorAdapter dartTestGeneratorAdapter = DartTestGeneratorAdapter(); final StringBuffer buffer = StringBuffer(); - dartGeneratorAdapter.generate(buffer, options, root, FileType.source); + dartTestGeneratorAdapter.generate(buffer, options, root, FileType.source); expect(buffer.toString(), startsWith('// Copyright 2013')); }); diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index 74c8aad15ca..305ca203fe7 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -26,7 +26,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: Int32? = nil')); @@ -49,7 +50,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Foobar: Int')); expect(code, contains(' case one = 0')); @@ -77,7 +79,8 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Foo: Int')); expect(code, contains('let fooArg = Foo(rawValue: args[0] as! Int)!')); @@ -120,7 +123,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('protocol Api')); expect(code, matches('func doSomething.*Input.*Output')); @@ -183,7 +187,8 @@ void main() { final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('var aBool: Bool? = nil')); expect(code, contains('var aInt: Int32? = nil')); @@ -232,7 +237,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, contains('init(binaryMessenger: FlutterBinaryMessenger)')); @@ -267,7 +273,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('.*doSomething(.*) ->'))); expect(code, matches('doSomething(.*)')); @@ -301,7 +308,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('completion: @escaping () -> Void')); expect(code, contains('completion()')); @@ -329,7 +337,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doSomething() -> Output')); expect(code, contains('let result = api.doSomething()')); @@ -358,7 +367,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doSomething(completion: @escaping (Output) -> Void)')); @@ -378,7 +388,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: [Any?]? = nil')); @@ -397,7 +408,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: [AnyHashable: Any?]? = nil')); @@ -433,7 +445,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Outer')); expect(code, contains('struct Nested')); @@ -481,7 +494,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('protocol Api')); expect(code, contains('api.doSomething(arg: argArg) { result in')); @@ -526,7 +540,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); expect(code, matches('func doSomething.*Input.*completion.*Output.*Void')); @@ -558,7 +573,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Enum1: Int')); expect(code, contains('case one = 0')); @@ -575,7 +591,8 @@ void main() { final SwiftOptions swiftOptions = SwiftOptions( copyrightHeader: makeIterable('hello world'), ); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); }); @@ -601,7 +618,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: [Int32?]')); @@ -629,7 +647,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); expect(code, contains('var field1: [String?: String?]')); @@ -659,7 +678,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(arg: [Int32?]')); }); @@ -688,7 +708,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(arg argArg: [Int32?]')); }); @@ -713,7 +734,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit() -> [Int32?]')); expect(code, contains('let result = api.doit()')); @@ -740,7 +762,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect( code, contains('func doit(completion: @escaping ([Int32?]) -> Void')); @@ -769,7 +792,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func add(x: Int32, y: Int32) -> Int32')); expect(code, contains('let args = message as! [Any?]')); @@ -800,7 +824,8 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('let channel = FlutterBasicMessageChannel')); expect(code, contains('let result = response as! Int32')); @@ -830,7 +855,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit() -> Int32?')); }); @@ -854,7 +880,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(completion: @escaping (Int32?) -> Void')); }); @@ -881,7 +908,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('let fooArg = args[0] as? Int32')); }); @@ -908,7 +936,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect( code, @@ -944,7 +973,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('var input: String\n')); }); @@ -1025,7 +1055,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { expect(code, contains('///$comment')); @@ -1061,7 +1092,8 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(': FlutterStandardReader '))); }); @@ -1104,7 +1136,8 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - generateSwift(swiftOptions, root, sink); + final SwiftGenerator generator = SwiftGenerator(); + generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains(': FlutterStandardReader ')); }); From 45f3d820041e675d37cec8cbe675de5cca1b1fed Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 14:35:31 -0800 Subject: [PATCH 56/87] private unique methods and reorder --- packages/pigeon/lib/cpp_generator.dart | 208 +++++++++++------------ packages/pigeon/lib/objc_generator.dart | 100 +++++------ packages/pigeon/lib/swift_generator.dart | 20 +-- 3 files changed, 164 insertions(+), 164 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 3f94ab2396d..d280cea61c4 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -105,9 +105,9 @@ class CppGenerator extends Generator { void writeHeaders(CppOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { if (fileType == FileType.header) { - writeCppHeaderHeader(languageOptions, root, sink, indent); + _writeCppHeaderHeader(languageOptions, root, sink, indent); } else { - writeCppSourceHeader(languageOptions, root, sink, indent); + _writeCppSourceHeader(languageOptions, root, sink, indent); } } @@ -115,9 +115,9 @@ class CppGenerator extends Generator { void writeImports(CppOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { if (fileType == FileType.header) { - writeCppHeaderImports(languageOptions, root, sink, indent); + _writeCppHeaderImports(languageOptions, root, sink, indent); } else { - writeCppSourceImports(languageOptions, root, sink, indent); + _writeCppSourceImports(languageOptions, root, sink, indent); } } @@ -125,7 +125,7 @@ class CppGenerator extends Generator { void writeEnum(CppOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType, Enum anEnum) { if (fileType == FileType.header) { - writeCppHeaderEnum(languageOptions, root, sink, indent, anEnum); + _writeCppHeaderEnum(languageOptions, root, sink, indent, anEnum); } } @@ -179,6 +179,68 @@ class CppGenerator extends Generator { customClassNames, customEnumNames); } + /// Writes Cpp header file header to sink. + void _writeCppHeaderHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('$_commentPrefix $generatedCodeWarning'); + indent.writeln('$_commentPrefix $seeAlsoWarning'); + indent.addln(''); + } + + /// Writes Cpp header file imports to sink. + void _writeCppHeaderImports( + CppOptions options, Root root, StringSink sink, Indent indent) { + final String guardName = + _getGuardName(options.headerIncludePath, options.namespace); + indent.writeln('#ifndef $guardName'); + indent.writeln('#define $guardName'); + + _writeSystemHeaderIncludeBlock(indent, [ + 'flutter/basic_message_channel.h', + 'flutter/binary_messenger.h', + 'flutter/encodable_value.h', + 'flutter/standard_message_codec.h', + ]); + indent.addln(''); + _writeSystemHeaderIncludeBlock(indent, [ + 'map', + 'string', + 'optional', + ]); + indent.addln(''); + if (options.namespace != null) { + indent.writeln('namespace ${options.namespace} {'); + } + indent.addln(''); + if (options.namespace?.endsWith('_pigeontest') ?? false) { + final String testFixtureClass = + '${_pascalCaseFromSnakeCase(options.namespace!.replaceAll('_pigeontest', ''))}Test'; + indent.writeln('class $testFixtureClass;'); + } + indent.addln(''); + indent.writeln('$_commentPrefix Generated class from Pigeon.'); + } + + /// Writes Cpp header enum to sink. + void _writeCppHeaderEnum(CppOptions options, Root root, StringSink sink, + Indent indent, Enum anEnum) { + indent.writeln(''); + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + indent.write('enum class ${anEnum.name} '); + indent.scoped('{', '};', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + indent.writeln( + '${member.name} = $index${index == anEnum.members.length - 1 ? '' : ','}'); + }); + }); + } + /// Writes the declaration for the custom class [klass]. /// /// See [_writeCppSourceDataClass] for the corresponding declaration. @@ -258,6 +320,43 @@ class CppGenerator extends Generator { indent.writeln(''); } + /// Writes Cpp source file header to sink. + void _writeCppSourceHeader( + CppOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('$_commentPrefix $generatedCodeWarning'); + indent.writeln('$_commentPrefix $seeAlsoWarning'); + indent.addln(''); + indent.addln('#undef _HAS_EXCEPTIONS'); + indent.addln(''); + } + + /// Writes Cpp source file imports to sink. + void _writeCppSourceImports( + CppOptions options, Root root, StringSink sink, Indent indent) { + indent.writeln('#include "${options.headerIncludePath}"'); + indent.addln(''); + _writeSystemHeaderIncludeBlock(indent, [ + 'flutter/basic_message_channel.h', + 'flutter/binary_messenger.h', + 'flutter/encodable_value.h', + 'flutter/standard_message_codec.h', + ]); + indent.addln(''); + _writeSystemHeaderIncludeBlock(indent, [ + 'map', + 'string', + 'optional', + ]); + indent.addln(''); + + if (options.namespace != null) { + indent.writeln('namespace ${options.namespace} {'); + } + } + void _writeCppSourceClassEncode( CppOptions languageOptions, Root root, @@ -438,105 +537,6 @@ else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodabl writeClassDecode(languageOptions, root, sink, indent, fileType, klass, customClassNames, customEnumNames); } - - /// Writes Cpp header file header to sink. - void writeCppHeaderHeader( - CppOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('$_commentPrefix $generatedCodeWarning'); - indent.writeln('$_commentPrefix $seeAlsoWarning'); - indent.addln(''); - } - - /// Writes Cpp header file imports to sink. - void writeCppHeaderImports( - CppOptions options, Root root, StringSink sink, Indent indent) { - final String guardName = - _getGuardName(options.headerIncludePath, options.namespace); - indent.writeln('#ifndef $guardName'); - indent.writeln('#define $guardName'); - - _writeSystemHeaderIncludeBlock(indent, [ - 'flutter/basic_message_channel.h', - 'flutter/binary_messenger.h', - 'flutter/encodable_value.h', - 'flutter/standard_message_codec.h', - ]); - indent.addln(''); - _writeSystemHeaderIncludeBlock(indent, [ - 'map', - 'string', - 'optional', - ]); - indent.addln(''); - if (options.namespace != null) { - indent.writeln('namespace ${options.namespace} {'); - } - indent.addln(''); - if (options.namespace?.endsWith('_pigeontest') ?? false) { - final String testFixtureClass = - '${_pascalCaseFromSnakeCase(options.namespace!.replaceAll('_pigeontest', ''))}Test'; - indent.writeln('class $testFixtureClass;'); - } - indent.addln(''); - indent.writeln('$_commentPrefix Generated class from Pigeon.'); - } - - /// Writes Cpp header enum to sink. - void writeCppHeaderEnum(CppOptions options, Root root, StringSink sink, - Indent indent, Enum anEnum) { - indent.writeln(''); - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - indent.write('enum class ${anEnum.name} '); - indent.scoped('{', '};', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - indent.writeln( - '${member.name} = $index${index == anEnum.members.length - 1 ? '' : ','}'); - }); - }); - } - - /// Writes Cpp source file header to sink. - void writeCppSourceHeader( - CppOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('$_commentPrefix $generatedCodeWarning'); - indent.writeln('$_commentPrefix $seeAlsoWarning'); - indent.addln(''); - indent.addln('#undef _HAS_EXCEPTIONS'); - indent.addln(''); - } - - /// Writes Cpp source file imports to sink. - void writeCppSourceImports( - CppOptions options, Root root, StringSink sink, Indent indent) { - indent.writeln('#include "${options.headerIncludePath}"'); - indent.addln(''); - _writeSystemHeaderIncludeBlock(indent, [ - 'flutter/basic_message_channel.h', - 'flutter/binary_messenger.h', - 'flutter/encodable_value.h', - 'flutter/standard_message_codec.h', - ]); - indent.addln(''); - _writeSystemHeaderIncludeBlock(indent, [ - 'map', - 'string', - 'optional', - ]); - indent.addln(''); - - if (options.namespace != null) { - indent.writeln('namespace ${options.namespace} {'); - } - } } String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 3cf8021c002..ce267e135b3 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -115,9 +115,9 @@ class ObjcGenerator extends Generator { void writeHeaders(ObjcOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { if (fileType == FileType.header) { - writeObjcHeaderHeader(languageOptions, root, sink, indent); + _writeObjcHeaderHeader(languageOptions, root, sink, indent); } else { - writeObjcSourceHeader(languageOptions, root, sink, indent); + _writeObjcSourceHeader(languageOptions, root, sink, indent); } } @@ -125,9 +125,9 @@ class ObjcGenerator extends Generator { void writeImports(ObjcOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType) { if (fileType == FileType.header) { - writeObjcHeaderImports(languageOptions, root, sink, indent); + _writeObjcHeaderImports(languageOptions, root, sink, indent); } else { - writeObjcSourceImports(languageOptions, root, sink, indent); + _writeObjcSourceImports(languageOptions, root, sink, indent); } } @@ -135,7 +135,7 @@ class ObjcGenerator extends Generator { void writeEnum(ObjcOptions languageOptions, Root root, StringSink sink, Indent indent, FileType fileType, Enum anEnum) { if (fileType == FileType.header) { - writeObjcHeaderEnum(languageOptions, root, sink, indent, anEnum); + _writeObjcHeaderEnum(languageOptions, root, sink, indent, anEnum); } } @@ -191,6 +191,49 @@ class ObjcGenerator extends Generator { // Header File Methods. + /// Writes Objc header file header to sink. + void _writeObjcHeaderHeader( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + if (options.copyrightHeader != null) { + addLines(indent, options.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.addln(''); + } + + /// Writes Objc header file imports to sink. + void _writeObjcHeaderImports( + ObjcOptions options, Root root, StringSink sink, Indent indent) { + indent.writeln('#import '); + indent.addln(''); + + indent.writeln('@protocol FlutterBinaryMessenger;'); + indent.writeln('@protocol FlutterMessageCodec;'); + indent.writeln('@class FlutterError;'); + indent.writeln('@class FlutterStandardTypedData;'); + indent.addln(''); + } + + /// Writes single Objc header enum. + void _writeObjcHeaderEnum(ObjcOptions options, Root root, StringSink sink, + Indent indent, Enum anEnum) { + final String enumName = _className(options.prefix, anEnum.name); + addDocumentationComments( + indent, anEnum.documentationComments, _docCommentSpec); + + indent.write('typedef NS_ENUM(NSUInteger, $enumName) '); + indent.scoped('{', '};', () { + enumerate(anEnum.members, (int index, final EnumMember member) { + addDocumentationComments( + indent, member.documentationComments, _docCommentSpec); + // Capitalized first letter to ensure Swift compatibility + indent.writeln( + '$enumName${member.name[0].toUpperCase()}${member.name.substring(1)} = $index,'); + }); + }); + } + /// Writes the class declaration for a data class. /// /// Example: @@ -246,53 +289,10 @@ class ObjcGenerator extends Generator { indent.writeln(''); } - /// Writes Objc header file header to sink. - void writeObjcHeaderHeader( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - if (options.copyrightHeader != null) { - addLines(indent, options.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.addln(''); - } - - /// Writes Objc header file imports to sink. - void writeObjcHeaderImports( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - indent.writeln('#import '); - indent.addln(''); - - indent.writeln('@protocol FlutterBinaryMessenger;'); - indent.writeln('@protocol FlutterMessageCodec;'); - indent.writeln('@class FlutterError;'); - indent.writeln('@class FlutterStandardTypedData;'); - indent.addln(''); - } - - /// Writes single Objc header enum. - void writeObjcHeaderEnum(ObjcOptions options, Root root, StringSink sink, - Indent indent, Enum anEnum) { - final String enumName = _className(options.prefix, anEnum.name); - addDocumentationComments( - indent, anEnum.documentationComments, _docCommentSpec); - - indent.write('typedef NS_ENUM(NSUInteger, $enumName) '); - indent.scoped('{', '};', () { - enumerate(anEnum.members, (int index, final EnumMember member) { - addDocumentationComments( - indent, member.documentationComments, _docCommentSpec); - // Capitalized first letter to ensure Swift compatibility - indent.writeln( - '$enumName${member.name[0].toUpperCase()}${member.name.substring(1)} = $index,'); - }); - }); - } - // Source File Methods. /// Writes Objc Source file header to sink. - void writeObjcSourceHeader( + void _writeObjcSourceHeader( ObjcOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); @@ -303,7 +303,7 @@ class ObjcGenerator extends Generator { } /// Writes Objc source file imports to sink. - void writeObjcSourceImports( + void _writeObjcSourceImports( ObjcOptions options, Root root, StringSink sink, Indent indent) { indent.writeln('#import "${options.headerIncludePath}"'); indent.writeln('#import '); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index bfd7dab1009..ec76b562999 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -145,16 +145,6 @@ import FlutterMacOS }); } - void _writeClassField(Indent indent, NamedType field) { - addDocumentationComments( - indent, field.documentationComments, _docCommentSpec); - - indent.write( - 'var ${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}'); - final String defaultNil = field.type.isNullable ? ' = nil' : ''; - indent.addln(defaultNil); - } - @override void writeClassEncode( SwiftOptions languageOptions, @@ -260,6 +250,16 @@ import FlutterMacOS }); } + void _writeClassField(Indent indent, NamedType field) { + addDocumentationComments( + indent, field.documentationComments, _docCommentSpec); + + indent.write( + 'var ${field.name}: ${_nullsafeSwiftTypeForDartType(field.type)}'); + final String defaultNil = field.type.isNullable ? ' = nil' : ''; + indent.addln(defaultNil); + } + HostDatatype _getHostDatatype(Root root, NamedType field) { return getFieldHostDatatype(field, root.classes, root.enums, (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); From 3a01adec3b3fc6ec607d9dad820c66e1c560af77 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 16:43:18 -0800 Subject: [PATCH 57/87] changelog --- packages/pigeon/CHANGELOG.md | 4 ++++ packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 394a84a7f80..235f434d9cf 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.0.2 + +* Adds writeImports method to Generator classes. + ## 5.0.1 * Adds writeHeaders method to Generator classes and updates tests to use new Generators. diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 577bf8216de..e3016ad19af 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '5.0.1'; +const String pigeonVersion = '5.0.2'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index f2a5a9a6639..3e1b364ac62 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 5.0.1 # This must match the version in lib/generator_tools.dart +version: 5.0.2 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" From 91ffeb4adce02f297bb0b911266461aeec4cca9e Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 16:44:58 -0800 Subject: [PATCH 58/87] changelog --- packages/pigeon/CHANGELOG.md | 4 ++++ packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 235f434d9cf..f3328922108 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.0.3 + +* Adds writeEnum method to Generator classes. + ## 5.0.2 * Adds writeImports method to Generator classes. diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index e3016ad19af..73c1fd36272 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '5.0.2'; +const String pigeonVersion = '5.0.3'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 3e1b364ac62..a72557dab8a 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 5.0.2 # This must match the version in lib/generator_tools.dart +version: 5.0.3 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" From 1bbfa53b3b8aa3cb8abe67e28200d4afe1788fd6 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 16:46:00 -0800 Subject: [PATCH 59/87] changelog --- packages/pigeon/CHANGELOG.md | 4 ++++ packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index f3328922108..33c5fabb787 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.0.4 + +* Adds writeEnum method to Generator classes. + ## 5.0.3 * Adds writeEnum method to Generator classes. diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 73c1fd36272..d6ef9703cf4 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '5.0.3'; +const String pigeonVersion = '5.0.4'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index a72557dab8a..1740c655da9 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 5.0.3 # This must match the version in lib/generator_tools.dart +version: 5.0.4 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" From c92b944787d6a28448caf45282b1d8868ecb9cf0 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 16:49:10 -0800 Subject: [PATCH 60/87] changelog --- packages/pigeon/CHANGELOG.md | 4 ++++ packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 33c5fabb787..bda54aef371 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.0.5 + +* Adds writeApi method to Generator classes. + ## 5.0.4 * Adds writeEnum method to Generator classes. diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index d6ef9703cf4..07eac70ad9b 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '5.0.4'; +const String pigeonVersion = '5.0.5'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 1740c655da9..e4feca00cb9 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 5.0.4 # This must match the version in lib/generator_tools.dart +version: 5.0.5 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" From 02fd734a60a6588ba410e6fcdea67b492306cc15 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 17:22:40 -0800 Subject: [PATCH 61/87] prologue --- packages/pigeon/lib/cpp_generator.dart | 14 +++++++------- packages/pigeon/lib/dart_generator.dart | 8 ++++---- packages/pigeon/lib/generator.dart | 2 +- packages/pigeon/lib/java_generator.dart | 8 ++++---- packages/pigeon/lib/kotlin_generator.dart | 8 ++++---- packages/pigeon/lib/objc_generator.dart | 14 +++++++------- packages/pigeon/lib/swift_generator.dart | 8 ++++---- 7 files changed, 31 insertions(+), 31 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 82fb8bf62b7..d2cd209c0d9 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -84,23 +84,23 @@ class CppGenerator extends Generator> { final Indent indent = Indent(sink); if (fileType == FileType.header) { - writeFileHeaders(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); generateCppHeader(generatorOptions.languageOptions, root, sink, indent); } else { - writeFileHeaders(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); generateCppSource(generatorOptions.languageOptions, root, sink, indent); } } @override - void writeFileHeaders(OutputFileOptions generatorOptions, + void writeFilePrologue(OutputFileOptions generatorOptions, Root root, StringSink sink, Indent indent) { final FileType fileType = generatorOptions.fileType; if (fileType == FileType.header) { - writeCppHeaderHeader( + writeCppHeaderPrologue( generatorOptions.languageOptions, root, sink, indent); } else { - writeCppSourceHeader( + writeCppSourcePrologue( generatorOptions.languageOptions, root, sink, indent); } } @@ -1067,7 +1067,7 @@ void _writeSystemHeaderIncludeBlock(Indent indent, List headers) { } /// Writes Cpp header file header to sink. -void writeCppHeaderHeader( +void writeCppHeaderPrologue( CppOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); @@ -1163,7 +1163,7 @@ void generateCppHeader( } /// Writes Cpp source file header to sink. -void writeCppSourceHeader( +void writeCppSourcePrologue( CppOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index daf4171754b..724a1dfc1a8 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -80,14 +80,14 @@ class DartGenerator extends Generator { void generate(DartOptions generatorOptions, Root root, StringSink sink) { final Indent indent = Indent(sink); - writeFileHeaders(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); generateDart(generatorOptions, root, sink, indent); } @override - void writeFileHeaders( + void writeFilePrologue( DartOptions generatorOptions, Root root, StringSink sink, Indent indent) { - writeHeader(generatorOptions, root, sink, indent); + writePrologue(generatorOptions, root, sink, indent); } /// Generates Dart files for testing with specified [DartOptions] @@ -512,7 +512,7 @@ String _addGenericTypesNullable(TypeDeclaration type) { } /// Writes file header to sink. -void writeHeader(DartOptions opt, Root root, StringSink sink, Indent indent) { +void writePrologue(DartOptions opt, Root root, StringSink sink, Indent indent) { if (opt.copyrightHeader != null) { addLines(indent, opt.copyrightHeader!, linePrefix: '// '); } diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 473e1a3e46f..67e2fdbd602 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -22,7 +22,7 @@ abstract class Generator { ); /// Adds specified file headers. - void writeFileHeaders( + void writeFilePrologue( T generatorOptions, Root root, StringSink sink, diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 6a18fba04aa..84357703b15 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -95,14 +95,14 @@ class JavaGenerator extends Generator { void generate(JavaOptions generatorOptions, Root root, StringSink sink) { final Indent indent = Indent(sink); - writeFileHeaders(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); generateJava(generatorOptions, root, sink, indent); } @override - void writeFileHeaders( + void writeFilePrologue( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { - writeHeader(generatorOptions, root, sink, indent); + writePrologue(generatorOptions, root, sink, indent); } } @@ -544,7 +544,7 @@ String _castObject( } /// Writes file header to sink. -void writeHeader( +void writePrologue( JavaOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index eed3e6da387..5e47a152ebc 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -79,14 +79,14 @@ class KotlinGenerator extends Generator { ) { final Indent indent = Indent(sink); - writeFileHeaders(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); generateKotlin(generatorOptions, root, sink, indent); } @override - void writeFileHeaders(KotlinOptions generatorOptions, Root root, + void writeFilePrologue(KotlinOptions generatorOptions, Root root, StringSink sink, Indent indent) { - writeHeader(generatorOptions, root, sink, indent); + writePrologue(generatorOptions, root, sink, indent); } } @@ -461,7 +461,7 @@ String _nullsafeKotlinTypeForDartType(TypeDeclaration type) { } /// Writes file header to sink. -void writeHeader( +void writePrologue( KotlinOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 33922019d2c..25e06b98f42 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -77,23 +77,23 @@ class ObjcGenerator extends Generator> { final Indent indent = Indent(sink); if (fileType == FileType.header) { - writeFileHeaders(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); generateObjcHeader(generatorOptions.languageOptions, root, sink, indent); } else { - writeFileHeaders(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); generateObjcSource(generatorOptions.languageOptions, root, sink, indent); } } @override - void writeFileHeaders(OutputFileOptions generatorOptions, + void writeFilePrologue(OutputFileOptions generatorOptions, Root root, StringSink sink, Indent indent) { final FileType fileType = generatorOptions.fileType; if (fileType == FileType.header) { - writeObjcHeaderHeader( + writeObjcHeaderPrologue( generatorOptions.languageOptions, root, sink, indent); } else { - writeObjcSourceHeader( + writeObjcSourcePrologue( generatorOptions.languageOptions, root, sink, indent); } } @@ -567,7 +567,7 @@ void _writeFlutterApiDeclaration( } /// Writes Objc header file header to sink. -void writeObjcHeaderHeader( +void writeObjcHeaderPrologue( ObjcOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); @@ -911,7 +911,7 @@ void _writeFlutterApiSource( } /// Writes Objc Source file header to sink. -void writeObjcSourceHeader( +void writeObjcSourcePrologue( ObjcOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 44532e91f15..a55be7090b8 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -57,14 +57,14 @@ class SwiftGenerator extends Generator { @override void generate(SwiftOptions generatorOptions, Root root, StringSink sink) { final Indent indent = Indent(sink); - writeFileHeaders(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); generateSwift(generatorOptions, root, sink, indent); } @override - void writeFileHeaders(SwiftOptions generatorOptions, Root root, + void writeFilePrologue(SwiftOptions generatorOptions, Root root, StringSink sink, Indent indent) { - writeHeader(generatorOptions, root, sink, indent); + writePrologue(generatorOptions, root, sink, indent); } } @@ -454,7 +454,7 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { } /// Writes file header to sink. -void writeHeader( +void writePrologue( SwiftOptions options, Root root, StringSink sink, Indent indent) { if (options.copyrightHeader != null) { addLines(indent, options.copyrightHeader!, linePrefix: '// '); From cdc2da694a840b9c0329fb910d37921217a6f966 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 17:53:01 -0800 Subject: [PATCH 62/87] gen --- packages/pigeon/mock_handler_tester/test/message.dart | 2 +- packages/pigeon/mock_handler_tester/test/test.dart | 2 +- .../com/example/alternate_language_test_plugin/CoreTests.java | 2 +- .../alternate_language_test_plugin/ios/Classes/CoreTests.gen.h | 2 +- .../alternate_language_test_plugin/ios/Classes/CoreTests.gen.m | 2 +- .../flutter_null_safe_unit_tests/lib/core_tests.gen.dart | 2 +- .../flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart | 2 +- .../flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart | 2 +- .../flutter_null_safe_unit_tests/lib/null_fields.gen.dart | 2 +- .../flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart | 2 +- .../flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart | 2 +- .../flutter_null_safe_unit_tests/lib/primitive.dart | 2 +- .../lib/src/generated/core_tests.gen.dart | 2 +- .../src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt | 2 +- .../platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift | 2 +- .../test_plugin/macos/Classes/CoreTests.gen.swift | 2 +- .../test_plugin/windows/pigeon/core_tests.gen.cpp | 2 +- .../platform_tests/test_plugin/windows/pigeon/core_tests.gen.h | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/packages/pigeon/mock_handler_tester/test/message.dart b/packages/pigeon/mock_handler_tester/test/message.dart index f621ac645da..1780b3c7504 100644 --- a/packages/pigeon/mock_handler_tester/test/message.dart +++ b/packages/pigeon/mock_handler_tester/test/message.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/mock_handler_tester/test/test.dart b/packages/pigeon/mock_handler_tester/test/test.dart index f9be7a1f0c6..075fe0e7ca6 100644 --- a/packages/pigeon/mock_handler_tester/test/test.dart +++ b/packages/pigeon/mock_handler_tester/test/test.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, unnecessary_import // ignore_for_file: avoid_relative_lib_imports diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index bb5e3ba569a..b95b18fb650 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), do not edit directly. // See also: https://pub.dev/packages/pigeon package com.example.alternate_language_test_plugin; diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index 99a55d66a71..74c3c2e68f4 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), do not edit directly. // See also: https://pub.dev/packages/pigeon #import diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index 1e0bc26defd..c52ea0822e1 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), do not edit directly. // See also: https://pub.dev/packages/pigeon #import "CoreTests.gen.h" diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart index fbdca3b2ed4..e681a886aaf 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart index 692de832122..aa2c80d3824 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/multiple_arity.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart index 605a5f2c8c5..d60b52646b1 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/non_null_fields.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart index cd6273f8d65..6d2d1d41f03 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_fields.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart index 0999065d1ae..930fccd57fa 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart index 03522dd4cb7..75e73d74eea 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/nullable_returns.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart index 78eee146e5f..f2961e54cca 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/primitive.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index fbdca3b2ed4..e681a886aaf 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), 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, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index 258a4328e98..15d31704b6d 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), do not edit directly. // See also: https://pub.dev/packages/pigeon package com.example.test_plugin diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index a754852b62e..ecd65d85009 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index a754852b62e..ecd65d85009 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp index 5e748c1f154..7cd0f9cec35 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.cpp @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index 48092005912..e6e0825cf88 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v5.0.4), do not edit directly. +// Autogenerated from Pigeon (v5.0.5), do not edit directly. // See also: https://pub.dev/packages/pigeon #ifndef PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ From 3464c373779e69b25ee56a1f7e91f986b10e913f Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 23:10:42 -0800 Subject: [PATCH 63/87] dart --- packages/pigeon/lib/dart_generator.dart | 741 ++++++++++++------------ packages/pigeon/lib/generator.dart | 22 +- 2 files changed, 380 insertions(+), 383 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index f930979cc8d..9de09227aa2 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -90,7 +90,14 @@ class DartGenerator extends Generator { writeDataClass(generatorOptions, root, sink, indent, klass); } - generateDart(generatorOptions, root, sink, indent); + for (final Api api in root.apis) { + indent.writeln(''); + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); + } + } } @override @@ -284,21 +291,366 @@ $resultAt != null }); } - /// Generates Dart files for testing with specified [DartOptions] + /// Writes the code for host [Api], [api]. + /// Example: + /// class FooCodec extends StandardMessageCodec {...} + /// + /// abstract class Foo { + /// static const MessageCodec codec = FooCodec(); + /// int add(int x, int y); + /// static void setup(Foo api, {BinaryMessenger? binaryMessenger}) {...} + /// } + @override + void writeFlutterApi( + DartOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, { + String Function(Method)? channelNameFunc, + bool isMockHandler = false, + }) { + assert(api.location == ApiLocation.flutter); + final List customEnumNames = + root.enums.map((Enum x) => x.name).toList(); + String codecName = _standardMessageCodec; + if (getCodecClasses(api, root).isNotEmpty) { + codecName = _getCodecName(api); + _writeCodec(indent, codecName, api, root); + } + indent.addln(''); + addDocumentationComments( + indent, api.documentationComments, _docCommentSpec); + + indent.write('abstract class ${api.name} '); + indent.scoped('{', '}', () { + indent + .writeln('static const MessageCodec codec = $codecName();'); + indent.addln(''); + for (final Method func in api.methods) { + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + + final bool isAsync = func.isAsynchronous; + final String returnType = isAsync + ? 'Future<${_addGenericTypesNullable(func.returnType)}>' + : _addGenericTypesNullable(func.returnType); + final String argSignature = _getMethodArgumentsSignature( + func, + _getArgumentName, + ); + indent.writeln('$returnType ${func.name}($argSignature);'); + indent.writeln(''); + } + indent.write( + 'static void setup(${api.name}? api, {BinaryMessenger? binaryMessenger}) '); + indent.scoped('{', '}', () { + for (final Method func in api.methods) { + indent.write(''); + indent.scoped('{', '}', () { + indent.writeln( + 'final BasicMessageChannel channel = BasicMessageChannel(', + ); + final String channelName = channelNameFunc == null + ? makeChannelName(api, func) + : channelNameFunc(func); + indent.nest(2, () { + indent.writeln("'$channelName', codec,"); + indent.writeln( + 'binaryMessenger: binaryMessenger);', + ); + }); + final String messageHandlerSetter = + isMockHandler ? 'setMockMessageHandler' : 'setMessageHandler'; + indent.write('if (api == null) '); + indent.scoped('{', '}', () { + indent.writeln('channel.$messageHandlerSetter(null);'); + }, addTrailingNewline: false); + indent.add(' else '); + indent.scoped('{', '}', () { + indent.write( + 'channel.$messageHandlerSetter((Object? message) async ', + ); + indent.scoped('{', '});', () { + final String returnType = + _addGenericTypesNullable(func.returnType); + final bool isAsync = func.isAsynchronous; + final String emptyReturnStatement = isMockHandler + ? 'return [];' + : func.returnType.isVoid + ? 'return;' + : 'return null;'; + String call; + if (func.arguments.isEmpty) { + indent.writeln('// ignore message'); + call = 'api.${func.name}()'; + } else { + indent.writeln('assert(message != null,'); + indent.writeln("'Argument for $channelName was null.');"); + const String argsArray = 'args'; + indent.writeln( + 'final List $argsArray = (message as List?)!;'); + String argNameFunc(int index, NamedType type) => + _getSafeArgumentName(index, type); + enumerate(func.arguments, (int count, NamedType arg) { + final String argType = _addGenericTypes(arg.type); + final String argName = argNameFunc(count, arg); + final String genericArgType = + _makeGenericTypeArguments(arg.type); + final String castCall = _makeGenericCastCall(arg.type); + + final String leftHandSide = 'final $argType? $argName'; + if (customEnumNames.contains(arg.type.baseName)) { + indent.writeln( + '$leftHandSide = $argsArray[$count] == null ? null : $argType.values[$argsArray[$count] as int];'); + } else { + indent.writeln( + '$leftHandSide = ($argsArray[$count] as $genericArgType?)${castCall.isEmpty ? '' : '?$castCall'};'); + } + if (!arg.type.isNullable) { + indent.writeln( + "assert($argName != null, 'Argument for $channelName was null, expected non-null $argType.');"); + } + }); + final Iterable argNames = + indexMap(func.arguments, (int index, NamedType field) { + final String name = _getSafeArgumentName(index, field); + return '$name${field.type.isNullable ? '' : '!'}'; + }); + call = 'api.${func.name}(${argNames.join(', ')})'; + } + if (func.returnType.isVoid) { + if (isAsync) { + indent.writeln('await $call;'); + } else { + indent.writeln('$call;'); + } + indent.writeln(emptyReturnStatement); + } else { + if (isAsync) { + indent.writeln('final $returnType output = await $call;'); + } else { + indent.writeln('final $returnType output = $call;'); + } + const String returnExpression = 'output'; + final String returnStatement = isMockHandler + ? 'return [$returnExpression];' + : 'return $returnExpression;'; + indent.writeln(returnStatement); + } + }); + }); + }); + } + }); + }); + } + + /// Writes the code for host [Api], [api]. + /// Example: + /// class FooCodec extends StandardMessageCodec {...} + /// + /// class Foo { + /// Foo(BinaryMessenger? binaryMessenger) {} + /// static const MessageCodec codec = FooCodec(); + /// Future add(int x, int y) async {...} + /// } + /// + /// Messages will be sent and received in a list. + /// + /// If the message recieved was succesful, + /// the result will be contained at the 0'th index. + /// + /// If the message was a failure, the list will contain 3 items: + /// a code, a message, and details in that order. + @override + void writeHostApi(DartOptions generatorOptions, Root root, StringSink sink, + Indent indent, Api api) { + assert(api.location == ApiLocation.host); + String codecName = _standardMessageCodec; + if (getCodecClasses(api, root).isNotEmpty) { + codecName = _getCodecName(api); + _writeCodec(indent, codecName, api, root); + } + indent.addln(''); + bool first = true; + addDocumentationComments( + indent, api.documentationComments, _docCommentSpec); + indent.write('class ${api.name} '); + indent.scoped('{', '}', () { + indent.format(''' +/// Constructor for [${api.name}]. The [binaryMessenger] named argument is +/// available for dependency injection. If it is left null, the default +/// BinaryMessenger will be used which routes to the host platform. +${api.name}({BinaryMessenger? binaryMessenger}) +\t\t: _binaryMessenger = binaryMessenger; +final BinaryMessenger? _binaryMessenger; +'''); + + indent + .writeln('static const MessageCodec codec = $codecName();'); + indent.addln(''); + for (final Method func in api.methods) { + if (!first) { + indent.writeln(''); + } else { + first = false; + } + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + String argSignature = ''; + String sendArgument = 'null'; + if (func.arguments.isNotEmpty) { + String argNameFunc(int index, NamedType type) => + _getSafeArgumentName(index, type); + final Iterable argExpressions = + indexMap(func.arguments, (int index, NamedType type) { + final String name = argNameFunc(index, type); + if (root.enums + .map((Enum e) => e.name) + .contains(type.type.baseName)) { + return '$name${type.type.isNullable ? '?' : ''}.index'; + } else { + return name; + } + }); + sendArgument = '[${argExpressions.join(', ')}]'; + argSignature = _getMethodArgumentsSignature(func, argNameFunc); + } + indent.write( + 'Future<${_addGenericTypesNullable(func.returnType)}> ${func.name}($argSignature) async ', + ); + indent.scoped('{', '}', () { + final String channelName = makeChannelName(api, func); + indent.writeln( + 'final BasicMessageChannel channel = BasicMessageChannel('); + indent.nest(2, () { + indent.writeln("'$channelName', codec,"); + indent.writeln('binaryMessenger: _binaryMessenger);'); + }); + final String returnType = _makeGenericTypeArguments(func.returnType); + final String genericCastCall = _makeGenericCastCall(func.returnType); + const String accessor = 'replyList[0]'; + // Avoid warnings from pointlessly casting to `Object?`. + final String nullablyTypedAccessor = + returnType == 'Object' ? accessor : '($accessor as $returnType?)'; + final String nullHandler = func.returnType.isNullable + ? (genericCastCall.isEmpty ? '' : '?') + : '!'; + final String returnStatement = func.returnType.isVoid + ? 'return;' + : 'return $nullablyTypedAccessor$nullHandler$genericCastCall;'; + indent.format(''' +final List? replyList = +\t\tawait channel.send($sendArgument) as List?; +if (replyList == null) { +\tthrow PlatformException( +\t\tcode: 'channel-error', +\t\tmessage: 'Unable to establish connection on channel.', +\t); +} else if (replyList.length > 1) { +\tthrow PlatformException( +\t\tcode: replyList[0]! as String, +\t\tmessage: replyList[1] as String?, +\t\tdetails: replyList[2], +\t);'''); + // On iOS we can return nil from functions to accommodate error + // handling. Returning a nil value and not returning an error is an + // exception. + if (!func.returnType.isNullable && !func.returnType.isVoid) { + indent.format(''' +} else if (replyList[0] == null) { +\tthrow PlatformException( +\t\tcode: 'null-error', +\t\tmessage: 'Host platform returned null value for non-null return value.', +\t);'''); + } + indent.format(''' +} else { +\t$returnStatement +}'''); + }); + } + }); + } + + /// Generates Dart source code for test support libraries based on the given AST + /// represented by [root], outputting the code to [sink]. [sourceOutPath] is the + /// path of the generated dart code to be tested. [testOutPath] is where the + /// test code will be generated. void generateTest(DartOptions generatorOptions, Root root, StringSink sink) { final Indent indent = Indent(sink); final String sourceOutPath = generatorOptions.sourceOutPath ?? ''; final String testOutPath = generatorOptions.testOutPath ?? ''; - writeTestHeader(generatorOptions, root, sink, indent); - writeTestImports(generatorOptions, root, sink, indent); - generateTestDart( - generatorOptions, - root, - sink, - indent, - sourceOutPath: sourceOutPath, - testOutPath: testOutPath, + _writeTestPrologue(generatorOptions, root, sink, indent); + _writeTestImports(generatorOptions, root, sink, indent); + final String relativeDartPath = + path.Context(style: path.Style.posix).relative( + _posixify(sourceOutPath), + from: _posixify(path.dirname(testOutPath)), ); + late final String? packageName = _deducePackageName(sourceOutPath); + if (!relativeDartPath.contains('/lib/') || packageName == null) { + // If we can't figure out the package name or the relative path doesn't + // include a 'lib' directory, try relative path import which only works in + // certain (older) versions of Dart. + // TODO(gaaclarke): We should add a command-line parameter to override this import. + indent.writeln( + "import '${_escapeForDartSingleQuotedString(relativeDartPath)}';"); + } else { + final String path = + relativeDartPath.replaceFirst(RegExp(r'^.*/lib/'), ''); + indent.writeln("import 'package:$packageName/$path';"); + } + for (final Api api in root.apis) { + if (api.location == ApiLocation.host && api.dartHostTestHandler != null) { + final Api mockApi = Api( + name: api.dartHostTestHandler!, + methods: api.methods, + location: ApiLocation.flutter, + dartHostTestHandler: api.dartHostTestHandler, + documentationComments: api.documentationComments, + ); + indent.writeln(''); + writeFlutterApi( + generatorOptions, + root, + sink, + indent, + mockApi, + channelNameFunc: (Method func) => makeChannelName(api, func), + isMockHandler: true, + ); + } + } + } + + /// Writes file header to sink. + void _writeTestPrologue( + DartOptions opt, Root root, StringSink sink, Indent indent) { + if (opt.copyrightHeader != null) { + addLines(indent, opt.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); + indent.writeln( + '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import', + ); + indent.writeln('// ignore_for_file: avoid_relative_lib_imports'); + } + + /// Writes file imports to sink. + void _writeTestImports( + DartOptions opt, Root root, StringSink sink, Indent indent) { + indent.writeln("import 'dart:async';"); + indent.writeln( + "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", + ); + indent.writeln( + "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); + indent.writeln("import 'package:flutter/services.dart';"); + indent.writeln("import 'package:flutter_test/flutter_test.dart';"); + indent.writeln(''); } } @@ -400,279 +752,6 @@ String _getMethodArgumentsSignature( }).join(', '); } -/// Writes the code for host [Api], [api]. -/// Example: -/// class FooCodec extends StandardMessageCodec {...} -/// -/// class Foo { -/// Foo(BinaryMessenger? binaryMessenger) {} -/// static const MessageCodec codec = FooCodec(); -/// Future add(int x, int y) async {...} -/// } -/// -/// Messages will be sent and received in a list. -/// -/// If the message recieved was succesful, -/// the result will be contained at the 0'th index. -/// -/// If the message was a failure, the list will contain 3 items: -/// a code, a message, and details in that order. -void _writeHostApi(DartOptions opt, Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.host); - String codecName = _standardMessageCodec; - if (getCodecClasses(api, root).isNotEmpty) { - codecName = _getCodecName(api); - _writeCodec(indent, codecName, api, root); - } - indent.addln(''); - bool first = true; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec); - indent.write('class ${api.name} '); - indent.scoped('{', '}', () { - indent.format(''' -/// Constructor for [${api.name}]. The [binaryMessenger] named argument is -/// available for dependency injection. If it is left null, the default -/// BinaryMessenger will be used which routes to the host platform. -${api.name}({BinaryMessenger? binaryMessenger}) -\t\t: _binaryMessenger = binaryMessenger; -final BinaryMessenger? _binaryMessenger; -'''); - - indent.writeln('static const MessageCodec codec = $codecName();'); - indent.addln(''); - for (final Method func in api.methods) { - if (!first) { - indent.writeln(''); - } else { - first = false; - } - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - String argSignature = ''; - String sendArgument = 'null'; - if (func.arguments.isNotEmpty) { - String argNameFunc(int index, NamedType type) => - _getSafeArgumentName(index, type); - final Iterable argExpressions = - indexMap(func.arguments, (int index, NamedType type) { - final String name = argNameFunc(index, type); - if (root.enums.map((Enum e) => e.name).contains(type.type.baseName)) { - return '$name${type.type.isNullable ? '?' : ''}.index'; - } else { - return name; - } - }); - sendArgument = '[${argExpressions.join(', ')}]'; - argSignature = _getMethodArgumentsSignature(func, argNameFunc); - } - indent.write( - 'Future<${_addGenericTypesNullable(func.returnType)}> ${func.name}($argSignature) async ', - ); - indent.scoped('{', '}', () { - final String channelName = makeChannelName(api, func); - indent.writeln( - 'final BasicMessageChannel channel = BasicMessageChannel('); - indent.nest(2, () { - indent.writeln("'$channelName', codec,"); - indent.writeln('binaryMessenger: _binaryMessenger);'); - }); - final String returnType = _makeGenericTypeArguments(func.returnType); - final String genericCastCall = _makeGenericCastCall(func.returnType); - const String accessor = 'replyList[0]'; - // Avoid warnings from pointlessly casting to `Object?`. - final String nullablyTypedAccessor = - returnType == 'Object' ? accessor : '($accessor as $returnType?)'; - final String nullHandler = func.returnType.isNullable - ? (genericCastCall.isEmpty ? '' : '?') - : '!'; - final String returnStatement = func.returnType.isVoid - ? 'return;' - : 'return $nullablyTypedAccessor$nullHandler$genericCastCall;'; - indent.format(''' -final List? replyList = -\t\tawait channel.send($sendArgument) as List?; -if (replyList == null) { -\tthrow PlatformException( -\t\tcode: 'channel-error', -\t\tmessage: 'Unable to establish connection on channel.', -\t); -} else if (replyList.length > 1) { -\tthrow PlatformException( -\t\tcode: replyList[0]! as String, -\t\tmessage: replyList[1] as String?, -\t\tdetails: replyList[2], -\t);'''); - // On iOS we can return nil from functions to accommodate error - // handling. Returning a nil value and not returning an error is an - // exception. - if (!func.returnType.isNullable && !func.returnType.isVoid) { - indent.format(''' -} else if (replyList[0] == null) { -\tthrow PlatformException( -\t\tcode: 'null-error', -\t\tmessage: 'Host platform returned null value for non-null return value.', -\t);'''); - } - indent.format(''' -} else { -\t$returnStatement -}'''); - }); - } - }); -} - -/// Writes the code for host [Api], [api]. -/// Example: -/// class FooCodec extends StandardMessageCodec {...} -/// -/// abstract class Foo { -/// static const MessageCodec codec = FooCodec(); -/// int add(int x, int y); -/// static void setup(Foo api, {BinaryMessenger? binaryMessenger}) {...} -/// } -void _writeFlutterApi( - DartOptions opt, - Indent indent, - Api api, - Root root, { - String Function(Method)? channelNameFunc, - bool isMockHandler = false, -}) { - assert(api.location == ApiLocation.flutter); - final List customEnumNames = - root.enums.map((Enum x) => x.name).toList(); - String codecName = _standardMessageCodec; - if (getCodecClasses(api, root).isNotEmpty) { - codecName = _getCodecName(api); - _writeCodec(indent, codecName, api, root); - } - indent.addln(''); - addDocumentationComments(indent, api.documentationComments, _docCommentSpec); - - indent.write('abstract class ${api.name} '); - indent.scoped('{', '}', () { - indent.writeln('static const MessageCodec codec = $codecName();'); - indent.addln(''); - for (final Method func in api.methods) { - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - - final bool isAsync = func.isAsynchronous; - final String returnType = isAsync - ? 'Future<${_addGenericTypesNullable(func.returnType)}>' - : _addGenericTypesNullable(func.returnType); - final String argSignature = _getMethodArgumentsSignature( - func, - _getArgumentName, - ); - indent.writeln('$returnType ${func.name}($argSignature);'); - indent.writeln(''); - } - indent.write( - 'static void setup(${api.name}? api, {BinaryMessenger? binaryMessenger}) '); - indent.scoped('{', '}', () { - for (final Method func in api.methods) { - indent.write(''); - indent.scoped('{', '}', () { - indent.writeln( - 'final BasicMessageChannel channel = BasicMessageChannel(', - ); - final String channelName = channelNameFunc == null - ? makeChannelName(api, func) - : channelNameFunc(func); - indent.nest(2, () { - indent.writeln("'$channelName', codec,"); - indent.writeln( - 'binaryMessenger: binaryMessenger);', - ); - }); - final String messageHandlerSetter = - isMockHandler ? 'setMockMessageHandler' : 'setMessageHandler'; - indent.write('if (api == null) '); - indent.scoped('{', '}', () { - indent.writeln('channel.$messageHandlerSetter(null);'); - }, addTrailingNewline: false); - indent.add(' else '); - indent.scoped('{', '}', () { - indent.write( - 'channel.$messageHandlerSetter((Object? message) async ', - ); - indent.scoped('{', '});', () { - final String returnType = - _addGenericTypesNullable(func.returnType); - final bool isAsync = func.isAsynchronous; - final String emptyReturnStatement = isMockHandler - ? 'return [];' - : func.returnType.isVoid - ? 'return;' - : 'return null;'; - String call; - if (func.arguments.isEmpty) { - indent.writeln('// ignore message'); - call = 'api.${func.name}()'; - } else { - indent.writeln('assert(message != null,'); - indent.writeln("'Argument for $channelName was null.');"); - const String argsArray = 'args'; - indent.writeln( - 'final List $argsArray = (message as List?)!;'); - String argNameFunc(int index, NamedType type) => - _getSafeArgumentName(index, type); - enumerate(func.arguments, (int count, NamedType arg) { - final String argType = _addGenericTypes(arg.type); - final String argName = argNameFunc(count, arg); - final String genericArgType = - _makeGenericTypeArguments(arg.type); - final String castCall = _makeGenericCastCall(arg.type); - - final String leftHandSide = 'final $argType? $argName'; - if (customEnumNames.contains(arg.type.baseName)) { - indent.writeln( - '$leftHandSide = $argsArray[$count] == null ? null : $argType.values[$argsArray[$count] as int];'); - } else { - indent.writeln( - '$leftHandSide = ($argsArray[$count] as $genericArgType?)${castCall.isEmpty ? '' : '?$castCall'};'); - } - if (!arg.type.isNullable) { - indent.writeln( - "assert($argName != null, 'Argument for $channelName was null, expected non-null $argType.');"); - } - }); - final Iterable argNames = - indexMap(func.arguments, (int index, NamedType field) { - final String name = _getSafeArgumentName(index, field); - return '$name${field.type.isNullable ? '' : '!'}'; - }); - call = 'api.${func.name}(${argNames.join(', ')})'; - } - if (func.returnType.isVoid) { - if (isAsync) { - indent.writeln('await $call;'); - } else { - indent.writeln('$call;'); - } - indent.writeln(emptyReturnStatement); - } else { - if (isAsync) { - indent.writeln('final $returnType output = await $call;'); - } else { - indent.writeln('final $returnType output = $call;'); - } - const String returnExpression = 'output'; - final String returnStatement = isMockHandler - ? 'return [$returnExpression];' - : 'return $returnExpression;'; - indent.writeln(returnStatement); - } - }); - }); - }); - } - }); - }); -} - /// Converts a [List] of [TypeDeclaration]s to a comma separated [String] to be /// used in Dart code. String _flattenTypeArguments(List args) { @@ -708,20 +787,7 @@ String _addGenericTypesNullable(TypeDeclaration type) { /// Generates Dart source code for the given AST represented by [root], /// outputting the code to [sink]. -void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) { - void writeApi(Api api) { - if (api.location == ApiLocation.host) { - _writeHostApi(opt, indent, api, root); - } else if (api.location == ApiLocation.flutter) { - _writeFlutterApi(opt, indent, api, root); - } - } - - for (final Api api in root.apis) { - indent.writeln(''); - writeApi(api); - } -} +void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) {} /// Crawls up the path of [dartFilePath] until it finds a pubspec.yaml in a /// parent directory and returns its path. @@ -771,82 +837,3 @@ String _posixify(String inputPath) { final path.Context context = path.Context(style: path.Style.posix); return context.fromUri(path.toUri(path.absolute(inputPath))); } - -/// Writes file header to sink. -void writeTestHeader( - DartOptions opt, Root root, StringSink sink, Indent indent) { - if (opt.copyrightHeader != null) { - addLines(indent, opt.copyrightHeader!, linePrefix: '// '); - } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.writeln( - '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import', - ); - indent.writeln('// ignore_for_file: avoid_relative_lib_imports'); -} - -/// Writes file imports to sink. -void writeTestImports( - DartOptions opt, Root root, StringSink sink, Indent indent) { - indent.writeln("import 'dart:async';"); - indent.writeln( - "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", - ); - indent.writeln( - "import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;"); - indent.writeln("import 'package:flutter/services.dart';"); - indent.writeln("import 'package:flutter_test/flutter_test.dart';"); - indent.writeln(''); -} - -/// Generates Dart source code for test support libraries based on the given AST -/// represented by [root], outputting the code to [sink]. [dartOutPath] is the -/// path of the generated dart code to be tested. [testOutPath] is where the -/// test code will be generated. -void generateTestDart( - DartOptions opt, - Root root, - StringSink sink, - Indent indent, { - required String sourceOutPath, - required String testOutPath, -}) { - final String relativeDartPath = - path.Context(style: path.Style.posix).relative( - _posixify(sourceOutPath), - from: _posixify(path.dirname(testOutPath)), - ); - late final String? packageName = _deducePackageName(sourceOutPath); - if (!relativeDartPath.contains('/lib/') || packageName == null) { - // If we can't figure out the package name or the relative path doesn't - // include a 'lib' directory, try relative path import which only works in - // certain (older) versions of Dart. - // TODO(gaaclarke): We should add a command-line parameter to override this import. - indent.writeln( - "import '${_escapeForDartSingleQuotedString(relativeDartPath)}';"); - } else { - final String path = relativeDartPath.replaceFirst(RegExp(r'^.*/lib/'), ''); - indent.writeln("import 'package:$packageName/$path';"); - } - for (final Api api in root.apis) { - if (api.location == ApiLocation.host && api.dartHostTestHandler != null) { - final Api mockApi = Api( - name: api.dartHostTestHandler!, - methods: api.methods, - location: ApiLocation.flutter, - dartHostTestHandler: api.dartHostTestHandler, - documentationComments: api.documentationComments, - ); - indent.writeln(''); - _writeFlutterApi( - opt, - indent, - mockApi, - root, - channelNameFunc: (Method func) => makeChannelName(api, func), - isMockHandler: true, - ); - } - } -} diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 55356611f1b..981fcc8dfbe 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -80,11 +80,21 @@ abstract class Generator { Set customEnumNames, ); - // /// Writes a single Flutter Api to file. - // void writeFlutterApi(T generatorOptions, Root root, StringSink sink, - // Indent indent, FileType fileType, Api api,); + /// Writes a single Flutter Api to file. + void writeFlutterApi( + T generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ); - // /// Writes a single Host Api to file. - // void writeHostApi(T generatorOptions, Root root, StringSink sink, - // Indent indent, FileType fileType, Api api,); + /// Writes a single Host Api to file. + void writeHostApi( + T generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ); } From 0e36e5b49597cbfa537a4c550f1d64752845b573 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 23:10:50 -0800 Subject: [PATCH 64/87] java --- packages/pigeon/lib/java_generator.dart | 479 ++++++++++++------------ 1 file changed, 242 insertions(+), 237 deletions(-) diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index f3a4a9f1629..5c541aaf27b 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -90,7 +90,8 @@ class JavaGenerator extends Generator { /// Instantiates a Java Generator. JavaGenerator(); - /// Generates Java files with specified [JavaOptions] + /// Generates the ".java" file for the AST represented by [root] to [sink] with the + /// provided [generatorOptions]. @override void generate(JavaOptions generatorOptions, Root root, StringSink sink) { final Indent indent = Indent(sink); @@ -114,7 +115,24 @@ class JavaGenerator extends Generator { indent.addln(''); writeDataClass(generatorOptions, root, sink, indent, klass); } - generateJava(generatorOptions, root, sink, indent); + if (root.apis.any((Api api) => + api.location == ApiLocation.host && + api.methods.any((Method it) => it.isAsynchronous))) { + indent.addln(''); + _writeResultInterface(indent); + } + for (final Api api in root.apis) { + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(indent, api, root); + indent.addln(''); + } + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); + } + } + _writeWrapError(indent); }); } @@ -352,83 +370,168 @@ class JavaGenerator extends Generator { indent.writeln('return $result;'); }); } -} -/// Calculates the name of the codec that will be generated for [api]. -String _getCodecName(Api api) => '${api.name}Codec'; - -/// Converts an expression that evaluates to an nullable int to an expression -/// that evaluates to a nullable enum. -String _intToEnum(String expression, String enumName) => - '$expression == null ? null : $enumName.values()[(int)$expression]'; + /// Writes the code for a flutter [Api], [api]. + /// Example: + /// public static class Foo { + /// public Foo(BinaryMessenger argBinaryMessenger) {...} + /// public interface Reply { + /// void reply(T reply); + /// } + /// public int add(int x, int y, Reply callback) {...} + /// } + @override + void writeFlutterApi( + JavaOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.flutter); + const List generatedMessages = [ + ' Generated class from Pigeon that represents Flutter messages that can be called from Java.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); -/// Writes the codec class that will be used by [api]. -/// Example: -/// private static class FooCodec extends StandardMessageCodec {...} -void _writeCodec(Indent indent, Api api, Root root) { - assert(getCodecClasses(api, root).isNotEmpty); - final Iterable codecClasses = getCodecClasses(api, root); - final String codecName = _getCodecName(api); - indent - .write('private static class $codecName extends $_standardMessageCodec '); - indent.scoped('{', '}', () { - indent - .writeln('public static final $codecName INSTANCE = new $codecName();'); - indent.writeln('private $codecName() {}'); - indent.writeln('@Override'); - indent.write( - 'protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) '); + indent.write('public static class ${api.name} '); indent.scoped('{', '}', () { - indent.write('switch (type) '); + indent.writeln('private final BinaryMessenger binaryMessenger;'); + indent.write('public ${api.name}(BinaryMessenger argBinaryMessenger)'); indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in codecClasses) { - indent.write('case (byte)${customClass.enumeration}: '); - indent.writeScoped('', '', () { - indent.writeln( - 'return ${customClass.name}.fromList((ArrayList) readValue(buffer));'); - }); + indent.writeln('this.binaryMessenger = argBinaryMessenger;'); + }); + indent.write('public interface Reply '); + indent.scoped('{', '}', () { + indent.writeln('void reply(T reply);'); + }); + final String codecName = _getCodecName(api); + indent.writeln('/** The codec used by ${api.name}. */'); + indent.write('static MessageCodec getCodec() '); + indent.scoped('{', '}', () { + indent.write('return '); + if (getCodecClasses(api, root).isNotEmpty) { + indent.writeln('$codecName.INSTANCE;'); + } else { + indent.writeln('new $_standardMessageCodec();'); } - indent.write('default:'); - indent.writeScoped('', '', () { - indent.writeln('return super.readValueOfType(type, buffer);'); - }); }); - }); - indent.writeln('@Override'); - indent.write( - 'protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) '); - indent.writeScoped('{', '}', () { - for (final EnumeratedClass customClass in codecClasses) { - indent.write('if (value instanceof ${customClass.name}) '); - indent.scoped('{', '} else ', () { - indent.writeln('stream.write(${customClass.enumeration});'); + + for (final Method func in api.methods) { + final String channelName = makeChannelName(api, func); + final String returnType = func.returnType.isVoid + ? 'Void' + : _javaTypeForDartType(func.returnType); + String sendArgument; + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + if (func.arguments.isEmpty) { + indent + .write('public void ${func.name}(Reply<$returnType> callback) '); + sendArgument = 'null'; + } else { + final Iterable argTypes = func.arguments + .map((NamedType e) => _nullsafeJavaTypeForDartType(e.type)); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgumentName); + if (func.arguments.length == 1) { + sendArgument = + 'new ArrayList(Collections.singletonList(${argNames.first}))'; + } else { + sendArgument = + 'new ArrayList(Arrays.asList(${argNames.join(', ')}))'; + } + final String argsSignature = + map2(argTypes, argNames, (String x, String y) => '$x $y') + .join(', '); + indent.write( + 'public void ${func.name}($argsSignature, Reply<$returnType> callback) '); + } + indent.scoped('{', '}', () { + const String channel = 'channel'; + indent.writeln('BasicMessageChannel $channel ='); + indent.inc(); + indent.inc(); indent.writeln( - 'writeValue(stream, ((${customClass.name}) value).toList());'); + 'new BasicMessageChannel<>(binaryMessenger, "$channelName", getCodec());'); + indent.dec(); + indent.dec(); + indent.write('$channel.send($sendArgument, channelReply -> '); + indent.scoped('{', '});', () { + if (func.returnType.isVoid) { + indent.writeln('callback.reply(null);'); + } else { + const String output = 'output'; + indent.writeln('@SuppressWarnings("ConstantConditions")'); + if (func.returnType.baseName == 'int') { + indent.writeln( + '$returnType $output = channelReply == null ? null : ((Number)channelReply).longValue();'); + } else { + indent.writeln( + '$returnType $output = ($returnType)channelReply;'); + } + indent.writeln('callback.reply($output);'); + } + }); }); } - indent.scoped('{', '}', () { - indent.writeln('super.writeValue(stream, value);'); - }); }); - }); -} + } -/// Write the java code that represents a host [Api], [api]. -/// Example: -/// public interface Foo { -/// int add(int x, int y); -/// static void setup(BinaryMessenger binaryMessenger, Foo api) {...} -/// } -void _writeHostApi(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.host); + /// Write the java code that represents a host [Api], [api]. + /// Example: + /// public interface Foo { + /// int add(int x, int y); + /// static void setup(BinaryMessenger binaryMessenger, Foo api) {...} + /// } + @override + void writeHostApi(JavaOptions generatorOptions, Root root, StringSink sink, + Indent indent, Api api) { + assert(api.location == ApiLocation.host); - bool isEnum(TypeDeclaration type) => - root.enums.map((Enum e) => e.name).contains(type.baseName); + const List generatedMessages = [ + ' Generated interface from Pigeon that represents a handler of messages from Flutter.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); + + indent.write('public interface ${api.name} '); + indent.scoped('{', '}', () { + for (final Method method in api.methods) { + _writeInterfaceMethod( + generatorOptions, root, sink, indent, api, method); + } + indent.addln(''); + final String codecName = _getCodecName(api); + indent.writeln('/** The codec used by ${api.name}. */'); + indent.write('static MessageCodec getCodec() '); + indent.scoped('{', '}', () { + indent.write('return '); + if (getCodecClasses(api, root).isNotEmpty) { + indent.write('$codecName.INSTANCE;'); + } else { + indent.write('new $_standardMessageCodec();'); + } + }); + + indent.writeln( + '${_docCommentPrefix}Sets up an instance of `${api.name}` to handle messages through the `binaryMessenger`.$_docCommentSuffix'); + indent.write( + 'static void setup(BinaryMessenger binaryMessenger, ${api.name} api) '); + indent.scoped('{', '}', () { + for (final Method method in api.methods) { + _writeMethodSetup(generatorOptions, root, sink, indent, api, method); + } + }); + }); + } /// Write a method in the interface. /// Example: /// int add(int x, int y); - void writeInterfaceMethod(final Method method) { + void _writeInterfaceMethod(JavaOptions generatorOptions, Root root, + StringSink sink, Indent indent, Api api, final Method method) { final String returnType = method.isAsynchronous ? 'void' : _nullsafeJavaTypeForDartType(method.returnType); @@ -458,7 +561,11 @@ void _writeHostApi(Indent indent, Api api, Root root) { /// Write a static setup function in the interface. /// Example: /// static void setup(BinaryMessenger binaryMessenger, Foo api) {...} - void writeMethodSetup(final Method method) { + void _writeMethodSetup(JavaOptions generatorOptions, Root root, + StringSink sink, Indent indent, Api api, final Method method) { + //TODO(tarrinneal): See if this is needed or if generator_tools is enough + bool isEnum(TypeDeclaration type) => + root.enums.map((Enum e) => e.name).contains(type.baseName); final String channelName = makeChannelName(api, method); indent.write(''); indent.scoped('{', '}', () { @@ -574,38 +681,85 @@ Result<$returnType> $resultName = new Result<$returnType>() { }); } - const List generatedMessages = [ - ' Generated interface from Pigeon that represents a handler of messages from Flutter.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - - indent.write('public interface ${api.name} '); - indent.scoped('{', '}', () { - api.methods.forEach(writeInterfaceMethod); - indent.addln(''); + /// Writes the codec class that will be used by [api]. + /// Example: + /// private static class FooCodec extends StandardMessageCodec {...} + void _writeCodec(Indent indent, Api api, Root root) { + assert(getCodecClasses(api, root).isNotEmpty); + final Iterable codecClasses = getCodecClasses(api, root); final String codecName = _getCodecName(api); - indent.writeln('/** The codec used by ${api.name}. */'); - indent.write('static MessageCodec getCodec() '); + indent.write( + 'private static class $codecName extends $_standardMessageCodec '); indent.scoped('{', '}', () { - indent.write('return '); - if (getCodecClasses(api, root).isNotEmpty) { - indent.write('$codecName.INSTANCE;'); - } else { - indent.write('new $_standardMessageCodec();'); - } + indent.writeln( + 'public static final $codecName INSTANCE = new $codecName();'); + indent.writeln('private $codecName() {}'); + indent.writeln('@Override'); + indent.write( + 'protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) '); + indent.scoped('{', '}', () { + indent.write('switch (type) '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in codecClasses) { + indent.write('case (byte)${customClass.enumeration}: '); + indent.writeScoped('', '', () { + indent.writeln( + 'return ${customClass.name}.fromList((ArrayList) readValue(buffer));'); + }); + } + indent.write('default:'); + indent.writeScoped('', '', () { + indent.writeln('return super.readValueOfType(type, buffer);'); + }); + }); + }); + indent.writeln('@Override'); + indent.write( + 'protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) '); + indent.writeScoped('{', '}', () { + for (final EnumeratedClass customClass in codecClasses) { + indent.write('if (value instanceof ${customClass.name}) '); + indent.scoped('{', '} else ', () { + indent.writeln('stream.write(${customClass.enumeration});'); + indent.writeln( + 'writeValue(stream, ((${customClass.name}) value).toList());'); + }); + } + indent.scoped('{', '}', () { + indent.writeln('super.writeValue(stream, value);'); + }); + }); }); + } - indent.writeln( - '${_docCommentPrefix}Sets up an instance of `${api.name}` to handle messages through the `binaryMessenger`.$_docCommentSuffix'); - indent.write( - 'static void setup(BinaryMessenger binaryMessenger, ${api.name} api) '); + void _writeResultInterface(Indent indent) { + indent.write('public interface Result '); indent.scoped('{', '}', () { - api.methods.forEach(writeMethodSetup); + indent.writeln('void success(T result);'); + indent.writeln('void error(Throwable error);'); }); - }); + } + + void _writeWrapError(Indent indent) { + indent.format(''' +@NonNull private static ArrayList wrapError(@NonNull Throwable exception) { +\tArrayList errorList = new ArrayList<>(3); +\terrorList.add(exception.toString()); +\terrorList.add(exception.getClass().getSimpleName()); +\terrorList.add("Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); +\treturn errorList; +}'''); + } } +/// Calculates the name of the codec that will be generated for [api]. +String _getCodecName(Api api) => '${api.name}Codec'; + +/// Converts an expression that evaluates to an nullable int to an expression +/// that evaluates to a nullable enum. +String _intToEnum(String expression, String enumName) => + '$expression == null ? null : $enumName.values()[(int)$expression]'; + String _getArgumentName(int count, NamedType argument) => argument.name.isEmpty ? 'arg$count' : argument.name; @@ -613,106 +767,6 @@ String _getArgumentName(int count, NamedType argument) => String _getSafeArgumentName(int count, NamedType argument) => '${_getArgumentName(count, argument)}Arg'; -/// Writes the code for a flutter [Api], [api]. -/// Example: -/// public static class Foo { -/// public Foo(BinaryMessenger argBinaryMessenger) {...} -/// public interface Reply { -/// void reply(T reply); -/// } -/// public int add(int x, int y, Reply callback) {...} -/// } -void _writeFlutterApi(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.flutter); - const List generatedMessages = [ - ' Generated class from Pigeon that represents Flutter messages that can be called from Java.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - - indent.write('public static class ${api.name} '); - indent.scoped('{', '}', () { - indent.writeln('private final BinaryMessenger binaryMessenger;'); - indent.write('public ${api.name}(BinaryMessenger argBinaryMessenger)'); - indent.scoped('{', '}', () { - indent.writeln('this.binaryMessenger = argBinaryMessenger;'); - }); - indent.write('public interface Reply '); - indent.scoped('{', '}', () { - indent.writeln('void reply(T reply);'); - }); - final String codecName = _getCodecName(api); - indent.writeln('/** The codec used by ${api.name}. */'); - indent.write('static MessageCodec getCodec() '); - indent.scoped('{', '}', () { - indent.write('return '); - if (getCodecClasses(api, root).isNotEmpty) { - indent.writeln('$codecName.INSTANCE;'); - } else { - indent.writeln('new $_standardMessageCodec();'); - } - }); - - for (final Method func in api.methods) { - final String channelName = makeChannelName(api, func); - final String returnType = func.returnType.isVoid - ? 'Void' - : _javaTypeForDartType(func.returnType); - String sendArgument; - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - if (func.arguments.isEmpty) { - indent.write('public void ${func.name}(Reply<$returnType> callback) '); - sendArgument = 'null'; - } else { - final Iterable argTypes = func.arguments - .map((NamedType e) => _nullsafeJavaTypeForDartType(e.type)); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgumentName); - if (func.arguments.length == 1) { - sendArgument = - 'new ArrayList(Collections.singletonList(${argNames.first}))'; - } else { - sendArgument = - 'new ArrayList(Arrays.asList(${argNames.join(', ')}))'; - } - final String argsSignature = - map2(argTypes, argNames, (String x, String y) => '$x $y') - .join(', '); - indent.write( - 'public void ${func.name}($argsSignature, Reply<$returnType> callback) '); - } - indent.scoped('{', '}', () { - const String channel = 'channel'; - indent.writeln('BasicMessageChannel $channel ='); - indent.inc(); - indent.inc(); - indent.writeln( - 'new BasicMessageChannel<>(binaryMessenger, "$channelName", getCodec());'); - indent.dec(); - indent.dec(); - indent.write('$channel.send($sendArgument, channelReply -> '); - indent.scoped('{', '});', () { - if (func.returnType.isVoid) { - indent.writeln('callback.reply(null);'); - } else { - const String output = 'output'; - indent.writeln('@SuppressWarnings("ConstantConditions")'); - if (func.returnType.baseName == 'int') { - indent.writeln( - '$returnType $output = channelReply == null ? null : ((Number)channelReply).longValue();'); - } else { - indent - .writeln('$returnType $output = ($returnType)channelReply;'); - } - indent.writeln('callback.reply($output);'); - } - }); - }); - } - }); -} - String _makeGetter(NamedType field) { final String uppercased = field.name.substring(0, 1).toUpperCase() + field.name.substring(1); @@ -790,52 +844,3 @@ String _castObject( return '(${hostDatatype.datatype})$varName'; } } - -/// Generates the ".java" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateJava( - JavaOptions options, Root root, StringSink sink, Indent indent) { - void writeResultInterface() { - indent.write('public interface Result '); - indent.scoped('{', '}', () { - indent.writeln('void success(T result);'); - indent.writeln('void error(Throwable error);'); - }); - } - - void writeApi(Api api) { - if (api.location == ApiLocation.host) { - _writeHostApi(indent, api, root); - } else if (api.location == ApiLocation.flutter) { - _writeFlutterApi(indent, api, root); - } - } - - void writeWrapError() { - indent.format(''' -@NonNull private static ArrayList wrapError(@NonNull Throwable exception) { -\tArrayList errorList = new ArrayList<>(3); -\terrorList.add(exception.toString()); -\terrorList.add(exception.getClass().getSimpleName()); -\terrorList.add("Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); -\treturn errorList; -}'''); - } - - if (root.apis.any((Api api) => - api.location == ApiLocation.host && - api.methods.any((Method it) => it.isAsynchronous))) { - indent.addln(''); - writeResultInterface(); - } - - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(indent, api, root); - indent.addln(''); - } - writeApi(api); - } - - writeWrapError(); -} From 8d6c4350bd45e756aa61b1237fe5f631a2e97354 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 23:18:40 -0800 Subject: [PATCH 65/87] kotlin --- packages/pigeon/lib/kotlin_generator.dart | 629 +++++++++++----------- 1 file changed, 317 insertions(+), 312 deletions(-) diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index f324662a884..c0b5ae19a60 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -70,7 +70,8 @@ class KotlinGenerator extends Generator { /// Instantiates a Kotlin Generator. KotlinGenerator(); - /// Generates Kotlin files with specified [KotlinOptions] + /// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the + /// provided [KotlinOptions]. @override void generate(KotlinOptions generatorOptions, Root root, StringSink sink) { final Indent indent = Indent(sink); @@ -86,7 +87,28 @@ class KotlinGenerator extends Generator { indent.addln(''); writeDataClass(generatorOptions, root, sink, indent, klass); } - generateKotlin(generatorOptions, root, sink, indent); + if (root.apis.any((Api api) => + api.location == ApiLocation.host && + api.methods.any((Method it) => it.isAsynchronous))) { + indent.addln(''); + } + + for (final Api api in root.apis) { + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(indent, api, root); + indent.addln(''); + } + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); + } + } + + indent.addln(''); + _writeWrapResult(indent); + indent.addln(''); + _writeWrapError(indent); } @override @@ -302,302 +324,337 @@ class KotlinGenerator extends Generator { indent.add(defaultNil); } - HostDatatype _getHostDatatype(Root root, NamedType field) { - return getFieldHostDatatype(field, root.classes, root.enums, - (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); - } -} + /// Writes the code for a flutter [Api], [api]. + /// Example: + /// class Foo(private val binaryMessenger: BinaryMessenger) { + /// fun add(x: Int, y: Int, callback: (Int?) -> Unit) {...} + /// } + @override + void writeFlutterApi( + KotlinOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.flutter); + final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; -/// Calculates the name of the codec that will be generated for [api]. -String _getCodecName(Api api) => '${api.name}Codec'; + const List generatedMessages = [ + ' Generated class from Pigeon that represents Flutter messages that can be called from Kotlin.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); -/// Writes the codec class that will be used by [api]. -/// Example: -/// private static class FooCodec extends StandardMessageCodec {...} -void _writeCodec(Indent indent, Api api, Root root) { - assert(getCodecClasses(api, root).isNotEmpty); - final Iterable codecClasses = getCodecClasses(api, root); - final String codecName = _getCodecName(api); - indent.writeln('@Suppress("UNCHECKED_CAST")'); - indent.write('private object $codecName : StandardMessageCodec() '); - indent.scoped('{', '}', () { - indent.write( - 'override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? '); + final String apiName = api.name; + indent.writeln('@Suppress("UNCHECKED_CAST")'); + indent + .write('class $apiName(private val binaryMessenger: BinaryMessenger) '); indent.scoped('{', '}', () { - indent.write('return when (type) '); + indent.write('companion object '); indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in codecClasses) { - indent.write('${customClass.enumeration}.toByte() -> '); - indent.scoped('{', '}', () { - indent.write('return (readValue(buffer) as? List)?.let '); - indent.scoped('{', '}', () { - indent.writeln('${customClass.name}.fromList(it)'); - }); - }); - } - indent.writeln('else -> super.readValueOfType(type, buffer)'); + indent.writeln('/** The codec used by $apiName. */'); + indent.write('val codec: MessageCodec by lazy '); + indent.scoped('{', '}', () { + if (isCustomCodec) { + indent.writeln(_getCodecName(api)); + } else { + indent.writeln('StandardMessageCodec()'); + } + }); }); - }); - indent.write( - 'override fun writeValue(stream: ByteArrayOutputStream, value: Any?) '); - indent.writeScoped('{', '}', () { - indent.write('when (value) '); - indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in codecClasses) { - indent.write('is ${customClass.name} -> '); - indent.scoped('{', '}', () { - indent.writeln('stream.write(${customClass.enumeration})'); - indent.writeln('writeValue(stream, value.toList())'); - }); + for (final Method func in api.methods) { + final String channelName = makeChannelName(api, func); + final String returnType = func.returnType.isVoid + ? '' + : _nullsafeKotlinTypeForDartType(func.returnType); + String sendArgument; + + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + + if (func.arguments.isEmpty) { + indent.write('fun ${func.name}(callback: ($returnType) -> Unit) '); + sendArgument = 'null'; + } else { + final Iterable argTypes = func.arguments + .map((NamedType e) => _nullsafeKotlinTypeForDartType(e.type)); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgumentName); + sendArgument = 'listOf(${argNames.join(', ')})'; + final String argsSignature = map2(argTypes, argNames, + (String type, String name) => '$name: $type').join(', '); + if (func.returnType.isVoid) { + indent.write( + 'fun ${func.name}($argsSignature, callback: () -> Unit) '); + } else { + indent.write( + 'fun ${func.name}($argsSignature, callback: ($returnType) -> Unit) '); + } } - indent.writeln('else -> super.writeValue(stream, value)'); - }); + indent.scoped('{', '}', () { + const String channel = 'channel'; + indent.writeln( + 'val $channel = BasicMessageChannel(binaryMessenger, "$channelName", codec)'); + indent.write('$channel.send($sendArgument) '); + if (func.returnType.isVoid) { + indent.scoped('{', '}', () { + indent.writeln('callback()'); + }); + } else { + final String forceUnwrap = func.returnType.isNullable ? '?' : ''; + indent.scoped('{', '}', () { + indent.writeln('val result = it as$forceUnwrap $returnType'); + indent.writeln('callback(result)'); + }); + } + }); + } }); - }); -} + } -/// Write the kotlin code that represents a host [Api], [api]. -/// Example: -/// interface Foo { -/// Int add(x: Int, y: Int); -/// companion object { -/// fun setUp(binaryMessenger: BinaryMessenger, api: Api) {...} -/// } -/// } -void _writeHostApi(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.host); - - final String apiName = api.name; - - final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; - - const List generatedMessages = [ - ' Generated interface from Pigeon that represents a handler of messages from Flutter.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - - indent.write('interface $apiName '); - indent.scoped('{', '}', () { - for (final Method method in api.methods) { - final List argSignature = []; - if (method.arguments.isNotEmpty) { - final Iterable argTypes = method.arguments - .map((NamedType e) => _nullsafeKotlinTypeForDartType(e.type)); - final Iterable argNames = - method.arguments.map((NamedType e) => e.name); - argSignature - .addAll(map2(argTypes, argNames, (String argType, String argName) { - return '$argName: $argType'; - })); - } + /// Write the kotlin code that represents a host [Api], [api]. + /// Example: + /// interface Foo { + /// Int add(x: Int, y: Int); + /// companion object { + /// fun setUp(binaryMessenger: BinaryMessenger, api: Api) {...} + /// } + /// } + @override + void writeHostApi( + KotlinOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.host); - final String returnType = method.returnType.isVoid - ? '' - : _nullsafeKotlinTypeForDartType(method.returnType); + final String apiName = api.name; - addDocumentationComments( - indent, method.documentationComments, _docCommentSpec); + final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; - if (method.isAsynchronous) { - argSignature.add('callback: ($returnType) -> Unit'); - indent.writeln('fun ${method.name}(${argSignature.join(', ')})'); - } else if (method.returnType.isVoid) { - indent.writeln('fun ${method.name}(${argSignature.join(', ')})'); - } else { - indent.writeln( - 'fun ${method.name}(${argSignature.join(', ')}): $returnType'); - } - } + const List generatedMessages = [ + ' Generated interface from Pigeon that represents a handler of messages from Flutter.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); - indent.addln(''); - indent.write('companion object '); + indent.write('interface $apiName '); indent.scoped('{', '}', () { - indent.writeln('/** The codec used by $apiName. */'); - indent.write('val codec: MessageCodec by lazy '); - indent.scoped('{', '}', () { - if (isCustomCodec) { - indent.writeln(_getCodecName(api)); + for (final Method method in api.methods) { + final List argSignature = []; + if (method.arguments.isNotEmpty) { + final Iterable argTypes = method.arguments + .map((NamedType e) => _nullsafeKotlinTypeForDartType(e.type)); + final Iterable argNames = + method.arguments.map((NamedType e) => e.name); + argSignature.addAll( + map2(argTypes, argNames, (String argType, String argName) { + return '$argName: $argType'; + })); + } + + final String returnType = method.returnType.isVoid + ? '' + : _nullsafeKotlinTypeForDartType(method.returnType); + + addDocumentationComments( + indent, method.documentationComments, _docCommentSpec); + + if (method.isAsynchronous) { + argSignature.add('callback: ($returnType) -> Unit'); + indent.writeln('fun ${method.name}(${argSignature.join(', ')})'); + } else if (method.returnType.isVoid) { + indent.writeln('fun ${method.name}(${argSignature.join(', ')})'); } else { - indent.writeln('StandardMessageCodec()'); + indent.writeln( + 'fun ${method.name}(${argSignature.join(', ')}): $returnType'); } - }); - indent.writeln( - '/** Sets up an instance of `$apiName` to handle messages through the `binaryMessenger`. */'); - indent.writeln('@Suppress("UNCHECKED_CAST")'); - indent.write( - 'fun setUp(binaryMessenger: BinaryMessenger, api: $apiName?) '); + } + + indent.addln(''); + indent.write('companion object '); indent.scoped('{', '}', () { - for (final Method method in api.methods) { - indent.write('run '); - indent.scoped('{', '}', () { - String? taskQueue; - if (method.taskQueueType != TaskQueueType.serial) { - taskQueue = 'taskQueue'; - indent.writeln( - 'val $taskQueue = binaryMessenger.makeBackgroundTaskQueue()'); - } + indent.writeln('/** The codec used by $apiName. */'); + indent.write('val codec: MessageCodec by lazy '); + indent.scoped('{', '}', () { + if (isCustomCodec) { + indent.writeln(_getCodecName(api)); + } else { + indent.writeln('StandardMessageCodec()'); + } + }); + indent.writeln( + '/** Sets up an instance of `$apiName` to handle messages through the `binaryMessenger`. */'); + indent.writeln('@Suppress("UNCHECKED_CAST")'); + indent.write( + 'fun setUp(binaryMessenger: BinaryMessenger, api: $apiName?) '); + indent.scoped('{', '}', () { + for (final Method method in api.methods) { + indent.write('run '); + indent.scoped('{', '}', () { + String? taskQueue; + if (method.taskQueueType != TaskQueueType.serial) { + taskQueue = 'taskQueue'; + indent.writeln( + 'val $taskQueue = binaryMessenger.makeBackgroundTaskQueue()'); + } - final String channelName = makeChannelName(api, method); + final String channelName = makeChannelName(api, method); - indent.write( - 'val channel = BasicMessageChannel(binaryMessenger, "$channelName", codec'); + indent.write( + 'val channel = BasicMessageChannel(binaryMessenger, "$channelName", codec'); - if (taskQueue != null) { - indent.addln(', $taskQueue)'); - } else { - indent.addln(')'); - } + if (taskQueue != null) { + indent.addln(', $taskQueue)'); + } else { + indent.addln(')'); + } - indent.write('if (api != null) '); - indent.scoped('{', '}', () { - final String messageVarName = - method.arguments.isNotEmpty ? 'message' : '_'; - - indent.write('channel.setMessageHandler '); - indent.scoped('{ $messageVarName, reply ->', '}', () { - indent.writeln('var wrapped = listOf()'); - indent.write('try '); - indent.scoped('{', '}', () { - final List methodArgument = []; - if (method.arguments.isNotEmpty) { - indent.writeln('val args = message as List'); - enumerate(method.arguments, (int index, NamedType arg) { - final String argName = _getSafeArgumentName(index, arg); - final String argIndex = 'args[$index]'; - indent.writeln( - 'val $argName = ${_castForceUnwrap(argIndex, arg.type, root)}'); - methodArgument.add(argName); - }); - } - final String call = - 'api.${method.name}(${methodArgument.join(', ')})'; - if (method.isAsynchronous) { - indent.write('$call '); - final String resultValue = - method.returnType.isVoid ? 'null' : 'it'; - indent.scoped('{', '}', () { - indent.writeln('reply.reply(wrapResult($resultValue))'); - }); - } else if (method.returnType.isVoid) { - indent.writeln(call); - indent.writeln('wrapped = listOf(null)'); - } else { - indent.writeln('wrapped = listOf($call)'); - } - }, addTrailingNewline: false); - indent.add(' catch (exception: Error) '); - indent.scoped('{', '}', () { - indent.writeln('wrapped = wrapError(exception)'); - if (method.isAsynchronous) { + indent.write('if (api != null) '); + indent.scoped('{', '}', () { + final String messageVarName = + method.arguments.isNotEmpty ? 'message' : '_'; + + indent.write('channel.setMessageHandler '); + indent.scoped('{ $messageVarName, reply ->', '}', () { + indent.writeln('var wrapped = listOf()'); + indent.write('try '); + indent.scoped('{', '}', () { + final List methodArgument = []; + if (method.arguments.isNotEmpty) { + indent.writeln('val args = message as List'); + enumerate(method.arguments, (int index, NamedType arg) { + final String argName = _getSafeArgumentName(index, arg); + final String argIndex = 'args[$index]'; + indent.writeln( + 'val $argName = ${_castForceUnwrap(argIndex, arg.type, root)}'); + methodArgument.add(argName); + }); + } + final String call = + 'api.${method.name}(${methodArgument.join(', ')})'; + if (method.isAsynchronous) { + indent.write('$call '); + final String resultValue = + method.returnType.isVoid ? 'null' : 'it'; + indent.scoped('{', '}', () { + indent.writeln('reply.reply(wrapResult($resultValue))'); + }); + } else if (method.returnType.isVoid) { + indent.writeln(call); + indent.writeln('wrapped = listOf(null)'); + } else { + indent.writeln('wrapped = listOf($call)'); + } + }, addTrailingNewline: false); + indent.add(' catch (exception: Error) '); + indent.scoped('{', '}', () { + indent.writeln('wrapped = wrapError(exception)'); + if (method.isAsynchronous) { + indent.writeln('reply.reply(wrapped)'); + } + }); + if (!method.isAsynchronous) { indent.writeln('reply.reply(wrapped)'); } }); - if (!method.isAsynchronous) { - indent.writeln('reply.reply(wrapped)'); - } + }, addTrailingNewline: false); + indent.scoped(' else {', '}', () { + indent.writeln('channel.setMessageHandler(null)'); }); - }, addTrailingNewline: false); - indent.scoped(' else {', '}', () { - indent.writeln('channel.setMessageHandler(null)'); }); - }); - } + } + }); }); }); - }); -} - -String _getArgumentName(int count, NamedType argument) => - argument.name.isEmpty ? 'arg$count' : argument.name; - -/// Returns an argument name that can be used in a context where it is possible to collide. -String _getSafeArgumentName(int count, NamedType argument) => - '${_getArgumentName(count, argument)}Arg'; + } -/// Writes the code for a flutter [Api], [api]. -/// Example: -/// class Foo(private val binaryMessenger: BinaryMessenger) { -/// fun add(x: Int, y: Int, callback: (Int?) -> Unit) {...} -/// } -void _writeFlutterApi(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.flutter); - final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; - - const List generatedMessages = [ - ' Generated class from Pigeon that represents Flutter messages that can be called from Kotlin.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - - final String apiName = api.name; - indent.writeln('@Suppress("UNCHECKED_CAST")'); - indent.write('class $apiName(private val binaryMessenger: BinaryMessenger) '); - indent.scoped('{', '}', () { - indent.write('companion object '); + /// Writes the codec class that will be used by [api]. + /// Example: + /// private static class FooCodec extends StandardMessageCodec {...} + void _writeCodec(Indent indent, Api api, Root root) { + assert(getCodecClasses(api, root).isNotEmpty); + final Iterable codecClasses = getCodecClasses(api, root); + final String codecName = _getCodecName(api); + indent.writeln('@Suppress("UNCHECKED_CAST")'); + indent.write('private object $codecName : StandardMessageCodec() '); indent.scoped('{', '}', () { - indent.writeln('/** The codec used by $apiName. */'); - indent.write('val codec: MessageCodec by lazy '); + indent.write( + 'override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? '); indent.scoped('{', '}', () { - if (isCustomCodec) { - indent.writeln(_getCodecName(api)); - } else { - indent.writeln('StandardMessageCodec()'); - } + indent.write('return when (type) '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in codecClasses) { + indent.write('${customClass.enumeration}.toByte() -> '); + indent.scoped('{', '}', () { + indent.write('return (readValue(buffer) as? List)?.let '); + indent.scoped('{', '}', () { + indent.writeln('${customClass.name}.fromList(it)'); + }); + }); + } + indent.writeln('else -> super.readValueOfType(type, buffer)'); + }); + }); + + indent.write( + 'override fun writeValue(stream: ByteArrayOutputStream, value: Any?) '); + indent.writeScoped('{', '}', () { + indent.write('when (value) '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in codecClasses) { + indent.write('is ${customClass.name} -> '); + indent.scoped('{', '}', () { + indent.writeln('stream.write(${customClass.enumeration})'); + indent.writeln('writeValue(stream, value.toList())'); + }); + } + indent.writeln('else -> super.writeValue(stream, value)'); + }); }); }); + } - for (final Method func in api.methods) { - final String channelName = makeChannelName(api, func); - final String returnType = func.returnType.isVoid - ? '' - : _nullsafeKotlinTypeForDartType(func.returnType); - String sendArgument; - - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - - if (func.arguments.isEmpty) { - indent.write('fun ${func.name}(callback: ($returnType) -> Unit) '); - sendArgument = 'null'; - } else { - final Iterable argTypes = func.arguments - .map((NamedType e) => _nullsafeKotlinTypeForDartType(e.type)); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgumentName); - sendArgument = 'listOf(${argNames.join(', ')})'; - final String argsSignature = map2(argTypes, argNames, - (String type, String name) => '$name: $type').join(', '); - if (func.returnType.isVoid) { - indent - .write('fun ${func.name}($argsSignature, callback: () -> Unit) '); - } else { - indent.write( - 'fun ${func.name}($argsSignature, callback: ($returnType) -> Unit) '); - } - } - indent.scoped('{', '}', () { - const String channel = 'channel'; + void _writeWrapResult(Indent indent) { + indent.write('private fun wrapResult(result: Any?): List '); + indent.scoped('{', '}', () { + indent.writeln('return listOf(result)'); + }); + } + + void _writeWrapError(Indent indent) { + indent.write('private fun wrapError(exception: Throwable): List '); + indent.scoped('{', '}', () { + indent.write('return '); + indent.scoped('listOf(', ')', () { + indent.writeln('exception.javaClass.simpleName,'); + indent.writeln('exception.toString(),'); indent.writeln( - 'val $channel = BasicMessageChannel(binaryMessenger, "$channelName", codec)'); - indent.write('$channel.send($sendArgument) '); - if (func.returnType.isVoid) { - indent.scoped('{', '}', () { - indent.writeln('callback()'); - }); - } else { - final String forceUnwrap = func.returnType.isNullable ? '?' : ''; - indent.scoped('{', '}', () { - indent.writeln('val result = it as$forceUnwrap $returnType'); - indent.writeln('callback(result)'); - }); - } + '"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)'); }); - } - }); + }); + } } +HostDatatype _getHostDatatype(Root root, NamedType field) { + return getFieldHostDatatype(field, root.classes, root.enums, + (TypeDeclaration x) => _kotlinTypeForBuiltinDartType(x)); +} + +/// Calculates the name of the codec that will be generated for [api]. +String _getCodecName(Api api) => '${api.name}Codec'; + +String _getArgumentName(int count, NamedType argument) => + argument.name.isEmpty ? 'arg$count' : argument.name; + +/// Returns an argument name that can be used in a context where it is possible to collide. +String _getSafeArgumentName(int count, NamedType argument) => + '${_getArgumentName(count, argument)}Arg'; + String _castForceUnwrap(String value, TypeDeclaration type, Root root) { if (isEnum(root, type)) { final String forceUnwrap = type.isNullable ? '' : '!!'; @@ -677,55 +734,3 @@ String _nullsafeKotlinTypeForDartType(TypeDeclaration type) { final String nullSafe = type.isNullable ? '?' : ''; return '${_kotlinTypeForDartType(type)}$nullSafe'; } - -/// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateKotlin( - KotlinOptions options, Root root, StringSink sink, Indent indent) { - void writeApi(Api api) { - if (api.location == ApiLocation.host) { - _writeHostApi(indent, api, root); - } else if (api.location == ApiLocation.flutter) { - _writeFlutterApi(indent, api, root); - } - } - - void writeWrapResult() { - indent.write('private fun wrapResult(result: Any?): List '); - indent.scoped('{', '}', () { - indent.writeln('return listOf(result)'); - }); - } - - void writeWrapError() { - indent.write('private fun wrapError(exception: Throwable): List '); - indent.scoped('{', '}', () { - indent.write('return '); - indent.scoped('listOf(', ')', () { - indent.writeln('exception.javaClass.simpleName,'); - indent.writeln('exception.toString(),'); - indent.writeln( - '"Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception)'); - }); - }); - } - - if (root.apis.any((Api api) => - api.location == ApiLocation.host && - api.methods.any((Method it) => it.isAsynchronous))) { - indent.addln(''); - } - - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(indent, api, root); - indent.addln(''); - } - writeApi(api); - } - - indent.addln(''); - writeWrapResult(); - indent.addln(''); - writeWrapError(); -} From 434c98fa8abf8a063f7d962ba3488daa9aff2b26 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 23:25:07 -0800 Subject: [PATCH 66/87] swift --- packages/pigeon/lib/swift_generator.dart | 655 ++++++++++++----------- 1 file changed, 333 insertions(+), 322 deletions(-) diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index ed7db3685dd..15c5b51250a 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -68,7 +68,29 @@ class SwiftGenerator extends Generator { indent.addln(''); writeDataClass(generatorOptions, root, sink, indent, klass); } - generateSwift(generatorOptions, root, sink, indent); + + if (root.apis.any((Api api) => + api.location == ApiLocation.host && + api.methods.any((Method it) => it.isAsynchronous))) { + indent.addln(''); + } + + for (final Api api in root.apis) { + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(indent, api, root); + indent.addln(''); + } + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); + } + } + + indent.addln(''); + _writeWrapResult(indent); + indent.addln(''); + _writeWrapError(indent); } @override @@ -256,223 +278,345 @@ import FlutterMacOS indent.addln(defaultNil); } - HostDatatype _getHostDatatype(Root root, NamedType field) { - return getFieldHostDatatype(field, root.classes, root.enums, - (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); - } -} - -/// Calculates the name of the codec that will be generated for [api]. -String _getCodecName(Api api) => '${api.name}Codec'; + /// Writes the code for a flutter [Api], [api]. + /// Example: + /// class Foo { + /// private let binaryMessenger: FlutterBinaryMessenger + /// init(binaryMessenger: FlutterBinaryMessenger) {...} + /// func add(x: Int32, y: Int32, completion: @escaping (Int32?) -> Void) {...} + /// } + @override + void writeFlutterApi( + SwiftOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.flutter); + const List generatedComments = [ + ' Generated class from Pigeon that represents Flutter messages that can be called from Swift.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedComments); -/// Writes the codec classwill be used for encoding messages for the [api]. -/// Example: -/// private class FooHostApiCodecReader: FlutterStandardReader {...} -/// private class FooHostApiCodecWriter: FlutterStandardWriter {...} -/// private class FooHostApiCodecReaderWriter: FlutterStandardReaderWriter {...} -void _writeCodec(Indent indent, Api api, Root root) { - assert(getCodecClasses(api, root).isNotEmpty); - final String codecName = _getCodecName(api); - final String readerWriterName = '${codecName}ReaderWriter'; - final String readerName = '${codecName}Reader'; - final String writerName = '${codecName}Writer'; - - // Generate Reader - indent.write('private class $readerName: FlutterStandardReader '); - indent.scoped('{', '}', () { - if (getCodecClasses(api, root).isNotEmpty) { - indent.write('override func readValue(ofType type: UInt8) -> Any? '); + indent.write('class ${api.name} '); + indent.scoped('{', '}', () { + indent.writeln('private let binaryMessenger: FlutterBinaryMessenger'); + indent.write('init(binaryMessenger: FlutterBinaryMessenger)'); indent.scoped('{', '}', () { - indent.write('switch type '); + indent.writeln('self.binaryMessenger = binaryMessenger'); + }); + final String codecName = _getCodecName(api); + String codecArgumentString = ''; + if (getCodecClasses(api, root).isNotEmpty) { + codecArgumentString = ', codec: codec'; + indent.write('var codec: FlutterStandardMessageCodec '); indent.scoped('{', '}', () { - for (final EnumeratedClass customClass - in getCodecClasses(api, root)) { - indent.write('case ${customClass.enumeration}:'); - indent.scoped('', '', () { - indent.write( - 'return ${customClass.name}.fromList(self.readValue() as! [Any])'); - }); - } - indent.write('default:'); - indent.scoped('', '', () { - indent.writeln('return super.readValue(ofType: type)'); - }); + indent.writeln('return $codecName.shared'); }); - }); - } - }); + } + for (final Method func in api.methods) { + final String channelName = makeChannelName(api, func); + final String returnType = func.returnType.isVoid + ? '' + : _nullsafeSwiftTypeForDartType(func.returnType); + String sendArgument; + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); - // Generate Writer - indent.write('private class $writerName: FlutterStandardWriter '); - indent.scoped('{', '}', () { - if (getCodecClasses(api, root).isNotEmpty) { - indent.write('override func writeValue(_ value: Any) '); - indent.scoped('{', '}', () { - indent.write(''); - for (final EnumeratedClass customClass in getCodecClasses(api, root)) { - indent.add('if let value = value as? ${customClass.name} '); - indent.scoped('{', '} else ', () { - indent.writeln('super.writeByte(${customClass.enumeration})'); - indent.writeln('super.writeValue(value.toList())'); - }, addTrailingNewline: false); + if (func.arguments.isEmpty) { + indent.write( + 'func ${func.name}(completion: @escaping ($returnType) -> Void) '); + sendArgument = 'nil'; + } else { + final Iterable argTypes = func.arguments + .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type)); + final Iterable argLabels = + indexMap(func.arguments, _getArgumentName); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgumentName); + sendArgument = '[${argNames.join(', ')}]'; + final String argsSignature = map3( + argTypes, + argLabels, + argNames, + (String type, String label, String name) => + '$label $name: $type').join(', '); + if (func.returnType.isVoid) { + indent.write( + 'func ${func.name}($argsSignature, completion: @escaping () -> Void) '); + } else { + indent.write( + 'func ${func.name}($argsSignature, completion: @escaping ($returnType) -> Void) '); + } } indent.scoped('{', '}', () { - indent.writeln('super.writeValue(value)'); + const String channel = 'channel'; + indent.writeln( + 'let $channel = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger$codecArgumentString)'); + indent.write('$channel.sendMessage($sendArgument) '); + if (func.returnType.isVoid) { + indent.scoped('{ _ in', '}', () { + indent.writeln('completion()'); + }); + } else { + indent.scoped('{ response in', '}', () { + indent.writeln( + 'let result = ${_castForceUnwrap("response", func.returnType, root)}'); + indent.writeln('completion(result)'); + }); + } }); - }); - } - }); - indent.writeln(''); - - // Generate ReaderWriter - indent.write('private class $readerWriterName: FlutterStandardReaderWriter '); - indent.scoped('{', '}', () { - indent.write( - 'override func reader(with data: Data) -> FlutterStandardReader '); - indent.scoped('{', '}', () { - indent.writeln('return $readerName(data: data)'); - }); - indent.writeln(''); - indent.write( - 'override func writer(with data: NSMutableData) -> FlutterStandardWriter '); - indent.scoped('{', '}', () { - indent.writeln('return $writerName(data: data)'); + } }); - }); - indent.writeln(''); + } - // Generate Codec - indent.write('class $codecName: FlutterStandardMessageCodec '); - indent.scoped('{', '}', () { - indent.writeln( - 'static let shared = $codecName(readerWriter: $readerWriterName())'); - }); -} + /// Write the swift code that represents a host [Api], [api]. + /// Example: + /// protocol Foo { + /// Int32 add(x: Int32, y: Int32) + /// } + @override + void writeHostApi( + SwiftOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.host); -/// Write the swift code that represents a host [Api], [api]. -/// Example: -/// protocol Foo { -/// Int32 add(x: Int32, y: Int32) -/// } -void _writeHostApi(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.host); - - final String apiName = api.name; - - const List generatedComments = [ - ' Generated protocol from Pigeon that represents a handler of messages from Flutter.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedComments); - - indent.write('protocol $apiName '); - indent.scoped('{', '}', () { - for (final Method method in api.methods) { - final List argSignature = []; - if (method.arguments.isNotEmpty) { - final Iterable argTypes = method.arguments - .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type)); - final Iterable argNames = - method.arguments.map((NamedType e) => e.name); - argSignature - .addAll(map2(argTypes, argNames, (String argType, String argName) { - return '$argName: $argType'; - })); - } + final String apiName = api.name; - final String returnType = method.returnType.isVoid - ? '' - : _nullsafeSwiftTypeForDartType(method.returnType); - addDocumentationComments( - indent, method.documentationComments, _docCommentSpec); - - if (method.isAsynchronous) { - argSignature.add('completion: @escaping ($returnType) -> Void'); - indent.writeln('func ${method.name}(${argSignature.join(', ')})'); - } else if (method.returnType.isVoid) { - indent.writeln('func ${method.name}(${argSignature.join(', ')})'); - } else { - indent.writeln( - 'func ${method.name}(${argSignature.join(', ')}) -> $returnType'); - } - } - }); + const List generatedComments = [ + ' Generated protocol from Pigeon that represents a handler of messages from Flutter.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedComments); - indent.addln(''); - indent.writeln( - '$_docCommentPrefix Generated setup class from Pigeon to handle messages through the `binaryMessenger`.'); - indent.write('class ${apiName}Setup '); - indent.scoped('{', '}', () { - final String codecName = _getCodecName(api); - indent.writeln('$_docCommentPrefix The codec used by $apiName.'); - String codecArgumentString = ''; - if (getCodecClasses(api, root).isNotEmpty) { - codecArgumentString = ', codec: codec'; - indent.writeln( - 'static var codec: FlutterStandardMessageCodec { $codecName.shared }'); - } - indent.writeln( - '$_docCommentPrefix Sets up an instance of `$apiName` to handle messages through the `binaryMessenger`.'); - indent.write( - 'static func setUp(binaryMessenger: FlutterBinaryMessenger, api: $apiName?) '); + indent.write('protocol $apiName '); indent.scoped('{', '}', () { for (final Method method in api.methods) { - final String channelName = makeChannelName(api, method); - final String varChannelName = '${method.name}Channel'; + final List argSignature = []; + if (method.arguments.isNotEmpty) { + final Iterable argTypes = method.arguments + .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type)); + final Iterable argNames = + method.arguments.map((NamedType e) => e.name); + argSignature.addAll( + map2(argTypes, argNames, (String argType, String argName) { + return '$argName: $argType'; + })); + } + + final String returnType = method.returnType.isVoid + ? '' + : _nullsafeSwiftTypeForDartType(method.returnType); addDocumentationComments( indent, method.documentationComments, _docCommentSpec); + if (method.isAsynchronous) { + argSignature.add('completion: @escaping ($returnType) -> Void'); + indent.writeln('func ${method.name}(${argSignature.join(', ')})'); + } else if (method.returnType.isVoid) { + indent.writeln('func ${method.name}(${argSignature.join(', ')})'); + } else { + indent.writeln( + 'func ${method.name}(${argSignature.join(', ')}) -> $returnType'); + } + } + }); + + indent.addln(''); + indent.writeln( + '$_docCommentPrefix Generated setup class from Pigeon to handle messages through the `binaryMessenger`.'); + indent.write('class ${apiName}Setup '); + indent.scoped('{', '}', () { + final String codecName = _getCodecName(api); + indent.writeln('$_docCommentPrefix The codec used by $apiName.'); + String codecArgumentString = ''; + if (getCodecClasses(api, root).isNotEmpty) { + codecArgumentString = ', codec: codec'; indent.writeln( - 'let $varChannelName = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger$codecArgumentString)'); - indent.write('if let api = api '); - indent.scoped('{', '}', () { - indent.write('$varChannelName.setMessageHandler '); - final String messageVarName = - method.arguments.isNotEmpty ? 'message' : '_'; - indent.scoped('{ $messageVarName, reply in', '}', () { - final List methodArgument = []; - if (method.arguments.isNotEmpty) { - indent.writeln('let args = message as! [Any?]'); - enumerate(method.arguments, (int index, NamedType arg) { - final String argName = _getSafeArgumentName(index, arg); - final String argIndex = 'args[$index]'; - indent.writeln( - 'let $argName = ${_castForceUnwrap(argIndex, arg.type, root)}'); - methodArgument.add('${arg.name}: $argName'); - }); - } - final String call = - 'api.${method.name}(${methodArgument.join(', ')})'; - if (method.isAsynchronous) { - indent.write('$call '); - if (method.returnType.isVoid) { - indent.scoped('{', '}', () { - indent.writeln('reply(wrapResult(nil))'); - }); - } else { - indent.scoped('{ result in', '}', () { - indent.writeln('reply(wrapResult(result))'); + 'static var codec: FlutterStandardMessageCodec { $codecName.shared }'); + } + indent.writeln( + '$_docCommentPrefix Sets up an instance of `$apiName` to handle messages through the `binaryMessenger`.'); + indent.write( + 'static func setUp(binaryMessenger: FlutterBinaryMessenger, api: $apiName?) '); + indent.scoped('{', '}', () { + for (final Method method in api.methods) { + final String channelName = makeChannelName(api, method); + final String varChannelName = '${method.name}Channel'; + addDocumentationComments( + indent, method.documentationComments, _docCommentSpec); + + indent.writeln( + 'let $varChannelName = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger$codecArgumentString)'); + indent.write('if let api = api '); + indent.scoped('{', '}', () { + indent.write('$varChannelName.setMessageHandler '); + final String messageVarName = + method.arguments.isNotEmpty ? 'message' : '_'; + indent.scoped('{ $messageVarName, reply in', '}', () { + final List methodArgument = []; + if (method.arguments.isNotEmpty) { + indent.writeln('let args = message as! [Any?]'); + enumerate(method.arguments, (int index, NamedType arg) { + final String argName = _getSafeArgumentName(index, arg); + final String argIndex = 'args[$index]'; + indent.writeln( + 'let $argName = ${_castForceUnwrap(argIndex, arg.type, root)}'); + methodArgument.add('${arg.name}: $argName'); }); } - } else { - if (method.returnType.isVoid) { - indent.writeln(call); - indent.writeln('reply(wrapResult(nil))'); + final String call = + 'api.${method.name}(${methodArgument.join(', ')})'; + if (method.isAsynchronous) { + indent.write('$call '); + if (method.returnType.isVoid) { + indent.scoped('{', '}', () { + indent.writeln('reply(wrapResult(nil))'); + }); + } else { + indent.scoped('{ result in', '}', () { + indent.writeln('reply(wrapResult(result))'); + }); + } } else { - indent.writeln('let result = $call'); - indent.writeln('reply(wrapResult(result))'); + if (method.returnType.isVoid) { + indent.writeln(call); + indent.writeln('reply(wrapResult(nil))'); + } else { + indent.writeln('let result = $call'); + indent.writeln('reply(wrapResult(result))'); + } } + }); + }, addTrailingNewline: false); + indent.scoped(' else {', '}', () { + indent.writeln('$varChannelName.setMessageHandler(nil)'); + }); + } + }); + }); + } + + /// Writes the codec classwill be used for encoding messages for the [api]. + /// Example: + /// private class FooHostApiCodecReader: FlutterStandardReader {...} + /// private class FooHostApiCodecWriter: FlutterStandardWriter {...} + /// private class FooHostApiCodecReaderWriter: FlutterStandardReaderWriter {...} + void _writeCodec(Indent indent, Api api, Root root) { + assert(getCodecClasses(api, root).isNotEmpty); + final String codecName = _getCodecName(api); + final String readerWriterName = '${codecName}ReaderWriter'; + final String readerName = '${codecName}Reader'; + final String writerName = '${codecName}Writer'; + + // Generate Reader + indent.write('private class $readerName: FlutterStandardReader '); + indent.scoped('{', '}', () { + if (getCodecClasses(api, root).isNotEmpty) { + indent.write('override func readValue(ofType type: UInt8) -> Any? '); + indent.scoped('{', '}', () { + indent.write('switch type '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass + in getCodecClasses(api, root)) { + indent.write('case ${customClass.enumeration}:'); + indent.scoped('', '', () { + indent.write( + 'return ${customClass.name}.fromList(self.readValue() as! [Any])'); + }); } + indent.write('default:'); + indent.scoped('', '', () { + indent.writeln('return super.readValue(ofType: type)'); + }); }); - }, addTrailingNewline: false); - indent.scoped(' else {', '}', () { - indent.writeln('$varChannelName.setMessageHandler(nil)'); }); } }); - }); + + // Generate Writer + indent.write('private class $writerName: FlutterStandardWriter '); + indent.scoped('{', '}', () { + if (getCodecClasses(api, root).isNotEmpty) { + indent.write('override func writeValue(_ value: Any) '); + indent.scoped('{', '}', () { + indent.write(''); + for (final EnumeratedClass customClass + in getCodecClasses(api, root)) { + indent.add('if let value = value as? ${customClass.name} '); + indent.scoped('{', '} else ', () { + indent.writeln('super.writeByte(${customClass.enumeration})'); + indent.writeln('super.writeValue(value.toList())'); + }, addTrailingNewline: false); + } + indent.scoped('{', '}', () { + indent.writeln('super.writeValue(value)'); + }); + }); + } + }); + indent.writeln(''); + + // Generate ReaderWriter + indent + .write('private class $readerWriterName: FlutterStandardReaderWriter '); + indent.scoped('{', '}', () { + indent.write( + 'override func reader(with data: Data) -> FlutterStandardReader '); + indent.scoped('{', '}', () { + indent.writeln('return $readerName(data: data)'); + }); + indent.writeln(''); + indent.write( + 'override func writer(with data: NSMutableData) -> FlutterStandardWriter '); + indent.scoped('{', '}', () { + indent.writeln('return $writerName(data: data)'); + }); + }); + indent.writeln(''); + + // Generate Codec + indent.write('class $codecName: FlutterStandardMessageCodec '); + indent.scoped('{', '}', () { + indent.writeln( + 'static let shared = $codecName(readerWriter: $readerWriterName())'); + }); + } + + void _writeWrapResult(Indent indent) { + indent.write('private func wrapResult(_ result: Any?) -> [Any?] '); + indent.scoped('{', '}', () { + indent.writeln('return [result]'); + }); + } + + void _writeWrapError(Indent indent) { + indent.write('private func wrapError(_ error: FlutterError) -> [Any?] '); + indent.scoped('{', '}', () { + indent.write('return '); + indent.scoped('[', ']', () { + indent.writeln('error.code,'); + indent.writeln('error.message,'); + indent.writeln('error.details'); + }); + }); + } +} + +HostDatatype _getHostDatatype(Root root, NamedType field) { + return getFieldHostDatatype(field, root.classes, root.enums, + (TypeDeclaration x) => _swiftTypeForBuiltinDartType(x)); } +/// Calculates the name of the codec that will be generated for [api]. +String _getCodecName(Api api) => '${api.name}Codec'; + String _getArgumentName(int count, NamedType argument) => argument.name.isEmpty ? 'arg$count' : argument.name; @@ -487,93 +631,6 @@ String _camelCase(String text) { return pascal[0].toLowerCase() + pascal.substring(1); } -/// Writes the code for a flutter [Api], [api]. -/// Example: -/// class Foo { -/// private let binaryMessenger: FlutterBinaryMessenger -/// init(binaryMessenger: FlutterBinaryMessenger) {...} -/// func add(x: Int32, y: Int32, completion: @escaping (Int32?) -> Void) {...} -/// } -void _writeFlutterApi(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.flutter); - const List generatedComments = [ - ' Generated class from Pigeon that represents Flutter messages that can be called from Swift.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedComments); - - indent.write('class ${api.name} '); - indent.scoped('{', '}', () { - indent.writeln('private let binaryMessenger: FlutterBinaryMessenger'); - indent.write('init(binaryMessenger: FlutterBinaryMessenger)'); - indent.scoped('{', '}', () { - indent.writeln('self.binaryMessenger = binaryMessenger'); - }); - final String codecName = _getCodecName(api); - String codecArgumentString = ''; - if (getCodecClasses(api, root).isNotEmpty) { - codecArgumentString = ', codec: codec'; - indent.write('var codec: FlutterStandardMessageCodec '); - indent.scoped('{', '}', () { - indent.writeln('return $codecName.shared'); - }); - } - for (final Method func in api.methods) { - final String channelName = makeChannelName(api, func); - final String returnType = func.returnType.isVoid - ? '' - : _nullsafeSwiftTypeForDartType(func.returnType); - String sendArgument; - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - - if (func.arguments.isEmpty) { - indent.write( - 'func ${func.name}(completion: @escaping ($returnType) -> Void) '); - sendArgument = 'nil'; - } else { - final Iterable argTypes = func.arguments - .map((NamedType e) => _nullsafeSwiftTypeForDartType(e.type)); - final Iterable argLabels = - indexMap(func.arguments, _getArgumentName); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgumentName); - sendArgument = '[${argNames.join(', ')}]'; - final String argsSignature = map3( - argTypes, - argLabels, - argNames, - (String type, String label, String name) => - '$label $name: $type').join(', '); - if (func.returnType.isVoid) { - indent.write( - 'func ${func.name}($argsSignature, completion: @escaping () -> Void) '); - } else { - indent.write( - 'func ${func.name}($argsSignature, completion: @escaping ($returnType) -> Void) '); - } - } - indent.scoped('{', '}', () { - const String channel = 'channel'; - indent.writeln( - 'let $channel = FlutterBasicMessageChannel(name: "$channelName", binaryMessenger: binaryMessenger$codecArgumentString)'); - indent.write('$channel.sendMessage($sendArgument) '); - if (func.returnType.isVoid) { - indent.scoped('{ _ in', '}', () { - indent.writeln('completion()'); - }); - } else { - indent.scoped('{ response in', '}', () { - indent.writeln( - 'let result = ${_castForceUnwrap("response", func.returnType, root)}'); - indent.writeln('completion(result)'); - }); - } - }); - } - }); -} - String _castForceUnwrap(String value, TypeDeclaration type, Root root) { if (isEnum(root, type)) { final String forceUnwrap = type.isNullable ? '' : '!'; @@ -650,50 +707,4 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { /// Generates the ".swift" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateSwift( - SwiftOptions options, Root root, StringSink sink, Indent indent) { - void writeApi(Api api, Root root) { - if (api.location == ApiLocation.host) { - _writeHostApi(indent, api, root); - } else if (api.location == ApiLocation.flutter) { - _writeFlutterApi(indent, api, root); - } - } - - void writeWrapResult() { - indent.write('private func wrapResult(_ result: Any?) -> [Any?] '); - indent.scoped('{', '}', () { - indent.writeln('return [result]'); - }); - } - - void writeWrapError() { - indent.write('private func wrapError(_ error: FlutterError) -> [Any?] '); - indent.scoped('{', '}', () { - indent.write('return '); - indent.scoped('[', ']', () { - indent.writeln('error.code,'); - indent.writeln('error.message,'); - indent.writeln('error.details'); - }); - }); - } - - if (root.apis.any((Api api) => - api.location == ApiLocation.host && - api.methods.any((Method it) => it.isAsynchronous))) { - indent.addln(''); - } - - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(indent, api, root); - indent.addln(''); - } - writeApi(api, root); - } - - indent.addln(''); - writeWrapResult(); - indent.addln(''); - writeWrapError(); -} + SwiftOptions options, Root root, StringSink sink, Indent indent) {} From 1e1f7130ff584b64fddf03e94efd6b9092f82d6a Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 6 Jan 2023 23:50:29 -0800 Subject: [PATCH 67/87] cpp --- packages/pigeon/lib/cpp_generator.dart | 1195 ++++++++++++------------ 1 file changed, 614 insertions(+), 581 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 4c5ca20c0c4..71e02b42191 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -98,10 +98,31 @@ class CppGenerator extends Generator> { for (final Class klass in root.classes) { writeDataClass(generatorOptions, root, sink, indent, klass); } + + for (final Api api in root.apis) { + _writeCodec(generatorOptions, root, sink, indent, api); + indent.addln(''); + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); + } + } + if (generatorOptions.fileType == FileType.header) { - generateCppHeader(generatorOptions.languageOptions, root, sink, indent); + if (generatorOptions.languageOptions.namespace != null) { + indent.writeln( + '} // namespace ${generatorOptions.languageOptions.namespace}'); + } + final String guardName = _getGuardName( + generatorOptions.languageOptions.headerIncludePath, + generatorOptions.languageOptions.namespace); + indent.writeln('#endif // $guardName'); } else { - generateCppSource(generatorOptions.languageOptions, root, sink, indent); + if (generatorOptions.languageOptions.namespace != null) { + indent.writeln( + '} // namespace ${generatorOptions.languageOptions.namespace}'); + } } } @@ -166,6 +187,7 @@ class CppGenerator extends Generator> { Set customClassNames, Set customEnumNames, ) { + assert(generatorOptions.fileType == FileType.source); _writeCppSourceClassEncode(generatorOptions.languageOptions, root, sink, indent, klass, customClassNames, customEnumNames); } @@ -180,10 +202,57 @@ class CppGenerator extends Generator> { Set customClassNames, Set customEnumNames, ) { + assert(generatorOptions.fileType == FileType.source); _writeCppSourceClassDecode(generatorOptions, root, sink, indent, klass, customClassNames, customEnumNames); } + @override + void writeFlutterApi( + OutputFileOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + if (generatorOptions.fileType == FileType.header) { + _writeFlutterApiHeader(indent, api, root); + } else { + _writeFlutterApiSource(indent, api, root); + } + } + + @override + void writeHostApi( + OutputFileOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + if (generatorOptions.fileType == FileType.header) { + _writeHostApiHeader(indent, api, root); + } else { + _writeHostApiSource(indent, api, root); + } + } + + void _writeCodec( + OutputFileOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + if (generatorOptions.fileType == FileType.header) { + _writeCodecHeader(indent, api, root); + } else { + _writeCodecSource(indent, api, root); + } + } + + // Header methods. + /// Writes Cpp header file header to sink. void _writeCppHeaderPrologue(OutputFileOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -329,6 +398,199 @@ class CppGenerator extends Generator> { indent.writeln(''); } + void _writeCodecHeader(Indent indent, Api api, Root root) { + assert(getCodecClasses(api, root).isNotEmpty); + final String codeSerializerName = _getCodecSerializerName(api); + indent + .write('class $codeSerializerName : public $_defaultCodecSerializer '); + indent.scoped('{', '};', () { + indent.scoped(' public:', '', () { + indent.writeln(''); + indent.format(''' +inline static $codeSerializerName& GetInstance() { +\tstatic $codeSerializerName sInstance; +\treturn sInstance; +} +'''); + indent.writeln('$codeSerializerName();'); + }); + indent.writeScoped(' public:', '', () { + indent.writeln( + 'void WriteValue(const flutter::EncodableValue& value, flutter::ByteStreamWriter* stream) const override;'); + }); + indent.writeScoped(' protected:', '', () { + indent.writeln( + 'flutter::EncodableValue ReadValueOfType(uint8_t type, flutter::ByteStreamReader* stream) const override;'); + }); + }, nestCount: 0); + } + + void _writeErrorOr(Indent indent, + {Iterable friends = const []}) { + final String friendLines = friends + .map((String className) => '\tfriend class $className;') + .join('\n'); + indent.format(''' +class FlutterError { + public: +\texplicit FlutterError(const std::string& code) +\t\t: code_(code) {} +\texplicit FlutterError(const std::string& code, const std::string& message) +\t\t: code_(code), message_(message) {} +\texplicit FlutterError(const std::string& code, const std::string& message, const flutter::EncodableValue& details) +\t\t: code_(code), message_(message), details_(details) {} + +\tconst std::string& code() const { return code_; } +\tconst std::string& message() const { return message_; } +\tconst flutter::EncodableValue& details() const { return details_; } + + private: +\tstd::string code_; +\tstd::string message_; +\tflutter::EncodableValue details_; +}; + +template class ErrorOr { + public: +\tErrorOr(const T& rhs) { new(&v_) T(rhs); } +\tErrorOr(const T&& rhs) { v_ = std::move(rhs); } +\tErrorOr(const FlutterError& rhs) { +\t\tnew(&v_) FlutterError(rhs); +\t} +\tErrorOr(const FlutterError&& rhs) { v_ = std::move(rhs); } + +\tbool has_error() const { return std::holds_alternative(v_); } +\tconst T& value() const { return std::get(v_); }; +\tconst FlutterError& error() const { return std::get(v_); }; + + private: +$friendLines +\tErrorOr() = default; +\tT TakeValue() && { return std::get(std::move(v_)); } + +\tstd::variant v_; +}; +'''); + } + + void _writeHostApiHeader(Indent indent, Api api, Root root) { + assert(api.location == ApiLocation.host); + + const List generatedMessages = [ + ' Generated interface from Pigeon that represents a handler of messages from Flutter.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); + indent.write('class ${api.name} '); + indent.scoped('{', '};', () { + indent.scoped(' public:', '', () { + indent.writeln('${api.name}(const ${api.name}&) = delete;'); + indent.writeln('${api.name}& operator=(const ${api.name}&) = delete;'); + indent.writeln('virtual ~${api.name}() { };'); + for (final Method method in api.methods) { + final HostDatatype returnType = getHostDatatype( + method.returnType, + root.classes, + root.enums, + (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + final String returnTypeName = _apiReturnType(returnType); + + final List argSignature = []; + if (method.arguments.isNotEmpty) { + final Iterable argTypes = + method.arguments.map((NamedType arg) { + final HostDatatype hostType = getFieldHostDatatype( + arg, + root.classes, + root.enums, + (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + return _hostApiArgumentType(hostType); + }); + final Iterable argNames = + method.arguments.map((NamedType e) => _makeVariableName(e)); + argSignature.addAll( + map2(argTypes, argNames, (String argType, String argName) { + return '$argType $argName'; + })); + } + + addDocumentationComments( + indent, method.documentationComments, _docCommentSpec); + + if (method.isAsynchronous) { + argSignature + .add('std::function result'); + indent.writeln( + 'virtual void ${_makeMethodName(method)}(${argSignature.join(', ')}) = 0;'); + } else { + indent.writeln( + 'virtual $returnTypeName ${_makeMethodName(method)}(${argSignature.join(', ')}) = 0;'); + } + } + indent.addln(''); + indent.writeln('$_commentPrefix The codec used by ${api.name}.'); + indent + .writeln('static const flutter::StandardMessageCodec& GetCodec();'); + indent.writeln( + '$_commentPrefix Sets up an instance of `${api.name}` to handle messages through the `binary_messenger`.'); + indent.writeln( + 'static void SetUp(flutter::BinaryMessenger* binary_messenger, ${api.name}* api);'); + indent.writeln( + 'static flutter::EncodableList WrapError(std::string_view error_message);'); + indent.writeln( + 'static flutter::EncodableList WrapError(const FlutterError& error);'); + }); + indent.scoped(' protected:', '', () { + indent.writeln('${api.name}() = default;'); + }); + }, nestCount: 0); + } + + void _writeFlutterApiHeader(Indent indent, Api api, Root root) { + assert(api.location == ApiLocation.flutter); + + const List generatedMessages = [ + ' Generated class from Pigeon that represents Flutter messages that can be called from C++.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); + indent.write('class ${api.name} '); + indent.scoped('{', '};', () { + indent.scoped(' private:', '', () { + indent.writeln('flutter::BinaryMessenger* binary_messenger_;'); + }); + indent.scoped(' public:', '', () { + indent + .write('${api.name}(flutter::BinaryMessenger* binary_messenger);'); + indent.writeln(''); + indent + .writeln('static const flutter::StandardMessageCodec& GetCodec();'); + for (final Method func in api.methods) { + final String returnType = func.returnType.isVoid + ? 'void' + : _nullSafeCppTypeForDartType(func.returnType); + final String callback = 'std::function&& callback'; + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + if (func.arguments.isEmpty) { + indent.writeln('void ${func.name}($callback);'); + } else { + final Iterable argTypes = func.arguments + .map((NamedType e) => _nullSafeCppTypeForDartType(e.type)); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgumentName); + final String argsSignature = + map2(argTypes, argNames, (String x, String y) => '$x $y') + .join(', '); + indent.writeln('void ${func.name}($argsSignature, $callback);'); + } + } + }); + }, nestCount: 0); + } + + // Source methods. + /// Writes Cpp source file header to sink. void _writeCppSourcePrologue(OutputFileOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -549,569 +811,403 @@ else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodabl writeClassDecode(generatorOptions, root, sink, indent, klass, customClassNames, customEnumNames); } -} - -String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; - -const String _pointerPrefix = 'pointer'; -const String _encodablePrefix = 'encodable'; - -void _writeCodecHeader(Indent indent, Api api, Root root) { - assert(getCodecClasses(api, root).isNotEmpty); - final String codeSerializerName = _getCodecSerializerName(api); - indent.write('class $codeSerializerName : public $_defaultCodecSerializer '); - indent.scoped('{', '};', () { - indent.scoped(' public:', '', () { - indent.writeln(''); - indent.format(''' -inline static $codeSerializerName& GetInstance() { -\tstatic $codeSerializerName sInstance; -\treturn sInstance; -} -'''); - indent.writeln('$codeSerializerName();'); - }); - indent.writeScoped(' public:', '', () { - indent.writeln( - 'void WriteValue(const flutter::EncodableValue& value, flutter::ByteStreamWriter* stream) const override;'); - }); - indent.writeScoped(' protected:', '', () { - indent.writeln( - 'flutter::EncodableValue ReadValueOfType(uint8_t type, flutter::ByteStreamReader* stream) const override;'); - }); - }, nestCount: 0); -} -void _writeCodecSource(Indent indent, Api api, Root root) { - assert(getCodecClasses(api, root).isNotEmpty); - final String codeSerializerName = _getCodecSerializerName(api); - indent.writeln('$codeSerializerName::$codeSerializerName() {}'); - indent.write( - 'flutter::EncodableValue $codeSerializerName::ReadValueOfType(uint8_t type, flutter::ByteStreamReader* stream) const '); - indent.scoped('{', '}', () { - indent.write('switch (type) '); + void _writeCodecSource(Indent indent, Api api, Root root) { + assert(getCodecClasses(api, root).isNotEmpty); + final String codeSerializerName = _getCodecSerializerName(api); + indent.writeln('$codeSerializerName::$codeSerializerName() {}'); + indent.write( + 'flutter::EncodableValue $codeSerializerName::ReadValueOfType(uint8_t type, flutter::ByteStreamReader* stream) const '); indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in getCodecClasses(api, root)) { - indent.write('case ${customClass.enumeration}:'); + indent.write('switch (type) '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in getCodecClasses(api, root)) { + indent.write('case ${customClass.enumeration}:'); + indent.writeScoped('', '', () { + indent.writeln( + 'return flutter::CustomEncodableValue(${customClass.name}(std::get(ReadValue(stream))));'); + }); + } + indent.write('default:'); indent.writeScoped('', '', () { indent.writeln( - 'return flutter::CustomEncodableValue(${customClass.name}(std::get(ReadValue(stream))));'); - }); - } - indent.write('default:'); - indent.writeScoped('', '', () { - indent.writeln( - 'return $_defaultCodecSerializer::ReadValueOfType(type, stream);'); - }, addTrailingNewline: false); + 'return $_defaultCodecSerializer::ReadValueOfType(type, stream);'); + }, addTrailingNewline: false); + }); }); - }); - indent.writeln(''); - indent.write( - 'void $codeSerializerName::WriteValue(const flutter::EncodableValue& value, flutter::ByteStreamWriter* stream) const '); - indent.writeScoped('{', '}', () { + indent.writeln(''); indent.write( - 'if (const flutter::CustomEncodableValue* custom_value = std::get_if(&value)) '); - indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in getCodecClasses(api, root)) { - indent - .write('if (custom_value->type() == typeid(${customClass.name})) '); - indent.scoped('{', '}', () { - indent.writeln('stream->WriteByte(${customClass.enumeration});'); - indent.writeln( - 'WriteValue(flutter::EncodableValue(std::any_cast<${customClass.name}>(*custom_value).ToEncodableList()), stream);'); - indent.writeln('return;'); - }); - } - }); - indent.writeln('$_defaultCodecSerializer::WriteValue(value, stream);'); - }); -} - -void _writeErrorOr(Indent indent, - {Iterable friends = const []}) { - final String friendLines = friends - .map((String className) => '\tfriend class $className;') - .join('\n'); - indent.format(''' -class FlutterError { - public: -\texplicit FlutterError(const std::string& code) -\t\t: code_(code) {} -\texplicit FlutterError(const std::string& code, const std::string& message) -\t\t: code_(code), message_(message) {} -\texplicit FlutterError(const std::string& code, const std::string& message, const flutter::EncodableValue& details) -\t\t: code_(code), message_(message), details_(details) {} - -\tconst std::string& code() const { return code_; } -\tconst std::string& message() const { return message_; } -\tconst flutter::EncodableValue& details() const { return details_; } - - private: -\tstd::string code_; -\tstd::string message_; -\tflutter::EncodableValue details_; -}; - -template class ErrorOr { - public: -\tErrorOr(const T& rhs) { new(&v_) T(rhs); } -\tErrorOr(const T&& rhs) { v_ = std::move(rhs); } -\tErrorOr(const FlutterError& rhs) { -\t\tnew(&v_) FlutterError(rhs); -\t} -\tErrorOr(const FlutterError&& rhs) { v_ = std::move(rhs); } - -\tbool has_error() const { return std::holds_alternative(v_); } -\tconst T& value() const { return std::get(v_); }; -\tconst FlutterError& error() const { return std::get(v_); }; - - private: -$friendLines -\tErrorOr() = default; -\tT TakeValue() && { return std::get(std::move(v_)); } - -\tstd::variant v_; -}; -'''); -} - -void _writeHostApiHeader(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.host); - - const List generatedMessages = [ - ' Generated interface from Pigeon that represents a handler of messages from Flutter.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - indent.write('class ${api.name} '); - indent.scoped('{', '};', () { - indent.scoped(' public:', '', () { - indent.writeln('${api.name}(const ${api.name}&) = delete;'); - indent.writeln('${api.name}& operator=(const ${api.name}&) = delete;'); - indent.writeln('virtual ~${api.name}() { };'); - for (final Method method in api.methods) { - final HostDatatype returnType = getHostDatatype( - method.returnType, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - final String returnTypeName = _apiReturnType(returnType); - - final List argSignature = []; - if (method.arguments.isNotEmpty) { - final Iterable argTypes = - method.arguments.map((NamedType arg) { - final HostDatatype hostType = getFieldHostDatatype( - arg, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - return _hostApiArgumentType(hostType); + 'void $codeSerializerName::WriteValue(const flutter::EncodableValue& value, flutter::ByteStreamWriter* stream) const '); + indent.writeScoped('{', '}', () { + indent.write( + 'if (const flutter::CustomEncodableValue* custom_value = std::get_if(&value)) '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in getCodecClasses(api, root)) { + indent.write( + 'if (custom_value->type() == typeid(${customClass.name})) '); + indent.scoped('{', '}', () { + indent.writeln('stream->WriteByte(${customClass.enumeration});'); + indent.writeln( + 'WriteValue(flutter::EncodableValue(std::any_cast<${customClass.name}>(*custom_value).ToEncodableList()), stream);'); + indent.writeln('return;'); }); - final Iterable argNames = - method.arguments.map((NamedType e) => _makeVariableName(e)); - argSignature.addAll( - map2(argTypes, argNames, (String argType, String argName) { - return '$argType $argName'; - })); - } - - addDocumentationComments( - indent, method.documentationComments, _docCommentSpec); - - if (method.isAsynchronous) { - argSignature.add('std::function result'); - indent.writeln( - 'virtual void ${_makeMethodName(method)}(${argSignature.join(', ')}) = 0;'); - } else { - indent.writeln( - 'virtual $returnTypeName ${_makeMethodName(method)}(${argSignature.join(', ')}) = 0;'); } - } - indent.addln(''); - indent.writeln('$_commentPrefix The codec used by ${api.name}.'); - indent.writeln('static const flutter::StandardMessageCodec& GetCodec();'); - indent.writeln( - '$_commentPrefix Sets up an instance of `${api.name}` to handle messages through the `binary_messenger`.'); - indent.writeln( - 'static void SetUp(flutter::BinaryMessenger* binary_messenger, ${api.name}* api);'); - indent.writeln( - 'static flutter::EncodableList WrapError(std::string_view error_message);'); - indent.writeln( - 'static flutter::EncodableList WrapError(const FlutterError& error);'); - }); - indent.scoped(' protected:', '', () { - indent.writeln('${api.name}() = default;'); + }); + indent.writeln('$_defaultCodecSerializer::WriteValue(value, stream);'); }); - }, nestCount: 0); -} + } -void _writeHostApiSource(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.host); + void _writeHostApiSource(Indent indent, Api api, Root root) { + assert(api.location == ApiLocation.host); - final String codeSerializerName = getCodecClasses(api, root).isNotEmpty - ? _getCodecSerializerName(api) - : _defaultCodecSerializer; - indent.format(''' + final String codeSerializerName = getCodecClasses(api, root).isNotEmpty + ? _getCodecSerializerName(api) + : _defaultCodecSerializer; + indent.format(''' /// The codec used by ${api.name}. const flutter::StandardMessageCodec& ${api.name}::GetCodec() { \treturn flutter::StandardMessageCodec::GetInstance(&$codeSerializerName::GetInstance()); } '''); - indent.writeln( - '$_commentPrefix Sets up an instance of `${api.name}` to handle messages through the `binary_messenger`.'); - indent.write( - 'void ${api.name}::SetUp(flutter::BinaryMessenger* binary_messenger, ${api.name}* api) '); - indent.scoped('{', '}', () { - for (final Method method in api.methods) { - final String channelName = makeChannelName(api, method); - indent.write(''); - indent.scoped('{', '}', () { - indent.writeln( - 'auto channel = std::make_unique>('); - indent.inc(); - indent.inc(); - indent.writeln('binary_messenger, "$channelName", &GetCodec());'); - indent.dec(); - indent.dec(); - indent.write('if (api != nullptr) '); - indent.scoped('{', '} else {', () { - indent.write( - 'channel->SetMessageHandler([api](const flutter::EncodableValue& message, const flutter::MessageReply& reply) '); - indent.scoped('{', '});', () { - indent.writeln('flutter::EncodableList wrapped;'); - indent.write('try '); - indent.scoped('{', '}', () { - final List methodArgument = []; - if (method.arguments.isNotEmpty) { - indent.writeln( - 'const auto& args = std::get(message);'); - - // Writes the code to declare and populate a variable called - // [argName] to use as a parameter to an API method call from - // an existing EncodablValue variable called [encodableArgName] - // which corresponds to [arg] in the API definition. - void extractEncodedArgument( - String argName, - String encodableArgName, - NamedType arg, - HostDatatype hostType) { - if (arg.type.isNullable) { - // Nullable arguments are always pointers, with nullptr - // corresponding to null. - if (hostType.datatype == 'int64_t') { - // The EncodableValue will either be an int32_t or an - // int64_t depending on the value, but the generated API - // requires an int64_t so that it can handle any case. - // Create a local variable for the 64-bit value... - final String valueVarName = '${argName}_value'; - indent.writeln( - 'const int64_t $valueVarName = $encodableArgName.IsNull() ? 0 : $encodableArgName.LongValue();'); - // ... then declare the arg as a reference to that local. - indent.writeln( - 'const auto* $argName = $encodableArgName.IsNull() ? nullptr : &$valueVarName;'); - } else if (hostType.datatype == 'flutter::EncodableValue') { - // Generic objects just pass the EncodableValue through - // directly. - indent.writeln( - 'const auto* $argName = &$encodableArgName;'); - } else if (hostType.isBuiltin) { - indent.writeln( - 'const auto* $argName = std::get_if<${hostType.datatype}>(&$encodableArgName);'); - } else { - indent.writeln( - 'const auto* $argName = &(std::any_cast(std::get($encodableArgName)));'); - } - } else { - // Non-nullable arguments are either passed by value or - // reference, but the extraction doesn't need to distinguish - // since those are the same at the call site. - if (hostType.datatype == 'int64_t') { - // The EncodableValue will either be an int32_t or an - // int64_t depending on the value, but the generated API - // requires an int64_t so that it can handle any case. - indent.writeln( - 'const int64_t $argName = $encodableArgName.LongValue();'); - } else if (hostType.datatype == 'flutter::EncodableValue') { - // Generic objects just pass the EncodableValue through - // directly. This creates an alias just to avoid having to - // special-case the argName/encodableArgName distinction - // at a higher level. - indent - .writeln('const auto& $argName = $encodableArgName;'); - } else if (hostType.isBuiltin) { - indent.writeln( - 'const auto& $argName = std::get<${hostType.datatype}>($encodableArgName);'); + indent.writeln( + '$_commentPrefix Sets up an instance of `${api.name}` to handle messages through the `binary_messenger`.'); + indent.write( + 'void ${api.name}::SetUp(flutter::BinaryMessenger* binary_messenger, ${api.name}* api) '); + indent.scoped('{', '}', () { + for (final Method method in api.methods) { + final String channelName = makeChannelName(api, method); + indent.write(''); + indent.scoped('{', '}', () { + indent.writeln( + 'auto channel = std::make_unique>('); + indent.inc(); + indent.inc(); + indent.writeln('binary_messenger, "$channelName", &GetCodec());'); + indent.dec(); + indent.dec(); + indent.write('if (api != nullptr) '); + indent.scoped('{', '} else {', () { + indent.write( + 'channel->SetMessageHandler([api](const flutter::EncodableValue& message, const flutter::MessageReply& reply) '); + indent.scoped('{', '});', () { + indent.writeln('flutter::EncodableList wrapped;'); + indent.write('try '); + indent.scoped('{', '}', () { + final List methodArgument = []; + if (method.arguments.isNotEmpty) { + indent.writeln( + 'const auto& args = std::get(message);'); + + // Writes the code to declare and populate a variable called + // [argName] to use as a parameter to an API method call from + // an existing EncodablValue variable called [encodableArgName] + // which corresponds to [arg] in the API definition. + void extractEncodedArgument( + String argName, + String encodableArgName, + NamedType arg, + HostDatatype hostType) { + if (arg.type.isNullable) { + // Nullable arguments are always pointers, with nullptr + // corresponding to null. + if (hostType.datatype == 'int64_t') { + // The EncodableValue will either be an int32_t or an + // int64_t depending on the value, but the generated API + // requires an int64_t so that it can handle any case. + // Create a local variable for the 64-bit value... + final String valueVarName = '${argName}_value'; + indent.writeln( + 'const int64_t $valueVarName = $encodableArgName.IsNull() ? 0 : $encodableArgName.LongValue();'); + // ... then declare the arg as a reference to that local. + indent.writeln( + 'const auto* $argName = $encodableArgName.IsNull() ? nullptr : &$valueVarName;'); + } else if (hostType.datatype == + 'flutter::EncodableValue') { + // Generic objects just pass the EncodableValue through + // directly. + indent.writeln( + 'const auto* $argName = &$encodableArgName;'); + } else if (hostType.isBuiltin) { + indent.writeln( + 'const auto* $argName = std::get_if<${hostType.datatype}>(&$encodableArgName);'); + } else { + indent.writeln( + 'const auto* $argName = &(std::any_cast(std::get($encodableArgName)));'); + } } else { - indent.writeln( - 'const auto& $argName = std::any_cast(std::get($encodableArgName));'); + // Non-nullable arguments are either passed by value or + // reference, but the extraction doesn't need to distinguish + // since those are the same at the call site. + if (hostType.datatype == 'int64_t') { + // The EncodableValue will either be an int32_t or an + // int64_t depending on the value, but the generated API + // requires an int64_t so that it can handle any case. + indent.writeln( + 'const int64_t $argName = $encodableArgName.LongValue();'); + } else if (hostType.datatype == + 'flutter::EncodableValue') { + // Generic objects just pass the EncodableValue through + // directly. This creates an alias just to avoid having to + // special-case the argName/encodableArgName distinction + // at a higher level. + indent.writeln( + 'const auto& $argName = $encodableArgName;'); + } else if (hostType.isBuiltin) { + indent.writeln( + 'const auto& $argName = std::get<${hostType.datatype}>($encodableArgName);'); + } else { + indent.writeln( + 'const auto& $argName = std::any_cast(std::get($encodableArgName));'); + } } } - } - enumerate(method.arguments, (int index, NamedType arg) { - final HostDatatype hostType = getHostDatatype( - arg.type, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - final String argName = _getSafeArgumentName(index, arg); - - final String encodableArgName = - '${_encodablePrefix}_$argName'; - indent.writeln( - 'const auto& $encodableArgName = args.at($index);'); - if (!arg.type.isNullable) { - indent.write('if ($encodableArgName.IsNull()) '); - indent.scoped('{', '}', () { - indent.writeln( - 'reply(flutter::EncodableValue(WrapError("$argName unexpectedly null.")));'); - indent.writeln('return;'); - }); - } - extractEncodedArgument( - argName, encodableArgName, arg, hostType); - methodArgument.add(argName); - }); - } + enumerate(method.arguments, (int index, NamedType arg) { + final HostDatatype hostType = getHostDatatype( + arg.type, + root.classes, + root.enums, + (TypeDeclaration x) => + _baseCppTypeForBuiltinDartType(x)); + final String argName = _getSafeArgumentName(index, arg); + + final String encodableArgName = + '${_encodablePrefix}_$argName'; + indent.writeln( + 'const auto& $encodableArgName = args.at($index);'); + if (!arg.type.isNullable) { + indent.write('if ($encodableArgName.IsNull()) '); + indent.scoped('{', '}', () { + indent.writeln( + 'reply(flutter::EncodableValue(WrapError("$argName unexpectedly null.")));'); + indent.writeln('return;'); + }); + } + extractEncodedArgument( + argName, encodableArgName, arg, hostType); + methodArgument.add(argName); + }); + } - String wrapResponse(String reply, TypeDeclaration returnType) { - String elseBody = ''; - final String ifCondition; - final String errorGetter; - final String prefix = (reply != '') ? '\t' : ''; - - const String nullValue = 'flutter::EncodableValue()'; - if (returnType.isVoid) { - elseBody = - '$prefix\twrapped.push_back($nullValue);${indent.newline}'; - ifCondition = 'output.has_value()'; - errorGetter = 'value'; + final HostDatatype returnType = getHostDatatype( + method.returnType, + root.classes, + root.enums, + (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + final String returnTypeName = _apiReturnType(returnType); + if (method.isAsynchronous) { + methodArgument.add( + '[&wrapped, &reply]($returnTypeName&& output) {${indent.newline}' + '${_wrapResponse(indent, root, '\treply(flutter::EncodableValue(std::move(wrapped)));${indent.newline}', method.returnType)}' + '}', + ); + } + final String call = + 'api->${_makeMethodName(method)}(${methodArgument.join(', ')})'; + if (method.isAsynchronous) { + indent.format('$call;'); } else { - final HostDatatype hostType = getHostDatatype( - returnType, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - const String extractedValue = 'std::move(output).TakeValue()'; - final String wrapperType = hostType.isBuiltin - ? 'flutter::EncodableValue' - : 'flutter::CustomEncodableValue'; - if (returnType.isNullable) { - // The value is a std::optional, so needs an extra layer of - // handling. - elseBody = ''' -$prefix\tauto output_optional = $extractedValue; -$prefix\tif (output_optional) { -$prefix\t\twrapped.push_back($wrapperType(std::move(output_optional).value())); -$prefix\t} else { -$prefix\t\twrapped.push_back($nullValue); -$prefix\t}${indent.newline}'''; - } else { - elseBody = - '$prefix\twrapped.push_back($wrapperType($extractedValue));${indent.newline}'; - } - ifCondition = 'output.has_error()'; - errorGetter = 'error'; + indent.writeln('$returnTypeName output = $call;'); + indent.format( + _wrapResponse(indent, root, '', method.returnType)); } - return '${prefix}if ($ifCondition) {${indent.newline}' - '$prefix\twrapped = WrapError(output.$errorGetter());${indent.newline}' - '$prefix} else {${indent.newline}' - '$elseBody' - '$prefix}' - '$prefix$reply'; - } - - final HostDatatype returnType = getHostDatatype( - method.returnType, - root.classes, - root.enums, - (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - final String returnTypeName = _apiReturnType(returnType); - if (method.isAsynchronous) { - methodArgument.add( - '[&wrapped, &reply]($returnTypeName&& output) {${indent.newline}' - '${wrapResponse('\treply(flutter::EncodableValue(std::move(wrapped)));${indent.newline}', method.returnType)}' - '}', - ); - } - final String call = - 'api->${_makeMethodName(method)}(${methodArgument.join(', ')})'; - if (method.isAsynchronous) { - indent.format('$call;'); - } else { - indent.writeln('$returnTypeName output = $call;'); - indent.format(wrapResponse('', method.returnType)); - } - }); - indent.write('catch (const std::exception& exception) '); - indent.scoped('{', '}', () { - indent.writeln('wrapped = WrapError(exception.what());'); - if (method.isAsynchronous) { + }); + indent.write('catch (const std::exception& exception) '); + indent.scoped('{', '}', () { + indent.writeln('wrapped = WrapError(exception.what());'); + if (method.isAsynchronous) { + indent.writeln( + 'reply(flutter::EncodableValue(std::move(wrapped)));'); + } + }); + if (!method.isAsynchronous) { indent.writeln( 'reply(flutter::EncodableValue(std::move(wrapped)));'); } }); - if (!method.isAsynchronous) { - indent.writeln( - 'reply(flutter::EncodableValue(std::move(wrapped)));'); - } + }); + indent.scoped(null, '}', () { + indent.writeln('channel->SetMessageHandler(nullptr);'); }); }); - indent.scoped(null, '}', () { - indent.writeln('channel->SetMessageHandler(nullptr);'); - }); - }); - } - }); -} - -String _getArgumentName(int count, NamedType argument) => - argument.name.isEmpty ? 'arg$count' : _makeVariableName(argument); - -/// Returns an argument name that can be used in a context where it is possible to collide. -String _getSafeArgumentName(int count, NamedType argument) => - '${_getArgumentName(count, argument)}_arg'; - -void _writeFlutterApiHeader(Indent indent, Api api) { - assert(api.location == ApiLocation.flutter); - - const List generatedMessages = [ - ' Generated class from Pigeon that represents Flutter messages that can be called from C++.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - indent.write('class ${api.name} '); - indent.scoped('{', '};', () { - indent.scoped(' private:', '', () { - indent.writeln('flutter::BinaryMessenger* binary_messenger_;'); - }); - indent.scoped(' public:', '', () { - indent.write('${api.name}(flutter::BinaryMessenger* binary_messenger);'); - indent.writeln(''); - indent.writeln('static const flutter::StandardMessageCodec& GetCodec();'); - for (final Method func in api.methods) { - final String returnType = func.returnType.isVoid - ? 'void' - : _nullSafeCppTypeForDartType(func.returnType); - final String callback = 'std::function&& callback'; - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - if (func.arguments.isEmpty) { - indent.writeln('void ${func.name}($callback);'); - } else { - final Iterable argTypes = func.arguments - .map((NamedType e) => _nullSafeCppTypeForDartType(e.type)); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgumentName); - final String argsSignature = - map2(argTypes, argNames, (String x, String y) => '$x $y') - .join(', '); - indent.writeln('void ${func.name}($argsSignature, $callback);'); - } } }); - }, nestCount: 0); + + indent.addln(''); + indent.format(''' +flutter::EncodableList ${api.name}::WrapError(std::string_view error_message) { +\treturn flutter::EncodableList({ +\t\tflutter::EncodableValue(std::string(error_message)), +\t\tflutter::EncodableValue("Error"), +\t\tflutter::EncodableValue() +\t}); } +flutter::EncodableList ${api.name}::WrapError(const FlutterError& error) { +\treturn flutter::EncodableList({ +\t\tflutter::EncodableValue(error.message()), +\t\tflutter::EncodableValue(error.code()), +\t\terror.details() +\t}); +}'''); + indent.addln(''); + } -void _writeFlutterApiSource(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.flutter); - indent.writeln( - '$_commentPrefix Generated class from Pigeon that represents Flutter messages that can be called from C++.'); - indent.write( - '${api.name}::${api.name}(flutter::BinaryMessenger* binary_messenger) '); - indent.scoped('{', '}', () { - indent.writeln('this->binary_messenger_ = binary_messenger;'); - }); - indent.writeln(''); - final String codeSerializerName = getCodecClasses(api, root).isNotEmpty - ? _getCodecSerializerName(api) - : _defaultCodecSerializer; - indent.format(''' + String _wrapResponse( + Indent indent, Root root, String reply, TypeDeclaration returnType) { + String elseBody = ''; + final String ifCondition; + final String errorGetter; + final String prefix = (reply != '') ? '\t' : ''; + + const String nullValue = 'flutter::EncodableValue()'; + if (returnType.isVoid) { + elseBody = '$prefix\twrapped.push_back($nullValue);${indent.newline}'; + ifCondition = 'output.has_value()'; + errorGetter = 'value'; + } else { + final HostDatatype hostType = getHostDatatype(returnType, root.classes, + root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + const String extractedValue = 'std::move(output).TakeValue()'; + final String wrapperType = hostType.isBuiltin + ? 'flutter::EncodableValue' + : 'flutter::CustomEncodableValue'; + if (returnType.isNullable) { + // The value is a std::optional, so needs an extra layer of + // handling. + elseBody = ''' +$prefix\tauto output_optional = $extractedValue; +$prefix\tif (output_optional) { +$prefix\t\twrapped.push_back($wrapperType(std::move(output_optional).value())); +$prefix\t} else { +$prefix\t\twrapped.push_back($nullValue); +$prefix\t}${indent.newline}'''; + } else { + elseBody = + '$prefix\twrapped.push_back($wrapperType($extractedValue));${indent.newline}'; + } + ifCondition = 'output.has_error()'; + errorGetter = 'error'; + } + return '${prefix}if ($ifCondition) {${indent.newline}' + '$prefix\twrapped = WrapError(output.$errorGetter());${indent.newline}' + '$prefix} else {${indent.newline}' + '$elseBody' + '$prefix}' + '$prefix$reply'; + } + + void _writeFlutterApiSource(Indent indent, Api api, Root root) { + assert(api.location == ApiLocation.flutter); + indent.writeln( + '$_commentPrefix Generated class from Pigeon that represents Flutter messages that can be called from C++.'); + indent.write( + '${api.name}::${api.name}(flutter::BinaryMessenger* binary_messenger) '); + indent.scoped('{', '}', () { + indent.writeln('this->binary_messenger_ = binary_messenger;'); + }); + indent.writeln(''); + final String codeSerializerName = getCodecClasses(api, root).isNotEmpty + ? _getCodecSerializerName(api) + : _defaultCodecSerializer; + indent.format(''' const flutter::StandardMessageCodec& ${api.name}::GetCodec() { \treturn flutter::StandardMessageCodec::GetInstance(&$codeSerializerName::GetInstance()); } '''); - for (final Method func in api.methods) { - final String channelName = makeChannelName(api, func); - final String returnType = func.returnType.isVoid - ? 'void' - : _nullSafeCppTypeForDartType(func.returnType); - String sendArgument; - final String callback = 'std::function&& callback'; - if (func.arguments.isEmpty) { - indent.write('void ${api.name}::${func.name}($callback) '); - sendArgument = 'flutter::EncodableValue()'; - } else { - final Iterable argTypes = func.arguments - .map((NamedType e) => _nullSafeCppTypeForDartType(e.type)); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgumentName); - sendArgument = - 'flutter::EncodableList { ${argNames.map((String arg) => 'flutter::CustomEncodableValue($arg)').join(', ')} }'; - final String argsSignature = - map2(argTypes, argNames, (String x, String y) => '$x $y').join(', '); - indent - .write('void ${api.name}::${func.name}($argsSignature, $callback) '); - } - indent.scoped('{', '}', () { - const String channel = 'channel'; - indent.writeln( - 'auto channel = std::make_unique>('); - indent.inc(); - indent.inc(); - indent.writeln('binary_messenger_, "$channelName", &GetCodec());'); - indent.dec(); - indent.dec(); - indent.write( - '$channel->Send($sendArgument, [callback](const uint8_t* reply, size_t reply_size) '); - indent.scoped('{', '});', () { - if (func.returnType.isVoid) { - indent.writeln('callback();'); - } else { - indent.writeln( - 'std::unique_ptr decoded_reply = GetCodec().DecodeMessage(reply, reply_size);'); - indent.writeln( - 'flutter::EncodableValue args = *(flutter::EncodableValue*)(decoded_reply.release());'); - const String output = 'output'; - - final bool isBuiltin = - _baseCppTypeForBuiltinDartType(func.returnType) != null; - final String returnTypeName = - _baseCppTypeForDartType(func.returnType); - if (func.returnType.isNullable) { - indent.writeln('$returnType $output{};'); + for (final Method func in api.methods) { + final String channelName = makeChannelName(api, func); + final String returnType = func.returnType.isVoid + ? 'void' + : _nullSafeCppTypeForDartType(func.returnType); + String sendArgument; + final String callback = 'std::function&& callback'; + if (func.arguments.isEmpty) { + indent.write('void ${api.name}::${func.name}($callback) '); + sendArgument = 'flutter::EncodableValue()'; + } else { + final Iterable argTypes = func.arguments + .map((NamedType e) => _nullSafeCppTypeForDartType(e.type)); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgumentName); + sendArgument = + 'flutter::EncodableList { ${argNames.map((String arg) => 'flutter::CustomEncodableValue($arg)').join(', ')} }'; + final String argsSignature = + map2(argTypes, argNames, (String x, String y) => '$x $y') + .join(', '); + indent.write( + 'void ${api.name}::${func.name}($argsSignature, $callback) '); + } + indent.scoped('{', '}', () { + const String channel = 'channel'; + indent.writeln( + 'auto channel = std::make_unique>('); + indent.inc(); + indent.inc(); + indent.writeln('binary_messenger_, "$channelName", &GetCodec());'); + indent.dec(); + indent.dec(); + indent.write( + '$channel->Send($sendArgument, [callback](const uint8_t* reply, size_t reply_size) '); + indent.scoped('{', '});', () { + if (func.returnType.isVoid) { + indent.writeln('callback();'); } else { - indent.writeln('$returnTypeName $output{};'); - } - const String pointerVariable = '${_pointerPrefix}_$output'; - if (func.returnType.baseName == 'int') { - indent.format(''' + indent.writeln( + 'std::unique_ptr decoded_reply = GetCodec().DecodeMessage(reply, reply_size);'); + indent.writeln( + 'flutter::EncodableValue args = *(flutter::EncodableValue*)(decoded_reply.release());'); + const String output = 'output'; + + final bool isBuiltin = + _baseCppTypeForBuiltinDartType(func.returnType) != null; + final String returnTypeName = + _baseCppTypeForDartType(func.returnType); + if (func.returnType.isNullable) { + indent.writeln('$returnType $output{};'); + } else { + indent.writeln('$returnTypeName $output{};'); + } + const String pointerVariable = '${_pointerPrefix}_$output'; + if (func.returnType.baseName == 'int') { + indent.format(''' if (const int32_t* $pointerVariable = std::get_if(&args)) \t$output = *$pointerVariable; else if (const int64_t* ${pointerVariable}_64 = std::get_if(&args)) \t$output = *${pointerVariable}_64;'''); - } else if (!isBuiltin) { - indent.write( - 'if (const flutter::EncodableList* $pointerVariable = std::get_if(&args)) '); - indent.scoped('{', '}', () { - indent.writeln('$output = $returnTypeName(*$pointerVariable);'); - }); - } else { - indent.write( - 'if (const $returnTypeName* $pointerVariable = std::get_if<$returnTypeName>(&args)) '); - indent.scoped('{', '}', () { - indent.writeln('$output = *$pointerVariable;'); - }); - } + } else if (!isBuiltin) { + indent.write( + 'if (const flutter::EncodableList* $pointerVariable = std::get_if(&args)) '); + indent.scoped('{', '}', () { + indent.writeln('$output = $returnTypeName(*$pointerVariable);'); + }); + } else { + indent.write( + 'if (const $returnTypeName* $pointerVariable = std::get_if<$returnTypeName>(&args)) '); + indent.scoped('{', '}', () { + indent.writeln('$output = *$pointerVariable;'); + }); + } - indent.writeln('callback($output);'); - } + indent.writeln('callback($output);'); + } + }); }); - }); + } } } +String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; + +const String _pointerPrefix = 'pointer'; +const String _encodablePrefix = 'encodable'; + +String _getArgumentName(int count, NamedType argument) => + argument.name.isEmpty ? 'arg$count' : _makeVariableName(argument); + +/// Returns an argument name that can be used in a context where it is possible to collide. +String _getSafeArgumentName(int count, NamedType argument) => + '${_getArgumentName(count, argument)}_arg'; + /// Returns a non-nullable variant of [type]. HostDatatype _nonNullableType(HostDatatype type) { return HostDatatype( @@ -1287,69 +1383,6 @@ void _writeSystemHeaderIncludeBlock(Indent indent, List headers) { } } -/// Generates the ".h" file for the AST represented by [root] to [sink] with the -/// provided [options] and [headerFileName]. -void generateCppHeader( - CppOptions options, Root root, StringSink sink, Indent indent) { - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodecHeader(indent, api, root); - } - indent.addln(''); - if (api.location == ApiLocation.host) { - _writeHostApiHeader(indent, api, root); - } else if (api.location == ApiLocation.flutter) { - _writeFlutterApiHeader(indent, api); - } - } - - if (options.namespace != null) { - indent.writeln('} // namespace ${options.namespace}'); - } - final String guardName = - _getGuardName(options.headerIncludePath, options.namespace); - indent.writeln('#endif // $guardName'); -} - -/// Generates the ".cpp" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateCppSource( - CppOptions options, Root root, StringSink sink, Indent indent) { - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodecSource(indent, api, root); - indent.addln(''); - } - if (api.location == ApiLocation.host) { - _writeHostApiSource(indent, api, root); - - indent.addln(''); - indent.format(''' -flutter::EncodableList ${api.name}::WrapError(std::string_view error_message) { -\treturn flutter::EncodableList({ -\t\tflutter::EncodableValue(std::string(error_message)), -\t\tflutter::EncodableValue("Error"), -\t\tflutter::EncodableValue() -\t}); -} -flutter::EncodableList ${api.name}::WrapError(const FlutterError& error) { -\treturn flutter::EncodableList({ -\t\tflutter::EncodableValue(error.message()), -\t\tflutter::EncodableValue(error.code()), -\t\terror.details() -\t}); -}'''); - indent.addln(''); - } else if (api.location == ApiLocation.flutter) { - _writeFlutterApiSource(indent, api, root); - } - } - - if (options.namespace != null) { - indent.writeln('} // namespace ${options.namespace}'); - } -} - /// Validates an AST to make sure the cpp generator supports everything. List validateCpp(CppOptions options, Root root) { final List result = []; From 3038ae0f33b6f15347b4d24679876d0324ee751d Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Sat, 7 Jan 2023 01:06:14 -0800 Subject: [PATCH 68/87] objc --- packages/pigeon/lib/cpp_generator.dart | 8 +- packages/pigeon/lib/objc_generator.dart | 714 ++++++++++++------------ 2 files changed, 377 insertions(+), 345 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 71e02b42191..313c993ed64 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -79,7 +79,6 @@ class CppGenerator extends Generator> { @override void generate(OutputFileOptions generatorOptions, Root root, StringSink sink) { - final FileType fileType = generatorOptions.fileType; assert(generatorOptions.fileType == FileType.header || generatorOptions.fileType == FileType.source); @@ -100,8 +99,10 @@ class CppGenerator extends Generator> { } for (final Api api in root.apis) { - _writeCodec(generatorOptions, root, sink, indent, api); - indent.addln(''); + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(generatorOptions, root, sink, indent, api); + indent.addln(''); + } if (api.location == ApiLocation.host) { writeHostApi(generatorOptions, root, sink, indent, api); } else if (api.location == ApiLocation.flutter) { @@ -587,6 +588,7 @@ $friendLines } }); }, nestCount: 0); + indent.writeln(''); } // Source methods. diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 766917e1b1b..e09e3dbe2e8 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -105,10 +105,29 @@ class ObjcGenerator extends Generator> { writeDataClass(generatorOptions, root, sink, indent, klass); } + indent.writeln(''); + + for (final Api api in root.apis) { + if (generatorOptions.fileType == FileType.source) { + final String codecName = + _getCodecName(generatorOptions.languageOptions.prefix, api.name); + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec( + indent, codecName, generatorOptions.languageOptions, api, root); + indent.addln(''); + } + _writeCodecGetter( + indent, codecName, generatorOptions.languageOptions, api, root); + indent.addln(''); + } + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); + } + } if (generatorOptions.fileType == FileType.header) { - generateObjcHeader(generatorOptions.languageOptions, root, sink, indent); - } else { - generateObjcSource(generatorOptions.languageOptions, root, sink, indent); + indent.writeln('NS_ASSUME_NONNULL_END'); } } @@ -196,6 +215,39 @@ class ObjcGenerator extends Generator> { } } + @override + void writeFlutterApi( + OutputFileOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + if (generatorOptions.fileType == FileType.header) { + _writeFlutterApiDeclaration( + indent, api, generatorOptions.languageOptions, root); + } else { + _writeFlutterApiSource( + indent, generatorOptions.languageOptions, api, root); + } + } + + @override + void writeHostApi( + OutputFileOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + if (generatorOptions.fileType == FileType.header) { + _writeHostApiDeclaration( + indent, api, generatorOptions.languageOptions, root); + } else { + _writeHostApiSource(indent, generatorOptions.languageOptions, api, root); + } + } + // Header File Methods. /// Writes Objc header file header to sink. @@ -296,6 +348,118 @@ class ObjcGenerator extends Generator> { indent.writeln(''); } + /// Writes the declaration for an host [Api]. + /// + /// Example: + /// @protocol Foo + /// - (NSInteger)add:(NSInteger)x to:(NSInteger)y error:(NSError**)error; + /// @end + /// + /// extern void FooSetup(id binaryMessenger, NSObject *_Nullable api); + void _writeHostApiDeclaration( + Indent indent, Api api, ObjcOptions options, Root root) { + indent.writeln( + '$_docCommentPrefix The codec used by ${_className(options.prefix, api.name)}.'); + indent.writeln( + 'NSObject *${_getCodecGetterName(options.prefix, api.name)}(void);'); + indent.addln(''); + final String apiName = _className(options.prefix, api.name); + addDocumentationComments( + indent, api.documentationComments, _docCommentSpec); + + indent.writeln('@protocol $apiName'); + for (final Method func in api.methods) { + final _ObjcPtr returnTypeName = + _objcTypeForDartType(options.prefix, func.returnType); + + String? lastArgName; + String? lastArgType; + String? returnType; + if (func.isAsynchronous) { + returnType = 'void'; + if (func.returnType.isVoid) { + lastArgType = 'void(^)(FlutterError *_Nullable)'; + lastArgName = 'completion'; + } else { + lastArgType = + 'void(^)(${returnTypeName.ptr}_Nullable, FlutterError *_Nullable)'; + lastArgName = 'completion'; + } + } else { + returnType = func.returnType.isVoid + ? 'void' + : 'nullable ${returnTypeName.ptr.trim()}'; + lastArgType = 'FlutterError *_Nullable *_Nonnull'; + lastArgName = 'error'; + } + final List generatorComments = []; + if (!func.returnType.isNullable && + !func.returnType.isVoid && + !func.isAsynchronous) { + generatorComments.add(' @return `nil` only when `error != nil`.'); + } + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec, + generatorComments: generatorComments); + + final String signature = _makeObjcSignature( + func: func, + options: options, + returnType: returnType, + lastArgName: lastArgName, + lastArgType: lastArgType, + isEnum: (TypeDeclaration t) => isEnum(root, t), + ); + indent.writeln('$signature;'); + } + indent.writeln('@end'); + indent.writeln(''); + indent.writeln( + 'extern void ${apiName}Setup(id binaryMessenger, NSObject<$apiName> *_Nullable api);'); + indent.writeln(''); + } + + /// Writes the declaration for an flutter [Api]. + /// + /// Example: + /// + /// @interface Foo : NSObject + /// - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; + /// - (void)add:(NSInteger)x to:(NSInteger)y completion:(void(^)(NSError *, NSInteger result)completion; + /// @end + void _writeFlutterApiDeclaration( + Indent indent, Api api, ObjcOptions options, Root root) { + indent.writeln( + '$_docCommentPrefix The codec used by ${_className(options.prefix, api.name)}.'); + indent.writeln( + 'NSObject *${_getCodecGetterName(options.prefix, api.name)}(void);'); + indent.addln(''); + final String apiName = _className(options.prefix, api.name); + addDocumentationComments( + indent, api.documentationComments, _docCommentSpec); + + indent.writeln('@interface $apiName : NSObject'); + indent.writeln( + '- (instancetype)initWithBinaryMessenger:(id)binaryMessenger;'); + for (final Method func in api.methods) { + final _ObjcPtr returnType = + _objcTypeForDartType(options.prefix, func.returnType); + final String callbackType = _callbackForType(func.returnType, returnType); + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + + indent.writeln('${_makeObjcSignature( + func: func, + options: options, + returnType: 'void', + lastArgName: 'completion', + lastArgType: callbackType, + isEnum: (TypeDeclaration t) => isEnum(root, t), + )};'); + } + indent.writeln('@end'); + } + // Source File Methods. /// Writes Objc Source file header to sink. @@ -453,6 +617,138 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { }); }); } + + /// Writes the method declaration for the initializer. + /// + /// Example '+ (instancetype)makeWithFoo:(NSString *)foo' + void _writeObjcSourceClassInitializerDeclaration(Indent indent, Class klass, + List classes, List enums, String? prefix) { + final List customEnumNames = enums.map((Enum x) => x.name).toList(); + indent.write('+ (instancetype)makeWith'); + bool isFirst = true; + indent.nest(2, () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final String label = isFirst ? _capitalize(field.name) : field.name; + final void Function(String) printer = isFirst + ? indent.add + : (String x) { + indent.addln(''); + indent.write(x); + }; + isFirst = false; + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + classes, + enums, + (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), + customResolver: customEnumNames.contains(field.type.baseName) + ? (String x) => _className(prefix, x) + : (String x) => '${_className(prefix, x)} *'); + final String nullable = + _isNullable(hostDatatype, field.type) ? 'nullable ' : ''; + printer('$label:($nullable${hostDatatype.datatype})${field.name}'); + } + }); + } + + /// Writes the codec that will be used for encoding messages for the [api]. + /// + /// Example: + /// @interface FooHostApiCodecReader : FlutterStandardReader + /// ... + /// @interface FooHostApiCodecWriter : FlutterStandardWriter + /// ... + /// @interface FooHostApiCodecReaderWriter : FlutterStandardReaderWriter + /// ... + /// NSObject *FooHostApiCodecGetCodec() {...} + void _writeCodec( + Indent indent, String name, ObjcOptions options, Api api, Root root) { + assert(getCodecClasses(api, root).isNotEmpty); + final Iterable codecClasses = getCodecClasses(api, root); + final String readerWriterName = '${name}ReaderWriter'; + final String readerName = '${name}Reader'; + final String writerName = '${name}Writer'; + indent.writeln('@interface $readerName : FlutterStandardReader'); + indent.writeln('@end'); + indent.writeln('@implementation $readerName'); + indent.writeln('- (nullable id)readValueOfType:(UInt8)type '); + indent.scoped('{', '}', () { + indent.write('switch (type) '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in codecClasses) { + indent.write('case ${customClass.enumeration}: '); + indent.writeScoped('', '', () { + indent.writeln( + 'return [${_className(options.prefix, customClass.name)} fromList:[self readValue]];'); + }); + } + indent.write('default:'); + indent.writeScoped('', '', () { + indent.writeln('return [super readValueOfType:type];'); + }); + }); + }); + indent.writeln('@end'); + indent.addln(''); + indent.writeln('@interface $writerName : FlutterStandardWriter'); + indent.writeln('@end'); + indent.writeln('@implementation $writerName'); + indent.writeln('- (void)writeValue:(id)value '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in codecClasses) { + indent.write( + 'if ([value isKindOfClass:[${_className(options.prefix, customClass.name)} class]]) '); + indent.scoped('{', '} else ', () { + indent.writeln('[self writeByte:${customClass.enumeration}];'); + indent.writeln('[self writeValue:[value toList]];'); + }); + } + indent.scoped('{', '}', () { + indent.writeln('[super writeValue:value];'); + }); + }); + indent.writeln('@end'); + indent.addln(''); + indent.format(''' +@interface $readerWriterName : FlutterStandardReaderWriter +@end +@implementation $readerWriterName +- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { +\treturn [[$writerName alloc] initWithData:data]; +} +- (FlutterStandardReader *)readerWithData:(NSData *)data { +\treturn [[$readerName alloc] initWithData:data]; +} +@end +'''); + } + + void _writeCodecGetter( + Indent indent, String name, ObjcOptions options, Api api, Root root) { + final String readerWriterName = '${name}ReaderWriter'; + + indent.write( + 'NSObject *${_getCodecGetterName(options.prefix, api.name)}() '); + indent.scoped('{', '}', () { + indent + .writeln('static FlutterStandardMessageCodec *sSharedObject = nil;'); + if (getCodecClasses(api, root).isNotEmpty) { + indent.writeln('static dispatch_once_t sPred = 0;'); + indent.write('dispatch_once(&sPred, ^'); + indent.scoped('{', '});', () { + indent.writeln( + '$readerWriterName *readerWriter = [[$readerWriterName alloc] init];'); + indent.writeln( + 'sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];'); + }); + } else { + indent.writeln( + 'sSharedObject = [FlutterStandardMessageCodec sharedInstance];'); + } + + indent.writeln('return sSharedObject;'); + }); + } } /// Calculates the ObjC class name, possibly prefixed. @@ -551,39 +847,6 @@ String _propertyTypeForDartType(NamedType field) { bool _isNullable(HostDatatype hostDatatype, TypeDeclaration type) => hostDatatype.datatype.contains('*') && type.isNullable; -/// Writes the method declaration for the initializer. -/// -/// Example '+ (instancetype)makeWithFoo:(NSString *)foo' -void _writeObjcSourceClassInitializerDeclaration(Indent indent, Class klass, - List classes, List enums, String? prefix) { - final List customEnumNames = enums.map((Enum x) => x.name).toList(); - indent.write('+ (instancetype)makeWith'); - bool isFirst = true; - indent.nest(2, () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final String label = isFirst ? _capitalize(field.name) : field.name; - final void Function(String) printer = isFirst - ? indent.add - : (String x) { - indent.addln(''); - indent.write(x); - }; - isFirst = false; - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - classes, - enums, - (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), - customResolver: customEnumNames.contains(field.type.baseName) - ? (String x) => _className(prefix, x) - : (String x) => '${_className(prefix, x)} *'); - final String nullable = - _isNullable(hostDatatype, field.type) ? 'nullable ' : ''; - printer('$label:($nullable${hostDatatype.datatype})${field.name}'); - } - }); -} - /// Generates the name of the codec that will be generated. String _getCodecName(String? prefix, String className) => '${_className(prefix, className)}Codec'; @@ -593,104 +856,6 @@ String _getCodecName(String? prefix, String className) => String _getCodecGetterName(String? prefix, String className) => '${_className(prefix, className)}GetCodec'; -/// Writes the codec that will be used for encoding messages for the [api]. -/// -/// Example: -/// @interface FooHostApiCodecReader : FlutterStandardReader -/// ... -/// @interface FooHostApiCodecWriter : FlutterStandardWriter -/// ... -/// @interface FooHostApiCodecReaderWriter : FlutterStandardReaderWriter -/// ... -/// NSObject *FooHostApiCodecGetCodec() {...} -void _writeCodec( - Indent indent, String name, ObjcOptions options, Api api, Root root) { - assert(getCodecClasses(api, root).isNotEmpty); - final Iterable codecClasses = getCodecClasses(api, root); - final String readerWriterName = '${name}ReaderWriter'; - final String readerName = '${name}Reader'; - final String writerName = '${name}Writer'; - indent.writeln('@interface $readerName : FlutterStandardReader'); - indent.writeln('@end'); - indent.writeln('@implementation $readerName'); - indent.writeln('- (nullable id)readValueOfType:(UInt8)type '); - indent.scoped('{', '}', () { - indent.write('switch (type) '); - indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in codecClasses) { - indent.write('case ${customClass.enumeration}: '); - indent.writeScoped('', '', () { - indent.writeln( - 'return [${_className(options.prefix, customClass.name)} fromList:[self readValue]];'); - }); - } - indent.write('default:'); - indent.writeScoped('', '', () { - indent.writeln('return [super readValueOfType:type];'); - }); - }); - }); - indent.writeln('@end'); - indent.addln(''); - indent.writeln('@interface $writerName : FlutterStandardWriter'); - indent.writeln('@end'); - indent.writeln('@implementation $writerName'); - indent.writeln('- (void)writeValue:(id)value '); - indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in codecClasses) { - indent.write( - 'if ([value isKindOfClass:[${_className(options.prefix, customClass.name)} class]]) '); - indent.scoped('{', '} else ', () { - indent.writeln('[self writeByte:${customClass.enumeration}];'); - indent.writeln('[self writeValue:[value toList]];'); - }); - } - indent.scoped('{', '}', () { - indent.writeln('[super writeValue:value];'); - }); - }); - indent.writeln('@end'); - indent.addln(''); - indent.format(''' -@interface $readerWriterName : FlutterStandardReaderWriter -@end -@implementation $readerWriterName -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { -\treturn [[$writerName alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { -\treturn [[$readerName alloc] initWithData:data]; -} -@end -'''); -} - -void _writeCodecGetter( - Indent indent, String name, ObjcOptions options, Api api, Root root) { - final String readerWriterName = '${name}ReaderWriter'; - - indent.write( - 'NSObject *${_getCodecGetterName(options.prefix, api.name)}() '); - indent.scoped('{', '}', () { - indent.writeln('static FlutterStandardMessageCodec *sSharedObject = nil;'); - if (getCodecClasses(api, root).isNotEmpty) { - indent.writeln('static dispatch_once_t sPred = 0;'); - indent.write('dispatch_once(&sPred, ^'); - indent.scoped('{', '});', () { - indent.writeln( - '$readerWriterName *readerWriter = [[$readerWriterName alloc] init];'); - indent.writeln( - 'sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];'); - }); - } else { - indent.writeln( - 'sSharedObject = [FlutterStandardMessageCodec sharedInstance];'); - } - - indent.writeln('return sSharedObject;'); - }); -} - String _capitalize(String str) => (str.isEmpty) ? '' : str[0].toUpperCase() + str.substring(1); @@ -770,127 +935,10 @@ String _makeObjcSignature({ return '- ($returnType)$argSignature'; } -/// Writes the declaration for an host [Api]. -/// -/// Example: -/// @protocol Foo -/// - (NSInteger)add:(NSInteger)x to:(NSInteger)y error:(NSError**)error; -/// @end -/// -/// extern void FooSetup(id binaryMessenger, NSObject *_Nullable api); -void _writeHostApiDeclaration( - Indent indent, Api api, ObjcOptions options, Root root) { - final String apiName = _className(options.prefix, api.name); - addDocumentationComments(indent, api.documentationComments, _docCommentSpec); - - indent.writeln('@protocol $apiName'); - for (final Method func in api.methods) { - final _ObjcPtr returnTypeName = - _objcTypeForDartType(options.prefix, func.returnType); - - String? lastArgName; - String? lastArgType; - String? returnType; - if (func.isAsynchronous) { - returnType = 'void'; - if (func.returnType.isVoid) { - lastArgType = 'void(^)(FlutterError *_Nullable)'; - lastArgName = 'completion'; - } else { - lastArgType = - 'void(^)(${returnTypeName.ptr}_Nullable, FlutterError *_Nullable)'; - lastArgName = 'completion'; - } - } else { - returnType = func.returnType.isVoid - ? 'void' - : 'nullable ${returnTypeName.ptr.trim()}'; - lastArgType = 'FlutterError *_Nullable *_Nonnull'; - lastArgName = 'error'; - } - final List generatorComments = []; - if (!func.returnType.isNullable && - !func.returnType.isVoid && - !func.isAsynchronous) { - generatorComments.add(' @return `nil` only when `error != nil`.'); - } - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec, - generatorComments: generatorComments); - - final String signature = _makeObjcSignature( - func: func, - options: options, - returnType: returnType, - lastArgName: lastArgName, - lastArgType: lastArgType, - isEnum: (TypeDeclaration t) => isEnum(root, t), - ); - indent.writeln('$signature;'); - } - indent.writeln('@end'); - indent.writeln(''); - indent.writeln( - 'extern void ${apiName}Setup(id binaryMessenger, NSObject<$apiName> *_Nullable api);'); - indent.writeln(''); -} - -/// Writes the declaration for an flutter [Api]. -/// -/// Example: -/// -/// @interface Foo : NSObject -/// - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; -/// - (void)add:(NSInteger)x to:(NSInteger)y completion:(void(^)(NSError *, NSInteger result)completion; -/// @end -void _writeFlutterApiDeclaration( - Indent indent, Api api, ObjcOptions options, Root root) { - final String apiName = _className(options.prefix, api.name); - addDocumentationComments(indent, api.documentationComments, _docCommentSpec); - - indent.writeln('@interface $apiName : NSObject'); - indent.writeln( - '- (instancetype)initWithBinaryMessenger:(id)binaryMessenger;'); - for (final Method func in api.methods) { - final _ObjcPtr returnType = - _objcTypeForDartType(options.prefix, func.returnType); - final String callbackType = _callbackForType(func.returnType, returnType); - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - - indent.writeln('${_makeObjcSignature( - func: func, - options: options, - returnType: 'void', - lastArgName: 'completion', - lastArgType: callbackType, - isEnum: (TypeDeclaration t) => isEnum(root, t), - )};'); - } - indent.writeln('@end'); -} - /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options]. void generateObjcHeader( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - indent.writeln(''); - - for (final Api api in root.apis) { - indent.writeln( - '$_docCommentPrefix The codec used by ${_className(options.prefix, api.name)}.'); - indent.writeln( - 'NSObject *${_getCodecGetterName(options.prefix, api.name)}(void);'); - indent.addln(''); - if (api.location == ApiLocation.host) { - _writeHostApiDeclaration(indent, api, options, root); - } else if (api.location == ApiLocation.flutter) { - _writeFlutterApiDeclaration(indent, api, options, root); - } - } - - indent.writeln('NS_ASSUME_NONNULL_END'); -} + ObjcOptions options, Root root, StringSink sink, Indent indent) {} String _listGetter(Set customClassNames, String list, NamedType field, int index, String? prefix) { @@ -1078,105 +1126,87 @@ void _writeHostApiSource( /// Writes the definition code for a flutter [Api]. /// See also: [_writeFlutterApiDeclaration] void _writeFlutterApiSource( - Indent indent, ObjcOptions options, Api api, Root root) { + Indent indent, ObjcOptions languageOptions, Api api, Root root) { assert(api.location == ApiLocation.flutter); - final String apiName = _className(options.prefix, api.name); - - void writeExtension() { - indent.writeln('@interface $apiName ()'); - indent.writeln( - '@property (nonatomic, strong) NSObject *binaryMessenger;'); - indent.writeln('@end'); - } - - void writeInitializer() { - indent.write( - '- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger '); - indent.scoped('{', '}', () { - indent.writeln('self = [super init];'); - indent.write('if (self) '); - indent.scoped('{', '}', () { - indent.writeln('_binaryMessenger = binaryMessenger;'); - }); - indent.writeln('return self;'); - }); - } + final String apiName = _className(languageOptions.prefix, api.name); - void writeMethod(Method func) { - final _ObjcPtr returnType = - _objcTypeForDartType(options.prefix, func.returnType); - final String callbackType = _callbackForType(func.returnType, returnType); - - String argNameFunc(int count, NamedType arg) => _getSafeArgName(count, arg); - final Iterable argNames = indexMap(func.arguments, argNameFunc); - String sendArgument; - if (func.arguments.isEmpty) { - sendArgument = 'nil'; - } else { - String makeVarOrNSNullExpression(String x) => '$x ?: [NSNull null]'; - sendArgument = '@[${argNames.map(makeVarOrNSNullExpression).join(', ')}]'; - } - indent.write(_makeObjcSignature( - func: func, - options: options, - returnType: 'void', - lastArgName: 'completion', - lastArgType: callbackType, - argNameFunc: argNameFunc, - isEnum: (TypeDeclaration t) => isEnum(root, t), - )); - indent.scoped(' {', '}', () { - indent.writeln('FlutterBasicMessageChannel *channel ='); - indent.inc(); - indent.writeln('[FlutterBasicMessageChannel'); - indent.inc(); - indent.writeln('messageChannelWithName:@"${makeChannelName(api, func)}"'); - indent.writeln('binaryMessenger:self.binaryMessenger'); - indent.write('codec:${_getCodecGetterName(options.prefix, api.name)}()'); - indent.addln('];'); - indent.dec(); - indent.dec(); - indent.write('[channel sendMessage:$sendArgument reply:^(id reply) '); - indent.scoped('{', '}];', () { - if (func.returnType.isVoid) { - indent.writeln('completion(nil);'); - } else { - indent.writeln('${returnType.ptr}output = reply;'); - indent.writeln('completion(output, nil);'); - } - }); - }); - } - - writeExtension(); + _writeExtension(indent, apiName); indent.addln(''); indent.writeln('@implementation $apiName'); indent.addln(''); - writeInitializer(); - api.methods.forEach(writeMethod); + _writeInitializer(indent); + for (final Method func in api.methods) { + _writeMethod(languageOptions, root, indent, api, func); + } indent.writeln('@end'); } -/// Generates the ".m" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateObjcSource( - ObjcOptions options, Root root, StringSink sink, Indent indent) { - void writeApi(Api api) { - final String codecName = _getCodecName(options.prefix, api.name); - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(indent, codecName, options, api, root); - indent.addln(''); - } - _writeCodecGetter(indent, codecName, options, api, root); - indent.addln(''); - if (api.location == ApiLocation.host) { - _writeHostApiSource(indent, options, api, root); - } else if (api.location == ApiLocation.flutter) { - _writeFlutterApiSource(indent, options, api, root); - } - } +void _writeExtension(Indent indent, String apiName) { + indent.writeln('@interface $apiName ()'); + indent.writeln( + '@property (nonatomic, strong) NSObject *binaryMessenger;'); + indent.writeln('@end'); +} + +void _writeInitializer(Indent indent) { + indent.write( + '- (instancetype)initWithBinaryMessenger:(NSObject *)binaryMessenger '); + indent.scoped('{', '}', () { + indent.writeln('self = [super init];'); + indent.write('if (self) '); + indent.scoped('{', '}', () { + indent.writeln('_binaryMessenger = binaryMessenger;'); + }); + indent.writeln('return self;'); + }); +} - root.apis.forEach(writeApi); +void _writeMethod(ObjcOptions languageOptions, Root root, Indent indent, + Api api, Method func) { + final _ObjcPtr returnType = + _objcTypeForDartType(languageOptions.prefix, func.returnType); + final String callbackType = _callbackForType(func.returnType, returnType); + + String argNameFunc(int count, NamedType arg) => _getSafeArgName(count, arg); + final Iterable argNames = indexMap(func.arguments, argNameFunc); + String sendArgument; + if (func.arguments.isEmpty) { + sendArgument = 'nil'; + } else { + String makeVarOrNSNullExpression(String x) => '$x ?: [NSNull null]'; + sendArgument = '@[${argNames.map(makeVarOrNSNullExpression).join(', ')}]'; + } + indent.write(_makeObjcSignature( + func: func, + options: languageOptions, + returnType: 'void', + lastArgName: 'completion', + lastArgType: callbackType, + argNameFunc: argNameFunc, + isEnum: (TypeDeclaration t) => isEnum(root, t), + )); + indent.scoped(' {', '}', () { + indent.writeln('FlutterBasicMessageChannel *channel ='); + indent.inc(); + indent.writeln('[FlutterBasicMessageChannel'); + indent.inc(); + indent.writeln('messageChannelWithName:@"${makeChannelName(api, func)}"'); + indent.writeln('binaryMessenger:self.binaryMessenger'); + indent.write( + 'codec:${_getCodecGetterName(languageOptions.prefix, api.name)}()'); + indent.addln('];'); + indent.dec(); + indent.dec(); + indent.write('[channel sendMessage:$sendArgument reply:^(id reply) '); + indent.scoped('{', '}];', () { + if (func.returnType.isVoid) { + indent.writeln('completion(nil);'); + } else { + indent.writeln('${returnType.ptr}output = reply;'); + indent.writeln('completion(output, nil);'); + } + }); + }); } /// Looks through the AST for features that aren't supported by the ObjC From c1e8f667487be1fa2519ae4154d9826994762119 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Sat, 7 Jan 2023 01:15:58 -0800 Subject: [PATCH 69/87] remove unneeded java method --- packages/pigeon/lib/java_generator.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 5c541aaf27b..acbc901ab86 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -563,9 +563,6 @@ class JavaGenerator extends Generator { /// static void setup(BinaryMessenger binaryMessenger, Foo api) {...} void _writeMethodSetup(JavaOptions generatorOptions, Root root, StringSink sink, Indent indent, Api api, final Method method) { - //TODO(tarrinneal): See if this is needed or if generator_tools is enough - bool isEnum(TypeDeclaration type) => - root.enums.map((Enum e) => e.name).contains(type.baseName); final String channelName = makeChannelName(api, method); indent.write(''); indent.scoped('{', '}', () { @@ -614,7 +611,7 @@ class JavaGenerator extends Generator { ? '($argName == null) ? null : $argName.longValue()' : argName; String accessor = 'args.get($index)'; - if (isEnum(arg.type)) { + if (isEnum(root, arg.type)) { accessor = _intToEnum(accessor, arg.type.baseName); } else if (argType != 'Object') { accessor = '($argType)$accessor'; From 90960118c1dd875304b8db2d92c7c5715f322161 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Sat, 7 Jan 2023 13:19:14 -0800 Subject: [PATCH 70/87] analyze --- packages/pigeon/test/java_generator_test.dart | 1 - packages/pigeon/test/kotlin_generator_test.dart | 1 - packages/pigeon/test/swift_generator_test.dart | 1 - 3 files changed, 3 deletions(-) diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index 61cc14d9ed3..f2a25288754 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'package:pigeon/ast.dart'; -import 'package:pigeon/generator_tools.dart'; import 'package:pigeon/java_generator.dart'; import 'package:pigeon/pigeon.dart'; import 'package:test/test.dart'; diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 2e85079e426..96056c1b1b1 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'package:pigeon/ast.dart'; -import 'package:pigeon/generator_tools.dart'; import 'package:pigeon/kotlin_generator.dart'; import 'package:test/test.dart'; diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index 68c9d91fdad..305ca203fe7 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'package:pigeon/ast.dart'; -import 'package:pigeon/generator_tools.dart'; import 'package:pigeon/swift_generator.dart'; import 'package:test/test.dart'; From 2ed7097172e2467279f78111e4db267fac0cb202 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 10 Jan 2023 22:20:47 -0800 Subject: [PATCH 71/87] single file gens --- packages/pigeon/lib/dart_generator.dart | 49 +++------- packages/pigeon/lib/generator.dart | 94 +++++++++++++++++-- packages/pigeon/lib/java_generator.dart | 93 +++++++++++------- packages/pigeon/lib/kotlin_generator.dart | 78 +++++++-------- packages/pigeon/lib/swift_generator.dart | 77 +++++++-------- .../com/example/test_plugin/CoreTests.gen.kt | 2 - .../ios/Classes/CoreTests.gen.swift | 1 - .../macos/Classes/CoreTests.gen.swift | 1 - 8 files changed, 226 insertions(+), 169 deletions(-) diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 9de09227aa2..ba40f3f0f7e 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -71,35 +71,10 @@ class DartOptions { } /// Class that manages all Dart code generation. -class DartGenerator extends Generator { +class DartGenerator extends StructuredGenerator { /// Instantiates a Dart Generator. DartGenerator(); - /// Generates Dart files with specified [DartOptions] - @override - void generate(DartOptions generatorOptions, Root root, StringSink sink) { - final Indent indent = Indent(sink); - - writeFilePrologue(generatorOptions, root, sink, indent); - writeFileImports(generatorOptions, root, sink, indent); - for (final Enum anEnum in root.enums) { - writeEnum(generatorOptions, root, sink, indent, anEnum); - } - for (final Class klass in root.classes) { - indent.writeln(''); - writeDataClass(generatorOptions, root, sink, indent, klass); - } - - for (final Api api in root.apis) { - indent.writeln(''); - if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); - } - } - } - @override void writeFilePrologue( DartOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -150,22 +125,14 @@ class DartGenerator extends Generator { root.classes.map((Class x) => x.name).toSet(); final Set customEnumNames = root.enums.map((Enum x) => x.name).toSet(); - void writeConstructor() { - indent.write(klass.name); - indent.scoped('({', '});', () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final String required = field.type.isNullable ? '' : 'required '; - indent.writeln('${required}this.${field.name},'); - } - }); - } + indent.writeln(''); addDocumentationComments( indent, klass.documentationComments, _docCommentSpec); indent.write('class ${klass.name} '); indent.scoped('{', '}', () { - writeConstructor(); + _writeConstructor(indent, klass); indent.addln(''); for (final NamedType field in getFieldsInSerializationOrder(klass)) { addDocumentationComments( @@ -183,6 +150,16 @@ class DartGenerator extends Generator { }); } + void _writeConstructor(Indent indent, Class klass) { + indent.write(klass.name); + indent.scoped('({', '});', () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final String required = field.type.isNullable ? '' : 'required '; + indent.writeln('${required}this.${field.name},'); + } + }); + } + @override void writeClassEncode( DartOptions generatorOptions, diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 981fcc8dfbe..e0a3d6e6f66 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -10,19 +10,57 @@ import 'generator_tools.dart'; /// This provides the structure that is common across generators for different languages. abstract class Generator { /// Generates files for specified language with specified [generatorOptions] - /// - /// This method, when overridden, should follow a generic structure that is currently: - /// 1. Create Indent - /// 2. Write File Headers - /// 3. Write Imports - /// 4. Write Enums - /// 5. Write Data Classes - /// 6. Write Apis void generate( T generatorOptions, Root root, StringSink sink, ); +} + +/// A Superclass that enforces code generation across platforms. +abstract class StructuredGenerator extends Generator { + @override + void generate( + T generatorOptions, + Root root, + StringSink sink, + ) { + final Indent indent = Indent(sink); + + prePrologue(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, sink, indent); + writeFileImports(generatorOptions, root, sink, indent); + + preEnums(generatorOptions, root, sink, indent); + for (final Enum anEnum in root.enums) { + writeEnum(generatorOptions, root, sink, indent, anEnum); + } + + preDataClasses(generatorOptions, root, sink, indent); + for (final Class klass in root.classes) { + writeDataClass(generatorOptions, root, sink, indent, klass); + } + + preApis(generatorOptions, root, sink, indent); + for (final Api api in root.apis) { + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); + } + } + postWriteFile(generatorOptions, root, sink, indent); + } + + /// Pre-process or write before [writeFilePrologue]. + /// + /// This method is not a reqiured method, and does not need to be overriden if not needed. + void prePrologue( + T generatorOptions, + Root root, + StringSink sink, + Indent indent, + ) {} /// Adds specified headers to file. void writeFilePrologue( @@ -40,6 +78,16 @@ abstract class Generator { Indent indent, ); + /// Pre-process for enums or writes before any [writeEnum] calls. + /// + /// This method is not a reqiured method, and does not need to be overriden if not needed. + void preEnums( + T generatorOptions, + Root root, + StringSink sink, + Indent indent, + ) {} + /// Writes a single Enum to file. void writeEnum( T generatorOptions, @@ -49,6 +97,16 @@ abstract class Generator { Enum anEnum, ); + /// Pre-process for data classes or writes before any [writeDataClass] calls. + /// + /// This method is not a reqiured method, and does not need to be overriden if not needed. + void preDataClasses( + T generatorOptions, + Root root, + StringSink sink, + Indent indent, + ) {} + /// Writes a single data class to file. void writeDataClass( T generatorOptions, @@ -80,6 +138,16 @@ abstract class Generator { Set customEnumNames, ); + /// Pre-process for apis and/or writes before any [writeFlutterApi] or [writeHostApi] calls. + /// + /// This method is not a reqiured method, and does not need to be overriden if not needed. + void preApis( + T generatorOptions, + Root root, + StringSink sink, + Indent indent, + ) {} + /// Writes a single Flutter Api to file. void writeFlutterApi( T generatorOptions, @@ -97,4 +165,14 @@ abstract class Generator { Indent indent, Api api, ); + + /// Post-process for generate and/or writes after all other methods. + /// + /// This method is not a reqiured method, and does not need to be overriden if not needed. + void postWriteFile( + T generatorOptions, + Root root, + StringSink sink, + Indent indent, + ) {} } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index acbc901ab86..844695eabe9 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -86,7 +86,7 @@ class JavaOptions { } /// Class that manages all Java code generation. -class JavaGenerator extends Generator { +class JavaGenerator extends StructuredGenerator { /// Instantiates a Java Generator. JavaGenerator(); @@ -98,42 +98,22 @@ class JavaGenerator extends Generator { writeFilePrologue(generatorOptions, root, sink, indent); writeFileImports(generatorOptions, root, sink, indent); - indent.writeln( - '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); - indent.writeln( - '@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})'); - if (generatorOptions.useGeneratedAnnotation ?? false) { - indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); + preEnums(generatorOptions, root, sink, indent); + for (final Enum anEnum in root.enums) { + writeEnum(generatorOptions, root, sink, indent, anEnum); } - indent.write('public class ${generatorOptions.className!} '); - indent.scoped('{', '}', () { - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(generatorOptions, root, sink, indent, anEnum); - } - for (final Class klass in root.classes) { - indent.addln(''); - writeDataClass(generatorOptions, root, sink, indent, klass); - } - if (root.apis.any((Api api) => - api.location == ApiLocation.host && - api.methods.any((Method it) => it.isAsynchronous))) { - indent.addln(''); - _writeResultInterface(indent); - } - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(indent, api, root); - indent.addln(''); - } - if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); - } + for (final Class klass in root.classes) { + writeDataClass(generatorOptions, root, sink, indent, klass); + } + preApis(generatorOptions, root, sink, indent); + for (final Api api in root.apis) { + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); } - _writeWrapError(indent); - }); + } + postWriteFile(generatorOptions, root, sink, indent); } @override @@ -171,6 +151,20 @@ class JavaGenerator extends Generator { indent.addln(''); } + @override + void preEnums( + JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + indent.writeln( + '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); + indent.writeln( + '@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"})'); + if (generatorOptions.useGeneratedAnnotation ?? false) { + indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); + } + indent.writeln('public class ${generatorOptions.className!} {'); + indent.inc(); + } + @override void writeEnum(JavaOptions generatorOptions, Root root, StringSink sink, Indent indent, Enum anEnum) { @@ -181,6 +175,7 @@ class JavaGenerator extends Generator { .toUpperCase(); } + indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -212,6 +207,7 @@ class JavaGenerator extends Generator { const List generatedMessages = [ ' Generated class from Pigeon that represents data sent in messages.' ]; + indent.addln(''); addDocumentationComments( indent, klass.documentationComments, _docCommentSpec, generatorComments: generatedMessages); @@ -389,6 +385,9 @@ class JavaGenerator extends Generator { Api api, ) { assert(api.location == ApiLocation.flutter); + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(indent, api, root); + } const List generatedMessages = [ ' Generated class from Pigeon that represents Flutter messages that can be called from Java.' ]; @@ -479,6 +478,17 @@ class JavaGenerator extends Generator { }); } + @override + void preApis( + JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + if (root.apis.any((Api api) => + api.location == ApiLocation.host && + api.methods.any((Method it) => it.isAsynchronous))) { + indent.addln(''); + _writeResultInterface(indent); + } + } + /// Write the java code that represents a host [Api], [api]. /// Example: /// public interface Foo { @@ -489,7 +499,9 @@ class JavaGenerator extends Generator { void writeHostApi(JavaOptions generatorOptions, Root root, StringSink sink, Indent indent, Api api) { assert(api.location == ApiLocation.host); - + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(indent, api, root); + } const List generatedMessages = [ ' Generated interface from Pigeon that represents a handler of messages from Flutter.' ]; @@ -727,6 +739,7 @@ Result<$returnType> $resultName = new Result<$returnType>() { }); }); }); + indent.addln(''); } void _writeResultInterface(Indent indent) { @@ -747,6 +760,14 @@ Result<$returnType> $resultName = new Result<$returnType>() { \treturn errorList; }'''); } + + @override + void postWriteFile( + JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + _writeWrapError(indent); + indent.dec(); + indent.addln('}'); + } } /// Calculates the name of the codec that will be generated for [api]. diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index c0b5ae19a60..115f55be9f4 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -66,51 +66,10 @@ class KotlinOptions { } /// Class that manages all Kotlin code generation. -class KotlinGenerator extends Generator { +class KotlinGenerator extends StructuredGenerator { /// Instantiates a Kotlin Generator. KotlinGenerator(); - /// Generates the ".kotlin" file for the AST represented by [root] to [sink] with the - /// provided [KotlinOptions]. - @override - void generate(KotlinOptions generatorOptions, Root root, StringSink sink) { - final Indent indent = Indent(sink); - - writeFilePrologue(generatorOptions, root, sink, indent); - writeFileImports(generatorOptions, root, sink, indent); - indent.writeln('/** Generated class from Pigeon. */'); - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(generatorOptions, root, sink, indent, anEnum); - } - for (final Class klass in root.classes) { - indent.addln(''); - writeDataClass(generatorOptions, root, sink, indent, klass); - } - if (root.apis.any((Api api) => - api.location == ApiLocation.host && - api.methods.any((Method it) => it.isAsynchronous))) { - indent.addln(''); - } - - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(indent, api, root); - indent.addln(''); - } - if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); - } - } - - indent.addln(''); - _writeWrapResult(indent); - indent.addln(''); - _writeWrapError(indent); - } - @override void writeFilePrologue(KotlinOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -119,12 +78,12 @@ class KotlinGenerator extends Generator { } indent.writeln('// $generatedCodeWarning'); indent.writeln('// $seeAlsoWarning'); - indent.addln(''); } @override void writeFileImports(KotlinOptions generatorOptions, Root root, StringSink sink, Indent indent) { + indent.addln(''); if (generatorOptions.package != null) { indent.writeln('package ${generatorOptions.package}'); } @@ -136,12 +95,12 @@ class KotlinGenerator extends Generator { indent.writeln('import io.flutter.plugin.common.StandardMessageCodec'); indent.writeln('import java.io.ByteArrayOutputStream'); indent.writeln('import java.nio.ByteBuffer'); - indent.addln(''); } @override void writeEnum(KotlinOptions generatorOptions, Root root, StringSink sink, Indent indent, Enum anEnum) { + indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); indent.write('enum class ${anEnum.name}(val raw: Int) '); @@ -179,6 +138,7 @@ class KotlinGenerator extends Generator { const List generatedMessages = [ ' Generated class from Pigeon that represents data sent in messages.' ]; + indent.addln(''); addDocumentationComments( indent, klass.documentationComments, _docCommentSpec, generatorComments: generatedMessages); @@ -324,6 +284,20 @@ class KotlinGenerator extends Generator { indent.add(defaultNil); } + @override + void preApis( + KotlinOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + ) { + if (root.apis.any((Api api) => + api.location == ApiLocation.host && + api.methods.any((Method it) => it.isAsynchronous))) { + indent.addln(''); + } + } + /// Writes the code for a flutter [Api], [api]. /// Example: /// class Foo(private val binaryMessenger: BinaryMessenger) { @@ -339,6 +313,9 @@ class KotlinGenerator extends Generator { ) { assert(api.location == ApiLocation.flutter); final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; + if (isCustomCodec) { + _writeCodec(indent, api, root); + } const List generatedMessages = [ ' Generated class from Pigeon that represents Flutter messages that can be called from Kotlin.' @@ -435,6 +412,9 @@ class KotlinGenerator extends Generator { final String apiName = api.name; final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; + if (isCustomCodec) { + _writeCodec(indent, api, root); + } const List generatedMessages = [ ' Generated interface from Pigeon that represents a handler of messages from Flutter.' @@ -617,9 +597,11 @@ class KotlinGenerator extends Generator { }); }); }); + indent.addln(''); } void _writeWrapResult(Indent indent) { + indent.addln(''); indent.write('private fun wrapResult(result: Any?): List '); indent.scoped('{', '}', () { indent.writeln('return listOf(result)'); @@ -627,6 +609,7 @@ class KotlinGenerator extends Generator { } void _writeWrapError(Indent indent) { + indent.addln(''); indent.write('private fun wrapError(exception: Throwable): List '); indent.scoped('{', '}', () { indent.write('return '); @@ -638,6 +621,13 @@ class KotlinGenerator extends Generator { }); }); } + + @override + void postWriteFile(KotlinOptions generatorOptions, Root root, StringSink sink, + Indent indent) { + _writeWrapResult(indent); + _writeWrapError(indent); + } } HostDatatype _getHostDatatype(Root root, NamedType field) { diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 15c5b51250a..9e862cd0f33 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -49,50 +49,10 @@ class SwiftOptions { } /// Class that manages all Swift code generation. -class SwiftGenerator extends Generator { +class SwiftGenerator extends StructuredGenerator { /// Instantiates a Swift Generator. SwiftGenerator(); - /// Generates Swift files with specified [SwiftOptions] - @override - void generate(SwiftOptions generatorOptions, Root root, StringSink sink) { - final Indent indent = Indent(sink); - writeFilePrologue(generatorOptions, root, sink, indent); - writeFileImports(generatorOptions, root, sink, indent); - indent.writeln('$_docCommentPrefix Generated class from Pigeon.'); - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(generatorOptions, root, sink, indent, anEnum); - } - for (final Class klass in root.classes) { - indent.addln(''); - writeDataClass(generatorOptions, root, sink, indent, klass); - } - - if (root.apis.any((Api api) => - api.location == ApiLocation.host && - api.methods.any((Method it) => it.isAsynchronous))) { - indent.addln(''); - } - - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(indent, api, root); - indent.addln(''); - } - if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); - } - } - - indent.addln(''); - _writeWrapResult(indent); - indent.addln(''); - _writeWrapError(indent); - } - @override void writeFilePrologue(SwiftOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -123,6 +83,7 @@ import FlutterMacOS @override void writeEnum(SwiftOptions generatorOptions, Root root, StringSink sink, Indent indent, Enum anEnum) { + indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -147,6 +108,7 @@ import FlutterMacOS const List generatedComments = [ ' Generated class from Pigeon that represents data sent in messages.' ]; + indent.addln(''); addDocumentationComments( indent, klass.documentationComments, _docCommentSpec, generatorComments: generatedComments); @@ -278,6 +240,20 @@ import FlutterMacOS indent.addln(defaultNil); } + @override + void preApis( + SwiftOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + ) { + if (root.apis.any((Api api) => + api.location == ApiLocation.host && + api.methods.any((Method it) => it.isAsynchronous))) { + indent.addln(''); + } + } + /// Writes the code for a flutter [Api], [api]. /// Example: /// class Foo { @@ -294,6 +270,10 @@ import FlutterMacOS Api api, ) { assert(api.location == ApiLocation.flutter); + final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; + if (isCustomCodec) { + _writeCodec(indent, api, root); + } const List generatedComments = [ ' Generated class from Pigeon that represents Flutter messages that can be called from Swift.' ]; @@ -389,6 +369,11 @@ import FlutterMacOS final String apiName = api.name; + final bool isCustomCodec = getCodecClasses(api, root).isNotEmpty; + if (isCustomCodec) { + _writeCodec(indent, api, root); + } + const List generatedComments = [ ' Generated protocol from Pigeon that represents a handler of messages from Flutter.' ]; @@ -587,9 +572,11 @@ import FlutterMacOS indent.writeln( 'static let shared = $codecName(readerWriter: $readerWriterName())'); }); + indent.addln(''); } void _writeWrapResult(Indent indent) { + indent.addln(''); indent.write('private func wrapResult(_ result: Any?) -> [Any?] '); indent.scoped('{', '}', () { indent.writeln('return [result]'); @@ -597,6 +584,7 @@ import FlutterMacOS } void _writeWrapError(Indent indent) { + indent.addln(''); indent.write('private func wrapError(_ error: FlutterError) -> [Any?] '); indent.scoped('{', '}', () { indent.write('return '); @@ -607,6 +595,13 @@ import FlutterMacOS }); }); } + + @override + void postWriteFile(SwiftOptions generatorOptions, Root root, StringSink sink, + Indent indent) { + _writeWrapResult(indent); + _writeWrapError(indent); + } } HostDatatype _getHostDatatype(Root root, NamedType field) { diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index 15d31704b6d..903a87d4e70 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -15,8 +15,6 @@ import io.flutter.plugin.common.StandardMessageCodec import java.io.ByteArrayOutputStream import java.nio.ByteBuffer -/** Generated class from Pigeon. */ - enum class AnEnum(val raw: Int) { ONE(0), TWO(1), diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index ecd65d85009..2b4138e4b2b 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -15,7 +15,6 @@ import FlutterMacOS #endif -/// Generated class from Pigeon. enum AnEnum: Int { case one = 0 diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index ecd65d85009..2b4138e4b2b 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -15,7 +15,6 @@ import FlutterMacOS #endif -/// Generated class from Pigeon. enum AnEnum: Int { case one = 0 From 0da8ba8d6a74a5d20a6d3af1261bf761508fe36a Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 10 Jan 2023 23:28:01 -0800 Subject: [PATCH 72/87] objc --- packages/pigeon/lib/objc_generator.dart | 1005 ++++++++--------- .../ios/Classes/CoreTests.gen.h | 1 + .../ios/Classes/CoreTests.gen.m | 3 + 3 files changed, 465 insertions(+), 544 deletions(-) diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index e09e3dbe2e8..5c330de9be8 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -64,206 +64,41 @@ class ObjcOptions { } } -/// Class that manages all Objc header code generation. +/// Class that manages all Objc code generation. class ObjcGenerator extends Generator> { /// Instantiates a Objc Generator. ObjcGenerator(); - /// Generates Objc header files with specified [ObjcOptions] + /// Generates Objc files of type specified in [ObjcOptions] @override void generate(OutputFileOptions generatorOptions, Root root, StringSink sink) { - final Indent indent = Indent(sink); - - writeFilePrologue(generatorOptions, root, sink, indent); - writeFileImports(generatorOptions, root, sink, indent); if (generatorOptions.fileType == FileType.header) { - indent.writeln('NS_ASSUME_NONNULL_BEGIN'); - - for (final Enum anEnum in root.enums) { - indent.writeln(''); - writeEnum(generatorOptions, root, sink, indent, anEnum); - } - indent.writeln(''); - for (final Class klass in root.classes) { - indent.writeln( - '@class ${_className(generatorOptions.languageOptions.prefix, klass.name)};'); - } - indent.addln(''); + ObjcHeaderGenerator() + .generate(generatorOptions.languageOptions, root, sink); } else if (generatorOptions.fileType == FileType.source) { - _writeObjcSourceHelperFunctions(indent); - indent.addln(''); - - for (final Class klass in root.classes) { - _writeObjcSourceDataClassExtension( - generatorOptions.languageOptions, indent, klass); - } - indent.writeln(''); - } - - for (final Class klass in root.classes) { - writeDataClass(generatorOptions, root, sink, indent, klass); - } - - indent.writeln(''); - - for (final Api api in root.apis) { - if (generatorOptions.fileType == FileType.source) { - final String codecName = - _getCodecName(generatorOptions.languageOptions.prefix, api.name); - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec( - indent, codecName, generatorOptions.languageOptions, api, root); - indent.addln(''); - } - _writeCodecGetter( - indent, codecName, generatorOptions.languageOptions, api, root); - indent.addln(''); - } - if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); - } - } - if (generatorOptions.fileType == FileType.header) { - indent.writeln('NS_ASSUME_NONNULL_END'); - } - } - - @override - void writeFilePrologue(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent) { - if (generatorOptions.fileType == FileType.header) { - _writeObjcHeaderPrologue( - generatorOptions.languageOptions, root, sink, indent); - } else { - _writeObjcSourcePrologue( - generatorOptions.languageOptions, root, sink, indent); - } - } - - @override - void writeFileImports(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent) { - if (generatorOptions.fileType == FileType.header) { - _writeObjcHeaderImports( - generatorOptions.languageOptions, root, sink, indent); - } else { - _writeObjcSourceImports( - generatorOptions.languageOptions, root, sink, indent); - } - } - - @override - void writeEnum(OutputFileOptions generatorOptions, Root root, - StringSink sink, Indent indent, Enum anEnum) { - if (generatorOptions.fileType == FileType.header) { - _writeObjcHeaderEnum( - generatorOptions.languageOptions, root, sink, indent, anEnum); - } - } - - @override - void writeDataClass(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent, Class klass) { - if (generatorOptions.fileType == FileType.header) { - _writeObjcHeaderDataClass( - generatorOptions.languageOptions, root, sink, indent, klass); - } else { - _writeObjcSourceDataClassImplementation( - generatorOptions, root, sink, indent, klass); - indent.writeln(''); - } - } - - @override - void writeClassEncode( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - ) { - if (generatorOptions.fileType == FileType.source) { - final String className = - _className(generatorOptions.languageOptions.prefix, klass.name); - - _writeObjcSourceClassEncode(generatorOptions.languageOptions, root, sink, - indent, klass, customClassNames, customEnumNames, className); - } - } - - @override - void writeClassDecode( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - ) { - if (generatorOptions.fileType == FileType.source) { - final String className = - _className(generatorOptions.languageOptions.prefix, klass.name); - - _writeObjcSourceClassDecode(generatorOptions.languageOptions, root, sink, - indent, klass, customClassNames, customEnumNames, className); - } - } - - @override - void writeFlutterApi( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Api api, - ) { - if (generatorOptions.fileType == FileType.header) { - _writeFlutterApiDeclaration( - indent, api, generatorOptions.languageOptions, root); - } else { - _writeFlutterApiSource( - indent, generatorOptions.languageOptions, api, root); + ObjcSourceGenerator() + .generate(generatorOptions.languageOptions, root, sink); } } +} +/// Generates Objc .h file. +class ObjcHeaderGenerator extends StructuredGenerator { @override - void writeHostApi( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Api api, - ) { - if (generatorOptions.fileType == FileType.header) { - _writeHostApiDeclaration( - indent, api, generatorOptions.languageOptions, root); - } else { - _writeHostApiSource(indent, generatorOptions.languageOptions, api, root); - } - } - - // Header File Methods. - - /// Writes Objc header file header to sink. - void _writeObjcHeaderPrologue( - ObjcOptions languageOptions, Root root, StringSink sink, Indent indent) { - if (languageOptions.copyrightHeader != null) { - addLines(indent, languageOptions.copyrightHeader!, linePrefix: '// '); + void writeFilePrologue( + ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + if (generatorOptions.copyrightHeader != null) { + addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } indent.writeln('// $generatedCodeWarning'); indent.writeln('// $seeAlsoWarning'); indent.addln(''); } - /// Writes Objc header file imports to sink. - void _writeObjcHeaderImports( - ObjcOptions languageOptions, Root root, StringSink sink, Indent indent) { + @override + void writeFileImports( + ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { indent.writeln('#import '); indent.addln(''); @@ -272,12 +107,14 @@ class ObjcGenerator extends Generator> { indent.writeln('@class FlutterError;'); indent.writeln('@class FlutterStandardTypedData;'); indent.addln(''); + indent.writeln('NS_ASSUME_NONNULL_BEGIN'); } - /// Writes single Objc header enum. - void _writeObjcHeaderEnum(ObjcOptions languageOptions, Root root, - StringSink sink, Indent indent, Enum anEnum) { - final String enumName = _className(languageOptions.prefix, anEnum.name); + @override + void writeEnum(ObjcOptions generatorOptions, Root root, StringSink sink, + Indent indent, Enum anEnum) { + final String enumName = _className(generatorOptions.prefix, anEnum.name); + indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -293,14 +130,20 @@ class ObjcGenerator extends Generator> { }); } - /// Writes the class declaration for a data class. - /// - /// Example: - /// @interface Foo : NSObject - /// @property (nonatomic, copy) NSString *bar; - /// @end - void _writeObjcHeaderDataClass(ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass) { + @override + void preDataClasses( + ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + indent.writeln(''); + for (final Class klass in root.classes) { + indent.writeln( + '@class ${_className(generatorOptions.prefix, klass.name)};'); + } + indent.writeln(''); + } + + @override + void writeDataClass(ObjcOptions generatorOptions, Root root, StringSink sink, + Indent indent, Class klass) { final List classes = root.classes; final List enums = root.enums; final String? prefix = generatorOptions.prefix; @@ -348,29 +191,89 @@ class ObjcGenerator extends Generator> { indent.writeln(''); } - /// Writes the declaration for an host [Api]. - /// - /// Example: - /// @protocol Foo - /// - (NSInteger)add:(NSInteger)x to:(NSInteger)y error:(NSError**)error; - /// @end - /// - /// extern void FooSetup(id binaryMessenger, NSObject *_Nullable api); - void _writeHostApiDeclaration( - Indent indent, Api api, ObjcOptions options, Root root) { + @override + void writeClassEncode( + ObjcOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + ) {} + + @override + void writeClassDecode( + ObjcOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + ) {} + + @override + void writeFlutterApi( + ObjcOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { indent.writeln( - '$_docCommentPrefix The codec used by ${_className(options.prefix, api.name)}.'); + '$_docCommentPrefix The codec used by ${_className(generatorOptions.prefix, api.name)}.'); indent.writeln( - 'NSObject *${_getCodecGetterName(options.prefix, api.name)}(void);'); + 'NSObject *${_getCodecGetterName(generatorOptions.prefix, api.name)}(void);'); indent.addln(''); - final String apiName = _className(options.prefix, api.name); + final String apiName = _className(generatorOptions.prefix, api.name); + addDocumentationComments( + indent, api.documentationComments, _docCommentSpec); + + indent.writeln('@interface $apiName : NSObject'); + indent.writeln( + '- (instancetype)initWithBinaryMessenger:(id)binaryMessenger;'); + for (final Method func in api.methods) { + final _ObjcPtr returnType = + _objcTypeForDartType(generatorOptions.prefix, func.returnType); + final String callbackType = _callbackForType(func.returnType, returnType); + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + + indent.writeln('${_makeObjcSignature( + func: func, + options: generatorOptions, + returnType: 'void', + lastArgName: 'completion', + lastArgType: callbackType, + isEnum: (TypeDeclaration t) => isEnum(root, t), + )};'); + } + indent.writeln('@end'); + indent.writeln(''); + } + + @override + void writeHostApi( + ObjcOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + indent.writeln( + '$_docCommentPrefix The codec used by ${_className(generatorOptions.prefix, api.name)}.'); + indent.writeln( + 'NSObject *${_getCodecGetterName(generatorOptions.prefix, api.name)}(void);'); + indent.addln(''); + final String apiName = _className(generatorOptions.prefix, api.name); addDocumentationComments( indent, api.documentationComments, _docCommentSpec); indent.writeln('@protocol $apiName'); for (final Method func in api.methods) { final _ObjcPtr returnTypeName = - _objcTypeForDartType(options.prefix, func.returnType); + _objcTypeForDartType(generatorOptions.prefix, func.returnType); String? lastArgName; String? lastArgType; @@ -404,7 +307,7 @@ class ObjcGenerator extends Generator> { final String signature = _makeObjcSignature( func: func, - options: options, + options: generatorOptions, returnType: returnType, lastArgName: lastArgName, lastArgType: lastArgType, @@ -419,71 +322,330 @@ class ObjcGenerator extends Generator> { indent.writeln(''); } - /// Writes the declaration for an flutter [Api]. - /// - /// Example: - /// - /// @interface Foo : NSObject - /// - (instancetype)initWithBinaryMessenger:(id)binaryMessenger; - /// - (void)add:(NSInteger)x to:(NSInteger)y completion:(void(^)(NSError *, NSInteger result)completion; - /// @end - void _writeFlutterApiDeclaration( - Indent indent, Api api, ObjcOptions options, Root root) { - indent.writeln( - '$_docCommentPrefix The codec used by ${_className(options.prefix, api.name)}.'); - indent.writeln( - 'NSObject *${_getCodecGetterName(options.prefix, api.name)}(void);'); + @override + void postWriteFile( + ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + indent.writeln('NS_ASSUME_NONNULL_END'); + } +} + +/// Generates Objc .m file. +class ObjcSourceGenerator extends StructuredGenerator { + @override + void writeFilePrologue( + ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + if (generatorOptions.copyrightHeader != null) { + addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); + } + indent.writeln('// $generatedCodeWarning'); + indent.writeln('// $seeAlsoWarning'); indent.addln(''); - final String apiName = _className(options.prefix, api.name); - addDocumentationComments( - indent, api.documentationComments, _docCommentSpec); + } + + @override + void writeFileImports( + ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + indent.writeln('#import "${generatorOptions.headerIncludePath}"'); + indent.writeln('#import '); + indent.addln(''); + + indent.writeln('#if !__has_feature(objc_arc)'); + indent.writeln('#error File requires ARC to be enabled.'); + indent.writeln('#endif'); + indent.addln(''); + } + + @override + void writeEnum(ObjcOptions generatorOptions, Root root, StringSink sink, + Indent indent, Enum anEnum) { + // Intentionally left blank. + } + + @override + void preDataClasses( + ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + _writeObjcSourceHelperFunctions(indent); + indent.addln(''); + + for (final Class klass in root.classes) { + _writeObjcSourceDataClassExtension(generatorOptions, indent, klass); + } + indent.writeln(''); + } + + @override + void writeDataClass(ObjcOptions generatorOptions, Root root, StringSink sink, + Indent indent, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + final String className = _className(generatorOptions.prefix, klass.name); + + indent.writeln('@implementation $className'); + _writeObjcSourceClassInitializer(generatorOptions, root, sink, indent, + klass, customClassNames, customEnumNames, className); + writeClassDecode(generatorOptions, root, sink, indent, klass, + customClassNames, customEnumNames); + writeClassEncode(generatorOptions, root, sink, indent, klass, + customClassNames, customEnumNames); + indent.writeln('@end'); + indent.writeln(''); + } + + @override + void writeClassEncode( + ObjcOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + indent.write('- (NSArray *)toList '); + indent.scoped('{', '}', () { + indent.write('return'); + indent.scoped(' @[', '];', () { + for (final NamedType field in klass.fields) { + indent.writeln( + '${_arrayValue(customClassNames, customEnumNames, field)},'); + } + }); + }); + } + + @override + void writeClassDecode( + ObjcOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + final String className = _className(generatorOptions.prefix, klass.name); + indent.write('+ ($className *)fromList:(NSArray *)list '); + indent.scoped('{', '}', () { + const String resultName = 'pigeonResult'; + indent.writeln('$className *$resultName = [[$className alloc] init];'); + enumerate(getFieldsInSerializationOrder(klass), + (int index, final NamedType field) { + if (customEnumNames.contains(field.type.baseName)) { + indent.writeln( + '$resultName.${field.name} = [${_listGetter(customClassNames, 'list', field, index, generatorOptions.prefix)} integerValue];'); + } else { + indent.writeln( + '$resultName.${field.name} = ${_listGetter(customClassNames, 'list', field, index, generatorOptions.prefix)};'); + if (!field.type.isNullable) { + indent.writeln('NSAssert($resultName.${field.name} != nil, @"");'); + } + } + }); + indent.writeln('return $resultName;'); + }); - indent.writeln('@interface $apiName : NSObject'); indent.writeln( - '- (instancetype)initWithBinaryMessenger:(id)binaryMessenger;'); - for (final Method func in api.methods) { - final _ObjcPtr returnType = - _objcTypeForDartType(options.prefix, func.returnType); - final String callbackType = _callbackForType(func.returnType, returnType); - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); + '+ (nullable $className *)nullableFromList:(NSArray *)list { return (list) ? [$className fromList:list] : nil; }'); + } - indent.writeln('${_makeObjcSignature( - func: func, - options: options, - returnType: 'void', - lastArgName: 'completion', - lastArgType: callbackType, - isEnum: (TypeDeclaration t) => isEnum(root, t), - )};'); + _writeCodecAndGetter(ObjcOptions generatorOptions, Root root, StringSink sink, + Indent indent, Api api) { + final String codecName = _getCodecName(generatorOptions.prefix, api.name); + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(indent, codecName, generatorOptions, api, root); + indent.addln(''); + } + _writeCodecGetter(indent, codecName, generatorOptions, api, root); + indent.addln(''); + } + + @override + void writeFlutterApi( + ObjcOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.flutter); + final String apiName = _className(generatorOptions.prefix, api.name); + + _writeCodecAndGetter(generatorOptions, root, sink, indent, api); + + _writeExtension(indent, apiName); + indent.addln(''); + indent.writeln('@implementation $apiName'); + indent.addln(''); + _writeInitializer(indent); + for (final Method func in api.methods) { + _writeMethod(generatorOptions, root, indent, api, func); } indent.writeln('@end'); + indent.writeln(''); + } + + @override + void writeHostApi( + ObjcOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.host); + final String apiName = _className(generatorOptions.prefix, api.name); + + _writeCodecAndGetter(generatorOptions, root, sink, indent, api); + + const String channelName = 'channel'; + indent.write( + 'void ${apiName}Setup(id binaryMessenger, NSObject<$apiName> *api) '); + indent.scoped('{', '}', () { + for (final Method func in api.methods) { + indent.write(''); + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + + indent.scoped('{', '}', () { + String? taskQueue; + if (func.taskQueueType != TaskQueueType.serial) { + taskQueue = 'taskQueue'; + indent.writeln( + 'NSObject *$taskQueue = [binaryMessenger makeBackgroundTaskQueue];'); + } + _writeChannelAllocation( + generatorOptions, indent, api, func, channelName, taskQueue); + indent.write('if (api) '); + indent.scoped('{', '}', () { + _writeChannelApiBinding( + generatorOptions, root, indent, apiName, func, channelName); + }); + indent.write('else '); + indent.scoped('{', '}', () { + indent.writeln('[$channelName setMessageHandler:nil];'); + }); + }); + } + }); + } + + void _writeChannelApiBinding(ObjcOptions generatorOptions, Root root, + Indent indent, String apiName, Method func, String channel) { + void unpackArgs(String variable, Iterable argNames) { + indent.writeln('NSArray *args = $variable;'); + map3(wholeNumbers.take(func.arguments.length), argNames, func.arguments, + (int count, String argName, NamedType arg) { + if (isEnum(root, arg.type)) { + return '${_className(generatorOptions.prefix, arg.type.baseName)} $argName = [GetNullableObjectAtIndex(args, $count) integerValue];'; + } else { + final _ObjcPtr argType = + _objcTypeForDartType(generatorOptions.prefix, arg.type); + return '${argType.ptr}$argName = GetNullableObjectAtIndex(args, $count);'; + } + }).forEach(indent.writeln); + } + + void writeAsyncBindings(Iterable selectorComponents, + String callSignature, _ObjcPtr returnType) { + if (func.returnType.isVoid) { + const String callback = 'callback(wrapResult(nil, error));'; + if (func.arguments.isEmpty) { + indent.writeScoped( + '[api ${selectorComponents.first}:^(FlutterError *_Nullable error) {', + '}];', () { + indent.writeln(callback); + }); + } else { + indent.writeScoped( + '[api $callSignature ${selectorComponents.last}:^(FlutterError *_Nullable error) {', + '}];', () { + indent.writeln(callback); + }); + } + } else { + const String callback = 'callback(wrapResult(output, error));'; + if (func.arguments.isEmpty) { + indent.writeScoped( + '[api ${selectorComponents.first}:^(${returnType.ptr}_Nullable output, FlutterError *_Nullable error) {', + '}];', () { + indent.writeln(callback); + }); + } else { + indent.writeScoped( + '[api $callSignature ${selectorComponents.last}:^(${returnType.ptr}_Nullable output, FlutterError *_Nullable error) {', + '}];', () { + indent.writeln(callback); + }); + } + } + } + + void writeSyncBindings(String call, _ObjcPtr returnType) { + indent.writeln('FlutterError *error;'); + if (func.returnType.isVoid) { + indent.writeln('$call;'); + indent.writeln('callback(wrapResult(nil, error));'); + } else { + indent.writeln('${returnType.ptr}output = $call;'); + indent.writeln('callback(wrapResult(output, error));'); + } + } + + // TODO(gaaclarke): Incorporate this into _getSelectorComponents. + final String lastSelectorComponent = + func.isAsynchronous ? 'completion' : 'error'; + final String selector = _getSelector(func, lastSelectorComponent); + indent.writeln( + 'NSCAssert([api respondsToSelector:@selector($selector)], @"$apiName api (%@) doesn\'t respond to @selector($selector)", api);'); + indent.write( + '[$channel setMessageHandler:^(id _Nullable message, FlutterReply callback) '); + indent.scoped('{', '}];', () { + final _ObjcPtr returnType = + _objcTypeForDartType(generatorOptions.prefix, func.returnType); + final Iterable selectorComponents = + _getSelectorComponents(func, lastSelectorComponent); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgName); + final String callSignature = + map2(selectorComponents.take(argNames.length), argNames, + (String selectorComponent, String argName) { + return '$selectorComponent:$argName'; + }).join(' '); + if (func.arguments.isNotEmpty) { + unpackArgs('message', argNames); + } + if (func.isAsynchronous) { + writeAsyncBindings(selectorComponents, callSignature, returnType); + } else { + final String syncCall = func.arguments.isEmpty + ? '[api ${selectorComponents.first}:&error]' + : '[api $callSignature error:&error]'; + writeSyncBindings(syncCall, returnType); + } + }); } - // Source File Methods. + void _writeChannelAllocation(ObjcOptions generatorOptions, Indent indent, + Api api, Method func, String varName, String? taskQueue) { + indent.writeln('FlutterBasicMessageChannel *$varName ='); + indent.inc(); + indent.writeln('[[FlutterBasicMessageChannel alloc]'); + indent.inc(); + indent.writeln('initWithName:@"${makeChannelName(api, func)}"'); + indent.writeln('binaryMessenger:binaryMessenger'); + indent.write('codec:'); + indent.add('${_getCodecGetterName(generatorOptions.prefix, api.name)}()'); - /// Writes Objc Source file header to sink. - void _writeObjcSourcePrologue( - ObjcOptions languageOptions, Root root, StringSink sink, Indent indent) { - if (languageOptions.copyrightHeader != null) { - addLines(indent, languageOptions.copyrightHeader!, linePrefix: '// '); + if (taskQueue != null) { + indent.addln(''); + indent.addln('taskQueue:$taskQueue];'); + } else { + indent.addln('];'); } - indent.writeln('// $generatedCodeWarning'); - indent.writeln('// $seeAlsoWarning'); - indent.addln(''); - } - - /// Writes Objc source file imports to sink. - void _writeObjcSourceImports( - ObjcOptions languageOptions, Root root, StringSink sink, Indent indent) { - indent.writeln('#import "${languageOptions.headerIncludePath}"'); - indent.writeln('#import '); - indent.addln(''); - - indent.writeln('#if !__has_feature(objc_arc)'); - indent.writeln('#error File requires ARC to be enabled.'); - indent.writeln('#endif'); - indent.addln(''); + indent.dec(); + indent.dec(); } void _writeObjcSourceHelperFunctions(Indent indent) { @@ -515,30 +677,11 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { .writeln('+ (nullable $className *)nullableFromList:(NSArray *)list;'); indent.writeln('- (NSArray *)toList;'); indent.writeln('@end'); + indent.writeln(''); } - void _writeObjcSourceDataClassImplementation( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass) { - final Set customClassNames = - root.classes.map((Class x) => x.name).toSet(); - final Set customEnumNames = - root.enums.map((Enum x) => x.name).toSet(); - final String className = - _className(generatorOptions.languageOptions.prefix, klass.name); - - indent.writeln('@implementation $className'); - _writeObjcSourceClassInitializer(generatorOptions.languageOptions, root, - sink, indent, klass, customClassNames, customEnumNames, className); - writeClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - writeClassEncode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - indent.writeln('@end'); - } + void _writeObjcSourceDataClassImplementation(ObjcOptions generatorOptions, + Root root, StringSink sink, Indent indent, Class klass) {} void _writeObjcSourceClassInitializer( ObjcOptions languageOptions, @@ -562,95 +705,6 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { }); } - void _writeObjcSourceClassDecode( - ObjcOptions languageOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - String className, - ) { - indent.write('+ ($className *)fromList:(NSArray *)list '); - indent.scoped('{', '}', () { - const String resultName = 'pigeonResult'; - indent.writeln('$className *$resultName = [[$className alloc] init];'); - enumerate(getFieldsInSerializationOrder(klass), - (int index, final NamedType field) { - if (customEnumNames.contains(field.type.baseName)) { - indent.writeln( - '$resultName.${field.name} = [${_listGetter(customClassNames, 'list', field, index, languageOptions.prefix)} integerValue];'); - } else { - indent.writeln( - '$resultName.${field.name} = ${_listGetter(customClassNames, 'list', field, index, languageOptions.prefix)};'); - if (!field.type.isNullable) { - indent.writeln('NSAssert($resultName.${field.name} != nil, @"");'); - } - } - }); - indent.writeln('return $resultName;'); - }); - - indent.writeln( - '+ (nullable $className *)nullableFromList:(NSArray *)list { return (list) ? [$className fromList:list] : nil; }'); - } - - void _writeObjcSourceClassEncode( - ObjcOptions languageOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - String className, - ) { - indent.write('- (NSArray *)toList '); - indent.scoped('{', '}', () { - indent.write('return'); - indent.scoped(' @[', '];', () { - for (final NamedType field in klass.fields) { - indent.writeln( - '${_arrayValue(customClassNames, customEnumNames, field)},'); - } - }); - }); - } - - /// Writes the method declaration for the initializer. - /// - /// Example '+ (instancetype)makeWithFoo:(NSString *)foo' - void _writeObjcSourceClassInitializerDeclaration(Indent indent, Class klass, - List classes, List enums, String? prefix) { - final List customEnumNames = enums.map((Enum x) => x.name).toList(); - indent.write('+ (instancetype)makeWith'); - bool isFirst = true; - indent.nest(2, () { - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - final String label = isFirst ? _capitalize(field.name) : field.name; - final void Function(String) printer = isFirst - ? indent.add - : (String x) { - indent.addln(''); - indent.write(x); - }; - isFirst = false; - final HostDatatype hostDatatype = getFieldHostDatatype( - field, - classes, - enums, - (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), - customResolver: customEnumNames.contains(field.type.baseName) - ? (String x) => _className(prefix, x) - : (String x) => '${_className(prefix, x)} *'); - final String nullable = - _isNullable(hostDatatype, field.type) ? 'nullable ' : ''; - printer('$label:($nullable${hostDatatype.datatype})${field.name}'); - } - }); - } - /// Writes the codec that will be used for encoding messages for the [api]. /// /// Example: @@ -751,6 +805,39 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { } } +/// Writes the method declaration for the initializer. +/// +/// Example '+ (instancetype)makeWithFoo:(NSString *)foo' +void _writeObjcSourceClassInitializerDeclaration(Indent indent, Class klass, + List classes, List enums, String? prefix) { + final List customEnumNames = enums.map((Enum x) => x.name).toList(); + indent.write('+ (instancetype)makeWith'); + bool isFirst = true; + indent.nest(2, () { + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + final String label = isFirst ? _capitalize(field.name) : field.name; + final void Function(String) printer = isFirst + ? indent.add + : (String x) { + indent.addln(''); + indent.write(x); + }; + isFirst = false; + final HostDatatype hostDatatype = getFieldHostDatatype( + field, + classes, + enums, + (TypeDeclaration x) => _objcTypePtrForPrimitiveDartType(prefix, x), + customResolver: customEnumNames.contains(field.type.baseName) + ? (String x) => _className(prefix, x) + : (String x) => '${_className(prefix, x)} *'); + final String nullable = + _isNullable(hostDatatype, field.type) ? 'nullable ' : ''; + printer('$label:($nullable${hostDatatype.datatype})${field.name}'); + } + }); +} + /// Calculates the ObjC class name, possibly prefixed. String _className(String? prefix, String className) { if (prefix != null) { @@ -971,176 +1058,6 @@ String _getSelector(Method func, String lastSelectorComponent) => String _getSafeArgName(int count, NamedType arg) => arg.name.isEmpty ? 'arg$count' : 'arg_${arg.name}'; -/// Writes the definition code for a host [Api]. -/// See also: [_writeHostApiDeclaration] -void _writeHostApiSource( - Indent indent, ObjcOptions options, Api api, Root root) { - assert(api.location == ApiLocation.host); - final String apiName = _className(options.prefix, api.name); - - void writeChannelAllocation(Method func, String varName, String? taskQueue) { - indent.writeln('FlutterBasicMessageChannel *$varName ='); - indent.inc(); - indent.writeln('[[FlutterBasicMessageChannel alloc]'); - indent.inc(); - indent.writeln('initWithName:@"${makeChannelName(api, func)}"'); - indent.writeln('binaryMessenger:binaryMessenger'); - indent.write('codec:'); - indent.add('${_getCodecGetterName(options.prefix, api.name)}()'); - - if (taskQueue != null) { - indent.addln(''); - indent.addln('taskQueue:$taskQueue];'); - } else { - indent.addln('];'); - } - indent.dec(); - indent.dec(); - } - - void writeChannelApiBinding(Method func, String channel) { - void unpackArgs(String variable, Iterable argNames) { - indent.writeln('NSArray *args = $variable;'); - map3(wholeNumbers.take(func.arguments.length), argNames, func.arguments, - (int count, String argName, NamedType arg) { - if (isEnum(root, arg.type)) { - return '${_className(options.prefix, arg.type.baseName)} $argName = [GetNullableObjectAtIndex(args, $count) integerValue];'; - } else { - final _ObjcPtr argType = - _objcTypeForDartType(options.prefix, arg.type); - return '${argType.ptr}$argName = GetNullableObjectAtIndex(args, $count);'; - } - }).forEach(indent.writeln); - } - - void writeAsyncBindings(Iterable selectorComponents, - String callSignature, _ObjcPtr returnType) { - if (func.returnType.isVoid) { - const String callback = 'callback(wrapResult(nil, error));'; - if (func.arguments.isEmpty) { - indent.writeScoped( - '[api ${selectorComponents.first}:^(FlutterError *_Nullable error) {', - '}];', () { - indent.writeln(callback); - }); - } else { - indent.writeScoped( - '[api $callSignature ${selectorComponents.last}:^(FlutterError *_Nullable error) {', - '}];', () { - indent.writeln(callback); - }); - } - } else { - const String callback = 'callback(wrapResult(output, error));'; - if (func.arguments.isEmpty) { - indent.writeScoped( - '[api ${selectorComponents.first}:^(${returnType.ptr}_Nullable output, FlutterError *_Nullable error) {', - '}];', () { - indent.writeln(callback); - }); - } else { - indent.writeScoped( - '[api $callSignature ${selectorComponents.last}:^(${returnType.ptr}_Nullable output, FlutterError *_Nullable error) {', - '}];', () { - indent.writeln(callback); - }); - } - } - } - - void writeSyncBindings(String call, _ObjcPtr returnType) { - indent.writeln('FlutterError *error;'); - if (func.returnType.isVoid) { - indent.writeln('$call;'); - indent.writeln('callback(wrapResult(nil, error));'); - } else { - indent.writeln('${returnType.ptr}output = $call;'); - indent.writeln('callback(wrapResult(output, error));'); - } - } - - // TODO(gaaclarke): Incorporate this into _getSelectorComponents. - final String lastSelectorComponent = - func.isAsynchronous ? 'completion' : 'error'; - final String selector = _getSelector(func, lastSelectorComponent); - indent.writeln( - 'NSCAssert([api respondsToSelector:@selector($selector)], @"$apiName api (%@) doesn\'t respond to @selector($selector)", api);'); - indent.write( - '[$channel setMessageHandler:^(id _Nullable message, FlutterReply callback) '); - indent.scoped('{', '}];', () { - final _ObjcPtr returnType = - _objcTypeForDartType(options.prefix, func.returnType); - final Iterable selectorComponents = - _getSelectorComponents(func, lastSelectorComponent); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgName); - final String callSignature = - map2(selectorComponents.take(argNames.length), argNames, - (String selectorComponent, String argName) { - return '$selectorComponent:$argName'; - }).join(' '); - if (func.arguments.isNotEmpty) { - unpackArgs('message', argNames); - } - if (func.isAsynchronous) { - writeAsyncBindings(selectorComponents, callSignature, returnType); - } else { - final String syncCall = func.arguments.isEmpty - ? '[api ${selectorComponents.first}:&error]' - : '[api $callSignature error:&error]'; - writeSyncBindings(syncCall, returnType); - } - }); - } - - const String channelName = 'channel'; - indent.write( - 'void ${apiName}Setup(id binaryMessenger, NSObject<$apiName> *api) '); - indent.scoped('{', '}', () { - for (final Method func in api.methods) { - indent.write(''); - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - - indent.scoped('{', '}', () { - String? taskQueue; - if (func.taskQueueType != TaskQueueType.serial) { - taskQueue = 'taskQueue'; - indent.writeln( - 'NSObject *$taskQueue = [binaryMessenger makeBackgroundTaskQueue];'); - } - writeChannelAllocation(func, channelName, taskQueue); - indent.write('if (api) '); - indent.scoped('{', '}', () { - writeChannelApiBinding(func, channelName); - }); - indent.write('else '); - indent.scoped('{', '}', () { - indent.writeln('[$channelName setMessageHandler:nil];'); - }); - }); - } - }); -} - -/// Writes the definition code for a flutter [Api]. -/// See also: [_writeFlutterApiDeclaration] -void _writeFlutterApiSource( - Indent indent, ObjcOptions languageOptions, Api api, Root root) { - assert(api.location == ApiLocation.flutter); - final String apiName = _className(languageOptions.prefix, api.name); - - _writeExtension(indent, apiName); - indent.addln(''); - indent.writeln('@implementation $apiName'); - indent.addln(''); - _writeInitializer(indent); - for (final Method func in api.methods) { - _writeMethod(languageOptions, root, indent, api, func); - } - indent.writeln('@end'); -} - void _writeExtension(Indent indent, String apiName) { indent.writeln('@interface $apiName ()'); indent.writeln( diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h index 74c3c2e68f4..e0ac4f05d54 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h @@ -209,6 +209,7 @@ NSObject *FlutterIntegrationCoreApiGetCodec(void); - (void)echoString:(NSString *)aString completion:(void (^)(NSString *_Nullable, NSError *_Nullable))completion; @end + /// The codec used by HostTrivialApi. NSObject *HostTrivialApiGetCodec(void); diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m index c52ea0822e1..1b0720b5276 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.m @@ -34,11 +34,13 @@ + (AllTypes *)fromList:(NSArray *)list; + (nullable AllTypes *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end + @interface AllNullableTypes () + (AllNullableTypes *)fromList:(NSArray *)list; + (nullable AllNullableTypes *)nullableFromList:(NSArray *)list; - (NSArray *)toList; @end + @interface AllNullableTypesWrapper () + (AllNullableTypesWrapper *)fromList:(NSArray *)list; + (nullable AllNullableTypesWrapper *)nullableFromList:(NSArray *)list; @@ -895,6 +897,7 @@ - (void)echoString:(NSString *)arg_aString }]; } @end + NSObject *HostTrivialApiGetCodec() { static FlutterStandardMessageCodec *sSharedObject = nil; sSharedObject = [FlutterStandardMessageCodec sharedInstance]; From a7356c58cb861e9ac925df734690633bc664672d Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Tue, 10 Jan 2023 23:57:34 -0800 Subject: [PATCH 73/87] Cpp --- packages/pigeon/lib/cpp_generator.dart | 996 +++++++++++------------- packages/pigeon/lib/objc_generator.dart | 2 +- 2 files changed, 469 insertions(+), 529 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 313c993ed64..1a119691948 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -75,203 +75,40 @@ class CppGenerator extends Generator> { /// Instantiates a Cpp Generator. CppGenerator(); - /// Generates Cpp header files with specified [CppOptions] + /// Generates C++ file of type specified in [generatorOptions] @override void generate(OutputFileOptions generatorOptions, Root root, StringSink sink) { assert(generatorOptions.fileType == FileType.header || generatorOptions.fileType == FileType.source); - - final Indent indent = Indent(sink); - writeFilePrologue(generatorOptions, root, sink, indent); - writeFileImports(generatorOptions, root, sink, indent); - - for (final Enum anEnum in root.enums) { - writeEnum(generatorOptions, root, sink, indent, anEnum); - } - - indent.addln(''); - if (generatorOptions.fileType == FileType.header) { - _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); - } - for (final Class klass in root.classes) { - writeDataClass(generatorOptions, root, sink, indent, klass); - } - - for (final Api api in root.apis) { - if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(generatorOptions, root, sink, indent, api); - indent.addln(''); - } - if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); - } - } - - if (generatorOptions.fileType == FileType.header) { - if (generatorOptions.languageOptions.namespace != null) { - indent.writeln( - '} // namespace ${generatorOptions.languageOptions.namespace}'); - } - final String guardName = _getGuardName( - generatorOptions.languageOptions.headerIncludePath, - generatorOptions.languageOptions.namespace); - indent.writeln('#endif // $guardName'); - } else { - if (generatorOptions.languageOptions.namespace != null) { - indent.writeln( - '} // namespace ${generatorOptions.languageOptions.namespace}'); - } - } - } - - @override - void writeFilePrologue(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent) { - final FileType fileType = generatorOptions.fileType; - if (fileType == FileType.header) { - _writeCppHeaderPrologue(generatorOptions, root, sink, indent); - } else { - _writeCppSourcePrologue(generatorOptions, root, sink, indent); - } - } - - @override - void writeFileImports(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent) { - final FileType fileType = generatorOptions.fileType; - if (fileType == FileType.header) { - _writeCppHeaderImports(generatorOptions, root, sink, indent); - } else { - _writeCppSourceImports(generatorOptions, root, sink, indent); - } - } - - @override - void writeEnum(OutputFileOptions generatorOptions, Root root, - StringSink sink, Indent indent, Enum anEnum) { - final FileType fileType = generatorOptions.fileType; - if (fileType == FileType.header) { - _writeCppHeaderEnum(generatorOptions, root, sink, indent, anEnum); - } - } - - @override - void writeDataClass(OutputFileOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass) { - if (generatorOptions.fileType == FileType.header) { - // When generating for a Pigeon unit test, add a test fixture friend class to - // allow unit testing private methods, since testing serialization via public - // methods is essentially an end-to-end test. - String? testFixtureClass; - if (generatorOptions.languageOptions.namespace?.endsWith('_pigeontest') ?? - false) { - testFixtureClass = - '${_pascalCaseFromSnakeCase(generatorOptions.languageOptions.namespace!.replaceAll('_pigeontest', ''))}Test'; - } - _writeCppHeaderDataClass(generatorOptions, root, sink, indent, klass, - testFriend: testFixtureClass); - } else { - _writeCppSourceDataClass(generatorOptions, root, sink, indent, klass); - } - } - - @override - void writeClassEncode( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - ) { - assert(generatorOptions.fileType == FileType.source); - _writeCppSourceClassEncode(generatorOptions.languageOptions, root, sink, - indent, klass, customClassNames, customEnumNames); - } - - @override - void writeClassDecode( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - ) { - assert(generatorOptions.fileType == FileType.source); - _writeCppSourceClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - } - - @override - void writeFlutterApi( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Api api, - ) { if (generatorOptions.fileType == FileType.header) { - _writeFlutterApiHeader(indent, api, root); - } else { - _writeFlutterApiSource(indent, api, root); + CppHeaderGenerator() + .generate(generatorOptions.languageOptions, root, sink); + } else if (generatorOptions.fileType == FileType.source) { + CppSourceGenerator() + .generate(generatorOptions.languageOptions, root, sink); } } +} +/// Writes C++ header (.h) file to sink. +class CppHeaderGenerator extends StructuredGenerator { @override - void writeHostApi( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Api api, - ) { - if (generatorOptions.fileType == FileType.header) { - _writeHostApiHeader(indent, api, root); - } else { - _writeHostApiSource(indent, api, root); - } - } - - void _writeCodec( - OutputFileOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Api api, - ) { - if (generatorOptions.fileType == FileType.header) { - _writeCodecHeader(indent, api, root); - } else { - _writeCodecSource(indent, api, root); - } - } - - // Header methods. - - /// Writes Cpp header file header to sink. - void _writeCppHeaderPrologue(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent) { - if (generatorOptions.languageOptions.copyrightHeader != null) { - addLines(indent, generatorOptions.languageOptions.copyrightHeader!, - linePrefix: '// '); + void writeFilePrologue( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + if (generatorOptions.copyrightHeader != null) { + addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } indent.writeln('$_commentPrefix $generatedCodeWarning'); indent.writeln('$_commentPrefix $seeAlsoWarning'); indent.addln(''); } - /// Writes Cpp header file imports to sink. - void _writeCppHeaderImports(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent) { + @override + void writeFileImports( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { final String guardName = _getGuardName( - generatorOptions.languageOptions.headerIncludePath, - generatorOptions.languageOptions.namespace); + generatorOptions.headerIncludePath, generatorOptions.namespace); indent.writeln('#ifndef $guardName'); indent.writeln('#define $guardName'); @@ -288,24 +125,22 @@ class CppGenerator extends Generator> { 'optional', ]); indent.addln(''); - if (generatorOptions.languageOptions.namespace != null) { - indent - .writeln('namespace ${generatorOptions.languageOptions.namespace} {'); + if (generatorOptions.namespace != null) { + indent.writeln('namespace ${generatorOptions.namespace} {'); } indent.addln(''); - if (generatorOptions.languageOptions.namespace?.endsWith('_pigeontest') ?? - false) { + if (generatorOptions.namespace?.endsWith('_pigeontest') ?? false) { final String testFixtureClass = - '${_pascalCaseFromSnakeCase(generatorOptions.languageOptions.namespace!.replaceAll('_pigeontest', ''))}Test'; + '${_pascalCaseFromSnakeCase(generatorOptions.namespace!.replaceAll('_pigeontest', ''))}Test'; indent.writeln('class $testFixtureClass;'); } indent.addln(''); indent.writeln('$_commentPrefix Generated class from Pigeon.'); } - /// Writes Cpp header enum to sink. - void _writeCppHeaderEnum(OutputFileOptions options, Root root, - StringSink sink, Indent indent, Enum anEnum) { + @override + void writeEnum(CppOptions generatorOptions, Root root, StringSink sink, + Indent indent, Enum anEnum) { indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -320,13 +155,23 @@ class CppGenerator extends Generator> { }); } - /// Writes the declaration for the custom class [klass]. - /// - /// See [_writeCppSourceDataClass] for the corresponding declaration. - /// This is intended to be added to the header. - void _writeCppHeaderDataClass(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent, Class klass, - {String? testFriend}) { + @override + void preDataClasses( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); + } + + @override + void writeDataClass(CppOptions generatorOptions, Root root, StringSink sink, + Indent indent, Class klass) { + // When generating for a Pigeon unit test, add a test fixture friend class to + // allow unit testing private methods, since testing serialization via public + // methods is essentially an end-to-end test. + String? testFixtureClass; + if (generatorOptions.namespace?.endsWith('_pigeontest') ?? false) { + testFixtureClass = + '${_pascalCaseFromSnakeCase(generatorOptions.namespace!.replaceAll('_pigeontest', ''))}Test'; + } indent.addln(''); const List generatedMessages = [ @@ -381,8 +226,8 @@ class CppGenerator extends Generator> { indent.writeln('friend class ${api.name};'); indent.writeln('friend class ${_getCodecSerializerName(api)};'); } - if (testFriend != null) { - indent.writeln('friend class $testFriend;'); + if (testFixtureClass != null) { + indent.writeln('friend class $testFixtureClass;'); } for (final NamedType field in getFieldsInSerializationOrder(klass)) { @@ -399,84 +244,97 @@ class CppGenerator extends Generator> { indent.writeln(''); } - void _writeCodecHeader(Indent indent, Api api, Root root) { - assert(getCodecClasses(api, root).isNotEmpty); - final String codeSerializerName = _getCodecSerializerName(api); - indent - .write('class $codeSerializerName : public $_defaultCodecSerializer '); + @override + void writeClassEncode( + CppOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + // Intentionally left blank. + } + + @override + void writeClassDecode( + CppOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Class klass, + Set customClassNames, + Set customEnumNames, + ) { + // Intentionally left blank. + } + + @override + void writeFlutterApi( + CppOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.flutter); + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(generatorOptions, root, sink, indent, api); + } + const List generatedMessages = [ + ' Generated class from Pigeon that represents Flutter messages that can be called from C++.' + ]; + addDocumentationComments(indent, api.documentationComments, _docCommentSpec, + generatorComments: generatedMessages); + indent.write('class ${api.name} '); indent.scoped('{', '};', () { + indent.scoped(' private:', '', () { + indent.writeln('flutter::BinaryMessenger* binary_messenger_;'); + }); indent.scoped(' public:', '', () { + indent + .write('${api.name}(flutter::BinaryMessenger* binary_messenger);'); indent.writeln(''); - indent.format(''' -inline static $codeSerializerName& GetInstance() { -\tstatic $codeSerializerName sInstance; -\treturn sInstance; -} -'''); - indent.writeln('$codeSerializerName();'); - }); - indent.writeScoped(' public:', '', () { - indent.writeln( - 'void WriteValue(const flutter::EncodableValue& value, flutter::ByteStreamWriter* stream) const override;'); - }); - indent.writeScoped(' protected:', '', () { - indent.writeln( - 'flutter::EncodableValue ReadValueOfType(uint8_t type, flutter::ByteStreamReader* stream) const override;'); + indent + .writeln('static const flutter::StandardMessageCodec& GetCodec();'); + for (final Method func in api.methods) { + final String returnType = func.returnType.isVoid + ? 'void' + : _nullSafeCppTypeForDartType(func.returnType); + final String callback = 'std::function&& callback'; + addDocumentationComments( + indent, func.documentationComments, _docCommentSpec); + if (func.arguments.isEmpty) { + indent.writeln('void ${func.name}($callback);'); + } else { + final Iterable argTypes = func.arguments + .map((NamedType e) => _nullSafeCppTypeForDartType(e.type)); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgumentName); + final String argsSignature = + map2(argTypes, argNames, (String x, String y) => '$x $y') + .join(', '); + indent.writeln('void ${func.name}($argsSignature, $callback);'); + } + } }); }, nestCount: 0); + indent.writeln(''); } - void _writeErrorOr(Indent indent, - {Iterable friends = const []}) { - final String friendLines = friends - .map((String className) => '\tfriend class $className;') - .join('\n'); - indent.format(''' -class FlutterError { - public: -\texplicit FlutterError(const std::string& code) -\t\t: code_(code) {} -\texplicit FlutterError(const std::string& code, const std::string& message) -\t\t: code_(code), message_(message) {} -\texplicit FlutterError(const std::string& code, const std::string& message, const flutter::EncodableValue& details) -\t\t: code_(code), message_(message), details_(details) {} - -\tconst std::string& code() const { return code_; } -\tconst std::string& message() const { return message_; } -\tconst flutter::EncodableValue& details() const { return details_; } - - private: -\tstd::string code_; -\tstd::string message_; -\tflutter::EncodableValue details_; -}; - -template class ErrorOr { - public: -\tErrorOr(const T& rhs) { new(&v_) T(rhs); } -\tErrorOr(const T&& rhs) { v_ = std::move(rhs); } -\tErrorOr(const FlutterError& rhs) { -\t\tnew(&v_) FlutterError(rhs); -\t} -\tErrorOr(const FlutterError&& rhs) { v_ = std::move(rhs); } - -\tbool has_error() const { return std::holds_alternative(v_); } -\tconst T& value() const { return std::get(v_); }; -\tconst FlutterError& error() const { return std::get(v_); }; - - private: -$friendLines -\tErrorOr() = default; -\tT TakeValue() && { return std::get(std::move(v_)); } - -\tstd::variant v_; -}; -'''); - } - - void _writeHostApiHeader(Indent indent, Api api, Root root) { + @override + void writeHostApi( + CppOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { assert(api.location == ApiLocation.host); - + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(generatorOptions, root, sink, indent, api); + } const List generatedMessages = [ ' Generated interface from Pigeon that represents a handler of messages from Flutter.' ]; @@ -547,58 +405,107 @@ $friendLines }, nestCount: 0); } - void _writeFlutterApiHeader(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.flutter); - - const List generatedMessages = [ - ' Generated class from Pigeon that represents Flutter messages that can be called from C++.' - ]; - addDocumentationComments(indent, api.documentationComments, _docCommentSpec, - generatorComments: generatedMessages); - indent.write('class ${api.name} '); + void _writeCodec(CppOptions generatorOptions, Root root, StringSink sink, + Indent indent, Api api) { + assert(getCodecClasses(api, root).isNotEmpty); + final String codeSerializerName = _getCodecSerializerName(api); + indent + .write('class $codeSerializerName : public $_defaultCodecSerializer '); indent.scoped('{', '};', () { - indent.scoped(' private:', '', () { - indent.writeln('flutter::BinaryMessenger* binary_messenger_;'); - }); indent.scoped(' public:', '', () { - indent - .write('${api.name}(flutter::BinaryMessenger* binary_messenger);'); indent.writeln(''); - indent - .writeln('static const flutter::StandardMessageCodec& GetCodec();'); - for (final Method func in api.methods) { - final String returnType = func.returnType.isVoid - ? 'void' - : _nullSafeCppTypeForDartType(func.returnType); - final String callback = 'std::function&& callback'; - addDocumentationComments( - indent, func.documentationComments, _docCommentSpec); - if (func.arguments.isEmpty) { - indent.writeln('void ${func.name}($callback);'); - } else { - final Iterable argTypes = func.arguments - .map((NamedType e) => _nullSafeCppTypeForDartType(e.type)); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgumentName); - final String argsSignature = - map2(argTypes, argNames, (String x, String y) => '$x $y') - .join(', '); - indent.writeln('void ${func.name}($argsSignature, $callback);'); - } - } + indent.format(''' +inline static $codeSerializerName& GetInstance() { +\tstatic $codeSerializerName sInstance; +\treturn sInstance; +} +'''); + indent.writeln('$codeSerializerName();'); + }); + indent.writeScoped(' public:', '', () { + indent.writeln( + 'void WriteValue(const flutter::EncodableValue& value, flutter::ByteStreamWriter* stream) const override;'); + }); + indent.writeScoped(' protected:', '', () { + indent.writeln( + 'flutter::EncodableValue ReadValueOfType(uint8_t type, flutter::ByteStreamReader* stream) const override;'); }); }, nestCount: 0); - indent.writeln(''); + indent.addln(''); } - // Source methods. + @override + void postWriteFile( + CppOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + ) { + if (generatorOptions.namespace != null) { + indent.writeln('} // namespace ${generatorOptions.namespace}'); + } + final String guardName = _getGuardName( + generatorOptions.headerIncludePath, generatorOptions.namespace); + indent.writeln('#endif // $guardName'); + } - /// Writes Cpp source file header to sink. - void _writeCppSourcePrologue(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent) { - if (generatorOptions.languageOptions.copyrightHeader != null) { - addLines(indent, generatorOptions.languageOptions.copyrightHeader!, - linePrefix: '// '); + void _writeErrorOr(Indent indent, + {Iterable friends = const []}) { + final String friendLines = friends + .map((String className) => '\tfriend class $className;') + .join('\n'); + indent.format(''' + +class FlutterError { + public: +\texplicit FlutterError(const std::string& code) +\t\t: code_(code) {} +\texplicit FlutterError(const std::string& code, const std::string& message) +\t\t: code_(code), message_(message) {} +\texplicit FlutterError(const std::string& code, const std::string& message, const flutter::EncodableValue& details) +\t\t: code_(code), message_(message), details_(details) {} + +\tconst std::string& code() const { return code_; } +\tconst std::string& message() const { return message_; } +\tconst flutter::EncodableValue& details() const { return details_; } + + private: +\tstd::string code_; +\tstd::string message_; +\tflutter::EncodableValue details_; +}; + +template class ErrorOr { + public: +\tErrorOr(const T& rhs) { new(&v_) T(rhs); } +\tErrorOr(const T&& rhs) { v_ = std::move(rhs); } +\tErrorOr(const FlutterError& rhs) { +\t\tnew(&v_) FlutterError(rhs); +\t} +\tErrorOr(const FlutterError&& rhs) { v_ = std::move(rhs); } + +\tbool has_error() const { return std::holds_alternative(v_); } +\tconst T& value() const { return std::get(v_); }; +\tconst FlutterError& error() const { return std::get(v_); }; + + private: +$friendLines +\tErrorOr() = default; +\tT TakeValue() && { return std::get(std::move(v_)); } + +\tstd::variant v_; +}; +'''); + } +} + +/// Writes C++ source (.cpp) file to sink. +class CppSourceGenerator extends StructuredGenerator { + @override + void writeFilePrologue( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + if (generatorOptions.copyrightHeader != null) { + addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } indent.writeln('$_commentPrefix $generatedCodeWarning'); indent.writeln('$_commentPrefix $seeAlsoWarning'); @@ -607,11 +514,10 @@ $friendLines indent.addln(''); } - /// Writes Cpp source file imports to sink. - void _writeCppSourceImports(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent) { - indent.writeln( - '#include "${generatorOptions.languageOptions.headerIncludePath}"'); + @override + void writeFileImports( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + indent.writeln('#include "${generatorOptions.headerIncludePath}"'); indent.addln(''); _writeSystemHeaderIncludeBlock(indent, [ 'flutter/basic_message_channel.h', @@ -627,13 +533,50 @@ $friendLines ]); indent.addln(''); - if (generatorOptions.languageOptions.namespace != null) { - indent - .writeln('namespace ${generatorOptions.languageOptions.namespace} {'); + if (generatorOptions.namespace != null) { + indent.writeln('namespace ${generatorOptions.namespace} {'); } } - void _writeCppSourceClassEncode( + @override + void writeEnum(CppOptions generatorOptions, Root root, StringSink sink, + Indent indent, Enum anEnum) { + // Intentionally left empty. + } + + @override + void writeDataClass(CppOptions generatorOptions, Root root, StringSink sink, + Indent indent, Class klass) { + final Set customClassNames = + root.classes.map((Class x) => x.name).toSet(); + final Set customEnumNames = + root.enums.map((Enum x) => x.name).toSet(); + + indent.addln(''); + indent.writeln('$_commentPrefix ${klass.name}'); + indent.addln(''); + + // Getters and setters. + for (final NamedType field in getFieldsInSerializationOrder(klass)) { + _writeCppSourceClassField( + generatorOptions, root, sink, indent, klass, field); + } + + // Serialization. + writeClassEncode(generatorOptions, root, sink, indent, klass, + customClassNames, customEnumNames); + + // Default constructor. + indent.writeln('${klass.name}::${klass.name}() {}'); + indent.addln(''); + + // Deserialization. + writeClassDecode(generatorOptions, root, sink, indent, klass, + customClassNames, customEnumNames); + } + + @override + void writeClassEncode( CppOptions generatorOptions, Root root, StringSink sink, @@ -685,8 +628,9 @@ $friendLines indent.addln(''); } - void _writeCppSourceClassDecode( - OutputFileOptions generatorOptions, + @override + void writeClassDecode( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent, @@ -743,124 +687,122 @@ else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodabl indent.addln(''); } - void _writeCppSourceClassField(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent, Class klass, NamedType field) { - final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, - root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); - final String instanceVariableName = _makeInstanceVariableName(field); - final String qualifiedGetterName = - '${klass.name}::${_makeGetterName(field)}'; - final String qualifiedSetterName = - '${klass.name}::${_makeSetterName(field)}'; - final String returnExpression = hostDatatype.isNullable - ? '$instanceVariableName ? &(*$instanceVariableName) : nullptr' - : instanceVariableName; - - // Generates the string for a setter treating the type as [type], to allow - // generating multiple setter variants. - String makeSetter(HostDatatype type) { - const String setterArgumentName = 'value_arg'; - final String valueExpression = type.isNullable - ? '$setterArgumentName ? ${_valueType(type)}(*$setterArgumentName) : std::nullopt' - : setterArgumentName; - return 'void $qualifiedSetterName(${_unownedArgumentType(type)} $setterArgumentName) ' - '{ $instanceVariableName = $valueExpression; }'; + @override + void writeFlutterApi( + CppOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(api.location == ApiLocation.flutter); + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(generatorOptions, root, sink, indent, api); } - indent.writeln( - '${_getterReturnType(hostDatatype)} $qualifiedGetterName() const ' - '{ return $returnExpression; }'); - indent.writeln(makeSetter(hostDatatype)); - if (hostDatatype.isNullable) { - // Write the non-nullable variant; see _writeCppHeaderDataClass. - final HostDatatype nonNullType = _nonNullableType(hostDatatype); - indent.writeln(makeSetter(nonNullType)); - } - - indent.addln(''); - } - - /// Writes the implementation for the custom class [klass]. - /// - /// See [_writeCppHeaderDataClass] for the corresponding declaration. - /// This is intended to be added to the implementation file. - void _writeCppSourceDataClass(OutputFileOptions generatorOptions, - Root root, StringSink sink, Indent indent, Class klass) { - final Set customClassNames = - root.classes.map((Class x) => x.name).toSet(); - final Set customEnumNames = - root.enums.map((Enum x) => x.name).toSet(); - - indent.addln(''); - indent.writeln('$_commentPrefix ${klass.name}'); - indent.addln(''); - - // Getters and setters. - for (final NamedType field in getFieldsInSerializationOrder(klass)) { - _writeCppSourceClassField( - generatorOptions, root, sink, indent, klass, field); - } - - // Serialization. - writeClassEncode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - - // Default constructor. - indent.writeln('${klass.name}::${klass.name}() {}'); - indent.addln(''); - - // Deserialization. - writeClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - } - - void _writeCodecSource(Indent indent, Api api, Root root) { - assert(getCodecClasses(api, root).isNotEmpty); - final String codeSerializerName = _getCodecSerializerName(api); - indent.writeln('$codeSerializerName::$codeSerializerName() {}'); + '$_commentPrefix Generated class from Pigeon that represents Flutter messages that can be called from C++.'); indent.write( - 'flutter::EncodableValue $codeSerializerName::ReadValueOfType(uint8_t type, flutter::ByteStreamReader* stream) const '); + '${api.name}::${api.name}(flutter::BinaryMessenger* binary_messenger) '); indent.scoped('{', '}', () { - indent.write('switch (type) '); - indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in getCodecClasses(api, root)) { - indent.write('case ${customClass.enumeration}:'); - indent.writeScoped('', '', () { - indent.writeln( - 'return flutter::CustomEncodableValue(${customClass.name}(std::get(ReadValue(stream))));'); - }); - } - indent.write('default:'); - indent.writeScoped('', '', () { - indent.writeln( - 'return $_defaultCodecSerializer::ReadValueOfType(type, stream);'); - }, addTrailingNewline: false); - }); + indent.writeln('this->binary_messenger_ = binary_messenger;'); }); indent.writeln(''); - indent.write( - 'void $codeSerializerName::WriteValue(const flutter::EncodableValue& value, flutter::ByteStreamWriter* stream) const '); - indent.writeScoped('{', '}', () { - indent.write( - 'if (const flutter::CustomEncodableValue* custom_value = std::get_if(&value)) '); + final String codeSerializerName = getCodecClasses(api, root).isNotEmpty + ? _getCodecSerializerName(api) + : _defaultCodecSerializer; + indent.format(''' +const flutter::StandardMessageCodec& ${api.name}::GetCodec() { +\treturn flutter::StandardMessageCodec::GetInstance(&$codeSerializerName::GetInstance()); +} +'''); + for (final Method func in api.methods) { + final String channelName = makeChannelName(api, func); + final String returnType = func.returnType.isVoid + ? 'void' + : _nullSafeCppTypeForDartType(func.returnType); + String sendArgument; + final String callback = 'std::function&& callback'; + if (func.arguments.isEmpty) { + indent.write('void ${api.name}::${func.name}($callback) '); + sendArgument = 'flutter::EncodableValue()'; + } else { + final Iterable argTypes = func.arguments + .map((NamedType e) => _nullSafeCppTypeForDartType(e.type)); + final Iterable argNames = + indexMap(func.arguments, _getSafeArgumentName); + sendArgument = + 'flutter::EncodableList { ${argNames.map((String arg) => 'flutter::CustomEncodableValue($arg)').join(', ')} }'; + final String argsSignature = + map2(argTypes, argNames, (String x, String y) => '$x $y') + .join(', '); + indent.write( + 'void ${api.name}::${func.name}($argsSignature, $callback) '); + } indent.scoped('{', '}', () { - for (final EnumeratedClass customClass in getCodecClasses(api, root)) { - indent.write( - 'if (custom_value->type() == typeid(${customClass.name})) '); - indent.scoped('{', '}', () { - indent.writeln('stream->WriteByte(${customClass.enumeration});'); + const String channel = 'channel'; + indent.writeln( + 'auto channel = std::make_unique>('); + indent.inc(); + indent.inc(); + indent.writeln('binary_messenger_, "$channelName", &GetCodec());'); + indent.dec(); + indent.dec(); + indent.write( + '$channel->Send($sendArgument, [callback](const uint8_t* reply, size_t reply_size) '); + indent.scoped('{', '});', () { + if (func.returnType.isVoid) { + indent.writeln('callback();'); + } else { indent.writeln( - 'WriteValue(flutter::EncodableValue(std::any_cast<${customClass.name}>(*custom_value).ToEncodableList()), stream);'); - indent.writeln('return;'); - }); - } + 'std::unique_ptr decoded_reply = GetCodec().DecodeMessage(reply, reply_size);'); + indent.writeln( + 'flutter::EncodableValue args = *(flutter::EncodableValue*)(decoded_reply.release());'); + const String output = 'output'; + + final bool isBuiltin = + _baseCppTypeForBuiltinDartType(func.returnType) != null; + final String returnTypeName = + _baseCppTypeForDartType(func.returnType); + if (func.returnType.isNullable) { + indent.writeln('$returnType $output{};'); + } else { + indent.writeln('$returnTypeName $output{};'); + } + const String pointerVariable = '${_pointerPrefix}_$output'; + if (func.returnType.baseName == 'int') { + indent.format(''' +if (const int32_t* $pointerVariable = std::get_if(&args)) +\t$output = *$pointerVariable; +else if (const int64_t* ${pointerVariable}_64 = std::get_if(&args)) +\t$output = *${pointerVariable}_64;'''); + } else if (!isBuiltin) { + indent.write( + 'if (const flutter::EncodableList* $pointerVariable = std::get_if(&args)) '); + indent.scoped('{', '}', () { + indent.writeln('$output = $returnTypeName(*$pointerVariable);'); + }); + } else { + indent.write( + 'if (const $returnTypeName* $pointerVariable = std::get_if<$returnTypeName>(&args)) '); + indent.scoped('{', '}', () { + indent.writeln('$output = *$pointerVariable;'); + }); + } + + indent.writeln('callback($output);'); + } + }); }); - indent.writeln('$_defaultCodecSerializer::WriteValue(value, stream);'); - }); + } } - void _writeHostApiSource(Indent indent, Api api, Root root) { + @override + void writeHostApi(CppOptions generatorOptions, Root root, StringSink sink, + Indent indent, Api api) { assert(api.location == ApiLocation.host); + if (getCodecClasses(api, root).isNotEmpty) { + _writeCodec(generatorOptions, root, sink, indent, api); + } final String codeSerializerName = getCodecClasses(api, root).isNotEmpty ? _getCodecSerializerName(api) @@ -1054,6 +996,103 @@ flutter::EncodableList ${api.name}::WrapError(const FlutterError& error) { indent.addln(''); } + @override + void postWriteFile( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + if (generatorOptions.namespace != null) { + indent.writeln('} // namespace ${generatorOptions.namespace}'); + } + } + + void _writeCodec( + CppOptions generatorOptions, + Root root, + StringSink sink, + Indent indent, + Api api, + ) { + assert(getCodecClasses(api, root).isNotEmpty); + final String codeSerializerName = _getCodecSerializerName(api); + indent.writeln('$codeSerializerName::$codeSerializerName() {}'); + indent.write( + 'flutter::EncodableValue $codeSerializerName::ReadValueOfType(uint8_t type, flutter::ByteStreamReader* stream) const '); + indent.scoped('{', '}', () { + indent.write('switch (type) '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in getCodecClasses(api, root)) { + indent.write('case ${customClass.enumeration}:'); + indent.writeScoped('', '', () { + indent.writeln( + 'return flutter::CustomEncodableValue(${customClass.name}(std::get(ReadValue(stream))));'); + }); + } + indent.write('default:'); + indent.writeScoped('', '', () { + indent.writeln( + 'return $_defaultCodecSerializer::ReadValueOfType(type, stream);'); + }, addTrailingNewline: false); + }); + }); + indent.writeln(''); + indent.write( + 'void $codeSerializerName::WriteValue(const flutter::EncodableValue& value, flutter::ByteStreamWriter* stream) const '); + indent.writeScoped('{', '}', () { + indent.write( + 'if (const flutter::CustomEncodableValue* custom_value = std::get_if(&value)) '); + indent.scoped('{', '}', () { + for (final EnumeratedClass customClass in getCodecClasses(api, root)) { + indent.write( + 'if (custom_value->type() == typeid(${customClass.name})) '); + indent.scoped('{', '}', () { + indent.writeln('stream->WriteByte(${customClass.enumeration});'); + indent.writeln( + 'WriteValue(flutter::EncodableValue(std::any_cast<${customClass.name}>(*custom_value).ToEncodableList()), stream);'); + indent.writeln('return;'); + }); + } + }); + indent.writeln('$_defaultCodecSerializer::WriteValue(value, stream);'); + }); + indent.writeln(''); + } + + void _writeCppSourceClassField(CppOptions generatorOptions, Root root, + StringSink sink, Indent indent, Class klass, NamedType field) { + final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, + root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); + final String instanceVariableName = _makeInstanceVariableName(field); + final String qualifiedGetterName = + '${klass.name}::${_makeGetterName(field)}'; + final String qualifiedSetterName = + '${klass.name}::${_makeSetterName(field)}'; + final String returnExpression = hostDatatype.isNullable + ? '$instanceVariableName ? &(*$instanceVariableName) : nullptr' + : instanceVariableName; + + // Generates the string for a setter treating the type as [type], to allow + // generating multiple setter variants. + String makeSetter(HostDatatype type) { + const String setterArgumentName = 'value_arg'; + final String valueExpression = type.isNullable + ? '$setterArgumentName ? ${_valueType(type)}(*$setterArgumentName) : std::nullopt' + : setterArgumentName; + return 'void $qualifiedSetterName(${_unownedArgumentType(type)} $setterArgumentName) ' + '{ $instanceVariableName = $valueExpression; }'; + } + + indent.writeln( + '${_getterReturnType(hostDatatype)} $qualifiedGetterName() const ' + '{ return $returnExpression; }'); + indent.writeln(makeSetter(hostDatatype)); + if (hostDatatype.isNullable) { + // Write the non-nullable variant; see _writeCppHeaderDataClass. + final HostDatatype nonNullType = _nonNullableType(hostDatatype); + indent.writeln(makeSetter(nonNullType)); + } + + indent.addln(''); + } + String _wrapResponse( Indent indent, Root root, String reply, TypeDeclaration returnType) { String elseBody = ''; @@ -1097,105 +1136,6 @@ $prefix\t}${indent.newline}'''; '$prefix}' '$prefix$reply'; } - - void _writeFlutterApiSource(Indent indent, Api api, Root root) { - assert(api.location == ApiLocation.flutter); - indent.writeln( - '$_commentPrefix Generated class from Pigeon that represents Flutter messages that can be called from C++.'); - indent.write( - '${api.name}::${api.name}(flutter::BinaryMessenger* binary_messenger) '); - indent.scoped('{', '}', () { - indent.writeln('this->binary_messenger_ = binary_messenger;'); - }); - indent.writeln(''); - final String codeSerializerName = getCodecClasses(api, root).isNotEmpty - ? _getCodecSerializerName(api) - : _defaultCodecSerializer; - indent.format(''' -const flutter::StandardMessageCodec& ${api.name}::GetCodec() { -\treturn flutter::StandardMessageCodec::GetInstance(&$codeSerializerName::GetInstance()); -} -'''); - for (final Method func in api.methods) { - final String channelName = makeChannelName(api, func); - final String returnType = func.returnType.isVoid - ? 'void' - : _nullSafeCppTypeForDartType(func.returnType); - String sendArgument; - final String callback = 'std::function&& callback'; - if (func.arguments.isEmpty) { - indent.write('void ${api.name}::${func.name}($callback) '); - sendArgument = 'flutter::EncodableValue()'; - } else { - final Iterable argTypes = func.arguments - .map((NamedType e) => _nullSafeCppTypeForDartType(e.type)); - final Iterable argNames = - indexMap(func.arguments, _getSafeArgumentName); - sendArgument = - 'flutter::EncodableList { ${argNames.map((String arg) => 'flutter::CustomEncodableValue($arg)').join(', ')} }'; - final String argsSignature = - map2(argTypes, argNames, (String x, String y) => '$x $y') - .join(', '); - indent.write( - 'void ${api.name}::${func.name}($argsSignature, $callback) '); - } - indent.scoped('{', '}', () { - const String channel = 'channel'; - indent.writeln( - 'auto channel = std::make_unique>('); - indent.inc(); - indent.inc(); - indent.writeln('binary_messenger_, "$channelName", &GetCodec());'); - indent.dec(); - indent.dec(); - indent.write( - '$channel->Send($sendArgument, [callback](const uint8_t* reply, size_t reply_size) '); - indent.scoped('{', '});', () { - if (func.returnType.isVoid) { - indent.writeln('callback();'); - } else { - indent.writeln( - 'std::unique_ptr decoded_reply = GetCodec().DecodeMessage(reply, reply_size);'); - indent.writeln( - 'flutter::EncodableValue args = *(flutter::EncodableValue*)(decoded_reply.release());'); - const String output = 'output'; - - final bool isBuiltin = - _baseCppTypeForBuiltinDartType(func.returnType) != null; - final String returnTypeName = - _baseCppTypeForDartType(func.returnType); - if (func.returnType.isNullable) { - indent.writeln('$returnType $output{};'); - } else { - indent.writeln('$returnTypeName $output{};'); - } - const String pointerVariable = '${_pointerPrefix}_$output'; - if (func.returnType.baseName == 'int') { - indent.format(''' -if (const int32_t* $pointerVariable = std::get_if(&args)) -\t$output = *$pointerVariable; -else if (const int64_t* ${pointerVariable}_64 = std::get_if(&args)) -\t$output = *${pointerVariable}_64;'''); - } else if (!isBuiltin) { - indent.write( - 'if (const flutter::EncodableList* $pointerVariable = std::get_if(&args)) '); - indent.scoped('{', '}', () { - indent.writeln('$output = $returnTypeName(*$pointerVariable);'); - }); - } else { - indent.write( - 'if (const $returnTypeName* $pointerVariable = std::get_if<$returnTypeName>(&args)) '); - indent.scoped('{', '}', () { - indent.writeln('$output = *$pointerVariable;'); - }); - } - - indent.writeln('callback($output);'); - } - }); - }); - } - } } String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 5c330de9be8..f3f174289e4 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -69,7 +69,7 @@ class ObjcGenerator extends Generator> { /// Instantiates a Objc Generator. ObjcGenerator(); - /// Generates Objc files of type specified in [ObjcOptions] + /// Generates Objc file of type specified in [generatorOptions] @override void generate(OutputFileOptions generatorOptions, Root root, StringSink sink) { From 892ac554370b8976c4daf27f99eb175efecdbca6 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 11 Jan 2023 13:36:53 -0800 Subject: [PATCH 74/87] analyze --- packages/pigeon/lib/objc_generator.dart | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index f3f174289e4..711c1e73687 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -450,8 +450,8 @@ class ObjcSourceGenerator extends StructuredGenerator { '+ (nullable $className *)nullableFromList:(NSArray *)list { return (list) ? [$className fromList:list] : nil; }'); } - _writeCodecAndGetter(ObjcOptions generatorOptions, Root root, StringSink sink, - Indent indent, Api api) { + void _writeCodecAndGetter(ObjcOptions generatorOptions, Root root, + StringSink sink, Indent indent, Api api) { final String codecName = _getCodecName(generatorOptions.prefix, api.name); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(indent, codecName, generatorOptions, api, root); @@ -680,9 +680,6 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { indent.writeln(''); } - void _writeObjcSourceDataClassImplementation(ObjcOptions generatorOptions, - Root root, StringSink sink, Indent indent, Class klass) {} - void _writeObjcSourceClassInitializer( ObjcOptions languageOptions, Root root, From 1e6e5c2503190da1ded36fb78af5f4759ee3e06c Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 11 Jan 2023 13:53:39 -0800 Subject: [PATCH 75/87] vocab --- packages/pigeon/lib/cpp_generator.dart | 4 ++-- packages/pigeon/lib/objc_generator.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 1a119691948..9a3e6bc90d3 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -254,7 +254,7 @@ class CppHeaderGenerator extends StructuredGenerator { Set customClassNames, Set customEnumNames, ) { - // Intentionally left blank. + // Intentionally left empty. } @override @@ -267,7 +267,7 @@ class CppHeaderGenerator extends StructuredGenerator { Set customClassNames, Set customEnumNames, ) { - // Intentionally left blank. + // Intentionally left empty. } @override diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 711c1e73687..4bf159814bd 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -358,7 +358,7 @@ class ObjcSourceGenerator extends StructuredGenerator { @override void writeEnum(ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent, Enum anEnum) { - // Intentionally left blank. + // Intentionally left empty. } @override From 98d78c35c629f53ee3b2ea9cdbe682e1950e068c Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Wed, 11 Jan 2023 14:58:58 -0800 Subject: [PATCH 76/87] vocab --- packages/pigeon/lib/cpp_generator.dart | 4 ++-- packages/pigeon/lib/generator.dart | 4 ++-- packages/pigeon/lib/java_generator.dart | 4 ++-- packages/pigeon/lib/kotlin_generator.dart | 4 ++-- packages/pigeon/lib/objc_generator.dart | 2 +- packages/pigeon/lib/swift_generator.dart | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 9a3e6bc90d3..acd3300ecd4 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -435,7 +435,7 @@ inline static $codeSerializerName& GetInstance() { } @override - void postWriteFile( + void finalWriteFile( CppOptions generatorOptions, Root root, StringSink sink, @@ -997,7 +997,7 @@ flutter::EncodableList ${api.name}::WrapError(const FlutterError& error) { } @override - void postWriteFile( + void finalWriteFile( CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { if (generatorOptions.namespace != null) { indent.writeln('} // namespace ${generatorOptions.namespace}'); diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index e0a3d6e6f66..4e9f8a6fd4e 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -49,7 +49,7 @@ abstract class StructuredGenerator extends Generator { writeFlutterApi(generatorOptions, root, sink, indent, api); } } - postWriteFile(generatorOptions, root, sink, indent); + finalWriteFile(generatorOptions, root, sink, indent); } /// Pre-process or write before [writeFilePrologue]. @@ -169,7 +169,7 @@ abstract class StructuredGenerator extends Generator { /// Post-process for generate and/or writes after all other methods. /// /// This method is not a reqiured method, and does not need to be overriden if not needed. - void postWriteFile( + void finalWriteFile( T generatorOptions, Root root, StringSink sink, diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 844695eabe9..5f708e09e28 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -113,7 +113,7 @@ class JavaGenerator extends StructuredGenerator { writeFlutterApi(generatorOptions, root, sink, indent, api); } } - postWriteFile(generatorOptions, root, sink, indent); + finalWriteFile(generatorOptions, root, sink, indent); } @override @@ -762,7 +762,7 @@ Result<$returnType> $resultName = new Result<$returnType>() { } @override - void postWriteFile( + void finalWriteFile( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { _writeWrapError(indent); indent.dec(); diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 115f55be9f4..32ae1761700 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -623,8 +623,8 @@ class KotlinGenerator extends StructuredGenerator { } @override - void postWriteFile(KotlinOptions generatorOptions, Root root, StringSink sink, - Indent indent) { + void finalWriteFile(KotlinOptions generatorOptions, Root root, + StringSink sink, Indent indent) { _writeWrapResult(indent); _writeWrapError(indent); } diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 4bf159814bd..bc1bae88795 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -323,7 +323,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { } @override - void postWriteFile( + void finalWriteFile( ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { indent.writeln('NS_ASSUME_NONNULL_END'); } diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 9e862cd0f33..0622c9659d2 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -597,7 +597,7 @@ import FlutterMacOS } @override - void postWriteFile(SwiftOptions generatorOptions, Root root, StringSink sink, + void finalWriteFile(SwiftOptions generatorOptions, Root root, StringSink sink, Indent indent) { _writeWrapResult(indent); _writeWrapError(indent); From 555b240c284d0b547d1739d0b576f00fc180085d Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 12 Jan 2023 10:16:20 -0800 Subject: [PATCH 77/87] typo --- packages/pigeon/lib/generator.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 4e9f8a6fd4e..2cf46a77d7e 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -54,7 +54,7 @@ abstract class StructuredGenerator extends Generator { /// Pre-process or write before [writeFilePrologue]. /// - /// This method is not a reqiured method, and does not need to be overriden if not needed. + /// This method is not a reqiured method, and does not need to be overridden if not needed. void prePrologue( T generatorOptions, Root root, @@ -80,7 +80,7 @@ abstract class StructuredGenerator extends Generator { /// Pre-process for enums or writes before any [writeEnum] calls. /// - /// This method is not a reqiured method, and does not need to be overriden if not needed. + /// This method is not a reqiured method, and does not need to be overridden if not needed. void preEnums( T generatorOptions, Root root, @@ -99,7 +99,7 @@ abstract class StructuredGenerator extends Generator { /// Pre-process for data classes or writes before any [writeDataClass] calls. /// - /// This method is not a reqiured method, and does not need to be overriden if not needed. + /// This method is not a reqiured method, and does not need to be overridden if not needed. void preDataClasses( T generatorOptions, Root root, @@ -140,7 +140,7 @@ abstract class StructuredGenerator extends Generator { /// Pre-process for apis and/or writes before any [writeFlutterApi] or [writeHostApi] calls. /// - /// This method is not a reqiured method, and does not need to be overriden if not needed. + /// This method is not a reqiured method, and does not need to be overridden if not needed. void preApis( T generatorOptions, Root root, @@ -168,7 +168,7 @@ abstract class StructuredGenerator extends Generator { /// Post-process for generate and/or writes after all other methods. /// - /// This method is not a reqiured method, and does not need to be overriden if not needed. + /// This method is not a reqiured method, and does not need to be overridden if not needed. void finalWriteFile( T generatorOptions, Root root, From d80046b49298747deb8b27ece5669ad950a4250a Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 12 Jan 2023 10:17:13 -0800 Subject: [PATCH 78/87] less comma --- packages/pigeon/lib/generator.dart | 81 ++++++------------------------ 1 file changed, 14 insertions(+), 67 deletions(-) diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 2cf46a77d7e..2b6823431aa 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -10,11 +10,7 @@ import 'generator_tools.dart'; /// This provides the structure that is common across generators for different languages. abstract class Generator { /// Generates files for specified language with specified [generatorOptions] - void generate( - T generatorOptions, - Root root, - StringSink sink, - ); + void generate(T generatorOptions, Root root, StringSink sink); } /// A Superclass that enforces code generation across platforms. @@ -56,65 +52,35 @@ abstract class StructuredGenerator extends Generator { /// /// This method is not a reqiured method, and does not need to be overridden if not needed. void prePrologue( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - ) {} + T generatorOptions, Root root, StringSink sink, Indent indent) {} /// Adds specified headers to file. void writeFilePrologue( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - ); + T generatorOptions, Root root, StringSink sink, Indent indent); /// Adds specified imports to file. void writeFileImports( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - ); + T generatorOptions, Root root, StringSink sink, Indent indent); /// Pre-process for enums or writes before any [writeEnum] calls. /// /// This method is not a reqiured method, and does not need to be overridden if not needed. void preEnums( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - ) {} + T generatorOptions, Root root, StringSink sink, Indent indent) {} /// Writes a single Enum to file. - void writeEnum( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - Enum anEnum, - ); + void writeEnum(T generatorOptions, Root root, StringSink sink, Indent indent, + Enum anEnum); /// Pre-process for data classes or writes before any [writeDataClass] calls. /// /// This method is not a reqiured method, and does not need to be overridden if not needed. void preDataClasses( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - ) {} + T generatorOptions, Root root, StringSink sink, Indent indent) {} /// Writes a single data class to file. - void writeDataClass( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - ); + void writeDataClass(T generatorOptions, Root root, StringSink sink, + Indent indent, Class klass); /// Writes a single class encode method to file. void writeClassEncode( @@ -141,38 +107,19 @@ abstract class StructuredGenerator extends Generator { /// Pre-process for apis and/or writes before any [writeFlutterApi] or [writeHostApi] calls. /// /// This method is not a reqiured method, and does not need to be overridden if not needed. - void preApis( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - ) {} + void preApis(T generatorOptions, Root root, StringSink sink, Indent indent) {} /// Writes a single Flutter Api to file. void writeFlutterApi( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - Api api, - ); + T generatorOptions, Root root, StringSink sink, Indent indent, Api api); /// Writes a single Host Api to file. void writeHostApi( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - Api api, - ); + T generatorOptions, Root root, StringSink sink, Indent indent, Api api); /// Post-process for generate and/or writes after all other methods. /// /// This method is not a reqiured method, and does not need to be overridden if not needed. void finalWriteFile( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - ) {} + T generatorOptions, Root root, StringSink sink, Indent indent) {} } From a70a0e7e2497e3816a9403ffbcb4f364846d592e Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 12 Jan 2023 12:15:56 -0800 Subject: [PATCH 79/87] wrap write methods --- packages/pigeon/lib/cpp_generator.dart | 7 ++- packages/pigeon/lib/generator.dart | 77 +++++++++++------------ packages/pigeon/lib/java_generator.dart | 34 ++-------- packages/pigeon/lib/kotlin_generator.dart | 5 +- packages/pigeon/lib/objc_generator.dart | 8 ++- packages/pigeon/lib/swift_generator.dart | 7 ++- 6 files changed, 56 insertions(+), 82 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index acd3300ecd4..b20ad8810e7 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -156,9 +156,10 @@ class CppHeaderGenerator extends StructuredGenerator { } @override - void preDataClasses( + void writeDataClasses( CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); + super.writeDataClasses(generatorOptions, root, sink, indent); } @override @@ -435,7 +436,7 @@ inline static $codeSerializerName& GetInstance() { } @override - void finalWriteFile( + void writeGeneralUtilities( CppOptions generatorOptions, Root root, StringSink sink, @@ -997,7 +998,7 @@ flutter::EncodableList ${api.name}::WrapError(const FlutterError& error) { } @override - void finalWriteFile( + void writeGeneralUtilities( CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { if (generatorOptions.namespace != null) { indent.writeln('} // namespace ${generatorOptions.namespace}'); diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 2b6823431aa..ae100c96402 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -23,60 +23,46 @@ abstract class StructuredGenerator extends Generator { ) { final Indent indent = Indent(sink); - prePrologue(generatorOptions, root, sink, indent); writeFilePrologue(generatorOptions, root, sink, indent); + writeFileImports(generatorOptions, root, sink, indent); - preEnums(generatorOptions, root, sink, indent); - for (final Enum anEnum in root.enums) { - writeEnum(generatorOptions, root, sink, indent, anEnum); - } + writeEnums(generatorOptions, root, sink, indent); - preDataClasses(generatorOptions, root, sink, indent); - for (final Class klass in root.classes) { - writeDataClass(generatorOptions, root, sink, indent, klass); - } + writeDataClasses(generatorOptions, root, sink, indent); - preApis(generatorOptions, root, sink, indent); - for (final Api api in root.apis) { - if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); - } - } - finalWriteFile(generatorOptions, root, sink, indent); - } + writeApis(generatorOptions, root, sink, indent); - /// Pre-process or write before [writeFilePrologue]. - /// - /// This method is not a reqiured method, and does not need to be overridden if not needed. - void prePrologue( - T generatorOptions, Root root, StringSink sink, Indent indent) {} + writeGeneralUtilities(generatorOptions, root, sink, indent); + } /// Adds specified headers to file. void writeFilePrologue( T generatorOptions, Root root, StringSink sink, Indent indent); - /// Adds specified imports to file. + /// Writes specified imports to file. void writeFileImports( T generatorOptions, Root root, StringSink sink, Indent indent); - /// Pre-process for enums or writes before any [writeEnum] calls. - /// - /// This method is not a reqiured method, and does not need to be overridden if not needed. - void preEnums( - T generatorOptions, Root root, StringSink sink, Indent indent) {} + /// Writes all enums to file. Can be overridden to add extra code before/after enums. + void writeEnums( + T generatorOptions, Root root, StringSink sink, Indent indent) { + for (final Enum anEnum in root.enums) { + writeEnum(generatorOptions, root, sink, indent, anEnum); + } + } /// Writes a single Enum to file. void writeEnum(T generatorOptions, Root root, StringSink sink, Indent indent, Enum anEnum); - /// Pre-process for data classes or writes before any [writeDataClass] calls. - /// - /// This method is not a reqiured method, and does not need to be overridden if not needed. - void preDataClasses( - T generatorOptions, Root root, StringSink sink, Indent indent) {} + /// Writes all apis to file. Can be overridden to add extra code before/after apis. + void writeDataClasses( + T generatorOptions, Root root, StringSink sink, Indent indent) { + for (final Class klass in root.classes) { + writeDataClass(generatorOptions, root, sink, indent, klass); + } + } /// Writes a single data class to file. void writeDataClass(T generatorOptions, Root root, StringSink sink, @@ -104,10 +90,17 @@ abstract class StructuredGenerator extends Generator { Set customEnumNames, ); - /// Pre-process for apis and/or writes before any [writeFlutterApi] or [writeHostApi] calls. - /// - /// This method is not a reqiured method, and does not need to be overridden if not needed. - void preApis(T generatorOptions, Root root, StringSink sink, Indent indent) {} + /// Writes all data classes to file. Can be overridden to add extra code before/after classes. + void writeApis( + T generatorOptions, Root root, StringSink sink, Indent indent) { + for (final Api api in root.apis) { + if (api.location == ApiLocation.host) { + writeHostApi(generatorOptions, root, sink, indent, api); + } else if (api.location == ApiLocation.flutter) { + writeFlutterApi(generatorOptions, root, sink, indent, api); + } + } + } /// Writes a single Flutter Api to file. void writeFlutterApi( @@ -117,9 +110,9 @@ abstract class StructuredGenerator extends Generator { void writeHostApi( T generatorOptions, Root root, StringSink sink, Indent indent, Api api); - /// Post-process for generate and/or writes after all other methods. + /// Writes any necessary helper utilities to file if needed. /// - /// This method is not a reqiured method, and does not need to be overridden if not needed. - void finalWriteFile( + /// This method is not reqiured, and does not need to be overridden. + void writeGeneralUtilities( T generatorOptions, Root root, StringSink sink, Indent indent) {} } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 5f708e09e28..cfd53057ef8 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -90,32 +90,6 @@ class JavaGenerator extends StructuredGenerator { /// Instantiates a Java Generator. JavaGenerator(); - /// Generates the ".java" file for the AST represented by [root] to [sink] with the - /// provided [generatorOptions]. - @override - void generate(JavaOptions generatorOptions, Root root, StringSink sink) { - final Indent indent = Indent(sink); - - writeFilePrologue(generatorOptions, root, sink, indent); - writeFileImports(generatorOptions, root, sink, indent); - preEnums(generatorOptions, root, sink, indent); - for (final Enum anEnum in root.enums) { - writeEnum(generatorOptions, root, sink, indent, anEnum); - } - for (final Class klass in root.classes) { - writeDataClass(generatorOptions, root, sink, indent, klass); - } - preApis(generatorOptions, root, sink, indent); - for (final Api api in root.apis) { - if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); - } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); - } - } - finalWriteFile(generatorOptions, root, sink, indent); - } - @override void writeFilePrologue( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -152,7 +126,7 @@ class JavaGenerator extends StructuredGenerator { } @override - void preEnums( + void writeEnums( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { indent.writeln( '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); @@ -163,6 +137,7 @@ class JavaGenerator extends StructuredGenerator { } indent.writeln('public class ${generatorOptions.className!} {'); indent.inc(); + super.writeEnums(generatorOptions, root, sink, indent); } @override @@ -479,7 +454,7 @@ class JavaGenerator extends StructuredGenerator { } @override - void preApis( + void writeApis( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { if (root.apis.any((Api api) => api.location == ApiLocation.host && @@ -487,6 +462,7 @@ class JavaGenerator extends StructuredGenerator { indent.addln(''); _writeResultInterface(indent); } + super.writeApis(generatorOptions, root, sink, indent); } /// Write the java code that represents a host [Api], [api]. @@ -762,7 +738,7 @@ Result<$returnType> $resultName = new Result<$returnType>() { } @override - void finalWriteFile( + void writeGeneralUtilities( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { _writeWrapError(indent); indent.dec(); diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 32ae1761700..d48a62c6b82 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -285,7 +285,7 @@ class KotlinGenerator extends StructuredGenerator { } @override - void preApis( + void writeApis( KotlinOptions generatorOptions, Root root, StringSink sink, @@ -296,6 +296,7 @@ class KotlinGenerator extends StructuredGenerator { api.methods.any((Method it) => it.isAsynchronous))) { indent.addln(''); } + super.writeApis(generatorOptions, root, sink, indent); } /// Writes the code for a flutter [Api], [api]. @@ -623,7 +624,7 @@ class KotlinGenerator extends StructuredGenerator { } @override - void finalWriteFile(KotlinOptions generatorOptions, Root root, + void writeGeneralUtilities(KotlinOptions generatorOptions, Root root, StringSink sink, Indent indent) { _writeWrapResult(indent); _writeWrapError(indent); diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index bc1bae88795..e7f21d81e8b 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -131,7 +131,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { } @override - void preDataClasses( + void writeDataClasses( ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { indent.writeln(''); for (final Class klass in root.classes) { @@ -139,6 +139,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { '@class ${_className(generatorOptions.prefix, klass.name)};'); } indent.writeln(''); + super.writeDataClasses(generatorOptions, root, sink, indent); } @override @@ -323,7 +324,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { } @override - void finalWriteFile( + void writeGeneralUtilities( ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { indent.writeln('NS_ASSUME_NONNULL_END'); } @@ -362,7 +363,7 @@ class ObjcSourceGenerator extends StructuredGenerator { } @override - void preDataClasses( + void writeDataClasses( ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { _writeObjcSourceHelperFunctions(indent); indent.addln(''); @@ -371,6 +372,7 @@ class ObjcSourceGenerator extends StructuredGenerator { _writeObjcSourceDataClassExtension(generatorOptions, indent, klass); } indent.writeln(''); + super.writeDataClasses(generatorOptions, root, sink, indent); } @override diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 0622c9659d2..fb5f49754a6 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -241,7 +241,7 @@ import FlutterMacOS } @override - void preApis( + void writeApis( SwiftOptions generatorOptions, Root root, StringSink sink, @@ -252,6 +252,7 @@ import FlutterMacOS api.methods.any((Method it) => it.isAsynchronous))) { indent.addln(''); } + super.writeApis(generatorOptions, root, sink, indent); } /// Writes the code for a flutter [Api], [api]. @@ -597,8 +598,8 @@ import FlutterMacOS } @override - void finalWriteFile(SwiftOptions generatorOptions, Root root, StringSink sink, - Indent indent) { + void writeGeneralUtilities(SwiftOptions generatorOptions, Root root, + StringSink sink, Indent indent) { _writeWrapResult(indent); _writeWrapError(indent); } From 585c9d832c5dc846c2828e17556050fa3f1d566c Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 12 Jan 2023 12:21:35 -0800 Subject: [PATCH 80/87] move code from writeGeneralUtilities --- packages/pigeon/lib/cpp_generator.dart | 44 ++++++++++++------------- packages/pigeon/lib/java_generator.dart | 2 ++ packages/pigeon/lib/objc_generator.dart | 13 ++++---- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index b20ad8810e7..d5cae464da0 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -271,6 +271,18 @@ class CppHeaderGenerator extends StructuredGenerator { // Intentionally left empty. } + @override + void writeApis( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + super.writeApis(generatorOptions, root, sink, indent); + if (generatorOptions.namespace != null) { + indent.writeln('} // namespace ${generatorOptions.namespace}'); + } + final String guardName = _getGuardName( + generatorOptions.headerIncludePath, generatorOptions.namespace); + indent.writeln('#endif // $guardName'); + } + @override void writeFlutterApi( CppOptions generatorOptions, @@ -435,21 +447,6 @@ inline static $codeSerializerName& GetInstance() { indent.addln(''); } - @override - void writeGeneralUtilities( - CppOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - ) { - if (generatorOptions.namespace != null) { - indent.writeln('} // namespace ${generatorOptions.namespace}'); - } - final String guardName = _getGuardName( - generatorOptions.headerIncludePath, generatorOptions.namespace); - indent.writeln('#endif // $guardName'); - } - void _writeErrorOr(Indent indent, {Iterable friends = const []}) { final String friendLines = friends @@ -688,6 +685,15 @@ else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodabl indent.addln(''); } + @override + void writeApis( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + super.writeApis(generatorOptions, root, sink, indent); + if (generatorOptions.namespace != null) { + indent.writeln('} // namespace ${generatorOptions.namespace}'); + } + } + @override void writeFlutterApi( CppOptions generatorOptions, @@ -997,14 +1003,6 @@ flutter::EncodableList ${api.name}::WrapError(const FlutterError& error) { indent.addln(''); } - @override - void writeGeneralUtilities( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { - if (generatorOptions.namespace != null) { - indent.writeln('} // namespace ${generatorOptions.namespace}'); - } - } - void _writeCodec( CppOptions generatorOptions, Root root, diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index cfd53057ef8..7b8916db0ea 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -741,6 +741,8 @@ Result<$returnType> $resultName = new Result<$returnType>() { void writeGeneralUtilities( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { _writeWrapError(indent); + + // These lines close the main class. indent.dec(); indent.addln('}'); } diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index e7f21d81e8b..a3374dc6013 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -214,6 +214,13 @@ class ObjcHeaderGenerator extends StructuredGenerator { Set customEnumNames, ) {} + @override + void writeApis( + ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + super.writeApis(generatorOptions, root, sink, indent); + indent.writeln('NS_ASSUME_NONNULL_END'); + } + @override void writeFlutterApi( ObjcOptions generatorOptions, @@ -322,12 +329,6 @@ class ObjcHeaderGenerator extends StructuredGenerator { 'extern void ${apiName}Setup(id binaryMessenger, NSObject<$apiName> *_Nullable api);'); indent.writeln(''); } - - @override - void writeGeneralUtilities( - ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { - indent.writeln('NS_ASSUME_NONNULL_END'); - } } /// Generates Objc .m file. From ab2fef1a298dc5d13a7d6d834b5c0e64f51a5a2a Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 12 Jan 2023 12:28:59 -0800 Subject: [PATCH 81/87] update changelog --- packages/pigeon/CHANGELOG.md | 20 ++------------------ packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 3 files changed, 4 insertions(+), 20 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index bda54aef371..dd900fc77dd 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,22 +1,6 @@ -## 5.0.5 +## 6.0.0 -* Adds writeApi method to Generator classes. - -## 5.0.4 - -* Adds writeEnum method to Generator classes. - -## 5.0.3 - -* Adds writeEnum method to Generator classes. - -## 5.0.2 - -* Adds writeImports method to Generator classes. - -## 5.0.1 - -* Adds writeHeaders method to Generator classes and updates tests to use new Generators. +* Creates StructuredGenerator class and implements it on all platforms. ## 5.0.0 diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index 07eac70ad9b..3dc1df4d513 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -9,7 +9,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. This must match the version in pubspec.yaml. -const String pigeonVersion = '5.0.5'; +const String pigeonVersion = '6.0.0'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index e4feca00cb9..caa82a391df 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/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3Apigeon -version: 5.0.5 # This must match the version in lib/generator_tools.dart +version: 6.0.0 # This must match the version in lib/generator_tools.dart environment: sdk: ">=2.12.0 <3.0.0" From f324943c6bdd9235da7e7346e41aabf8f55316d0 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 12 Jan 2023 16:34:15 -0800 Subject: [PATCH 82/87] adds open and close namespace and fixes nits --- packages/pigeon/lib/cpp_generator.dart | 63 +++----- packages/pigeon/lib/dart_generator.dart | 2 +- packages/pigeon/lib/generator.dart | 38 ++++- packages/pigeon/lib/java_generator.dart | 10 +- packages/pigeon/lib/kotlin_generator.dart | 2 +- packages/pigeon/lib/objc_generator.dart | 14 +- packages/pigeon/lib/pigeon_lib.dart | 14 +- packages/pigeon/lib/swift_generator.dart | 2 +- .../CoreTests.java | 19 ++- .../com/example/test_plugin/CoreTests.gen.kt | 24 +-- .../ios/Classes/CoreTests.gen.swift | 24 +-- .../macos/Classes/CoreTests.gen.swift | 24 +-- packages/pigeon/test/cpp_generator_test.dart | 56 +++---- packages/pigeon/test/dart_generator_test.dart | 82 +++++----- packages/pigeon/test/java_generator_test.dart | 78 ++++----- .../pigeon/test/kotlin_generator_test.dart | 66 ++++---- packages/pigeon/test/objc_generator_test.dart | 148 +++++++++--------- .../pigeon/test/swift_generator_test.dart | 66 ++++---- 18 files changed, 372 insertions(+), 360 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 470ffc40a3c..402ed286a31 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -72,8 +72,8 @@ class CppOptions { /// Class that manages all Cpp code generation. class CppGenerator extends Generator> { - /// Instantiates a Cpp Generator. - CppGenerator(); + /// Constructor. + const CppGenerator(); /// Generates C++ file of type specified in [generatorOptions] @override @@ -82,10 +82,10 @@ class CppGenerator extends Generator> { assert(generatorOptions.fileType == FileType.header || generatorOptions.fileType == FileType.source); if (generatorOptions.fileType == FileType.header) { - CppHeaderGenerator() + const CppHeaderGenerator() .generate(generatorOptions.languageOptions, root, sink); } else if (generatorOptions.fileType == FileType.source) { - CppSourceGenerator() + const CppSourceGenerator() .generate(generatorOptions.languageOptions, root, sink); } } @@ -93,6 +93,9 @@ class CppGenerator extends Generator> { /// Writes C++ header (.h) file to sink. class CppHeaderGenerator extends StructuredGenerator { + /// Constructor. + const CppHeaderGenerator(); + @override void writeFilePrologue( CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -245,32 +248,6 @@ class CppHeaderGenerator extends StructuredGenerator { indent.writeln(''); } - @override - void writeClassEncode( - CppOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - ) { - // Intentionally left empty. - } - - @override - void writeClassDecode( - CppOptions generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - ) { - // Intentionally left empty. - } - @override void writeApis( CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -499,6 +476,9 @@ $friendLines /// Writes C++ source (.cpp) file to sink. class CppSourceGenerator extends StructuredGenerator { + /// Constructor. + const CppSourceGenerator(); + @override void writeFilePrologue( CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -530,7 +510,11 @@ class CppSourceGenerator extends StructuredGenerator { 'optional', ]); indent.addln(''); + } + @override + void writeOpenNamespace( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { if (generatorOptions.namespace != null) { indent.writeln('namespace ${generatorOptions.namespace} {'); } @@ -539,7 +523,7 @@ class CppSourceGenerator extends StructuredGenerator { @override void writeEnum(CppOptions generatorOptions, Root root, StringSink sink, Indent indent, Enum anEnum) { - // Intentionally left empty. + // Intentionally left empty as there are no enums in this file. } @override @@ -685,15 +669,6 @@ else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodabl indent.addln(''); } - @override - void writeApis( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { - super.writeApis(generatorOptions, root, sink, indent); - if (generatorOptions.namespace != null) { - indent.writeln('} // namespace ${generatorOptions.namespace}'); - } - } - @override void writeFlutterApi( CppOptions generatorOptions, @@ -1138,6 +1113,14 @@ ${prefix}flutter::EncodableList wrapped; $nonErrorPath ${prefix}reply(flutter::EncodableValue(std::move(wrapped)));'''; } + + @override + void writeCloseNamespace( + CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + if (generatorOptions.namespace != null) { + indent.writeln('} // namespace ${generatorOptions.namespace}'); + } + } } String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer'; diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index ba40f3f0f7e..80fa954c00a 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -73,7 +73,7 @@ class DartOptions { /// Class that manages all Dart code generation. class DartGenerator extends StructuredGenerator { /// Instantiates a Dart Generator. - DartGenerator(); + const DartGenerator(); @override void writeFilePrologue( diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index ae100c96402..05e1a2db8ea 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -5,16 +5,22 @@ import 'ast.dart'; import 'generator_tools.dart'; -/// A superclass of generator classes. +/// An abstract base class of generators. /// /// This provides the structure that is common across generators for different languages. abstract class Generator { + /// Constructor. + const Generator(); + /// Generates files for specified language with specified [generatorOptions] void generate(T generatorOptions, Root root, StringSink sink); } -/// A Superclass that enforces code generation across platforms. +/// An abstract base class that enforces code generation across platforms. abstract class StructuredGenerator extends Generator { + /// Constructor. + const StructuredGenerator(); + @override void generate( T generatorOptions, @@ -27,13 +33,17 @@ abstract class StructuredGenerator extends Generator { writeFileImports(generatorOptions, root, sink, indent); + writeOpenNamespace(generatorOptions, root, sink, indent); + + writeGeneralUtilities(generatorOptions, root, sink, indent); + writeEnums(generatorOptions, root, sink, indent); writeDataClasses(generatorOptions, root, sink, indent); writeApis(generatorOptions, root, sink, indent); - writeGeneralUtilities(generatorOptions, root, sink, indent); + writeCloseNamespace(generatorOptions, root, sink, indent); } /// Adds specified headers to file. @@ -44,6 +54,18 @@ abstract class StructuredGenerator extends Generator { void writeFileImports( T generatorOptions, Root root, StringSink sink, Indent indent); + /// Writes necessary code that opens file namespace if needed. + /// + /// This method is not required, and does not need to be overridden. + void writeOpenNamespace( + T generatorOptions, Root root, StringSink sink, Indent indent) {} + + /// Writes any necessary helper utilities to file if needed. + /// + /// This method is not required, and does not need to be overridden. + void writeGeneralUtilities( + T generatorOptions, Root root, StringSink sink, Indent indent) {} + /// Writes all enums to file. Can be overridden to add extra code before/after enums. void writeEnums( T generatorOptions, Root root, StringSink sink, Indent indent) { @@ -77,7 +99,7 @@ abstract class StructuredGenerator extends Generator { Class klass, Set customClassNames, Set customEnumNames, - ); + ) {} /// Writes a single class decode method to file. void writeClassDecode( @@ -88,7 +110,7 @@ abstract class StructuredGenerator extends Generator { Class klass, Set customClassNames, Set customEnumNames, - ); + ) {} /// Writes all data classes to file. Can be overridden to add extra code before/after classes. void writeApis( @@ -110,9 +132,9 @@ abstract class StructuredGenerator extends Generator { void writeHostApi( T generatorOptions, Root root, StringSink sink, Indent indent, Api api); - /// Writes any necessary helper utilities to file if needed. + /// Writes necessary code that closes file namespace if needed. /// - /// This method is not reqiured, and does not need to be overridden. - void writeGeneralUtilities( + /// This method is not required, and does not need to be overridden. + void writeCloseNamespace( T generatorOptions, Root root, StringSink sink, Indent indent) {} } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 7b8916db0ea..830eefb1636 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -88,7 +88,7 @@ class JavaOptions { /// Class that manages all Java code generation. class JavaGenerator extends StructuredGenerator { /// Instantiates a Java Generator. - JavaGenerator(); + const JavaGenerator(); @override void writeFilePrologue( @@ -126,7 +126,7 @@ class JavaGenerator extends StructuredGenerator { } @override - void writeEnums( + void writeOpenNamespace( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { indent.writeln( '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); @@ -137,7 +137,6 @@ class JavaGenerator extends StructuredGenerator { } indent.writeln('public class ${generatorOptions.className!} {'); indent.inc(); - super.writeEnums(generatorOptions, root, sink, indent); } @override @@ -741,8 +740,11 @@ Result<$returnType> $resultName = new Result<$returnType>() { void writeGeneralUtilities( JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { _writeWrapError(indent); + } - // These lines close the main class. + @override + void writeCloseNamespace( + JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { indent.dec(); indent.addln('}'); } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index d48a62c6b82..34564607ceb 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -68,7 +68,7 @@ class KotlinOptions { /// Class that manages all Kotlin code generation. class KotlinGenerator extends StructuredGenerator { /// Instantiates a Kotlin Generator. - KotlinGenerator(); + const KotlinGenerator(); @override void writeFilePrologue(KotlinOptions generatorOptions, Root root, diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index a3374dc6013..cbd54a5fb20 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -67,17 +67,17 @@ class ObjcOptions { /// Class that manages all Objc code generation. class ObjcGenerator extends Generator> { /// Instantiates a Objc Generator. - ObjcGenerator(); + const ObjcGenerator(); /// Generates Objc file of type specified in [generatorOptions] @override void generate(OutputFileOptions generatorOptions, Root root, StringSink sink) { if (generatorOptions.fileType == FileType.header) { - ObjcHeaderGenerator() + const ObjcHeaderGenerator() .generate(generatorOptions.languageOptions, root, sink); } else if (generatorOptions.fileType == FileType.source) { - ObjcSourceGenerator() + const ObjcSourceGenerator() .generate(generatorOptions.languageOptions, root, sink); } } @@ -85,6 +85,9 @@ class ObjcGenerator extends Generator> { /// Generates Objc .h file. class ObjcHeaderGenerator extends StructuredGenerator { + /// Constructor. + const ObjcHeaderGenerator(); + @override void writeFilePrologue( ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -333,6 +336,9 @@ class ObjcHeaderGenerator extends StructuredGenerator { /// Generates Objc .m file. class ObjcSourceGenerator extends StructuredGenerator { + /// Constructor. + const ObjcSourceGenerator(); + @override void writeFilePrologue( ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { @@ -360,7 +366,7 @@ class ObjcSourceGenerator extends StructuredGenerator { @override void writeEnum(ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent, Enum anEnum) { - // Intentionally left empty. + // Intentionally left empty as there are no enums in this file. } @override diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart index 40f3fee3048..04c0b95ab6f 100644 --- a/packages/pigeon/lib/pigeon_lib.dart +++ b/packages/pigeon/lib/pigeon_lib.dart @@ -426,7 +426,7 @@ class DartGeneratorAdapter implements GeneratorAdapter { StringSink sink, PigeonOptions options, Root root, FileType fileType) { final DartOptions dartOptionsWithHeader = _dartOptionsWithCopyrightHeader( options.dartOptions, options.copyrightHeader); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(dartOptionsWithHeader, root, sink); } @@ -455,7 +455,7 @@ class DartTestGeneratorAdapter implements GeneratorAdapter { dartOutPath: options.dartOut, testOutPath: options.dartTestOut, ); - final DartGenerator testGenerator = DartGenerator(); + const DartGenerator testGenerator = DartGenerator(); testGenerator.generateTest(dartOptionsWithHeader, root, sink); } @@ -493,7 +493,7 @@ class ObjcGeneratorAdapter implements GeneratorAdapter { final OutputFileOptions outputFileOptions = OutputFileOptions( fileType: fileType, languageOptions: objcOptionsWithHeader); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); generator.generate(outputFileOptions, root, sink); } @@ -528,7 +528,7 @@ class JavaGeneratorAdapter implements GeneratorAdapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); } @@ -556,7 +556,7 @@ class SwiftGeneratorAdapter implements GeneratorAdapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); } @@ -589,7 +589,7 @@ class CppGeneratorAdapter implements GeneratorAdapter { final OutputFileOptions outputFileOptions = OutputFileOptions( fileType: fileType, languageOptions: cppOptionsWithHeader); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); generator.generate(outputFileOptions, root, sink); } @@ -623,7 +623,7 @@ class KotlinGeneratorAdapter implements GeneratorAdapter { copyrightHeader: options.copyrightHeader != null ? _lineReader(options.copyrightHeader!) : null)); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); } diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index fb5f49754a6..1347a3cc770 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -51,7 +51,7 @@ class SwiftOptions { /// Class that manages all Swift code generation. class SwiftGenerator extends StructuredGenerator { /// Instantiates a Swift Generator. - SwiftGenerator(); + const SwiftGenerator(); @override void writeFilePrologue(SwiftOptions generatorOptions, Root root, diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java index bce812b6749..d97d0cc5df9 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java @@ -24,6 +24,15 @@ /** Generated class from Pigeon. */ @SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression"}) public class CoreTests { + @NonNull + private static ArrayList wrapError(@NonNull Throwable exception) { + ArrayList errorList = new ArrayList<>(3); + errorList.add(exception.toString()); + errorList.add(exception.getClass().getSimpleName()); + errorList.add( + "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); + return errorList; + } public enum AnEnum { ONE(0), @@ -1647,14 +1656,4 @@ static void setup(BinaryMessenger binaryMessenger, HostTrivialApi api) { } } } - - @NonNull - private static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList<>(3); - errorList.add(exception.toString()); - errorList.add(exception.getClass().getSimpleName()); - errorList.add( - "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); - return errorList; - } } diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt index 46ac1490507..c2c039086f5 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/CoreTests.gen.kt @@ -15,6 +15,18 @@ import io.flutter.plugin.common.StandardMessageCodec import java.io.ByteArrayOutputStream import java.nio.ByteBuffer +private fun wrapResult(result: Any?): List { + return listOf(result) +} + +private fun wrapError(exception: Throwable): List { + return listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) + ) +} + enum class AnEnum(val raw: Int) { ONE(0), TWO(1), @@ -808,15 +820,3 @@ interface HostTrivialApi { } } } - -private fun wrapResult(result: Any?): List { - return listOf(result) -} - -private fun wrapError(exception: Throwable): List { - return listOf( - exception.javaClass.simpleName, - exception.toString(), - "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) - ) -} diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift index b957c87a03b..407ee693538 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/CoreTests.gen.swift @@ -16,6 +16,18 @@ import FlutterMacOS +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: FlutterError) -> [Any?] { + return [ + error.code, + error.message, + error.details + ] +} + enum AnEnum: Int { case one = 0 case two = 1 @@ -665,15 +677,3 @@ class HostTrivialApiSetup { } } } - -private func wrapResult(_ result: Any?) -> [Any?] { - return [result] -} - -private func wrapError(_ error: FlutterError) -> [Any?] { - return [ - error.code, - error.message, - error.details - ] -} diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift index b957c87a03b..407ee693538 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/CoreTests.gen.swift @@ -16,6 +16,18 @@ import FlutterMacOS +private func wrapResult(_ result: Any?) -> [Any?] { + return [result] +} + +private func wrapError(_ error: FlutterError) -> [Any?] { + return [ + error.code, + error.message, + error.details + ] +} + enum AnEnum: Int { case one = 0 case two = 1 @@ -665,15 +677,3 @@ class HostTrivialApiSetup { } } } - -private func wrapResult(_ result: Any?) -> [Any?] { - return [result] -} - -private func wrapError(_ error: FlutterError) -> [Any?] { - return [ - error.code, - error.message, - error.details - ] -} diff --git a/packages/pigeon/test/cpp_generator_test.dart b/packages/pigeon/test/cpp_generator_test.dart index 16854a0f509..97dc1298600 100644 --- a/packages/pigeon/test/cpp_generator_test.dart +++ b/packages/pigeon/test/cpp_generator_test.dart @@ -46,7 +46,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -60,7 +60,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -114,7 +114,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -135,7 +135,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -169,7 +169,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -219,7 +219,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -279,7 +279,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -292,7 +292,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -324,7 +324,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -345,7 +345,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -387,7 +387,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -400,7 +400,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -467,7 +467,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -505,7 +505,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -610,7 +610,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -641,7 +641,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -745,7 +745,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -856,7 +856,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -944,7 +944,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -964,7 +964,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1087,7 +1087,7 @@ void main() { ], enums: []); { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1107,7 +1107,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1173,7 +1173,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1291,7 +1291,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1332,7 +1332,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1380,7 +1380,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1455,7 +1455,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1515,7 +1515,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final CppGenerator generator = CppGenerator(); + const CppGenerator generator = CppGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, diff --git a/packages/pigeon/test/dart_generator_test.dart b/packages/pigeon/test/dart_generator_test.dart index 15ce9e09ac4..d99dde7a71b 100644 --- a/packages/pigeon/test/dart_generator_test.dart +++ b/packages/pigeon/test/dart_generator_test.dart @@ -29,7 +29,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); @@ -50,7 +50,7 @@ void main() { enums: [anEnum], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum Foobar')); @@ -94,7 +94,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); @@ -121,7 +121,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); @@ -149,7 +149,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); @@ -187,7 +187,7 @@ void main() { ) ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( @@ -230,7 +230,7 @@ void main() { ) ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( @@ -283,7 +283,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('abstract class Api')); @@ -318,7 +318,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doSomething')); @@ -352,7 +352,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); // The next line verifies that we're not setting a variable to the value of "doSomething", but @@ -383,7 +383,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('output.*=.*doSomething[(][)]')); @@ -426,7 +426,7 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum1?.index,')); @@ -454,7 +454,7 @@ void main() { ]) ]); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum Foo {')); @@ -498,7 +498,7 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('enum1.index,')); @@ -526,7 +526,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('channel.send[(]null[)]')); @@ -585,7 +585,7 @@ void main() { ], enums: []); final StringBuffer mainCodeSink = StringBuffer(); final StringBuffer testCodeSink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, mainCodeSink); final String mainCode = mainCodeSink.toString(); expect(mainCode, isNot(contains(r"import 'fo\'o.dart';"))); @@ -595,7 +595,7 @@ void main() { expect(mainCode, isNot(contains("'${Keys.result}': output"))); expect(mainCode, isNot(contains('return [];'))); - final DartGenerator testGenerator = DartGenerator(); + const DartGenerator testGenerator = DartGenerator(); testGenerator.generateTest( DartOptions( sourceOutPath: "fo'o.dart", @@ -650,7 +650,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('abstract class Api')); @@ -695,7 +695,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.s*doSomething'))); @@ -740,7 +740,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Api')); @@ -769,7 +769,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, matches('channel.send[(]null[)]')); @@ -783,7 +783,7 @@ void main() { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate( DartOptions(copyrightHeader: makeIterable('hello world')), root, @@ -813,7 +813,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); @@ -841,7 +841,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); @@ -871,7 +871,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doit(List arg')); @@ -900,7 +900,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('doit(List arg')); @@ -925,7 +925,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future> doit(')); @@ -961,7 +961,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('List doit(')); @@ -989,7 +989,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit()')); @@ -1015,7 +1015,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future?> doit()')); @@ -1041,7 +1041,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit()')); @@ -1065,7 +1065,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('int? doit();')); @@ -1090,7 +1090,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit();')); @@ -1114,7 +1114,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect( @@ -1144,7 +1144,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('Future doit(int? arg_foo) async {')); @@ -1171,7 +1171,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('void doit(int? foo);')); @@ -1189,7 +1189,7 @@ name: foobar final Root root = Root(classes: [], apis: [], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator testGenerator = DartGenerator(); + const DartGenerator testGenerator = DartGenerator(); testGenerator.generateTest( DartOptions( sourceOutPath: path.join(foo.path, 'bar.dart'), @@ -1279,7 +1279,7 @@ name: foobar ], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); for (final String comment in comments) { @@ -1315,7 +1315,7 @@ name: foobar enums: [], ); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, isNot(contains('extends StandardMessageCodec'))); @@ -1359,7 +1359,7 @@ name: foobar ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final DartGenerator generator = DartGenerator(); + const DartGenerator generator = DartGenerator(); generator.generate(DartOptions(), root, sink); final String code = sink.toString(); expect(code, contains('extends StandardMessageCodec')); @@ -1399,7 +1399,7 @@ name: foobar ); final StringBuffer sink = StringBuffer(); - final DartGenerator testGenerator = DartGenerator(); + const DartGenerator testGenerator = DartGenerator(); testGenerator.generateTest( DartOptions( sourceOutPath: 'code.dart', diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index f2a25288754..40ec00545e7 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -27,7 +27,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public class Messages')); @@ -56,7 +56,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Foobar')); @@ -88,7 +88,7 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages', package: 'com.google.foobar'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('package com.google.foobar;')); @@ -132,7 +132,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public interface Api')); @@ -204,7 +204,7 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('private @Nullable Boolean aBool;')); @@ -254,7 +254,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Api')); @@ -289,7 +289,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('=.*doSomething'))); @@ -324,7 +324,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Reply')); @@ -353,7 +353,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Output doSomething()')); @@ -382,7 +382,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doSomething(Reply')); @@ -402,7 +402,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Foobar')); @@ -422,7 +422,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Foobar')); @@ -459,7 +459,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public class Messages')); @@ -511,7 +511,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public interface Api')); @@ -563,7 +563,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public static class Api')); @@ -597,7 +597,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Enum1')); @@ -637,7 +637,7 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('public enum Foo')); @@ -658,7 +658,7 @@ void main() { className: 'Messages', copyrightHeader: makeIterable('hello world'), ); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); @@ -685,7 +685,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); @@ -714,7 +714,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Foobar')); @@ -745,7 +745,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(@NonNull List arg')); @@ -775,7 +775,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(@NonNull List arg')); @@ -801,7 +801,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('List doit(')); @@ -828,7 +828,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(Reply> callback)')); @@ -852,7 +852,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('doit(Reply callback)')); @@ -883,7 +883,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Messages')); @@ -915,7 +915,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Api'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('Object xArg = args.get(0)')); @@ -942,7 +942,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Messages')); @@ -975,7 +975,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( @@ -1002,7 +1002,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('@Nullable Long doit();')); @@ -1027,7 +1027,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); // Java doesn't accept nullability annotations in type arguments. @@ -1056,7 +1056,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains(' void doit(@Nullable Long foo);')); @@ -1084,7 +1084,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( @@ -1116,7 +1116,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect( @@ -1142,7 +1142,7 @@ void main() { final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages', useGeneratedAnnotation: true); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains('@javax.annotation.Generated("dev.flutter.pigeon")')); @@ -1160,7 +1160,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, @@ -1243,7 +1243,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { @@ -1284,7 +1284,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(' extends StandardMessageCodec'))); @@ -1329,7 +1329,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const JavaOptions javaOptions = JavaOptions(className: 'Messages'); - final JavaGenerator generator = JavaGenerator(); + const JavaGenerator generator = JavaGenerator(); generator.generate(javaOptions, root, sink); final String code = sink.toString(); expect(code, contains(' extends StandardMessageCodec')); diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 96056c1b1b1..aa4ec3efb37 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -27,7 +27,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar (')); @@ -51,7 +51,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Foobar(val raw: Int) {')); @@ -80,7 +80,7 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Foo(val raw: Int) {')); @@ -127,7 +127,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('interface Api')); @@ -217,7 +217,7 @@ void main() { final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val aBool: Boolean? = null')); @@ -270,7 +270,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, @@ -308,7 +308,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('.*doSomething(.*) ->'))); @@ -345,7 +345,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('callback: () -> Unit')); @@ -375,7 +375,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doSomething(): Output')); @@ -407,7 +407,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doSomething(callback: (Output) -> Unit)')); @@ -428,7 +428,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); @@ -449,7 +449,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); @@ -488,7 +488,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Outer')); @@ -542,7 +542,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('interface Api')); @@ -591,7 +591,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); @@ -625,7 +625,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum class Enum1(val raw: Int)')); @@ -643,7 +643,7 @@ void main() { final KotlinOptions kotlinOptions = KotlinOptions( copyrightHeader: makeIterable('hello world'), ); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); @@ -671,7 +671,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); @@ -701,7 +701,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('data class Foobar')); @@ -733,7 +733,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(arg: List')); @@ -764,7 +764,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(argArg: List')); @@ -790,7 +790,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(): List')); @@ -818,7 +818,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(callback: (List) -> Unit')); @@ -847,7 +847,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun add(x: Long, y: Long): Long')); @@ -885,7 +885,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val channel = BasicMessageChannel')); @@ -914,7 +914,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(): Long?')); @@ -939,7 +939,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(callback: (Long?) -> Unit')); @@ -967,7 +967,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect( @@ -998,7 +998,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('fun doit(fooArg: Long?, callback: () -> Unit')); @@ -1034,7 +1034,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains('val input: String\n')); @@ -1116,7 +1116,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { @@ -1157,7 +1157,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(' : StandardMessageCodec() '))); @@ -1202,7 +1202,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const KotlinOptions kotlinOptions = KotlinOptions(); - final KotlinGenerator generator = KotlinGenerator(); + const KotlinGenerator generator = KotlinGenerator(); generator.generate(kotlinOptions, root, sink); final String code = sink.toString(); expect(code, contains(' : StandardMessageCodec() ')); diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart index c6b45fd4d43..64f92c857eb 100644 --- a/packages/pigeon/test/objc_generator_test.dart +++ b/packages/pigeon/test/objc_generator_test.dart @@ -18,7 +18,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -39,7 +39,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -62,7 +62,7 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -86,7 +86,7 @@ void main() { ) ]); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -128,7 +128,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -167,7 +167,7 @@ void main() { const ObjcOptions options = ObjcOptions(headerIncludePath: 'foo.h', prefix: 'AC'); { - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -179,7 +179,7 @@ void main() { expect(code, contains(':(ACFoo)foo error:')); } { - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -248,7 +248,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -286,7 +286,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -331,7 +331,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -384,7 +384,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -418,7 +418,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -445,7 +445,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -471,7 +471,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -496,7 +496,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -516,7 +516,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -556,7 +556,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -598,7 +598,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -640,7 +640,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -685,7 +685,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -720,7 +720,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -755,7 +755,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -792,7 +792,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -827,7 +827,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -857,7 +857,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -886,7 +886,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -915,7 +915,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -947,7 +947,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -972,7 +972,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -993,7 +993,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1020,7 +1020,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1055,7 +1055,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1095,7 +1095,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1140,7 +1140,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1173,7 +1173,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1199,7 +1199,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1244,7 +1244,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1288,7 +1288,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1314,7 +1314,7 @@ void main() { ]) ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1347,7 +1347,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1369,7 +1369,7 @@ void main() { test('source copyright', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1386,7 +1386,7 @@ void main() { test('header copyright', () { final Root root = Root(apis: [], classes: [], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1420,7 +1420,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1456,7 +1456,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1469,7 +1469,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1509,7 +1509,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1522,7 +1522,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1565,7 +1565,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1598,7 +1598,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1612,7 +1612,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1645,7 +1645,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1659,7 +1659,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1694,7 +1694,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1710,7 +1710,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1751,7 +1751,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1767,7 +1767,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1806,7 +1806,7 @@ void main() { ], classes: [], enums: []); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1822,7 +1822,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1872,7 +1872,7 @@ void main() { final Root divideRoot = getDivideRoot(ApiLocation.host); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1885,7 +1885,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1902,7 +1902,7 @@ void main() { final Root divideRoot = getDivideRoot(ApiLocation.flutter); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1915,7 +1915,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -1937,7 +1937,7 @@ void main() { ]), ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1966,7 +1966,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -1997,7 +1997,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -2025,7 +2025,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -2058,7 +2058,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -2070,7 +2070,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -2105,7 +2105,7 @@ void main() { ); { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -2117,7 +2117,7 @@ void main() { } { final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -2147,7 +2147,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -2237,7 +2237,7 @@ void main() { ], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.header, @@ -2278,7 +2278,7 @@ void main() { enums: [], ); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, @@ -2326,7 +2326,7 @@ void main() { ]) ], enums: []); final StringBuffer sink = StringBuffer(); - final ObjcGenerator generator = ObjcGenerator(); + const ObjcGenerator generator = ObjcGenerator(); final OutputFileOptions generatorOptions = OutputFileOptions( fileType: FileType.source, diff --git a/packages/pigeon/test/swift_generator_test.dart b/packages/pigeon/test/swift_generator_test.dart index 305ca203fe7..dfd2dfbb487 100644 --- a/packages/pigeon/test/swift_generator_test.dart +++ b/packages/pigeon/test/swift_generator_test.dart @@ -26,7 +26,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); @@ -50,7 +50,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Foobar: Int')); @@ -79,7 +79,7 @@ void main() { ]); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Foo: Int')); @@ -123,7 +123,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('protocol Api')); @@ -187,7 +187,7 @@ void main() { final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('var aBool: Bool? = nil')); @@ -237,7 +237,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); @@ -273,7 +273,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, isNot(matches('.*doSomething(.*) ->'))); @@ -308,7 +308,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('completion: @escaping () -> Void')); @@ -337,7 +337,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doSomething() -> Output')); @@ -367,7 +367,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, @@ -388,7 +388,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); @@ -408,7 +408,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); @@ -445,7 +445,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Outer')); @@ -494,7 +494,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('protocol Api')); @@ -540,7 +540,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('class Api')); @@ -573,7 +573,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('enum Enum1: Int')); @@ -591,7 +591,7 @@ void main() { final SwiftOptions swiftOptions = SwiftOptions( copyrightHeader: makeIterable('hello world'), ); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, startsWith('// hello world')); @@ -618,7 +618,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); @@ -647,7 +647,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('struct Foobar')); @@ -678,7 +678,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(arg: [Int32?]')); @@ -708,7 +708,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(arg argArg: [Int32?]')); @@ -734,7 +734,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit() -> [Int32?]')); @@ -762,7 +762,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect( @@ -792,7 +792,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func add(x: Int32, y: Int32) -> Int32')); @@ -824,7 +824,7 @@ void main() { ], classes: [], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('let channel = FlutterBasicMessageChannel')); @@ -855,7 +855,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit() -> Int32?')); @@ -880,7 +880,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('func doit(completion: @escaping (Int32?) -> Void')); @@ -908,7 +908,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('let fooArg = args[0] as? Int32')); @@ -936,7 +936,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect( @@ -973,7 +973,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains('var input: String\n')); @@ -1055,7 +1055,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); for (final String comment in comments) { @@ -1092,7 +1092,7 @@ void main() { ); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, isNot(contains(': FlutterStandardReader '))); @@ -1136,7 +1136,7 @@ void main() { ], enums: []); final StringBuffer sink = StringBuffer(); const SwiftOptions swiftOptions = SwiftOptions(); - final SwiftGenerator generator = SwiftGenerator(); + const SwiftGenerator generator = SwiftGenerator(); generator.generate(swiftOptions, root, sink); final String code = sink.toString(); expect(code, contains(': FlutterStandardReader ')); From 32bb197f981e99959b383924dff7299134b8c21d Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 12 Jan 2023 16:42:38 -0800 Subject: [PATCH 83/87] makes writeEnum optional --- packages/pigeon/lib/cpp_generator.dart | 6 ------ packages/pigeon/lib/generator.dart | 4 ++-- packages/pigeon/lib/objc_generator.dart | 6 ------ 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 402ed286a31..b5def44593e 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -520,12 +520,6 @@ class CppSourceGenerator extends StructuredGenerator { } } - @override - void writeEnum(CppOptions generatorOptions, Root root, StringSink sink, - Indent indent, Enum anEnum) { - // Intentionally left empty as there are no enums in this file. - } - @override void writeDataClass(CppOptions generatorOptions, Root root, StringSink sink, Indent indent, Class klass) { diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 05e1a2db8ea..13bd4ff92a9 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -74,9 +74,9 @@ abstract class StructuredGenerator extends Generator { } } - /// Writes a single Enum to file. + /// Writes a single Enum to file. This is needed in most generators. void writeEnum(T generatorOptions, Root root, StringSink sink, Indent indent, - Enum anEnum); + Enum anEnum) {} /// Writes all apis to file. Can be overridden to add extra code before/after apis. void writeDataClasses( diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index cbd54a5fb20..4197f23741d 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -363,12 +363,6 @@ class ObjcSourceGenerator extends StructuredGenerator { indent.addln(''); } - @override - void writeEnum(ObjcOptions generatorOptions, Root root, StringSink sink, - Indent indent, Enum anEnum) { - // Intentionally left empty as there are no enums in this file. - } - @override void writeDataClasses( ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { From c9f2a57c8200f6540cdf9ea93858c1b054af03ae Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Thu, 12 Jan 2023 22:35:31 -0800 Subject: [PATCH 84/87] remove unneeded sink --- packages/pigeon/lib/cpp_generator.dart | 71 ++++------ packages/pigeon/lib/dart_generator.dart | 40 +++--- packages/pigeon/lib/generator.dart | 129 ++++++++---------- packages/pigeon/lib/java_generator.dart | 58 ++++---- packages/pigeon/lib/kotlin_generator.dart | 35 ++--- packages/pigeon/lib/objc_generator.dart | 65 ++++----- packages/pigeon/lib/swift_generator.dart | 38 +++--- .../windows/pigeon/core_tests.gen.h | 4 +- 8 files changed, 188 insertions(+), 252 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index b5def44593e..b7cc211ed5f 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -98,7 +98,7 @@ class CppHeaderGenerator extends StructuredGenerator { @override void writeFilePrologue( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + CppOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.copyrightHeader != null) { addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } @@ -108,8 +108,7 @@ class CppHeaderGenerator extends StructuredGenerator { } @override - void writeFileImports( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + void writeFileImports(CppOptions generatorOptions, Root root, Indent indent) { final String guardName = _getGuardName( generatorOptions.headerIncludePath, generatorOptions.namespace); indent.writeln('#ifndef $guardName'); @@ -142,8 +141,8 @@ class CppHeaderGenerator extends StructuredGenerator { } @override - void writeEnum(CppOptions generatorOptions, Root root, StringSink sink, - Indent indent, Enum anEnum) { + void writeEnum( + CppOptions generatorOptions, Root root, Indent indent, Enum anEnum) { indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -159,15 +158,14 @@ class CppHeaderGenerator extends StructuredGenerator { } @override - void writeDataClasses( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + void writeGeneralUtilities( + CppOptions generatorOptions, Root root, Indent indent) { _writeErrorOr(indent, friends: root.apis.map((Api api) => api.name)); - super.writeDataClasses(generatorOptions, root, sink, indent); } @override - void writeDataClass(CppOptions generatorOptions, Root root, StringSink sink, - Indent indent, Class klass) { + void writeDataClass( + CppOptions generatorOptions, Root root, Indent indent, Class klass) { // When generating for a Pigeon unit test, add a test fixture friend class to // allow unit testing private methods, since testing serialization via public // methods is essentially an end-to-end test. @@ -249,9 +247,8 @@ class CppHeaderGenerator extends StructuredGenerator { } @override - void writeApis( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { - super.writeApis(generatorOptions, root, sink, indent); + void writeApis(CppOptions generatorOptions, Root root, Indent indent) { + super.writeApis(generatorOptions, root, indent); if (generatorOptions.namespace != null) { indent.writeln('} // namespace ${generatorOptions.namespace}'); } @@ -264,13 +261,12 @@ class CppHeaderGenerator extends StructuredGenerator { void writeFlutterApi( CppOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { assert(api.location == ApiLocation.flutter); if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(generatorOptions, root, sink, indent, api); + _writeCodec(generatorOptions, root, indent, api); } const List generatedMessages = [ ' Generated class from Pigeon that represents Flutter messages that can be called from C++.' @@ -317,13 +313,12 @@ class CppHeaderGenerator extends StructuredGenerator { void writeHostApi( CppOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { assert(api.location == ApiLocation.host); if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(generatorOptions, root, sink, indent, api); + _writeCodec(generatorOptions, root, indent, api); } const List generatedMessages = [ ' Generated interface from Pigeon that represents a handler of messages from Flutter.' @@ -395,8 +390,8 @@ class CppHeaderGenerator extends StructuredGenerator { }, nestCount: 0); } - void _writeCodec(CppOptions generatorOptions, Root root, StringSink sink, - Indent indent, Api api) { + void _writeCodec( + CppOptions generatorOptions, Root root, Indent indent, Api api) { assert(getCodecClasses(api, root).isNotEmpty); final String codeSerializerName = _getCodecSerializerName(api); indent @@ -481,7 +476,7 @@ class CppSourceGenerator extends StructuredGenerator { @override void writeFilePrologue( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + CppOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.copyrightHeader != null) { addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } @@ -493,8 +488,7 @@ class CppSourceGenerator extends StructuredGenerator { } @override - void writeFileImports( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + void writeFileImports(CppOptions generatorOptions, Root root, Indent indent) { indent.writeln('#include "${generatorOptions.headerIncludePath}"'); indent.addln(''); _writeSystemHeaderIncludeBlock(indent, [ @@ -514,15 +508,15 @@ class CppSourceGenerator extends StructuredGenerator { @override void writeOpenNamespace( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + CppOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.namespace != null) { indent.writeln('namespace ${generatorOptions.namespace} {'); } } @override - void writeDataClass(CppOptions generatorOptions, Root root, StringSink sink, - Indent indent, Class klass) { + void writeDataClass( + CppOptions generatorOptions, Root root, Indent indent, Class klass) { final Set customClassNames = root.classes.map((Class x) => x.name).toSet(); final Set customEnumNames = @@ -534,28 +528,26 @@ class CppSourceGenerator extends StructuredGenerator { // Getters and setters. for (final NamedType field in getFieldsInSerializationOrder(klass)) { - _writeCppSourceClassField( - generatorOptions, root, sink, indent, klass, field); + _writeCppSourceClassField(generatorOptions, root, indent, klass, field); } // Serialization. - writeClassEncode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); + writeClassEncode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); // Default constructor. indent.writeln('${klass.name}::${klass.name}() {}'); indent.addln(''); // Deserialization. - writeClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); + writeClassDecode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); } @override void writeClassEncode( CppOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -608,7 +600,6 @@ class CppSourceGenerator extends StructuredGenerator { void writeClassDecode( CppOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -667,13 +658,12 @@ else if (const int64_t* ${pointerFieldName}_64 = std::get_if(&$encodabl void writeFlutterApi( CppOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { assert(api.location == ApiLocation.flutter); if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(generatorOptions, root, sink, indent, api); + _writeCodec(generatorOptions, root, indent, api); } indent.writeln( '$_commentPrefix Generated class from Pigeon that represents Flutter messages that can be called from C++.'); @@ -773,11 +763,11 @@ else if (const int64_t* ${pointerVariable}_64 = std::get_if(&args)) } @override - void writeHostApi(CppOptions generatorOptions, Root root, StringSink sink, - Indent indent, Api api) { + void writeHostApi( + CppOptions generatorOptions, Root root, Indent indent, Api api) { assert(api.location == ApiLocation.host); if (getCodecClasses(api, root).isNotEmpty) { - _writeCodec(generatorOptions, root, sink, indent, api); + _writeCodec(generatorOptions, root, indent, api); } final String codeSerializerName = getCodecClasses(api, root).isNotEmpty @@ -973,7 +963,6 @@ flutter::EncodableValue ${api.name}::WrapError(const FlutterError& error) { void _writeCodec( CppOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { @@ -1023,7 +1012,7 @@ flutter::EncodableValue ${api.name}::WrapError(const FlutterError& error) { } void _writeCppSourceClassField(CppOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, NamedType field) { + Indent indent, Class klass, NamedType field) { final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, root.enums, (TypeDeclaration x) => _baseCppTypeForBuiltinDartType(x)); final String instanceVariableName = _makeInstanceVariableName(field); @@ -1110,7 +1099,7 @@ ${prefix}reply(flutter::EncodableValue(std::move(wrapped)));'''; @override void writeCloseNamespace( - CppOptions generatorOptions, Root root, StringSink sink, Indent indent) { + CppOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.namespace != null) { indent.writeln('} // namespace ${generatorOptions.namespace}'); } diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 80fa954c00a..0961f006ce4 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -77,7 +77,7 @@ class DartGenerator extends StructuredGenerator { @override void writeFilePrologue( - DartOptions generatorOptions, Root root, StringSink sink, Indent indent) { + DartOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.copyrightHeader != null) { addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } @@ -91,7 +91,7 @@ class DartGenerator extends StructuredGenerator { @override void writeFileImports( - DartOptions generatorOptions, Root root, StringSink sink, Indent indent) { + DartOptions generatorOptions, Root root, Indent indent) { indent.writeln("import 'dart:async';"); indent.writeln( "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", @@ -103,8 +103,8 @@ class DartGenerator extends StructuredGenerator { } @override - void writeEnum(DartOptions generatorOptions, Root root, StringSink sink, - Indent indent, Enum anEnum) { + void writeEnum( + DartOptions generatorOptions, Root root, Indent indent, Enum anEnum) { indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -119,8 +119,8 @@ class DartGenerator extends StructuredGenerator { } @override - void writeDataClass(DartOptions generatorOptions, Root root, StringSink sink, - Indent indent, Class klass) { + void writeDataClass( + DartOptions generatorOptions, Root root, Indent indent, Class klass) { final Set customClassNames = root.classes.map((Class x) => x.name).toSet(); final Set customEnumNames = @@ -142,11 +142,11 @@ class DartGenerator extends StructuredGenerator { indent.writeln('$datatype ${field.name};'); indent.writeln(''); } - writeClassEncode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); + writeClassEncode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); indent.writeln(''); - writeClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); + writeClassDecode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); }); } @@ -164,7 +164,6 @@ class DartGenerator extends StructuredGenerator { void writeClassEncode( DartOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -198,7 +197,6 @@ class DartGenerator extends StructuredGenerator { void writeClassDecode( DartOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -281,7 +279,6 @@ $resultAt != null void writeFlutterApi( DartOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, { String Function(Method)? channelNameFunc, @@ -441,8 +438,8 @@ $resultAt != null /// If the message was a failure, the list will contain 3 items: /// a code, a message, and details in that order. @override - void writeHostApi(DartOptions generatorOptions, Root root, StringSink sink, - Indent indent, Api api) { + void writeHostApi( + DartOptions generatorOptions, Root root, Indent indent, Api api) { assert(api.location == ApiLocation.host); String codecName = _standardMessageCodec; if (getCodecClasses(api, root).isNotEmpty) { @@ -559,8 +556,8 @@ if (replyList == null) { final Indent indent = Indent(sink); final String sourceOutPath = generatorOptions.sourceOutPath ?? ''; final String testOutPath = generatorOptions.testOutPath ?? ''; - _writeTestPrologue(generatorOptions, root, sink, indent); - _writeTestImports(generatorOptions, root, sink, indent); + _writeTestPrologue(generatorOptions, root, indent); + _writeTestImports(generatorOptions, root, indent); final String relativeDartPath = path.Context(style: path.Style.posix).relative( _posixify(sourceOutPath), @@ -592,7 +589,6 @@ if (replyList == null) { writeFlutterApi( generatorOptions, root, - sink, indent, mockApi, channelNameFunc: (Method func) => makeChannelName(api, func), @@ -603,8 +599,7 @@ if (replyList == null) { } /// Writes file header to sink. - void _writeTestPrologue( - DartOptions opt, Root root, StringSink sink, Indent indent) { + void _writeTestPrologue(DartOptions opt, Root root, Indent indent) { if (opt.copyrightHeader != null) { addLines(indent, opt.copyrightHeader!, linePrefix: '// '); } @@ -617,8 +612,7 @@ if (replyList == null) { } /// Writes file imports to sink. - void _writeTestImports( - DartOptions opt, Root root, StringSink sink, Indent indent) { + void _writeTestImports(DartOptions opt, Root root, Indent indent) { indent.writeln("import 'dart:async';"); indent.writeln( "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", @@ -764,7 +758,7 @@ String _addGenericTypesNullable(TypeDeclaration type) { /// Generates Dart source code for the given AST represented by [root], /// outputting the code to [sink]. -void generateDart(DartOptions opt, Root root, StringSink sink, Indent indent) {} +void generateDart(DartOptions opt, Root root, Indent indent) {} /// Crawls up the path of [dartFilePath] until it finds a pubspec.yaml in a /// parent directory and returns its path. diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index 13bd4ff92a9..b7c0bf2de3c 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -1,6 +1,6 @@ // Copyright 2013 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. +// found in the LICENSE [indent]. import 'ast.dart'; import 'generator_tools.dart'; @@ -29,112 +29,93 @@ abstract class StructuredGenerator extends Generator { ) { final Indent indent = Indent(sink); - writeFilePrologue(generatorOptions, root, sink, indent); + writeFilePrologue(generatorOptions, root, indent); - writeFileImports(generatorOptions, root, sink, indent); + writeFileImports(generatorOptions, root, indent); - writeOpenNamespace(generatorOptions, root, sink, indent); + writeOpenNamespace(generatorOptions, root, indent); - writeGeneralUtilities(generatorOptions, root, sink, indent); + writeGeneralUtilities(generatorOptions, root, indent); - writeEnums(generatorOptions, root, sink, indent); + writeEnums(generatorOptions, root, indent); - writeDataClasses(generatorOptions, root, sink, indent); + writeDataClasses(generatorOptions, root, indent); - writeApis(generatorOptions, root, sink, indent); + writeApis(generatorOptions, root, indent); - writeCloseNamespace(generatorOptions, root, sink, indent); + writeCloseNamespace(generatorOptions, root, indent); } - /// Adds specified headers to file. - void writeFilePrologue( - T generatorOptions, Root root, StringSink sink, Indent indent); + /// Adds specified headers to [indent]. + void writeFilePrologue(T generatorOptions, Root root, Indent indent); - /// Writes specified imports to file. - void writeFileImports( - T generatorOptions, Root root, StringSink sink, Indent indent); + /// Writes specified imports to [indent]. + void writeFileImports(T generatorOptions, Root root, Indent indent); - /// Writes necessary code that opens file namespace if needed. + /// Writes code to [indent] that opens file namespace if needed. /// /// This method is not required, and does not need to be overridden. - void writeOpenNamespace( - T generatorOptions, Root root, StringSink sink, Indent indent) {} + void writeOpenNamespace(T generatorOptions, Root root, Indent indent) {} - /// Writes any necessary helper utilities to file if needed. + /// Writes code to [indent] that closes file namespace if needed. /// /// This method is not required, and does not need to be overridden. - void writeGeneralUtilities( - T generatorOptions, Root root, StringSink sink, Indent indent) {} + void writeCloseNamespace(T generatorOptions, Root root, Indent indent) {} - /// Writes all enums to file. Can be overridden to add extra code before/after enums. - void writeEnums( - T generatorOptions, Root root, StringSink sink, Indent indent) { + /// Writes any necessary helper utilities to [indent] if needed. + /// + /// This method is not required, and does not need to be overridden. + void writeGeneralUtilities(T generatorOptions, Root root, Indent indent) {} + + /// Writes all enums to [indent]. + /// + /// Can be overridden to add extra code before/after enums. + void writeEnums(T generatorOptions, Root root, Indent indent) { for (final Enum anEnum in root.enums) { - writeEnum(generatorOptions, root, sink, indent, anEnum); + writeEnum(generatorOptions, root, indent, anEnum); } } - /// Writes a single Enum to file. This is needed in most generators. - void writeEnum(T generatorOptions, Root root, StringSink sink, Indent indent, - Enum anEnum) {} + /// Writes a single Enum to [indent]. This is needed in most generators. + void writeEnum(T generatorOptions, Root root, Indent indent, Enum anEnum) {} - /// Writes all apis to file. Can be overridden to add extra code before/after apis. - void writeDataClasses( - T generatorOptions, Root root, StringSink sink, Indent indent) { + /// Writes all data classes to [indent]. + /// + /// Can be overridden to add extra code before/after apis. + void writeDataClasses(T generatorOptions, Root root, Indent indent) { for (final Class klass in root.classes) { - writeDataClass(generatorOptions, root, sink, indent, klass); + writeDataClass(generatorOptions, root, indent, klass); } } - /// Writes a single data class to file. - void writeDataClass(T generatorOptions, Root root, StringSink sink, - Indent indent, Class klass); + /// Writes a single data class to [indent]. + void writeDataClass( + T generatorOptions, Root root, Indent indent, Class klass); - /// Writes a single class encode method to file. - void writeClassEncode( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - ) {} - - /// Writes a single class decode method to file. - void writeClassDecode( - T generatorOptions, - Root root, - StringSink sink, - Indent indent, - Class klass, - Set customClassNames, - Set customEnumNames, - ) {} - - /// Writes all data classes to file. Can be overridden to add extra code before/after classes. - void writeApis( - T generatorOptions, Root root, StringSink sink, Indent indent) { + /// Writes a single class encode method to [indent]. + void writeClassEncode(T generatorOptions, Root root, Indent indent, + Class klass, Set customClassNames, Set customEnumNames) {} + + /// Writes a single class decode method to [indent]. + void writeClassDecode(T generatorOptions, Root root, Indent indent, + Class klass, Set customClassNames, Set customEnumNames) {} + + /// Writes all apis to [indent]. + /// + /// Can be overridden to add extra code before/after classes. + void writeApis(T generatorOptions, Root root, Indent indent) { for (final Api api in root.apis) { if (api.location == ApiLocation.host) { - writeHostApi(generatorOptions, root, sink, indent, api); + writeHostApi(generatorOptions, root, indent, api); } else if (api.location == ApiLocation.flutter) { - writeFlutterApi(generatorOptions, root, sink, indent, api); + writeFlutterApi(generatorOptions, root, indent, api); } } } - /// Writes a single Flutter Api to file. - void writeFlutterApi( - T generatorOptions, Root root, StringSink sink, Indent indent, Api api); - - /// Writes a single Host Api to file. - void writeHostApi( - T generatorOptions, Root root, StringSink sink, Indent indent, Api api); + /// Writes a single Flutter Api to [indent]. + void writeFlutterApi(T generatorOptions, Root root, Indent indent, Api api); - /// Writes necessary code that closes file namespace if needed. - /// - /// This method is not required, and does not need to be overridden. - void writeCloseNamespace( - T generatorOptions, Root root, StringSink sink, Indent indent) {} + /// Writes a single Host Api to [indent]. + void writeHostApi(T generatorOptions, Root root, Indent indent, Api api); } diff --git a/packages/pigeon/lib/java_generator.dart b/packages/pigeon/lib/java_generator.dart index 830eefb1636..e6e7f8c921b 100644 --- a/packages/pigeon/lib/java_generator.dart +++ b/packages/pigeon/lib/java_generator.dart @@ -92,7 +92,7 @@ class JavaGenerator extends StructuredGenerator { @override void writeFilePrologue( - JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + JavaOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.copyrightHeader != null) { addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } @@ -103,7 +103,7 @@ class JavaGenerator extends StructuredGenerator { @override void writeFileImports( - JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + JavaOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.package != null) { indent.writeln('package ${generatorOptions.package};'); } @@ -127,7 +127,7 @@ class JavaGenerator extends StructuredGenerator { @override void writeOpenNamespace( - JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + JavaOptions generatorOptions, Root root, Indent indent) { indent.writeln( '$_docCommentPrefix Generated class from Pigeon.$_docCommentSuffix'); indent.writeln( @@ -140,8 +140,8 @@ class JavaGenerator extends StructuredGenerator { } @override - void writeEnum(JavaOptions generatorOptions, Root root, StringSink sink, - Indent indent, Enum anEnum) { + void writeEnum( + JavaOptions generatorOptions, Root root, Indent indent, Enum anEnum) { String camelToSnake(String camelCase) { final RegExp regex = RegExp('([a-z])([A-Z]+)'); return camelCase @@ -171,8 +171,8 @@ class JavaGenerator extends StructuredGenerator { } @override - void writeDataClass(JavaOptions generatorOptions, Root root, StringSink sink, - Indent indent, Class klass) { + void writeDataClass( + JavaOptions generatorOptions, Root root, Indent indent, Class klass) { final Set customClassNames = root.classes.map((Class x) => x.name).toSet(); final Set customEnumNames = @@ -189,7 +189,7 @@ class JavaGenerator extends StructuredGenerator { indent.write('public static class ${klass.name} '); indent.scoped('{', '}', () { for (final NamedType field in getFieldsInSerializationOrder(klass)) { - _writeClassField(generatorOptions, root, sink, indent, field); + _writeClassField(generatorOptions, root, indent, field); indent.addln(''); } @@ -201,16 +201,16 @@ class JavaGenerator extends StructuredGenerator { indent.writeln('private ${klass.name}() {}'); } - _writeClassBuilder(generatorOptions, root, sink, indent, klass); - writeClassEncode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - writeClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); + _writeClassBuilder(generatorOptions, root, indent, klass); + writeClassEncode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); + writeClassDecode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); }); } - void _writeClassField(JavaOptions generatorOptions, Root root, - StringSink sink, Indent indent, NamedType field) { + void _writeClassField( + JavaOptions generatorOptions, Root root, Indent indent, NamedType field) { final HostDatatype hostDatatype = getFieldHostDatatype(field, root.classes, root.enums, (TypeDeclaration x) => _javaTypeForBuiltinDartType(x)); final String nullability = field.type.isNullable ? '@Nullable' : '@NonNull'; @@ -237,7 +237,6 @@ class JavaGenerator extends StructuredGenerator { void _writeClassBuilder( JavaOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, ) { @@ -276,7 +275,6 @@ class JavaGenerator extends StructuredGenerator { void writeClassEncode( JavaOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -313,7 +311,6 @@ class JavaGenerator extends StructuredGenerator { void writeClassDecode( JavaOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -354,7 +351,6 @@ class JavaGenerator extends StructuredGenerator { void writeFlutterApi( JavaOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { @@ -453,15 +449,14 @@ class JavaGenerator extends StructuredGenerator { } @override - void writeApis( - JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + void writeApis(JavaOptions generatorOptions, Root root, Indent indent) { if (root.apis.any((Api api) => api.location == ApiLocation.host && api.methods.any((Method it) => it.isAsynchronous))) { indent.addln(''); _writeResultInterface(indent); } - super.writeApis(generatorOptions, root, sink, indent); + super.writeApis(generatorOptions, root, indent); } /// Write the java code that represents a host [Api], [api]. @@ -471,8 +466,8 @@ class JavaGenerator extends StructuredGenerator { /// static void setup(BinaryMessenger binaryMessenger, Foo api) {...} /// } @override - void writeHostApi(JavaOptions generatorOptions, Root root, StringSink sink, - Indent indent, Api api) { + void writeHostApi( + JavaOptions generatorOptions, Root root, Indent indent, Api api) { assert(api.location == ApiLocation.host); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(indent, api, root); @@ -486,8 +481,7 @@ class JavaGenerator extends StructuredGenerator { indent.write('public interface ${api.name} '); indent.scoped('{', '}', () { for (final Method method in api.methods) { - _writeInterfaceMethod( - generatorOptions, root, sink, indent, api, method); + _writeInterfaceMethod(generatorOptions, root, indent, api, method); } indent.addln(''); final String codecName = _getCodecName(api); @@ -508,7 +502,7 @@ class JavaGenerator extends StructuredGenerator { 'static void setup(BinaryMessenger binaryMessenger, ${api.name} api) '); indent.scoped('{', '}', () { for (final Method method in api.methods) { - _writeMethodSetup(generatorOptions, root, sink, indent, api, method); + _writeMethodSetup(generatorOptions, root, indent, api, method); } }); }); @@ -518,7 +512,7 @@ class JavaGenerator extends StructuredGenerator { /// Example: /// int add(int x, int y); void _writeInterfaceMethod(JavaOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, final Method method) { + Indent indent, Api api, final Method method) { final String returnType = method.isAsynchronous ? 'void' : _nullsafeJavaTypeForDartType(method.returnType); @@ -548,8 +542,8 @@ class JavaGenerator extends StructuredGenerator { /// Write a static setup function in the interface. /// Example: /// static void setup(BinaryMessenger binaryMessenger, Foo api) {...} - void _writeMethodSetup(JavaOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, final Method method) { + void _writeMethodSetup(JavaOptions generatorOptions, Root root, Indent indent, + Api api, final Method method) { final String channelName = makeChannelName(api, method); indent.write(''); indent.scoped('{', '}', () { @@ -738,13 +732,13 @@ Result<$returnType> $resultName = new Result<$returnType>() { @override void writeGeneralUtilities( - JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + JavaOptions generatorOptions, Root root, Indent indent) { _writeWrapError(indent); } @override void writeCloseNamespace( - JavaOptions generatorOptions, Root root, StringSink sink, Indent indent) { + JavaOptions generatorOptions, Root root, Indent indent) { indent.dec(); indent.addln('}'); } diff --git a/packages/pigeon/lib/kotlin_generator.dart b/packages/pigeon/lib/kotlin_generator.dart index 34564607ceb..76b270ba67e 100644 --- a/packages/pigeon/lib/kotlin_generator.dart +++ b/packages/pigeon/lib/kotlin_generator.dart @@ -71,8 +71,8 @@ class KotlinGenerator extends StructuredGenerator { const KotlinGenerator(); @override - void writeFilePrologue(KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent) { + void writeFilePrologue( + KotlinOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.copyrightHeader != null) { addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } @@ -81,8 +81,8 @@ class KotlinGenerator extends StructuredGenerator { } @override - void writeFileImports(KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent) { + void writeFileImports( + KotlinOptions generatorOptions, Root root, Indent indent) { indent.addln(''); if (generatorOptions.package != null) { indent.writeln('package ${generatorOptions.package}'); @@ -98,8 +98,8 @@ class KotlinGenerator extends StructuredGenerator { } @override - void writeEnum(KotlinOptions generatorOptions, Root root, StringSink sink, - Indent indent, Enum anEnum) { + void writeEnum( + KotlinOptions generatorOptions, Root root, Indent indent, Enum anEnum) { indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -128,8 +128,8 @@ class KotlinGenerator extends StructuredGenerator { } @override - void writeDataClass(KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass) { + void writeDataClass( + KotlinOptions generatorOptions, Root root, Indent indent, Class klass) { final Set customClassNames = root.classes.map((Class x) => x.name).toSet(); final Set customEnumNames = @@ -156,10 +156,10 @@ class KotlinGenerator extends StructuredGenerator { }); indent.scoped(') {', '}', () { - writeClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - writeClassEncode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); + writeClassDecode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); + writeClassEncode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); }); } @@ -167,7 +167,6 @@ class KotlinGenerator extends StructuredGenerator { void writeClassEncode( KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -200,7 +199,6 @@ class KotlinGenerator extends StructuredGenerator { void writeClassDecode( KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -288,7 +286,6 @@ class KotlinGenerator extends StructuredGenerator { void writeApis( KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent, ) { if (root.apis.any((Api api) => @@ -296,7 +293,7 @@ class KotlinGenerator extends StructuredGenerator { api.methods.any((Method it) => it.isAsynchronous))) { indent.addln(''); } - super.writeApis(generatorOptions, root, sink, indent); + super.writeApis(generatorOptions, root, indent); } /// Writes the code for a flutter [Api], [api]. @@ -308,7 +305,6 @@ class KotlinGenerator extends StructuredGenerator { void writeFlutterApi( KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { @@ -404,7 +400,6 @@ class KotlinGenerator extends StructuredGenerator { void writeHostApi( KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { @@ -624,8 +619,8 @@ class KotlinGenerator extends StructuredGenerator { } @override - void writeGeneralUtilities(KotlinOptions generatorOptions, Root root, - StringSink sink, Indent indent) { + void writeGeneralUtilities( + KotlinOptions generatorOptions, Root root, Indent indent) { _writeWrapResult(indent); _writeWrapError(indent); } diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart index 4197f23741d..2b165c91d1d 100644 --- a/packages/pigeon/lib/objc_generator.dart +++ b/packages/pigeon/lib/objc_generator.dart @@ -90,7 +90,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { @override void writeFilePrologue( - ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + ObjcOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.copyrightHeader != null) { addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } @@ -101,7 +101,7 @@ class ObjcHeaderGenerator extends StructuredGenerator { @override void writeFileImports( - ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + ObjcOptions generatorOptions, Root root, Indent indent) { indent.writeln('#import '); indent.addln(''); @@ -114,8 +114,8 @@ class ObjcHeaderGenerator extends StructuredGenerator { } @override - void writeEnum(ObjcOptions generatorOptions, Root root, StringSink sink, - Indent indent, Enum anEnum) { + void writeEnum( + ObjcOptions generatorOptions, Root root, Indent indent, Enum anEnum) { final String enumName = _className(generatorOptions.prefix, anEnum.name); indent.writeln(''); addDocumentationComments( @@ -135,19 +135,19 @@ class ObjcHeaderGenerator extends StructuredGenerator { @override void writeDataClasses( - ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + ObjcOptions generatorOptions, Root root, Indent indent) { indent.writeln(''); for (final Class klass in root.classes) { indent.writeln( '@class ${_className(generatorOptions.prefix, klass.name)};'); } indent.writeln(''); - super.writeDataClasses(generatorOptions, root, sink, indent); + super.writeDataClasses(generatorOptions, root, indent); } @override - void writeDataClass(ObjcOptions generatorOptions, Root root, StringSink sink, - Indent indent, Class klass) { + void writeDataClass( + ObjcOptions generatorOptions, Root root, Indent indent, Class klass) { final List classes = root.classes; final List enums = root.enums; final String? prefix = generatorOptions.prefix; @@ -199,7 +199,6 @@ class ObjcHeaderGenerator extends StructuredGenerator { void writeClassEncode( ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -210,7 +209,6 @@ class ObjcHeaderGenerator extends StructuredGenerator { void writeClassDecode( ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -218,9 +216,8 @@ class ObjcHeaderGenerator extends StructuredGenerator { ) {} @override - void writeApis( - ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { - super.writeApis(generatorOptions, root, sink, indent); + void writeApis(ObjcOptions generatorOptions, Root root, Indent indent) { + super.writeApis(generatorOptions, root, indent); indent.writeln('NS_ASSUME_NONNULL_END'); } @@ -228,7 +225,6 @@ class ObjcHeaderGenerator extends StructuredGenerator { void writeFlutterApi( ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { @@ -268,7 +264,6 @@ class ObjcHeaderGenerator extends StructuredGenerator { void writeHostApi( ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { @@ -341,7 +336,7 @@ class ObjcSourceGenerator extends StructuredGenerator { @override void writeFilePrologue( - ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + ObjcOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.copyrightHeader != null) { addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } @@ -352,7 +347,7 @@ class ObjcSourceGenerator extends StructuredGenerator { @override void writeFileImports( - ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + ObjcOptions generatorOptions, Root root, Indent indent) { indent.writeln('#import "${generatorOptions.headerIncludePath}"'); indent.writeln('#import '); indent.addln(''); @@ -365,7 +360,7 @@ class ObjcSourceGenerator extends StructuredGenerator { @override void writeDataClasses( - ObjcOptions generatorOptions, Root root, StringSink sink, Indent indent) { + ObjcOptions generatorOptions, Root root, Indent indent) { _writeObjcSourceHelperFunctions(indent); indent.addln(''); @@ -373,12 +368,12 @@ class ObjcSourceGenerator extends StructuredGenerator { _writeObjcSourceDataClassExtension(generatorOptions, indent, klass); } indent.writeln(''); - super.writeDataClasses(generatorOptions, root, sink, indent); + super.writeDataClasses(generatorOptions, root, indent); } @override - void writeDataClass(ObjcOptions generatorOptions, Root root, StringSink sink, - Indent indent, Class klass) { + void writeDataClass( + ObjcOptions generatorOptions, Root root, Indent indent, Class klass) { final Set customClassNames = root.classes.map((Class x) => x.name).toSet(); final Set customEnumNames = @@ -386,12 +381,12 @@ class ObjcSourceGenerator extends StructuredGenerator { final String className = _className(generatorOptions.prefix, klass.name); indent.writeln('@implementation $className'); - _writeObjcSourceClassInitializer(generatorOptions, root, sink, indent, - klass, customClassNames, customEnumNames, className); - writeClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - writeClassEncode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); + _writeObjcSourceClassInitializer(generatorOptions, root, indent, klass, + customClassNames, customEnumNames, className); + writeClassDecode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); + writeClassEncode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); indent.writeln('@end'); indent.writeln(''); } @@ -400,7 +395,6 @@ class ObjcSourceGenerator extends StructuredGenerator { void writeClassEncode( ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -422,7 +416,6 @@ class ObjcSourceGenerator extends StructuredGenerator { void writeClassDecode( ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -453,8 +446,8 @@ class ObjcSourceGenerator extends StructuredGenerator { '+ (nullable $className *)nullableFromList:(NSArray *)list { return (list) ? [$className fromList:list] : nil; }'); } - void _writeCodecAndGetter(ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api) { + void _writeCodecAndGetter( + ObjcOptions generatorOptions, Root root, Indent indent, Api api) { final String codecName = _getCodecName(generatorOptions.prefix, api.name); if (getCodecClasses(api, root).isNotEmpty) { _writeCodec(indent, codecName, generatorOptions, api, root); @@ -468,14 +461,13 @@ class ObjcSourceGenerator extends StructuredGenerator { void writeFlutterApi( ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { assert(api.location == ApiLocation.flutter); final String apiName = _className(generatorOptions.prefix, api.name); - _writeCodecAndGetter(generatorOptions, root, sink, indent, api); + _writeCodecAndGetter(generatorOptions, root, indent, api); _writeExtension(indent, apiName); indent.addln(''); @@ -493,14 +485,13 @@ class ObjcSourceGenerator extends StructuredGenerator { void writeHostApi( ObjcOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { assert(api.location == ApiLocation.host); final String apiName = _className(generatorOptions.prefix, api.name); - _writeCodecAndGetter(generatorOptions, root, sink, indent, api); + _writeCodecAndGetter(generatorOptions, root, indent, api); const String channelName = 'channel'; indent.write( @@ -686,7 +677,6 @@ static id GetNullableObjectAtIndex(NSArray* array, NSInteger key) { void _writeObjcSourceClassInitializer( ObjcOptions languageOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -1024,8 +1014,7 @@ String _makeObjcSignature({ /// Generates the ".h" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateObjcHeader( - ObjcOptions options, Root root, StringSink sink, Indent indent) {} +void generateObjcHeader(ObjcOptions options, Root root, Indent indent) {} String _listGetter(Set customClassNames, String list, NamedType field, int index, String? prefix) { diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 1347a3cc770..879d51b5f23 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -54,8 +54,8 @@ class SwiftGenerator extends StructuredGenerator { const SwiftGenerator(); @override - void writeFilePrologue(SwiftOptions generatorOptions, Root root, - StringSink sink, Indent indent) { + void writeFilePrologue( + SwiftOptions generatorOptions, Root root, Indent indent) { if (generatorOptions.copyrightHeader != null) { addLines(indent, generatorOptions.copyrightHeader!, linePrefix: '// '); } @@ -65,8 +65,8 @@ class SwiftGenerator extends StructuredGenerator { } @override - void writeFileImports(SwiftOptions generatorOptions, Root root, - StringSink sink, Indent indent) { + void writeFileImports( + SwiftOptions generatorOptions, Root root, Indent indent) { indent.writeln('import Foundation'); indent.format(''' #if os(iOS) @@ -81,8 +81,8 @@ import FlutterMacOS } @override - void writeEnum(SwiftOptions generatorOptions, Root root, StringSink sink, - Indent indent, Enum anEnum) { + void writeEnum( + SwiftOptions generatorOptions, Root root, Indent indent, Enum anEnum) { indent.writeln(''); addDocumentationComments( indent, anEnum.documentationComments, _docCommentSpec); @@ -98,8 +98,8 @@ import FlutterMacOS } @override - void writeDataClass(SwiftOptions generatorOptions, Root root, StringSink sink, - Indent indent, Class klass) { + void writeDataClass( + SwiftOptions generatorOptions, Root root, Indent indent, Class klass) { final Set customClassNames = root.classes.map((Class x) => x.name).toSet(); final Set customEnumNames = @@ -120,10 +120,10 @@ import FlutterMacOS }); indent.writeln(''); - writeClassDecode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); - writeClassEncode(generatorOptions, root, sink, indent, klass, - customClassNames, customEnumNames); + writeClassDecode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); + writeClassEncode(generatorOptions, root, indent, klass, customClassNames, + customEnumNames); }); } @@ -131,7 +131,6 @@ import FlutterMacOS void writeClassEncode( SwiftOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -166,7 +165,6 @@ import FlutterMacOS void writeClassDecode( SwiftOptions generatorOptions, Root root, - StringSink sink, Indent indent, Class klass, Set customClassNames, @@ -244,7 +242,6 @@ import FlutterMacOS void writeApis( SwiftOptions generatorOptions, Root root, - StringSink sink, Indent indent, ) { if (root.apis.any((Api api) => @@ -252,7 +249,7 @@ import FlutterMacOS api.methods.any((Method it) => it.isAsynchronous))) { indent.addln(''); } - super.writeApis(generatorOptions, root, sink, indent); + super.writeApis(generatorOptions, root, indent); } /// Writes the code for a flutter [Api], [api]. @@ -266,7 +263,6 @@ import FlutterMacOS void writeFlutterApi( SwiftOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { @@ -362,7 +358,6 @@ import FlutterMacOS void writeHostApi( SwiftOptions generatorOptions, Root root, - StringSink sink, Indent indent, Api api, ) { @@ -598,8 +593,8 @@ import FlutterMacOS } @override - void writeGeneralUtilities(SwiftOptions generatorOptions, Root root, - StringSink sink, Indent indent) { + void writeGeneralUtilities( + SwiftOptions generatorOptions, Root root, Indent indent) { _writeWrapResult(indent); _writeWrapError(indent); } @@ -702,5 +697,4 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { /// Generates the ".swift" file for the AST represented by [root] to [sink] with the /// provided [options]. -void generateSwift( - SwiftOptions options, Root root, StringSink sink, Indent indent) {} +void generateSwift(SwiftOptions options, Root root, Indent indent) {} diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index d57104b14aa..8dbd2dcb495 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -22,8 +22,6 @@ class CoreTestsTest; // Generated class from Pigeon. -enum class AnEnum { one = 0, two = 1, three = 2 }; - class FlutterError { public: explicit FlutterError(const std::string& code) : code_(code) {} @@ -65,6 +63,8 @@ class ErrorOr { std::variant v_; }; +enum class AnEnum { one = 0, two = 1, three = 2 }; + // Generated class from Pigeon that represents data sent in messages. class AllTypes { public: From e45c622a3f49a5d8d4dccd85811b20da2f3723d5 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 13 Jan 2023 08:26:53 -0800 Subject: [PATCH 85/87] remove unneeded namespace from guardname --- packages/pigeon/lib/cpp_generator.dart | 11 +++-------- .../test_plugin/windows/pigeon/core_tests.gen.h | 6 +++--- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index b7cc211ed5f..c00f8ef78c8 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -109,8 +109,7 @@ class CppHeaderGenerator extends StructuredGenerator { @override void writeFileImports(CppOptions generatorOptions, Root root, Indent indent) { - final String guardName = _getGuardName( - generatorOptions.headerIncludePath, generatorOptions.namespace); + final String guardName = _getGuardName(generatorOptions.headerIncludePath); indent.writeln('#ifndef $guardName'); indent.writeln('#define $guardName'); @@ -252,8 +251,7 @@ class CppHeaderGenerator extends StructuredGenerator { if (generatorOptions.namespace != null) { indent.writeln('} // namespace ${generatorOptions.namespace}'); } - final String guardName = _getGuardName( - generatorOptions.headerIncludePath, generatorOptions.namespace); + final String guardName = _getGuardName(generatorOptions.headerIncludePath); indent.writeln('#endif // $guardName'); } @@ -1275,14 +1273,11 @@ String _nullSafeCppTypeForDartType(TypeDeclaration type, } } -String _getGuardName(String? headerFileName, String? namespace) { +String _getGuardName(String? headerFileName) { String guardName = 'PIGEON_'; if (headerFileName != null) { guardName += '${headerFileName.replaceAll('.', '_').toUpperCase()}_'; } - if (namespace != null) { - guardName += '${namespace.toUpperCase()}_'; - } return '${guardName}H_'; } diff --git a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h index 8dbd2dcb495..c752a5a1f3d 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/pigeon/core_tests.gen.h @@ -5,8 +5,8 @@ // Autogenerated from Pigeon (v6.0.0), do not edit directly. // See also: https://pub.dev/packages/pigeon -#ifndef PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ -#define PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ +#ifndef PIGEON_CORE_TESTS_GEN_H_H_ +#define PIGEON_CORE_TESTS_GEN_H_H_ #include #include #include @@ -413,4 +413,4 @@ class HostTrivialApi { HostTrivialApi() = default; }; } // namespace core_tests_pigeontest -#endif // PIGEON_CORE_TESTS_GEN_H_CORE_TESTS_PIGEONTEST_H_ +#endif // PIGEON_CORE_TESTS_GEN_H_H_ From 7dc64d31c3956d2526e6ca61bfce63474774f112 Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 13 Jan 2023 08:30:56 -0800 Subject: [PATCH 86/87] [indent] --- packages/pigeon/lib/generator.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigeon/lib/generator.dart b/packages/pigeon/lib/generator.dart index b7c0bf2de3c..c730f92a714 100644 --- a/packages/pigeon/lib/generator.dart +++ b/packages/pigeon/lib/generator.dart @@ -1,6 +1,6 @@ // Copyright 2013 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 [indent]. +// found in the LICENSE file. import 'ast.dart'; import 'generator_tools.dart'; From 263e832e69c7788c697115f064bdd337e4017d1c Mon Sep 17 00:00:00 2001 From: tarrinneal Date: Fri, 13 Jan 2023 10:25:51 -0800 Subject: [PATCH 87/87] clean up --- packages/pigeon/lib/cpp_generator.dart | 20 ++++++++++---------- packages/pigeon/lib/dart_generator.dart | 4 ---- packages/pigeon/lib/swift_generator.dart | 4 ---- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index c00f8ef78c8..105f6bd0f0e 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -245,16 +245,6 @@ class CppHeaderGenerator extends StructuredGenerator { indent.writeln(''); } - @override - void writeApis(CppOptions generatorOptions, Root root, Indent indent) { - super.writeApis(generatorOptions, root, indent); - if (generatorOptions.namespace != null) { - indent.writeln('} // namespace ${generatorOptions.namespace}'); - } - final String guardName = _getGuardName(generatorOptions.headerIncludePath); - indent.writeln('#endif // $guardName'); - } - @override void writeFlutterApi( CppOptions generatorOptions, @@ -465,6 +455,16 @@ $friendLines }; '''); } + + @override + void writeCloseNamespace( + CppOptions generatorOptions, Root root, Indent indent) { + if (generatorOptions.namespace != null) { + indent.writeln('} // namespace ${generatorOptions.namespace}'); + } + final String guardName = _getGuardName(generatorOptions.headerIncludePath); + indent.writeln('#endif // $guardName'); + } } /// Writes C++ source (.cpp) file to sink. diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart index 0961f006ce4..3b62affc3b1 100644 --- a/packages/pigeon/lib/dart_generator.dart +++ b/packages/pigeon/lib/dart_generator.dart @@ -756,10 +756,6 @@ String _addGenericTypesNullable(TypeDeclaration type) { return type.isNullable ? '$genericdType?' : genericdType; } -/// Generates Dart source code for the given AST represented by [root], -/// outputting the code to [sink]. -void generateDart(DartOptions opt, Root root, Indent indent) {} - /// Crawls up the path of [dartFilePath] until it finds a pubspec.yaml in a /// parent directory and returns its path. String? _findPubspecPath(String dartFilePath) { diff --git a/packages/pigeon/lib/swift_generator.dart b/packages/pigeon/lib/swift_generator.dart index 879d51b5f23..46e14005ca4 100644 --- a/packages/pigeon/lib/swift_generator.dart +++ b/packages/pigeon/lib/swift_generator.dart @@ -694,7 +694,3 @@ String _nullsafeSwiftTypeForDartType(TypeDeclaration type) { final String nullSafe = type.isNullable ? '?' : ''; return '${_swiftTypeForDartType(type)}$nullSafe'; } - -/// Generates the ".swift" file for the AST represented by [root] to [sink] with the -/// provided [options]. -void generateSwift(SwiftOptions options, Root root, Indent indent) {}