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

Side by Side Diff: pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart

Issue 1536083002: completion performance measurement for local status page (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: rebase Created 5 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
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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.manager; 5 library services.completion.dart.manager;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/plugin/protocol/protocol.dart'; 9 import 'package:analysis_server/plugin/protocol/protocol.dart';
10 import 'package:analysis_server/src/provisional/completion/completion_core.dart' 10 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
11 show CompletionContributor, CompletionRequest; 11 show CompletionContributor, CompletionRequest;
12 import 'package:analysis_server/src/provisional/completion/dart/completion_dart. dart'; 12 import 'package:analysis_server/src/provisional/completion/dart/completion_dart. dart';
13 import 'package:analysis_server/src/provisional/completion/dart/completion_plugi n.dart'; 13 import 'package:analysis_server/src/provisional/completion/dart/completion_plugi n.dart';
14 import 'package:analysis_server/src/provisional/completion/dart/completion_targe t.dart'; 14 import 'package:analysis_server/src/provisional/completion/dart/completion_targe t.dart';
15 import 'package:analysis_server/src/services/completion/completion_core.dart'; 15 import 'package:analysis_server/src/services/completion/completion_core.dart';
16 import 'package:analysis_server/src/services/completion/completion_performance.d art';
16 import 'package:analysis_server/src/services/completion/dart/common_usage_sorter .dart'; 17 import 'package:analysis_server/src/services/completion/dart/common_usage_sorter .dart';
17 import 'package:analysis_server/src/services/completion/dart/contribution_sorter .dart'; 18 import 'package:analysis_server/src/services/completion/dart/contribution_sorter .dart';
18 import 'package:analysis_server/src/services/completion/dart/optype.dart'; 19 import 'package:analysis_server/src/services/completion/dart/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/dart/element/element.dart'; 21 import 'package:analyzer/dart/element/element.dart';
21 import 'package:analyzer/dart/element/type.dart'; 22 import 'package:analyzer/dart/element/type.dart';
22 import 'package:analyzer/file_system/file_system.dart'; 23 import 'package:analyzer/file_system/file_system.dart';
23 import 'package:analyzer/src/context/context.dart' 24 import 'package:analyzer/src/context/context.dart'
24 show AnalysisFutureHelper, AnalysisContextImpl; 25 show AnalysisFutureHelper, AnalysisContextImpl;
25 import 'package:analyzer/src/generated/ast.dart'; 26 import 'package:analyzer/src/generated/ast.dart';
(...skipping 14 matching lines...) Expand all
40 */ 41 */
41 static DartContributionSorter contributionSorter = new CommonUsageSorter(); 42 static DartContributionSorter contributionSorter = new CommonUsageSorter();
42 43
43 @override 44 @override
44 Future<List<CompletionSuggestion>> computeSuggestions( 45 Future<List<CompletionSuggestion>> computeSuggestions(
45 CompletionRequest request) async { 46 CompletionRequest request) async {
46 if (!AnalysisEngine.isDartFileName(request.source.shortName)) { 47 if (!AnalysisEngine.isDartFileName(request.source.shortName)) {
47 return EMPTY_LIST; 48 return EMPTY_LIST;
48 } 49 }
49 50
51 CompletionPerformance performance =
52 (request as CompletionRequestImpl).performance;
53 const BUILD_REQUEST_TAG = 'build DartCompletionRequestImpl';
54 performance.logStartTime(BUILD_REQUEST_TAG);
50 DartCompletionRequestImpl dartRequest = 55 DartCompletionRequestImpl dartRequest =
51 await DartCompletionRequestImpl.from(request); 56 await DartCompletionRequestImpl.from(request);
57 performance.logElapseTime(BUILD_REQUEST_TAG);
58
59 // Don't suggest in comments.
60 if (dartRequest.target.isCommentText) {
61 return EMPTY_LIST;
62 }
63
52 ReplacementRange range = 64 ReplacementRange range =
53 new ReplacementRange.compute(dartRequest.offset, dartRequest.target); 65 new ReplacementRange.compute(dartRequest.offset, dartRequest.target);
54 (request as CompletionRequestImpl) 66 (request as CompletionRequestImpl)
55 ..replacementOffset = range.offset 67 ..replacementOffset = range.offset
56 ..replacementLength = range.length; 68 ..replacementLength = range.length;
57 69
58 // Don't suggest in comments.
59 if (dartRequest.target.isCommentText) {
60 return EMPTY_LIST;
61 }
62
63 // Request Dart specific completions from each contributor 70 // Request Dart specific completions from each contributor
64 Map<String, CompletionSuggestion> suggestionMap = 71 Map<String, CompletionSuggestion> suggestionMap =
65 <String, CompletionSuggestion>{}; 72 <String, CompletionSuggestion>{};
66 for (DartCompletionContributor contributor 73 for (DartCompletionContributor contributor
67 in dartCompletionPlugin.contributors) { 74 in dartCompletionPlugin.contributors) {
75 String contributorTag =
76 'DartCompletionManager - ${contributor.runtimeType}';
77 performance.logStartTime(contributorTag);
68 List<CompletionSuggestion> contributorSuggestions = 78 List<CompletionSuggestion> contributorSuggestions =
69 await contributor.computeSuggestions(dartRequest); 79 await contributor.computeSuggestions(dartRequest);
80 performance.logElapseTime(contributorTag);
70 81
71 for (CompletionSuggestion newSuggestion in contributorSuggestions) { 82 for (CompletionSuggestion newSuggestion in contributorSuggestions) {
72 var oldSuggestion = suggestionMap.putIfAbsent( 83 var oldSuggestion = suggestionMap.putIfAbsent(
73 newSuggestion.completion, () => newSuggestion); 84 newSuggestion.completion, () => newSuggestion);
74 if (newSuggestion != oldSuggestion && 85 if (newSuggestion != oldSuggestion &&
75 newSuggestion.relevance > oldSuggestion.relevance) { 86 newSuggestion.relevance > oldSuggestion.relevance) {
76 suggestionMap[newSuggestion.completion] = newSuggestion; 87 suggestionMap[newSuggestion.completion] = newSuggestion;
77 } 88 }
78 } 89 }
79 } 90 }
80 91
81 // Adjust suggestion relevance before returning 92 // Adjust suggestion relevance before returning
82 List<CompletionSuggestion> suggestions = suggestionMap.values.toList(); 93 List<CompletionSuggestion> suggestions = suggestionMap.values.toList();
94 const SORT_TAG = 'DartCompletionManager - sort';
95 performance.logStartTime(SORT_TAG);
83 await contributionSorter.sort(dartRequest, suggestions); 96 await contributionSorter.sort(dartRequest, suggestions);
97 performance.logElapseTime(SORT_TAG);
84 return suggestions; 98 return suggestions;
85 } 99 }
86 } 100 }
87 101
88 /** 102 /**
89 * The information about a requested list of completions within a Dart file. 103 * The information about a requested list of completions within a Dart file.
90 */ 104 */
91 class DartCompletionRequestImpl implements DartCompletionRequest { 105 class DartCompletionRequestImpl implements DartCompletionRequest {
92 @override 106 @override
93 final AnalysisContext context; 107 final AnalysisContext context;
(...skipping 24 matching lines...) Expand all
118 */ 132 */
119 LibraryElement _coreLib; 133 LibraryElement _coreLib;
120 134
121 /** 135 /**
122 * The [DartType] for Object in dart:core 136 * The [DartType] for Object in dart:core
123 */ 137 */
124 InterfaceType _objectType; 138 InterfaceType _objectType;
125 139
126 OpType _opType; 140 OpType _opType;
127 141
142 final CompletionPerformance performance;
143
128 DartCompletionRequestImpl._( 144 DartCompletionRequestImpl._(
129 this.context, 145 this.context,
130 this.resourceProvider, 146 this.resourceProvider,
131 this.searchEngine, 147 this.searchEngine,
132 this.librarySource, 148 this.librarySource,
133 this.source, 149 this.source,
134 this.offset, 150 this.offset,
135 CompilationUnit unit) { 151 CompilationUnit unit,
152 this.performance) {
136 _updateTargets(unit); 153 _updateTargets(unit);
137 } 154 }
138 155
139 @override 156 @override
140 LibraryElement get coreLib { 157 LibraryElement get coreLib {
141 if (_coreLib == null) { 158 if (_coreLib == null) {
142 Source coreUri = context.sourceFactory.forUri('dart:core'); 159 Source coreUri = context.sourceFactory.forUri('dart:core');
143 _coreLib = context.computeLibraryElement(coreUri); 160 _coreLib = context.computeLibraryElement(coreUri);
144 } 161 }
145 return _coreLib; 162 return _coreLib;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 } 201 }
185 202
186 // For internal use only 203 // For internal use only
187 @override 204 @override
188 Future<List<Directive>> resolveDirectives() async { 205 Future<List<Directive>> resolveDirectives() async {
189 CompilationUnit libUnit; 206 CompilationUnit libUnit;
190 if (librarySource == source) { 207 if (librarySource == source) {
191 libUnit = target.unit; 208 libUnit = target.unit;
192 } else if (librarySource != null) { 209 } else if (librarySource != null) {
193 // TODO(danrubel) only resolve the directives 210 // TODO(danrubel) only resolve the directives
211 const RESOLVE_DIRECTIVES_TAG = 'resolve directives';
212 performance.logStartTime(RESOLVE_DIRECTIVES_TAG);
194 libUnit = await new AnalysisFutureHelper<CompilationUnit>( 213 libUnit = await new AnalysisFutureHelper<CompilationUnit>(
195 context, 214 context,
196 new LibrarySpecificUnit(librarySource, librarySource), 215 new LibrarySpecificUnit(librarySource, librarySource),
197 RESOLVED_UNIT3) 216 RESOLVED_UNIT3)
198 .computeAsync(); 217 .computeAsync();
218 performance.logElapseTime(RESOLVE_DIRECTIVES_TAG);
199 } 219 }
200 return libUnit?.directives; 220 return libUnit?.directives;
201 } 221 }
202 222
203 @override 223 @override
204 Future resolveExpression(Expression expression) async { 224 Future resolveExpression(Expression expression) async {
205 // Return immediately if the expression has already been resolved 225 // Return immediately if the expression has already been resolved
206 if (expression.propagatedType != null) { 226 if (expression.propagatedType != null) {
207 return; 227 return;
208 } 228 }
209 229
210 // Gracefully degrade if librarySource cannot be determined 230 // Gracefully degrade if librarySource cannot be determined
211 if (librarySource == null) { 231 if (librarySource == null) {
212 return; 232 return;
213 } 233 }
214 234
215 // Resolve declarations in the target unit 235 // Resolve declarations in the target unit
216 // TODO(danrubel) resolve the expression or containing method 236 // TODO(danrubel) resolve the expression or containing method
217 // rather than the entire complilation unit 237 // rather than the entire complilation unit
238 const RESOLVE_EXPRESSION_TAG = 'resolve expression';
239 performance.logStartTime(RESOLVE_EXPRESSION_TAG);
218 CompilationUnit resolvedUnit = 240 CompilationUnit resolvedUnit =
219 await new AnalysisFutureHelper<CompilationUnit>(context, 241 await new AnalysisFutureHelper<CompilationUnit>(context,
220 new LibrarySpecificUnit(librarySource, source), RESOLVED_UNIT) 242 new LibrarySpecificUnit(librarySource, source), RESOLVED_UNIT)
221 .computeAsync(); 243 .computeAsync();
244 performance.logElapseTime(RESOLVE_EXPRESSION_TAG);
222 245
223 // TODO(danrubel) determine if the underlying source has been modified 246 // TODO(danrubel) determine if the underlying source has been modified
224 // in a way that invalidates the completion request 247 // in a way that invalidates the completion request
225 // and return null 248 // and return null
226 249
227 // Gracefully degrade if unit cannot be resolved 250 // Gracefully degrade if unit cannot be resolved
228 if (resolvedUnit == null) { 251 if (resolvedUnit == null) {
229 return; 252 return;
230 } 253 }
231 254
(...skipping 28 matching lines...) Expand all
260 dotTarget = node.prefix; 283 dotTarget = node.prefix;
261 } 284 }
262 } 285 }
263 } 286 }
264 287
265 /** 288 /**
266 * Return a [Future] that completes with a newly created completion request 289 * Return a [Future] that completes with a newly created completion request
267 * based on the given [request]. 290 * based on the given [request].
268 */ 291 */
269 static Future<DartCompletionRequest> from(CompletionRequest request) async { 292 static Future<DartCompletionRequest> from(CompletionRequest request) async {
293 CompletionPerformance performance =
294 (request as CompletionRequestImpl).performance;
295 const BUILD_REQUEST_TAG = 'build DartCompletionRequest';
296 performance.logStartTime(BUILD_REQUEST_TAG);
297
270 Source source = request.source; 298 Source source = request.source;
271 AnalysisContext context = request.context; 299 AnalysisContext context = request.context;
300
301 const PARSE_TAG = 'parse unit';
302 performance.logStartTime(PARSE_TAG);
272 CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT); 303 CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT);
304 performance.logElapseTime(PARSE_TAG);
273 305
274 Source libSource; 306 Source libSource;
275 if (unit.directives.any((d) => d is PartOfDirective)) { 307 if (unit.directives.any((d) => d is PartOfDirective)) {
276 List<Source> libraries = context.getLibrariesContaining(source); 308 List<Source> libraries = context.getLibrariesContaining(source);
277 if (libraries.isNotEmpty) { 309 if (libraries.isNotEmpty) {
278 libSource = libraries[0]; 310 libSource = libraries[0];
279 } 311 }
280 } else { 312 } else {
281 libSource = source; 313 libSource = source;
282 } 314 }
283 315
284 // Most (all?) contributors need declarations in scope to be resolved 316 // Most (all?) contributors need declarations in scope to be resolved
285 if (libSource != null) { 317 if (libSource != null) {
318 const RESOLVE_DECLARATIONS_TAG = 'resolve declarations';
319 performance.logStartTime(RESOLVE_DECLARATIONS_TAG);
286 unit = await new AnalysisFutureHelper<CompilationUnit>(context, 320 unit = await new AnalysisFutureHelper<CompilationUnit>(context,
287 new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3) 321 new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3)
288 .computeAsync(); 322 .computeAsync();
323 performance.logElapseTime(RESOLVE_DECLARATIONS_TAG);
289 } 324 }
290 325
291 DartCompletionRequestImpl dartRequest = new DartCompletionRequestImpl._( 326 DartCompletionRequestImpl dartRequest = new DartCompletionRequestImpl._(
292 request.context, 327 request.context,
293 request.resourceProvider, 328 request.resourceProvider,
294 request.searchEngine, 329 request.searchEngine,
295 libSource, 330 libSource,
296 request.source, 331 request.source,
297 request.offset, 332 request.offset,
298 unit); 333 unit,
334 performance);
299 335
300 // Resolve the expression in which the completion occurs 336 // Resolve the expression in which the completion occurs
301 // to properly determine if identifiers should be suggested 337 // to properly determine if identifiers should be suggested
302 // rather than invocations. 338 // rather than invocations.
303 if (dartRequest.target.maybeFunctionalArgument()) { 339 if (dartRequest.target.maybeFunctionalArgument()) {
304 AstNode node = dartRequest.target.containingNode.parent; 340 AstNode node = dartRequest.target.containingNode.parent;
305 if (node is Expression) { 341 if (node is Expression) {
342 const FUNCTIONAL_ARG_TAG = 'resolve expression for isFunctionalArg';
343 performance.logStartTime(FUNCTIONAL_ARG_TAG);
306 await dartRequest.resolveExpression(node); 344 await dartRequest.resolveExpression(node);
345 performance.logElapseTime(FUNCTIONAL_ARG_TAG);
307 } 346 }
308 } 347 }
309 348
349 performance.logElapseTime(BUILD_REQUEST_TAG);
310 return dartRequest; 350 return dartRequest;
311 } 351 }
312 } 352 }
313 353
314 /** 354 /**
315 * Utility class for computing the code completion replacement range 355 * Utility class for computing the code completion replacement range
316 */ 356 */
317 class ReplacementRange { 357 class ReplacementRange {
318 int offset; 358 int offset;
319 int length; 359 int length;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 // Replacement range for import URI 400 // Replacement range for import URI
361 return new ReplacementRange(start, end - start); 401 return new ReplacementRange(start, end - start);
362 } 402 }
363 } 403 }
364 } 404 }
365 } 405 }
366 } 406 }
367 return new ReplacementRange(requestOffset, 0); 407 return new ReplacementRange(requestOffset, 0);
368 } 408 }
369 } 409 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698