| 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 services.completion.dart; | 5 library services.completion.dart; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol.dart'; | 9 import 'package:analysis_server/src/protocol.dart'; |
| 10 import 'package:analysis_server/src/services/completion/arglist_computer.dart'; | 10 import 'package:analysis_server/src/services/completion/arglist_computer.dart'; |
| 11 import 'package:analysis_server/src/services/completion/combinator_computer.dart
'; | 11 import 'package:analysis_server/src/services/completion/combinator_computer.dart
'; |
| 12 import 'package:analysis_server/src/services/completion/completion_manager.dart'
; | 12 import 'package:analysis_server/src/services/completion/completion_manager.dart'
; |
| 13 import 'package:analysis_server/src/services/completion/completion_target.dart'; |
| 13 import 'package:analysis_server/src/services/completion/dart_completion_cache.da
rt'; | 14 import 'package:analysis_server/src/services/completion/dart_completion_cache.da
rt'; |
| 14 import 'package:analysis_server/src/services/completion/imported_computer.dart'; | 15 import 'package:analysis_server/src/services/completion/imported_computer.dart'; |
| 15 import 'package:analysis_server/src/services/completion/invocation_computer.dart
'; | 16 import 'package:analysis_server/src/services/completion/invocation_computer.dart
'; |
| 16 import 'package:analysis_server/src/services/completion/keyword_computer.dart'; | 17 import 'package:analysis_server/src/services/completion/keyword_computer.dart'; |
| 17 import 'package:analysis_server/src/services/completion/local_computer.dart'; | 18 import 'package:analysis_server/src/services/completion/local_computer.dart'; |
| 18 import 'package:analysis_server/src/services/completion/optype.dart'; | 19 import 'package:analysis_server/src/services/completion/optype.dart'; |
| 19 import 'package:analysis_server/src/services/search/search_engine.dart'; | 20 import 'package:analysis_server/src/services/search/search_engine.dart'; |
| 20 import 'package:analyzer/src/generated/ast.dart'; | 21 import 'package:analyzer/src/generated/ast.dart'; |
| 21 import 'package:analyzer/src/generated/engine.dart'; | 22 import 'package:analyzer/src/generated/engine.dart'; |
| 22 import 'package:analyzer/src/generated/source.dart'; | 23 import 'package:analyzer/src/generated/source.dart'; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 * Compute suggestions based upon cached information only | 91 * Compute suggestions based upon cached information only |
| 91 * then send an initial response to the client. | 92 * then send an initial response to the client. |
| 92 * Return a list of computers for which [computeFull] should be called | 93 * Return a list of computers for which [computeFull] should be called |
| 93 */ | 94 */ |
| 94 List<DartCompletionComputer> computeFast(DartCompletionRequest request) { | 95 List<DartCompletionComputer> computeFast(DartCompletionRequest request) { |
| 95 return request.performance.logElapseTime('computeFast', () { | 96 return request.performance.logElapseTime('computeFast', () { |
| 96 CompilationUnit unit = context.parseCompilationUnit(source); | 97 CompilationUnit unit = context.parseCompilationUnit(source); |
| 97 request.unit = unit; | 98 request.unit = unit; |
| 98 request.node = new NodeLocator.con1(request.offset).searchWithin(unit); | 99 request.node = new NodeLocator.con1(request.offset).searchWithin(unit); |
| 99 request.node.accept(new _ReplacementOffsetBuilder(request)); | 100 request.node.accept(new _ReplacementOffsetBuilder(request)); |
| 101 request.target = new CompletionTarget.forOffset(unit, request.offset); |
| 100 List<DartCompletionComputer> todo = new List.from(computers); | 102 List<DartCompletionComputer> todo = new List.from(computers); |
| 101 todo.removeWhere((DartCompletionComputer c) { | 103 todo.removeWhere((DartCompletionComputer c) { |
| 102 return request.performance.logElapseTime( | 104 return request.performance.logElapseTime( |
| 103 'computeFast ${c.runtimeType}', | 105 'computeFast ${c.runtimeType}', |
| 104 () { | 106 () { |
| 105 return c.computeFast(request); | 107 return c.computeFast(request); |
| 106 }); | 108 }); |
| 107 }); | 109 }); |
| 108 sendResults(request, todo.isEmpty); | 110 sendResults(request, todo.isEmpty); |
| 109 return todo; | 111 return todo; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 122 return; | 124 return; |
| 123 } | 125 } |
| 124 request.performance.logElapseTime('waitForAnalysis'); | 126 request.performance.logElapseTime('waitForAnalysis'); |
| 125 if (unit == null) { | 127 if (unit == null) { |
| 126 sendResults(request, true); | 128 sendResults(request, true); |
| 127 return; | 129 return; |
| 128 } | 130 } |
| 129 request.performance.logElapseTime('computeFull', () { | 131 request.performance.logElapseTime('computeFull', () { |
| 130 request.unit = unit; | 132 request.unit = unit; |
| 131 request.node = new NodeLocator.con1(request.offset).searchWithin(unit); | 133 request.node = new NodeLocator.con1(request.offset).searchWithin(unit); |
| 134 // TODO(paulberry): Do we need to invoke _ReplacementOffsetBuilder |
| 135 // again? |
| 136 request.target = new CompletionTarget.forOffset(unit, request.offset); |
| 132 int count = todo.length; | 137 int count = todo.length; |
| 133 todo.forEach((DartCompletionComputer c) { | 138 todo.forEach((DartCompletionComputer c) { |
| 134 String name = c.runtimeType.toString(); | 139 String name = c.runtimeType.toString(); |
| 135 String completeTag = 'computeFull $name complete'; | 140 String completeTag = 'computeFull $name complete'; |
| 136 request.performance.logStartTime(completeTag); | 141 request.performance.logStartTime(completeTag); |
| 137 request.performance.logElapseTime('computeFull $name', () { | 142 request.performance.logElapseTime('computeFull $name', () { |
| 138 c.computeFull(request).then((bool changed) { | 143 c.computeFull(request).then((bool changed) { |
| 139 request.performance.logElapseTime(completeTag); | 144 request.performance.logElapseTime(completeTag); |
| 140 bool last = --count == 0; | 145 bool last = --count == 0; |
| 141 if (changed || last) { | 146 if (changed || last) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 CompilationUnit unit; | 236 CompilationUnit unit; |
| 232 | 237 |
| 233 /** | 238 /** |
| 234 * The node in which the completion occurred. This node | 239 * The node in which the completion occurred. This node |
| 235 * may or may not be resolved when [DartCompletionComputer.computeFast] | 240 * may or may not be resolved when [DartCompletionComputer.computeFast] |
| 236 * is called but is resolved when [DartCompletionComputer.computeFull]. | 241 * is called but is resolved when [DartCompletionComputer.computeFull]. |
| 237 */ | 242 */ |
| 238 AstNode node; | 243 AstNode node; |
| 239 | 244 |
| 240 /** | 245 /** |
| 246 * The completion target. This determines what part of the parse tree |
| 247 * will receive the newly inserted text. |
| 248 * |
| 249 * TODO(paulberry) gradually transition code over to using this rather than |
| 250 * [node]. |
| 251 */ |
| 252 CompletionTarget target; |
| 253 |
| 254 /** |
| 241 * Information about the types of suggestions that should be included. | 255 * Information about the types of suggestions that should be included. |
| 242 */ | 256 */ |
| 243 OpType _optype; | 257 OpType _optype; |
| 244 | 258 |
| 245 /** | 259 /** |
| 246 * The offset of the start of the text to be replaced. | 260 * The offset of the start of the text to be replaced. |
| 247 * This will be different than the offset used to request the completion | 261 * This will be different than the offset used to request the completion |
| 248 * suggestions if there was a portion of an identifier before the original | 262 * suggestions if there was a portion of an identifier before the original |
| 249 * offset. In particular, the replacementOffset will be the offset of the | 263 * offset. In particular, the replacementOffset will be the offset of the |
| 250 * beginning of said identifier. | 264 * beginning of said identifier. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 271 * Return the original text from the [replacementOffset] to the [offset] | 285 * Return the original text from the [replacementOffset] to the [offset] |
| 272 * that can be used to filter the suggestions on the server side. | 286 * that can be used to filter the suggestions on the server side. |
| 273 */ | 287 */ |
| 274 String get filterText { | 288 String get filterText { |
| 275 return context.getContents( | 289 return context.getContents( |
| 276 source).data.substring(replacementOffset, offset); | 290 source).data.substring(replacementOffset, offset); |
| 277 } | 291 } |
| 278 | 292 |
| 279 /** | 293 /** |
| 280 * Information about the types of suggestions that should be included. | 294 * Information about the types of suggestions that should be included. |
| 281 * This will return `null` if the [node] has not been set. | 295 * The [target] must be set first. |
| 282 */ | 296 */ |
| 283 OpType get optype { | 297 OpType get optype { |
| 284 if (_optype == null && node != null) { | 298 if (_optype == null) { |
| 285 _optype = new OpType.forCompletion(node, offset); | 299 _optype = new OpType.forCompletion(target, offset); |
| 286 } | 300 } |
| 287 return _optype; | 301 return _optype; |
| 288 } | 302 } |
| 289 } | 303 } |
| 290 | 304 |
| 291 /** | 305 /** |
| 292 * Visitor used to determine the replacement offset and length | 306 * Visitor used to determine the replacement offset and length |
| 293 * based upon the cursor location. | 307 * based upon the cursor location. |
| 294 */ | 308 */ |
| 295 class _ReplacementOffsetBuilder extends SimpleAstVisitor { | 309 class _ReplacementOffsetBuilder extends SimpleAstVisitor { |
| 296 final DartCompletionRequest request; | 310 final DartCompletionRequest request; |
| 297 | 311 |
| 298 _ReplacementOffsetBuilder(this.request) { | 312 _ReplacementOffsetBuilder(this.request) { |
| 299 request.replacementOffset = request.offset; | 313 request.replacementOffset = request.offset; |
| 300 request.replacementLength = 0; | 314 request.replacementLength = 0; |
| 301 } | 315 } |
| 302 | 316 |
| 303 visitSimpleIdentifier(SimpleIdentifier node) { | 317 visitSimpleIdentifier(SimpleIdentifier node) { |
| 304 request.replacementOffset = node.offset; | 318 request.replacementOffset = node.offset; |
| 305 request.replacementLength = node.length; | 319 request.replacementLength = node.length; |
| 306 } | 320 } |
| 307 } | 321 } |
| OLD | NEW |