Skip to content

Commit 2875eaf

Browse files
committed
[pigeon] Use a const for custom type ids for gobject generated files (#156100)
Adds a custom type identifier to generated gobject headers for the user. Calling fl_value_new_custom_object is now possible with that constant. This fixes flutter/flutter#156100 Also updated the CONTRIBUTING.md file to include the gobject generator.
1 parent 3c7859f commit 2875eaf

File tree

10 files changed

+433
-159
lines changed

10 files changed

+433
-159
lines changed

packages/pigeon/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## NEXT
1+
## 25.4.0
22

3+
* [gobject] Adds type id constants in header files so that they can be used by the user.
34
* Updates minimum supported SDK version to Flutter 3.27/Dart 3.6.
45

56
## 25.3.2

packages/pigeon/CONTRIBUTING.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ generators with that AST.
1919
## Source Index
2020

2121
* [ast.dart](./lib/src/ast.dart) - The data structure for representing the Abstract Syntax Tree.
22-
* [dart_generator.dart](./lib/src/dart_generator.dart) - The Dart code generator.
23-
* [java_generator.dart](./lib/src/java_generator.dart) - The Java code generator.
24-
* [kotlin_generator.dart](./lib/src/kotlin_generator.dart) - The Kotlin code generator.
25-
* [objc_generator.dart](./lib/src/objc_generator.dart) - The Objective-C code
22+
* [dart_generator.dart](./lib/src/dart/dart_generator.dart) - The Dart code generator.
23+
* [java_generator.dart](./lib/src/java/java_generator.dart) - The Java code generator.
24+
* [kotlin_generator.dart](./lib/src/kotlin/kotlin_generator.dart) - The Kotlin code generator.
25+
* [objc_generator.dart](./lib/src/objc/objc_generator.dart) - The Objective-C code
2626
generator (header and source files).
27-
* [swift_generator.dart](./lib/src/swift_generator.dart) - The Swift code generator.
28-
* [cpp_generator.dart](./lib/src/cpp_generator.dart) - The C++ code generator.
27+
* [swift_generator.dart](./lib/src/swift/swift_generator.dart) - The Swift code generator.
28+
* [cpp_generator.dart](./lib/src/cpp/cpp_generator.dart) - The C++ code generator.
29+
* [gobject_generator.dart](./lib/src/gobject/gobject_generator.dart) - The GObject code generator.
2930
* [generator_tools.dart](./lib/src/generator_tools.dart) - Shared code between generators.
3031
* [pigeon_cl.dart](./lib/src/pigeon_cl.dart) - The top-level function executed by
3132
the command line tool in [bin/][./bin].

packages/pigeon/example/app/linux/messages.g.cc

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ static FlValue* pigeon_example_package_message_data_to_list(
9191
? fl_value_new_string(self->description)
9292
: fl_value_new_null());
9393
fl_value_append_take(values,
94-
fl_value_new_custom(129, fl_value_new_int(self->code),
94+
fl_value_new_custom(pigeon_example_package_code_type_id,
95+
fl_value_new_int(self->code),
9596
(GDestroyNotify)fl_value_unref));
9697
fl_value_append_take(values, fl_value_ref(self->data));
9798
return values;
@@ -126,11 +127,14 @@ G_DEFINE_TYPE(PigeonExamplePackageMessageCodec,
126127
pigeon_example_package_message_codec,
127128
fl_standard_message_codec_get_type())
128129

130+
const int pigeon_example_package_code_type_id = 129;
131+
const int pigeon_example_package_message_data_type_id = 130;
132+
129133
static gboolean
130134
pigeon_example_package_message_codec_write_pigeon_example_package_code(
131135
FlStandardMessageCodec* codec, GByteArray* buffer, FlValue* value,
132136
GError** error) {
133-
uint8_t type = 129;
137+
uint8_t type = pigeon_example_package_code_type_id;
134138
g_byte_array_append(buffer, &type, sizeof(uint8_t));
135139
return fl_standard_message_codec_write_value(codec, buffer, value, error);
136140
}
@@ -139,7 +143,7 @@ static gboolean
139143
pigeon_example_package_message_codec_write_pigeon_example_package_message_data(
140144
FlStandardMessageCodec* codec, GByteArray* buffer,
141145
PigeonExamplePackageMessageData* value, GError** error) {
142-
uint8_t type = 130;
146+
uint8_t type = pigeon_example_package_message_data_type_id;
143147
g_byte_array_append(buffer, &type, sizeof(uint8_t));
144148
g_autoptr(FlValue) values =
145149
pigeon_example_package_message_data_to_list(value);
@@ -151,13 +155,13 @@ static gboolean pigeon_example_package_message_codec_write_value(
151155
GError** error) {
152156
if (fl_value_get_type(value) == FL_VALUE_TYPE_CUSTOM) {
153157
switch (fl_value_get_custom_type(value)) {
154-
case 129:
158+
case pigeon_example_package_code_type_id:
155159
return pigeon_example_package_message_codec_write_pigeon_example_package_code(
156160
codec, buffer,
157161
reinterpret_cast<FlValue*>(
158162
const_cast<gpointer>(fl_value_get_custom_value(value))),
159163
error);
160-
case 130:
164+
case pigeon_example_package_message_data_type_id:
161165
return pigeon_example_package_message_codec_write_pigeon_example_package_message_data(
162166
codec, buffer,
163167
PIGEON_EXAMPLE_PACKAGE_MESSAGE_DATA(
@@ -176,7 +180,8 @@ pigeon_example_package_message_codec_read_pigeon_example_package_code(
176180
FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset,
177181
GError** error) {
178182
return fl_value_new_custom(
179-
129, fl_standard_message_codec_read_value(codec, buffer, offset, error),
183+
pigeon_example_package_code_type_id,
184+
fl_standard_message_codec_read_value(codec, buffer, offset, error),
180185
(GDestroyNotify)fl_value_unref);
181186
}
182187

@@ -198,17 +203,18 @@ pigeon_example_package_message_codec_read_pigeon_example_package_message_data(
198203
return nullptr;
199204
}
200205

201-
return fl_value_new_custom_object(130, G_OBJECT(value));
206+
return fl_value_new_custom_object(pigeon_example_package_message_data_type_id,
207+
G_OBJECT(value));
202208
}
203209

204210
static FlValue* pigeon_example_package_message_codec_read_value_of_type(
205211
FlStandardMessageCodec* codec, GBytes* buffer, size_t* offset, int type,
206212
GError** error) {
207213
switch (type) {
208-
case 129:
214+
case pigeon_example_package_code_type_id:
209215
return pigeon_example_package_message_codec_read_pigeon_example_package_code(
210216
codec, buffer, offset, error);
211-
case 130:
217+
case pigeon_example_package_message_data_type_id:
212218
return pigeon_example_package_message_codec_read_pigeon_example_package_message_data(
213219
codec, buffer, offset, error);
214220
default:

packages/pigeon/example/app/linux/messages.g.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ G_DECLARE_FINAL_TYPE(PigeonExamplePackageMessageCodec,
9595
PIGEON_EXAMPLE_PACKAGE, MESSAGE_CODEC,
9696
FlStandardMessageCodec)
9797

98+
/**
99+
* Custom type ID constants:
100+
*
101+
* Constants used to identify custom types in the codec.
102+
* They are used in the codec to encode and decode custom types.
103+
* They may be used in custom object creation functions to identify the type.
104+
*/
105+
extern const int pigeon_example_package_code_type_id;
106+
extern const int pigeon_example_package_message_data_type_id;
107+
98108
G_DECLARE_FINAL_TYPE(PigeonExamplePackageExampleHostApi,
99109
pigeon_example_package_example_host_api,
100110
PIGEON_EXAMPLE_PACKAGE, EXAMPLE_HOST_API, GObject)

packages/pigeon/lib/src/generator_tools.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import 'generator.dart';
1515
/// The current version of pigeon.
1616
///
1717
/// This must match the version in pubspec.yaml.
18-
const String pigeonVersion = '25.3.2';
18+
const String pigeonVersion = '25.4.0';
1919

2020
/// Read all the content from [stdin] to a String.
2121
String readStdin() {

packages/pigeon/lib/src/gobject/gobject_generator.dart

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,28 @@ class GObjectHeaderGenerator
338338
indent.newln();
339339
_writeDeclareFinalType(indent, module, _codecBaseName,
340340
parentClassName: _standardCodecName);
341+
342+
final Iterable<EnumeratedType> customTypes =
343+
getEnumeratedTypes(root, excludeSealedClasses: true);
344+
345+
if (customTypes.isNotEmpty) {
346+
indent.newln();
347+
addDocumentationComments(
348+
indent,
349+
<String>[
350+
'Custom type ID constants:',
351+
'',
352+
'Constants used to identify custom types in the codec.',
353+
'They are used in the codec to encode and decode custom types.',
354+
'They may be used in custom object creation functions to identify the type.',
355+
],
356+
_docCommentSpec);
357+
}
358+
359+
for (final EnumeratedType customType in customTypes) {
360+
final String customTypeId = _getCustomTypeId(module, customType);
361+
indent.writeln('extern const int $customTypeId;');
362+
}
341363
}
342364

343365
@override
@@ -1019,18 +1041,26 @@ class GObjectSourceGenerator
10191041
_writeDefineType(indent, module, _codecBaseName,
10201042
parentType: 'fl_standard_message_codec_get_type()');
10211043

1044+
indent.newln();
1045+
for (final EnumeratedType customType in customTypes) {
1046+
final String customTypeId = _getCustomTypeId(module, customType);
1047+
indent.writeln('const int $customTypeId = ${customType.enumeration};');
1048+
}
1049+
10221050
for (final EnumeratedType customType in customTypes) {
10231051
final String customTypeName = _getClassName(module, customType.name);
10241052
final String snakeCustomTypeName =
10251053
_snakeCaseFromCamelCase(customTypeName);
1054+
final String customTypeId = _getCustomTypeId(module, customType);
1055+
10261056
indent.newln();
10271057
final String valueType = customType.type == CustomTypes.customClass
10281058
? '$customTypeName*'
10291059
: 'FlValue*';
10301060
indent.writeScoped(
10311061
'static gboolean ${codecMethodPrefix}_write_$snakeCustomTypeName($_standardCodecName* codec, GByteArray* buffer, $valueType value, GError** error) {',
10321062
'}', () {
1033-
indent.writeln('uint8_t type = ${customType.enumeration};');
1063+
indent.writeln('uint8_t type = $customTypeId;');
10341064
indent.writeln('g_byte_array_append(buffer, &type, sizeof(uint8_t));');
10351065
if (customType.type == CustomTypes.customClass) {
10361066
indent.writeln(
@@ -1053,7 +1083,8 @@ class GObjectSourceGenerator
10531083
indent.writeScoped('switch (fl_value_get_custom_type(value)) {', '}',
10541084
() {
10551085
for (final EnumeratedType customType in customTypes) {
1056-
indent.writeln('case ${customType.enumeration}:');
1086+
final String customTypeId = _getCustomTypeId(module, customType);
1087+
indent.writeln('case $customTypeId:');
10571088
indent.nest(1, () {
10581089
final String customTypeName =
10591090
_getClassName(module, customType.name);
@@ -1082,6 +1113,7 @@ class GObjectSourceGenerator
10821113
final String customTypeName = _getClassName(module, customType.name);
10831114
final String snakeCustomTypeName =
10841115
_snakeCaseFromCamelCase(customTypeName);
1116+
final String customTypeId = _getCustomTypeId(module, customType);
10851117
indent.newln();
10861118
indent.writeScoped(
10871119
'static FlValue* ${codecMethodPrefix}_read_$snakeCustomTypeName($_standardCodecName* codec, GBytes* buffer, size_t* offset, GError** error) {',
@@ -1102,10 +1134,10 @@ class GObjectSourceGenerator
11021134
});
11031135
indent.newln();
11041136
indent.writeln(
1105-
'return fl_value_new_custom_object(${customType.enumeration}, G_OBJECT(value));');
1137+
'return fl_value_new_custom_object($customTypeId, G_OBJECT(value));');
11061138
} else if (customType.type == CustomTypes.customEnum) {
11071139
indent.writeln(
1108-
'return fl_value_new_custom(${customType.enumeration}, fl_standard_message_codec_read_value(codec, buffer, offset, error), (GDestroyNotify)fl_value_unref);');
1140+
'return fl_value_new_custom($customTypeId, fl_standard_message_codec_read_value(codec, buffer, offset, error), (GDestroyNotify)fl_value_unref);');
11091141
}
11101142
});
11111143
}
@@ -1117,9 +1149,10 @@ class GObjectSourceGenerator
11171149
indent.writeScoped('switch (type) {', '}', () {
11181150
for (final EnumeratedType customType in customTypes) {
11191151
final String customTypeName = _getClassName(module, customType.name);
1152+
final String customTypeId = _getCustomTypeId(module, customType);
11201153
final String snakeCustomTypeName =
11211154
_snakeCaseFromCamelCase(customTypeName);
1122-
indent.writeln('case ${customType.enumeration}:');
1155+
indent.writeln('case $customTypeId:');
11231156
indent.nest(1, () {
11241157
indent.writeln(
11251158
'return ${codecMethodPrefix}_read_$snakeCustomTypeName(codec, buffer, offset, error);');
@@ -1922,6 +1955,16 @@ String _getMethodPrefix(String module, String name) {
19221955
return _snakeCaseFromCamelCase(className);
19231956
}
19241957

1958+
// Returns the code for the custom type id definition for [customType].
1959+
String _getCustomTypeId(String module, EnumeratedType customType) {
1960+
final String customTypeName = _getClassName(module, customType.name);
1961+
1962+
final String snakeCustomTypeName = _snakeCaseFromCamelCase(customTypeName);
1963+
1964+
final String customTypeId = '${snakeCustomTypeName}_type_id';
1965+
return customTypeId;
1966+
}
1967+
19251968
// Returns an enumeration value in C++ form.
19261969
String _getEnumValue(String module, String enumName, String memberName) {
19271970
final String snakeEnumName = _snakeCaseFromCamelCase(enumName);
@@ -2062,12 +2105,14 @@ String _referenceValue(String module, TypeDeclaration type, String variableName,
20622105
}
20632106
}
20642107

2065-
int _getTypeEnumeration(Root root, TypeDeclaration type) {
2066-
return getEnumeratedTypes(root, excludeSealedClasses: true)
2067-
.firstWhere((EnumeratedType t) =>
2068-
(type.isClass && t.associatedClass == type.associatedClass) ||
2069-
(type.isEnum && t.associatedEnum == type.associatedEnum))
2070-
.enumeration;
2108+
String _getCustomTypeIdFromDeclaration(
2109+
Root root, TypeDeclaration type, String module) {
2110+
return _getCustomTypeId(
2111+
module,
2112+
getEnumeratedTypes(root, excludeSealedClasses: true).firstWhere(
2113+
(EnumeratedType t) =>
2114+
(type.isClass && t.associatedClass == type.associatedClass) ||
2115+
(type.isEnum && t.associatedEnum == type.associatedEnum)));
20712116
}
20722117

20732118
// Returns code to convert the native data type stored in [variableName] to a FlValue.
@@ -2078,12 +2123,15 @@ String _makeFlValue(
20782123
{String? lengthVariableName}) {
20792124
final String value;
20802125
if (type.isClass) {
2081-
final int enumeration = _getTypeEnumeration(root, type);
2082-
value = 'fl_value_new_custom_object($enumeration, G_OBJECT($variableName))';
2126+
final String customTypeId =
2127+
_getCustomTypeIdFromDeclaration(root, type, module);
2128+
value =
2129+
'fl_value_new_custom_object($customTypeId, G_OBJECT($variableName))';
20832130
} else if (type.isEnum) {
2084-
final int enumeration = _getTypeEnumeration(root, type);
2131+
final String customTypeId =
2132+
_getCustomTypeIdFromDeclaration(root, type, module);
20852133
value =
2086-
'fl_value_new_custom($enumeration, fl_value_new_int(${type.isNullable ? '*$variableName' : variableName}), (GDestroyNotify)fl_value_unref)';
2134+
'fl_value_new_custom($customTypeId, fl_value_new_int(${type.isNullable ? '*$variableName' : variableName}), (GDestroyNotify)fl_value_unref)';
20872135
} else if (_isFlValueWrappedType(type)) {
20882136
value = 'fl_value_ref($variableName)';
20892137
} else if (type.baseName == 'void') {

0 commit comments

Comments
 (0)