blob: f1bdfaf66e175b9eaa25e68db07f50cdcf4c05fc [file] [edit]
// Copyright (c) 2026, 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 file.
// Anonymous methods containing jumps.
// SharedOptions=--enable-experiment=anonymous-methods
import '../../static_type_helper.dart';
void testBreak() {
Object? o;
if (o is int || o is String); // Make them types of interest.
o = "a";
do {
o = 1;
break;
o = "b"; // ignore: dead_code
} while (false);
o.expectStaticType<Exactly<int>>;
o = "a";
do {
o = 1;
null.{ break; };
o = "b"; // ignore: dead_code
} while (false);
o.expectStaticType<Exactly<int>>;
o = "a";
do {
null.{
o = 1;
break;
o = "b"; // ignore: dead_code
};
} while (false);
o.expectStaticType<Exactly<int>>;
}
void testBreakL() {
Object? o;
if (o is int || o is String); // Make them types of interest.
o = "a";
L: {
o = 1;
break L;
o = "b"; // ignore: dead_code
}
o.expectStaticType<Exactly<int>>;
o = "a";
L: {
o = 1;
null.{ break L; };
o = "b"; // ignore: dead_code
}
o.expectStaticType<Exactly<int>>;
o = "a";
L: {
null.{
o = 1;
break L;
o = "b"; // ignore: dead_code
};
}
o.expectStaticType<Exactly<int>>;
o = "a";
L: null.{
o = 1;
break L;
o = "b"; // ignore: dead_code
};
o.expectStaticType<Exactly<int>>;
Iterable<Object?> f() sync* {
Object? o;
if (o is int || o is String);
o = "a";
L: yield null.{
o = 1;
break L;
o = "b"; // ignore: dead_code
};
o.expectStaticType<Exactly<int>>;
}
f().isEmpty;
}
void testContinue() {
Object? o;
bool doContinue = true;
if (o is int || o is String); // Make them types of interest.
o = "a";
do {
if (doContinue) {
doContinue = false;
continue;
} else {
break;
}
o = 1; // ignore: dead_code
} while (false);
// Loop flow analysis is conservative, so `o = 1` might have occurred.
o.expectStaticType<Exactly<Object?>>;
o = "a";
do {
if (doContinue) {
doContinue = false;
null.{ continue; };
} else {
null.{ break; };
}
o = 1; // ignore: dead_code
} while (false);
o.expectStaticType<Exactly<Object?>>;
o = "a";
do {
null.{
if (doContinue) {
doContinue = false;
continue;
} else {
break;
}
o = 1; // ignore: dead_code
};
} while (false);
o.expectStaticType<Exactly<Object?>>;
}
void testContinueL() {
Object? o;
bool doContinue = true;
if (o is int || o is String); // Make them types of interest.
o = "a";
L: do {
if (doContinue) {
doContinue = false;
continue L;
} else {
break;
}
o = 1; // ignore: dead_code
} while (false);
// Loop flow analysis is conservative, so `o = 1` might have occurred.
o.expectStaticType<Exactly<Object?>>;
o = "a";
L: do {
if (doContinue) {
doContinue = false;
null.{ continue L; };
} else {
null.{ break; };
}
o = 1; // ignore: dead_code
} while (false);
o.expectStaticType<Exactly<Object?>>;
o = "a";
L: do {
null.{
if (doContinue) {
doContinue = false;
continue L;
} else {
break;
}
o = 1; // ignore: dead_code
};
} while (false);
o.expectStaticType<Exactly<Object?>>;
o = "a";
L: do {
do {
if (doContinue) {
doContinue = false;
continue L;
} else {
break L;
}
} while (false);
o = 1; // ignore: dead_code
} while (false);
// Loop flow analysis is conservative, so `o = 1` might have occurred.
o.expectStaticType<Exactly<Object?>>;
o = "a";
L: do {
do {
if (doContinue) {
doContinue = false;
null.{ continue L; };
} else {
null.{ break L; };
}
} while (false);
o = 1; // ignore: dead_code
} while (false);
o.expectStaticType<Exactly<Object?>>;
o = "a";
L: do {
do {
null.{
if (doContinue) {
doContinue = false;
continue L;
} else {
break L;
}
};
} while (false);
o = 1; // ignore: dead_code
} while (false);
o.expectStaticType<Exactly<Object?>>;
}
void main() {
testBreak();
testBreakL();
testContinue();
testContinueL();
}