mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 03:47:13 +00:00
[cfe] Add basic support for pattern-for-in loops
Part of https://github.com/dart-lang/sdk/issues/49749 Change-Id: I7becfa2ef558fb483716d7d1bc195d858cc69094 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/281660 Commit-Queue: Chloe Stefantsova <cstefantsova@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
parent
a66dcf1b77
commit
85c2bd891b
|
@ -6980,10 +6980,34 @@ class BodyBuilder extends StackListenerImpl
|
|||
@override
|
||||
void handleForInLoopParts(Token? awaitToken, Token forToken,
|
||||
Token leftParenthesis, Token? patternKeyword, Token inKeyword) {
|
||||
if (patternKeyword != null) {
|
||||
throw new UnimplementedError(
|
||||
'TODO(paulberry): handle pattern in for-in loop');
|
||||
debugEvent("ForIntLoopParts");
|
||||
assert(checkState(forToken, [
|
||||
unionOfKinds([
|
||||
ValueKinds.Expression,
|
||||
ValueKinds.Generator,
|
||||
ValueKinds.ProblemBuilder,
|
||||
]),
|
||||
unionOfKinds([
|
||||
ValueKinds.Expression,
|
||||
ValueKinds.Generator,
|
||||
ValueKinds.ProblemBuilder,
|
||||
ValueKinds.Pattern,
|
||||
ValueKinds.Statement, // Variable for non-pattern for-in loop.
|
||||
]),
|
||||
]));
|
||||
Object expression = pop() as Object;
|
||||
Object pattern = pop() as Object;
|
||||
|
||||
if (pattern is Pattern) {
|
||||
pop(); // Metadata.
|
||||
for (VariableDeclaration variable in pattern.declaredVariables) {
|
||||
declareVariable(variable, scope);
|
||||
typeInferrer.assignedVariables.declare(variable);
|
||||
}
|
||||
}
|
||||
|
||||
push(pattern);
|
||||
push(expression);
|
||||
push(awaitToken ?? NullValues.AwaitToken);
|
||||
push(forToken);
|
||||
push(inKeyword);
|
||||
|
@ -7090,6 +7114,21 @@ class BodyBuilder extends StackListenerImpl
|
|||
new VariableGetImpl(variable, forNullGuardedAccess: false)
|
||||
..fileOffset = inToken.offset,
|
||||
voidContext: true);
|
||||
} else if (lvalue is Pattern) {
|
||||
/// We are in the case where `lvalue` is a pattern:
|
||||
///
|
||||
/// for (pattern in expression) body
|
||||
///
|
||||
/// This is normalized to:
|
||||
///
|
||||
/// for (final #t in expression) {
|
||||
/// pattern = #t;
|
||||
/// body;
|
||||
/// }
|
||||
elements.syntheticAssignment = null;
|
||||
elements.expressionEffects = new PatternVariableDeclaration(
|
||||
lvalue, new VariableGetImpl(variable, forNullGuardedAccess: false),
|
||||
fileOffset: inToken.offset, isFinal: false);
|
||||
} else {
|
||||
Message message = forest.isVariablesDeclaration(lvalue)
|
||||
? fasta.messageForInLoopExactlyOneVariable
|
||||
|
@ -7123,6 +7162,24 @@ class BodyBuilder extends StackListenerImpl
|
|||
@override
|
||||
void endForIn(Token endToken) {
|
||||
debugEvent("ForIn");
|
||||
assert(checkState(endToken, [
|
||||
/* body= */ ValueKinds.Statement,
|
||||
/* inKeyword = */ ValueKinds.Token,
|
||||
/* forToken = */ ValueKinds.Token,
|
||||
/* awaitToken = */ ValueKinds.AwaitTokenOrNull,
|
||||
/* expression = */ unionOfKinds([
|
||||
ValueKinds.Expression,
|
||||
ValueKinds.Generator,
|
||||
ValueKinds.ProblemBuilder,
|
||||
]),
|
||||
/* lvalue = */ unionOfKinds([
|
||||
ValueKinds.Expression,
|
||||
ValueKinds.Generator,
|
||||
ValueKinds.ProblemBuilder,
|
||||
ValueKinds.Pattern,
|
||||
ValueKinds.Statement,
|
||||
]),
|
||||
]));
|
||||
Statement body = popStatement();
|
||||
|
||||
Token inKeyword = pop() as Token;
|
||||
|
|
|
@ -60,6 +60,8 @@ class ValueKinds {
|
|||
const SingleValueKind<type.AsyncMarker>();
|
||||
static const ValueKind AsyncModifier =
|
||||
const SingleValueKind<type.AsyncMarker>();
|
||||
static const ValueKind AwaitTokenOrNull =
|
||||
const SingleValueKind<type.Token>(NullValues.AwaitToken);
|
||||
static const ValueKind BreakTarget =
|
||||
const SingleValueKind<type.JumpTarget>(NullValues.BreakTarget);
|
||||
static const ValueKind Bool = const SingleValueKind<bool>();
|
||||
|
|
|
@ -71,6 +71,24 @@ class LocalForInVariable implements ForInVariable {
|
|||
}
|
||||
}
|
||||
|
||||
class PatternVariableDeclarationForInVariable implements ForInVariable {
|
||||
PatternVariableDeclaration patternVariableDeclaration;
|
||||
|
||||
PatternVariableDeclarationForInVariable(this.patternVariableDeclaration);
|
||||
|
||||
@override
|
||||
DartType computeElementType(InferenceVisitorBase visitor) {
|
||||
return (patternVariableDeclaration.initializer as VariableGet)
|
||||
.variable
|
||||
.type;
|
||||
}
|
||||
|
||||
@override
|
||||
Expression? inferAssignment(InferenceVisitorBase visitor, DartType rhsType) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class PropertyForInVariable implements ForInVariable {
|
||||
final PropertySet propertySet;
|
||||
|
||||
|
|
|
@ -1517,8 +1517,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
return new ExpressionInferenceResult(inferredType, iterable);
|
||||
}
|
||||
|
||||
ForInVariable computeForInVariable(
|
||||
Expression? syntheticAssignment, bool hasProblem) {
|
||||
ForInVariable computeForInVariable(Expression? syntheticAssignment,
|
||||
Statement? expressionEffects, bool hasProblem) {
|
||||
if (syntheticAssignment is VariableSet) {
|
||||
return new LocalForInVariable(syntheticAssignment);
|
||||
} else if (syntheticAssignment is PropertySet) {
|
||||
|
@ -1531,6 +1531,9 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
return new StaticForInVariable(syntheticAssignment);
|
||||
} else if (syntheticAssignment is InvalidExpression || hasProblem) {
|
||||
return new InvalidForInVariable(syntheticAssignment);
|
||||
} else if (syntheticAssignment == null &&
|
||||
expressionEffects is PatternVariableDeclaration) {
|
||||
return new PatternVariableDeclarationForInVariable(expressionEffects);
|
||||
} else {
|
||||
UriOffset uriOffset = _computeUriOffset(syntheticAssignment!);
|
||||
return problems.unhandled(
|
||||
|
@ -1551,8 +1554,8 @@ class InferenceVisitorImpl extends InferenceVisitorBase
|
|||
required bool hasProblem}) {
|
||||
// ignore: unnecessary_null_comparison
|
||||
assert(hasProblem != null);
|
||||
ForInVariable forInVariable =
|
||||
computeForInVariable(syntheticAssignment, hasProblem);
|
||||
ForInVariable forInVariable = computeForInVariable(
|
||||
syntheticAssignment, expressionEffects, hasProblem);
|
||||
DartType elementType = forInVariable.computeElementType(this);
|
||||
ExpressionInferenceResult iterableResult =
|
||||
inferForInIterable(iterable, elementType, isAsync: isAsync);
|
||||
|
|
50
pkg/front_end/testcases/patterns/simple_pattern_for_in.dart
Normal file
50
pkg/front_end/testcases/patterns/simple_pattern_for_in.dart
Normal file
|
@ -0,0 +1,50 @@
|
|||
test1(dynamic x) {
|
||||
for (var [int y] in x) {
|
||||
if (y % 10 == 0) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
test2(Iterable<List<String>> x) {
|
||||
for (var [..., String y] in x) {
|
||||
if (y.startsWith("f")) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
test3(Iterable<dynamic> x) {
|
||||
for (var [int y, ...] in x) {
|
||||
return y;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
main() {
|
||||
expectEquals(test1([[1], [2], [3]]), -1);
|
||||
expectEquals(test1([[1], [2], [30]]), 30);
|
||||
expectEquals(test2([["foo", "bar", "baz"], ["bar", "foo", "baz"], ["bar", "baz", "foo"]]), "foo");
|
||||
expectEquals(test2([]), "");
|
||||
expectThrows(() => test3([[null, 1, 2]]));
|
||||
expectEquals(test3([]), -1);
|
||||
}
|
||||
|
||||
expectEquals(x, y) {
|
||||
if (x != y) {
|
||||
throw "Expected '${x}' to be equal to '${y}'.";
|
||||
}
|
||||
}
|
||||
|
||||
expectThrows(void Function() f) {
|
||||
bool hasThrown = true;
|
||||
try {
|
||||
f();
|
||||
hasThrown = false;
|
||||
} catch (e) {}
|
||||
if (!hasThrown) {
|
||||
throw "Expected function to throw.";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
static method test1(dynamic x) → dynamic {
|
||||
for (final dynamic #t1 in x as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t1;
|
||||
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 #t2 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::num::%}(10){(core::num) → core::int} =={core::num::==}{(core::Object) → core::bool} 0) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method test2(core::Iterable<core::List<core::String>> x) → dynamic {
|
||||
for (final core::List<core::String> #t3 in x) {
|
||||
core::String y;
|
||||
{
|
||||
final dynamic #0#0 = #t3;
|
||||
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#2.{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic};
|
||||
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#2.{core::num::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::String && (let final dynamic #t4 = y = #0#6{core::String} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::String::startsWith}("f"){(core::Pattern, [core::int]) → core::bool}) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static method test3(core::Iterable<dynamic> x) → dynamic {
|
||||
for (final dynamic #t5 in x) {
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t5;
|
||||
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::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t6 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
return y;
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::expectEquals(self::test1(<core::List<core::int>>[<core::int>[1], <core::int>[2], <core::int>[3]]), 1.{core::int::unary-}(){() → core::int});
|
||||
self::expectEquals(self::test1(<core::List<core::int>>[<core::int>[1], <core::int>[2], <core::int>[30]]), 30);
|
||||
self::expectEquals(self::test2(<core::List<core::String>>[<core::String>["foo", "bar", "baz"], <core::String>["bar", "foo", "baz"], <core::String>["bar", "baz", "foo"]]), "foo");
|
||||
self::expectEquals(self::test2(<core::List<core::String>>[]), "");
|
||||
self::expectThrows(() → void => self::test3(<dynamic>[<core::int?>[null, 1, 2]]));
|
||||
self::expectEquals(self::test3(<dynamic>[]), 1.{core::int::unary-}(){() → core::int});
|
||||
}
|
||||
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
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
static method test1(dynamic x) → dynamic {
|
||||
{
|
||||
core::Iterator<dynamic> :sync-for-iterator = (x as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
|
||||
for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
|
||||
final dynamic #t1 = :sync-for-iterator.{core::Iterator::current}{dynamic};
|
||||
{
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t1;
|
||||
function ##0#6#initializer() → dynamic
|
||||
return #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
|
||||
late final dynamic #0#6 = ##0#6#initializer(){() → 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 core::int #t2 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::num::%}(10){(core::num) → core::int} =={core::num::==}{(core::Object) → core::bool} 0) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method test2(core::Iterable<core::List<core::String>> x) → dynamic {
|
||||
{
|
||||
core::Iterator<core::List<core::String>> :sync-for-iterator = x.{core::Iterable::iterator}{core::Iterator<core::List<core::String>>};
|
||||
for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
|
||||
final core::List<core::String> #t3 = :sync-for-iterator.{core::Iterator::current}{core::List<core::String>};
|
||||
{
|
||||
core::String y;
|
||||
{
|
||||
final dynamic #0#0 = #t3;
|
||||
function ##0#2#initializer() → core::int
|
||||
return #0#0{core::List<dynamic>}.{core::List::length}{core::int};
|
||||
late final core::int #0#2 = ##0#2#initializer(){() → core::int};
|
||||
function ##0#6#initializer() → dynamic
|
||||
return #0#0{core::List<dynamic>}.{core::List::[]}(#0#2.{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic};
|
||||
late final dynamic #0#6 = ##0#6#initializer(){() → dynamic};
|
||||
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#2.{core::num::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::String && (let final core::String #t4 = y = #0#6{core::String} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::String::startsWith}("f"){(core::Pattern, [core::int]) → core::bool}) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static method test3(core::Iterable<dynamic> x) → dynamic {
|
||||
{
|
||||
core::Iterator<dynamic> :sync-for-iterator = x.{core::Iterable::iterator}{core::Iterator<dynamic>};
|
||||
for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
|
||||
final dynamic #t5 = :sync-for-iterator.{core::Iterator::current}{dynamic};
|
||||
{
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t5;
|
||||
function ##0#6#initializer() → dynamic
|
||||
return #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
|
||||
late final dynamic #0#6 = ##0#6#initializer(){() → dynamic};
|
||||
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::int && (let final core::int #t6 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
return y;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::expectEquals(self::test1(core::_GrowableList::_literal3<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(1), core::_GrowableList::_literal1<core::int>(2), core::_GrowableList::_literal1<core::int>(3))), 1.{core::int::unary-}(){() → core::int});
|
||||
self::expectEquals(self::test1(core::_GrowableList::_literal3<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(1), core::_GrowableList::_literal1<core::int>(2), core::_GrowableList::_literal1<core::int>(30))), 30);
|
||||
self::expectEquals(self::test2(core::_GrowableList::_literal3<core::List<core::String>>(core::_GrowableList::_literal3<core::String>("foo", "bar", "baz"), core::_GrowableList::_literal3<core::String>("bar", "foo", "baz"), core::_GrowableList::_literal3<core::String>("bar", "baz", "foo"))), "foo");
|
||||
self::expectEquals(self::test2(core::_GrowableList::•<core::List<core::String>>(0)), "");
|
||||
self::expectThrows(() → void => self::test3(core::_GrowableList::_literal1<dynamic>(core::_GrowableList::_literal3<core::int?>(null, 1, 2))));
|
||||
self::expectEquals(self::test3(core::_GrowableList::•<dynamic>(0)), 1.{core::int::unary-}(){() → core::int});
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated: InstanceInvocation @ org-dartlang-testcase:///simple_pattern_for_in.dart:7:10 -> IntConstant(-1)
|
||||
Evaluated: InstanceInvocation @ org-dartlang-testcase:///simple_pattern_for_in.dart:23:10 -> IntConstant(-1)
|
||||
Evaluated: InstanceInvocation @ org-dartlang-testcase:///simple_pattern_for_in.dart:27:40 -> IntConstant(-1)
|
||||
Evaluated: InstanceInvocation @ org-dartlang-testcase:///simple_pattern_for_in.dart:32:27 -> IntConstant(-1)
|
||||
Extra constant evaluation: evaluated: 138, effectively constant: 4
|
|
@ -0,0 +1,6 @@
|
|||
test1(dynamic x) {}
|
||||
test2(Iterable<List<String>> x) {}
|
||||
test3(Iterable<dynamic> x) {}
|
||||
main() {}
|
||||
expectEquals(x, y) {}
|
||||
expectThrows(void Function() f) {}
|
|
@ -0,0 +1,6 @@
|
|||
expectEquals(x, y) {}
|
||||
expectThrows(void Function() f) {}
|
||||
main() {}
|
||||
test1(dynamic x) {}
|
||||
test2(Iterable<List<String>> x) {}
|
||||
test3(Iterable<dynamic> x) {}
|
|
@ -0,0 +1,78 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
static method test1(dynamic x) → dynamic {
|
||||
for (final dynamic #t1 in x as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t1;
|
||||
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 #t2 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::num::%}(10){(core::num) → core::int} =={core::num::==}{(core::Object) → core::bool} 0) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method test2(core::Iterable<core::List<core::String>> x) → dynamic {
|
||||
for (final core::List<core::String> #t3 in x) {
|
||||
core::String y;
|
||||
{
|
||||
final dynamic #0#0 = #t3;
|
||||
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#2.{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic};
|
||||
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#2.{core::num::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::String && (let final dynamic #t4 = y = #0#6{core::String} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::String::startsWith}("f"){(core::Pattern, [core::int]) → core::bool}) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static method test3(core::Iterable<dynamic> x) → dynamic {
|
||||
for (final dynamic #t5 in x) {
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t5;
|
||||
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::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t6 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
return y;
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::expectEquals(self::test1(<core::List<core::int>>[<core::int>[1], <core::int>[2], <core::int>[3]]), 1.{core::int::unary-}(){() → core::int});
|
||||
self::expectEquals(self::test1(<core::List<core::int>>[<core::int>[1], <core::int>[2], <core::int>[30]]), 30);
|
||||
self::expectEquals(self::test2(<core::List<core::String>>[<core::String>["foo", "bar", "baz"], <core::String>["bar", "foo", "baz"], <core::String>["bar", "baz", "foo"]]), "foo");
|
||||
self::expectEquals(self::test2(<core::List<core::String>>[]), "");
|
||||
self::expectThrows(() → void => self::test3(<dynamic>[<core::int?>[null, 1, 2]]));
|
||||
self::expectEquals(self::test3(<dynamic>[]), 1.{core::int::unary-}(){() → core::int});
|
||||
}
|
||||
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
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
static method test1(dynamic x) → dynamic {
|
||||
for (final dynamic #t1 in x as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>) {
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t1;
|
||||
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 #t2 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::num::%}(10){(core::num) → core::int} =={core::num::==}{(core::Object) → core::bool} 0) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method test2(core::Iterable<core::List<core::String>> x) → dynamic {
|
||||
for (final core::List<core::String> #t3 in x) {
|
||||
core::String y;
|
||||
{
|
||||
final dynamic #0#0 = #t3;
|
||||
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#2.{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic};
|
||||
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#2.{core::num::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::String && (let final dynamic #t4 = y = #0#6{core::String} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::String::startsWith}("f"){(core::Pattern, [core::int]) → core::bool}) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static method test3(core::Iterable<dynamic> x) → dynamic {
|
||||
for (final dynamic #t5 in x) {
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t5;
|
||||
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::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::int && (let final dynamic #t6 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
return y;
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::expectEquals(self::test1(<core::List<core::int>>[<core::int>[1], <core::int>[2], <core::int>[3]]), 1.{core::int::unary-}(){() → core::int});
|
||||
self::expectEquals(self::test1(<core::List<core::int>>[<core::int>[1], <core::int>[2], <core::int>[30]]), 30);
|
||||
self::expectEquals(self::test2(<core::List<core::String>>[<core::String>["foo", "bar", "baz"], <core::String>["bar", "foo", "baz"], <core::String>["bar", "baz", "foo"]]), "foo");
|
||||
self::expectEquals(self::test2(<core::List<core::String>>[]), "");
|
||||
self::expectThrows(() → void => self::test3(<dynamic>[<core::int?>[null, 1, 2]]));
|
||||
self::expectEquals(self::test3(<dynamic>[]), 1.{core::int::unary-}(){() → core::int});
|
||||
}
|
||||
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
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static method test1(dynamic x) → dynamic
|
||||
;
|
||||
static method test2(core::Iterable<core::List<core::String>> x) → dynamic
|
||||
;
|
||||
static method test3(core::Iterable<dynamic> x) → dynamic
|
||||
;
|
||||
static method main() → dynamic
|
||||
;
|
||||
static method expectEquals(dynamic x, dynamic y) → dynamic
|
||||
;
|
||||
static method expectThrows(() → void f) → dynamic
|
||||
;
|
|
@ -0,0 +1,111 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
import "dart:_internal" as _in;
|
||||
|
||||
static method test1(dynamic x) → dynamic {
|
||||
{
|
||||
core::Iterator<dynamic> :sync-for-iterator = (x as{TypeError,ForDynamic,ForNonNullableByDefault} core::Iterable<dynamic>).{core::Iterable::iterator}{core::Iterator<dynamic>};
|
||||
for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
|
||||
final dynamic #t1 = :sync-for-iterator.{core::Iterator::current}{dynamic};
|
||||
{
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t1;
|
||||
function ##0#6#initializer() → dynamic
|
||||
return #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
|
||||
late final dynamic #0#6 = ##0#6#initializer(){() → 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 core::int #t2 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::num::%}(10){(core::num) → core::int} =={core::num::==}{(core::Object) → core::bool} 0) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method test2(core::Iterable<core::List<core::String>> x) → dynamic {
|
||||
{
|
||||
core::Iterator<core::List<core::String>> :sync-for-iterator = x.{core::Iterable::iterator}{core::Iterator<core::List<core::String>>};
|
||||
for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
|
||||
final core::List<core::String> #t3 = :sync-for-iterator.{core::Iterator::current}{core::List<core::String>};
|
||||
{
|
||||
core::String y;
|
||||
{
|
||||
final dynamic #0#0 = #t3;
|
||||
function ##0#2#initializer() → core::int
|
||||
return #0#0{core::List<dynamic>}.{core::List::length}{core::int};
|
||||
late final core::int #0#2 = ##0#2#initializer(){() → core::int};
|
||||
function ##0#6#initializer() → dynamic
|
||||
return #0#0{core::List<dynamic>}.{core::List::[]}(#0#2.{core::num::-}(1){(core::num) → core::int}){(core::int) → dynamic};
|
||||
late final dynamic #0#6 = ##0#6#initializer(){() → dynamic};
|
||||
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#2.{core::num::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::String && (let final core::String #t4 = y = #0#6{core::String} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
if(y.{core::String::startsWith}("f"){(core::Pattern, [core::int]) → core::bool}) {
|
||||
return y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
static method test3(core::Iterable<dynamic> x) → dynamic {
|
||||
{
|
||||
core::Iterator<dynamic> :sync-for-iterator = x.{core::Iterable::iterator}{core::Iterator<dynamic>};
|
||||
for (; :sync-for-iterator.{core::Iterator::moveNext}(){() → core::bool}; ) {
|
||||
final dynamic #t5 = :sync-for-iterator.{core::Iterator::current}{dynamic};
|
||||
{
|
||||
core::int y;
|
||||
{
|
||||
final dynamic #0#0 = #t5;
|
||||
function ##0#6#initializer() → dynamic
|
||||
return #0#0{core::List<dynamic>}.{core::List::[]}(0){(core::int) → dynamic};
|
||||
late final dynamic #0#6 = ##0#6#initializer(){() → dynamic};
|
||||
if(!(#0#0 is{ForNonNullableByDefault} core::List<dynamic> && #0#0{core::List<dynamic>}.{core::List::length}{core::int}.{core::num::>=}(#C1){(core::num) → core::bool} && (#0#6 is{ForNonNullableByDefault} core::int && (let final core::int #t6 = y = #0#6{core::int} in true))))
|
||||
throw new _in::ReachabilityError::•();
|
||||
}
|
||||
return y;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1.{core::int::unary-}(){() → core::int};
|
||||
}
|
||||
static method main() → dynamic {
|
||||
self::expectEquals(self::test1(core::_GrowableList::_literal3<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(1), core::_GrowableList::_literal1<core::int>(2), core::_GrowableList::_literal1<core::int>(3))), 1.{core::int::unary-}(){() → core::int});
|
||||
self::expectEquals(self::test1(core::_GrowableList::_literal3<core::List<core::int>>(core::_GrowableList::_literal1<core::int>(1), core::_GrowableList::_literal1<core::int>(2), core::_GrowableList::_literal1<core::int>(30))), 30);
|
||||
self::expectEquals(self::test2(core::_GrowableList::_literal3<core::List<core::String>>(core::_GrowableList::_literal3<core::String>("foo", "bar", "baz"), core::_GrowableList::_literal3<core::String>("bar", "foo", "baz"), core::_GrowableList::_literal3<core::String>("bar", "baz", "foo"))), "foo");
|
||||
self::expectEquals(self::test2(core::_GrowableList::•<core::List<core::String>>(0)), "");
|
||||
self::expectThrows(() → void => self::test3(core::_GrowableList::_literal1<dynamic>(core::_GrowableList::_literal3<core::int?>(null, 1, 2))));
|
||||
self::expectEquals(self::test3(core::_GrowableList::•<dynamic>(0)), 1.{core::int::unary-}(){() → core::int});
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
Extra constant evaluation status:
|
||||
Evaluated: InstanceInvocation @ org-dartlang-testcase:///simple_pattern_for_in.dart:7:10 -> IntConstant(-1)
|
||||
Evaluated: InstanceInvocation @ org-dartlang-testcase:///simple_pattern_for_in.dart:23:10 -> IntConstant(-1)
|
||||
Evaluated: InstanceInvocation @ org-dartlang-testcase:///simple_pattern_for_in.dart:27:40 -> IntConstant(-1)
|
||||
Evaluated: InstanceInvocation @ org-dartlang-testcase:///simple_pattern_for_in.dart:32:27 -> IntConstant(-1)
|
||||
Extra constant evaluation: evaluated: 138, effectively constant: 4
|
Loading…
Reference in a new issue