f343c3ceb7
This splits cached expression by receiver type such that the initializing expression for a cached variable isn't stored in the late variable initializer, if it can be obtained in different ways. For instance having both a list pattern and a map pattern in the same switch will trigger caching of the .length property but obtaining expression differ base on the receiver type, in the first case List.length and in second case Map.length. Closes #51138 Closes #51140 Change-Id: Ic4d8ca394a872113114514f72274413b836fdfb5 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/280081 Reviewed-by: Chloe Stefantsova <cstefantsova@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
60 lines
2.5 KiB
Plaintext
60 lines
2.5 KiB
Plaintext
library /*isNonNullableByDefault*/;
|
|
import self as self;
|
|
import "dart:core" as core;
|
|
import "dart:_internal" as _in;
|
|
|
|
static method test1(dynamic x) → dynamic {
|
|
core::int y;
|
|
{
|
|
final dynamic #0#0 = x;
|
|
late final dynamic #0#6 = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
|
|
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int} =={core::num::==}{(core::Object) → core::bool} #C1 && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t1 = y = #0#6{core::int} in true))))
|
|
throw new _in::ReachabilityError::•();
|
|
}
|
|
return y;
|
|
}
|
|
static method test2(dynamic x) → dynamic {
|
|
core::String a;
|
|
core::String b;
|
|
{
|
|
final dynamic #0#0 = x;
|
|
late final core::int #0#2 = #0#0{core::List<dynamic>}.{core::List::length}{core::int};
|
|
late final dynamic #0#6 = #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
|
|
late final dynamic #0#7 = #0#0{core::List<dynamic>}.{core::List::[]}(#0#2.{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic};
|
|
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#2.{core::num::>=}(#C2){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::String && (let final dynamic #t2 = a = #0#6{core::String} in true)) && (#0#7 is{ForNonNullableByDefault} core::String && (let final dynamic #t3 = b = #0#7{core::String} in true))))
|
|
throw new _in::ReachabilityError::•();
|
|
}
|
|
return a.{core::String::+}(b){(core::String) → core::String};
|
|
}
|
|
static method main() → dynamic {
|
|
self::expectEquals(self::test1(<core::int>[0]), 0);
|
|
self::expectThrows(() → void => self::test1(<dynamic>[]));
|
|
self::expectThrows(() → void => self::test1(<core::int>[0, 1, 2]));
|
|
self::expectEquals(self::test2(<core::String>["one", "two", "three", "four"]), "onefour");
|
|
self::expectThrows(() → void => self::test2(<core::String>["one"]));
|
|
self::expectThrows(() → void => self::test2("one"));
|
|
self::expectThrows(() → void => self::test2(null));
|
|
}
|
|
static method expectEquals(dynamic x, dynamic y) → dynamic {
|
|
if(!(x =={core::Object::==}{(core::Object) → core::bool} y)) {
|
|
throw "Expected ${x} to be equal to ${y}.";
|
|
}
|
|
}
|
|
static method expectThrows(() → void f) → dynamic {
|
|
core::bool hasThrown = true;
|
|
try {
|
|
f(){() → void};
|
|
hasThrown = false;
|
|
}
|
|
on core::Object catch(final core::Object e) {
|
|
}
|
|
if(!hasThrown) {
|
|
throw "Expected function to throw.";
|
|
}
|
|
}
|
|
|
|
constants {
|
|
#C1 = 1
|
|
#C2 = 2
|
|
}
|