[cfe] Make widget transform location field nullable

The widget transformer doesn't handle widgets with optional positional
parameters and therefore doesn't provide locations in these cases.
For this reason we leave the location field nullable and don't null check
it on construction.

Close #43371

Change-Id: I2595eb215e8fab477ab0819b70e25d9fb921ed01
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/162187
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.1.expect
index b4fad46..772111a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.1.expect
@@ -9,7 +9,7 @@
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field wid::_Location? _location /*isNullableByDefault, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
-      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4!
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.2.expect
index b6f2a14..fa8d466 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.2.expect
@@ -9,7 +9,7 @@
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field wid::_Location? _location /*isNullableByDefault, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
-      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4!
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.3.expect
index b4fad46..772111a 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_const.yaml.world.3.expect
@@ -9,7 +9,7 @@
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field wid::_Location? _location /*isNullableByDefault, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
-      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4!
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.1.expect
index cf1b295..451ec20 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.1.expect
@@ -9,7 +9,7 @@
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field wid::_Location? _location /*isNullableByDefault, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
-      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4!
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.2.expect
index c2ce924..b996249 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transform_nnbd.yaml.world.2.expect
@@ -9,7 +9,7 @@
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field wid::_Location? _location /*isNullableByDefault, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
-      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4!
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml
new file mode 100644
index 0000000..0813f0a
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml
@@ -0,0 +1,82 @@
+# Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE.md file.
+
+type: newworld
+target: DDC
+trackWidgetCreation: true
+worlds:
+  - entry: main.dart
+    experiments: non-nullable
+    sources:
+      main.dart: |
+        // @dart=2.8
+        import 'foo.dart';
+      foo.dart: |
+        // @dart=2.8
+        import 'package:flutter/src/widgets/framework.dart';
+        import 'package:flutter/src/widgets/widget_inspector.dart';
+
+        class Foo extends StatelessWidget {
+          const Foo([Object key]) : super(key: key);
+        }
+      flutter/lib/src/widgets/framework.dart: |
+        abstract class Bar {
+          const Bar();
+        }
+        abstract class Widget extends Bar {
+          final Object? key;
+
+          const Widget({this.key});
+        }
+        abstract class StatelessWidget extends Widget {
+          const StatelessWidget({Object? key}) : super(key: key);
+        }
+      flutter/lib/src/widgets/widget_inspector.dart: |
+        abstract class _HasCreationLocation {
+          _Location get _location;
+        }
+        /// A tuple with file, line, and column number, for displaying human-readable
+        /// file locations.
+        class _Location {
+          const _Location({
+            required this.file,
+            required this.line,
+            required this.column,
+            required this.name,
+            required this.parameterLocations,
+          });
+          /// File path of the location.
+          final String file;
+          /// 1-based line number.
+          final int line;
+          /// 1-based column number.
+          final int column;
+          /// Optional name of the parameter or function at this location.
+          final String name;
+          /// Optional locations of the parameters of the member at this location.
+          final List<_Location> parameterLocations;
+        }
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "flutter",
+              "rootUri": "../flutter",
+              "packageUri": "lib/"
+            }
+          ]
+        }
+    expectedLibraryCount: 4
+  - entry: main.dart
+    worldType: updated
+    invalidate:
+      - main.dart
+    expectInitializeFromDill: false
+    sources:
+      main.dart: |
+        // @dart=2.8
+        import 'foo.dart';
+        Foo foo = const Foo();
+    expectedLibraryCount: 4
\ No newline at end of file
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.1.expect
new file mode 100644
index 0000000..c8ff76f
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.1.expect
@@ -0,0 +1,65 @@
+main = <No Member>;
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+  abstract class Bar extends dart.core::Object /*hasConstConstructor*/  {
+    const constructor •() → fra::Bar
+      : super dart.core::Object::•()
+      ;
+  }
+  abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
+    final field dart.core::Object? key;
+    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    const constructor •({dart.core::Object? key = #C1, wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
+      : fra::Widget::key = key, super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
+      ;
+  }
+  abstract class StatelessWidget extends fra::Widget /*hasConstConstructor*/  {
+    const constructor •({dart.core::Object? key = #C1, wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::StatelessWidget
+      : super fra::Widget::•(key: key, $creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
+      ;
+  }
+}
+library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
+
+  abstract class _HasCreationLocation extends dart.core::Object {
+    synthetic constructor •() → wid::_HasCreationLocation
+      : super dart.core::Object::•()
+      ;
+    abstract get _location() → wid::_Location;
+  }
+  class _Location extends dart.core::Object /*hasConstConstructor*/  {
+    final field dart.core::String file;
+    final field dart.core::int line;
+    final field dart.core::int column;
+    final field dart.core::String name;
+    final field dart.core::List<wid::_Location> parameterLocations;
+    const constructor •({required dart.core::String file = #C1, required dart.core::int line = #C1, required dart.core::int column = #C1, required dart.core::String name = #C1, required dart.core::List<wid::_Location> parameterLocations = #C1}) → wid::_Location
+      : wid::_Location::file = file, wid::_Location::line = line, wid::_Location::column = column, wid::_Location::name = name, wid::_Location::parameterLocations = parameterLocations, super dart.core::Object::•()
+      ;
+  }
+}
+library from "org-dartlang-test:///foo.dart" as foo {
+
+  import "package:flutter/src/widgets/framework.dart";
+  import "package:flutter/src/widgets/widget_inspector.dart";
+
+  class Foo extends fra::StatelessWidget /*hasConstConstructor*/  {
+    const constructor •([dart.core::Object* key = #C1]) → foo::Foo*
+      : super fra::StatelessWidget::•(key: key)
+      ;
+    abstract member-signature get key() → dart.core::Object*; -> fra::Widget::key
+    abstract member-signature operator ==(dynamic other) → dart.core::bool*; -> dart.core::Object::==
+    abstract member-signature get hashCode() → dart.core::int*; -> dart.core::Object::hashCode
+    abstract member-signature method toString() → dart.core::String*; -> dart.core::Object::toString
+    abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
+    abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
+  }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+  import "org-dartlang-test:///foo.dart";
+
+}
+constants  {
+  #C1 = null
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.2.expect
new file mode 100644
index 0000000..a05b0cf
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_43371.yaml.world.2.expect
@@ -0,0 +1,67 @@
+main = <No Member>;
+library from "package:flutter/src/widgets/framework.dart" as fra {
+
+  abstract class Bar extends dart.core::Object /*hasConstConstructor*/  {
+    const constructor •() → fra::Bar
+      : super dart.core::Object::•()
+      ;
+  }
+  abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
+    final field dart.core::Object? key;
+    final field wid::_Location? _location /*isNullableByDefault, from null */;
+    const constructor •({dart.core::Object? key = #C1, wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
+      : fra::Widget::key = key, super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
+      ;
+  }
+  abstract class StatelessWidget extends fra::Widget /*hasConstConstructor*/  {
+    const constructor •({dart.core::Object? key = #C1, wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::StatelessWidget
+      : super fra::Widget::•(key: key, $creationLocationd_0dea112b090073317d4: $creationLocationd_0dea112b090073317d4)
+      ;
+  }
+}
+library from "package:flutter/src/widgets/widget_inspector.dart" as wid {
+
+  abstract class _HasCreationLocation extends dart.core::Object {
+    synthetic constructor •() → wid::_HasCreationLocation
+      : super dart.core::Object::•()
+      ;
+    abstract get _location() → wid::_Location;
+  }
+  class _Location extends dart.core::Object /*hasConstConstructor*/  {
+    final field dart.core::String file;
+    final field dart.core::int line;
+    final field dart.core::int column;
+    final field dart.core::String name;
+    final field dart.core::List<wid::_Location> parameterLocations;
+    const constructor •({required dart.core::String file = #C1, required dart.core::int line = #C1, required dart.core::int column = #C1, required dart.core::String name = #C1, required dart.core::List<wid::_Location> parameterLocations = #C1}) → wid::_Location
+      : wid::_Location::file = file, wid::_Location::line = line, wid::_Location::column = column, wid::_Location::name = name, wid::_Location::parameterLocations = parameterLocations, super dart.core::Object::•()
+      ;
+  }
+}
+library from "org-dartlang-test:///foo.dart" as foo {
+
+  import "package:flutter/src/widgets/framework.dart";
+  import "package:flutter/src/widgets/widget_inspector.dart";
+
+  class Foo extends fra::StatelessWidget /*hasConstConstructor*/  {
+    const constructor •([dart.core::Object* key = #C1]) → foo::Foo*
+      : super fra::StatelessWidget::•(key: key)
+      ;
+    abstract member-signature get key() → dart.core::Object*; -> fra::Widget::key
+    abstract member-signature operator ==(dynamic other) → dart.core::bool*; -> dart.core::Object::==
+    abstract member-signature get hashCode() → dart.core::int*; -> dart.core::Object::hashCode
+    abstract member-signature method toString() → dart.core::String*; -> dart.core::Object::toString
+    abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
+    abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
+  }
+}
+library from "org-dartlang-test:///main.dart" as main {
+
+  import "org-dartlang-test:///foo.dart";
+
+  static field foo::Foo* foo = #C2;
+}
+constants  {
+  #C1 = null
+  #C2 = foo::Foo {key:#C1, _location:#C1}
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.1.expect
index ad57ba5..99f8ec3 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.1.expect
@@ -9,7 +9,7 @@
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field wid::_Location? _location /*isNullableByDefault, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
-      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4!
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
   }
 }
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.2.expect
index 1990ba5..26c487d 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/flutter_widget_transformer_non_const.yaml.world.2.expect
@@ -9,7 +9,7 @@
   abstract class Widget extends fra::Bar implements wid::_HasCreationLocation /*hasConstConstructor*/  {
     final field wid::_Location? _location /*isNullableByDefault, from null */;
     const constructor •({wid::_Location? $creationLocationd_0dea112b090073317d4}) → fra::Widget
-      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4!
+      : super fra::Bar::•(), fra::Widget::_location = $creationLocationd_0dea112b090073317d4
       ;
   }
 }
diff --git a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
index 5e18e6f..5cc3962 100644
--- a/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
+++ b/pkg/kernel/lib/transformations/track_widget_constructor_locations.dart
@@ -424,14 +424,8 @@
         }
       }
       if (!hasRedirectingInitializer) {
-        constructor.initializers.add(new FieldInitializer(
-          locationField,
-          clazz.enclosingLibrary.isNonNullableByDefault
-              // The parameter is nullable so that it can be optional but the
-              // field is non-nullable so we check it here.
-              ? new NullCheck(new VariableGet(variable))
-              : new VariableGet(variable),
-        ));
+        constructor.initializers.add(
+            new FieldInitializer(locationField, new VariableGet(variable)));
         // TODO(jacobr): add an assert verifying the locationField is not
         // null. Currently, we cannot safely add this assert because we do not
         // handle Widget classes with optional positional arguments. There are