Version 2.18.0-166.0.dev
Merge commit 'f28a665c4ecf6a1e5a296e53251d9a1b481b0a60' into 'dev'
diff --git a/DEPS b/DEPS
index b6c119a..5756948 100644
--- a/DEPS
+++ b/DEPS
@@ -123,7 +123,7 @@
"linter_rev": "a8529c6692922b45bc287543b355c90d7b1286d3", # 1.24.0
"lints_rev": "8294e5648ab49474541527e2911e72e4c5aefe55",
"logging_rev": "f6979e3bc3b6e1847a08335b7eb6304e18986195",
- "markdown_rev": "5699cafa9ef004875fd7de8ae9ea00e5295e87a4", # 5.0.0
+ "markdown_rev": "e3f4bd28c9e61b522f75f291d4d6cfcfeccd83ee", # 5.0.0
"markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
"matcher_rev": "12cdc5fbafd666ed908359ae215d5d0306087969",
"mime_rev": "c2c5ffd594674f32dc277521369da1557a1622d3",
diff --git a/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart b/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
index 626004f..a744db5f 100644
--- a/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
+++ b/pkg/analysis_server/lib/src/analytics/google_analytics_manager.dart
@@ -154,6 +154,7 @@
analytics.sendEvent('language_server', 'session', parameters: {
'flags': sessionData.commandLineArguments,
'clientId': sessionData.clientId,
+ 'clientVersion': sessionData.clientVersion,
'sdkVersion': sessionData.sdkVersion,
'duration': duration.toString(),
'plugins': _pluginData.usageCountData,
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/make_conditional_on_debug_mode.dart b/pkg/analysis_server/lib/src/services/correction/dart/make_conditional_on_debug_mode.dart
index dc0822b..eab4042 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/make_conditional_on_debug_mode.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/make_conditional_on_debug_mode.dart
@@ -4,7 +4,6 @@
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
-import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -26,22 +25,16 @@
if (resolvedResult.session.uriConverter.uriToPath(_foundationUri) == null) {
return;
}
- final node = this.node;
- var parent = node.parent;
- var grandparent = parent?.parent;
- if (node is SimpleIdentifier &&
- parent is MethodInvocation &&
- parent.methodName == node &&
- node.name == 'print' &&
- grandparent is ExpressionStatement) {
- var indent = utils.getLinePrefix(grandparent.offset);
+ var printInvocation = utils.findSimplePrintInvocation(node);
+ if (printInvocation != null) {
+ var indent = utils.getLinePrefix(printInvocation.offset);
await builder.addDartFileEdit(file, (builder) {
- builder.addInsertion(grandparent.offset, (builder) {
+ builder.addInsertion(printInvocation.offset, (builder) {
builder.writeln('if (kDebugMode) {');
builder.write(indent);
builder.write(utils.getIndent(1));
});
- builder.addInsertion(grandparent.end, (builder) {
+ builder.addInsertion(printInvocation.end, (builder) {
builder.writeln();
builder.write(indent);
builder.write('}');
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/remove_print.dart b/pkg/analysis_server/lib/src/services/correction/dart/remove_print.dart
new file mode 100644
index 0000000..d079f60
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/remove_print.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2022, 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';
+
+/// Generates corrections that remove print expression statements, but
+/// not other usages of print.
+class RemovePrint extends CorrectionProducer {
+ @override
+ bool get canBeAppliedToFile => true;
+
+ @override
+ FixKind get fixKind => DartFixKind.REMOVE_PRINT;
+
+ @override
+ List<Object> get multiFixArguments => [];
+
+ @override
+ FixKind get multiFixKind => DartFixKind.REMOVE_PRINT_MULTI;
+
+ @override
+ Future<void> compute(ChangeBuilder builder) async {
+ final printInvocation = utils.findSimplePrintInvocation(node);
+ if (printInvocation != null) {
+ await builder.addDartFileEdit(file, (builder) {
+ var start = utils.getLineContentStart(printInvocation.offset);
+ var end = utils.getLineContentEnd(printInvocation.end);
+ final nextLine = utils.getLineNext(printInvocation.end);
+ if (nextLine != end) {
+ // Preserve indent if there is more on the line after the print.
+ start = printInvocation.offset;
+ } else if (start != utils.getLineThis(printInvocation.offset)) {
+ // Preserve newline if there is more on the line before the print.
+ end = end - utils.endOfLine.length;
+ }
+ builder.addDeletion(SourceRange(start, end - start));
+ });
+ }
+ }
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 9a729ee..e98c474 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -1063,6 +1063,16 @@
DartFixKindPriority.DEFAULT,
'Remove parentheses in getter invocation',
);
+ static const REMOVE_PRINT = FixKind(
+ 'dart.fix.remove.removePrint',
+ DartFixKindPriority.DEFAULT,
+ 'Remove print statement',
+ );
+ static const REMOVE_PRINT_MULTI = FixKind(
+ 'dart.fix.remove.removePrint.multi',
+ DartFixKindPriority.IN_FILE,
+ 'Remove print statements in file',
+ );
static const REMOVE_QUESTION_MARK = FixKind(
'dart.fix.remove.questionMark',
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 cc2890e..542b4eb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -132,6 +132,7 @@
import 'package:analysis_server/src/services/correction/dart/remove_operator.dart';
import 'package:analysis_server/src/services/correction/dart/remove_parameters_in_getter_declaration.dart';
import 'package:analysis_server/src/services/correction/dart/remove_parentheses_in_getter_invocation.dart';
+import 'package:analysis_server/src/services/correction/dart/remove_print.dart';
import 'package:analysis_server/src/services/correction/dart/remove_question_mark.dart';
import 'package:analysis_server/src/services/correction/dart/remove_returned_value.dart';
import 'package:analysis_server/src/services/correction/dart/remove_this_expression.dart';
@@ -388,6 +389,7 @@
],
LintNames.avoid_print: [
MakeConditionalOnDebugMode.new,
+ RemovePrint.new,
],
LintNames.avoid_private_typedef_functions: [
InlineTypedef.new,
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index be9d2c0..3f0281a7 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -573,6 +573,25 @@
return conflicts;
}
+ /// Returns the [ExpressionStatement] associated with [node] if [node] points
+ /// to the identifier for a simple `print`. Returns `null`,
+ /// otherwise.
+ ExpressionStatement? findSimplePrintInvocation(AstNode node) {
+ var parent = node.parent;
+ var grandparent = parent?.parent;
+ if (node is SimpleIdentifier) {
+ var element = node.staticElement;
+ if (element is FunctionElement &&
+ element.name == 'print' &&
+ element.library.isDartCore &&
+ parent is MethodInvocation &&
+ grandparent is ExpressionStatement) {
+ return grandparent;
+ }
+ }
+ return null;
+ }
+
/// Returns the indentation with the given level.
String getIndent(int level) => repeat(' ', level);
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
index 1734e00..4b5664a 100644
--- a/pkg/analysis_server/test/services/correction/util_test.dart
+++ b/pkg/analysis_server/test/services/correction/util_test.dart
@@ -272,6 +272,46 @@
''');
}
+ Future<void> test_findSimplePrintInvocation() async {
+ await resolveTestCode('''
+void f() {
+ print('hi');
+}
+''');
+ var printIdentifier = findNode.simple('print');
+ var expected = findNode.expressionStatement('print');
+ var result = CorrectionUtils(testAnalysisResult)
+ .findSimplePrintInvocation(printIdentifier);
+ expect(result, expected);
+ }
+
+ Future<void> test_findSimplePrintInvocation_custom_print() async {
+ await resolveTestCode('''
+void print(String toPrint) {
+}
+
+void f() {
+ print('hi');
+}
+''');
+ var printIdentifier = findNode.simple('print(\'hi\'');
+ var result = CorrectionUtils(testAnalysisResult)
+ .findSimplePrintInvocation(printIdentifier);
+ expect(result, null);
+ }
+
+ Future<void> test_findSimplePrintInvocation_negative() async {
+ await resolveTestCode('''
+void f() {
+ true ? print('hi') : print('false');
+}
+''');
+ var printIdentifier = findNode.simple('print(\'false');
+ var result = CorrectionUtils(testAnalysisResult)
+ .findSimplePrintInvocation(printIdentifier);
+ expect(result, null);
+ }
+
Future<void> test_invertCondition_binary_compare() async {
await assert_invertCondition('0 < 1', '0 >= 1');
await assert_invertCondition('0 > 1', '0 <= 1');
diff --git a/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart b/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart
new file mode 100644
index 0000000..129b7a0
--- /dev/null
+++ b/pkg/analysis_server/test/src/analytics/google_analytics_manager_test.dart
@@ -0,0 +1,321 @@
+// Copyright (c) 2022, 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/protocol/protocol.dart';
+import 'package:analysis_server/src/analytics/google_analytics_manager.dart';
+import 'package:analysis_server/src/analytics/percentile_calculator.dart';
+import 'package:analysis_server/src/plugin/plugin_manager.dart';
+import 'package:analyzer/dart/analysis/context_root.dart' as analyzer;
+import 'package:telemetry/telemetry.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(GoogleAnalyticsManagerTest);
+ });
+}
+
+@reflectiveTest
+class GoogleAnalyticsManagerTest {
+ final analytics = _MockAnalytics();
+ late final GoogleAnalyticsManager manager;
+
+ void setUp() {
+ manager = GoogleAnalyticsManager(analytics);
+ }
+
+ void test_plugin_request() {
+ _defaultStartup();
+ PluginManager.pluginResponseTimes[_MockPluginInfo('a')] = {
+ 'analysis.getNavigation': PercentileCalculator(),
+ };
+ manager.shutdown();
+ analytics.assertEvents([
+ _ExpectedEvent.session(),
+ _ExpectedEvent.pluginRequest(parameters: {
+ 'pluginId': 'a',
+ 'method': 'analysis.getNavigation',
+ 'duration': _IsPercentiles(),
+ }),
+ ]);
+ PluginManager.pluginResponseTimes.clear();
+ }
+
+ void test_server_request() {
+ _defaultStartup();
+ manager.startedRequest(
+ request: Request('1', 'server.shutdown'), startTime: _now());
+ manager.sentResponse(response: Response('1'));
+ manager.shutdown();
+ analytics.assertEvents([
+ _ExpectedEvent.session(),
+ _ExpectedEvent.request(parameters: {
+ 'latency': _IsPercentiles(),
+ 'method': 'server.shutdown',
+ 'duration': _IsPercentiles(),
+ }),
+ ]);
+ }
+
+ void test_shutdownWithoutStartup() {
+ manager.shutdown();
+ analytics.assertNoEvents();
+ }
+
+ void test_startup_withoutVersion() {
+ var arguments = ['a', 'b'];
+ var clientId = 'clientId';
+ var sdkVersion = 'sdkVersion';
+ manager.startUp(
+ time: DateTime.now(),
+ arguments: arguments,
+ clientId: clientId,
+ clientVersion: null,
+ sdkVersion: sdkVersion);
+ manager.shutdown();
+ analytics.assertEvents([
+ _ExpectedEvent.session(parameters: {
+ 'flags': arguments.join(' '),
+ 'clientId': clientId,
+ 'clientVersion': '',
+ 'sdkVersion': sdkVersion,
+ 'duration': _IsStringEncodedPositiveInt(),
+ }),
+ ]);
+ }
+
+ void test_startup_withPlugins() {
+ _defaultStartup();
+ manager.changedPlugins(_MockPluginManager(plugins: [
+ _MockPluginInfo('a'),
+ _MockPluginInfo('b'),
+ ]));
+ manager.shutdown();
+ analytics.assertEvents([
+ _ExpectedEvent.session(parameters: {
+ 'plugins': '{"recordCount":1,"rootCounts":{"a":"1[0, 0, 0, 0, 0, 0, '
+ '0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]","b":"1[0, 0, 0, 0, 0, '
+ '0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"}}'
+ }),
+ ]);
+ }
+
+ void test_startup_withVersion() {
+ var arguments = ['a', 'b'];
+ var clientId = 'clientId';
+ var clientVersion = 'clientVersion';
+ var sdkVersion = 'sdkVersion';
+ manager.startUp(
+ time: DateTime.now(),
+ arguments: arguments,
+ clientId: clientId,
+ clientVersion: clientVersion,
+ sdkVersion: sdkVersion);
+ manager.shutdown();
+ analytics.assertEvents([
+ _ExpectedEvent.session(parameters: {
+ 'flags': arguments.join(' '),
+ 'clientId': clientId,
+ 'clientVersion': clientVersion,
+ '': isNull,
+ 'sdkVersion': sdkVersion,
+ 'duration': _IsStringEncodedPositiveInt(),
+ }),
+ ]);
+ }
+
+ void _defaultStartup() {
+ manager.startUp(
+ time: DateTime.now(),
+ arguments: [],
+ clientId: '',
+ clientVersion: null,
+ sdkVersion: '');
+ }
+
+ DateTime _now() => DateTime.now();
+}
+
+/// A record of an event that was reported to analytics.
+class _Event {
+ final String category;
+ final String action;
+ final String? label;
+ final int? value;
+ final Map<String, String>? parameters;
+
+ _Event(this.category, this.action, this.label, this.value, this.parameters);
+}
+
+/// A record of an event that was reported to analytics.
+class _ExpectedEvent {
+ final String category;
+ final String action;
+ final String? label;
+ final int? value;
+ final Map<String, Object>? parameters;
+
+ _ExpectedEvent(this.category, this.action,
+ {this.label, // ignore: unused_element
+ this.value, // ignore: unused_element
+ this.parameters});
+
+ _ExpectedEvent.pluginRequest({Map<String, Object>? parameters})
+ : this('language_server', 'pluginRequest', parameters: parameters);
+
+ _ExpectedEvent.request({Map<String, Object>? parameters})
+ : this('language_server', 'request', parameters: parameters);
+
+ _ExpectedEvent.session({Map<String, Object>? parameters})
+ : this('language_server', 'session', parameters: parameters);
+
+ /// Compare the expected event with the [actual] event, failing if the actual
+ /// doesn't match the expected.
+ void matches(_Event actual) {
+ expect(actual.category, category);
+ expect(actual.action, action);
+ if (label != null) {
+ expect(actual.label, label);
+ }
+ if (value != null) {
+ expect(actual.value, value);
+ }
+ final actualParameters = actual.parameters;
+ final expectedParameters = parameters;
+ if (expectedParameters != null) {
+ if (actualParameters == null) {
+ fail('Expected parameters but found none');
+ }
+ for (var expectedKey in expectedParameters.keys) {
+ var actualValue = actualParameters[expectedKey];
+ var expectedValue = expectedParameters[expectedKey];
+ expect(actualValue, expectedValue, reason: 'For key $expectedKey');
+ }
+ }
+ }
+}
+
+/// A matcher for strings containing positive integer values.
+class _IsPercentiles extends Matcher {
+ const _IsPercentiles();
+
+ @override
+ Description describe(Description description) =>
+ description.add('percentiles');
+
+ @override
+ bool matches(Object? item, Map matchState) {
+ if (item is! String || !item.endsWith(']')) {
+ return false;
+ }
+ var index = item.indexOf('[');
+ var count = item.substring(0, index);
+ if (!_isStringEncodedPositiveInt(count)) {
+ return false;
+ }
+ var percentiles = item.substring(index + 1, item.length - 1).split(', ');
+ if (percentiles.length != 20) {
+ return false;
+ }
+ for (var percentile in percentiles) {
+ if (!_isStringEncodedPositiveInt(percentile)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool _isStringEncodedPositiveInt(String item) {
+ try {
+ var value = int.parse(item);
+ return value >= 0;
+ } catch (exception) {
+ return false;
+ }
+ }
+}
+
+/// A matcher for strings containing positive integer values.
+class _IsStringEncodedPositiveInt extends Matcher {
+ const _IsStringEncodedPositiveInt();
+
+ @override
+ Description describe(Description description) =>
+ description.add('a string encoded positive integer');
+
+ @override
+ bool matches(Object? item, Map matchState) {
+ if (item is! String) {
+ return false;
+ }
+ try {
+ var value = int.parse(item);
+ return value >= 0;
+ } catch (exception) {
+ return false;
+ }
+ }
+}
+
+/// An implementation of [Analytics] specialized for testing.
+class _MockAnalytics implements Analytics {
+ List<_Event> events = [];
+
+ _MockAnalytics();
+
+ void assertEvents(List<_ExpectedEvent> expectedEvents) {
+ var expectedCount = expectedEvents.length;
+ expect(events, hasLength(expectedCount));
+ for (int i = 0; i < expectedCount; i++) {
+ expectedEvents[i].matches(events[i]);
+ }
+ }
+
+ void assertNoEvents() {
+ expect(events, isEmpty);
+ }
+
+ @override
+ void close() {
+ // ignored
+ }
+
+ @override
+ dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+ @override
+ Future sendEvent(String category, String action,
+ {String? label, int? value, Map<String, String>? parameters}) async {
+ events.add(_Event(category, action, label, value, parameters));
+ }
+
+ @override
+ Future waitForLastPing({Duration? timeout}) async {
+ // ignored
+ }
+}
+
+class _MockPluginInfo implements PluginInfo {
+ @override
+ String pluginId;
+
+ _MockPluginInfo(this.pluginId);
+
+ @override
+ Set<analyzer.ContextRoot> get contextRoots => {};
+
+ @override
+ dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class _MockPluginManager implements PluginManager {
+ @override
+ List<PluginInfo> plugins;
+
+ _MockPluginManager({this.plugins = const []});
+
+ @override
+ dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analysis_server/test/src/analytics/test_all.dart b/pkg/analysis_server/test/src/analytics/test_all.dart
index b969877..d372a69 100644
--- a/pkg/analysis_server/test/src/analytics/test_all.dart
+++ b/pkg/analysis_server/test/src/analytics/test_all.dart
@@ -4,10 +4,12 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'google_analytics_manager_test.dart' as google_analytics_manager;
import 'percentile_calculator_test.dart' as percentile_calculator;
void main() {
defineReflectiveSuite(() {
+ google_analytics_manager.main();
percentile_calculator.main();
});
}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/remove_print_test.dart b/pkg/analysis_server/test/src/services/correction/fix/remove_print_test.dart
new file mode 100644
index 0000000..2622507
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/remove_print_test.dart
@@ -0,0 +1,144 @@
+// Copyright (c) 2022, 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/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RemovePrintTest);
+ defineReflectiveTests(RemovePrintMultiTest);
+ });
+}
+
+@reflectiveTest
+class RemovePrintMultiTest extends FixInFileProcessorTest {
+ @override
+ void setUp() {
+ super.setUp();
+ createAnalysisOptionsFile(
+ lints: [LintNames.avoid_print],
+ );
+ }
+
+ Future<void> test_multi_prints() async {
+ await resolveTestCode('''
+void f() {
+ print('');
+ 1+2;
+ print('more');
+}
+''');
+ var fixes = await getFixesForFirstError();
+ expect(fixes, hasLength(1));
+ assertProduces(fixes.first, '''
+void f() {
+ 1+2;
+}
+''');
+ }
+
+ Future<void> test_multi_prints_on_line() async {
+ await resolveTestCode('''
+void f() {
+ print(''); 3+4; print('even more');
+ 1+2;
+ print('more');
+}
+''');
+ var fixes = await getFixesForFirstError();
+ expect(fixes, hasLength(1));
+ assertProduces(fixes.first, '''
+void f() {
+ 3+4;
+ 1+2;
+}
+''');
+ }
+
+ Future<void> test_multi_prints_stacked() async {
+ await resolveTestCode('''
+void f() {
+ print('');
+ print('more');
+}
+''');
+ var fixes = await getFixesForFirstError();
+ expect(fixes, hasLength(1));
+ assertProduces(fixes.first, '''
+void f() {
+}
+''');
+ }
+}
+
+@reflectiveTest
+class RemovePrintTest extends FixProcessorLintTest {
+ @override
+ FixKind get kind => DartFixKind.REMOVE_PRINT;
+
+ @override
+ String get lintCode => LintNames.avoid_print;
+
+ @override
+ void setUp() {
+ super.setUp();
+ writeTestPackageConfig();
+ }
+
+ Future<void> test_multi_statement() async {
+ await resolveTestCode('''
+void f() {
+ print(''); 1+2;
+}
+''');
+ await assertHasFix('''
+void f() {
+ 1+2;
+}
+''');
+ }
+
+ Future<void> test_multiline_but_still_simple() async {
+ await resolveTestCode('''
+void f() {
+ print('asdfasdf'
+ 'sdfg'
+ 'sdfgsdfgsdfg'
+ 'sdfgsdfgsdfg'
+ '${3}');
+}
+''');
+ await assertHasFix('''
+void f() {
+}
+''');
+ }
+
+ Future<void> test_nested() async {
+ await resolveTestCode('''
+void f(bool b) {
+ b ? print('') : f(true);
+}
+''');
+ await assertNoFix();
+ }
+
+ Future<void> test_statement() async {
+ await resolveTestCode('''
+void f() {
+ print('');
+}
+''');
+ await assertHasFix('''
+void f() {
+}
+''');
+ }
+}
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 d383acf..323361b 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
@@ -161,6 +161,7 @@
as remove_parameters_in_getter_declaration;
import 'remove_parentheses_in_getter_invocation_test.dart'
as remove_parentheses_in_getter_invocation;
+import 'remove_print_test.dart' as remove_print;
import 'remove_question_mark_test.dart' as remove_question_mark;
import 'remove_returned_value_test.dart' as remove_returned_value;
import 'remove_this_expression_test.dart' as remove_this_expression;
@@ -372,6 +373,7 @@
remove_operator.main();
remove_parameters_in_getter_declaration.main();
remove_parentheses_in_getter_invocation.main();
+ remove_print.main();
remove_question_mark.main();
remove_returned_value.main();
remove_this_expression.main();
diff --git a/tools/VERSION b/tools/VERSION
index 9d216f3..3548928 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 18
PATCH 0
-PRERELEASE 165
+PRERELEASE 166
PRERELEASE_PATCH 0
\ No newline at end of file