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 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 * The [SearchEngine] for this server, may be `null` if indexing is disabled. | 101 * The [SearchEngine] for this server, may be `null` if indexing is disabled. |
| 102 */ | 102 */ |
| 103 final SearchEngine searchEngine; | 103 final SearchEngine searchEngine; |
| 104 | 104 |
| 105 /** | 105 /** |
| 106 * The plugin associated with this analysis server. | 106 * The plugin associated with this analysis server. |
| 107 */ | 107 */ |
| 108 final ServerPlugin serverPlugin; | 108 final ServerPlugin serverPlugin; |
| 109 | 109 |
| 110 /** | 110 /** |
| 111 * [ContextManager] which handles the mapping from analysis roots | 111 * The [ContextManager] that handles the mapping from analysis roots to |
| 112 * to context directories. | 112 * context directories. |
| 113 */ | 113 */ |
| 114 ServerContextManager contextDirectoryManager; | 114 ServerContextManager contextManager; |
| 115 | 115 |
| 116 /** | 116 /** |
| 117 * A flag indicating whether the server is running. When false, contexts | 117 * A flag indicating whether the server is running. When false, contexts |
| 118 * will no longer be added to [contextWorkQueue], and [performOperation] will | 118 * will no longer be added to [contextWorkQueue], and [performOperation] will |
| 119 * discard any tasks it finds on [contextWorkQueue]. | 119 * discard any tasks it finds on [contextWorkQueue]. |
| 120 */ | 120 */ |
| 121 bool running; | 121 bool running; |
| 122 | 122 |
| 123 /** | 123 /** |
| 124 * A flag indicating the value of the 'analyzing' parameter sent in the last | 124 * A flag indicating the value of the 'analyzing' parameter sent in the last |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 247 | 247 |
| 248 /** | 248 /** |
| 249 * The plugins that are defined outside the analysis_server package. | 249 * The plugins that are defined outside the analysis_server package. |
| 250 */ | 250 */ |
| 251 List<Plugin> userDefinedPlugins; | 251 List<Plugin> userDefinedPlugins; |
| 252 | 252 |
| 253 /** | 253 /** |
| 254 * Initialize a newly created server to receive requests from and send | 254 * Initialize a newly created server to receive requests from and send |
| 255 * responses to the given [channel]. | 255 * responses to the given [channel]. |
| 256 * | 256 * |
| 257 * If a [contextManager] is provided, then the [packageResolverProvider] will | |
| 258 * be ignored. | |
| 259 * | |
| 257 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are | 260 * If [rethrowExceptions] is true, then any exceptions thrown by analysis are |
| 258 * propagated up the call stack. The default is true to allow analysis | 261 * propagated up the call stack. The default is true to allow analysis |
| 259 * exceptions to show up in unit tests, but it should be set to false when | 262 * exceptions to show up in unit tests, but it should be set to false when |
| 260 * running a full analysis server. | 263 * running a full analysis server. |
| 261 */ | 264 */ |
| 262 AnalysisServer(this.channel, this.resourceProvider, | 265 AnalysisServer(this.channel, this.resourceProvider, |
| 263 OptimizingPubPackageMapProvider packageMapProvider, Index _index, | 266 OptimizingPubPackageMapProvider packageMapProvider, Index _index, |
| 264 this.serverPlugin, AnalysisServerOptions analysisServerOptions, | 267 this.serverPlugin, AnalysisServerOptions analysisServerOptions, |
| 265 this.defaultSdk, this.instrumentationService, | 268 this.defaultSdk, this.instrumentationService, |
| 266 {ResolverProvider packageResolverProvider: null, | 269 {ContextManager contextManager: null, |
| 270 ResolverProvider packageResolverProvider: null, | |
| 267 this.rethrowExceptions: true}) | 271 this.rethrowExceptions: true}) |
| 268 : index = _index, | 272 : index = _index, |
| 269 searchEngine = _index != null ? createSearchEngine(_index) : null { | 273 searchEngine = _index != null ? createSearchEngine(_index) : null { |
| 270 _performance = performanceDuringStartup; | 274 _performance = performanceDuringStartup; |
| 271 operationQueue = new ServerOperationQueue(); | 275 operationQueue = new ServerOperationQueue(); |
| 272 contextDirectoryManager = new ServerContextManager(this, resourceProvider, | 276 if (contextManager == null) { |
| 273 packageResolverProvider, packageMapProvider, instrumentationService); | 277 contextManager = new ServerContextManager(this, resourceProvider, |
| 274 contextDirectoryManager.defaultOptions.incremental = true; | 278 packageResolverProvider, packageMapProvider, instrumentationService); |
| 275 contextDirectoryManager.defaultOptions.incrementalApi = | 279 AnalysisOptionsImpl options = |
| 276 analysisServerOptions.enableIncrementalResolutionApi; | 280 (contextManager as ServerContextManager).defaultOptions; |
| 277 contextDirectoryManager.defaultOptions.incrementalValidation = | 281 options.incremental = true; |
| 278 analysisServerOptions.enableIncrementalResolutionValidation; | 282 options.incrementalApi = |
| 279 contextDirectoryManager.defaultOptions.generateImplicitErrors = false; | 283 analysisServerOptions.enableIncrementalResolutionApi; |
| 284 options.incrementalValidation = | |
| 285 analysisServerOptions.enableIncrementalResolutionValidation; | |
| 286 options.generateImplicitErrors = false; | |
| 287 } else if (contextManager is! ServerContextManager) { | |
| 288 // TODO(brianwilkerson) Remove this when the interface is complete. | |
| 289 throw new StateError( | |
| 290 'The contextManager must be an instance of ServerContextManager'); | |
| 291 } | |
| 292 this.contextManager = contextManager; | |
| 280 _noErrorNotification = analysisServerOptions.noErrorNotification; | 293 _noErrorNotification = analysisServerOptions.noErrorNotification; |
| 281 AnalysisEngine.instance.logger = new AnalysisLogger(); | 294 AnalysisEngine.instance.logger = new AnalysisLogger(); |
| 282 _onAnalysisStartedController = new StreamController.broadcast(); | 295 _onAnalysisStartedController = new StreamController.broadcast(); |
| 283 _onFileAnalyzedController = new StreamController.broadcast(); | 296 _onFileAnalyzedController = new StreamController.broadcast(); |
| 284 _onPriorityChangeController = | 297 _onPriorityChangeController = |
| 285 new StreamController<PriorityChangeEvent>.broadcast(); | 298 new StreamController<PriorityChangeEvent>.broadcast(); |
| 286 running = true; | 299 running = true; |
| 287 onAnalysisStarted.first.then((_) { | 300 onAnalysisStarted.first.then((_) { |
| 288 onAnalysisComplete.then((_) { | 301 onAnalysisComplete.then((_) { |
| 289 performanceAfterStartup = new ServerPerformance(); | 302 performanceAfterStartup = new ServerPerformance(); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 314 * The stream that is notified when analysis of a context is started. | 327 * The stream that is notified when analysis of a context is started. |
| 315 */ | 328 */ |
| 316 Stream<AnalysisContext> get onAnalysisStarted { | 329 Stream<AnalysisContext> get onAnalysisStarted { |
| 317 return _onAnalysisStartedController.stream; | 330 return _onAnalysisStartedController.stream; |
| 318 } | 331 } |
| 319 | 332 |
| 320 /** | 333 /** |
| 321 * The stream that is notified when contexts are added or removed. | 334 * The stream that is notified when contexts are added or removed. |
| 322 */ | 335 */ |
| 323 Stream<ContextsChangedEvent> get onContextsChanged => | 336 Stream<ContextsChangedEvent> get onContextsChanged => |
| 324 contextDirectoryManager.onContextsChanged; | 337 contextManager.onContextsChanged; |
| 325 | 338 |
| 326 /** | 339 /** |
| 327 * The stream that is notified when a single file has been analyzed. | 340 * The stream that is notified when a single file has been analyzed. |
| 328 */ | 341 */ |
| 329 Stream get onFileAnalyzed => _onFileAnalyzedController.stream; | 342 Stream get onFileAnalyzed => _onFileAnalyzedController.stream; |
| 330 | 343 |
| 331 /** | 344 /** |
| 332 * The stream that is notified when priority sources change. | 345 * The stream that is notified when priority sources change. |
| 333 */ | 346 */ |
| 334 Stream<PriorityChangeEvent> get onPriorityChange => | 347 Stream<PriorityChangeEvent> get onPriorityChange => |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 367 void error(argument) { | 380 void error(argument) { |
| 368 running = false; | 381 running = false; |
| 369 } | 382 } |
| 370 | 383 |
| 371 /** | 384 /** |
| 372 * If the given notice applies to a file contained within an analysis root, | 385 * If the given notice applies to a file contained within an analysis root, |
| 373 * notify interested parties that the file has been (at least partially) | 386 * notify interested parties that the file has been (at least partially) |
| 374 * analyzed. | 387 * analyzed. |
| 375 */ | 388 */ |
| 376 void fileAnalyzed(ChangeNotice notice) { | 389 void fileAnalyzed(ChangeNotice notice) { |
| 377 if (contextDirectoryManager.isInAnalysisRoot(notice.source.fullName)) { | 390 if (contextManager.isInAnalysisRoot(notice.source.fullName)) { |
| 378 _onFileAnalyzedController.add(notice); | 391 _onFileAnalyzedController.add(notice); |
| 379 } | 392 } |
| 380 } | 393 } |
| 381 | 394 |
| 382 /** | 395 /** |
| 383 * Return the preferred [AnalysisContext] for analyzing the given [path]. | 396 * Return the preferred [AnalysisContext] for analyzing the given [path]. |
| 384 * This will be the context that explicitly contains the path, if any such | 397 * This will be the context that explicitly contains the path, if any such |
| 385 * context exists, otherwise it will be the first analysis context that | 398 * context exists, otherwise it will be the first analysis context that |
| 386 * implicitly analyzes it. Return `null` if no context is analyzing the | 399 * implicitly analyzes it. Return `null` if no context is analyzing the |
| 387 * path. | 400 * path. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 458 } | 471 } |
| 459 // try to find the deep-most containing context | 472 // try to find the deep-most containing context |
| 460 Resource resource = resourceProvider.getResource(path); | 473 Resource resource = resourceProvider.getResource(path); |
| 461 if (resource is! File) { | 474 if (resource is! File) { |
| 462 return new ContextSourcePair(null, null); | 475 return new ContextSourcePair(null, null); |
| 463 } | 476 } |
| 464 File file = resource; | 477 File file = resource; |
| 465 { | 478 { |
| 466 AnalysisContext containingContext = getContainingContext(path); | 479 AnalysisContext containingContext = getContainingContext(path); |
| 467 if (containingContext != null) { | 480 if (containingContext != null) { |
| 468 Source source = | 481 Source source = AbstractContextManager.createSourceInContext( |
| 469 ContextManager.createSourceInContext(containingContext, file); | 482 containingContext, file); |
| 470 return new ContextSourcePair(containingContext, source); | 483 return new ContextSourcePair(containingContext, source); |
| 471 } | 484 } |
| 472 } | 485 } |
| 473 // try to find a context that analysed the file | 486 // try to find a context that analysed the file |
| 474 for (AnalysisContext context in folderMap.values) { | 487 for (AnalysisContext context in folderMap.values) { |
| 475 Source source = ContextManager.createSourceInContext(context, file); | 488 Source source = |
| 489 AbstractContextManager.createSourceInContext(context, file); | |
| 476 SourceKind kind = context.getKindOf(source); | 490 SourceKind kind = context.getKindOf(source); |
| 477 if (kind != SourceKind.UNKNOWN) { | 491 if (kind != SourceKind.UNKNOWN) { |
| 478 return new ContextSourcePair(context, source); | 492 return new ContextSourcePair(context, source); |
| 479 } | 493 } |
| 480 } | 494 } |
| 481 // try to find a context for which the file is a priority source | 495 // try to find a context for which the file is a priority source |
| 482 for (InternalAnalysisContext context in folderMap.values) { | 496 for (InternalAnalysisContext context in folderMap.values) { |
| 483 List<Source> sources = context.getSourcesWithFullName(path); | 497 List<Source> sources = context.getSourcesWithFullName(path); |
| 484 if (sources.isNotEmpty) { | 498 if (sources.isNotEmpty) { |
| 485 Source source = sources.first; | 499 Source source = sources.first; |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 765 // Clear any operations that are pending. | 779 // Clear any operations that are pending. |
| 766 if (roots == null) { | 780 if (roots == null) { |
| 767 operationQueue.clear(); | 781 operationQueue.clear(); |
| 768 } else { | 782 } else { |
| 769 for (AnalysisContext context in _getContexts(roots)) { | 783 for (AnalysisContext context in _getContexts(roots)) { |
| 770 operationQueue.contextRemoved(context); | 784 operationQueue.contextRemoved(context); |
| 771 } | 785 } |
| 772 } | 786 } |
| 773 // Instruct the contextDirectoryManager to rebuild all contexts from | 787 // Instruct the contextDirectoryManager to rebuild all contexts from |
| 774 // scratch. | 788 // scratch. |
| 775 contextDirectoryManager.refresh(roots); | 789 contextManager.refresh(roots); |
| 776 } | 790 } |
| 777 | 791 |
| 778 /** | 792 /** |
| 779 * Schedules execution of the given [ServerOperation]. | 793 * Schedules execution of the given [ServerOperation]. |
| 780 */ | 794 */ |
| 781 void scheduleOperation(ServerOperation operation) { | 795 void scheduleOperation(ServerOperation operation) { |
| 782 addOperation(operation); | 796 addOperation(operation); |
| 783 _schedulePerformOperation(); | 797 _schedulePerformOperation(); |
| 784 } | 798 } |
| 785 | 799 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 870 * The current implementation is intentionally simplified and expected | 884 * The current implementation is intentionally simplified and expected |
| 871 * that only folders are given each given folder corresponds to the exactly | 885 * that only folders are given each given folder corresponds to the exactly |
| 872 * one context. | 886 * one context. |
| 873 * | 887 * |
| 874 * So, we can start working in parallel on adding services and improving | 888 * So, we can start working in parallel on adding services and improving |
| 875 * projects/contexts support. | 889 * projects/contexts support. |
| 876 */ | 890 */ |
| 877 void setAnalysisRoots(String requestId, List<String> includedPaths, | 891 void setAnalysisRoots(String requestId, List<String> includedPaths, |
| 878 List<String> excludedPaths, Map<String, String> packageRoots) { | 892 List<String> excludedPaths, Map<String, String> packageRoots) { |
| 879 try { | 893 try { |
| 880 contextDirectoryManager.setRoots( | 894 contextManager.setRoots(includedPaths, excludedPaths, packageRoots); |
| 881 includedPaths, excludedPaths, packageRoots); | |
| 882 } on UnimplementedError catch (e) { | 895 } on UnimplementedError catch (e) { |
| 883 throw new RequestFailure( | 896 throw new RequestFailure( |
| 884 new Response.unsupportedFeature(requestId, e.message)); | 897 new Response.unsupportedFeature(requestId, e.message)); |
| 885 } | 898 } |
| 886 } | 899 } |
| 887 | 900 |
| 888 /** | 901 /** |
| 889 * Implementation for `analysis.setSubscriptions`. | 902 * Implementation for `analysis.setSubscriptions`. |
| 890 */ | 903 */ |
| 891 void setAnalysisSubscriptions( | 904 void setAnalysisSubscriptions( |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 955 // Try to make the file analyzable. | 968 // Try to make the file analyzable. |
| 956 // If it is not in any context yet, add it to the first one which | 969 // If it is not in any context yet, add it to the first one which |
| 957 // could use it, e.g. imports its package, even if not the library. | 970 // could use it, e.g. imports its package, even if not the library. |
| 958 if (preferredContext == null) { | 971 if (preferredContext == null) { |
| 959 Resource resource = resourceProvider.getResource(file); | 972 Resource resource = resourceProvider.getResource(file); |
| 960 if (resource is File && resource.exists) { | 973 if (resource is File && resource.exists) { |
| 961 for (AnalysisContext context in folderMap.values) { | 974 for (AnalysisContext context in folderMap.values) { |
| 962 Uri uri = context.sourceFactory.restoreUri(source); | 975 Uri uri = context.sourceFactory.restoreUri(source); |
| 963 if (uri.scheme != 'file') { | 976 if (uri.scheme != 'file') { |
| 964 preferredContext = context; | 977 preferredContext = context; |
| 965 source = ContextManager.createSourceInContext(context, resource); | 978 source = AbstractContextManager.createSourceInContext( |
| 979 context, resource); | |
| 966 break; | 980 break; |
| 967 } | 981 } |
| 968 } | 982 } |
| 969 } | 983 } |
| 970 } | 984 } |
| 971 // Fill the source map. | 985 // Fill the source map. |
| 972 bool contextFound = false; | 986 bool contextFound = false; |
| 973 for (AnalysisContext context in folderMap.values) { | 987 for (AnalysisContext context in folderMap.values) { |
| 974 if (context == preferredContext || | 988 if (context == preferredContext || |
| 975 context.getKindOf(source) != SourceKind.UNKNOWN) { | 989 context.getKindOf(source) != SourceKind.UNKNOWN) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1002 }); | 1016 }); |
| 1003 operationQueue.reschedule(); | 1017 operationQueue.reschedule(); |
| 1004 _onPriorityChangeController.add(new PriorityChangeEvent(firstSource)); | 1018 _onPriorityChangeController.add(new PriorityChangeEvent(firstSource)); |
| 1005 } | 1019 } |
| 1006 | 1020 |
| 1007 /** | 1021 /** |
| 1008 * Returns `true` if errors should be reported for [file] with the given | 1022 * Returns `true` if errors should be reported for [file] with the given |
| 1009 * absolute path. | 1023 * absolute path. |
| 1010 */ | 1024 */ |
| 1011 bool shouldSendErrorsNotificationFor(String file) { | 1025 bool shouldSendErrorsNotificationFor(String file) { |
| 1012 return !_noErrorNotification && | 1026 return !_noErrorNotification && contextManager.isInAnalysisRoot(file); |
| 1013 contextDirectoryManager.isInAnalysisRoot(file); | |
| 1014 } | 1027 } |
| 1015 | 1028 |
| 1016 void shutdown() { | 1029 void shutdown() { |
| 1017 running = false; | 1030 running = false; |
| 1018 if (index != null) { | 1031 if (index != null) { |
| 1019 index.clear(); | 1032 index.clear(); |
| 1020 index.stop(); | 1033 index.stop(); |
| 1021 } | 1034 } |
| 1022 // Defer closing the channel and shutting down the instrumentation server so | 1035 // Defer closing the channel and shutting down the instrumentation server so |
| 1023 // that the shutdown response can be sent and logged. | 1036 // that the shutdown response can be sent and logged. |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1150 // | 1163 // |
| 1151 // Update existing contexts. | 1164 // Update existing contexts. |
| 1152 // | 1165 // |
| 1153 folderMap.forEach((Folder folder, AnalysisContext context) { | 1166 folderMap.forEach((Folder folder, AnalysisContext context) { |
| 1154 AnalysisOptionsImpl options = | 1167 AnalysisOptionsImpl options = |
| 1155 new AnalysisOptionsImpl.from(context.analysisOptions); | 1168 new AnalysisOptionsImpl.from(context.analysisOptions); |
| 1156 optionUpdaters.forEach((OptionUpdater optionUpdater) { | 1169 optionUpdaters.forEach((OptionUpdater optionUpdater) { |
| 1157 optionUpdater(options); | 1170 optionUpdater(options); |
| 1158 }); | 1171 }); |
| 1159 context.analysisOptions = options; | 1172 context.analysisOptions = options; |
| 1173 // TODO(brianwilkerson) As far as I can tell, this doesn't cause analysis | |
|
Paul Berry
2015/07/09 21:45:57
Ouch. I believe you are right.
| |
| 1174 // to be scheduled for this context. | |
| 1160 }); | 1175 }); |
| 1161 // | 1176 // |
| 1162 // Update the defaults used to create new contexts. | 1177 // Update the defaults used to create new contexts. |
| 1163 // | 1178 // |
| 1164 AnalysisOptionsImpl options = contextDirectoryManager.defaultOptions; | 1179 AnalysisOptionsImpl options = contextManager.defaultOptions; |
| 1165 optionUpdaters.forEach((OptionUpdater optionUpdater) { | 1180 optionUpdaters.forEach((OptionUpdater optionUpdater) { |
| 1166 optionUpdater(options); | 1181 optionUpdater(options); |
| 1167 }); | 1182 }); |
| 1168 } | 1183 } |
| 1169 | 1184 |
| 1170 /** | 1185 /** |
| 1171 * Return a set of contexts containing all of the resources in the given list | 1186 * Return a set of contexts containing all of the resources in the given list |
| 1172 * of [resources]. | 1187 * of [resources]. |
| 1173 */ | 1188 */ |
| 1174 Set<AnalysisContext> _getContexts(List<Resource> resources) { | 1189 Set<AnalysisContext> _getContexts(List<Resource> resources) { |
| 1175 Set<AnalysisContext> contexts = new HashSet<AnalysisContext>(); | 1190 Set<AnalysisContext> contexts = new HashSet<AnalysisContext>(); |
| 1176 resources.forEach((Resource resource) { | 1191 resources.forEach((Resource resource) { |
| 1177 if (resource is Folder) { | 1192 if (resource is Folder) { |
| 1178 contexts | 1193 contexts.addAll(contextManager.contextsInAnalysisRoot(resource)); |
| 1179 .addAll(contextDirectoryManager.contextsInAnalysisRoot(resource)); | |
| 1180 } | 1194 } |
| 1181 }); | 1195 }); |
| 1182 return contexts; | 1196 return contexts; |
| 1183 } | 1197 } |
| 1184 | 1198 |
| 1185 /** | 1199 /** |
| 1186 * Returns the [CompilationUnit] of the Dart file with the given [source] that | 1200 * Returns the [CompilationUnit] of the Dart file with the given [source] that |
| 1187 * should be used to resend notifications for already resolved unit. | 1201 * should be used to resend notifications for already resolved unit. |
| 1188 * Returns `null` if the file is not a part of any context, library has not | 1202 * Returns `null` if the file is not a part of any context, library has not |
| 1189 * been yet resolved, or any problem happened. | 1203 * been yet resolved, or any problem happened. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1236 | 1250 |
| 1237 class AnalysisServerOptions { | 1251 class AnalysisServerOptions { |
| 1238 bool enableIncrementalResolutionApi = false; | 1252 bool enableIncrementalResolutionApi = false; |
| 1239 bool enableIncrementalResolutionValidation = false; | 1253 bool enableIncrementalResolutionValidation = false; |
| 1240 bool noErrorNotification = false; | 1254 bool noErrorNotification = false; |
| 1241 bool noIndex = false; | 1255 bool noIndex = false; |
| 1242 String fileReadMode = 'as-is'; | 1256 String fileReadMode = 'as-is'; |
| 1243 } | 1257 } |
| 1244 | 1258 |
| 1245 /** | 1259 /** |
| 1246 * A [ContextsChangedEvent] indicate what contexts were added or removed. | 1260 * An implementation of a [ContextsChangedEvent]. |
| 1247 * | |
| 1248 * No context should be added to the event more than once. It does not make | |
| 1249 * sense, for example, for a context to be both added and removed. | |
| 1250 */ | 1261 */ |
| 1251 class ContextsChangedEvent { | 1262 class ContextsChangedEventImpl implements ContextsChangedEvent { |
|
Paul Berry
2015/07/09 21:45:57
I don't follow the benefit of making an interface/
Brian Wilkerson
2015/07/13 17:18:50
I agree. Done.
| |
| 1252 | |
| 1253 /** | 1263 /** |
| 1254 * The contexts that were added to the server. | 1264 * The contexts that were added to the server. |
| 1255 */ | 1265 */ |
| 1256 final List<AnalysisContext> added; | 1266 final List<AnalysisContext> added; |
| 1257 | 1267 |
| 1258 /** | 1268 /** |
| 1259 * The contexts that were changed. | 1269 * The contexts that were changed. |
| 1260 */ | 1270 */ |
| 1261 final List<AnalysisContext> changed; | 1271 final List<AnalysisContext> changed; |
| 1262 | 1272 |
| 1263 /** | 1273 /** |
| 1264 * The contexts that were removed from the server. | 1274 * The contexts that were removed from the server. |
| 1265 */ | 1275 */ |
| 1266 final List<AnalysisContext> removed; | 1276 final List<AnalysisContext> removed; |
| 1267 | 1277 |
| 1268 ContextsChangedEvent({this.added: AnalysisContext.EMPTY_LIST, | 1278 ContextsChangedEventImpl({this.added: AnalysisContext.EMPTY_LIST, |
| 1269 this.changed: AnalysisContext.EMPTY_LIST, | 1279 this.changed: AnalysisContext.EMPTY_LIST, |
| 1270 this.removed: AnalysisContext.EMPTY_LIST}); | 1280 this.removed: AnalysisContext.EMPTY_LIST}); |
| 1271 } | 1281 } |
| 1272 | 1282 |
| 1273 /** | 1283 /** |
| 1274 * Information about a file - an [AnalysisContext] that analyses the file, | 1284 * Information about a file - an [AnalysisContext] that analyses the file, |
| 1275 * and the [Source] representing the file in this context. | 1285 * and the [Source] representing the file in this context. |
| 1276 */ | 1286 */ |
| 1277 class ContextSourcePair { | 1287 class ContextSourcePair { |
| 1278 /** | 1288 /** |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1293 | 1303 |
| 1294 /** | 1304 /** |
| 1295 * A [PriorityChangeEvent] indicates the set the priority files has changed. | 1305 * A [PriorityChangeEvent] indicates the set the priority files has changed. |
| 1296 */ | 1306 */ |
| 1297 class PriorityChangeEvent { | 1307 class PriorityChangeEvent { |
| 1298 final Source firstSource; | 1308 final Source firstSource; |
| 1299 | 1309 |
| 1300 PriorityChangeEvent(this.firstSource); | 1310 PriorityChangeEvent(this.firstSource); |
| 1301 } | 1311 } |
| 1302 | 1312 |
| 1303 class ServerContextManager extends ContextManager { | 1313 class ServerContextManager extends AbstractContextManager { |
| 1304 final AnalysisServer analysisServer; | 1314 final AnalysisServer analysisServer; |
| 1305 | 1315 |
| 1306 /** | 1316 /** |
| 1307 * The default options used to create new analysis contexts. | 1317 * The default options used to create new analysis contexts. |
| 1308 */ | 1318 */ |
| 1309 AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl(); | 1319 AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl(); |
| 1310 | 1320 |
| 1311 /** | 1321 /** |
| 1312 * The controller for sending [ContextsChangedEvent]s. | 1322 * The controller for sending [ContextsChangedEvent]s. |
| 1313 */ | 1323 */ |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 1331 | 1341 |
| 1332 @override | 1342 @override |
| 1333 AnalysisContext addContext(Folder folder, UriResolver packageUriResolver) { | 1343 AnalysisContext addContext(Folder folder, UriResolver packageUriResolver) { |
| 1334 InternalAnalysisContext context = | 1344 InternalAnalysisContext context = |
| 1335 AnalysisEngine.instance.createAnalysisContext(); | 1345 AnalysisEngine.instance.createAnalysisContext(); |
| 1336 context.contentCache = analysisServer.overlayState; | 1346 context.contentCache = analysisServer.overlayState; |
| 1337 analysisServer.folderMap[folder] = context; | 1347 analysisServer.folderMap[folder] = context; |
| 1338 context.sourceFactory = _createSourceFactory(packageUriResolver); | 1348 context.sourceFactory = _createSourceFactory(packageUriResolver); |
| 1339 context.analysisOptions = new AnalysisOptionsImpl.from(defaultOptions); | 1349 context.analysisOptions = new AnalysisOptionsImpl.from(defaultOptions); |
| 1340 _onContextsChangedController | 1350 _onContextsChangedController |
| 1341 .add(new ContextsChangedEvent(added: [context])); | 1351 .add(new ContextsChangedEventImpl(added: [context])); |
| 1342 analysisServer.schedulePerformAnalysisOperation(context); | 1352 analysisServer.schedulePerformAnalysisOperation(context); |
| 1343 return context; | 1353 return context; |
| 1344 } | 1354 } |
| 1345 | 1355 |
| 1346 @override | 1356 @override |
| 1347 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { | 1357 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { |
| 1348 AnalysisContext context = analysisServer.folderMap[contextFolder]; | 1358 AnalysisContext context = analysisServer.folderMap[contextFolder]; |
| 1349 if (context != null) { | 1359 if (context != null) { |
| 1350 context.applyChanges(changeSet); | 1360 context.applyChanges(changeSet); |
| 1351 analysisServer.schedulePerformAnalysisOperation(context); | 1361 analysisServer.schedulePerformAnalysisOperation(context); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1375 // computeFlushedFiles instead of using the referenced context above, this | 1385 // computeFlushedFiles instead of using the referenced context above, this |
| 1376 // is an attempt to be careful concerning the referenced issue. | 1386 // is an attempt to be careful concerning the referenced issue. |
| 1377 List<String> flushedFiles = computeFlushedFiles(folder); | 1387 List<String> flushedFiles = computeFlushedFiles(folder); |
| 1378 sendAnalysisNotificationFlushResults(analysisServer, flushedFiles); | 1388 sendAnalysisNotificationFlushResults(analysisServer, flushedFiles); |
| 1379 | 1389 |
| 1380 if (analysisServer.index != null) { | 1390 if (analysisServer.index != null) { |
| 1381 analysisServer.index.removeContext(context); | 1391 analysisServer.index.removeContext(context); |
| 1382 } | 1392 } |
| 1383 analysisServer.operationQueue.contextRemoved(context); | 1393 analysisServer.operationQueue.contextRemoved(context); |
| 1384 _onContextsChangedController | 1394 _onContextsChangedController |
| 1385 .add(new ContextsChangedEvent(removed: [context])); | 1395 .add(new ContextsChangedEventImpl(removed: [context])); |
| 1386 analysisServer.sendContextAnalysisDoneNotifications( | 1396 analysisServer.sendContextAnalysisDoneNotifications( |
| 1387 context, AnalysisDoneReason.CONTEXT_REMOVED); | 1397 context, AnalysisDoneReason.CONTEXT_REMOVED); |
| 1388 context.dispose(); | 1398 context.dispose(); |
| 1389 } | 1399 } |
| 1390 | 1400 |
| 1391 @override | 1401 @override |
| 1392 bool shouldFileBeAnalyzed(File file) { | 1402 bool shouldFileBeAnalyzed(File file) { |
| 1393 List<ShouldAnalyzeFile> functions = | 1403 List<ShouldAnalyzeFile> functions = |
| 1394 analysisServer.serverPlugin.analyzeFileFunctions; | 1404 analysisServer.serverPlugin.analyzeFileFunctions; |
| 1395 for (ShouldAnalyzeFile shouldAnalyzeFile in functions) { | 1405 for (ShouldAnalyzeFile shouldAnalyzeFile in functions) { |
| 1396 if (shouldAnalyzeFile(file)) { | 1406 if (shouldAnalyzeFile(file)) { |
| 1397 // Emacs creates dummy links to track the fact that a file is open for | 1407 // Emacs creates dummy links to track the fact that a file is open for |
| 1398 // editing and has unsaved changes (e.g. having unsaved changes to | 1408 // editing and has unsaved changes (e.g. having unsaved changes to |
| 1399 // 'foo.dart' causes a link '.#foo.dart' to be created, which points to | 1409 // 'foo.dart' causes a link '.#foo.dart' to be created, which points to |
| 1400 // the non-existent file 'username@hostname.pid'. To avoid these dummy | 1410 // the non-existent file 'username@hostname.pid'. To avoid these dummy |
| 1401 // links causing the analyzer to thrash, just ignore links to | 1411 // links causing the analyzer to thrash, just ignore links to |
| 1402 // non-existent files. | 1412 // non-existent files. |
| 1403 return file.exists; | 1413 return file.exists; |
| 1404 } | 1414 } |
| 1405 } | 1415 } |
| 1406 return false; | 1416 return false; |
| 1407 } | 1417 } |
| 1408 | 1418 |
| 1409 @override | 1419 @override |
| 1410 void updateContextPackageUriResolver( | 1420 void updateContextPackageUriResolver( |
| 1411 Folder contextFolder, UriResolver packageUriResolver) { | 1421 Folder contextFolder, UriResolver packageUriResolver) { |
| 1412 AnalysisContext context = analysisServer.folderMap[contextFolder]; | 1422 AnalysisContext context = analysisServer.folderMap[contextFolder]; |
| 1413 context.sourceFactory = _createSourceFactory(packageUriResolver); | 1423 context.sourceFactory = _createSourceFactory(packageUriResolver); |
| 1414 _onContextsChangedController | 1424 _onContextsChangedController |
| 1415 .add(new ContextsChangedEvent(changed: [context])); | 1425 .add(new ContextsChangedEventImpl(changed: [context])); |
| 1416 analysisServer.schedulePerformAnalysisOperation(context); | 1426 analysisServer.schedulePerformAnalysisOperation(context); |
| 1417 } | 1427 } |
| 1418 | 1428 |
| 1419 void _computingPackageMap(bool computing) { | 1429 void _computingPackageMap(bool computing) { |
| 1420 if (analysisServer.serverServices.contains(ServerService.STATUS)) { | 1430 if (analysisServer.serverServices.contains(ServerService.STATUS)) { |
| 1421 PubStatus pubStatus = new PubStatus(computing); | 1431 PubStatus pubStatus = new PubStatus(computing); |
| 1422 ServerStatusParams params = new ServerStatusParams(pub: pubStatus); | 1432 ServerStatusParams params = new ServerStatusParams(pub: pubStatus); |
| 1423 analysisServer.sendNotification(params.toNotification()); | 1433 analysisServer.sendNotification(params.toNotification()); |
| 1424 } | 1434 } |
| 1425 } | 1435 } |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1541 /** | 1551 /** |
| 1542 * The [PerformanceTag] for time spent in server request handlers. | 1552 * The [PerformanceTag] for time spent in server request handlers. |
| 1543 */ | 1553 */ |
| 1544 static PerformanceTag serverRequests = new PerformanceTag('serverRequests'); | 1554 static PerformanceTag serverRequests = new PerformanceTag('serverRequests'); |
| 1545 | 1555 |
| 1546 /** | 1556 /** |
| 1547 * The [PerformanceTag] for time spent in split store microtasks. | 1557 * The [PerformanceTag] for time spent in split store microtasks. |
| 1548 */ | 1558 */ |
| 1549 static PerformanceTag splitStore = new PerformanceTag('splitStore'); | 1559 static PerformanceTag splitStore = new PerformanceTag('splitStore'); |
| 1550 } | 1560 } |
| OLD | NEW |