Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: pkg/analysis_server/lib/src/domain_completion.dart

Issue 723263004: make completion managers responsible for their own caches (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: merge Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/completion_manager.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 domain.completion; 5 library domain.completion;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/src/analysis_server.dart'; 9 import 'package:analysis_server/src/analysis_server.dart';
10 import 'package:analysis_server/src/constants.dart'; 10 import 'package:analysis_server/src/constants.dart';
11 import 'package:analysis_server/src/protocol.dart'; 11 import 'package:analysis_server/src/protocol.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/search/search_engine.dart'; 13 import 'package:analysis_server/src/services/search/search_engine.dart';
14 import 'package:analyzer/src/generated/engine.dart'; 14 import 'package:analyzer/src/generated/engine.dart';
15 import 'package:analyzer/src/generated/source.dart'; 15 import 'package:analyzer/src/generated/source.dart';
16 16
17 export 'package:analysis_server/src/services/completion/completion_manager.dart' 17 export 'package:analysis_server/src/services/completion/completion_manager.dart'
18 show CompletionPerformance, OperationPerformance; 18 show CompletionPerformance, CompletionRequest, OperationPerformance;
19 19
20 /** 20 /**
21 * Instances of the class [CompletionDomainHandler] implement a [RequestHandler] 21 * Instances of the class [CompletionDomainHandler] implement a [RequestHandler]
22 * that handles requests in the search domain. 22 * that handles requests in the search domain.
23 */ 23 */
24 class CompletionDomainHandler implements RequestHandler { 24 class CompletionDomainHandler implements RequestHandler {
25 /** 25 /**
26 * The analysis server that is using this handler to process requests. 26 * The analysis server that is using this handler to process requests.
27 */ 27 */
28 final AnalysisServer server; 28 final AnalysisServer server;
29 29
30 /** 30 /**
31 * The next completion response id. 31 * The next completion response id.
32 */ 32 */
33 int _nextCompletionId = 0; 33 int _nextCompletionId = 0;
34 34
35 /** 35 /**
36 * Cached information from a prior completion operation. 36 * The completion manager for most recent [Source] and [AnalysisContext],
37 * The type of cached information depends upon the completion operation. 37 * or `null` if none.
38 */ 38 */
39 CompletionCache _cache; 39 CompletionManager _manager;
40 40
41 /** 41 /**
42 * The subscription for the cached context's source change stream. 42 * The subscription for the cached context's source change stream.
43 */ 43 */
44 StreamSubscription<SourcesChangedEvent> _sourcesChangedSubscription; 44 StreamSubscription<SourcesChangedEvent> _sourcesChangedSubscription;
45 45
46 /** 46 /**
47 * Code completion peformance for the last completion operation. 47 * Code completion peformance for the last completion operation.
48 */ 48 */
49 CompletionPerformance performance; 49 CompletionPerformance performance;
50 50
51 /** 51 /**
52 * Initialize a new request handler for the given [server]. 52 * Initialize a new request handler for the given [server].
53 */ 53 */
54 CompletionDomainHandler(this.server) { 54 CompletionDomainHandler(this.server) {
55 server.onContextsChanged.listen(contextsChanged); 55 server.onContextsChanged.listen(contextsChanged);
56 } 56 }
57 57
58 /** 58 /**
59 * Return the completion manager for most recent [Source] and [AnalysisContext ],
60 * or `null` if none.
61 */
62 CompletionManager get manager => _manager;
63
64 /**
65 * Return the [CompletionManager] for the given [context] and [source],
66 * creating a new manager or returning an existing manager as necessary.
67 */
68 CompletionManager completionManagerFor(AnalysisContext context,
69 Source source) {
70 if (_manager != null) {
71 if (_manager.context == context && _manager.source == source) {
72 return _manager;
73 }
74 _discardManager();
75 }
76 _manager =
77 createCompletionManager(context, source, server.searchEngine, null);
78 if (context != null) {
79 _sourcesChangedSubscription =
80 context.onSourcesChanged.listen(sourcesChanged);
81 }
82 return _manager;
83 }
84
85 /**
59 * If the context associated with the cache has changed or been removed 86 * If the context associated with the cache has changed or been removed
60 * then discard the cache. 87 * then discard the cache.
61 */ 88 */
62 void contextsChanged(ContextsChangedEvent event) { 89 void contextsChanged(ContextsChangedEvent event) {
63 if (_cache != null) { 90 if (_manager != null) {
64 AnalysisContext context = _cache.context; 91 AnalysisContext context = _manager.context;
65 if (event.changed.contains(context) || event.removed.contains(context)) { 92 if (event.changed.contains(context) || event.removed.contains(context)) {
66 _discardCache(); 93 _discardManager();
67 } 94 }
68 } 95 }
69 } 96 }
70 97
71 CompletionManager createCompletionManager(AnalysisContext context, 98 CompletionManager createCompletionManager(AnalysisContext context,
72 Source source, int offset, SearchEngine searchEngine, CompletionCache cach e, 99 Source source, SearchEngine searchEngine, CompletionCache cache) {
73 CompletionPerformance performance) { 100 return new CompletionManager.create(context, source, searchEngine, cache);
74 return new CompletionManager.create(
75 context,
76 source,
77 offset,
78 searchEngine,
79 cache,
80 performance);
81 } 101 }
82 102
83 @override 103 @override
84 Response handleRequest(Request request) { 104 Response handleRequest(Request request) {
85 try { 105 try {
86 String requestName = request.method; 106 String requestName = request.method;
87 if (requestName == COMPLETION_GET_SUGGESTIONS) { 107 if (requestName == COMPLETION_GET_SUGGESTIONS) {
88 return processRequest(request); 108 return processRequest(request);
89 } 109 }
90 } on RequestFailure catch (exception) { 110 } on RequestFailure catch (exception) {
91 return exception.response; 111 return exception.response;
92 } 112 }
93 return null; 113 return null;
94 } 114 }
95 115
96 /** 116 /**
97 * Process a `completion.getSuggestions` request. 117 * Process a `completion.getSuggestions` request.
98 */ 118 */
99 Response processRequest(Request request) { 119 Response processRequest(Request request) {
100 performance = new CompletionPerformance(); 120 performance = new CompletionPerformance();
101 // extract params 121 // extract params
102 CompletionGetSuggestionsParams params = 122 CompletionGetSuggestionsParams params =
103 new CompletionGetSuggestionsParams.fromRequest(request); 123 new CompletionGetSuggestionsParams.fromRequest(request);
104 // schedule completion analysis 124 // schedule completion analysis
105 String completionId = (_nextCompletionId++).toString(); 125 String completionId = (_nextCompletionId++).toString();
106 CompletionManager manager = createCompletionManager( 126 CompletionManager manager = completionManagerFor(
107 server.getAnalysisContext(params.file), 127 server.getAnalysisContext(params.file),
108 server.getSource(params.file), 128 server.getSource(params.file));
109 params.offset, 129 CompletionRequest completionRequest =
110 server.searchEngine, 130 new CompletionRequest(params.offset, performance);
111 _cache, 131 manager.results(completionRequest).listen((CompletionResult result) {
112 performance);
113 manager.results().listen((CompletionResult result) {
114 sendCompletionNotification( 132 sendCompletionNotification(
115 completionId, 133 completionId,
116 result.replacementOffset, 134 result.replacementOffset,
117 result.replacementLength, 135 result.replacementLength,
118 result.suggestions, 136 result.suggestions,
119 result.last); 137 result.last);
120 if (result.last) { 138 if (result.last) {
121 performance.complete(); 139 performance.complete();
122 CompletionCache newCache = manager.completionCache;
123 if (_cache != newCache) {
124 if (_cache != null) {
125 _discardCache();
126 }
127 _cache = newCache;
128 if (_cache.context != null) {
129 _sourcesChangedSubscription =
130 _cache.context.onSourcesChanged.listen(sourcesChanged);
131 }
132 }
133 } 140 }
134 }); 141 });
135 // initial response without results 142 // initial response without results
136 return new CompletionGetSuggestionsResult( 143 return new CompletionGetSuggestionsResult(
137 completionId).toResponse(request.id); 144 completionId).toResponse(request.id);
138 } 145 }
139 146
140 /** 147 /**
141 * Send completion notification results. 148 * Send completion notification results.
142 */ 149 */
143 void sendCompletionNotification(String completionId, int replacementOffset, 150 void sendCompletionNotification(String completionId, int replacementOffset,
144 int replacementLength, Iterable<CompletionSuggestion> results, bool isLast ) { 151 int replacementLength, Iterable<CompletionSuggestion> results, bool isLast ) {
145 server.sendNotification( 152 server.sendNotification(
146 new CompletionResultsParams( 153 new CompletionResultsParams(
147 completionId, 154 completionId,
148 replacementOffset, 155 replacementOffset,
149 replacementLength, 156 replacementLength,
150 results, 157 results,
151 isLast).toNotification()); 158 isLast).toNotification());
152 } 159 }
153 160
154 /** 161 /**
155 * Discard the cache if a source other than the source referenced by 162 * Discard the cache if a source other than the source referenced by
156 * the cache changes or if any source is added, removed, or deleted. 163 * the cache changes or if any source is added, removed, or deleted.
157 */ 164 */
158 void sourcesChanged(SourcesChangedEvent event) { 165 void sourcesChanged(SourcesChangedEvent event) {
159 166
160 bool shouldDiscardCache(SourcesChangedEvent event) { 167 bool shouldDiscardManager(SourcesChangedEvent event) {
161 if (_cache == null) { 168 if (_manager == null) {
162 return false; 169 return false;
163 } 170 }
164 if (event.wereSourcesAdded || event.wereSourcesRemovedOrDeleted) { 171 if (event.wereSourcesAdded || event.wereSourcesRemovedOrDeleted) {
165 return true; 172 return true;
166 } 173 }
167 var changedSources = event.changedSources; 174 var changedSources = event.changedSources;
168 return changedSources.length > 2 || 175 return changedSources.length > 2 ||
169 (changedSources.length == 1 && !changedSources.contains(_cache.source) ); 176 (changedSources.length == 1 && !changedSources.contains(_manager.sourc e));
170 } 177 }
171 178
172 if (shouldDiscardCache(event)) { 179 if (shouldDiscardManager(event)) {
173 _discardCache(); 180 _discardManager();
174 } 181 }
175 } 182 }
176 183
177 /** 184 /**
178 * Discard the sourcesChanged subscription if any 185 * Discard the sourcesChanged subscription if any
179 */ 186 */
180 void _discardCache() { 187 void _discardManager() {
181 if (_sourcesChangedSubscription != null) { 188 if (_sourcesChangedSubscription != null) {
182 _sourcesChangedSubscription.cancel(); 189 _sourcesChangedSubscription.cancel();
183 _sourcesChangedSubscription = null; 190 _sourcesChangedSubscription = null;
184 } 191 }
185 _cache = null; 192 _manager = null;
186 } 193 }
187 } 194 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/services/completion/completion_manager.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698