Skip to content

Commit 9a0a348

Browse files
committed
Adds non-null object fields
1 parent 6380b56 commit 9a0a348

File tree

3 files changed

+203
-13
lines changed

3 files changed

+203
-13
lines changed

packages/pigeon/lib/dart_generator.dart

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -470,15 +470,23 @@ void generateDart(DartOptions opt, Root root, StringSink sink) {
470470
'final Map<Object$nullTag, Object$nullTag> pigeonMap = <Object$nullTag, Object$nullTag>{};',
471471
);
472472
for (final NamedType field in klass.fields) {
473+
final String nullsafe = field.type.isNullable ? '?' : '';
473474
indent.write('pigeonMap[\'${field.name}\'] = ');
474475
if (customClassNames.contains(field.type.baseName)) {
475-
indent.addln(
476-
'${field.name} == null ? null : ${field.name}$unwrapOperator.encode();',
477-
);
476+
if (opt.isNullSafe) {
477+
indent.addln('${field.name}$nullsafe.encode();');
478+
} else {
479+
indent.addln(
480+
'${field.name} == null ? null : ${field.name}.encode();');
481+
}
478482
} else if (customEnumNames.contains(field.type.baseName)) {
479-
indent.addln(
480-
'${field.name} == null ? null : ${field.name}$unwrapOperator.index;',
481-
);
483+
if (opt.isNullSafe) {
484+
indent.addln('${field.name}$nullsafe.index;');
485+
} else {
486+
indent.addln(
487+
'${field.name} == null ? null : ${field.name}$unwrapOperator.index;',
488+
);
489+
}
482490
} else {
483491
indent.addln('${field.name};');
484492
}
@@ -490,15 +498,25 @@ void generateDart(DartOptions opt, Root root, StringSink sink) {
490498
void writeDecode() {
491499
void writeValueDecode(NamedType field) {
492500
if (customClassNames.contains(field.type.baseName)) {
493-
indent.format('''
501+
if (field.type.isNullable) {
502+
indent.format('''
494503
pigeonMap['${field.name}'] != null
495504
\t\t? ${field.type.baseName}.decode(pigeonMap['${field.name}']$unwrapOperator)
496505
\t\t: null''', leadingSpace: false, trailingNewline: false);
506+
} else {
507+
indent.add(
508+
'${field.type.baseName}.decode(pigeonMap[\'${field.name}\']$unwrapOperator)');
509+
}
497510
} else if (customEnumNames.contains(field.type.baseName)) {
498-
indent.format('''
511+
if (field.type.isNullable) {
512+
indent.format('''
499513
pigeonMap['${field.name}'] != null
500514
\t\t? ${field.type.baseName}.values[pigeonMap['${field.name}']$unwrapOperator as int]
501515
\t\t: null''', leadingSpace: false, trailingNewline: false);
516+
} else {
517+
indent.add(
518+
'${field.type.baseName}.values[pigeonMap[\'${field.name}\']$unwrapOperator as int]');
519+
}
502520
} else if (field.type.typeArguments.isNotEmpty) {
503521
final String genericType =
504522
_makeGenericTypeArguments(field.type, nullTag);

packages/pigeon/pigeons/non_null_fields.dart

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,24 @@ class SearchRequest {
1212
String query;
1313
}
1414

15+
enum SearchReplyType {
16+
success,
17+
error,
18+
}
19+
1520
class SearchReply {
16-
SearchReply(this.result, this.error, this.indices);
21+
SearchReply(
22+
this.result,
23+
this.error,
24+
this.indices,
25+
this.request,
26+
this.type,
27+
);
1728
String result;
1829
String error;
1930
List<int?> indices;
31+
SearchRequest request;
32+
SearchReplyType type;
2033
}
2134

2235
@HostApi()

packages/pigeon/test/dart_generator_test.dart

Lines changed: 163 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,168 @@ void main() {
204204
);
205205
});
206206

207+
test('nested null class nullsafe', () {
208+
final Root root = Root(apis: <Api>[], classes: <Class>[
209+
Class(
210+
name: 'Input',
211+
fields: <NamedType>[
212+
NamedType(
213+
type: const TypeDeclaration(
214+
baseName: 'String',
215+
isNullable: true,
216+
),
217+
name: 'input',
218+
offset: null)
219+
],
220+
),
221+
Class(
222+
name: 'Nested',
223+
fields: <NamedType>[
224+
NamedType(
225+
type: const TypeDeclaration(
226+
baseName: 'Input',
227+
isNullable: true,
228+
),
229+
name: 'nested',
230+
offset: null)
231+
],
232+
)
233+
], enums: <Enum>[]);
234+
final StringBuffer sink = StringBuffer();
235+
generateDart(const DartOptions(isNullSafe: true), root, sink);
236+
final String code = sink.toString();
237+
expect(
238+
code,
239+
contains(
240+
'pigeonMap[\'nested\'] = nested?.encode()',
241+
),
242+
);
243+
expect(
244+
code.replaceAll('\n', ' ').replaceAll(' ', ''),
245+
contains(
246+
'nested: pigeonMap[\'nested\'] != null ? Input.decode(pigeonMap[\'nested\']!) : null',
247+
),
248+
);
249+
});
250+
251+
test('nested non-null class nullsafe', () {
252+
final Root root = Root(apis: <Api>[], classes: <Class>[
253+
Class(
254+
name: 'Input',
255+
fields: <NamedType>[
256+
NamedType(
257+
type: const TypeDeclaration(
258+
baseName: 'String',
259+
isNullable: true,
260+
),
261+
name: 'input',
262+
offset: null)
263+
],
264+
),
265+
Class(
266+
name: 'Nested',
267+
fields: <NamedType>[
268+
NamedType(
269+
type: const TypeDeclaration(
270+
baseName: 'Input',
271+
isNullable: false,
272+
),
273+
name: 'nested',
274+
offset: null)
275+
],
276+
)
277+
], enums: <Enum>[]);
278+
final StringBuffer sink = StringBuffer();
279+
generateDart(const DartOptions(isNullSafe: true), root, sink);
280+
final String code = sink.toString();
281+
expect(
282+
code,
283+
contains(
284+
'pigeonMap[\'nested\'] = nested.encode()',
285+
),
286+
);
287+
expect(
288+
code.replaceAll('\n', ' ').replaceAll(' ', ''),
289+
contains(
290+
'nested: Input.decode(pigeonMap[\'nested\']!)',
291+
),
292+
);
293+
});
294+
295+
test('nested null enum nullsafe', () {
296+
final Root root = Root(apis: <Api>[], classes: <Class>[
297+
Class(
298+
name: 'Nested',
299+
fields: <NamedType>[
300+
NamedType(
301+
type: const TypeDeclaration(
302+
baseName: 'Input',
303+
isNullable: true,
304+
),
305+
name: 'nested',
306+
offset: null)
307+
],
308+
)
309+
], enums: <Enum>[
310+
Enum(
311+
name: 'Input',
312+
members: <String>['A', 'B'],
313+
)
314+
]);
315+
final StringBuffer sink = StringBuffer();
316+
generateDart(const DartOptions(isNullSafe: true), root, sink);
317+
final String code = sink.toString();
318+
expect(
319+
code,
320+
contains(
321+
'pigeonMap[\'nested\'] = nested?.index',
322+
),
323+
);
324+
expect(
325+
code.replaceAll('\n', ' ').replaceAll(' ', ''),
326+
contains(
327+
'nested: pigeonMap[\'nested\'] != null ? Input.values[pigeonMap[\'nested\']! as int] : null',
328+
),
329+
);
330+
});
331+
332+
test('nested non-null enum nullsafe', () {
333+
final Root root = Root(apis: <Api>[], classes: <Class>[
334+
Class(
335+
name: 'Nested',
336+
fields: <NamedType>[
337+
NamedType(
338+
type: const TypeDeclaration(
339+
baseName: 'Input',
340+
isNullable: false,
341+
),
342+
name: 'nested',
343+
offset: null)
344+
],
345+
)
346+
], enums: <Enum>[
347+
Enum(
348+
name: 'Input',
349+
members: <String>['A', 'B'],
350+
)
351+
]);
352+
final StringBuffer sink = StringBuffer();
353+
generateDart(const DartOptions(isNullSafe: true), root, sink);
354+
final String code = sink.toString();
355+
expect(
356+
code,
357+
contains(
358+
'pigeonMap[\'nested\'] = nested.index',
359+
),
360+
);
361+
expect(
362+
code.replaceAll('\n', ' ').replaceAll(' ', ''),
363+
contains(
364+
'nested: Input.values[pigeonMap[\'nested\']! as int]',
365+
),
366+
);
367+
});
368+
207369
test('flutterapi', () {
208370
final Root root = Root(apis: <Api>[
209371
Api(name: 'Api', location: ApiLocation.flutter, methods: <Method>[
@@ -443,10 +605,7 @@ void main() {
443605
final StringBuffer sink = StringBuffer();
444606
generateDart(const DartOptions(isNullSafe: true), root, sink);
445607
final String code = sink.toString();
446-
expect(
447-
code,
448-
contains(
449-
'pigeonMap[\'enum1\'] = enum1 == null ? null : enum1!.index;'));
608+
expect(code, contains('pigeonMap[\'enum1\'] = enum1?.index;'));
450609
expect(code, contains('? Enum.values[pigeonMap[\'enum1\']! as int]'));
451610
expect(code, contains('EnumClass doSomething(EnumClass arg0);'));
452611
});

0 commit comments

Comments
 (0)