Version 2.15.0-112.0.dev
Merge commit '9ecb2d0616d55b57730a5f9784eb6bb4627382eb' into 'dev'
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_return_type_nullable.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_return_type_nullable.dart
index 2f2107d..146e42b 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_return_type_nullable.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_return_type_nullable.dart
@@ -25,6 +25,11 @@
return;
}
+ final type = node.staticType;
+ if (type == null) {
+ return;
+ }
+
var body = node.thisOrAncestorOfType<FunctionBody>();
if (body == null) {
return;
@@ -37,22 +42,22 @@
if (body.isAsynchronous || body.isGenerator) {
if (returnType is! NamedType) {
- return null;
+ return;
}
var typeArguments = returnType.typeArguments;
if (typeArguments == null) {
- return null;
+ return;
}
var arguments = typeArguments.arguments;
if (arguments.length != 1) {
- return null;
+ return;
}
returnType = arguments[0];
}
if (node is! NullLiteral &&
- !typeSystem.isAssignableTo(returnType.typeOrThrow,
- typeSystem.promoteToNonNull(node.typeOrThrow))) {
+ !typeSystem.isAssignableTo(
+ returnType.typeOrThrow, typeSystem.promoteToNonNull(type))) {
return;
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/make_return_type_nullable_test.dart b/pkg/analysis_server/test/src/services/correction/fix/make_return_type_nullable_test.dart
index 1b3a4cc..ae6ff05 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/make_return_type_nullable_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/make_return_type_nullable_test.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -86,6 +87,23 @@
''');
}
+ /// This code is parsed in such a way that we find `void` as an `Expression`.
+ /// But this expression is a name in a `NamedType`, and so `NamedType` has
+ /// the `type`, but not `void` - its type is `null`. So, the producer should
+ /// check for `null`, and don't expect that every expression has a type.
+ Future<void> test_getter_sync_invalidVoid() async {
+ await resolveTestCode('''
+int f() {
+ return void;
+}
+''');
+ await assertNoFix(
+ errorFilter: (e) =>
+ e.errorCode ==
+ CompileTimeErrorCode.RETURN_OF_INVALID_TYPE_FROM_FUNCTION,
+ );
+ }
+
Future<void> test_incompatibilityIsNotLimitedToNullability() async {
await resolveTestCode('''
int f() {
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index bc6446c..67f2db7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -171,15 +171,6 @@
final _indexRequestedFiles =
<String, List<Completer<AnalysisDriverUnitIndex>>>{};
- /// The mapping from the files for which the unit element key was requested
- /// using `getUnitElementSignature` to the [Completer]s to report the result.
- final _unitElementSignatureFiles = <String, List<Completer<String>>>{};
-
- /// The mapping from the files for which the unit element key was requested
- /// using `getUnitElementSignature`, and which were found to be parts without
- /// known libraries, to the [Completer]s to report the result.
- final _unitElementSignatureParts = <String, List<Completer<String>>>{};
-
/// The mapping from the files for which the unit element was requested using
/// [getUnitElement2] to the [Completer]s to report the result.
final _unitElementRequestedFiles =
@@ -434,9 +425,6 @@
if (_indexRequestedFiles.isNotEmpty) {
return AnalysisDriverPriority.interactive;
}
- if (_unitElementSignatureFiles.isNotEmpty) {
- return AnalysisDriverPriority.interactive;
- }
if (_unitElementRequestedFiles.isNotEmpty) {
return AnalysisDriverPriority.interactive;
}
@@ -465,7 +453,6 @@
if (_errorsRequestedParts.isNotEmpty ||
_requestedParts.isNotEmpty ||
_partsToAnalyze.isNotEmpty ||
- _unitElementSignatureParts.isNotEmpty ||
_unitElementRequestedParts.isNotEmpty) {
return AnalysisDriverPriority.general;
}
@@ -837,17 +824,6 @@
);
}
- ApiSignature getResolvedUnitKeyByPath(String path) {
- _throwIfNotAbsolutePath(path);
- var file = fsState.getFileForPath(path);
-
- var signature = ApiSignature();
- signature.addUint32List(_saltForResolution);
- signature.addString(file.transitiveSignature);
- signature.addString(file.contentHash);
- return signature;
- }
-
/// Return a [Future] that completes with a [SomeResolvedUnitResult] for the
/// Dart file with the given [path]. If the file cannot be analyzed,
/// the [Future] completes with an [InvalidResult].
@@ -1057,23 +1033,6 @@
return;
}
- // Process a unit element key request.
- if (_unitElementSignatureFiles.isNotEmpty) {
- String path = _unitElementSignatureFiles.keys.first;
- String? signature = _computeUnitElementSignature(path);
- var completers = _unitElementSignatureFiles.remove(path)!;
- if (signature != null) {
- completers.forEach((completer) {
- completer.complete(signature);
- });
- } else {
- _unitElementSignatureParts
- .putIfAbsent(path, () => [])
- .addAll(completers);
- }
- return;
- }
-
// Process a unit element request.
if (_unitElementRequestedFiles.isNotEmpty) {
String path = _unitElementRequestedFiles.keys.first;
@@ -1211,17 +1170,6 @@
return;
}
- // Process a unit element signature request for a part.
- if (_unitElementSignatureParts.isNotEmpty) {
- String path = _unitElementSignatureParts.keys.first;
- String signature =
- _computeUnitElementSignature(path, asIsIfPartWithoutLibrary: true)!;
- _unitElementSignatureParts.remove(path)!.forEach((completer) {
- completer.complete(signature);
- });
- return;
- }
-
// Process a unit element request for a part.
if (_unitElementRequestedParts.isNotEmpty) {
String path = _unitElementRequestedParts.keys.first;
@@ -1508,23 +1456,6 @@
});
}
- String? _computeUnitElementSignature(String path,
- {bool asIsIfPartWithoutLibrary = false}) {
- FileState file = _fsState.getFileForPath(path);
-
- // Prepare the library - the file itself, or the known library.
- FileState? library = file.isPart ? file.library : file;
- if (library == null) {
- if (asIsIfPartWithoutLibrary) {
- library = file;
- } else {
- return null;
- }
- }
-
- return library.transitiveSignature;
- }
-
/// Creates new [FileSystemState] and [FileTracker] objects.
///
/// This is used both on initial construction and whenever the configuration
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 66bc7a5..3132dfd 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -141,7 +141,6 @@
LibraryCycle? _libraryCycle;
String? _transitiveSignature;
- String? _transitiveSignatureLinked;
/// The flag that shows whether the file has an error or warning that
/// might be fixed by a change to another file.
@@ -350,11 +349,6 @@
return _transitiveSignature!;
}
- /// The value `transitiveSignature.linked` is used often, so we cache it.
- String get transitiveSignatureLinked {
- return _transitiveSignatureLinked ??= '$transitiveSignature.linked';
- }
-
/// The [UnlinkedUnit2] of the file.
UnlinkedUnit2 get unlinked2 => _unlinked2!;
@@ -390,7 +384,6 @@
if (cycle == null) {
_libraryCycle = null;
_transitiveSignature = null;
- _transitiveSignatureLinked = null;
} else {
_libraryCycle = cycle;
_transitiveSignature = signature;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
index 413d6ab..2d5b660 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
@@ -36,20 +36,6 @@
/// files that [libraries] reference (but we don't compute these files).
String? transitiveSignature;
- /// The map from a library in [libraries] to its transitive signature.
- ///
- /// It is almost the same as [transitiveSignature], but is also based on
- /// the URI of this specific library. Currently we store each linked library
- /// with its own key, so we need unique keys. However practically we never
- /// can use just *one* library of a cycle, we always use the whole cycle.
- ///
- /// TODO(scheglov) Switch to loading the whole cycle maybe?
- final Map<FileState, String> transitiveSignatures = {};
-
- LibraryCycle();
-
- LibraryCycle.external() : transitiveSignature = '<external>';
-
/// Invalidate this cycle and any cycles that directly or indirectly use it.
///
/// Practically invalidation means that we clear the library cycle in all the
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index d1755aa..87d4094 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -1409,7 +1409,8 @@
if (targetChecks.checkAllParameters ||
(targetChecks.checkCovariantParameters &&
- (variable.isCovariantByClass || variable.isCovariantByDeclaration))) {
+ (variable.isCovariantByClass ||
+ variable.isCovariantByDeclaration))) {
newParameter = _typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
targetElement, newParameter, type);
} else {
@@ -3747,7 +3748,7 @@
// Filter elided parameters.
.where((p) => parameterStructure.namedParameters.contains(p.name))
.toList()
- ..sort(namedOrdering);
+ ..sort(namedOrdering);
for (ir.VariableDeclaration parameter in namedParameters) {
HInstruction value = namedValues[parameter.name];
if (value == null) {
@@ -6526,6 +6527,10 @@
const <DartType>[],
sourceInformation: trySourceInformation);
HInvokeStatic unwrappedException = kernelBuilder.pop();
+ unwrappedException.sideEffects
+ ..clearAllDependencies()
+ ..clearAllSideEffects();
+ unwrappedException.targetCanThrow = false;
tryInstruction.exception = exception;
int catchesIndex = 0;
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 886f1f0..a01c6bf 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -1933,7 +1933,7 @@
/// The type arguments passed in this static invocation.
final List<DartType> typeArguments;
- final bool targetCanThrow;
+ bool targetCanThrow;
@override
bool canThrow(AbstractValueDomain domain) => targetCanThrow;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 8877f33..fde9609 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -3327,6 +3327,14 @@
bool newGvnCandidates = false;
HGraph _graph;
+ // Blocks that can be reached via control flow not expressed by the basic
+ // block CFG. These are catch and finally blocks that are reached from some
+ // mid-block instruction that throws in the CFG region corresponding to the
+ // Dart language try-block. The value stored in the map is the HTry that owns
+ // the catch or finally block. This map is filled in on-the-fly since the HTry
+ // dominates the catch and finally so is visited first.
+ Map<HBasicBlock, HTry> _blocksWithImprecisePredecessors;
+
SsaLoadElimination(this._closedWorld)
: _fieldAnalysis = _closedWorld.fieldAnalysis;
@@ -3416,6 +3424,15 @@
}
}
+ // If the current block is a catch or finally block, it is reachable from
+ // any instruction in the try region that can generate an exception.
+ if (_blocksWithImprecisePredecessors != null) {
+ final tryInstruction = _blocksWithImprecisePredecessors[block];
+ if (tryInstruction != null) {
+ memorySet.killLocationsForExceptionEdge();
+ }
+ }
+
memories[block.id] = memorySet;
HInstruction instruction = block.first;
while (instruction != null) {
@@ -3425,6 +3442,17 @@
}
}
+ @override
+ visitTry(HTry instruction) {
+ _blocksWithImprecisePredecessors ??= {};
+ if (instruction.catchBlock != null) {
+ _blocksWithImprecisePredecessors[instruction.catchBlock] = instruction;
+ }
+ if (instruction.finallyBlock != null) {
+ _blocksWithImprecisePredecessors[instruction.finallyBlock] = instruction;
+ }
+ }
+
void checkNewGvnCandidates(HInstruction instruction, HInstruction existing) {
if (newGvnCandidates) return;
bool hasUseGvn(HInstruction insn) => insn.nonCheck().useGvn();
@@ -3712,6 +3740,30 @@
return !nonEscapingReceivers.contains(receiver);
}
+ /// Kills locations that are imprecise due to many possible edges from
+ /// instructions in the try region that can throw.
+ void killLocationsForExceptionEdge() {
+ // Ideally we would treat each strong (must) update in the try region as a
+ // weak (may) update at the catch block, but we don't track this. The
+ // conservative approximation is to kill everything.
+ //
+ // Aliases can be retained because they are not updated - they are generated
+ // by an allocation and are killed by escaping. There is an edge from any
+ // exit from the try region to the catch block which accounts for the kills
+ // via escapes. Similarly, array lengths don't have updates (set:length is
+ // modeled as an escape which kills the length on some path), so lengths
+ // don't need to be killed here.
+ //
+ // TODO(sra): A more precise accounting of the effects in the try region
+ // might improve precision.
+ fieldValues.forEach((key, map) {
+ if (key != MemoryFeature.length) {
+ map?.clear();
+ }
+ });
+ keyedValues.clear();
+ }
+
void registerAllocation(HInstruction instruction) {
assert(instruction == instruction.nonCheck());
nonEscapingReceivers.add(instruction);
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index d25cbd8..24ac86f 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -584,7 +584,8 @@
@override
String visitExitTry(HExitTry node) {
- return "ExitTry";
+ final targets = currentBlock.successors.map((block) => 'B${block.id}');
+ return "ExitTry: (${targets.join(', ')})";
}
@override
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index 6e63cb6..ad1c27b 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -39,7 +39,6 @@
package_config: any
path: any
source_maps: any
- test: any
cli_util: any
# Unpublished packages that can be used via path dependency
async_helper:
diff --git a/pkg/compiler/test/kernel/common_test_utils.dart b/pkg/compiler/test/kernel/common_test_utils.dart
deleted file mode 100644
index ed7c9e5..0000000
--- a/pkg/compiler/test/kernel/common_test_utils.dart
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:front_end/src/api_unstable/dart2js.dart'
- show
- CompilerOptions,
- DiagnosticMessage,
- computePlatformBinariesLocation,
- kernelForProgram,
- parseExperimentalArguments,
- parseExperimentalFlags;
-import 'package:kernel/ast.dart';
-import 'package:kernel/text/ast_to_text.dart' show Printer;
-import 'package:kernel/target/targets.dart';
-import 'package:test/test.dart';
-
-import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
-
-/// Environment define to update expectation files on failures.
-const kUpdateExpectations = 'updateExpectations';
-
-/// Environment define to dump actual results alongside expectations.
-const kDumpActualResult = 'dump.actual.result';
-
-class TestingDart2jsTarget extends Dart2jsTarget {
- TestingDart2jsTarget(TargetFlags flags) : super('dart2js', flags);
-}
-
-Future<Component> compileTestCaseToKernelProgram(Uri sourceUri,
- {Target target,
- bool enableSuperMixins = false,
- List<String> experimentalFlags,
- Map<String, String> environmentDefines}) async {
- final platformKernel =
- computePlatformBinariesLocation().resolve('dart2js_platform.dill');
- target ??= TestingDart2jsTarget(TargetFlags());
- environmentDefines ??= <String, String>{};
- final options = CompilerOptions()
- ..target = target
- ..additionalDills = <Uri>[platformKernel]
- ..environmentDefines = environmentDefines
- ..explicitExperimentalFlags =
- parseExperimentalFlags(parseExperimentalArguments(experimentalFlags),
- onError: (String message) {
- throw message;
- })
- ..onDiagnostic = (DiagnosticMessage message) {
- fail("Compilation error: ${message.plainTextFormatted.join('\n')}");
- };
-
- final Component component =
- (await kernelForProgram(sourceUri, options)).component;
-
- // Make sure the library name is the same and does not depend on the order
- // of test cases.
- component.mainMethod.enclosingLibrary.name = '#lib';
-
- return component;
-}
-
-String kernelLibraryToString(Library library) {
- final buffer = StringBuffer();
- Printer(buffer, showMetadata: true).writeLibraryFile(library);
- return buffer
- .toString()
- .replaceAll(library.importUri.toString(), library.name);
-}
-
-String kernelComponentToString(Component component) {
- final buffer = StringBuffer();
- Printer(buffer, showMetadata: true).writeComponentFile(component);
- final mainLibrary = component.mainMethod.enclosingLibrary;
- return buffer
- .toString()
- .replaceAll(mainLibrary.importUri.toString(), mainLibrary.name);
-}
-
-class Difference {
- final int line;
- final String actual;
- final String expected;
-
- Difference(this.line, this.actual, this.expected);
-}
-
-Difference findFirstDifference(String actual, String expected) {
- final actualLines = actual.split('\n');
- final expectedLines = expected.split('\n');
- int i = 0;
- for (; i < actualLines.length && i < expectedLines.length; ++i) {
- if (actualLines[i] != expectedLines[i]) {
- return Difference(i + 1, actualLines[i], expectedLines[i]);
- }
- }
- return Difference(i + 1, i < actualLines.length ? actualLines[i] : '<END>',
- i < expectedLines.length ? expectedLines[i] : '<END>');
-}
-
-void compareResultWithExpectationsFile(Uri source, String actual) {
- final expectFile = File(source.toFilePath() + '.expect');
- final expected = expectFile.existsSync() ? expectFile.readAsStringSync() : '';
-
- if (actual != expected) {
- if (bool.fromEnvironment(kUpdateExpectations)) {
- expectFile.writeAsStringSync(actual);
- print(" Updated $expectFile");
- } else {
- if (bool.fromEnvironment(kDumpActualResult)) {
- File(source.toFilePath() + '.actual').writeAsStringSync(actual);
- }
- Difference diff = findFirstDifference(actual, expected);
- fail("""
-
-Result is different for the test case $source
-
-The first difference is at line ${diff.line}.
-Actual: ${diff.actual}
-Expected: ${diff.expected}
-
-This failure can be caused by changes in the front-end if it starts generating
-different kernel AST for the same Dart programs.
-
-In order to re-generate expectations run tests with -D$kUpdateExpectations=true VM option:
-
- sdk/bin/dart -D$kUpdateExpectations=true pkg/compiler/test/kernel/goldens_test.dart
-
-In order to dump actual results into .actual files run tests with -D$kDumpActualResult=true VM option.
-""");
- }
- }
-}
diff --git a/pkg/compiler/test/kernel/data/list_generate_1.dart.expect b/pkg/compiler/test/kernel/data/list_generate_1.dart.expect
deleted file mode 100644
index 62d51f9..0000000
--- a/pkg/compiler/test/kernel/data/list_generate_1.dart.expect
+++ /dev/null
@@ -1,32 +0,0 @@
-library #lib;
-import self as self;
-import "dart:core" as core;
-import "dart:_interceptors" as _in;
-
-static field core::List<core::int*>* list1 = block {
- final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(10);
- for (core::int i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int) →* core::int}) {
- core::int* i = i;
- _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int*) → void};
- }
-} =>_list;
-static field core::List<core::int*>* list2 = block {
- final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(10);
- for (core::int i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int) →* core::int}) {
- core::int* i = i;
- _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int*) → void};
- }
-} =>_list;
-static field core::List<core::int*>* list3 = block {
- final _in::JSArray<core::int*> _list = _in::JSArray::allocateFixed<core::int*>(10);
- for (core::int i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int) →* core::int}) {
- core::int* i = i;
- _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int*) → void};
- }
-} =>_list;
-static field core::List<core::int*>* list4 = core::List::generate<core::int*>(10, (core::int* i) → core::int* => i, growable: self::someGrowable);
-static field core::bool* someGrowable = true;
-static method main() → void {
- self::someGrowable = !self::someGrowable;
- core::print(<core::List<core::int*>*>[self::list1, self::list2, self::list3, self::list4]);
-}
diff --git a/pkg/compiler/test/kernel/data/list_generate_2.dart.expect b/pkg/compiler/test/kernel/data/list_generate_2.dart.expect
deleted file mode 100644
index c87b037..0000000
--- a/pkg/compiler/test/kernel/data/list_generate_2.dart.expect
+++ /dev/null
@@ -1,21 +0,0 @@
-library #lib;
-import self as self;
-import "dart:core" as core;
-import "dart:_interceptors" as _in;
-
-static method main() → void {
- core::print( block {
- final _in::JSArray<core::List<core::int*>*> _list = _in::JSArray::allocateGrowable<core::List<core::int*>*>(10);
- for (core::int i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int) →* core::int}) {
- core::int* i = i;
- _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, block {
- final core::int _length = i;
- final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(_length);
- for (core::int i = 0; i.{core::num::<}(_length){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int) →* core::int}) {
- core::int* i = i;
- _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i.{core::num::+}(1){(core::num*) →* core::int*}){(core::int, core::int*) → void};
- }
- } =>_list){(core::int, core::List<core::int*>*) → void};
- }
- } =>_list);
-}
diff --git a/pkg/compiler/test/kernel/data/list_generate_3.dart.expect b/pkg/compiler/test/kernel/data/list_generate_3.dart.expect
deleted file mode 100644
index c8614fa..0000000
--- a/pkg/compiler/test/kernel/data/list_generate_3.dart.expect
+++ /dev/null
@@ -1,51 +0,0 @@
-library #lib;
-import self as self;
-import "dart:core" as core;
-import "dart:_interceptors" as _in;
-
-static field core::List<core::int*>* list1 = block {
- final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(10);
- for (core::int i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int) →* core::int}) {
- core::int* i = i;
- {
- _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int*) → void};
- }
- }
-} =>_list;
-static field core::List<core::int*>* list2 = block {
- final _in::JSArray<core::int*> _list = _in::JSArray::allocateGrowable<core::int*>(10);
- for (core::int i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int) →* core::int}) {
- core::int* i = i;
- {
- _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int*) → void};
- }
- }
-} =>_list;
-static field core::List<core::int*>* list3 = block {
- final _in::JSArray<core::int*> _list = _in::JSArray::allocateFixed<core::int*>(10);
- for (core::int i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int) →* core::int}) {
- core::int* i = i;
- {
- _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int*) → void};
- }
- }
-} =>_list;
-static field core::List<core::int*>* list4 = core::List::generate<core::int*>(10, (core::int* i) → core::int* {
- return i;
-}, growable: self::someGrowable);
-static field core::List<core::int*>* list5 = core::List::generate<core::int*>(10, (core::int* i) → core::int* {
- if(i.{core::int::isEven}{core::bool*})
- return i.{core::num::+}(1){(core::num*) →* core::int*};
- return i.{core::num::-}(1){(core::num*) →* core::int*};
-});
-static field core::List<core::int*>* list6 = core::List::generate<core::int*>(10, #C1);
-static field core::List<core::int*>* list7 = core::List::generate<core::int*>(10, self::bar);
-static field core::bool* someGrowable = true;
-static method foo(core::int* i) → core::int*
- return i;
-static get bar() → (core::int*) →* core::int*
- return #C1;
-static method main() → void {
- self::someGrowable = !self::someGrowable;
- core::print(<core::List<core::int*>*>[self::list1, self::list2, self::list3, self::list4, self::list5, self::list6, self::list7]);
-}
diff --git a/pkg/compiler/test/kernel/goldens_test.dart b/pkg/compiler/test/kernel/goldens_test.dart
deleted file mode 100644
index dcef219..0000000
--- a/pkg/compiler/test/kernel/goldens_test.dart
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:kernel/target/targets.dart';
-import 'package:kernel/ast.dart';
-import 'package:kernel/kernel.dart';
-import 'package:test/test.dart';
-
-import 'common_test_utils.dart';
-
-final String testRootDir = Platform.script.resolve('.').toFilePath();
-
-runTestCase(
- Uri source, List<String> experimentalFlags, bool soundNullSafety) async {
- final target =
- TestingDart2jsTarget(TargetFlags(enableNullSafety: soundNullSafety));
- Component component = await compileTestCaseToKernelProgram(source,
- target: target, experimentalFlags: experimentalFlags);
-
- String actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
-
- compareResultWithExpectationsFile(source, actual);
-}
-
-main() {
- group('goldens', () {
- final testCasesDir = new Directory(testRootDir + '/data');
-
- for (var entry
- in testCasesDir.listSync(recursive: true, followLinks: false)) {
- final path = entry.path;
- if (path.endsWith('.dart')) {
- final bool unsoundNullSafety = path.endsWith('_unsound.dart');
- test(
- path,
- () => runTestCase(
- entry.uri, const ['non-nullable'], !unsoundNullSafety));
- }
- }
- }, timeout: Timeout.none);
-}
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 2ee0aa7..dd9f732 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1539,6 +1539,7 @@
inout
input
inputs
+inscrutable
insert
inserted
inserting
diff --git a/pkg/compiler/test/kernel/data/list_generate_1.dart b/pkg/front_end/testcases/dart2js/list_generate_1.dart
similarity index 100%
rename from pkg/compiler/test/kernel/data/list_generate_1.dart
rename to pkg/front_end/testcases/dart2js/list_generate_1.dart
diff --git a/pkg/front_end/testcases/dart2js/list_generate_1.dart.strong.expect b/pkg/front_end/testcases/dart2js/list_generate_1.dart.strong.expect
new file mode 100644
index 0000000..ae26523
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_1.dart.strong.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> list1 = core::List::generate<core::int>(10, (core::int i) → core::int => i);
+static field core::List<core::int> list2 = core::List::generate<core::int>(10, (core::int i) → core::int => i, growable: true);
+static field core::List<core::int> list3 = core::List::generate<core::int>(10, (core::int i) → core::int => i, growable: false);
+static field core::List<core::int> list4 = core::List::generate<core::int>(10, (core::int i) → core::int => i, growable: self::someGrowable);
+static field core::bool someGrowable = true;
+static method main() → void {
+ self::someGrowable = !self::someGrowable;
+ core::print(<core::List<core::int>>[self::list1, self::list2, self::list3, self::list4]);
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_1.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate_1.dart.strong.transformed.expect
new file mode 100644
index 0000000..037687b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_1.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static field core::List<core::int> list1 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+} =>_list;
+static field core::List<core::int> list2 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+} =>_list;
+static field core::List<core::int> list3 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateFixed<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+} =>_list;
+static field core::List<core::int> list4 = core::List::generate<core::int>(10, (core::int i) → core::int => i, growable: self::someGrowable);
+static field core::bool someGrowable = true;
+static method main() → void {
+ self::someGrowable = !self::someGrowable;
+ core::print(<core::List<core::int>>[self::list1, self::list2, self::list3, self::list4]);
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_1.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/list_generate_1.dart.textual_outline.expect
new file mode 100644
index 0000000..d940e13
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_1.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+var list1 = List<int>.generate(10, (i) => i);
+var list2 = List<int>.generate(10, (i) => i, growable: true);
+var list3 = List<int>.generate(10, (i) => i, growable: false);
+var list4 = List<int>.generate(10, (i) => i, growable: someGrowable);
+bool someGrowable = true;
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_1.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/list_generate_1.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..4ed37d0
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_1.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+bool someGrowable = true;
+var list1 = List<int>.generate(10, (i) => i);
+var list2 = List<int>.generate(10, (i) => i, growable: true);
+var list3 = List<int>.generate(10, (i) => i, growable: false);
+var list4 = List<int>.generate(10, (i) => i, growable: someGrowable);
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.expect b/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.expect
new file mode 100644
index 0000000..ae26523
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.expect
@@ -0,0 +1,13 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> list1 = core::List::generate<core::int>(10, (core::int i) → core::int => i);
+static field core::List<core::int> list2 = core::List::generate<core::int>(10, (core::int i) → core::int => i, growable: true);
+static field core::List<core::int> list3 = core::List::generate<core::int>(10, (core::int i) → core::int => i, growable: false);
+static field core::List<core::int> list4 = core::List::generate<core::int>(10, (core::int i) → core::int => i, growable: self::someGrowable);
+static field core::bool someGrowable = true;
+static method main() → void {
+ self::someGrowable = !self::someGrowable;
+ core::print(<core::List<core::int>>[self::list1, self::list2, self::list3, self::list4]);
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.outline.expect
new file mode 100644
index 0000000..fd26d48
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.outline.expect
@@ -0,0 +1,11 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> list1;
+static field core::List<core::int> list2;
+static field core::List<core::int> list3;
+static field core::List<core::int> list4;
+static field core::bool someGrowable;
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.transformed.expect
new file mode 100644
index 0000000..037687b
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_1.dart.weak.transformed.expect
@@ -0,0 +1,32 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static field core::List<core::int> list1 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+} =>_list;
+static field core::List<core::int> list2 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+} =>_list;
+static field core::List<core::int> list3 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateFixed<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+} =>_list;
+static field core::List<core::int> list4 = core::List::generate<core::int>(10, (core::int i) → core::int => i, growable: self::someGrowable);
+static field core::bool someGrowable = true;
+static method main() → void {
+ self::someGrowable = !self::someGrowable;
+ core::print(<core::List<core::int>>[self::list1, self::list2, self::list3, self::list4]);
+}
diff --git a/pkg/compiler/test/kernel/data/list_generate_2.dart b/pkg/front_end/testcases/dart2js/list_generate_2.dart
similarity index 100%
rename from pkg/compiler/test/kernel/data/list_generate_2.dart
rename to pkg/front_end/testcases/dart2js/list_generate_2.dart
diff --git a/pkg/front_end/testcases/dart2js/list_generate_2.dart.strong.expect b/pkg/front_end/testcases/dart2js/list_generate_2.dart.strong.expect
new file mode 100644
index 0000000..d3c85ea
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_2.dart.strong.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+ core::print(core::List::generate<core::List<core::int>>(10, (core::int i) → core::List<core::int> => core::List::generate<core::int>(i, (core::int i) → core::int => i.{core::num::+}(1){(core::num) → core::int})));
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_2.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..3f9b290
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_2.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static method main() → void {
+ core::print( block {
+ final _in::JSArray<core::List<core::int>> _list = _in::JSArray::allocateGrowable<core::List<core::int>>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, block {
+ final core::int* _length = i;
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(_length);
+ for (core::int* i = 0; i.{core::num::<}(_length){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i.{core::num::+}(1){(core::num) → core::int}){(core::int, core::int) → void};
+ }
+ } =>_list){(core::int, core::List<core::int>) → void};
+ }
+ } =>_list);
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_2.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/list_generate_2.dart.textual_outline.expect
new file mode 100644
index 0000000..ab73b3a
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_2.dart.textual_outline.expect
@@ -0,0 +1 @@
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_2.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/list_generate_2.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..ab73b3a
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_2.dart.textual_outline_modelled.expect
@@ -0,0 +1 @@
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.expect b/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.expect
new file mode 100644
index 0000000..d3c85ea
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.expect
@@ -0,0 +1,7 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+ core::print(core::List::generate<core::List<core::int>>(10, (core::int i) → core::List<core::int> => core::List::generate<core::int>(i, (core::int i) → core::int => i.{core::num::+}(1){(core::num) → core::int})));
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.outline.expect
new file mode 100644
index 0000000..684454e
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.outline.expect
@@ -0,0 +1,5 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.transformed.expect
new file mode 100644
index 0000000..3f9b290
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_2.dart.weak.transformed.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static method main() → void {
+ core::print( block {
+ final _in::JSArray<core::List<core::int>> _list = _in::JSArray::allocateGrowable<core::List<core::int>>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, block {
+ final core::int* _length = i;
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(_length);
+ for (core::int* i = 0; i.{core::num::<}(_length){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i.{core::num::+}(1){(core::num) → core::int}){(core::int, core::int) → void};
+ }
+ } =>_list){(core::int, core::List<core::int>) → void};
+ }
+ } =>_list);
+}
diff --git a/pkg/compiler/test/kernel/data/list_generate_3.dart b/pkg/front_end/testcases/dart2js/list_generate_3.dart
similarity index 100%
rename from pkg/compiler/test/kernel/data/list_generate_3.dart
rename to pkg/front_end/testcases/dart2js/list_generate_3.dart
diff --git a/pkg/front_end/testcases/dart2js/list_generate_3.dart.strong.expect b/pkg/front_end/testcases/dart2js/list_generate_3.dart.strong.expect
new file mode 100644
index 0000000..4f4c5d2
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_3.dart.strong.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> list1 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+});
+static field core::List<core::int> list2 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+}, growable: true);
+static field core::List<core::int> list3 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+}, growable: false);
+static field core::List<core::int> list4 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+}, growable: self::someGrowable);
+static field core::List<core::int> list5 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ if(i.{core::int::isEven}{core::bool})
+ return i.{core::num::+}(1){(core::num) → core::int};
+ return i.{core::num::-}(1){(core::num) → core::int};
+});
+static field core::List<core::int> list6 = core::List::generate<core::int>(10, #C1);
+static field core::List<core::int> list7 = core::List::generate<core::int>(10, self::bar);
+static field core::bool someGrowable = true;
+static method foo(core::int i) → core::int
+ return i;
+static get bar() → (core::int) → core::int
+ return #C1;
+static method main() → void {
+ self::someGrowable = !self::someGrowable;
+ core::print(<core::List<core::int>>[self::list1, self::list2, self::list3, self::list4, self::list5, self::list6, self::list7]);
+}
+
+constants {
+ #C1 = static-tearoff self::foo
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_3.dart.strong.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..8fbe3a6
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_3.dart.strong.transformed.expect
@@ -0,0 +1,55 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static field core::List<core::int> list1 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ {
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+ }
+} =>_list;
+static field core::List<core::int> list2 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ {
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+ }
+} =>_list;
+static field core::List<core::int> list3 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateFixed<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ {
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+ }
+} =>_list;
+static field core::List<core::int> list4 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+}, growable: self::someGrowable);
+static field core::List<core::int> list5 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ if(i.{core::int::isEven}{core::bool})
+ return i.{core::num::+}(1){(core::num) → core::int};
+ return i.{core::num::-}(1){(core::num) → core::int};
+});
+static field core::List<core::int> list6 = core::List::generate<core::int>(10, #C1);
+static field core::List<core::int> list7 = core::List::generate<core::int>(10, self::bar);
+static field core::bool someGrowable = true;
+static method foo(core::int i) → core::int
+ return i;
+static get bar() → (core::int) → core::int
+ return #C1;
+static method main() → void {
+ self::someGrowable = !self::someGrowable;
+ core::print(<core::List<core::int>>[self::list1, self::list2, self::list3, self::list4, self::list5, self::list6, self::list7]);
+}
+
+constants {
+ #C1 = static-tearoff self::foo
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_3.dart.textual_outline.expect b/pkg/front_end/testcases/dart2js/list_generate_3.dart.textual_outline.expect
new file mode 100644
index 0000000..432cc1c
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_3.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+var list1 = List<int>.generate(10, (i) {
+ return i;
+});
+var list2 = List<int>.generate(10, (i) {
+ return i;
+}, growable: true);
+var list3 = List<int>.generate(10, (i) {
+ return i;
+}, growable: false);
+var list4 = List<int>.generate(10, (i) {
+ return i;
+}, growable: someGrowable);
+var list5 = List<int>.generate(10, (i) {
+ if (i.isEven) return i + 1;
+ return i - 1;
+});
+var list6 = List<int>.generate(10, foo);
+int foo(int i) => i;
+var list7 = List<int>.generate(10, bar);
+int Function(int) get bar => foo;
+bool someGrowable = true;
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_3.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/dart2js/list_generate_3.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..79c5b5f
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_3.dart.textual_outline_modelled.expect
@@ -0,0 +1,22 @@
+bool someGrowable = true;
+int Function(int) get bar => foo;
+int foo(int i) => i;
+var list1 = List<int>.generate(10, (i) {
+ return i;
+});
+var list2 = List<int>.generate(10, (i) {
+ return i;
+}, growable: true);
+var list3 = List<int>.generate(10, (i) {
+ return i;
+}, growable: false);
+var list4 = List<int>.generate(10, (i) {
+ return i;
+}, growable: someGrowable);
+var list5 = List<int>.generate(10, (i) {
+ if (i.isEven) return i + 1;
+ return i - 1;
+});
+var list6 = List<int>.generate(10, foo);
+var list7 = List<int>.generate(10, bar);
+void main() {}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.expect b/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.expect
new file mode 100644
index 0000000..4f4c5d2
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.expect
@@ -0,0 +1,36 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> list1 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+});
+static field core::List<core::int> list2 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+}, growable: true);
+static field core::List<core::int> list3 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+}, growable: false);
+static field core::List<core::int> list4 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+}, growable: self::someGrowable);
+static field core::List<core::int> list5 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ if(i.{core::int::isEven}{core::bool})
+ return i.{core::num::+}(1){(core::num) → core::int};
+ return i.{core::num::-}(1){(core::num) → core::int};
+});
+static field core::List<core::int> list6 = core::List::generate<core::int>(10, #C1);
+static field core::List<core::int> list7 = core::List::generate<core::int>(10, self::bar);
+static field core::bool someGrowable = true;
+static method foo(core::int i) → core::int
+ return i;
+static get bar() → (core::int) → core::int
+ return #C1;
+static method main() → void {
+ self::someGrowable = !self::someGrowable;
+ core::print(<core::List<core::int>>[self::list1, self::list2, self::list3, self::list4, self::list5, self::list6, self::list7]);
+}
+
+constants {
+ #C1 = static-tearoff self::foo
+}
diff --git a/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.outline.expect b/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.outline.expect
new file mode 100644
index 0000000..63bf114
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.outline.expect
@@ -0,0 +1,18 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> list1;
+static field core::List<core::int> list2;
+static field core::List<core::int> list3;
+static field core::List<core::int> list4;
+static field core::List<core::int> list5;
+static field core::List<core::int> list6;
+static field core::List<core::int> list7;
+static field core::bool someGrowable;
+static method foo(core::int i) → core::int
+ ;
+static get bar() → (core::int) → core::int
+ ;
+static method main() → void
+ ;
diff --git a/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.transformed.expect b/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.transformed.expect
new file mode 100644
index 0000000..8fbe3a6
--- /dev/null
+++ b/pkg/front_end/testcases/dart2js/list_generate_3.dart.weak.transformed.expect
@@ -0,0 +1,55 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:_interceptors" as _in;
+
+static field core::List<core::int> list1 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ {
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+ }
+} =>_list;
+static field core::List<core::int> list2 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateGrowable<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ {
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+ }
+} =>_list;
+static field core::List<core::int> list3 = block {
+ final _in::JSArray<core::int> _list = _in::JSArray::allocateFixed<core::int>(10);
+ for (core::int* i = 0; i.{core::num::<}(10){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::int*) → core::int*}) {
+ core::int i = i;
+ {
+ _list.{_in::JSArray::[]=}{Invariant,BoundsSafe}(i, i){(core::int, core::int) → void};
+ }
+ }
+} =>_list;
+static field core::List<core::int> list4 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ return i;
+}, growable: self::someGrowable);
+static field core::List<core::int> list5 = core::List::generate<core::int>(10, (core::int i) → core::int {
+ if(i.{core::int::isEven}{core::bool})
+ return i.{core::num::+}(1){(core::num) → core::int};
+ return i.{core::num::-}(1){(core::num) → core::int};
+});
+static field core::List<core::int> list6 = core::List::generate<core::int>(10, #C1);
+static field core::List<core::int> list7 = core::List::generate<core::int>(10, self::bar);
+static field core::bool someGrowable = true;
+static method foo(core::int i) → core::int
+ return i;
+static get bar() → (core::int) → core::int
+ return #C1;
+static method main() → void {
+ self::someGrowable = !self::someGrowable;
+ core::print(<core::List<core::int>>[self::list1, self::list2, self::list3, self::list4, self::list5, self::list6, self::list7]);
+}
+
+constants {
+ #C1 = static-tearoff self::foo
+}
diff --git a/sdk/lib/_http/websocket.dart b/sdk/lib/_http/websocket.dart
index c9c6246..4b9bbff 100644
--- a/sdk/lib/_http/websocket.dart
+++ b/sdk/lib/_http/websocket.dart
@@ -375,8 +375,10 @@
{Iterable<String>? protocols,
Map<String, dynamic>? headers,
CompressionOptions compression =
- CompressionOptions.compressionDefault}) =>
- _WebSocketImpl.connect(url, protocols, headers, compression: compression);
+ CompressionOptions.compressionDefault,
+ HttpClient? customClient}) =>
+ _WebSocketImpl.connect(url, protocols, headers,
+ compression: compression, customClient: customClient);
@Deprecated('This constructor will be removed in Dart 2.0. Use `implements`'
' instead of `extends` if implementing this abstract class.')
diff --git a/sdk/lib/_http/websocket_impl.dart b/sdk/lib/_http/websocket_impl.dart
index 7de33f0..fe2c5a7 100644
--- a/sdk/lib/_http/websocket_impl.dart
+++ b/sdk/lib/_http/websocket_impl.dart
@@ -999,8 +999,8 @@
static Future<WebSocket> connect(
String url, Iterable<String>? protocols, Map<String, dynamic>? headers,
- {CompressionOptions compression =
- CompressionOptions.compressionDefault}) {
+ {CompressionOptions compression = CompressionOptions.compressionDefault,
+ HttpClient? customClient}) {
Uri uri = Uri.parse(url);
if (uri.scheme != "ws" && uri.scheme != "wss") {
throw new WebSocketException("Unsupported URL scheme '${uri.scheme}'");
@@ -1024,7 +1024,7 @@
path: uri.path,
query: uri.query,
fragment: uri.fragment);
- return _httpClient.openUrl("GET", uri).then((request) {
+ return (customClient ?? _httpClient).openUrl("GET", uri).then((request) {
if (uri.userInfo != null && !uri.userInfo.isEmpty) {
// If the URL contains user information use that for basic
// authorization.
diff --git a/tests/language/regress/regress47166_test.dart b/tests/language/regress/regress47166_test.dart
new file mode 100644
index 0000000..b44d28b
--- /dev/null
+++ b/tests/language/regress/regress47166_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2021, 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/47166
+
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+void maybeThrow(bool doThrow) {
+ if (doThrow) throw Exception('omg!');
+}
+
+int triggerTheProblem(bool doThrow) {
+ int x = 1;
+ try {
+ x = 100;
+ maybeThrow(doThrow);
+ x = 1; // unreached.
+ log1 = x;
+ } catch (e) {
+ log2 = x;
+ }
+ log3 = x;
+
+ // This closure creates a context object ('box') subject to load elimination.
+ // In the reported bug, log2 and log3 were assigned constant '1' from an
+ // incorrect store-forwarding optimization of the boxed 'x'. The '1' came from
+ // the merge of '1' from the initialization of 'x' and the unreachable
+ // assignment of 'x'.
+ g = () => x;
+
+ log4 = x;
+ return x;
+}
+
+dynamic g;
+int log1 = 0, log2 = 0, log3 = 0, log4 = 0, log5 = 0, log6 = 0;
+
+void main() {
+ log5 = triggerTheProblem(true);
+ log6 = g(); // Use 'g'.
+ Expect.equals(
+ 'log1=0 log2=100 log3=100 log4=100 log5=100 log6=100',
+ 'log1=$log1 log2=$log2 log3=$log3 log4=$log4 log5=$log5 log6=$log6',
+ 'throwing');
+
+ // Run the test with 'doThrow' being false to avoid any confounding
+ // optimizations due to constant propagation.
+ log1 = log2 = log3 = log4 = log5 = log6 = 0;
+ log5 = triggerTheProblem(false);
+ log6 = g(); // Use 'g'.
+ Expect.equals(
+ 'log1=1 log2=0 log3=1 log4=1 log5=1 log6=1',
+ 'log1=$log1 log2=$log2 log3=$log3 log4=$log4 log5=$log5 log6=$log6',
+ 'not throwing');
+}
diff --git a/tests/standalone/io/web_socket_error_test.dart b/tests/standalone/io/web_socket_error_test.dart
index a7fdd0e..aca2548 100644
--- a/tests/standalone/io/web_socket_error_test.dart
+++ b/tests/standalone/io/web_socket_error_test.dart
@@ -48,8 +48,8 @@
: HttpServer.bind(HOST_NAME, 0, backlog: backlog);
Future<WebSocket> createClient(int port) =>
- // TODO(whesse): Add a client context argument to WebSocket.connect.
- WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
+ WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/',
+ customClient: secure ? HttpClient(context: clientContext) : null);
void testForceCloseServerEnd(int totalConnections) {
createServer().then((server) {
@@ -94,7 +94,6 @@
main() {
asyncStart();
new SecurityConfiguration(secure: false).runTests();
- // TODO(whesse): WebSocket.connect needs an optional context: parameter
- // new SecurityConfiguration(secure: true).runTests();
+ new SecurityConfiguration(secure: true).runTests();
asyncEnd();
}
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 9b0e789..f5927ba 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -13,10 +13,8 @@
import "dart:typed_data";
import "package:async_helper/async_helper.dart";
-import "package:convert/convert.dart";
import "package:crypto/crypto.dart";
import "package:expect/expect.dart";
-import "package:path/path.dart";
const WEB_SOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@@ -44,9 +42,17 @@
? HttpServer.bindSecure(HOST_NAME, 0, serverContext, backlog: backlog)
: HttpServer.bind(HOST_NAME, 0, backlog: backlog);
- Future<WebSocket> createClient(int port) =>
- // TODO(whesse): Add client context argument to WebSocket.connect
- WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
+ Future<WebSocket> createClient(int port,
+ {String? user,
+ Map<String, Object>? headers,
+ String? customUserAgent}) =>
+ WebSocket.connect(
+ '${secure ? "wss" : "ws"}://${user is Null ? "" : "$user@"}$HOST_NAME:$port/',
+ headers: headers,
+ customClient: secure
+ ? (HttpClient(context: clientContext)
+ ..userAgent = customUserAgent)
+ : null);
checkCloseStatus(webSocket, closeStatus, closeReason) {
Expect.equals(
@@ -304,7 +310,7 @@
asyncEnd();
});
- HttpClient client = new HttpClient();
+ final client = HttpClient(context: secure ? clientContext : null);
client
.postUrl(Uri.parse(
"${secure ? 'https:' : 'http:'}//$HOST_NAME:${server.port}/"))
@@ -401,12 +407,12 @@
var baseWsUrl = '$wsProtocol://$HOST_NAME:${server.port}/';
var httpProtocol = '${secure ? "https" : "http"}';
var baseHttpUrl = '$httpProtocol://$HOST_NAME:${server.port}/';
- HttpClient client = new HttpClient();
+ final client = HttpClient(context: secure ? clientContext : null);
for (int i = 0; i < connections; i++) {
var completer = new Completer();
futures.add(completer.future);
- WebSocket.connect('${baseWsUrl}').then((websocket) {
+ createClient(server.port).then((websocket) {
websocket.listen((_) {
websocket.close();
}, onDone: completer.complete);
@@ -456,9 +462,7 @@
});
});
- var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
-
- WebSocket.connect(url).then((websocket) {
+ createClient(server.port).then((websocket) {
return websocket.listen((message) {
Expect.equals("Hello", message);
websocket.close();
@@ -484,12 +488,11 @@
});
});
- var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
var headers = {
'My-Header': 'my-value',
'My-Header-Multiple': ['my-value-1', 'my-value-2']
};
- WebSocket.connect(url, headers: headers).then((websocket) {
+ createClient(server.port, headers: headers).then((websocket) {
return websocket.listen((message) {
Expect.equals("Hello", message);
websocket.close();
@@ -522,9 +525,7 @@
});
});
- var url =
- '${secure ? "wss" : "ws"}://$userInfo@$HOST_NAME:${server.port}/';
- WebSocket.connect(url).then((websocket) {
+ createClient(server.port, user: userInfo).then((websocket) {
return websocket.listen((message) {
Expect.equals("Hello", message);
websocket.close();
@@ -554,6 +555,24 @@
});
}
+ void testStaticClientUserAgentStaysTheSame() {
+ asyncStart();
+ createServer().then((server) {
+ server.transform(new WebSocketTransformer()).listen((webSocket) {
+ Expect.equals('Custom User Agent', WebSocket.userAgent);
+ server.close();
+ webSocket.close();
+ asyncEnd();
+ });
+ // Next line should take no effect on custom user agent value provided
+ WebSocket.userAgent = 'Custom User Agent';
+ createClient(server.port, customUserAgent: 'New User Agent')
+ .then((webSocket) {
+ webSocket.close();
+ });
+ });
+ }
+
void runTests() {
testRequestResponseClientCloses(2, null, null, 1);
testRequestResponseClientCloses(2, 3001, null, 2);
@@ -582,11 +601,11 @@
testAdditionalHeaders();
testBasicAuthentication();
testShouldSetUserAgent();
+ testStaticClientUserAgentStaysTheSame();
}
}
main() {
new SecurityConfiguration(secure: false).runTests();
- // TODO(whesse): Make WebSocket.connect() take an optional context: parameter.
- // new SecurityConfiguration(secure: true).runTests();
+ new SecurityConfiguration(secure: true).runTests();
}
diff --git a/tests/standalone_2/io/web_socket_test.dart b/tests/standalone_2/io/web_socket_test.dart
index a931549..5d7f425 100644
--- a/tests/standalone_2/io/web_socket_test.dart
+++ b/tests/standalone_2/io/web_socket_test.dart
@@ -15,10 +15,8 @@
import "dart:typed_data";
import "package:async_helper/async_helper.dart";
-import "package:convert/convert.dart";
import "package:crypto/crypto.dart";
import "package:expect/expect.dart";
-import "package:path/path.dart";
const WEB_SOCKET_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
@@ -46,9 +44,15 @@
? HttpServer.bindSecure(HOST_NAME, 0, serverContext, backlog: backlog)
: HttpServer.bind(HOST_NAME, 0, backlog: backlog);
- Future<WebSocket> createClient(int port) =>
- // TODO(whesse): Add client context argument to WebSocket.connect
- WebSocket.connect('${secure ? "wss" : "ws"}://$HOST_NAME:$port/');
+ Future<WebSocket> createClient(int port,
+ {String user, Map<String, Object> headers, String customUserAgent}) =>
+ WebSocket.connect(
+ '${secure ? "wss" : "ws"}://${user is Null ? "" : "$user@"}$HOST_NAME:$port/',
+ headers: headers,
+ customClient: secure
+ ? (HttpClient(context: clientContext)
+ ..userAgent = customUserAgent)
+ : null);
checkCloseStatus(webSocket, closeStatus, closeReason) {
Expect.equals(
@@ -306,7 +310,7 @@
asyncEnd();
});
- HttpClient client = new HttpClient();
+ final client = HttpClient(context: secure ? clientContext : null);
client
.postUrl(Uri.parse(
"${secure ? 'https:' : 'http:'}//$HOST_NAME:${server.port}/"))
@@ -403,12 +407,12 @@
var baseWsUrl = '$wsProtocol://$HOST_NAME:${server.port}/';
var httpProtocol = '${secure ? "https" : "http"}';
var baseHttpUrl = '$httpProtocol://$HOST_NAME:${server.port}/';
- HttpClient client = new HttpClient();
+ final client = HttpClient(context: secure ? clientContext : null);
for (int i = 0; i < connections; i++) {
var completer = new Completer();
futures.add(completer.future);
- WebSocket.connect('${baseWsUrl}').then((websocket) {
+ createClient(server.port).then((websocket) {
websocket.listen((_) {
websocket.close();
}, onDone: completer.complete);
@@ -458,9 +462,7 @@
});
});
- var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
-
- WebSocket.connect(url).then((websocket) {
+ createClient(server.port).then((websocket) {
return websocket.listen((message) {
Expect.equals("Hello", message);
websocket.close();
@@ -486,12 +488,11 @@
});
});
- var url = '${secure ? "wss" : "ws"}://$HOST_NAME:${server.port}/';
var headers = {
'My-Header': 'my-value',
'My-Header-Multiple': ['my-value-1', 'my-value-2']
};
- WebSocket.connect(url, headers: headers).then((websocket) {
+ createClient(server.port, headers: headers).then((websocket) {
return websocket.listen((message) {
Expect.equals("Hello", message);
websocket.close();
@@ -524,9 +525,7 @@
});
});
- var url =
- '${secure ? "wss" : "ws"}://$userInfo@$HOST_NAME:${server.port}/';
- WebSocket.connect(url).then((websocket) {
+ createClient(server.port, user: userInfo).then((websocket) {
return websocket.listen((message) {
Expect.equals("Hello", message);
websocket.close();
@@ -556,6 +555,24 @@
});
}
+ void testStaticClientUserAgentStaysTheSame() {
+ asyncStart();
+ createServer().then((server) {
+ server.transform(new WebSocketTransformer()).listen((webSocket) {
+ Expect.equals('Custom User Agent', WebSocket.userAgent);
+ server.close();
+ webSocket.close();
+ asyncEnd();
+ });
+ // Next line should take no effect on custom user agent value provided
+ WebSocket.userAgent = 'Custom User Agent';
+ createClient(server.port, customUserAgent: 'New User Agent')
+ .then((webSocket) {
+ webSocket.close();
+ });
+ });
+ }
+
void runTests() {
testRequestResponseClientCloses(2, null, null, 1);
testRequestResponseClientCloses(2, 3001, null, 2);
@@ -584,11 +601,11 @@
testAdditionalHeaders();
testBasicAuthentication();
testShouldSetUserAgent();
+ testStaticClientUserAgentStaysTheSame();
}
}
main() {
new SecurityConfiguration(secure: false).runTests();
- // TODO(whesse): Make WebSocket.connect() take an optional context: parameter.
- // new SecurityConfiguration(secure: true).runTests();
+ new SecurityConfiguration(secure: true).runTests();
}
diff --git a/tools/VERSION b/tools/VERSION
index 51b89ce..560e5c9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 111
+PRERELEASE 112
PRERELEASE_PATCH 0
\ No newline at end of file