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 analysis.server; | 5 library analysis.server; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 import 'dart:core' hide Resource; | 9 import 'dart:core' hide Resource; |
10 import 'dart:math' show max; | 10 import 'dart:math' show max; |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 * A table mapping [AnalysisService]s to the file paths for which these | 176 * A table mapping [AnalysisService]s to the file paths for which these |
177 * notifications should be sent. | 177 * notifications should be sent. |
178 */ | 178 */ |
179 Map<AnalysisService, Set<String>> analysisServices = | 179 Map<AnalysisService, Set<String>> analysisServices = |
180 new HashMap<AnalysisService, Set<String>>(); | 180 new HashMap<AnalysisService, Set<String>>(); |
181 | 181 |
182 /** | 182 /** |
183 * A table mapping [AnalysisContext]s to the completers that should be | 183 * A table mapping [AnalysisContext]s to the completers that should be |
184 * completed when analysis of this context is finished. | 184 * completed when analysis of this context is finished. |
185 */ | 185 */ |
186 Map<AnalysisContext, Completer<AnalysisDoneReason>> contextAnalysisDoneComplet
ers = | 186 Map<AnalysisContext, |
| 187 Completer<AnalysisDoneReason>> contextAnalysisDoneCompleters = |
187 new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>(); | 188 new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>(); |
188 | 189 |
189 /** | 190 /** |
190 * Performance information before initial analysis is complete. | 191 * Performance information before initial analysis is complete. |
191 */ | 192 */ |
192 ServerPerformance performanceDuringStartup = new ServerPerformance(); | 193 ServerPerformance performanceDuringStartup = new ServerPerformance(); |
193 | 194 |
194 /** | 195 /** |
195 * Performance information after initial analysis is complete | 196 * Performance information after initial analysis is complete |
196 * or `null` if the initial analysis is not yet complete | 197 * or `null` if the initial analysis is not yet complete |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 * responses to the given [channel]. | 285 * responses to the given [channel]. |
285 * | 286 * |
286 * If a [contextManager] is provided, then the [packageResolverProvider] will | 287 * If a [contextManager] is provided, then the [packageResolverProvider] will |
287 * be ignored. | 288 * be ignored. |
288 * | 289 * |
289 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are | 290 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are |
290 * propagated up the call stack. The default is true to allow analysis | 291 * propagated up the call stack. The default is true to allow analysis |
291 * exceptions to show up in unit tests, but it should be set to false when | 292 * exceptions to show up in unit tests, but it should be set to false when |
292 * running a full analysis server. | 293 * running a full analysis server. |
293 */ | 294 */ |
294 AnalysisServer(this.channel, this.resourceProvider, | 295 AnalysisServer( |
295 PubPackageMapProvider packageMapProvider, Index _index, this.serverPlugin, | 296 this.channel, |
296 this.options, this.defaultSdk, this.instrumentationService, | 297 this.resourceProvider, |
| 298 PubPackageMapProvider packageMapProvider, |
| 299 Index _index, |
| 300 this.serverPlugin, |
| 301 this.options, |
| 302 this.defaultSdk, |
| 303 this.instrumentationService, |
297 {ContextManager contextManager: null, | 304 {ContextManager contextManager: null, |
298 ResolverProvider packageResolverProvider: null, | 305 ResolverProvider packageResolverProvider: null, |
299 this.rethrowExceptions: true}) | 306 this.rethrowExceptions: true}) |
300 : index = _index, | 307 : index = _index, |
301 searchEngine = _index != null ? createSearchEngine(_index) : null { | 308 searchEngine = _index != null ? createSearchEngine(_index) : null { |
302 _performance = performanceDuringStartup; | 309 _performance = performanceDuringStartup; |
303 operationQueue = new ServerOperationQueue(); | 310 operationQueue = new ServerOperationQueue(); |
304 if (contextManager == null) { | 311 if (contextManager == null) { |
305 contextManager = new ContextManagerImpl(resourceProvider, | 312 contextManager = new ContextManagerImpl(resourceProvider, |
306 packageResolverProvider, packageMapProvider, instrumentationService); | 313 packageResolverProvider, packageMapProvider, instrumentationService); |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 * context and `null` [Source] is returned. | 490 * context and `null` [Source] is returned. |
484 * | 491 * |
485 * Does not return `null`. | 492 * Does not return `null`. |
486 */ | 493 */ |
487 ContextSourcePair getContextSourcePair(String path) { | 494 ContextSourcePair getContextSourcePair(String path) { |
488 // try SDK | 495 // try SDK |
489 { | 496 { |
490 Uri uri = resourceProvider.pathContext.toUri(path); | 497 Uri uri = resourceProvider.pathContext.toUri(path); |
491 Source sdkSource = defaultSdk.fromFileUri(uri); | 498 Source sdkSource = defaultSdk.fromFileUri(uri); |
492 if (sdkSource != null) { | 499 if (sdkSource != null) { |
493 AnalysisContext anyContext = folderMap.values.first; | 500 AnalysisContext sdkContext = defaultSdk.context; |
494 return new ContextSourcePair(anyContext, sdkSource); | 501 return new ContextSourcePair(sdkContext, sdkSource); |
495 } | 502 } |
496 } | 503 } |
497 // try to find the deep-most containing context | 504 // try to find the deep-most containing context |
498 Resource resource = resourceProvider.getResource(path); | 505 Resource resource = resourceProvider.getResource(path); |
499 if (resource is! File) { | 506 if (resource is! File) { |
500 return new ContextSourcePair(null, null); | 507 return new ContextSourcePair(null, null); |
501 } | 508 } |
502 File file = resource; | 509 File file = resource; |
503 { | 510 { |
504 AnalysisContext containingContext = getContainingContext(path); | 511 AnalysisContext containingContext = getContainingContext(path); |
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 preferredContext = context; | 1039 preferredContext = context; |
1033 source = | 1040 source = |
1034 ContextManagerImpl.createSourceInContext(context, resource); | 1041 ContextManagerImpl.createSourceInContext(context, resource); |
1035 break; | 1042 break; |
1036 } | 1043 } |
1037 } | 1044 } |
1038 } | 1045 } |
1039 } | 1046 } |
1040 // Fill the source map. | 1047 // Fill the source map. |
1041 bool contextFound = false; | 1048 bool contextFound = false; |
| 1049 if (preferredContext != null) { |
| 1050 sourceMap.putIfAbsent(preferredContext, () => <Source>[]).add(source); |
| 1051 contextFound = true; |
| 1052 } |
1042 for (AnalysisContext context in folderMap.values) { | 1053 for (AnalysisContext context in folderMap.values) { |
1043 if (context == preferredContext || | 1054 if (context.getKindOf(source) != SourceKind.UNKNOWN) { |
1044 context.getKindOf(source) != SourceKind.UNKNOWN) { | |
1045 sourceMap.putIfAbsent(context, () => <Source>[]).add(source); | 1055 sourceMap.putIfAbsent(context, () => <Source>[]).add(source); |
1046 contextFound = true; | 1056 contextFound = true; |
1047 } | 1057 } |
1048 } | 1058 } |
1049 if (firstSource == null) { | 1059 if (firstSource == null) { |
1050 firstSource = source; | 1060 firstSource = source; |
1051 } | 1061 } |
1052 if (!contextFound) { | 1062 if (!contextFound) { |
1053 unanalyzed.add(file); | 1063 unanalyzed.add(file); |
1054 } | 1064 } |
1055 }); | 1065 }); |
1056 if (unanalyzed.isNotEmpty) { | 1066 if (unanalyzed.isNotEmpty) { |
1057 StringBuffer buffer = new StringBuffer(); | 1067 StringBuffer buffer = new StringBuffer(); |
1058 buffer.writeAll(unanalyzed, ', '); | 1068 buffer.writeAll(unanalyzed, ', '); |
1059 throw new RequestFailure( | 1069 throw new RequestFailure( |
1060 new Response.unanalyzedPriorityFiles(requestId, buffer.toString())); | 1070 new Response.unanalyzedPriorityFiles(requestId, buffer.toString())); |
1061 } | 1071 } |
1062 folderMap.forEach((Folder folder, AnalysisContext context) { | 1072 sourceMap.forEach((context, List<Source> sourceList) { |
1063 List<Source> sourceList = sourceMap[context]; | |
1064 if (sourceList == null) { | |
1065 sourceList = Source.EMPTY_LIST; | |
1066 } | |
1067 context.analysisPriorityOrder = sourceList; | 1073 context.analysisPriorityOrder = sourceList; |
1068 // Schedule the context for analysis so that it has the opportunity to | 1074 // Schedule the context for analysis so that it has the opportunity to |
1069 // cache the AST's for the priority sources as soon as possible. | 1075 // cache the AST's for the priority sources as soon as possible. |
1070 schedulePerformAnalysisOperation(context); | 1076 schedulePerformAnalysisOperation(context); |
1071 }); | 1077 }); |
1072 operationQueue.reschedule(); | 1078 operationQueue.reschedule(); |
1073 _onPriorityChangeController.add(new PriorityChangeEvent(firstSource)); | 1079 _onPriorityChangeController.add(new PriorityChangeEvent(firstSource)); |
1074 } | 1080 } |
1075 | 1081 |
1076 /** | 1082 /** |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 resolvers.add(resourceResolver); | 1461 resolvers.add(resourceResolver); |
1456 return new SourceFactory(resolvers, disposition.packages); | 1462 return new SourceFactory(resolvers, disposition.packages); |
1457 } | 1463 } |
1458 } | 1464 } |
1459 | 1465 |
1460 /** | 1466 /** |
1461 * A class used by [AnalysisServer] to record performance information | 1467 * A class used by [AnalysisServer] to record performance information |
1462 * such as request latency. | 1468 * such as request latency. |
1463 */ | 1469 */ |
1464 class ServerPerformance { | 1470 class ServerPerformance { |
1465 | |
1466 /** | 1471 /** |
1467 * The creation time and the time when performance information | 1472 * The creation time and the time when performance information |
1468 * started to be recorded here. | 1473 * started to be recorded here. |
1469 */ | 1474 */ |
1470 int startTime = new DateTime.now().millisecondsSinceEpoch; | 1475 int startTime = new DateTime.now().millisecondsSinceEpoch; |
1471 | 1476 |
1472 /** | 1477 /** |
1473 * The number of requests. | 1478 * The number of requests. |
1474 */ | 1479 */ |
1475 int requestCount = 0; | 1480 int requestCount = 0; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 /** | 1557 /** |
1553 * The [PerformanceTag] for time spent in server request handlers. | 1558 * The [PerformanceTag] for time spent in server request handlers. |
1554 */ | 1559 */ |
1555 static PerformanceTag serverRequests = new PerformanceTag('serverRequests'); | 1560 static PerformanceTag serverRequests = new PerformanceTag('serverRequests'); |
1556 | 1561 |
1557 /** | 1562 /** |
1558 * The [PerformanceTag] for time spent in split store microtasks. | 1563 * The [PerformanceTag] for time spent in split store microtasks. |
1559 */ | 1564 */ |
1560 static PerformanceTag splitStore = new PerformanceTag('splitStore'); | 1565 static PerformanceTag splitStore = new PerformanceTag('splitStore'); |
1561 } | 1566 } |
OLD | NEW |