| // 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)); |
| } |
| } |