diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart index bb4aeb3105f..a17cafa2914 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix.dart @@ -344,6 +344,8 @@ class DartFixKind { const FixKind('REPLACE_WITH_BRACKETS', 50, "Replace with { }"); static const REPLACE_WITH_CONDITIONAL_ASSIGNMENT = const FixKind( 'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, "Replace with ??="); + static const REPLACE_WITH_EXTENSION_NAME = + const FixKind('REPLACE_WITH_EXTENSION_NAME', 50, "Replace with '{0}'"); static const REPLACE_WITH_IDENTIFIER = const FixKind('REPLACE_WITH_IDENTIFIER', 50, "Replace with identifier"); static const REPLACE_WITH_IS_EMPTY = 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 085ba9793ac..7f91dd0b43e 100644 --- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart +++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart @@ -562,6 +562,10 @@ class FixProcessor extends BaseProcessor { if (errorCode == StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH) { await _addFix_addMissingEnumCaseClauses(); } + if (errorCode == + CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER) { + await _addFix_replaceWithExtensionName(); + } // lints if (errorCode is LintCode) { String name = errorCode.name; @@ -3657,6 +3661,30 @@ class FixProcessor extends BaseProcessor { } } + Future _addFix_replaceWithExtensionName() async { + if (node is! SimpleIdentifier) { + return; + } + AstNode parent = node.parent; + AstNode target = null; + if (parent is MethodInvocation && node == parent.methodName) { + target = parent.target; + } else if (parent is PropertyAccess && node == parent.propertyName) { + target = parent.target; + } + if (target is! ExtensionOverride) { + return; + } + ExtensionOverride override = target; + var changeBuilder = _newDartChangeBuilder(); + await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) { + builder.addSimpleReplacement( + range.node(override), utils.getNodeText(override.extensionName)); + }); + _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_WITH_EXTENSION_NAME, + args: [override.extensionName.name]); + } + Future _addFix_replaceWithIdentifier() async { final FunctionTypedFormalParameter functionTyped = node.thisOrAncestorOfType(); diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart new file mode 100644 index 00000000000..b31de86229a --- /dev/null +++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_extension_name_test.dart @@ -0,0 +1,113 @@ +// Copyright (c) 2019, 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:analyzer/src/dart/analysis/experiments.dart'; +import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; +import 'package:test_reflective_loader/test_reflective_loader.dart'; + +import 'fix_processor.dart'; + +main() { + defineReflectiveSuite(() { + defineReflectiveTests(ReplaceWithExtensionNameTest); + }); +} + +@reflectiveTest +class ReplaceWithExtensionNameTest extends FixProcessorTest { + @override + FixKind get kind => DartFixKind.REPLACE_WITH_EXTENSION_NAME; + + @override + void setupResourceProvider() { + super.setupResourceProvider(); + createAnalysisOptionsFile(experiments: [EnableString.extension_methods]); + } + + test_getter() async { + await resolveTestUnit(''' +extension E on String { + static int get g => 0; +} + +void f() { + E('a').g; +} +'''); + await assertHasFix(''' +extension E on String { + static int get g => 0; +} + +void f() { + E.g; +} +'''); + } + + test_method() async { + await resolveTestUnit(''' +extension E on String { + static int m() => 0; +} + +void f() { + E('a').m(); +} +'''); + await assertHasFix(''' +extension E on String { + static int m() => 0; +} + +void f() { + E.m(); +} +'''); + } + + test_qualified() async { + newFile('/home/test/lib/ext.dart', content: ''' +extension E on String { + static int m() => 0; +} +'''); + await resolveTestUnit(''' +import 'ext.dart' as ext; + +void f() { + ext.E('a').m(); +} +'''); + await assertHasFix(''' +import 'ext.dart' as ext; + +void f() { + ext.E.m(); +} +'''); + } + + test_setter() async { + await resolveTestUnit(''' +extension E on String { + static set s(int i) {} +} + +void f() { + E('a').s = 3; +} +'''); + await assertHasFix(''' +extension E on String { + static set s(int i) {} +} + +void f() { + E.s = 3; +} +'''); + } +} 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 fe2e8a4bbaf..2046875274d 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 @@ -114,6 +114,7 @@ import 'replace_var_with_dynamic_test.dart' as replace_var_with_dynamic; import 'replace_with_brackets_test.dart' as replace_with_brackets; import 'replace_with_conditional_assignment_test.dart' as replace_with_conditional_assignment; +import 'replace_with_extension_name_test.dart' as replace_with_extension_name; import 'replace_with_identifier_test.dart' as replace_with_identifier; import 'replace_with_is_empty_test.dart' as replace_with_is_empty; import 'replace_with_is_not_empty_test.dart' as replace_with_is_not_empty; @@ -228,6 +229,7 @@ main() { replace_var_with_dynamic.main(); replace_with_brackets.main(); replace_with_conditional_assignment.main(); + replace_with_extension_name.main(); replace_with_identifier.main(); replace_with_is_empty.main(); replace_with_is_not_empty.main();