[pigeon] a few tweaks to the output after having upgraded video_player (#663)

diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md
index e85ec48..201508e 100644
--- a/packages/pigeon/CHANGELOG.md
+++ b/packages/pigeon/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 1.0.17
+
+* [dart_test] Adds missing linter ignores.
+* [objc] Factors out helper function for reading from NSDictionary's.
+* [objc] Renames static variables to match Google style.
+
 ## 1.0.16
 
 * Updates behavior of run\_tests.dart with no arguments.
diff --git a/packages/pigeon/bin/run_tests.dart b/packages/pigeon/bin/run_tests.dart
index 53e82c1..927c517 100644
--- a/packages/pigeon/bin/run_tests.dart
+++ b/packages/pigeon/bin/run_tests.dart
@@ -7,7 +7,7 @@
 ///
 /// usage: pub run pigeon:run_tests
 ////////////////////////////////////////////////////////////////////////////////
-import 'dart:io' show Process, Platform, exit, stdout, stderr;
+import 'dart:io' show File, Process, Platform, exit, stderr, stdout;
 import 'package:args/args.dart';
 import 'package:meta/meta.dart';
 import 'package:pigeon/functional.dart';
@@ -103,6 +103,34 @@
   return 0;
 }
 
+Future<int> _analyzeFlutterUnitTests(String flutterUnitTestsPath) async {
+  final String messagePath = '$flutterUnitTestsPath/lib/message.gen.dart';
+  final String messageTestPath = '$flutterUnitTestsPath/test/message_test.dart';
+  final int generateTestCode = await _runPigeon(
+    input: 'pigeons/message.dart',
+    dartOut: messagePath,
+    dartTestOut: messageTestPath,
+    streamOutput: true,
+  );
+  if (generateTestCode != 0) {
+    return generateTestCode;
+  }
+
+  final int analyzeCode = await _runProcess(
+    'flutter',
+    <String>['analyze'],
+    workingDirectory: flutterUnitTestsPath,
+  );
+  if (analyzeCode != 0) {
+    return analyzeCode;
+  }
+
+  // Delete these files that were just generated to help with the analyzer step.
+  File(messagePath).deleteSync();
+  File(messageTestPath).deleteSync();
+  return 0;
+}
+
 Future<int> _runFlutterUnitTests() async {
   const String flutterUnitTestsPath =
       'platform_tests/flutter_null_safe_unit_tests';
@@ -121,6 +149,11 @@
     return generateCode;
   }
 
+  final int analyzeCode = await _analyzeFlutterUnitTests(flutterUnitTestsPath);
+  if (analyzeCode != 0) {
+    return analyzeCode;
+  }
+
   final int testCode = await _runProcess(
     'flutter',
     <String>['test'],
diff --git a/packages/pigeon/lib/dart_generator.dart b/packages/pigeon/lib/dart_generator.dart
index 29893dc..44693ac 100644
--- a/packages/pigeon/lib/dart_generator.dart
+++ b/packages/pigeon/lib/dart_generator.dart
@@ -578,8 +578,9 @@
   indent.writeln('// $generatedCodeWarning');
   indent.writeln('// $seeAlsoWarning');
   indent.writeln(
-    '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import',
+    '// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis',
   );
+  indent.writeln('// ignore_for_file: avoid_relative_lib_imports');
   indent.writeln('// @dart = ${opt.isNullSafe ? '2.12' : '2.8'}');
   indent.writeln('import \'dart:async\';');
   indent.writeln(
@@ -590,6 +591,8 @@
   indent.writeln('import \'package:flutter/services.dart\';');
   indent.writeln('import \'package:flutter_test/flutter_test.dart\';');
   indent.writeln('');
+  // TODO(gaaclarke): Switch from relative paths to URIs. This fails in new versions of Dart,
+  // https://github.com/flutter/flutter/issues/97744.
   indent.writeln(
     'import \'${_escapeForDartSingleQuotedString(mainDartFile)}\';',
   );
diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart
index 1dfbcdf..ae03da6 100644
--- a/packages/pigeon/lib/generator_tools.dart
+++ b/packages/pigeon/lib/generator_tools.dart
@@ -8,7 +8,7 @@
 import 'ast.dart';
 
 /// The current version of pigeon. This must match the version in pubspec.yaml.
-const String pigeonVersion = '1.0.16';
+const String pigeonVersion = '1.0.17';
 
 /// Read all the content from [stdin] to a String.
 String readStdin() {
diff --git a/packages/pigeon/lib/objc_generator.dart b/packages/pigeon/lib/objc_generator.dart
index e232407..8419760 100644
--- a/packages/pigeon/lib/objc_generator.dart
+++ b/packages/pigeon/lib/objc_generator.dart
@@ -305,13 +305,13 @@
 @end
 
 NSObject<FlutterMessageCodec> *${_getCodecGetterName(options.prefix, api.name)}() {
-\tstatic dispatch_once_t s_pred = 0;
-\tstatic FlutterStandardMessageCodec *s_sharedObject = nil;
-\tdispatch_once(&s_pred, ^{
+\tstatic dispatch_once_t sPred = 0;
+\tstatic FlutterStandardMessageCodec *sSharedObject = nil;
+\tdispatch_once(&sPred, ^{
 \t\t$readerWriterName *readerWriter = [[$readerWriterName alloc] init];
-\t\ts_sharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
+\t\tsSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
 \t});
-\treturn s_sharedObject;
+\treturn sSharedObject;
 }
 ''');
 }
@@ -551,9 +551,9 @@
     if (prefix != null) {
       className = '$prefix$className';
     }
-    return '[$className fromMap:$dict[@"${field.name}"]]';
+    return '[$className fromMap:GetNullableObject($dict, @"${field.name}")]';
   } else {
-    return '$dict[@"${field.name}"]';
+    return 'GetNullableObject($dict, @"${field.name}")';
   }
 }
 
@@ -811,7 +811,7 @@
     indent.writeln('#endif');
   }
 
-  void writeWrapResultFunction() {
+  void writeHelperFunctions() {
     indent.format('''
 static NSDictionary<NSString *, id> *wrapResult(id result, FlutterError *error) {
 \tNSDictionary *errorDict = (NSDictionary *)[NSNull null];
@@ -827,6 +827,12 @@
 \t\t\t@"${Keys.error}": errorDict,
 \t\t\t};
 }''');
+    indent.format('''
+static id GetNullableObject(NSDictionary* dict, id key) {
+\tid result = dict[key];
+\treturn (result == [NSNull null]) ? nil : result;
+}
+''');
   }
 
   void writeDataClassExtension(Class klass) {
@@ -864,15 +870,9 @@
           } else {
             indent.writeln(
                 '$resultName.${field.name} = ${_dictGetter(classNames, 'dict', field, options.prefix)};');
-            if (field.type.isNullable) {
-              indent.write(
-                  'if ((NSNull *)$resultName.${field.name} == [NSNull null]) ');
-              indent.scoped('{', '}', () {
-                indent.writeln('$resultName.${field.name} = nil;');
-              });
-            } else {
-              indent.writeln(
-                  'NSAssert((NSNull *)$resultName.${field.name} != [NSNull null], @"");');
+            if (!field.type.isNullable) {
+              indent
+                  .writeln('NSAssert($resultName.${field.name} != nil, @"");');
             }
           }
         }
@@ -915,7 +915,7 @@
   indent.writeln('');
   writeArcEnforcer();
   indent.addln('');
-  writeWrapResultFunction();
+  writeHelperFunctions();
   indent.addln('');
   root.classes.forEach(writeDataClassExtension);
   indent.writeln('');
diff --git a/packages/pigeon/lib/pigeon_lib.dart b/packages/pigeon/lib/pigeon_lib.dart
index dd31610..858518c 100644
--- a/packages/pigeon/lib/pigeon_lib.dart
+++ b/packages/pigeon/lib/pigeon_lib.dart
@@ -350,7 +350,7 @@
 
   @override
   IOSink? shouldGenerate(PigeonOptions options) {
-    if (options.dartTestOut != null && options.dartOut != null) {
+    if (options.dartTestOut != null) {
       return _openSink(options.dartTestOut);
     } else {
       return null;
diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml
index 594479f..f6da1f9 100644
--- a/packages/pigeon/pubspec.yaml
+++ b/packages/pigeon/pubspec.yaml
@@ -2,7 +2,7 @@
 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%3Apigeon
-version: 1.0.16 # This must match the version in lib/generator_tools.dart
+version: 1.0.17 # This must match the version in lib/generator_tools.dart
 
 environment:
   sdk: ">=2.12.0 <3.0.0"
diff --git a/packages/pigeon/test/objc_generator_test.dart b/packages/pigeon/test/objc_generator_test.dart
index 6ff4cce..f534441 100644
--- a/packages/pigeon/test/objc_generator_test.dart
+++ b/packages/pigeon/test/objc_generator_test.dart
@@ -111,7 +111,9 @@
     expect(code, contains('#import "foo.h"'));
     expect(code, contains('@implementation Foobar'));
     expect(
-        code, contains('pigeonResult.enum1 = [dict[@"enum1"] integerValue];'));
+        code,
+        contains(
+            'pigeonResult.enum1 = [GetNullableObject(dict, @"enum1") integerValue];'));
   });
 
   test('gen one class header with enum', () {
@@ -308,7 +310,8 @@
     generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink);
     final String code = sink.toString();
     expect(code, contains('@implementation Foobar'));
-    expect(code, contains('pigeonResult.aBool = dict[@"aBool"];'));
+    expect(code,
+        contains('pigeonResult.aBool = GetNullableObject(dict, @"aBool");'));
   });
 
   test('nested class header', () {
@@ -351,8 +354,10 @@
     final StringBuffer sink = StringBuffer();
     generateObjcSource(const ObjcOptions(header: 'foo.h'), root, sink);
     final String code = sink.toString();
-    expect(code,
-        contains('pigeonResult.nested = [Input fromMap:dict[@"nested"]];'));
+    expect(
+        code,
+        contains(
+            'pigeonResult.nested = [Input fromMap:GetNullableObject(dict, @"nested")];'));
     expect(code, matches('[self.nested toMap].*@"nested"'));
   });