blob: 28964074ed6b52442309e8b3b4eb27dedc684282 [file] [log] [blame]
// 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/protocol/protocol_generated.dart';
import 'package:analysis_server/src/edit/edit_dartfix.dart';
import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
import 'package:analysis_server/src/services/correction/change_workspace.dart';
import 'package:analysis_server/src/services/correction/fix.dart';
import 'package:analysis_server/src/services/correction/fix_internal.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/instrumentation/service.dart';
import 'package:analyzer/src/error/codes.dart';
/// A processor used by [EditDartFix] to manage [FixErrorTask]s.
mixin FixErrorProcessor {
/// A mapping from [ErrorCode] to the fix that should be applied.
final errorTaskMap = <ErrorCode, FixErrorTask>{};
Future<bool> processErrors(ResolvedUnitResult result) async {
var foundError = false;
for (var error in result.errors) {
final task = errorTaskMap[error.errorCode];
if (task != null) {
await task.fixError(result, error);
} else if (error.errorCode.type == ErrorType.SYNTACTIC_ERROR) {
foundError = true;
}
}
return foundError;
}
void registerErrorTask(ErrorCode errorCode, FixErrorTask task) {
errorTaskMap[errorCode] = task;
}
}
/// A task for fixing a particular error
class FixErrorTask {
final DartFixListener listener;
FixErrorTask(this.listener);
Future<void> fixError(ResolvedUnitResult result, AnalysisError error) async {
final workspace = DartChangeWorkspace(listener.server.currentSessions);
final dartContext = DartFixContextImpl(
InstrumentationService.NULL_SERVICE,
workspace,
result,
error,
(name) => [],
);
final processor = FixProcessor(dartContext);
var fix = await processor.computeFix();
final location = listener.locationFor(result, error.offset, error.length);
if (fix != null) {
listener.addSourceChange(fix.change.message, location, fix.change);
} else {
// TODO(danrubel): Determine why the fix could not be applied
// and report that in the description.
listener.addRecommendation("Couldn't fix \"${error.message}\"", location);
}
}
static void fixNamedConstructorTypeArgs(DartFixRegistrar registrar,
DartFixListener listener, EditDartfixParams params) {
registrar.registerErrorTask(
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
FixErrorTask(listener));
}
}