mirror of
https://github.com/dart-lang/sdk
synced 2024-10-01 19:19:16 +00:00
Add nonNulls
, indexed
and other extensions on iterables.
Also adds `firstOrNull`, `lastOrNull`, `singleOrNull`, and `elementAtOrNull`. I chose `nonNulls` instead of `whereNotNull()`. The latter should have been a getter, but isn't. Making it a getter in the platform libraries would be confusing, and make migrating from `package:collection`'s function harder, so instead I gave it a completely new name. The alternative would be to retain the non-idiomatic `whereNotNull()` for familiarity. But then it would be tool late to fix. Fixes #49928 BUG= https://github.com/dart-lang/sdk/issues/49928 CoreLibraryReviewExempt: Everybody's on vacation, everybody everywhere. Change-Id: If464e3bd6bc97cbeefc3e5084b4cbaadac3f1e95 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290760 Reviewed-by: Aske Simon Christensen <askesc@google.com> Reviewed-by: Nate Bosch <nbosch@google.com> Commit-Queue: Lasse Nielsen <lrn@google.com>
This commit is contained in:
parent
6eba1cc3f1
commit
511bf8a80f
|
@ -136,6 +136,9 @@
|
|||
|
||||
#### `dart:collection`
|
||||
|
||||
- Added extension members `nonNulls`, `firstOrNull`, `lastOrNull`,
|
||||
`singleOrNull`, `elementAtOrNull` and `indexed` on `Iterable`s.
|
||||
Also exported from `dart:core`.
|
||||
- Deprecated the `HasNextIterator` class ([#50883][]).
|
||||
|
||||
- **Breaking change when migrating code to Dart 3.0**:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// 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.
|
||||
|
||||
import 'dart:collection' deferred as normal;
|
||||
import 'dart:collection' deferred as normal show HashSet;
|
||||
|
||||
@pragma('dart2js:load-priority:high')
|
||||
import 'dart:math' deferred as high;
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
AmbiguousExtension2,
|
||||
UnambiguousExtension1,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
AmbiguousExtension2,
|
||||
UnambiguousExtension2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
Extension1,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
Extension2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
A2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
E,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
NamedExtension,
|
||||
_extension#1,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
GeneralGeneric,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
A2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
A2,
|
||||
B2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
B3,
|
||||
B4,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
A2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
Extension,
|
||||
_extension#1,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
Extension,
|
||||
GenericExtension,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
HiddenExtension1,
|
||||
ShownExtension1,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
HiddenExtension2,
|
||||
ShownExtension2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
ShownExtension3,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName,
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
ClashingExtension,
|
||||
UniqueExtension1,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
ClashingExtension,
|
||||
UniqueExtension2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
HiddenExtension1,
|
||||
ShownExtension1,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
HiddenExtension2,
|
||||
ShownExtension2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
/*library: scope=[
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName,
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
A2,
|
||||
B2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
/*library: scope=[
|
||||
A2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
A3,
|
||||
A4,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
_extension#3,
|
||||
_extension#4,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
A2,
|
||||
B2,
|
||||
async.dart.FutureExtensions,
|
||||
collection.dart.IterableExtensions,
|
||||
collection.dart.NullableIterableExtensions,
|
||||
core.dart.DateTimeCopyWith,
|
||||
core.dart.EnumByName,
|
||||
core.dart.EnumName]*/
|
||||
|
|
|
@ -92,6 +92,7 @@ library /*isNonNullableByDefault*/;
|
|||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
import "dart:collection" as col;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
|
@ -170,7 +171,9 @@ additionalExports = (core::Deprecated,
|
|||
asy::FutureRecord7,
|
||||
asy::FutureRecord8,
|
||||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError)
|
||||
asy::ParallelWaitError,
|
||||
col::NullableIterableExtensions,
|
||||
col::IterableExtensions)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
|
|
|
@ -88,6 +88,7 @@ library /*isNonNullableByDefault*/;
|
|||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
import "dart:collection" as col;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
|
@ -166,7 +167,9 @@ additionalExports = (core::Deprecated,
|
|||
asy::FutureRecord7,
|
||||
asy::FutureRecord8,
|
||||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError)
|
||||
asy::ParallelWaitError,
|
||||
col::NullableIterableExtensions,
|
||||
col::IterableExtensions)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
|
|
|
@ -0,0 +1,209 @@
|
|||
//
|
||||
// Problems outside component:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main_lib1.dart: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
//
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:8:28: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// import 'main_lib3.dart' as imported;
|
||||
// ^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:15:7: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// new imported.Duplicate();
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:17:12: Error: 'NonExisting' isn't a type.
|
||||
// imported.NonExisting e;
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:18:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
// new imported.NonExisting();
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:19:13: Error: 'NonExisting' isn't a type.
|
||||
// <imported.NonExisting>[];
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:27:7: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// new exported.Duplicate();
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:29:12: Error: 'NonExisting' isn't a type.
|
||||
// exported.NonExisting e;
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:30:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
// new exported.NonExisting();
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:31:13: Error: 'NonExisting' isn't a type.
|
||||
// <exported.NonExisting>[];
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
import self as self;
|
||||
|
||||
import "org-dartlang-testcase:///main_lib1.dart" as exported;
|
||||
import "dart:core" as imported;
|
||||
import "org-dartlang-testcase:///main_lib2.dart" as imported;
|
||||
import "org-dartlang-testcase:///main_lib3.dart" as imported;
|
||||
|
||||
static method testImported() → dynamic {
|
||||
function f(dynamic d) → void {}
|
||||
Never n;
|
||||
<Never>[];
|
||||
invalid-type d;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:15:7: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
new imported.Duplicate();
|
||||
^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
invalid-type e;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:18:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
new imported.NonExisting();
|
||||
^^^^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
}
|
||||
static method testExported() → dynamic {
|
||||
function f(dynamic d) → void {}
|
||||
Never n;
|
||||
<Never>[];
|
||||
invalid-type d;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:27:7: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
new exported.Duplicate();
|
||||
^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
invalid-type e;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:30:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
new exported.NonExisting();
|
||||
^^^^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
}
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main_lib1.dart:7:1: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// export 'main_lib3.dart';
|
||||
// ^
|
||||
//
|
||||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
import "dart:collection" as col;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
core::bool,
|
||||
core::Comparable,
|
||||
core::DateTime,
|
||||
core::double,
|
||||
core::Duration,
|
||||
core::Enum,
|
||||
core::Error,
|
||||
core::AssertionError,
|
||||
core::TypeError,
|
||||
core::ArgumentError,
|
||||
core::RangeError,
|
||||
core::IndexError,
|
||||
core::NoSuchMethodError,
|
||||
core::UnsupportedError,
|
||||
core::UnimplementedError,
|
||||
core::StateError,
|
||||
core::ConcurrentModificationError,
|
||||
core::OutOfMemoryError,
|
||||
core::StackOverflowError,
|
||||
core::Exception,
|
||||
core::FormatException,
|
||||
core::IntegerDivisionByZeroException,
|
||||
core::Function,
|
||||
core::int,
|
||||
core::Invocation,
|
||||
core::Iterable,
|
||||
core::Iterator,
|
||||
core::List,
|
||||
core::Map,
|
||||
core::MapEntry,
|
||||
core::Null,
|
||||
core::num,
|
||||
core::Object,
|
||||
core::Pattern,
|
||||
core::Match,
|
||||
core::Record,
|
||||
core::RegExp,
|
||||
core::RegExpMatch,
|
||||
core::Set,
|
||||
core::Sink,
|
||||
core::StackTrace,
|
||||
core::Stopwatch,
|
||||
core::String,
|
||||
core::Runes,
|
||||
core::RuneIterator,
|
||||
core::StringBuffer,
|
||||
core::StringSink,
|
||||
core::Symbol,
|
||||
core::Type,
|
||||
core::Uri,
|
||||
core::UriData,
|
||||
core::Expando,
|
||||
core::WeakReference,
|
||||
core::Finalizer,
|
||||
core::DateTimeCopyWith,
|
||||
core::EnumName,
|
||||
core::EnumByName,
|
||||
core::identical,
|
||||
core::identityHashCode,
|
||||
core::print,
|
||||
core::Comparator,
|
||||
core::deprecated,
|
||||
core::override,
|
||||
asy::Future,
|
||||
asy::Stream,
|
||||
asy::FutureExtensions,
|
||||
<<<<<<< HEAD
|
||||
asy::FutureIterable,
|
||||
asy::FutureRecord2,
|
||||
asy::FutureRecord3,
|
||||
asy::FutureRecord4,
|
||||
asy::FutureRecord5,
|
||||
asy::FutureRecord6,
|
||||
asy::FutureRecord7,
|
||||
asy::FutureRecord8,
|
||||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError)
|
||||
=======
|
||||
col::NullableIterableExtensions,
|
||||
col::IterableExtensions)
|
||||
>>>>>>> 416033dff19 (Add `nonNulls`, `indexed` and other extensions on iterables.)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
export "org-dartlang-testcase:///main_lib3.dart";
|
||||
|
||||
static const field dynamic _exports# = #C1 /*isLegacy*/;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self3;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Duplicate extends core::Object {
|
||||
synthetic constructor •() → self3::Duplicate
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self4;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Duplicate extends core::Object {
|
||||
synthetic constructor •() → self4::Duplicate
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "{\"Duplicate\":\"'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.\",\"dynamic\":\"<dynamic>\",\"Never\":\"<Never>\"}"
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
//
|
||||
// Problems outside component:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main_lib1.dart: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
//
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:8:28: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// import 'main_lib3.dart' as imported;
|
||||
// ^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:15:7: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// new imported.Duplicate();
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:17:12: Error: 'NonExisting' isn't a type.
|
||||
// imported.NonExisting e;
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:18:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
// new imported.NonExisting();
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:19:13: Error: 'NonExisting' isn't a type.
|
||||
// <imported.NonExisting>[];
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:27:7: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// new exported.Duplicate();
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:29:12: Error: 'NonExisting' isn't a type.
|
||||
// exported.NonExisting e;
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:30:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
// new exported.NonExisting();
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:31:13: Error: 'NonExisting' isn't a type.
|
||||
// <exported.NonExisting>[];
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
import self as self;
|
||||
|
||||
import "org-dartlang-testcase:///main_lib1.dart" as exported;
|
||||
import "dart:core" as imported;
|
||||
import "org-dartlang-testcase:///main_lib2.dart" as imported;
|
||||
import "org-dartlang-testcase:///main_lib3.dart" as imported;
|
||||
|
||||
static method testImported() → dynamic {
|
||||
function f(dynamic d) → void {}
|
||||
Never n;
|
||||
<Never>[];
|
||||
invalid-type d;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:15:7: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
new imported.Duplicate();
|
||||
^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
invalid-type e;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:18:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
new imported.NonExisting();
|
||||
^^^^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
}
|
||||
static method testExported() → dynamic {
|
||||
function f(dynamic d) → void {}
|
||||
Never n;
|
||||
<Never>[];
|
||||
invalid-type d;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:27:7: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
new exported.Duplicate();
|
||||
^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
invalid-type e;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:30:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
new exported.NonExisting();
|
||||
^^^^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
}
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main_lib1.dart:7:1: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// export 'main_lib3.dart';
|
||||
// ^
|
||||
//
|
||||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
core::bool,
|
||||
core::Comparable,
|
||||
core::DateTime,
|
||||
core::double,
|
||||
core::Duration,
|
||||
core::Enum,
|
||||
core::Error,
|
||||
core::AssertionError,
|
||||
core::TypeError,
|
||||
core::ArgumentError,
|
||||
core::RangeError,
|
||||
core::IndexError,
|
||||
core::NoSuchMethodError,
|
||||
core::UnsupportedError,
|
||||
core::UnimplementedError,
|
||||
core::StateError,
|
||||
core::ConcurrentModificationError,
|
||||
core::OutOfMemoryError,
|
||||
core::StackOverflowError,
|
||||
core::Exception,
|
||||
core::FormatException,
|
||||
core::IntegerDivisionByZeroException,
|
||||
core::Function,
|
||||
core::int,
|
||||
core::Invocation,
|
||||
core::Iterable,
|
||||
core::Iterator,
|
||||
core::List,
|
||||
core::Map,
|
||||
core::MapEntry,
|
||||
core::Null,
|
||||
core::num,
|
||||
core::Object,
|
||||
core::Pattern,
|
||||
core::Match,
|
||||
core::Record,
|
||||
core::RegExp,
|
||||
core::RegExpMatch,
|
||||
core::Set,
|
||||
core::Sink,
|
||||
core::StackTrace,
|
||||
core::Stopwatch,
|
||||
core::String,
|
||||
core::Runes,
|
||||
core::RuneIterator,
|
||||
core::StringBuffer,
|
||||
core::StringSink,
|
||||
core::Symbol,
|
||||
core::Type,
|
||||
core::Uri,
|
||||
core::UriData,
|
||||
core::Expando,
|
||||
core::WeakReference,
|
||||
core::Finalizer,
|
||||
core::DateTimeCopyWith,
|
||||
core::EnumName,
|
||||
core::EnumByName,
|
||||
core::identical,
|
||||
core::identityHashCode,
|
||||
core::print,
|
||||
core::Comparator,
|
||||
core::deprecated,
|
||||
core::override,
|
||||
asy::Future,
|
||||
asy::Stream,
|
||||
asy::FutureExtensions)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
export "org-dartlang-testcase:///main_lib3.dart";
|
||||
|
||||
static const field dynamic _exports# = #C1 /*isLegacy*/;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self3;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Duplicate extends core::Object {
|
||||
synthetic constructor •() → self3::Duplicate
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self4;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Duplicate extends core::Object {
|
||||
synthetic constructor •() → self4::Duplicate
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "{\"Duplicate\":\"'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.\",\"dynamic\":\"<dynamic>\",\"Never\":\"<Never>\"}"
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
//
|
||||
// Problems outside component:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main_lib1.dart: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
//
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:8:28: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// import 'main_lib3.dart' as imported;
|
||||
// ^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:15:7: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// new imported.Duplicate();
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:17:12: Error: 'NonExisting' isn't a type.
|
||||
// imported.NonExisting e;
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:18:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
// new imported.NonExisting();
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:19:13: Error: 'NonExisting' isn't a type.
|
||||
// <imported.NonExisting>[];
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:27:7: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// new exported.Duplicate();
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:29:12: Error: 'NonExisting' isn't a type.
|
||||
// exported.NonExisting e;
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:30:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
// new exported.NonExisting();
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:31:13: Error: 'NonExisting' isn't a type.
|
||||
// <exported.NonExisting>[];
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
import self as self;
|
||||
|
||||
import "org-dartlang-testcase:///main_lib1.dart" as exported;
|
||||
import "dart:core" as imported;
|
||||
import "org-dartlang-testcase:///main_lib2.dart" as imported;
|
||||
import "org-dartlang-testcase:///main_lib3.dart" as imported;
|
||||
|
||||
static method testImported() → dynamic {
|
||||
function f(dynamic d) → void {}
|
||||
Never n;
|
||||
<Never>[];
|
||||
invalid-type d;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:15:7: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
new imported.Duplicate();
|
||||
^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
invalid-type e;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:18:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
new imported.NonExisting();
|
||||
^^^^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
}
|
||||
static method testExported() → dynamic {
|
||||
function f(dynamic d) → void {}
|
||||
Never n;
|
||||
<Never>[];
|
||||
invalid-type d;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:27:7: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
new exported.Duplicate();
|
||||
^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
invalid-type e;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:30:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
new exported.NonExisting();
|
||||
^^^^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
}
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main_lib1.dart:7:1: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// export 'main_lib3.dart';
|
||||
// ^
|
||||
//
|
||||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
core::bool,
|
||||
core::Comparable,
|
||||
core::DateTime,
|
||||
core::double,
|
||||
core::Duration,
|
||||
core::Enum,
|
||||
core::Error,
|
||||
core::AssertionError,
|
||||
core::TypeError,
|
||||
core::ArgumentError,
|
||||
core::RangeError,
|
||||
core::IndexError,
|
||||
core::NoSuchMethodError,
|
||||
core::UnsupportedError,
|
||||
core::UnimplementedError,
|
||||
core::StateError,
|
||||
core::ConcurrentModificationError,
|
||||
core::OutOfMemoryError,
|
||||
core::StackOverflowError,
|
||||
core::Exception,
|
||||
core::FormatException,
|
||||
core::IntegerDivisionByZeroException,
|
||||
core::Function,
|
||||
core::int,
|
||||
core::Invocation,
|
||||
core::Iterable,
|
||||
core::Iterator,
|
||||
core::List,
|
||||
core::Map,
|
||||
core::MapEntry,
|
||||
core::Null,
|
||||
core::num,
|
||||
core::Object,
|
||||
core::Pattern,
|
||||
core::Match,
|
||||
core::Record,
|
||||
core::RegExp,
|
||||
core::RegExpMatch,
|
||||
core::Set,
|
||||
core::Sink,
|
||||
core::StackTrace,
|
||||
core::Stopwatch,
|
||||
core::String,
|
||||
core::Runes,
|
||||
core::RuneIterator,
|
||||
core::StringBuffer,
|
||||
core::StringSink,
|
||||
core::Symbol,
|
||||
core::Type,
|
||||
core::Uri,
|
||||
core::UriData,
|
||||
core::Expando,
|
||||
core::WeakReference,
|
||||
core::Finalizer,
|
||||
core::DateTimeCopyWith,
|
||||
core::EnumName,
|
||||
core::EnumByName,
|
||||
core::identical,
|
||||
core::identityHashCode,
|
||||
core::print,
|
||||
core::Comparator,
|
||||
core::deprecated,
|
||||
core::override,
|
||||
asy::Future,
|
||||
asy::Stream,
|
||||
asy::FutureExtensions,
|
||||
asy::FutureIterable,
|
||||
asy::FutureRecord2,
|
||||
asy::FutureRecord3,
|
||||
asy::FutureRecord4,
|
||||
asy::FutureRecord5,
|
||||
asy::FutureRecord6,
|
||||
asy::FutureRecord7,
|
||||
asy::FutureRecord8,
|
||||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
export "org-dartlang-testcase:///main_lib3.dart";
|
||||
|
||||
static const field dynamic _exports# = #C1 /*isLegacy*/;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self3;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Duplicate extends core::Object {
|
||||
synthetic constructor •() → self3::Duplicate
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self4;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Duplicate extends core::Object {
|
||||
synthetic constructor •() → self4::Duplicate
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "{\"Duplicate\":\"'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.\",\"dynamic\":\"<dynamic>\",\"Never\":\"<Never>\"}"
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
//
|
||||
// Problems outside component:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main_lib1.dart: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
//
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:8:28: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// import 'main_lib3.dart' as imported;
|
||||
// ^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:15:7: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// new imported.Duplicate();
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:17:12: Error: 'NonExisting' isn't a type.
|
||||
// imported.NonExisting e;
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:18:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
// new imported.NonExisting();
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:19:13: Error: 'NonExisting' isn't a type.
|
||||
// <imported.NonExisting>[];
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:27:7: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// new exported.Duplicate();
|
||||
// ^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:29:12: Error: 'NonExisting' isn't a type.
|
||||
// exported.NonExisting e;
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:30:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
// new exported.NonExisting();
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main.dart:31:13: Error: 'NonExisting' isn't a type.
|
||||
// <exported.NonExisting>[];
|
||||
// ^^^^^^^^^^^
|
||||
//
|
||||
import self as self;
|
||||
|
||||
import "org-dartlang-testcase:///main_lib1.dart" as exported;
|
||||
import "dart:core" as imported;
|
||||
import "org-dartlang-testcase:///main_lib2.dart" as imported;
|
||||
import "org-dartlang-testcase:///main_lib3.dart" as imported;
|
||||
|
||||
static method testImported() → dynamic {
|
||||
function f(dynamic d) → void {}
|
||||
Never n;
|
||||
<Never>[];
|
||||
invalid-type d;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:15:7: Error: 'Duplicate' is imported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
new imported.Duplicate();
|
||||
^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
invalid-type e;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:18:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
new imported.NonExisting();
|
||||
^^^^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
}
|
||||
static method testExported() → dynamic {
|
||||
function f(dynamic d) → void {}
|
||||
Never n;
|
||||
<Never>[];
|
||||
invalid-type d;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:27:7: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
new exported.Duplicate();
|
||||
^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
invalid-type e;
|
||||
invalid-expression "pkg/front_end/testcases/general/error_export_from_dill/main.dart:30:16: Error: Couldn't find constructor 'NonExisting'.
|
||||
new exported.NonExisting();
|
||||
^^^^^^^^^^^";
|
||||
<invalid-type>[];
|
||||
}
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/general/error_export_from_dill/main_lib1.dart:7:1: Error: 'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.
|
||||
// export 'main_lib3.dart';
|
||||
// ^
|
||||
//
|
||||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
import "dart:collection" as col;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
core::bool,
|
||||
core::Comparable,
|
||||
core::DateTime,
|
||||
core::double,
|
||||
core::Duration,
|
||||
core::Enum,
|
||||
core::Error,
|
||||
core::AssertionError,
|
||||
core::TypeError,
|
||||
core::ArgumentError,
|
||||
core::RangeError,
|
||||
core::IndexError,
|
||||
core::NoSuchMethodError,
|
||||
core::UnsupportedError,
|
||||
core::UnimplementedError,
|
||||
core::StateError,
|
||||
core::ConcurrentModificationError,
|
||||
core::OutOfMemoryError,
|
||||
core::StackOverflowError,
|
||||
core::Exception,
|
||||
core::FormatException,
|
||||
core::IntegerDivisionByZeroException,
|
||||
core::Function,
|
||||
core::int,
|
||||
core::Invocation,
|
||||
core::Iterable,
|
||||
core::Iterator,
|
||||
core::List,
|
||||
core::Map,
|
||||
core::MapEntry,
|
||||
core::Null,
|
||||
core::num,
|
||||
core::Object,
|
||||
core::Pattern,
|
||||
core::Match,
|
||||
core::Record,
|
||||
core::RegExp,
|
||||
core::RegExpMatch,
|
||||
core::Set,
|
||||
core::Sink,
|
||||
core::StackTrace,
|
||||
core::Stopwatch,
|
||||
core::String,
|
||||
core::Runes,
|
||||
core::RuneIterator,
|
||||
core::StringBuffer,
|
||||
core::StringSink,
|
||||
core::Symbol,
|
||||
core::Type,
|
||||
core::Uri,
|
||||
core::UriData,
|
||||
core::Expando,
|
||||
core::WeakReference,
|
||||
core::Finalizer,
|
||||
core::DateTimeCopyWith,
|
||||
core::EnumName,
|
||||
core::EnumByName,
|
||||
core::identical,
|
||||
core::identityHashCode,
|
||||
core::print,
|
||||
core::Comparator,
|
||||
core::deprecated,
|
||||
core::override,
|
||||
asy::Future,
|
||||
asy::Stream,
|
||||
asy::FutureExtensions,
|
||||
col::NullableIterableExtensions,
|
||||
col::IterableExtensions)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
export "org-dartlang-testcase:///main_lib3.dart";
|
||||
|
||||
static const field dynamic _exports# = #C1 /*isLegacy*/;
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self3;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Duplicate extends core::Object {
|
||||
synthetic constructor •() → self3::Duplicate
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self4;
|
||||
import "dart:core" as core;
|
||||
|
||||
class Duplicate extends core::Object {
|
||||
synthetic constructor •() → self4::Duplicate
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = "{\"Duplicate\":\"'Duplicate' is exported from both 'pkg/front_end/testcases/general/error_export_from_dill/main_lib2.dart' and 'pkg/front_end/testcases/general/error_export_from_dill/main_lib3.dart'.\",\"dynamic\":\"<dynamic>\",\"Never\":\"<Never>\"}"
|
||||
}
|
|
@ -92,6 +92,7 @@ library /*isNonNullableByDefault*/;
|
|||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
import "dart:collection" as col;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
|
@ -170,7 +171,9 @@ additionalExports = (core::Deprecated,
|
|||
asy::FutureRecord7,
|
||||
asy::FutureRecord8,
|
||||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError)
|
||||
asy::ParallelWaitError,
|
||||
col::NullableIterableExtensions,
|
||||
col::IterableExtensions)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
|
|
|
@ -27,6 +27,7 @@ library /*isNonNullableByDefault*/;
|
|||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
import "dart:collection" as col;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
|
@ -105,7 +106,9 @@ additionalExports = (core::Deprecated,
|
|||
asy::FutureRecord7,
|
||||
asy::FutureRecord8,
|
||||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError)
|
||||
asy::ParallelWaitError,
|
||||
col::NullableIterableExtensions,
|
||||
col::IterableExtensions)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
|
|
|
@ -88,6 +88,7 @@ library /*isNonNullableByDefault*/;
|
|||
import self as self2;
|
||||
import "dart:core" as core;
|
||||
import "dart:async" as asy;
|
||||
import "dart:collection" as col;
|
||||
additionalExports = (core::Deprecated,
|
||||
core::pragma,
|
||||
core::BigInt,
|
||||
|
@ -166,7 +167,9 @@ additionalExports = (core::Deprecated,
|
|||
asy::FutureRecord7,
|
||||
asy::FutureRecord8,
|
||||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError)
|
||||
asy::ParallelWaitError,
|
||||
col::NullableIterableExtensions,
|
||||
col::IterableExtensions)
|
||||
|
||||
export "dart:core";
|
||||
export "org-dartlang-testcase:///main_lib2.dart";
|
||||
|
|
|
@ -13,6 +13,8 @@ additionalExports = (asy::Future,
|
|||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError,
|
||||
asy::Stream,
|
||||
col::IterableExtensions,
|
||||
col::NullableIterableExtensions,
|
||||
core::deprecated,
|
||||
core::override,
|
||||
core::identical,
|
||||
|
|
|
@ -13,6 +13,8 @@ additionalExports = (asy::Future,
|
|||
asy::FutureRecord9,
|
||||
asy::ParallelWaitError,
|
||||
asy::Stream,
|
||||
col::IterableExtensions,
|
||||
col::NullableIterableExtensions,
|
||||
core::deprecated,
|
||||
core::override,
|
||||
core::identical,
|
||||
|
|
|
@ -62,7 +62,7 @@ main() async {
|
|||
['Array', 'List', 'Record'].any((p) => klass.name.contains(p))) {
|
||||
Expect.isTrue(fields.length <= object.references.length);
|
||||
} else {
|
||||
Expect.equals(fields.length, object.references.length);
|
||||
Expect.equals(fields.length, object.references.length, klass.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,3 +16,88 @@ typedef IterableMixin<E> = Iterable<E>;
|
|||
/// in terms of `iterator`.
|
||||
// @Deprecated("Use Iterable instead")
|
||||
typedef IterableBase<E> = Iterable<E>;
|
||||
|
||||
/// Operations on iterables with nullable elements.
|
||||
@Since("3.0")
|
||||
extension NullableIterableExtensions<T extends Object> on Iterable<T?> {
|
||||
/// The non-`null` elements of this iterable.
|
||||
///
|
||||
/// The same elements as this iterable, except that `null` values
|
||||
/// are omitted.
|
||||
Iterable<T> get nonNulls => NonNullsIterable<T>(this);
|
||||
}
|
||||
|
||||
/// Operations on iterables.
|
||||
@Since("3.0")
|
||||
extension IterableExtensions<T> on Iterable<T> {
|
||||
/// Pairs of elements of the indices and elements of this iterable.
|
||||
///
|
||||
/// The elements are `(0, this.first)` through
|
||||
/// `(this.length - 1, this.last)`, in index/iteration order.
|
||||
Iterable<(int, T)> get indexed => IndexedIterable<T>(this, 0);
|
||||
|
||||
/// The first element of this iterator, or `null` if the iterable is empty.
|
||||
T? get firstOrNull {
|
||||
var iterator = this.iterator;
|
||||
if (iterator.moveNext()) return iterator.current;
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The last element of this iterable, or `null` if the iterable is empty.
|
||||
///
|
||||
/// This computation may not be efficient.
|
||||
/// The last value is potentially found by iterating the entire iterable
|
||||
/// and temporarily storing every value.
|
||||
/// The process only iterates the iterable once.
|
||||
/// If iterating more than once is not a problem, it may be more efficient
|
||||
/// for some iterables to do:
|
||||
/// ```dart
|
||||
/// var lastOrNull = iterable.isEmpty ? null : iterable.last;
|
||||
/// ```
|
||||
T? get lastOrNull {
|
||||
if (this is EfficientLengthIterable) {
|
||||
if (isEmpty) return null;
|
||||
return last;
|
||||
}
|
||||
var iterator = this.iterator;
|
||||
if (!iterator.moveNext()) return null;
|
||||
T result;
|
||||
do {
|
||||
result = iterator.current;
|
||||
} while (iterator.moveNext());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// The single element of this iterator, or `null`.
|
||||
///
|
||||
/// If the iterator has precisely one element, this is that element.
|
||||
/// Otherwise, if the iterator has zero elements, or it has two or more,
|
||||
/// the value is `null`.
|
||||
T? get singleOrNull {
|
||||
var iterator = this.iterator;
|
||||
if (iterator.moveNext()) {
|
||||
var result = iterator.current;
|
||||
if (!iterator.moveNext()) return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// The element at position [index] of this iterable, or `null`.
|
||||
///
|
||||
/// The [index] is zero based, and must be non-negative.
|
||||
///
|
||||
/// Returns the result of `elementAt(index)` if the iterable has
|
||||
/// at least `index + 1` elements, and `null` otherwise.
|
||||
T? elementAtOrNull(int index) {
|
||||
RangeError.checkNotNegative(index, "index");
|
||||
if (this is EfficientLengthIterable) {
|
||||
if (index >= length) return null;
|
||||
return elementAt(index);
|
||||
}
|
||||
var iterator = this.iterator;
|
||||
do {
|
||||
if (!iterator.moveNext()) return null;
|
||||
} while (--index >= 0);
|
||||
return iterator.current;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -183,6 +183,8 @@ export "dart:async"
|
|||
FutureRecord9,
|
||||
ParallelWaitError;
|
||||
|
||||
export "dart:collection" show NullableIterableExtensions, IterableExtensions;
|
||||
|
||||
part "annotations.dart";
|
||||
part "bigint.dart";
|
||||
part "bool.dart";
|
||||
|
|
|
@ -877,6 +877,155 @@ class WhereTypeIterator<T> implements Iterator<T> {
|
|||
T get current => _source.current as T;
|
||||
}
|
||||
|
||||
/// Implementation of [NullableIterableExtensions.nonNulls].
|
||||
///
|
||||
/// A filtering iterable, so it doesn't have efficient length
|
||||
/// and cannot forward most methods to the underlying [_source].
|
||||
class NonNullsIterable<T extends Object> extends Iterable<T> {
|
||||
final Iterable<T?> _source;
|
||||
NonNullsIterable(this._source);
|
||||
|
||||
T? get _firstNonNull {
|
||||
for (var element in _source) {
|
||||
if (element != null) return element;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
bool get isEmpty => _firstNonNull == null;
|
||||
bool get isNotEmpty => _firstNonNull != null;
|
||||
T get first => _firstNonNull ?? (throw IterableElementError.noElement());
|
||||
|
||||
Iterator<T> get iterator => NonNullsIterator<T>(_source.iterator);
|
||||
}
|
||||
|
||||
class NonNullsIterator<T extends Object> implements Iterator<T> {
|
||||
final Iterator<T?> _source;
|
||||
T? _current;
|
||||
|
||||
NonNullsIterator(this._source);
|
||||
|
||||
bool moveNext() {
|
||||
_current = null;
|
||||
while (_source.moveNext()) {
|
||||
var next = _source.current;
|
||||
if (next != null) {
|
||||
_current = next;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
T get current => _current ?? (throw IterableElementError.noElement());
|
||||
}
|
||||
|
||||
/// Implementation of [IterableExtensions.indexed].
|
||||
///
|
||||
/// Maps elements of [_source] one-to-one to record values,
|
||||
/// so has the same length as the original, and can define many
|
||||
/// operations in terms of the underlying source.
|
||||
class IndexedIterable<T> extends Iterable<(int, T)> {
|
||||
final Iterable<T> _source;
|
||||
|
||||
/// Offset applied to indices.
|
||||
///
|
||||
/// Used to implement `skip` efficiently for iterables which can skip
|
||||
/// efficiently.
|
||||
final int _start;
|
||||
|
||||
factory IndexedIterable(Iterable<T> source, int start) {
|
||||
if (source is EfficientLengthIterable<T>) {
|
||||
return EfficientLengthIndexedIterable(source, start);
|
||||
}
|
||||
return IndexedIterable._(source, start);
|
||||
}
|
||||
|
||||
IndexedIterable.nonEfficientLength(Iterable<T> source, int start)
|
||||
: this._(source, start);
|
||||
|
||||
IndexedIterable._(this._source, this._start);
|
||||
|
||||
int get length => _source.length;
|
||||
bool get isEmpty => _source.isEmpty;
|
||||
bool get isNotEmpty => _source.isNotEmpty;
|
||||
|
||||
(int, T) get first => (_start, _source.first);
|
||||
(int, T) get single => (_start, _source.single);
|
||||
(int, T) elementAt(int index) => (index + _start, _source.elementAt(index));
|
||||
|
||||
bool contains(Object? element) {
|
||||
if (element case (int index, Object? other) when index >= _start) {
|
||||
// Try to find the `index`th element without looking at the
|
||||
// intermediate values, and without throwing if there are fewer.
|
||||
var unbiasedIndex = index - _start;
|
||||
var iterator = _source.skip(unbiasedIndex).iterator;
|
||||
return iterator.moveNext() && iterator.current == other;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterable<(int, T)> take(int count) => IndexedIterable<T>.nonEfficientLength(
|
||||
_source.take(_checkCount(count)), _start);
|
||||
|
||||
Iterable<(int, T)> skip(int count) => IndexedIterable<T>.nonEfficientLength(
|
||||
_source.skip(_checkCount(count)), count + _start);
|
||||
|
||||
Iterator<(int, T)> get iterator =>
|
||||
IndexedIterator<T>(_source.iterator, _start);
|
||||
}
|
||||
|
||||
class EfficientLengthIndexedIterable<T> extends IndexedIterable<T>
|
||||
implements EfficientLengthIterable<(int, T)> {
|
||||
EfficientLengthIndexedIterable(super._source, super._start) : super._();
|
||||
|
||||
(int, T) get last {
|
||||
var length = _source.length;
|
||||
if (length <= 0) throw IterableElementError.noElement();
|
||||
var last = _source.last;
|
||||
if (length != this.length) {
|
||||
throw ConcurrentModificationError(this);
|
||||
}
|
||||
return (length - 1 + _start, last);
|
||||
}
|
||||
|
||||
bool contains(Object? element) {
|
||||
if (element case (int index, Object? other) when index >= _start) {
|
||||
var unbiasedIndex = index - _start;
|
||||
return unbiasedIndex < _source.length &&
|
||||
_source.elementAt(unbiasedIndex) == other;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Iterable<(int, T)> take(int count) => EfficientLengthIndexedIterable<T>(
|
||||
_source.take(_checkCount(count)), _start);
|
||||
|
||||
Iterable<(int, T)> skip(int count) => EfficientLengthIndexedIterable<T>(
|
||||
_source.skip(_checkCount(count)), _start + count);
|
||||
}
|
||||
|
||||
class IndexedIterator<T> implements Iterator<(int, T)> {
|
||||
final Iterator<T> _source;
|
||||
final int _start;
|
||||
int _index = -1;
|
||||
|
||||
IndexedIterator(this._source, this._start);
|
||||
|
||||
bool moveNext() {
|
||||
var index = ++_index;
|
||||
if (index >= 0 && _source.moveNext()) {
|
||||
return true;
|
||||
}
|
||||
_index = -2; // Ensures moveNext won't get called again.
|
||||
return false;
|
||||
}
|
||||
|
||||
(int, T) get current => _index >= 0
|
||||
? (_start + _index, _source.current)
|
||||
: (throw IterableElementError.noElement());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates errors throw by [Iterable] when the element count is wrong.
|
||||
*/
|
||||
|
|
365
tests/corelib/iterable_extension_test.dart
Normal file
365
tests/corelib/iterable_extension_test.dart
Normal file
|
@ -0,0 +1,365 @@
|
|||
// Copyright (c) 2023, 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.
|
||||
|
||||
import "dart:async" show FutureOr;
|
||||
import "package:expect/expect.dart";
|
||||
import "../language/static_type_helper.dart";
|
||||
// All extensions are exported by `dart:core`.
|
||||
|
||||
void main() {
|
||||
// Null-related extensions.
|
||||
testNonNulls();
|
||||
testFirstOrNull();
|
||||
testLastOrNull();
|
||||
testSingleOrNull();
|
||||
testElementAtOrNull();
|
||||
|
||||
// Record-related extensions.
|
||||
testIndexed();
|
||||
}
|
||||
|
||||
void testNonNulls() {
|
||||
// Static behavior.
|
||||
{
|
||||
// Removes nullability from element type.
|
||||
Iterable<int?> target = [];
|
||||
var result = target.nonNulls;
|
||||
result.expectStaticType<Exactly<Iterable<int>>>();
|
||||
}
|
||||
{
|
||||
// Works on subtypes of iterable.
|
||||
List<int?> target = [];
|
||||
var result = target.nonNulls;
|
||||
result.expectStaticType<Exactly<Iterable<int>>>();
|
||||
}
|
||||
{
|
||||
// Works on non-nullable types too (wish it didn't).
|
||||
Iterable<int> target = [];
|
||||
var result = target.nonNulls;
|
||||
result.expectStaticType<Exactly<Iterable<int>>>();
|
||||
}
|
||||
{
|
||||
// Removes nullability from `Never?`, giving `Never`.
|
||||
// (Cannot remove nullability from `Null`, so doesn't match
|
||||
// `Iterable<Null>`.)
|
||||
Iterable<Never?> target = [];
|
||||
var result = target.nonNulls;
|
||||
result.expectStaticType<Exactly<Iterable<Never>>>();
|
||||
}
|
||||
|
||||
// Dynamic behavior.
|
||||
|
||||
void test<T extends Object>(
|
||||
String name, Iterable<T?> input, List<T> expectedResults) {
|
||||
var actualResults = input.nonNulls;
|
||||
Expect.type<Iterable<T>>(actualResults, "$name type");
|
||||
Expect.listEquals(expectedResults, [...actualResults], "$name result");
|
||||
}
|
||||
|
||||
test<int>("empty iterable", Iterable.empty(), []);
|
||||
test<int>("empty list", [], []);
|
||||
test<int>("all non-null", numbers(5), [1, 2, 3, 4, 5]);
|
||||
test<int>("all null", numbers(5, where: none), []);
|
||||
test<int>("one non-null", numbers(5, where: only(3)), [3]);
|
||||
test<int>("some null", numbers(5, where: even), [2, 4]);
|
||||
test<int>("some null, list", [null, 2, null, 4, null], [2, 4]);
|
||||
|
||||
// Is lazy.
|
||||
var nonNulls = numbers(5, where: even, throwAt: 3).nonNulls;
|
||||
var it = nonNulls.iterator;
|
||||
Expect.isTrue(it.moveNext());
|
||||
Expect.equals(2, it.current);
|
||||
Expect.throws<UnimplementedError>(it.moveNext);
|
||||
}
|
||||
|
||||
void testFirstOrNull() {
|
||||
// Static behavior.
|
||||
// (Tested to ensure extension captures the correct type,
|
||||
// and the correct extension member is applied).
|
||||
{
|
||||
Iterable<int> target = [];
|
||||
var result = target.firstOrNull;
|
||||
result.expectStaticType<Exactly<int?>>();
|
||||
}
|
||||
{
|
||||
Iterable<int?> target = [];
|
||||
var result = target.firstOrNull;
|
||||
result.expectStaticType<Exactly<int?>>();
|
||||
}
|
||||
{
|
||||
Iterable<Never> target = [];
|
||||
var result = target.firstOrNull;
|
||||
result.expectStaticType<Exactly<Null>>();
|
||||
}
|
||||
// Dynamic behavior.
|
||||
void test<T extends Object>(
|
||||
String name, Iterable<T?> source, T? expectedResult) {
|
||||
var actualResult = source.firstOrNull;
|
||||
Expect.equals(expectedResult, actualResult, "firstOrNull $name");
|
||||
}
|
||||
|
||||
test<int>("Empty iterable", Iterable.empty(), null);
|
||||
test<Never>("Empty iterable", Iterable.empty(), null);
|
||||
test<int>("Empty list", [], null);
|
||||
test<int>("Single value", numbers(1), 1);
|
||||
test<int>("Multiple values", numbers(3), 1);
|
||||
test<int>("Nullable values", numbers(3, where: even), null);
|
||||
test<int>("Stops after first", numbers(3, throwAt: 2), 1);
|
||||
Expect.throws<UnimplementedError>(() => numbers(3, throwAt: 1).firstOrNull,
|
||||
null, "firstOrNull first throws");
|
||||
}
|
||||
|
||||
void testLastOrNull() {
|
||||
// Static behavior.
|
||||
{
|
||||
Iterable<int> target = [];
|
||||
var result = target.lastOrNull;
|
||||
result.expectStaticType<Exactly<int?>>();
|
||||
}
|
||||
{
|
||||
Iterable<int?> target = [];
|
||||
var result = target.lastOrNull;
|
||||
result.expectStaticType<Exactly<int?>>();
|
||||
}
|
||||
{
|
||||
Iterable<Never> target = [];
|
||||
var result = target.lastOrNull;
|
||||
result.expectStaticType<Exactly<Null>>();
|
||||
}
|
||||
// Dynamic behavior.
|
||||
void test<T>(String name, Iterable<T> source, T? expectedResult) {
|
||||
var actualResult = source.lastOrNull;
|
||||
Expect.equals(expectedResult, actualResult, "lastOrNull $name");
|
||||
}
|
||||
|
||||
test<int>("Empty iterable", Iterable.empty(), null);
|
||||
test<Never>("Empty iterable", Iterable.empty(), null);
|
||||
test<int>("Empty list", [], null);
|
||||
test<int?>("Single value", numbers(1), 1);
|
||||
test<int?>("Multiple values", numbers(3), 3);
|
||||
test<int?>("Nullable values", numbers(3, where: even), null);
|
||||
Expect.throws<UnimplementedError>(
|
||||
() => numbers(3, throwAt: 1).lastOrNull, null, "lastOrNull first throws");
|
||||
Expect.throws<UnimplementedError>(
|
||||
() => numbers(3, throwAt: 3).lastOrNull, null, "lastOrNull last throws");
|
||||
Expect.throws<UnimplementedError>(
|
||||
() => CurrentThrowIterable<int?>(numbers(3), 2).lastOrNull,
|
||||
null,
|
||||
"lastOrNull throw on current");
|
||||
}
|
||||
|
||||
void testSingleOrNull() {
|
||||
// Static behavior.
|
||||
{
|
||||
Iterable<int> target = [];
|
||||
var result = target.singleOrNull;
|
||||
result.expectStaticType<Exactly<int?>>();
|
||||
}
|
||||
{
|
||||
Iterable<int?> target = [];
|
||||
var result = target.singleOrNull;
|
||||
result.expectStaticType<Exactly<int?>>();
|
||||
}
|
||||
{
|
||||
Iterable<Never> target = [];
|
||||
var result = target.singleOrNull;
|
||||
result.expectStaticType<Exactly<Null>>();
|
||||
}
|
||||
// Dynamic behavior.
|
||||
void test<T>(String name, Iterable<T> source, T? expectedResult) {
|
||||
var actualResult = source.singleOrNull;
|
||||
Expect.equals(expectedResult, actualResult, "singleOrNull $name");
|
||||
}
|
||||
|
||||
test<int>("Empty iterable", Iterable.empty(), null);
|
||||
test<Never>("Empty iterable", Iterable.empty(), null);
|
||||
test<int>("Empty list", [], null);
|
||||
test<int?>("Single value", numbers(1), 1);
|
||||
test<int?>("Multiple values", numbers(3), null);
|
||||
test<int?>("Nullable values", numbers(3, where: even), null);
|
||||
Expect.throws<UnimplementedError>(() => numbers(3, throwAt: 1).singleOrNull,
|
||||
null, "singleOrNull first throws");
|
||||
Expect.throws<UnimplementedError>(() => numbers(3, throwAt: 2).singleOrNull,
|
||||
null, "singleOrNull second throws");
|
||||
test<int?>("Throws after two", numbers(3, throwAt: 3), null);
|
||||
}
|
||||
|
||||
void testElementAtOrNull() {
|
||||
// Static behavior.
|
||||
{
|
||||
Iterable<int> target = [];
|
||||
var result = target.elementAtOrNull(0);
|
||||
result.expectStaticType<Exactly<int?>>();
|
||||
}
|
||||
{
|
||||
Iterable<int?> target = [];
|
||||
var result = target.elementAtOrNull(0);
|
||||
result.expectStaticType<Exactly<int?>>();
|
||||
}
|
||||
{
|
||||
Iterable<Never> target = [];
|
||||
var result = target.elementAtOrNull(0);
|
||||
result.expectStaticType<Exactly<Null>>();
|
||||
}
|
||||
// Dynamic behavior.
|
||||
void test<T>(String name, Iterable<T> source, int index, T? expectedResult) {
|
||||
var actualResult = source.elementAtOrNull(index);
|
||||
Expect.equals(
|
||||
expectedResult, actualResult, "elementAtOrNull($index) $name");
|
||||
}
|
||||
|
||||
Expect.throwsArgumentError(() => numbers(3).elementAtOrNull(-1),
|
||||
"elementAtOrNull(negative) first throws");
|
||||
|
||||
test<int>("Empty iterable", Iterable<int>.empty(), 0, null);
|
||||
test<int>("Empty iterable", Iterable<int>.empty(), 1000000, null);
|
||||
test<Never>("Empty iterable", Iterable<Never>.empty(), 0, null);
|
||||
test<int>("Empty list", [], 0, null);
|
||||
test<int?>("Single value", numbers(1), 0, 1);
|
||||
test<int?>("Single value", numbers(1), 1, null);
|
||||
test<int?>("Multiple values first", numbers(3), 0, 1);
|
||||
test<int?>("Multiple values mid", numbers(3), 1, 2);
|
||||
test<int?>("Multiple values last", numbers(3), 2, 3);
|
||||
test<int?>("Multiple values overshoot", numbers(3), 3, null);
|
||||
test<int?>("Nullable values found", numbers(3, where: even), 2, null);
|
||||
test<int?>("Nullable values not found", numbers(3, where: even), 3, null);
|
||||
Expect.throws<UnimplementedError>(
|
||||
() => numbers(3, throwAt: 1).elementAtOrNull(1),
|
||||
null,
|
||||
"elementAtOrNull(1) first throws");
|
||||
Expect.throws<UnimplementedError>(
|
||||
() => numbers(3, throwAt: 2).elementAtOrNull(2),
|
||||
null,
|
||||
"elementAtOrNull(2) second throws");
|
||||
test<int?>("Throws after two", numbers(3, throwAt: 3), 1, 2);
|
||||
|
||||
var currentThrow2 = CurrentThrowIterable<int?>(numbers(3), 2);
|
||||
test<int?>("Throws current middle", currentThrow2, 0, 1);
|
||||
test<int?>("Throws current middle", currentThrow2, 2, 3);
|
||||
Expect.throws<UnimplementedError>(() => currentThrow2.elementAt(1));
|
||||
}
|
||||
|
||||
void testIndexed() {
|
||||
void test<T>(String name, Iterable<T> elements) {
|
||||
var values = elements.toList();
|
||||
var indexed = elements.indexed;
|
||||
testRec(name, values, indexed, 0, false);
|
||||
}
|
||||
|
||||
// Non-efficient-length iterables.
|
||||
test<int?>("NELI empty", numbers(0));
|
||||
test<int?>("NELI single", numbers(1));
|
||||
test<int?>("NELI two", numbers(2));
|
||||
test<int?>("NELI more", numbers(10));
|
||||
|
||||
// Efficient-length iterables (a list's `map` has efficient length).
|
||||
test<int?>("ELI empty", numbers(0).toList().map((x) => x));
|
||||
test<int?>("ELI single", numbers(1).toList().map((x) => x));
|
||||
test<int?>("ELI two", numbers(2).toList().map((x) => x));
|
||||
test<int?>("ELI more", numbers(10).toList().map((x) => x));
|
||||
}
|
||||
|
||||
// Helper function for `testIndexed`. Top-level because dart2js crashes
|
||||
// on recursive generic local functions.
|
||||
//
|
||||
// If [rec] is true, we're doing a recursive test on skip/take/both,
|
||||
// and `start` the number of leading elements skipped.
|
||||
void testRec<T>(String name, List<T> values, Iterable<(int, T)> indexed,
|
||||
int start, bool rec) {
|
||||
var length = values.length;
|
||||
Expect.equals(length, indexed.length, "$values length");
|
||||
Expect.equals(values.isEmpty, indexed.isEmpty);
|
||||
Expect.equals(values.isNotEmpty, indexed.isNotEmpty);
|
||||
Expect.listEquals([for (var i = 0; i < length; i++) (start + i, values[i])],
|
||||
indexed.toList());
|
||||
|
||||
int index = 0;
|
||||
indexed.forEach((pair) {
|
||||
Expect.equals(start + index, pair.$1);
|
||||
Expect.equals(values[index], pair.$2);
|
||||
index++;
|
||||
});
|
||||
Expect.equals(length, index);
|
||||
|
||||
Expect.isFalse(indexed.contains(0));
|
||||
Expect.isFalse(indexed.contains((start - 1, 0)));
|
||||
Expect.isFalse(indexed.contains((start + length, 0)));
|
||||
|
||||
if (values.isNotEmpty) {
|
||||
Expect.isFalse(indexed.contains(values.first));
|
||||
Expect.equals((start, values.first), indexed.first);
|
||||
Expect.equals((start + length - 1, values.last), indexed.last);
|
||||
for (var i = 0; i < length; i++) {
|
||||
Expect.equals((start + i, values[i]), indexed.elementAt(i));
|
||||
Expect.isTrue(indexed.contains((start + i, values[i])));
|
||||
}
|
||||
Expect.isFalse(indexed.contains((start - 1, values.first)));
|
||||
Expect.isFalse(indexed.contains((start + length, values.last)));
|
||||
if (length == 1) {
|
||||
Expect.equals((start, values.single), indexed.single);
|
||||
} else if (!rec) {
|
||||
Expect.throws<StateError>(() => indexed.single);
|
||||
// More than one element, so test skip/take.
|
||||
testRec("$name.skip(1)", values.sublist(1), indexed.skip(1), 1, true);
|
||||
testRec("$name.take(l-1)", values.sublist(0, length - 1),
|
||||
indexed.take(length - 1), 0, true);
|
||||
if (length > 2) {
|
||||
testRec("$name.skip(1).take(l-2)", values.sublist(1, length - 1),
|
||||
indexed.skip(1).take(length - 2), 1, true);
|
||||
testRec("$name.take(l-1).skip(1)", values.sublist(1, length - 1),
|
||||
indexed.take(length - 1).skip(1), 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Generates an iterable with [length] elements.
|
||||
///
|
||||
/// The elements are 1, ..., [length], except that if `isValue` returns
|
||||
/// `false` for a number, it's replaced by `null`.
|
||||
/// If [throwAt] is provided, the iterable throws an `UnimplementedError`
|
||||
/// (which shouldn't conflict with an actual error) instead of emitting
|
||||
/// a value at the [throwAt] index.
|
||||
Iterable<int?> numbers(int length,
|
||||
{bool Function(int) where = all, int? throwAt}) sync* {
|
||||
for (var i = 1; i <= length; i++) {
|
||||
if (i == throwAt) throw UnimplementedError("Error");
|
||||
yield where(i) ? i : null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterable which throws only when accessing [current].
|
||||
///
|
||||
/// Used to test that operations that don't need the value,
|
||||
/// also don't read it.
|
||||
///
|
||||
/// (Could also be achieved with
|
||||
/// ```
|
||||
/// _source.toList().map((x) => x == _throwAt ? throw ... : x));
|
||||
/// ```
|
||||
/// but that assumes optimization behavior that is not necessarily tested.)
|
||||
class CurrentThrowIterable<T> extends Iterable<T> {
|
||||
final T _throwAt;
|
||||
final Iterable<T> _source;
|
||||
CurrentThrowIterable(this._source, this._throwAt);
|
||||
Iterator<T> get iterator =>
|
||||
CurrentThrowIterator<T>(_source.iterator, _throwAt);
|
||||
}
|
||||
|
||||
class CurrentThrowIterator<T> implements Iterator<T> {
|
||||
final T _throwAt;
|
||||
Iterator<T> _source;
|
||||
CurrentThrowIterator(this._source, this._throwAt);
|
||||
bool moveNext() => _source.moveNext();
|
||||
T get current {
|
||||
var result = _source.current;
|
||||
if (result == _throwAt) throw UnimplementedError("Error");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
bool none(_) => false;
|
||||
bool all(_) => true;
|
||||
bool even(int n) => n.isEven;
|
||||
bool Function(int) only(int n1) => (int n2) => n1 == n2;
|
Loading…
Reference in a new issue