From a82b1c3b3151ea97c3e840debb84c6c20dbf59df Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Wed, 4 Feb 2026 15:09:09 +0800 Subject: [PATCH 01/16] Add logic to add generated annotation in kotlin --- .../lib/src/kotlin/kotlin_generator.dart | 18 ++++++++ .../pigeon/test/kotlin_generator_test.dart | 42 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart index 7df50a975990..2ce10fe9f9b5 100644 --- a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart +++ b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart @@ -44,6 +44,7 @@ class KotlinOptions { this.errorClassName, this.includeErrorClass = true, this.fileSpecificClassNameComponent, + this.useGeneratedAnnotation = false, }); /// The package where the generated class will live. @@ -64,6 +65,11 @@ class KotlinOptions { /// A String to augment class names to avoid cross file collisions. final String? fileSpecificClassNameComponent; + /// Determines if the `javax.annotation.Generated` is used in the output. This + /// is false by default since that dependency isn't available in plugins by + /// default . + final bool useGeneratedAnnotation; + /// Creates a [KotlinOptions] from a Map representation where: /// `x = KotlinOptions.fromMap(x.toMap())`. static KotlinOptions fromMap(Map map) { @@ -74,6 +80,7 @@ class KotlinOptions { includeErrorClass: map['includeErrorClass'] as bool? ?? true, fileSpecificClassNameComponent: map['fileSpecificClassNameComponent'] as String?, + useGeneratedAnnotation: map['useGeneratedAnnotation'] as bool? ?? false, ); } @@ -87,6 +94,7 @@ class KotlinOptions { 'includeErrorClass': includeErrorClass, if (fileSpecificClassNameComponent != null) 'fileSpecificClassNameComponent': fileSpecificClassNameComponent!, + 'useGeneratedAnnotation': useGeneratedAnnotation!, }; return result; } @@ -108,6 +116,7 @@ class InternalKotlinOptions extends InternalOptions { this.errorClassName, this.includeErrorClass = true, this.fileSpecificClassNameComponent, + this.useGeneratedAnnotation = false, }); /// Creates InternalKotlinOptions from KotlinOptions. @@ -119,6 +128,7 @@ class InternalKotlinOptions extends InternalOptions { copyrightHeader = options.copyrightHeader ?? copyrightHeader, errorClassName = options.errorClassName, includeErrorClass = options.includeErrorClass, + useGeneratedAnnotation = options.useGeneratedAnnotation, fileSpecificClassNameComponent = options.fileSpecificClassNameComponent ?? kotlinOut.split('/').lastOrNull?.split('.').first; @@ -143,6 +153,11 @@ class InternalKotlinOptions extends InternalOptions { /// A String to augment class names to avoid cross file collisions. final String? fileSpecificClassNameComponent; + + /// Determines if the `javax.annotation.Generated` is used in the output. This + /// is false by default since that dependency isn't available in plugins by + /// default . + final bool useGeneratedAnnotation; } /// Options that control how Kotlin code will be generated for a specific @@ -192,6 +207,9 @@ class KotlinGenerator extends StructuredGenerator { indent.writeln('// ${getGeneratedCodeWarning()}'); indent.writeln('// $seeAlsoWarning'); indent.writeln('@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")'); + if (generatorOptions.useGeneratedAnnotation) { + indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); + } } @override diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 10e5193dae96..6adf8645bd09 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -982,6 +982,48 @@ void main() { expect(code, startsWith('// hello world')); }); + test('generated annotation', () { + final root = Root(apis: [], classes: [], enums: []); + final sink = StringBuffer(); + final kotlinOptions = InternalKotlinOptions( + copyrightHeader: makeIterable('hello world'), + kotlinOut: '' + useGeneratedAnnotation: true, + ); + const generator = KotlinGenerator(); + generator.generate( + kotlinOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final code = sink.toString(); + expect(code, contains('@javax.annotation.Generated("dev.flutter.pigeon")')); + }); + + test('no generated annotation', () { + final root = Root(apis: [], classes: [], enums: []); + final sink = StringBuffer(); + final kotlinOptions = InternalKotlinOptions( + copyrightHeader: makeIterable('hello world'), + kotlinOut: '' + useGeneratedAnnotation: true, + ); + const generator = KotlinGenerator(); + generator.generate( + kotlinOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final code = sink.toString(); + expect(code, contains('@javax.annotation.Generated("dev.flutter.pigeon")')); + expect( + code, + isNot(contains('@javax.annotation.Generated("dev.flutter.pigeon")')), + ); + }); + test('generics - list', () { final classDefinition = Class( name: 'Foobar', From df74e390e089fbacd9a2bfe07e2ceb1a61a9df9e Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Wed, 4 Feb 2026 15:15:59 +0800 Subject: [PATCH 02/16] Add flags for parsing use_generated_annotation --- packages/pigeon/lib/src/pigeon_lib.dart | 3 +++ packages/pigeon/test/pigeon_lib_test.dart | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/packages/pigeon/lib/src/pigeon_lib.dart b/packages/pigeon/lib/src/pigeon_lib.dart index 75216141dc59..7cfe6d5a3506 100644 --- a/packages/pigeon/lib/src/pigeon_lib.dart +++ b/packages/pigeon/lib/src/pigeon_lib.dart @@ -547,6 +547,8 @@ ${_argParser.usage}'''; help: 'The package that generated Kotlin code will be in.', aliases: const ['experimental_kotlin_package'], ) + ..addFlag('kotlin_use_generated_annotation', + help: 'Adds the kotlin.annotation.Generated annotation to the output.') ..addOption( 'cpp_header_out', help: 'Path to generated C++ header file (.h).', @@ -638,6 +640,7 @@ ${_argParser.usage}'''; kotlinOut: results['kotlin_out'] as String?, kotlinOptions: KotlinOptions( package: results['kotlin_package'] as String?, + useGeneratedAnnotation: results['java_use_generated_annotation'] as bool? ?? false, ), cppHeaderOut: results['cpp_header_out'] as String?, cppSourceOut: results['cpp_source_out'] as String?, diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 2627787c4f03..4748c9caf60b 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -136,6 +136,14 @@ void main() { ]); expect(opts.kotlinOptions?.package, equals('com.google.foo')); }); + + test('parse args - kotlin_use_generated_annotation', () { + final PigeonOptions opts = Pigeon.parseArgs([ + '--kotlin_use_generated_annotation', + ]); + expect(opts.kotlinOptions!.useGeneratedAnnotation, isTrue); + }); + test('parse args - cpp_header_out', () { final PigeonOptions opts = Pigeon.parseArgs([ From a262475fe9e27162cd115f2fb3ab2473f8293226 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Wed, 4 Feb 2026 15:26:26 +0800 Subject: [PATCH 03/16] Fix wrong parsing logic --- packages/pigeon/CHANGELOG.md | 4 ++++ packages/pigeon/lib/src/generator_tools.dart | 2 +- packages/pigeon/lib/src/pigeon_lib.dart | 4 ++-- packages/pigeon/pubspec.yaml | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 721ab01fc459..a6abdc031301 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,7 @@ +## 26.1.8 + +* [kotlin] Adds option to add javax.annotation.Generated annotation. + ## 26.1.7 * [objc] Updates to use module imports. diff --git a/packages/pigeon/lib/src/generator_tools.dart b/packages/pigeon/lib/src/generator_tools.dart index e00fdf2063dd..37a3eb94e161 100644 --- a/packages/pigeon/lib/src/generator_tools.dart +++ b/packages/pigeon/lib/src/generator_tools.dart @@ -15,7 +15,7 @@ import 'generator.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '26.1.7'; +const String pigeonVersion = '26.1.8'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/lib/src/pigeon_lib.dart b/packages/pigeon/lib/src/pigeon_lib.dart index 7cfe6d5a3506..7495903b96a3 100644 --- a/packages/pigeon/lib/src/pigeon_lib.dart +++ b/packages/pigeon/lib/src/pigeon_lib.dart @@ -548,7 +548,7 @@ ${_argParser.usage}'''; aliases: const ['experimental_kotlin_package'], ) ..addFlag('kotlin_use_generated_annotation', - help: 'Adds the kotlin.annotation.Generated annotation to the output.') + help: 'Adds javax.annotation.Generated annotation to the output.') ..addOption( 'cpp_header_out', help: 'Path to generated C++ header file (.h).', @@ -640,7 +640,7 @@ ${_argParser.usage}'''; kotlinOut: results['kotlin_out'] as String?, kotlinOptions: KotlinOptions( package: results['kotlin_package'] as String?, - useGeneratedAnnotation: results['java_use_generated_annotation'] as bool? ?? false, + useGeneratedAnnotation: results['kotlin_use_generated_annotation'] as bool? ?? false, ), cppHeaderOut: results['cpp_header_out'] as String?, cppSourceOut: results['cpp_source_out'] as String?, diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index d01fb9466690..a2b22e26f34c 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%3A%22p%3A+pigeon%22 -version: 26.1.7 # This must match the version in lib/src/generator_tools.dart +version: 26.1.8 # This must match the version in lib/src/generator_tools.dart environment: sdk: ^3.9.0 From 4267595ca0327d7531eba6a55057bee4d325b729 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Wed, 4 Feb 2026 15:29:49 +0800 Subject: [PATCH 04/16] Fix test and remove unneeded code --- packages/pigeon/lib/src/kotlin/kotlin_generator.dart | 2 +- packages/pigeon/test/kotlin_generator_test.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart index 2ce10fe9f9b5..8f4e938fbc7e 100644 --- a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart +++ b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart @@ -94,7 +94,7 @@ class KotlinOptions { 'includeErrorClass': includeErrorClass, if (fileSpecificClassNameComponent != null) 'fileSpecificClassNameComponent': fileSpecificClassNameComponent!, - 'useGeneratedAnnotation': useGeneratedAnnotation!, + 'useGeneratedAnnotation': useGeneratedAnnotation, }; return result; } diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 6adf8645bd09..784387431ea7 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -987,7 +987,7 @@ void main() { final sink = StringBuffer(); final kotlinOptions = InternalKotlinOptions( copyrightHeader: makeIterable('hello world'), - kotlinOut: '' + kotlinOut: '', useGeneratedAnnotation: true, ); const generator = KotlinGenerator(); @@ -1006,7 +1006,7 @@ void main() { final sink = StringBuffer(); final kotlinOptions = InternalKotlinOptions( copyrightHeader: makeIterable('hello world'), - kotlinOut: '' + kotlinOut: '', useGeneratedAnnotation: true, ); const generator = KotlinGenerator(); From b9bd95fe5eec8129e835ea5aee295c571afde1e1 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Wed, 4 Feb 2026 15:41:16 +0800 Subject: [PATCH 05/16] Fix kotlin generator test --- packages/pigeon/test/kotlin_generator_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 784387431ea7..42a915d5a0d7 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -1007,7 +1007,6 @@ void main() { final kotlinOptions = InternalKotlinOptions( copyrightHeader: makeIterable('hello world'), kotlinOut: '', - useGeneratedAnnotation: true, ); const generator = KotlinGenerator(); generator.generate( From f154decb5b3328308f18d52394ebeb46c96787e6 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Wed, 4 Feb 2026 15:49:04 +0800 Subject: [PATCH 06/16] Fix test --- packages/pigeon/test/kotlin_generator_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 42a915d5a0d7..8a8808651e79 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -1016,7 +1016,6 @@ void main() { dartPackageName: DEFAULT_PACKAGE_NAME, ); final code = sink.toString(); - expect(code, contains('@javax.annotation.Generated("dev.flutter.pigeon")')); expect( code, isNot(contains('@javax.annotation.Generated("dev.flutter.pigeon")')), From 1afaa7bd39ca34a25550f92bd089db59e02ad9b3 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Fri, 6 Feb 2026 17:37:55 +0800 Subject: [PATCH 07/16] Format dart files --- packages/pigeon/lib/src/pigeon_lib.dart | 9 ++++++--- packages/pigeon/test/pigeon_lib_test.dart | 3 +-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/pigeon/lib/src/pigeon_lib.dart b/packages/pigeon/lib/src/pigeon_lib.dart index 7495903b96a3..e638629f33ad 100644 --- a/packages/pigeon/lib/src/pigeon_lib.dart +++ b/packages/pigeon/lib/src/pigeon_lib.dart @@ -547,8 +547,10 @@ ${_argParser.usage}'''; help: 'The package that generated Kotlin code will be in.', aliases: const ['experimental_kotlin_package'], ) - ..addFlag('kotlin_use_generated_annotation', - help: 'Adds javax.annotation.Generated annotation to the output.') + ..addFlag( + 'kotlin_use_generated_annotation', + help: 'Adds javax.annotation.Generated annotation to the output.', + ) ..addOption( 'cpp_header_out', help: 'Path to generated C++ header file (.h).', @@ -640,7 +642,8 @@ ${_argParser.usage}'''; kotlinOut: results['kotlin_out'] as String?, kotlinOptions: KotlinOptions( package: results['kotlin_package'] as String?, - useGeneratedAnnotation: results['kotlin_use_generated_annotation'] as bool? ?? false, + useGeneratedAnnotation: + results['kotlin_use_generated_annotation'] as bool? ?? false, ), cppHeaderOut: results['cpp_header_out'] as String?, cppSourceOut: results['cpp_source_out'] as String?, diff --git a/packages/pigeon/test/pigeon_lib_test.dart b/packages/pigeon/test/pigeon_lib_test.dart index 4748c9caf60b..86b0498554a2 100644 --- a/packages/pigeon/test/pigeon_lib_test.dart +++ b/packages/pigeon/test/pigeon_lib_test.dart @@ -136,7 +136,7 @@ void main() { ]); expect(opts.kotlinOptions?.package, equals('com.google.foo')); }); - + test('parse args - kotlin_use_generated_annotation', () { final PigeonOptions opts = Pigeon.parseArgs([ '--kotlin_use_generated_annotation', @@ -144,7 +144,6 @@ void main() { expect(opts.kotlinOptions!.useGeneratedAnnotation, isTrue); }); - test('parse args - cpp_header_out', () { final PigeonOptions opts = Pigeon.parseArgs([ '--cpp_header_out', From 79ccc951fceb299f3cdf4716d4bb24783a0277b3 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Fri, 6 Feb 2026 17:49:00 +0800 Subject: [PATCH 08/16] Address gemini-code-assist comments --- packages/pigeon/lib/src/generator_tools.dart | 4 + .../pigeon/lib/src/java/java_generator.dart | 2 +- .../lib/src/kotlin/kotlin_generator.dart | 2 +- packages/pigeon/test/java_generator_test.dart | 91 ++++++++++--------- .../pigeon/test/kotlin_generator_test.dart | 78 ++++++++-------- 5 files changed, 94 insertions(+), 83 deletions(-) diff --git a/packages/pigeon/lib/src/generator_tools.dart b/packages/pigeon/lib/src/generator_tools.dart index 37a3eb94e161..b5484d5c9b21 100644 --- a/packages/pigeon/lib/src/generator_tools.dart +++ b/packages/pigeon/lib/src/generator_tools.dart @@ -17,6 +17,10 @@ import 'generator.dart'; /// This must match the version in pubspec.yaml. const String pigeonVersion = '26.1.8'; +/// Annotation for generated code. +const String generatedAnnotation = + '@javax.annotation.Generated("dev.flutter.pigeon")'; + /// Read all the content from [stdin] to a String. String readStdin() { final bytes = []; diff --git a/packages/pigeon/lib/src/java/java_generator.dart b/packages/pigeon/lib/src/java/java_generator.dart index 2f08bc3a0c61..bf54254ec46f 100644 --- a/packages/pigeon/lib/src/java/java_generator.dart +++ b/packages/pigeon/lib/src/java/java_generator.dart @@ -202,7 +202,7 @@ class JavaGenerator extends StructuredGenerator { '@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"})', ); if (generatorOptions.useGeneratedAnnotation ?? false) { - indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); + indent.writeln(generatedAnnotation); } indent.writeln('public class ${generatorOptions.className!} {'); indent.inc(); diff --git a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart index 8f4e938fbc7e..6a4ab994ffbc 100644 --- a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart +++ b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart @@ -208,7 +208,7 @@ class KotlinGenerator extends StructuredGenerator { indent.writeln('// $seeAlsoWarning'); indent.writeln('@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")'); if (generatorOptions.useGeneratedAnnotation) { - indent.writeln('@javax.annotation.Generated("dev.flutter.pigeon")'); + indent.writeln(generatedAnnotation); } } diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index a7dd1bbfbcbc..06b2d3d237d3 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -4,6 +4,7 @@ import 'package:pigeon/pigeon.dart'; import 'package:pigeon/src/ast.dart'; +import 'package:pigeon/src/generator_tools.dart'; import 'package:pigeon/src/java/java_generator.dart'; import 'package:test/test.dart'; @@ -1611,51 +1612,53 @@ void main() { ); }); - test('generated annotation', () { - final classDefinition = Class(name: 'Foobar', fields: []); - final root = Root( - apis: [], - classes: [classDefinition], - enums: [], - ); - final sink = StringBuffer(); - const javaOptions = InternalJavaOptions( - className: 'Messages', - useGeneratedAnnotation: true, - javaOut: '', - ); - const generator = JavaGenerator(); - generator.generate( - javaOptions, - root, - sink, - dartPackageName: DEFAULT_PACKAGE_NAME, - ); - final code = sink.toString(); - expect(code, contains('@javax.annotation.Generated("dev.flutter.pigeon")')); - }); + group('generated annotation', () { + test('with generated annotation', () { + final classDefinition = Class(name: 'Foobar', fields: []); + final root = Root( + apis: [], + classes: [classDefinition], + enums: [], + ); + final sink = StringBuffer(); + const javaOptions = InternalJavaOptions( + className: 'Messages', + useGeneratedAnnotation: true, + javaOut: '', + ); + const generator = JavaGenerator(); + generator.generate( + javaOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final code = sink.toString(); + expect(code, contains(generatedAnnotation)); + }); - test('no generated annotation', () { - final classDefinition = Class(name: 'Foobar', fields: []); - final root = Root( - apis: [], - classes: [classDefinition], - enums: [], - ); - final sink = StringBuffer(); - const javaOptions = InternalJavaOptions(className: 'Messages', javaOut: ''); - const generator = JavaGenerator(); - generator.generate( - javaOptions, - root, - sink, - dartPackageName: DEFAULT_PACKAGE_NAME, - ); - final code = sink.toString(); - expect( - code, - isNot(contains('@javax.annotation.Generated("dev.flutter.pigeon")')), - ); + test('without generated annotation', () { + final classDefinition = Class(name: 'Foobar', fields: []); + final root = Root( + apis: [], + classes: [classDefinition], + enums: [], + ); + final sink = StringBuffer(); + const javaOptions = InternalJavaOptions( + className: 'Messages', + javaOut: '', + ); + const generator = JavaGenerator(); + generator.generate( + javaOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final code = sink.toString(); + expect(code, isNot(contains(generatedAnnotation))); + }); }); test('transfers documentation comments', () { diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 8a8808651e79..e0eefcb86e2b 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:pigeon/src/ast.dart'; +import 'package:pigeon/src/generator_tools.dart'; import 'package:pigeon/src/kotlin/kotlin_generator.dart'; import 'package:test/test.dart'; @@ -982,44 +983,47 @@ void main() { expect(code, startsWith('// hello world')); }); - test('generated annotation', () { - final root = Root(apis: [], classes: [], enums: []); - final sink = StringBuffer(); - final kotlinOptions = InternalKotlinOptions( - copyrightHeader: makeIterable('hello world'), - kotlinOut: '', - useGeneratedAnnotation: true, - ); - const generator = KotlinGenerator(); - generator.generate( - kotlinOptions, - root, - sink, - dartPackageName: DEFAULT_PACKAGE_NAME, - ); - final code = sink.toString(); - expect(code, contains('@javax.annotation.Generated("dev.flutter.pigeon")')); - }); + group('generated annotation', () { + late Root root; + late KotlinGenerator generator; + late StringBuffer sink; - test('no generated annotation', () { - final root = Root(apis: [], classes: [], enums: []); - final sink = StringBuffer(); - final kotlinOptions = InternalKotlinOptions( - copyrightHeader: makeIterable('hello world'), - kotlinOut: '', - ); - const generator = KotlinGenerator(); - generator.generate( - kotlinOptions, - root, - sink, - dartPackageName: DEFAULT_PACKAGE_NAME, - ); - final code = sink.toString(); - expect( - code, - isNot(contains('@javax.annotation.Generated("dev.flutter.pigeon")')), - ); + setUp(() { + root = Root(apis: [], classes: [], enums: []); + generator = const KotlinGenerator(); + sink = StringBuffer(); + }); + + test('with generated annotation', () { + final kotlinOptions = InternalKotlinOptions( + copyrightHeader: makeIterable('hello world'), + kotlinOut: '', + useGeneratedAnnotation: true, + ); + generator.generate( + kotlinOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final code = sink.toString(); + expect(code, contains(generatedAnnotation)); + }); + + test('without generated annotation', () { + final kotlinOptions = InternalKotlinOptions( + copyrightHeader: makeIterable('hello world'), + kotlinOut: '', + ); + generator.generate( + kotlinOptions, + root, + sink, + dartPackageName: DEFAULT_PACKAGE_NAME, + ); + final code = sink.toString(); + expect(code, isNot(contains(generatedAnnotation))); + }); }); test('generics - list', () { From d33ccffec730e4b78e497caac1e27962193d1632 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Fri, 6 Feb 2026 17:53:37 +0800 Subject: [PATCH 09/16] refactor: consolidate generated annotation constant and refactor test setup - Extract @javax.annotation.Generated("dev.flutter.pigeon") to shared constant in generator_tools.dart - Update kotlin_generator.dart and java_generator.dart to use shared constant - Refactor kotlin_generator_test.dart and java_generator_test.dart to use group() with setUp() pattern - Eliminates code duplication in test initialization across generator tests --- packages/pigeon/test/java_generator_test.dart | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/pigeon/test/java_generator_test.dart b/packages/pigeon/test/java_generator_test.dart index 06b2d3d237d3..664607bcdaa7 100644 --- a/packages/pigeon/test/java_generator_test.dart +++ b/packages/pigeon/test/java_generator_test.dart @@ -1613,20 +1613,28 @@ void main() { }); group('generated annotation', () { - test('with generated annotation', () { - final classDefinition = Class(name: 'Foobar', fields: []); - final root = Root( + late Class classDefinition; + late Root root; + late StringBuffer sink; + late JavaGenerator generator; + + setUp(() { + classDefinition = Class(name: 'Foobar', fields: []); + root = Root( apis: [], classes: [classDefinition], enums: [], ); - final sink = StringBuffer(); + sink = StringBuffer(); + generator = const JavaGenerator(); + }); + + test('with generated annotation', () { const javaOptions = InternalJavaOptions( className: 'Messages', useGeneratedAnnotation: true, javaOut: '', ); - const generator = JavaGenerator(); generator.generate( javaOptions, root, @@ -1638,18 +1646,10 @@ void main() { }); test('without generated annotation', () { - final classDefinition = Class(name: 'Foobar', fields: []); - final root = Root( - apis: [], - classes: [classDefinition], - enums: [], - ); - final sink = StringBuffer(); const javaOptions = InternalJavaOptions( className: 'Messages', javaOut: '', ); - const generator = JavaGenerator(); generator.generate( javaOptions, root, From 449b59760792bddeec0d5a0a9c87e924aea16fd4 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Mon, 9 Feb 2026 13:54:54 +0800 Subject: [PATCH 10/16] Add kotlinUseGeneratedAnnotation parameter to generation tool - Add kotlinUseGeneratedAnnotation parameter to runPigeon method - Pass useGeneratedAnnotation to KotlinOptions - Enable annotation for core_tests in generated test files --- packages/pigeon/tool/shared/generation.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/pigeon/tool/shared/generation.dart b/packages/pigeon/tool/shared/generation.dart index 99a19cb1fb71..b5979d958853 100644 --- a/packages/pigeon/tool/shared/generation.dart +++ b/packages/pigeon/tool/shared/generation.dart @@ -143,6 +143,7 @@ Future generateTestPigeons({ kotlinPackage: 'com.example.test_plugin', kotlinErrorClassName: kotlinErrorName, kotlinIncludeErrorClass: input != 'primitive', + kotlinUseGeneratedAnnotation: input == 'core_tests', // iOS/macOS swiftOut: skipLanguages.contains(GeneratorLanguage.swift) ? null @@ -217,6 +218,7 @@ Future runPigeon({ String? kotlinPackage, String? kotlinErrorClassName, bool kotlinIncludeErrorClass = true, + bool kotlinUseGeneratedAnnotation = false, bool swiftIncludeErrorClass = true, String? swiftOut, String? swiftErrorClassName, @@ -291,6 +293,7 @@ Future runPigeon({ package: kotlinPackage, errorClassName: kotlinErrorClassName, includeErrorClass: kotlinIncludeErrorClass, + useGeneratedAnnotation: kotlinUseGeneratedAnnotation, ), objcHeaderOut: objcHeaderOut, objcSourceOut: objcSourceOut, From 5e2b71a0f2c73ab8a01cde4a4b78e427cc443ec0 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Mon, 9 Feb 2026 14:09:56 +0800 Subject: [PATCH 11/16] Add javaUseGeneratedAnnotation parameter and test case - Add javaUseGeneratedAnnotation parameter to runPigeon method - Pass useGeneratedAnnotation to JavaOptions in PigeonOptions - Update test case to enable annotation for both Kotlin and Java - Generates CoreTestsWithAnnotation files for both languages --- packages/pigeon/tool/shared/generation.dart | 26 +++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/tool/shared/generation.dart b/packages/pigeon/tool/shared/generation.dart index b5979d958853..529c8da5d629 100644 --- a/packages/pigeon/tool/shared/generation.dart +++ b/packages/pigeon/tool/shared/generation.dart @@ -143,7 +143,6 @@ Future generateTestPigeons({ kotlinPackage: 'com.example.test_plugin', kotlinErrorClassName: kotlinErrorName, kotlinIncludeErrorClass: input != 'primitive', - kotlinUseGeneratedAnnotation: input == 'core_tests', // iOS/macOS swiftOut: skipLanguages.contains(GeneratorLanguage.swift) ? null @@ -209,6 +208,25 @@ Future generateTestPigeons({ return generateCode; } } + + // Test case for useGeneratedAnnotation feature with core_tests + final corePascalCaseName = _snakeToPascalCase('core_tests'); + int generateCodeWithAnnotation = await runPigeon( + input: './pigeons/core_tests.dart', + kotlinOut: '$outputBase/android/src/main/kotlin/com/example/test_plugin/${corePascalCaseName}WithAnnotation.gen.kt', + kotlinPackage: 'com.example.test_plugin', + kotlinErrorClassName: 'FlutterError', + kotlinIncludeErrorClass: true, + kotlinUseGeneratedAnnotation: true, + javaOut: '$alternateOutputBase/android/src/main/java/com/example/alternate_language_test_plugin/${corePascalCaseName}WithAnnotation.java', + javaPackage: 'com.example.alternate_language_test_plugin', + javaUseGeneratedAnnotation: true, + suppressVersion: true, + ); + if (generateCodeWithAnnotation != 0) { + return generateCodeWithAnnotation; + } + return 0; } @@ -232,6 +250,7 @@ Future runPigeon({ String? gobjectModule, String? javaOut, String? javaPackage, + bool javaUseGeneratedAnnotation = false, String? objcHeaderOut, String? objcSourceOut, String objcPrefix = '', @@ -287,7 +306,10 @@ Future runPigeon({ ? null : GObjectOptions(module: gobjectModule), javaOut: javaOut, - javaOptions: JavaOptions(package: javaPackage), + javaOptions: JavaOptions( + package: javaPackage, + useGeneratedAnnotation: javaUseGeneratedAnnotation, + ), kotlinOut: kotlinOut, kotlinOptions: KotlinOptions( package: kotlinPackage, From 04214ed928b79783d34908da9f7685f561aa434b Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Mon, 9 Feb 2026 14:10:33 +0800 Subject: [PATCH 12/16] Format generation.dart --- packages/pigeon/tool/shared/generation.dart | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/tool/shared/generation.dart b/packages/pigeon/tool/shared/generation.dart index 529c8da5d629..bb4b9b8ddeb8 100644 --- a/packages/pigeon/tool/shared/generation.dart +++ b/packages/pigeon/tool/shared/generation.dart @@ -213,12 +213,14 @@ Future generateTestPigeons({ final corePascalCaseName = _snakeToPascalCase('core_tests'); int generateCodeWithAnnotation = await runPigeon( input: './pigeons/core_tests.dart', - kotlinOut: '$outputBase/android/src/main/kotlin/com/example/test_plugin/${corePascalCaseName}WithAnnotation.gen.kt', + kotlinOut: + '$outputBase/android/src/main/kotlin/com/example/test_plugin/${corePascalCaseName}WithAnnotation.gen.kt', kotlinPackage: 'com.example.test_plugin', kotlinErrorClassName: 'FlutterError', kotlinIncludeErrorClass: true, kotlinUseGeneratedAnnotation: true, - javaOut: '$alternateOutputBase/android/src/main/java/com/example/alternate_language_test_plugin/${corePascalCaseName}WithAnnotation.java', + javaOut: + '$alternateOutputBase/android/src/main/java/com/example/alternate_language_test_plugin/${corePascalCaseName}WithAnnotation.java', javaPackage: 'com.example.alternate_language_test_plugin', javaUseGeneratedAnnotation: true, suppressVersion: true, From 34d41e18c16c485b5ec0b3e59656b91552b49d78 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Mon, 9 Feb 2026 14:24:39 +0800 Subject: [PATCH 13/16] Fix analyzer issues in generation.dart - Add type annotation for corePascalCaseName (String) - Make generateCodeWithAnnotation variable final - Remove redundant kotlinIncludeErrorClass: true (matches default) --- packages/pigeon/tool/shared/generation.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/pigeon/tool/shared/generation.dart b/packages/pigeon/tool/shared/generation.dart index bb4b9b8ddeb8..e97ad7add72e 100644 --- a/packages/pigeon/tool/shared/generation.dart +++ b/packages/pigeon/tool/shared/generation.dart @@ -210,20 +210,18 @@ Future generateTestPigeons({ } // Test case for useGeneratedAnnotation feature with core_tests - final corePascalCaseName = _snakeToPascalCase('core_tests'); - int generateCodeWithAnnotation = await runPigeon( + final String corePascalCaseName = _snakeToPascalCase('core_tests'); + final int generateCodeWithAnnotation = await runPigeon( input: './pigeons/core_tests.dart', kotlinOut: '$outputBase/android/src/main/kotlin/com/example/test_plugin/${corePascalCaseName}WithAnnotation.gen.kt', kotlinPackage: 'com.example.test_plugin', kotlinErrorClassName: 'FlutterError', - kotlinIncludeErrorClass: true, kotlinUseGeneratedAnnotation: true, javaOut: '$alternateOutputBase/android/src/main/java/com/example/alternate_language_test_plugin/${corePascalCaseName}WithAnnotation.java', javaPackage: 'com.example.alternate_language_test_plugin', javaUseGeneratedAnnotation: true, - suppressVersion: true, ); if (generateCodeWithAnnotation != 0) { return generateCodeWithAnnotation; From 0944a998a45e5a0a46c5a367d3ce1a294b3273a6 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Mon, 9 Feb 2026 16:10:01 +0800 Subject: [PATCH 14/16] Fix Kotlin @file: annotation prefix for @Generated --- packages/pigeon/lib/src/kotlin/kotlin_generator.dart | 5 ++++- packages/pigeon/test/kotlin_generator_test.dart | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart index 6a4ab994ffbc..bb9f7896676e 100644 --- a/packages/pigeon/lib/src/kotlin/kotlin_generator.dart +++ b/packages/pigeon/lib/src/kotlin/kotlin_generator.dart @@ -35,6 +35,9 @@ const String _pigeonMethodChannelCodec = 'PigeonMethodCodec'; const String _overflowClassName = '${classNamePrefix}CodecOverflow'; +/// Kotlin file-level annotation for generated code. +const String kotlinGeneratedAnnotation = '@file:$generatedAnnotation'; + /// Options that control how Kotlin code will be generated. class KotlinOptions { /// Creates a [KotlinOptions] object @@ -208,7 +211,7 @@ class KotlinGenerator extends StructuredGenerator { indent.writeln('// $seeAlsoWarning'); indent.writeln('@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")'); if (generatorOptions.useGeneratedAnnotation) { - indent.writeln(generatedAnnotation); + indent.writeln(kotlinGeneratedAnnotation); } } diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index e0eefcb86e2b..3719ed545ab4 100644 --- a/packages/pigeon/test/kotlin_generator_test.dart +++ b/packages/pigeon/test/kotlin_generator_test.dart @@ -1007,7 +1007,7 @@ void main() { dartPackageName: DEFAULT_PACKAGE_NAME, ); final code = sink.toString(); - expect(code, contains(generatedAnnotation)); + expect(code, contains(kotlinGeneratedAnnotation)); }); test('without generated annotation', () { @@ -1022,7 +1022,7 @@ void main() { dartPackageName: DEFAULT_PACKAGE_NAME, ); final code = sink.toString(); - expect(code, isNot(contains(generatedAnnotation))); + expect(code, isNot(contains(kotlinGeneratedAnnotation))); }); }); From a8254bab4dd199c76f00968f92edb1e672b2e868 Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Mon, 9 Feb 2026 16:13:45 +0800 Subject: [PATCH 15/16] Remove unrequired import --- packages/pigeon/test/kotlin_generator_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/pigeon/test/kotlin_generator_test.dart b/packages/pigeon/test/kotlin_generator_test.dart index 3719ed545ab4..1de8ae95e8ae 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/src/ast.dart'; -import 'package:pigeon/src/generator_tools.dart'; import 'package:pigeon/src/kotlin/kotlin_generator.dart'; import 'package:test/test.dart'; From 275d85f870138a40635efdb0f83935b09e78c1df Mon Sep 17 00:00:00 2001 From: jeffkwoh Date: Mon, 9 Feb 2026 16:30:32 +0800 Subject: [PATCH 16/16] Remove java generated goldens as they don't seems to be passing at HEAD --- packages/pigeon/tool/shared/generation.dart | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/pigeon/tool/shared/generation.dart b/packages/pigeon/tool/shared/generation.dart index e97ad7add72e..a183a44c344d 100644 --- a/packages/pigeon/tool/shared/generation.dart +++ b/packages/pigeon/tool/shared/generation.dart @@ -218,10 +218,6 @@ Future generateTestPigeons({ kotlinPackage: 'com.example.test_plugin', kotlinErrorClassName: 'FlutterError', kotlinUseGeneratedAnnotation: true, - javaOut: - '$alternateOutputBase/android/src/main/java/com/example/alternate_language_test_plugin/${corePascalCaseName}WithAnnotation.java', - javaPackage: 'com.example.alternate_language_test_plugin', - javaUseGeneratedAnnotation: true, ); if (generateCodeWithAnnotation != 0) { return generateCodeWithAnnotation;