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 services.completion.computer; | 5 library services.completion.computer; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_services/completion/completion_suggestion.dart'; | 9 import 'package:analysis_services/completion/completion_suggestion.dart'; |
| 10 import 'package:analysis_services/search/search_engine.dart'; | 10 import 'package:analysis_services/search/search_engine.dart'; |
| 11 import 'package:analysis_services/src/completion/top_level_computer.dart'; | 11 import 'package:analysis_services/src/completion/top_level_computer.dart'; |
| 12 import 'package:analyzer/src/generated/ast.dart'; | |
| 13 import 'package:analyzer/src/generated/element.dart'; | |
| 12 import 'package:analyzer/src/generated/engine.dart'; | 14 import 'package:analyzer/src/generated/engine.dart'; |
| 13 import 'package:analyzer/src/generated/source.dart'; | 15 import 'package:analyzer/src/generated/source.dart'; |
| 14 | 16 |
| 15 /** | 17 /** |
| 16 * The base class for computing code completion suggestions. | 18 * The base class for computing code completion suggestions. |
| 17 */ | 19 */ |
| 18 abstract class CompletionComputer { | 20 abstract class CompletionComputer { |
| 19 | 21 |
| 20 /** | 22 /** |
| 21 * Computes [CompletionSuggestion]s for the specified position in the source. | 23 * Computes [CompletionSuggestion]s for the specified position in the source. |
| 22 */ | 24 */ |
| 23 Future<List<CompletionSuggestion>> compute(); | 25 Future<List<CompletionSuggestion>> compute(); |
| 24 } | 26 } |
| 25 | 27 |
| 26 /** | 28 /** |
| 27 * Manages `CompletionComputer`s for a given completion request. | 29 * Manages `CompletionComputer`s for a given completion request. |
| 28 */ | 30 */ |
| 29 abstract class CompletionManager { | 31 abstract class CompletionManager { |
| 30 | 32 |
| 31 /** | |
| 32 * Create a manager for the given request. | |
| 33 */ | |
| 34 static CompletionManager create(Source source, int offset, | |
| 35 SearchEngine searchEngine) { | |
| 36 if (AnalysisEngine.isDartFileName(source.shortName)) { | |
| 37 return new DartCompletionManager(source, offset, searchEngine); | |
| 38 } | |
| 39 return new NoOpCompletionManager(source, offset); | |
| 40 } | |
| 41 | |
| 42 StreamController<CompletionResult> controller; | 33 StreamController<CompletionResult> controller; |
| 43 | 34 |
| 44 /** | 35 /** |
| 36 * Compute completion results and append them to the stream. | |
| 37 * Clients should not call this method directly as it is automatically called | |
| 38 * when a client listens to the stream returned by [results]. | |
| 39 */ | |
| 40 void compute(); | |
| 41 | |
| 42 /** | |
| 45 * Generate a stream of code completion results. | 43 * Generate a stream of code completion results. |
| 46 */ | 44 */ |
| 47 Stream<CompletionResult> results() { | 45 Stream<CompletionResult> results() { |
| 48 controller = new StreamController<CompletionResult>(onListen: () { | 46 controller = new StreamController<CompletionResult>(onListen: () { |
| 49 scheduleMicrotask(compute); | 47 scheduleMicrotask(compute); |
| 50 }); | 48 }); |
| 51 return controller.stream; | 49 return controller.stream; |
| 52 } | 50 } |
| 53 | 51 |
| 54 /** | 52 /** |
| 55 * Compute completion results and append them to the stream. | 53 * Create a manager for the given request. |
| 56 * Clients should not call this method directly as it is automatically called | |
| 57 * when a client listens to the stream returned by [results]. | |
| 58 */ | 54 */ |
| 59 void compute(); | 55 static CompletionManager create(AnalysisContext context, Source source, |
| 56 int offset, SearchEngine searchEngine) { | |
| 57 if (context != null) { | |
| 58 if (AnalysisEngine.isDartFileName(source.shortName)) { | |
| 59 return new DartCompletionManager(context, source, offset, searchEngine); | |
| 60 } | |
| 61 } | |
| 62 return new NoOpCompletionManager(source, offset); | |
| 63 } | |
| 60 } | 64 } |
| 61 | 65 |
| 62 /** | 66 /** |
| 63 * Code completion result generated by an [CompletionManager]. | 67 * Code completion result generated by an [CompletionManager]. |
| 64 */ | 68 */ |
| 65 class CompletionResult { | 69 class CompletionResult { |
| 66 | 70 |
| 67 /** | 71 /** |
| 68 * The length of the text to be replaced if the remainder of the identifier | 72 * The length of the text to be replaced if the remainder of the identifier |
| 69 * containing the cursor is to be replaced when the suggestion is applied | 73 * containing the cursor is to be replaced when the suggestion is applied |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 91 final bool last; | 95 final bool last; |
| 92 | 96 |
| 93 CompletionResult(this.replacementOffset, this.replacementLength, | 97 CompletionResult(this.replacementOffset, this.replacementLength, |
| 94 this.suggestions, this.last); | 98 this.suggestions, this.last); |
| 95 } | 99 } |
| 96 | 100 |
| 97 /** | 101 /** |
| 98 * Manages code completion for a given Dart file completion request. | 102 * Manages code completion for a given Dart file completion request. |
| 99 */ | 103 */ |
| 100 class DartCompletionManager extends CompletionManager { | 104 class DartCompletionManager extends CompletionManager { |
| 105 final AnalysisContext context; | |
| 101 final Source source; | 106 final Source source; |
| 102 final int offset; | 107 final int offset; |
| 103 final SearchEngine searchEngine; | 108 final SearchEngine searchEngine; |
| 104 | 109 |
| 105 DartCompletionManager(this.source, this.offset, this.searchEngine); | 110 DartCompletionManager(this.context, this.source, this.offset, |
| 111 this.searchEngine); | |
| 106 | 112 |
| 107 @override | 113 @override |
| 108 void compute() { | 114 void compute() { |
| 109 var computer = new TopLevelComputer(searchEngine); | 115 LibraryElement library = context.computeLibraryElement(source); |
|
scheglov
2014/08/07 02:42:25
Do we want to support the case when source is a pa
danrubel
2014/08/08 20:28:39
Definitely part of the plan. I'm incrementally imp
| |
| 116 CompilationUnit unit = context.resolveCompilationUnit(source, library); | |
| 117 TopLevelComputer computer = new TopLevelComputer(searchEngine, unit); | |
| 110 computer.compute().then((List<CompletionSuggestion> suggestions) { | 118 computer.compute().then((List<CompletionSuggestion> suggestions) { |
| 111 controller.add(new CompletionResult(offset, 0, suggestions, true)); | 119 controller.add(new CompletionResult(offset, 0, suggestions, true)); |
| 112 }); | 120 }); |
| 113 } | 121 } |
| 114 } | 122 } |
| 115 | 123 |
| 116 class NoOpCompletionManager extends CompletionManager { | 124 class NoOpCompletionManager extends CompletionManager { |
| 117 final Source source; | 125 final Source source; |
| 118 final int offset; | 126 final int offset; |
| 119 | 127 |
| 120 NoOpCompletionManager(this.source, this.offset); | 128 NoOpCompletionManager(this.source, this.offset); |
| 121 | 129 |
| 122 @override | 130 @override |
| 123 void compute() { | 131 void compute() { |
| 124 controller.add(new CompletionResult(offset, 0, [], true)); | 132 controller.add(new CompletionResult(offset, 0, [], true)); |
| 125 } | 133 } |
| 126 } | 134 } |
| OLD | NEW |