[analysis_server] Check for bulk-fixable errors to skip resolution during bulk fix operations
Change-Id: I21a9fa4ed71839e7e196240c0bda31403cfea96c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308080
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
index 529db27..8edae78 100644
--- a/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/bulk_fix_processor.dart
@@ -533,7 +533,19 @@
}
/// Returns whether [error] is something that might be fixable.
- bool _isFixableError(AnalysisError error) => hasFix(error.errorCode);
+ bool _isFixableError(AnalysisError error) {
+ final errorCode = error.errorCode;
+
+ // Special cases that can be bulk fixed by this class but not by
+ // FixProcessor.
+ if (errorCode == WarningCode.DUPLICATE_IMPORT ||
+ errorCode == HintCode.UNNECESSARY_IMPORT ||
+ errorCode == WarningCode.UNUSED_IMPORT) {
+ return true;
+ }
+
+ return FixProcessor.canBulkFix(errorCode);
+ }
/// Return the override set corresponding to the given [result], or `null` if
/// there is no corresponding configuration file or the file content isn't a
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 1643b50..4b28c47 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -19,7 +19,8 @@
bool hasFix(ErrorCode errorCode) {
if (errorCode is LintCode) {
var lintName = errorCode.name;
- return FixProcessor.lintProducerMap.containsKey(lintName);
+ return FixProcessor.lintProducerMap.containsKey(lintName) ||
+ FixProcessor.lintMultiProducerMap.containsKey(lintName);
}
// TODO(brianwilkerson) Either deprecate the part of the protocol supported by
// this function, or handle error codes associated with non-dart files.
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 0f76947..02f6931 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -5,6 +5,7 @@
import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
import 'package:analysis_server/plugin/edit/fix/fix_dart.dart';
import 'package:analysis_server/src/services/correction/base_processor.dart';
+import 'package:analysis_server/src/services/correction/bulk_fix_processor.dart';
import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
import 'package:analysis_server/src/services/correction/dart/add_async.dart';
import 'package:analysis_server/src/services/correction/dart/add_await.dart';
@@ -376,6 +377,9 @@
/// The computer for Dart fixes.
class FixProcessor extends BaseProcessor {
+ /// Cached results of [canBulkFix].
+ static final Map<ErrorCode, bool> _bulkFixableErrorCodes = {};
+
static final Map<String, List<MultiProducerGenerator>> lintMultiProducerMap =
{
LintNames.deprecated_member_use_from_same_package: [
@@ -1821,6 +1825,36 @@
}
}
+ /// Returns whether [errorCode] is an error that can be fixed in bulk.
+ static bool canBulkFix(ErrorCode errorCode) {
+ bool hasBulkFixProducers(List<ProducerGenerator>? producers) {
+ return producers != null &&
+ producers.any((producer) => producer().canBeAppliedInBulk);
+ }
+
+ return _bulkFixableErrorCodes.putIfAbsent(errorCode, () {
+ if (errorCode is LintCode) {
+ final producers = FixProcessor.lintProducerMap[errorCode.name];
+ if (hasBulkFixProducers(producers)) {
+ return true;
+ }
+
+ return FixProcessor.lintMultiProducerMap.containsKey(errorCode.name);
+ }
+
+ final producers = FixProcessor.nonLintProducerMap[errorCode];
+ if (hasBulkFixProducers(producers)) {
+ return true;
+ }
+
+ // We can't do detailed checks on multi-producers because the set of
+ // producers may vary depending on the resolved unit (we must configure
+ // them before we can determine the producers).
+ return FixProcessor.nonLintMultiProducerMap.containsKey(errorCode) ||
+ BulkFixProcessor.nonLintMultiProducerMap.containsKey(errorCode);
+ });
+ }
+
/// Associate the given correction producer [generator] with the lint with the
/// given [lintName].
static void registerFixForLint(String lintName, ProducerGenerator generator) {