Version 2.15.0-56.0.dev
Merge commit '92026cec4435bc846b5e30462818dfd9eded3dc2' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f6e9780..5f02905 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -198,8 +198,16 @@
#### Linter
-Updated the Linter to `1.9.0`, which includes changes that
-
+Updated the Linter to `1.10.0`, which includes changes that
+- improves regular expression parsing performance for common checks
+ (`camel_case_types`, `file_names`, etc.).
+- (internal) migrates to analyzer 2.1.0 APIs.
+- fixes false positive in `use_build_context_synchronously` in awaits inside
+ anonymous functions.
+- fixes `overridden_fields` false positive w/ static fields.
+- fixes false positive in `avoid_null_checks_in_equality_operators` w/
+ non-nullable params.
+- fixes false positive for deferred imports in `prefer_const_constructors`.
- marks `avoid_dynamic_calls` stable.
- (internal) removes unused `MockPubVisitor` and `MockRule` classes.
- fixes a `prefer_void_to_null` false positive w/ overridden properties.
diff --git a/DEPS b/DEPS
index 8315824..7d53ee7 100644
--- a/DEPS
+++ b/DEPS
@@ -122,7 +122,7 @@
"intl_tag": "0.17.0-nullsafety",
"jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_rev": "7e00f893440a72de0637970325e4ea44bd1e8c8e",
- "linter_tag": "1.9.0",
+ "linter_tag": "1.10.0",
"lints_tag": "f9670df2a66e0ec12eb51554e70c1cbf56c8f5d0",
"logging_rev": "575781ef196e4fed4fb737e38fb4b73d62727187",
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
index 14485d2..a586ac4 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/abstract_producer.dart
@@ -276,9 +276,7 @@
var selectionEnd = selectionOffset + selectionLength;
var locator = NodeLocator(selectionOffset, selectionEnd);
var node = locator.searchWithin(resolvedResult.unit);
- if (node == null) {
- return null;
- }
+ node ??= resolvedResult.unit;
return CorrectionProducerContext._(
resolvedResult: resolvedResult,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/add_eol_at_end_of_file.dart b/pkg/analysis_server/lib/src/services/correction/dart/add_eol_at_end_of_file.dart
new file mode 100644
index 0000000..3dd8cad
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/add_eol_at_end_of_file.dart
@@ -0,0 +1,41 @@
+// 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.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class AddEolAtEndOfFile extends CorrectionProducer {
+ @override
+ FixKind get fixKind => DartFixKind.ADD_EOL_AT_END_OF_FILE;
+
+ @override
+ Future<void> compute(ChangeBuilder builder) async {
+ var content = resolvedResult.content;
+ if (!content.endsWith(eol)) {
+ await builder.addDartFileEdit(file, (builder) {
+ builder.addSimpleInsertion(content.length, eol);
+ });
+ } else {
+ var index = content.length;
+ while (index > 0) {
+ var char = content[index - 1];
+ if (char != '\r' && char != '\n') {
+ break;
+ }
+ index--;
+ }
+
+ await builder.addDartFileEdit(file, (builder) {
+ builder.addSimpleReplacement(
+ SourceRange(index, content.length - index), eol);
+ });
+ }
+ }
+
+ /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+ static AddEolAtEndOfFile newInstance() => AddEolAtEndOfFile();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index fb59750..8ca363e 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -94,6 +94,8 @@
'dart.fix.add.diagnosticPropertyReference.multi',
DartFixKindPriority.IN_FILE,
'Add missing debug property references everywhere in file');
+ static const ADD_EOL_AT_END_OF_FILE = FixKind('dart.fix.add.eolAtEndOfFile',
+ DartFixKindPriority.DEFAULT, 'Add EOL at end of file');
static const ADD_FIELD_FORMAL_PARAMETERS = FixKind(
'dart.fix.add.fieldFormalParameters',
70,
@@ -745,10 +747,8 @@
'dart.fix.replace.nullWithVoid.multi',
DartFixKindPriority.DEFAULT,
"Replace 'Null' with 'void' everywhere in file");
- static const REPLACE_RETURN_TYPE = FixKind(
- 'dart.fix.replace.returnType',
- DartFixKindPriority.DEFAULT,
- "Replace the return type with '{0}'");
+ static const REPLACE_RETURN_TYPE = FixKind('dart.fix.replace.returnType',
+ DartFixKindPriority.DEFAULT, "Replace the return type with '{0}'");
static const REPLACE_RETURN_TYPE_FUTURE = FixKind(
'dart.fix.replace.returnTypeFuture',
DartFixKindPriority.DEFAULT,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index a67305f..d0e51d0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -12,6 +12,7 @@
import 'package:analysis_server/src/services/correction/dart/add_await.dart';
import 'package:analysis_server/src/services/correction/dart/add_const.dart';
import 'package:analysis_server/src/services/correction/dart/add_diagnostic_property_reference.dart';
+import 'package:analysis_server/src/services/correction/dart/add_eol_at_end_of_file.dart';
import 'package:analysis_server/src/services/correction/dart/add_explicit_cast.dart';
import 'package:analysis_server/src/services/correction/dart/add_field_formal_parameters.dart';
import 'package:analysis_server/src/services/correction/dart/add_key_to_constructors.dart';
@@ -409,6 +410,9 @@
RemoveEmptyStatement.newInstance,
ReplaceWithBrackets.newInstance,
],
+ LintNames.eol_at_end_of_file: [
+ AddEolAtEndOfFile.newInstance,
+ ],
LintNames.exhaustive_cases: [
AddMissingEnumLikeCaseClauses.newInstance,
],
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index 0f5d7d0..ccafb32 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -48,6 +48,7 @@
static const String empty_catches = 'empty_catches';
static const String empty_constructor_bodies = 'empty_constructor_bodies';
static const String empty_statements = 'empty_statements';
+ static const String eol_at_end_of_file = 'eol_at_end_of_file';
static const String exhaustive_cases = 'exhaustive_cases';
static const String hash_and_equals = 'hash_and_equals';
static const String no_duplicate_case_values = 'no_duplicate_case_values';
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_eol_at_end_of_file_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_eol_at_end_of_file_test.dart
new file mode 100644
index 0000000..07fb1f4
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_eol_at_end_of_file_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AddEolAtEndOfFileTest);
+ });
+}
+
+@reflectiveTest
+class AddEolAtEndOfFileTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.ADD_EOL_AT_END_OF_FILE;
+
+ @override
+ String get lintCode => LintNames.eol_at_end_of_file;
+
+ Future<void> test_missing_eol() async {
+ await resolveTestCode('''
+void f() {
+}''');
+ await assertHasFix('''
+void f() {
+}
+''');
+ }
+
+ Future<void> test_multiple_eol() async {
+ await resolveTestCode('''
+void f() {
+}
+
+''');
+ await assertHasFix('''
+void f() {
+}
+''');
+ }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_comparison_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_comparison_test.dart
index 2de13b2..3e73604 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/remove_comparison_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_comparison_test.dart
@@ -204,7 +204,7 @@
final String name = '';
@override
- operator ==(other) =>
+ operator ==(Object? other) =>
other != null &&
other is Person &&
name == other.name;
@@ -214,7 +214,7 @@
final String name = '';
@override
- operator ==(other) =>
+ operator ==(Object? other) =>
other != null &&
other is Person &&
name == other.name;
@@ -225,7 +225,7 @@
final String name = '';
@override
- operator ==(other) =>
+ operator ==(Object? other) =>
other is Person &&
name == other.name;
}
@@ -234,7 +234,7 @@
final String name = '';
@override
- operator ==(other) =>
+ operator ==(Object? other) =>
other is Person &&
name == other.name;
}
@@ -282,7 +282,7 @@
final String name = '';
@override
- operator ==(other) =>
+ operator ==(Object? other) =>
other != null &&
other is Person &&
name == other.name;
@@ -293,13 +293,11 @@
final String name = '';
@override
- operator ==(other) =>
+ operator ==(Object? other) =>
other is Person &&
name == other.name;
}
-''',
- errorFilter: (error) =>
- error.errorCode == HintCode.UNNECESSARY_NULL_COMPARISON_TRUE);
+''');
}
Future<void> test_functionBody() async {
@@ -308,7 +306,7 @@
final String name = '';
@override
- operator ==(other) {
+ operator ==(Object? other) {
return other != null &&
other is Person &&
name == other.name;
@@ -320,14 +318,12 @@
final String name = '';
@override
- operator ==(other) {
+ operator ==(Object? other) {
return other is Person &&
name == other.name;
}
}
-''',
- errorFilter: (error) =>
- error.errorCode == HintCode.UNNECESSARY_NULL_COMPARISON_TRUE);
+''');
}
Future<void> test_ifNullAssignmentStatement() async {
@@ -336,7 +332,7 @@
final String name = '';
@override
- operator ==(other) {
+ operator ==(Object? other) {
if (other is! Person) return false;
other ??= Person();
return other.name == name;
@@ -354,7 +350,7 @@
final String name = '';
@override
- operator ==(other) {
+ operator ==(Object? other) {
if (other is! Person) return false;
final toCompare = other ?? Person();
return toCompare.name == name;
@@ -367,7 +363,7 @@
final String name = '';
@override
- operator ==(other) {
+ operator ==(Object? other) {
if (other is! Person) return false;
final toCompare = other;
return toCompare.name == name;
@@ -386,7 +382,7 @@
final String name = '';
@override
- operator ==(other) {
+ operator ==(Object? other) {
if (other == null) return false;
return other is Person &&
name == other.name;
@@ -398,7 +394,7 @@
final String name = '';
@override
- operator ==(other) {
+ operator ==(Object? other) {
return other is Person &&
name == other.name;
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 5ff6f0d..9d30ea0 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -10,6 +10,7 @@
import 'add_curly_braces_test.dart' as add_curly_braces;
import 'add_diagnostic_property_reference_test.dart'
as add_diagnostic_property_reference;
+import 'add_eol_at_end_of_file_test.dart' as add_eol_at_end_of_file;
import 'add_explicit_cast_test.dart' as add_explicit_cast;
import 'add_field_formal_parameters_test.dart' as add_field_formal_parameters;
import 'add_key_to_constructors_test.dart' as add_key_to_constructors;
@@ -203,6 +204,7 @@
add_const.main();
add_curly_braces.main();
add_diagnostic_property_reference.main();
+ add_eol_at_end_of_file.main();
add_explicit_cast.main();
add_field_formal_parameters.main();
add_key_to_constructors.main();
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 9038287..8acd4ac 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -295,6 +295,9 @@
_instanceCreationExpressionResolver =
InstanceCreationExpressionResolver(this);
+ late final SimpleIdentifierResolver _simpleIdentifierResolver =
+ SimpleIdentifierResolver(this, flowAnalysis);
+
/// Initialize a newly created visitor to resolve the nodes in an AST node.
///
/// The [definingLibrary] is the element for the library containing the node
@@ -1857,7 +1860,7 @@
@override
void visitSimpleIdentifier(covariant SimpleIdentifierImpl node) {
- SimpleIdentifierResolver(this, flowAnalysis).resolve(node);
+ _simpleIdentifierResolver.resolve(node);
}
@override
diff --git a/pkg/dds/lib/src/dap/adapters/dart.dart b/pkg/dds/lib/src/dap/adapters/dart.dart
index b2ace33..5099eef 100644
--- a/pkg/dds/lib/src/dap/adapters/dart.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart.dart
@@ -467,11 +467,16 @@
/// The URI protocol will be changed to ws/wss but otherwise not normalised.
/// The caller should handle any other normalisation (such as adding /ws to
/// the end if required).
- Future<void> connectDebugger(Uri uri) async {
+ ///
+ /// If [resumeIfStarting] is true, isolates waiting to start will
+ /// automatically be resumed. This is usually desired in launch requests, but
+ /// not when attaching.
+ Future<void> connectDebugger(
+ Uri uri, {
+ required bool resumeIfStarting,
+ }) async {
// Start up a DDS instance for this VM.
if (enableDds) {
- // TODO(dantup): Do we need to worry about there already being one connected
- // if this URL came from another service that may have started one?
logger?.call('Starting a DDS instance for $uri');
try {
final dds = await DartDevelopmentService.startDartDevelopmentService(
@@ -552,7 +557,8 @@
final pauseEventKind = isolate.runnable ?? false
? vm.EventKind.kIsolateRunnable
: vm.EventKind.kIsolateStart;
- await _isolateManager.registerIsolate(isolate, pauseEventKind);
+ final thread =
+ await _isolateManager.registerIsolate(isolate, pauseEventKind);
// If the Isolate already has a Pause event we can give it to the
// IsolateManager to handle (if it's PausePostStart it will re-configure
@@ -560,9 +566,18 @@
// runnable - otherwise we'll handle this when it becomes runnable in an
// event later).
if (isolate.pauseEvent?.kind?.startsWith('Pause') ?? false) {
- await _isolateManager.handleEvent(isolate.pauseEvent!);
+ await _isolateManager.handleEvent(
+ isolate.pauseEvent!,
+ resumeIfStarting: resumeIfStarting,
+ );
} else if (isolate.runnable == true) {
- await _isolateManager.resumeIsolate(isolate);
+ // If requested, automatically resume. Otherwise send a Stopped event to
+ // inform the client UI the thread is paused.
+ if (resumeIfStarting) {
+ await _isolateManager.resumeIsolate(isolate);
+ } else {
+ _isolateManager.sendStoppedOnEntryEvent(thread.threadId);
+ }
}
}));
diff --git a/pkg/dds/lib/src/dap/adapters/dart_cli.dart b/pkg/dds/lib/src/dap/adapters/dart_cli.dart
index 7420692..bf0eab9 100644
--- a/pkg/dds/lib/src/dap/adapters/dart_cli.dart
+++ b/pkg/dds/lib/src/dap/adapters/dart_cli.dart
@@ -140,7 +140,7 @@
vmServiceInfoFile = File(serviceInfoFilePath);
unawaited(waitForVmServiceInfoFile(vmServiceInfoFile)
- .then((uri) => connectDebugger(uri)));
+ .then((uri) => connectDebugger(uri, resumeIfStarting: true)));
}
final vmArgs = <String>[
@@ -230,7 +230,7 @@
? Uri.parse(vmServiceUri)
: await waitForVmServiceInfoFile(File(vmServiceInfoFile!));
- unawaited(connectDebugger(uri));
+ unawaited(connectDebugger(uri, resumeIfStarting: false));
}
/// Calls the client (via a `runInTerminal` request) to spawn the process so
diff --git a/pkg/dds/lib/src/dap/isolate_manager.dart b/pkg/dds/lib/src/dap/isolate_manager.dart
index d579bde..6eb4a24 100644
--- a/pkg/dds/lib/src/dap/isolate_manager.dart
+++ b/pkg/dds/lib/src/dap/isolate_manager.dart
@@ -128,8 +128,14 @@
ThreadInfo? getThread(int threadId) => _threadsByThreadId[threadId];
- /// Handles Isolate and Debug events
- Future<void> handleEvent(vm.Event event) async {
+ /// Handles Isolate and Debug events.
+ ///
+ /// If [resumeIfStarting] is `true`, PauseStart/PausePostStart events will be
+ /// automatically resumed from.
+ Future<void> handleEvent(
+ vm.Event event, {
+ bool resumeIfStarting = true,
+ }) async {
final isolateId = event.isolate?.id;
if (isolateId == null) {
return;
@@ -151,7 +157,7 @@
if (eventKind == vm.EventKind.kIsolateExit) {
_handleExit(event);
} else if (eventKind?.startsWith('Pause') ?? false) {
- await _handlePause(event);
+ await _handlePause(event, resumeIfStarting: resumeIfStarting);
} else if (eventKind == vm.EventKind.kResume) {
_handleResumed(event);
}
@@ -163,7 +169,7 @@
/// New isolates will be configured with the correct pause-exception behaviour,
/// libraries will be marked as debuggable if appropriate, and breakpoints
/// sent.
- Future<void> registerIsolate(
+ Future<ThreadInfo> registerIsolate(
vm.IsolateRef isolate,
String eventKind,
) async {
@@ -193,6 +199,8 @@
await _configureIsolate(isolate);
registrationCompleter.complete();
}
+
+ return info;
}
Future<void> resumeIsolate(vm.IsolateRef isolateRef,
@@ -245,6 +253,11 @@
}
}
+ /// Sends an event informing the client that a thread is stopped at entry.
+ void sendStoppedOnEntryEvent(int threadId) {
+ _adapter.sendEvent(StoppedEventBody(reason: 'entry', threadId: threadId));
+ }
+
/// Records breakpoints for [uri].
///
/// [breakpoints] represents the new set and entirely replaces anything given
@@ -368,18 +381,23 @@
/// Handles a pause event.
///
- /// For [vm.EventKind.kPausePostRequest] which occurs after a restart, the isolate
- /// will be re-configured (pause-exception behaviour, debuggable libraries,
- /// breakpoints) and then resumed.
+ /// For [vm.EventKind.kPausePostRequest] which occurs after a restart, the
+ /// isolate will be re-configured (pause-exception behaviour, debuggable
+ /// libraries, breakpoints) and then (if [resumeIfStarting] is `true`)
+ /// resumed.
///
- /// For [vm.EventKind.kPauseStart], the isolate will be resumed.
+ /// For [vm.EventKind.kPauseStart] and [resumeIfStarting] is `true`, the
+ /// isolate will be resumed.
///
/// For breakpoints with conditions that are not met and for logpoints, the
/// isolate will be automatically resumed.
///
/// For all other pause types, the isolate will remain paused and a
/// corresponding "Stopped" event sent to the editor.
- Future<void> _handlePause(vm.Event event) async {
+ Future<void> _handlePause(
+ vm.Event event, {
+ bool resumeIfStarting = true,
+ }) async {
final eventKind = event.kind;
final isolate = event.isolate!;
final thread = _threadsByIsolateId[isolate.id!];
@@ -396,13 +414,21 @@
// after a hot restart.
if (eventKind == vm.EventKind.kPausePostRequest) {
await _configureIsolate(isolate);
- await resumeThread(thread.threadId);
+ if (resumeIfStarting) {
+ await resumeThread(thread.threadId);
+ }
} else if (eventKind == vm.EventKind.kPauseStart) {
// Don't resume from a PauseStart if this has already happened (see
// comments on [thread.hasBeenStarted]).
if (!thread.hasBeenStarted) {
- thread.hasBeenStarted = true;
- await resumeThread(thread.threadId);
+ // If requested, automatically resume. Otherwise send a Stopped event to
+ // inform the client UI the thread is paused.
+ if (resumeIfStarting) {
+ thread.hasBeenStarted = true;
+ await resumeThread(thread.threadId);
+ } else {
+ sendStoppedOnEntryEvent(thread.threadId);
+ }
}
} else {
// PauseExit, PauseBreakpoint, PauseInterrupted, PauseException
diff --git a/pkg/dds/test/dap/integration/debug_attach_test.dart b/pkg/dds/test/dap/integration/debug_attach_test.dart
index f0e3f14..3df0fc9 100644
--- a/pkg/dds/test/dap/integration/debug_attach_test.dart
+++ b/pkg/dds/test/dap/integration/debug_attach_test.dart
@@ -31,6 +31,7 @@
final outputEvents = await dap.client.collectOutput(
launch: () => dap.client.attach(
vmServiceUri: vmServiceUri.toString(),
+ autoResume: true,
cwd: dap.testAppDir.path,
),
);
@@ -81,6 +82,7 @@
final outputEvents = await dap.client.collectOutput(
launch: () => dap.client.attach(
vmServiceInfoFile: vmServiceInfoFilePath,
+ autoResume: true,
cwd: dap.testAppDir.path,
),
);
diff --git a/pkg/dds/test/dap/integration/test_client.dart b/pkg/dds/test/dap/integration/test_client.dart
index 08d7e8f..77ddc1a 100644
--- a/pkg/dds/test/dap/integration/test_client.dart
+++ b/pkg/dds/test/dap/integration/test_client.dart
@@ -62,6 +62,7 @@
/// Send an attachRequest to the server, asking it to attach to an existing
/// Dart program.
Future<Response> attach({
+ required bool autoResume,
String? vmServiceUri,
String? vmServiceInfoFile,
String? cwd,
@@ -70,12 +71,20 @@
bool? debugExternalPackageLibraries,
bool? evaluateGettersInDebugViews,
bool? evaluateToStringInDebugViews,
- }) {
+ }) async {
assert(
(vmServiceUri == null) != (vmServiceInfoFile == null),
'Provide exactly one of vmServiceUri/vmServiceInfoFile',
);
- return sendRequest(
+
+ // When attaching, the paused VM will not be automatically unpaused, but
+ // instead send a Stopped(reason: 'entry') event. Respond to this by
+ // resuming.
+ final resumeFuture = autoResume
+ ? expectStop('entry').then((event) => continue_(event.threadId!))
+ : null;
+
+ final attachResponse = sendRequest(
DartAttachRequestArguments(
vmServiceUri: vmServiceUri,
vmServiceInfoFile: vmServiceInfoFile,
@@ -94,6 +103,11 @@
// (DartAttachRequestArguments).
overrideCommand: 'attach',
);
+
+ // If we were expecting a pause and to resume, ensure that happens.
+ await resumeFuture;
+
+ return attachResponse;
}
/// Sends a continue request for the given thread.
@@ -553,17 +567,20 @@
final result =
await getValidStack(stop.threadId!, startFrame: 0, numFrames: 1);
- expect(result.stackFrames, hasLength(1));
- final frame = result.stackFrames[0];
- if (file != null) {
- expect(frame.source?.path, equals(file.path));
- }
- if (sourceName != null) {
- expect(frame.source?.name, equals(sourceName));
- }
- if (line != null) {
- expect(frame.line, equals(line));
+ if (file != null || line != null || sourceName != null) {
+ expect(result.stackFrames, hasLength(1));
+ final frame = result.stackFrames[0];
+
+ if (file != null) {
+ expect(frame.source?.path, equals(file.path));
+ }
+ if (sourceName != null) {
+ expect(frame.source?.name, equals(sourceName));
+ }
+ if (line != null) {
+ expect(frame.line, equals(line));
+ }
}
return stop;
diff --git a/runtime/tests/vm/dart/regress_46980_test.dart b/runtime/tests/vm/dart/regress_46980_test.dart
new file mode 100644
index 0000000..a923ba8
--- /dev/null
+++ b/runtime/tests/vm/dart/regress_46980_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+// VMOptions=--deterministic
+
+// The Dart Project Fuzz Tester (1.91).
+// Program generated as:
+// dart dartfuzz.dart --seed 929450448 --no-fp --no-ffi --no-flat
+
+import 'dart:collection';
+import 'dart:typed_data';
+
+MapEntry<List<int>, Map<String, String>>? var0 =
+ MapEntry<List<int>, Map<String, String>>(
+ Uint16List.fromList(<int>[-25]), <String, String>{
+ '': 'p8',
+ 'VGiZ+x': 'n6\u{1f600}',
+ 'j': 'hrNI',
+ '3@kX)\u{1f600}': 'TW+Z',
+ 'D': '\u2665Yqu',
+ 'wzBa\u{1f600}h': '-k'
+});
+num? var78 = 29;
+MapEntry<String, int> var141 = MapEntry<String, int>('\u{1f600}', 16);
+
+MapEntry<Map<bool, int>, MapEntry<bool, int>>? var2896 =
+ MapEntry<Map<bool, int>, MapEntry<bool, int>>(<bool, int>{
+ true: -79,
+ false: 13,
+ true: 35,
+ true: -84,
+ false: -9223372034707292159
+}, MapEntry<bool, int>(true, 0));
+
+main() {
+ for (var i = 0; i < 1848; i++) {
+ print(var2896);
+ }
+
+ print('$var0\n$var78\n$var141\n');
+}
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index a545c0e..1cd8ece 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1904,7 +1904,7 @@
ICData::Handle(zone_, ICData::ICDataOfEntriesArray(ic_data_entries));
const classid_t current_cid = receiver().GetClassId();
- const classid_t old_cid = ic_data.GetReceiverClassIdAt(0);
+ const classid_t old_cid = Smi::Value(Smi::RawCast(ic_data_entries.At(0)));
const bool same_receiver = current_cid == old_cid;
// The target didn't change, so we can stay inside monomorphic state.
@@ -1927,6 +1927,7 @@
// We stay in monomorphic state, patch the code object and keep the same
// data (old ICData entries array).
const auto& code = Code::Handle(zone_, target_function.EnsureHasCode());
+ ASSERT(data.ptr() == ic_data.entries());
CodePatcher::PatchInstanceCallAt(caller_frame_->pc(), caller_code_, data,
code);
ReturnJIT(code, data, target_function);
diff --git a/tools/VERSION b/tools/VERSION
index 2aaac9b..39cb874 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 55
+PRERELEASE 56
PRERELEASE_PATCH 0
\ No newline at end of file