Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library edit.domain; | 5 library edit.domain; |
| 6 | 6 |
| 7 import 'dart:async'; | |
| 8 | |
| 7 import 'package:analysis_server/src/analysis_server.dart'; | 9 import 'package:analysis_server/src/analysis_server.dart'; |
| 8 import 'package:analysis_server/src/constants.dart'; | 10 import 'package:analysis_server/src/constants.dart'; |
| 9 import 'package:analysis_server/src/edit/fix.dart'; | 11 import 'package:analysis_server/src/edit/fix.dart'; |
| 10 import 'package:analysis_server/src/protocol.dart'; | 12 import 'package:analysis_server/src/protocol.dart'; |
| 13 import 'package:analysis_server/src/protocol2.dart' as protocol show | |
| 14 LinkedEditGroup; | |
| 11 import 'package:analysis_server/src/protocol2.dart' show AnalysisError, | 15 import 'package:analysis_server/src/protocol2.dart' show AnalysisError, |
| 12 EditGetAssistsParams, EditGetAvailableRefactoringsParams, | 16 EditGetAssistsParams, EditGetAvailableRefactoringsParams, |
| 13 EditGetAvailableRefactoringsResult, EditGetFixesParams, RefactoringKind; | 17 EditGetAvailableRefactoringsResult, EditGetFixesParams, |
| 18 EditGetRefactoringParams, EditGetRefactoringResult, LinkedEditGroup, Locatio n, | |
| 19 RefactoringKind, RefactoringProblem, RefactoringProblemSeverity, RenameOptio ns, | |
| 20 SourceChange; | |
| 14 import 'package:analysis_server/src/services/correction/assist.dart'; | 21 import 'package:analysis_server/src/services/correction/assist.dart'; |
| 15 import 'package:analysis_server/src/services/correction/change.dart'; | 22 import 'package:analysis_server/src/services/correction/change.dart'; |
| 16 import 'package:analysis_server/src/services/correction/fix.dart'; | 23 import 'package:analysis_server/src/services/correction/fix.dart'; |
| 24 import 'package:analysis_server/src/services/correction/status.dart'; | |
| 17 import 'package:analysis_server/src/services/json.dart'; | 25 import 'package:analysis_server/src/services/json.dart'; |
| 18 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; | 26 import 'package:analysis_server/src/services/refactoring/refactoring.dart'; |
| 19 import 'package:analysis_server/src/services/search/search_engine.dart'; | 27 import 'package:analysis_server/src/services/search/search_engine.dart'; |
| 20 import 'package:analyzer/src/generated/ast.dart'; | 28 import 'package:analyzer/src/generated/ast.dart'; |
| 21 import 'package:analyzer/src/generated/element.dart'; | 29 import 'package:analyzer/src/generated/element.dart'; |
| 22 import 'package:analyzer/src/generated/engine.dart' as engine; | 30 import 'package:analyzer/src/generated/engine.dart' as engine; |
| 23 import 'package:analyzer/src/generated/error.dart' as engine; | 31 import 'package:analyzer/src/generated/error.dart' as engine; |
| 24 import 'package:analyzer/src/generated/source.dart'; | 32 import 'package:analyzer/src/generated/source.dart'; |
| 25 | 33 |
| 26 | 34 |
| 27 /** | 35 /** |
| 28 * Instances of the class [EditDomainHandler] implement a [RequestHandler] | 36 * Instances of the class [EditDomainHandler] implement a [RequestHandler] |
| 29 * that handles requests in the edit domain. | 37 * that handles requests in the edit domain. |
| 30 */ | 38 */ |
| 31 class EditDomainHandler implements RequestHandler { | 39 class EditDomainHandler implements RequestHandler { |
| 32 /** | 40 /** |
| 33 * The analysis server that is using this handler to process requests. | 41 * The analysis server that is using this handler to process requests. |
| 34 */ | 42 */ |
| 35 final AnalysisServer server; | 43 final AnalysisServer server; |
| 36 | 44 |
| 37 /** | 45 /** |
| 38 * The [SearchEngine] for this server. | 46 * The [SearchEngine] for this server. |
| 39 */ | 47 */ |
| 40 SearchEngine searchEngine; | 48 SearchEngine searchEngine; |
| 41 | 49 |
| 50 _RefactoringManager refactoringManager; | |
| 51 | |
| 42 /** | 52 /** |
| 43 * Initialize a newly created handler to handle requests for the given [server ]. | 53 * Initialize a newly created handler to handle requests for the given [server ]. |
| 44 */ | 54 */ |
| 45 EditDomainHandler(this.server) { | 55 EditDomainHandler(this.server) { |
| 46 searchEngine = server.searchEngine; | 56 searchEngine = server.searchEngine; |
| 57 refactoringManager = new _RefactoringManager(server, searchEngine); | |
| 47 } | 58 } |
| 48 | 59 |
| 49 Response getAssists(Request request) { | 60 Response getAssists(Request request) { |
| 50 var params = new EditGetAssistsParams.fromRequest(request); | 61 var params = new EditGetAssistsParams.fromRequest(request); |
| 51 List<Change> changes = <Change>[]; | 62 List<Change> changes = <Change>[]; |
| 52 List<CompilationUnit> units = | 63 List<CompilationUnit> units = |
| 53 server.getResolvedCompilationUnits(params.file); | 64 server.getResolvedCompilationUnits(params.file); |
| 54 if (units.isNotEmpty) { | 65 if (units.isNotEmpty) { |
| 55 CompilationUnit unit = units[0]; | 66 CompilationUnit unit = units[0]; |
| 56 List<Assist> assists = | 67 List<Assist> assists = |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 123 } | 134 } |
| 124 } | 135 } |
| 125 // respond | 136 // respond |
| 126 return new Response(request.id)..setResult(FIXES, errorFixesList); | 137 return new Response(request.id)..setResult(FIXES, errorFixesList); |
| 127 } | 138 } |
| 128 | 139 |
| 129 @override | 140 @override |
| 130 Response handleRequest(Request request) { | 141 Response handleRequest(Request request) { |
| 131 try { | 142 try { |
| 132 String requestName = request.method; | 143 String requestName = request.method; |
| 133 if (requestName == EDIT_GET_AVAILABLE_REFACTORINGS) { | 144 if (requestName == EDIT_GET_ASSISTS) { |
| 145 return getAssists(request); | |
| 146 } else if (requestName == EDIT_GET_AVAILABLE_REFACTORINGS) { | |
| 134 return getAvailableRefactorings(request); | 147 return getAvailableRefactorings(request); |
| 135 } else if (requestName == EDIT_GET_ASSISTS) { | |
| 136 return getAssists(request); | |
| 137 } else if (requestName == EDIT_GET_FIXES) { | 148 } else if (requestName == EDIT_GET_FIXES) { |
| 138 return getFixes(request); | 149 return getFixes(request); |
| 150 } else if (requestName == EDIT_GET_REFACTORING) { | |
| 151 refactoringManager.getRefactoring(request); | |
| 152 return Response.DELAYED_RESPONSE; | |
| 139 } | 153 } |
| 140 } on RequestFailure catch (exception) { | 154 } on RequestFailure catch (exception) { |
| 141 return exception.response; | 155 return exception.response; |
| 142 } | 156 } |
| 143 return null; | 157 return null; |
| 144 } | 158 } |
| 145 } | 159 } |
| 160 | |
| 161 | |
| 162 /** | |
| 163 * An object managing [Refactoring] instances. | |
|
Brian Wilkerson
2014/08/23 17:53:16
I think this class is assuming that we only need t
scheglov
2014/08/23 21:14:07
Done.
| |
| 164 */ | |
| 165 class _RefactoringManager { | |
| 166 final AnalysisServer server; | |
| 167 final SearchEngine searchEngine; | |
| 168 | |
| 169 RefactoringKind kind; | |
| 170 String file; | |
| 171 int offset; | |
| 172 int length; | |
| 173 Refactoring refactoring; | |
| 174 RefactoringStatus initStatus; | |
| 175 RefactoringStatus optionsStatus; | |
| 176 RefactoringStatus finalStatus; | |
| 177 | |
| 178 String requestId; | |
| 179 EditGetRefactoringResult result; | |
| 180 | |
| 181 _RefactoringManager(this.server, this.searchEngine) { | |
| 182 _reset(); | |
| 183 } | |
| 184 | |
| 185 bool get _hasFatalError { | |
| 186 return initStatus.hasFatalError || | |
| 187 optionsStatus.hasFatalError || | |
| 188 finalStatus.hasFatalError; | |
| 189 } | |
| 190 | |
| 191 void getRefactoring(Request request) { | |
| 192 // prepare for processing the request | |
| 193 requestId = request.id; | |
| 194 result = new EditGetRefactoringResult(<RefactoringProblem>[]); | |
| 195 // process the request | |
| 196 var params = new EditGetRefactoringParams.fromRequest(request); | |
| 197 _init(params.kind, params.file, params.offset, params.length).then((_) { | |
| 198 if (_hasFatalError) { | |
| 199 return _sendResultResponse(); | |
| 200 } | |
| 201 // set options | |
| 202 if (params.options == null) { | |
| 203 return _sendResultResponse(); | |
| 204 } | |
| 205 optionsStatus = _setOptions(params.options); | |
| 206 if (_hasFatalError) { | |
| 207 return _sendResultResponse(); | |
| 208 } | |
| 209 // done if just validation | |
| 210 if (params.validateOnly) { | |
| 211 return _sendResultResponse(); | |
| 212 } | |
| 213 // validation and create change | |
| 214 refactoring.checkFinalConditions().then((_finalStatus) { | |
| 215 finalStatus = _finalStatus; | |
| 216 if (_hasFatalError) { | |
| 217 return _sendResultResponse(); | |
| 218 } | |
| 219 return refactoring.createChange().then((change) { | |
| 220 result.change = new SourceChange( | |
| 221 change.message, | |
| 222 change.fileEdits, | |
| 223 <protocol.LinkedEditGroup>[]); | |
| 224 return _sendResultResponse(); | |
| 225 }); | |
| 226 }); | |
| 227 }); | |
| 228 } | |
| 229 | |
| 230 /** | |
| 231 * Initializes this context to perform a refactoring with the specified | |
| 232 * parameters. The existing [Refactoring] is reused or created as needed. | |
| 233 */ | |
| 234 Future<RefactoringStatus> _init(RefactoringKind kind, String file, int offset, | |
| 235 int length) { | |
| 236 List<RefactoringProblem> problems = <RefactoringProblem>[]; | |
| 237 // check if we can continue with the existing Refactoring instance | |
| 238 if (this.kind == kind && | |
| 239 this.file == file && | |
| 240 this.offset == offset && | |
| 241 this.length == length) { | |
| 242 return new Future.value(initStatus); | |
| 243 } | |
| 244 _reset(); | |
| 245 this.kind = kind; | |
| 246 this.file = file; | |
| 247 this.offset = offset; | |
| 248 this.length = length; | |
| 249 // create a new Refactoring instance | |
| 250 if (kind == RefactoringKind.RENAME) { | |
| 251 List<Element> elements = server.getElementsAtOffset(file, offset); | |
| 252 if (elements.isNotEmpty) { | |
| 253 Element element = elements[0]; | |
| 254 refactoring = new RenameRefactoring(searchEngine, element); | |
| 255 } | |
| 256 } | |
| 257 if (refactoring == null) { | |
| 258 initStatus = | |
| 259 new RefactoringStatus.fatal('Unable to create a refactoring'); | |
| 260 return new Future.value(initStatus); | |
| 261 } | |
| 262 // check initial conditions | |
| 263 return refactoring.checkInitialConditions().then((status) { | |
| 264 initStatus = status; | |
| 265 return initStatus; | |
| 266 }); | |
| 267 } | |
| 268 | |
| 269 void _reset() { | |
| 270 refactoring = null; | |
| 271 initStatus = new RefactoringStatus(); | |
| 272 optionsStatus = new RefactoringStatus(); | |
| 273 finalStatus = new RefactoringStatus(); | |
| 274 } | |
| 275 | |
| 276 void _sendResultResponse() { | |
| 277 // set problems | |
| 278 { | |
| 279 RefactoringStatus status = new RefactoringStatus(); | |
| 280 status.addStatus(initStatus); | |
| 281 status.addStatus(optionsStatus); | |
| 282 status.addStatus(finalStatus); | |
| 283 result.problems = status.problems; | |
| 284 } | |
| 285 // send the response | |
| 286 server.sendResponse(result.toResponse(requestId)); | |
| 287 // done with this request | |
| 288 requestId = null; | |
| 289 result = null; | |
| 290 } | |
| 291 | |
| 292 RefactoringStatus _setOptions(Object options) { | |
| 293 if (refactoring is RenameRefactoring) { | |
| 294 RenameRefactoring renameRefactoring = refactoring; | |
| 295 RenameOptions renameOptions = options; | |
| 296 String newName = renameOptions.newName; | |
| 297 renameRefactoring.newName = newName; | |
| 298 return renameRefactoring.checkNewName(); | |
| 299 } | |
| 300 return new RefactoringStatus(); | |
| 301 } | |
| 302 } | |
| OLD | NEW |