[pigeon] Improve casting and nullability-handling in generated code#11163
[pigeon] Improve casting and nullability-handling in generated code#11163srawlins wants to merge 8 commits intoflutter:mainfrom
Conversation
There are a number of positions where we attempt to cast a nullable expression to a non-nullable type with something like the following `foo as List<Object?>?)!`. This successfully performs the cast and avoids a lint rule which recommends not casting a nullable expression to a non-nullable type. But it can be done more simply. Here are some examples of the improved code: ```diff - data: (result[3] as Map<Object?, Object?>?)!.cast<String, String>(), + data: (result[3]! as Map<Object?, Object?>).cast<String, String>(), - final List<Object?> args = (message as List<Object?>?)!; + final List<Object?> args = message! as List<Object?>; - stringList: (result[13] as List<Object?>?)!.cast<String>(), + stringList: (result[13]! as List<Object?>).cast<String>(), ``` Since we are expecting these values to be non-null, we first null-assert them (`!`), and then cast the expression with `as`. There was previously a helper, `_makeGenericCastCall`, which generated the String representation for a call to `cast`, like `.cast<Object?>()`, which was called in three places. This change consoldiates the surrounding code to those call sites into a new helper, `_castValue`, which instead returns the complete String of casting a value to a type, possibly null-asserting the value and possibly calling `.cast()`. Combining all of the casting code into one function also allows us to avoid unnecessary parentheses: ```diff - final String? arg_aString = (args[0] as String?); + final String? arg_aString = args[0] as String?; ``` Improving the nullability-handling allows us to remove the `_addGenericTypes` helper, and rename the `addGenericTypesNullable` to just `addGenericTypes`, since the helper should always print an appropriate nullability suffix. One prominent change made to the generated code is the removal of "assert foo is not null" statements. These are redundant with the null-asserts (`!`), although they _might_ offer more information in the assertion message, though I honestly don't think so. The exception thrown by `!` has the relevant information in the stack trace.
There was a problem hiding this comment.
Code Review
This pull request refactors the nullability handling in the generated Dart code, resulting in simpler and more idiomatic casting logic. The introduction of the _castValue helper centralizes casting operations, and the removal of redundant null checks and parentheses improves code clarity. The changes across the generated files are consistent with these improvements. I've found one minor issue in a documentation comment.
Note: Security Review is unavailable for this PR.
Man, I thought I'd gotten rid of all of these years ago... |
There are a number of positions where we attempt to cast a nullable expression to a non-nullable type with something like the following
(foo as List<Object?>?)!. This successfully performs the cast and avoids a lint rule which recommends not casting a nullable expression to a non-nullable type. But it can be done more simply. Here are some examples of the improved code:Since we are expecting these values to be non-null, we first null-assert them (
!), and then cast the expression withas.There was previously a helper,
_makeGenericCastCall, which generated the String representation for a call tocast, like.cast<Object?>(), which was called in three places. This change consoldiates the surrounding code to those call sites into a new helper,_castValue, which instead returns the complete String of casting a value to a type, possibly null-asserting the value and possibly calling.cast().Combining all of the casting code into one function also allows us to avoid unnecessary parentheses:
Improving the nullability-handling allows us to remove the
_addGenericTypeshelper, and rename theaddGenericTypesNullableto justaddGenericTypes, since the helper should always print an appropriate nullability suffix.One prominent change made to the generated code is the removal of "assert foo is not null" statements. These are redundant with the null-asserts (
!), although they might offer more information in the assertion message, though I honestly don't think so. The exception thrown by!has the relevant information in the stack trace.Fixes flutter/flutter#116972
Pre-Review Checklist
[shared_preferences]///).