Skip to content

Commit 25454e6

Browse files
authored
[pigeon] Creates new Generator classes for each language (v3) (#3022)
* Rename generator class to Adapter * create new generator class and dart subclass * cpp and dart test gen * added files * Adds Generator class to all generators * adds swift * Updates tests to use new Adapter naming scheme * Dart generate methods * convert all generate functions to use new method * chagngelog * remove Generator class fields * move paths to options * remove dartTestOptions * Nits and combines source and header generators * renames Adapter to GeneratorAdapter * Update version number for breaking changes * nits * more personal nits * Fixes dart header bug * add gen files for clarity * better field naming * better field naming * removed unneeded dart test generator * Add filetype to generator * Adds filetype as field to generatorAdapters * nits * assert * Default FileType * alt v4 * alt v5 * nits
1 parent c4b3089 commit 25454e6

File tree

34 files changed

+687
-343
lines changed

34 files changed

+687
-343
lines changed

packages/pigeon/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 5.0.0
2+
3+
* Creates new Generator classes for each language.
4+
15
## 4.2.16
26

37
* [swift] Fixes warnings with `Object` parameters.

packages/pigeon/lib/cpp_generator.dart

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'ast.dart';
66
import 'functional.dart';
7+
import 'generator.dart';
78
import 'generator_tools.dart';
89
import 'pigeon_lib.dart' show Error;
910

@@ -21,36 +22,41 @@ const String _defaultCodecSerializer = 'flutter::StandardCodecSerializer';
2122
class CppOptions {
2223
/// Creates a [CppOptions] object
2324
const CppOptions({
24-
this.header,
25+
this.headerIncludePath,
2526
this.namespace,
2627
this.copyrightHeader,
28+
this.headerOutPath,
2729
});
2830

2931
/// The path to the header that will get placed in the source filed (example:
3032
/// "foo.h").
31-
final String? header;
33+
final String? headerIncludePath;
3234

3335
/// The namespace where the generated class will live.
3436
final String? namespace;
3537

3638
/// A copyright header that will get prepended to generated code.
3739
final Iterable<String>? copyrightHeader;
3840

41+
/// The path to the output header file location.
42+
final String? headerOutPath;
43+
3944
/// Creates a [CppOptions] from a Map representation where:
4045
/// `x = CppOptions.fromMap(x.toMap())`.
4146
static CppOptions fromMap(Map<String, Object> map) {
4247
return CppOptions(
43-
header: map['header'] as String?,
48+
headerIncludePath: map['header'] as String?,
4449
namespace: map['namespace'] as String?,
4550
copyrightHeader: map['copyrightHeader'] as Iterable<String>?,
51+
headerOutPath: map['cppHeaderOut'] as String?,
4652
);
4753
}
4854

4955
/// Converts a [CppOptions] to a Map representation where:
5056
/// `x = CppOptions.fromMap(x.toMap())`.
5157
Map<String, Object> toMap() {
5258
final Map<String, Object> result = <String, Object>{
53-
if (header != null) 'header': header!,
59+
if (headerIncludePath != null) 'header': headerIncludePath!,
5460
if (namespace != null) 'namespace': namespace!,
5561
if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!,
5662
};
@@ -64,6 +70,25 @@ class CppOptions {
6470
}
6571
}
6672

73+
/// Class that manages all Cpp code generation.
74+
class CppGenerator extends Generator<OutputFileOptions<CppOptions>> {
75+
/// Instantiates a Cpp Generator.
76+
CppGenerator();
77+
78+
/// Generates Cpp files with specified [OutputFileOptions<CppOptions>]
79+
@override
80+
void generate(OutputFileOptions<CppOptions> languageOptions, Root root,
81+
StringSink sink) {
82+
final FileType fileType = languageOptions.fileType;
83+
assert(fileType == FileType.header || fileType == FileType.source);
84+
if (fileType == FileType.header) {
85+
generateCppHeader(languageOptions.languageOptions, root, sink);
86+
} else {
87+
generateCppSource(languageOptions.languageOptions, root, sink);
88+
}
89+
}
90+
}
91+
6792
String _getCodecSerializerName(Api api) => '${api.name}CodecSerializer';
6893

6994
const String _pointerPrefix = 'pointer';
@@ -1026,8 +1051,8 @@ void _writeSystemHeaderIncludeBlock(Indent indent, List<String> headers) {
10261051

10271052
/// Generates the ".h" file for the AST represented by [root] to [sink] with the
10281053
/// provided [options] and [headerFileName].
1029-
void generateCppHeader(
1030-
String? headerFileName, CppOptions options, Root root, StringSink sink) {
1054+
void generateCppHeader(CppOptions options, Root root, StringSink sink) {
1055+
final String? headerFileName = options.headerOutPath;
10311056
final Indent indent = Indent(sink);
10321057
if (options.copyrightHeader != null) {
10331058
addLines(indent, options.copyrightHeader!, linePrefix: '// ');
@@ -1128,7 +1153,7 @@ void generateCppSource(CppOptions options, Root root, StringSink sink) {
11281153
indent.addln('#undef _HAS_EXCEPTIONS');
11291154
indent.addln('');
11301155

1131-
indent.writeln('#include "${options.header}"');
1156+
indent.writeln('#include "${options.headerIncludePath}"');
11321157
indent.addln('');
11331158
_writeSystemHeaderIncludeBlock(indent, <String>[
11341159
'flutter/basic_message_channel.h',

packages/pigeon/lib/dart_generator.dart

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:yaml/yaml.dart' as yaml;
99

1010
import 'ast.dart';
1111
import 'functional.dart';
12+
import 'generator.dart';
1213
import 'generator_tools.dart';
1314

1415
/// Documentation comment open symbol.
@@ -24,18 +25,30 @@ const String _standardMessageCodec = 'StandardMessageCodec';
2425
/// Options that control how Dart code will be generated.
2526
class DartOptions {
2627
/// Constructor for DartOptions.
27-
const DartOptions({this.copyrightHeader});
28+
DartOptions({
29+
this.copyrightHeader,
30+
this.sourceOutPath,
31+
this.testOutPath,
32+
});
2833

2934
/// A copyright header that will get prepended to generated code.
3035
final Iterable<String>? copyrightHeader;
3136

37+
/// Path to output generated Dart file.
38+
String? sourceOutPath;
39+
40+
/// Path to output generated Test file for tests.
41+
String? testOutPath;
42+
3243
/// Creates a [DartOptions] from a Map representation where:
3344
/// `x = DartOptions.fromMap(x.toMap())`.
3445
static DartOptions fromMap(Map<String, Object> map) {
3546
final Iterable<dynamic>? copyrightHeader =
3647
map['copyrightHeader'] as Iterable<dynamic>?;
3748
return DartOptions(
3849
copyrightHeader: copyrightHeader?.cast<String>(),
50+
sourceOutPath: map['sourceOutPath'] as String?,
51+
testOutPath: map['testOutPath'] as String?,
3952
);
4053
}
4154

@@ -44,6 +57,8 @@ class DartOptions {
4457
Map<String, Object> toMap() {
4558
final Map<String, Object> result = <String, Object>{
4659
if (copyrightHeader != null) 'copyrightHeader': copyrightHeader!,
60+
if (sourceOutPath != null) 'sourceOutPath': sourceOutPath!,
61+
if (testOutPath != null) 'testOutPath': testOutPath!,
4762
};
4863
return result;
4964
}
@@ -55,6 +70,33 @@ class DartOptions {
5570
}
5671
}
5772

73+
/// Class that manages all Dart code generation.
74+
class DartGenerator extends Generator<DartOptions> {
75+
/// Instantiates a Dart Generator.
76+
DartGenerator();
77+
78+
/// Generates Dart files with specified [DartOptions]
79+
@override
80+
void generate(DartOptions languageOptions, Root root, StringSink sink,
81+
{FileType fileType = FileType.na}) {
82+
assert(fileType == FileType.na);
83+
generateDart(languageOptions, root, sink);
84+
}
85+
86+
/// Generates Dart files for testing with specified [DartOptions]
87+
void generateTest(DartOptions languageOptions, Root root, StringSink sink) {
88+
final String sourceOutPath = languageOptions.sourceOutPath ?? '';
89+
final String testOutPath = languageOptions.testOutPath ?? '';
90+
generateTestDart(
91+
languageOptions,
92+
root,
93+
sink,
94+
sourceOutPath: sourceOutPath,
95+
testOutPath: testOutPath,
96+
);
97+
}
98+
}
99+
58100
String _escapeForDartSingleQuotedString(String raw) {
59101
return raw
60102
.replaceAll(r'\', r'\\')
@@ -699,14 +741,14 @@ String _posixify(String inputPath) {
699741
}
700742

701743
/// Generates Dart source code for test support libraries based on the given AST
702-
/// represented by [root], outputting the code to [sink]. [dartOutPath] is the
744+
/// represented by [root], outputting the code to [sink]. [sourceOutPath] is the
703745
/// path of the generated dart code to be tested. [testOutPath] is where the
704746
/// test code will be generated.
705747
void generateTestDart(
706748
DartOptions opt,
707749
Root root,
708750
StringSink sink, {
709-
required String dartOutPath,
751+
required String sourceOutPath,
710752
required String testOutPath,
711753
}) {
712754
final Indent indent = Indent(sink);
@@ -730,10 +772,10 @@ void generateTestDart(
730772
indent.writeln('');
731773
final String relativeDartPath =
732774
path.Context(style: path.Style.posix).relative(
733-
_posixify(dartOutPath),
775+
_posixify(sourceOutPath),
734776
from: _posixify(path.dirname(testOutPath)),
735777
);
736-
late final String? packageName = _deducePackageName(dartOutPath);
778+
late final String? packageName = _deducePackageName(sourceOutPath);
737779
if (!relativeDartPath.contains('/lib/') || packageName == null) {
738780
// If we can't figure out the package name or the relative path doesn't
739781
// include a 'lib' directory, try relative path import which only works in

packages/pigeon/lib/generator.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'ast.dart';
6+
7+
/// A superclass of generator classes.
8+
///
9+
/// This provides the structure that is common across generators for different languages.
10+
abstract class Generator<T> {
11+
/// Generates files for specified language with specified [languageOptions]
12+
void generate(T languageOptions, Root root, StringSink sink);
13+
}

packages/pigeon/lib/generator_tools.dart

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import 'dart:mirrors';
99
import 'ast.dart';
1010

1111
/// The current version of pigeon. This must match the version in pubspec.yaml.
12-
const String pigeonVersion = '4.2.16';
12+
const String pigeonVersion = '5.0.0';
1313

1414
/// Read all the content from [stdin] to a String.
1515
String readStdin() {
@@ -497,3 +497,29 @@ Iterable<NamedType> getFieldsInSerializationOrder(Class klass) {
497497
// This returns the fields in the order they are declared in the pigeon file.
498498
return klass.fields;
499499
}
500+
501+
/// Enum to specify which file will be generated for multi-file generators
502+
enum FileType {
503+
/// header file.
504+
header,
505+
506+
/// source file.
507+
source,
508+
509+
/// file type is not applicable.
510+
na,
511+
}
512+
513+
/// Options for [Generator]'s that have multiple output file types.
514+
///
515+
/// Specifies which file to write as well as wraps all language options.
516+
class OutputFileOptions<T> {
517+
/// Constructor.
518+
OutputFileOptions({required this.fileType, required this.languageOptions});
519+
520+
/// To specify which file type should be created.
521+
FileType fileType;
522+
523+
/// Options for specified language across all file types.
524+
T languageOptions;
525+
}

packages/pigeon/lib/java_generator.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'ast.dart';
66
import 'functional.dart';
7+
import 'generator.dart';
78
import 'generator_tools.dart';
89
import 'pigeon_lib.dart' show TaskQueueType;
910

@@ -84,6 +85,20 @@ class JavaOptions {
8485
}
8586
}
8687

88+
/// Class that manages all Java code generation.
89+
class JavaGenerator extends Generator<JavaOptions> {
90+
/// Instantiates a Java Generator.
91+
JavaGenerator();
92+
93+
/// Generates Java files with specified [JavaOptions]
94+
@override
95+
void generate(JavaOptions languageOptions, Root root, StringSink sink,
96+
{FileType fileType = FileType.na}) {
97+
assert(fileType == FileType.na);
98+
generateJava(languageOptions, root, sink);
99+
}
100+
}
101+
87102
/// Calculates the name of the codec that will be generated for [api].
88103
String _getCodecName(Api api) => '${api.name}Codec';
89104

packages/pigeon/lib/kotlin_generator.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'ast.dart';
66
import 'functional.dart';
7+
import 'generator.dart';
78
import 'generator_tools.dart';
89
import 'pigeon_lib.dart' show TaskQueueType;
910

@@ -64,6 +65,20 @@ class KotlinOptions {
6465
}
6566
}
6667

68+
/// Class that manages all Kotlin code generation.
69+
class KotlinGenerator extends Generator<KotlinOptions> {
70+
/// Instantiates a Kotlin Generator.
71+
KotlinGenerator();
72+
73+
/// Generates Kotlin files with specified [KotlinOptions]
74+
@override
75+
void generate(KotlinOptions languageOptions, Root root, StringSink sink,
76+
{FileType fileType = FileType.na}) {
77+
assert(fileType == FileType.na);
78+
generateKotlin(languageOptions, root, sink);
79+
}
80+
}
81+
6782
/// Calculates the name of the codec that will be generated for [api].
6883
String _getCodecName(Api api) => '${api.name}Codec';
6984

0 commit comments

Comments
 (0)