@@ -88,26 +88,36 @@ class CompletionHandler
8888 final offset =
8989 await lineInfo.mapResult ((lineInfo) => toOffset (lineInfo, pos));
9090
91- return offset.mapResult ((offset) {
92- if (unit.isError) {
93- return _getItemsFromPluginsOnly (
94- completionCapabilities,
95- clientSupportedCompletionKinds,
96- lineInfo.result,
97- path.result,
98- offset,
99- token,
100- );
101- } else {
102- return _getItems (
103- completionCapabilities,
104- clientSupportedCompletionKinds,
105- includeSuggestionSets,
106- unit.result,
107- offset,
108- token,
109- );
110- }
91+ return offset.mapResult ((offset) async {
92+ // For server results we need a valid unit, but if we don't have one
93+ // we shouldn't consider this an error when merging with plugin results.
94+ final serverResultsFuture = unit.isError
95+ ? Future .value (success (const < CompletionItem > []))
96+ : _getServerItems (
97+ completionCapabilities,
98+ clientSupportedCompletionKinds,
99+ includeSuggestionSets,
100+ unit.result,
101+ offset,
102+ token,
103+ );
104+
105+ final pluginResultsFuture = _getPluginResults (completionCapabilities,
106+ clientSupportedCompletionKinds, lineInfo.result, path.result, offset);
107+
108+ // Await both server + plugin results together to allow async/IO to
109+ // overlap.
110+ final serverAndPluginResults =
111+ await Future .wait ([serverResultsFuture, pluginResultsFuture]);
112+ final serverResults = serverAndPluginResults[0 ];
113+ final pluginResults = serverAndPluginResults[1 ];
114+
115+ if (serverResults.isError) return serverResults;
116+ if (pluginResults.isError) return pluginResults;
117+
118+ return success (
119+ serverResults.result.followedBy (pluginResults.result).toList (),
120+ );
111121 });
112122 }
113123
@@ -142,7 +152,29 @@ class CompletionHandler
142152 String _createImportedSymbolKey (String name, Uri declaringUri) =>
143153 '$name /$declaringUri ' ;
144154
145- Future <ErrorOr <List <CompletionItem >>> _getItems (
155+ Future <ErrorOr <List <CompletionItem >>> _getPluginResults (
156+ TextDocumentClientCapabilitiesCompletion completionCapabilities,
157+ HashSet <CompletionItemKind > clientSupportedCompletionKinds,
158+ LineInfo lineInfo,
159+ String path,
160+ int offset,
161+ ) async {
162+ final requestParams = plugin.CompletionGetSuggestionsParams (path, offset);
163+ final pluginResponses = await requestFromPlugins (path, requestParams);
164+
165+ final pluginResults = pluginResponses
166+ .map ((e) => plugin.CompletionGetSuggestionsResult .fromResponse (e))
167+ .toList ();
168+
169+ return success (_pluginResultsToItems (
170+ completionCapabilities,
171+ clientSupportedCompletionKinds,
172+ lineInfo,
173+ pluginResults,
174+ ).toList ());
175+ }
176+
177+ Future <ErrorOr <List <CompletionItem >>> _getServerItems (
146178 TextDocumentClientCapabilitiesCompletion completionCapabilities,
147179 HashSet <CompletionItemKind > clientSupportedCompletionKinds,
148180 bool includeSuggestionSets,
@@ -176,12 +208,8 @@ class CompletionHandler
176208 includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
177209 );
178210
179- final suggestions = await Future .wait ([
180- contributor.computeSuggestions (completionRequest),
181- _getPluginSuggestions (unit.path, offset),
182- ]);
183- final serverSuggestions = suggestions[0 ];
184- final pluginSuggestions = suggestions[1 ];
211+ final serverSuggestions =
212+ await contributor.computeSuggestions (completionRequest);
185213
186214 if (token.isCancellationRequested) {
187215 return cancelled ();
@@ -198,14 +226,6 @@ class CompletionHandler
198226 completionRequest.replacementLength,
199227 ),
200228 )
201- .followedBy (
202- _pluginResultsToItems (
203- completionCapabilities,
204- clientSupportedCompletionKinds,
205- unit.lineInfo,
206- pluginSuggestions,
207- ),
208- )
209229 .toList ();
210230
211231 // Now compute items in suggestion sets.
@@ -303,40 +323,6 @@ class CompletionHandler
303323 }
304324 }
305325
306- Future <ErrorOr <List <CompletionItem >>> _getItemsFromPluginsOnly (
307- TextDocumentClientCapabilitiesCompletion completionCapabilities,
308- HashSet <CompletionItemKind > clientSupportedCompletionKinds,
309- LineInfo lineInfo,
310- String path,
311- int offset,
312- CancellationToken token,
313- ) async {
314- final pluginResults = await _getPluginSuggestions (path, offset);
315-
316- if (token.isCancellationRequested) {
317- return cancelled ();
318- }
319-
320- return success (_pluginResultsToItems (
321- completionCapabilities,
322- clientSupportedCompletionKinds,
323- lineInfo,
324- pluginResults,
325- ).toList ());
326- }
327-
328- Future <List <plugin.CompletionGetSuggestionsResult >> _getPluginSuggestions (
329- String path,
330- int offset,
331- ) async {
332- final requestParams = plugin.CompletionGetSuggestionsParams (path, offset);
333- final responses = await requestFromPlugins (path, requestParams);
334-
335- return responses
336- .map ((e) => plugin.CompletionGetSuggestionsResult .fromResponse (e))
337- .toList ();
338- }
339-
340326 Iterable <CompletionItem > _pluginResultsToItems (
341327 TextDocumentClientCapabilitiesCompletion completionCapabilities,
342328 HashSet <CompletionItemKind > clientSupportedCompletionKinds,
0 commit comments