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 | 8 |
| 9 import 'package:analysis_server/src/analysis_logger.dart'; | 9 import 'package:analysis_server/src/analysis_logger.dart'; |
| 10 import 'package:analysis_server/src/channel.dart'; | 10 import 'package:analysis_server/src/channel.dart'; |
| 11 import 'package:analysis_server/src/context_directory_manager.dart'; | |
| 11 import 'package:analysis_server/src/domain_analysis.dart'; | 12 import 'package:analysis_server/src/domain_analysis.dart'; |
| 12 import 'package:analysis_server/src/protocol.dart'; | 13 import 'package:analysis_server/src/protocol.dart'; |
| 13 import 'package:analysis_server/src/resource.dart'; | 14 import 'package:analysis_server/src/resource.dart'; |
| 14 import 'package:analyzer/src/generated/ast.dart'; | 15 import 'package:analyzer/src/generated/ast.dart'; |
| 15 import 'package:analyzer/src/generated/engine.dart'; | 16 import 'package:analyzer/src/generated/engine.dart'; |
| 16 import 'package:analyzer/src/generated/error.dart'; | 17 import 'package:analyzer/src/generated/error.dart'; |
| 17 import 'package:analyzer/src/generated/java_core.dart'; | 18 import 'package:analyzer/src/generated/java_core.dart'; |
| 18 import 'package:analyzer/src/generated/source.dart'; | 19 import 'package:analyzer/src/generated/source.dart'; |
| 19 import 'package:analyzer/src/generated/sdk.dart'; | 20 import 'package:analyzer/src/generated/sdk.dart'; |
| 20 import 'package:analyzer/src/generated/sdk_io.dart'; | 21 import 'package:analyzer/src/generated/sdk_io.dart'; |
| 21 import 'package:analyzer/src/generated/source_io.dart'; | 22 import 'package:analyzer/src/generated/source_io.dart'; |
| 22 | 23 |
| 23 | 24 |
| 24 /** | 25 /** |
| 25 * An instance of [DirectoryBasedDartSdk] that is shared between | 26 * An instance of [DirectoryBasedDartSdk] that is shared between |
| 26 * [AnalysisServer] instances to improve performance. | 27 * [AnalysisServer] instances to improve performance. |
| 27 */ | 28 */ |
| 28 final DirectoryBasedDartSdk SHARED_SDK = DirectoryBasedDartSdk.defaultSdk; | 29 final DirectoryBasedDartSdk SHARED_SDK = DirectoryBasedDartSdk.defaultSdk; |
| 29 | 30 |
| 31 class AnalysisServerContextDirectoryManager extends ContextDirectoryManager { | |
| 32 final AnalysisServer analysisServer; | |
| 33 | |
| 34 AnalysisServerContextDirectoryManager(this.analysisServer, ResourceProvider re sourceProvider) | |
| 35 : super(resourceProvider); | |
| 36 | |
| 37 void addContext(Folder folder) { | |
| 38 PubFolder pubFolder = new PubFolder(analysisServer.defaultSdk, folder); | |
| 39 analysisServer.folderMap[folder] = pubFolder; | |
| 40 analysisServer.addContextToWorkQueue(pubFolder.context); | |
| 41 } | |
| 42 } | |
| 43 | |
| 30 /** | 44 /** |
| 31 * Instances of the class [AnalysisServer] implement a server that listens on a | 45 * Instances of the class [AnalysisServer] implement a server that listens on a |
| 32 * [CommunicationChannel] for analysis requests and process them. | 46 * [CommunicationChannel] for analysis requests and process them. |
| 33 */ | 47 */ |
| 34 class AnalysisServer { | 48 class AnalysisServer { |
| 35 /** | 49 /** |
| 36 * The name of the parameter whose value is a list of errors. | 50 * The name of the parameter whose value is a list of errors. |
| 37 */ | 51 */ |
| 38 static const String ERRORS_PARAM = 'errors'; | 52 static const String ERRORS_PARAM = 'errors'; |
| 39 | 53 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 52 */ | 66 */ |
| 53 static const String STATUS_NOTIFICATION = 'server.status'; | 67 static const String STATUS_NOTIFICATION = 'server.status'; |
| 54 | 68 |
| 55 /** | 69 /** |
| 56 * The channel from which requests are received and to which responses should | 70 * The channel from which requests are received and to which responses should |
| 57 * be sent. | 71 * be sent. |
| 58 */ | 72 */ |
| 59 final ServerCommunicationChannel channel; | 73 final ServerCommunicationChannel channel; |
| 60 | 74 |
| 61 /** | 75 /** |
| 62 * The [ResourceProvider] using which paths are converted into [Resource]s. | 76 * [ContextDirectoryManager] which handles the mapping from analysis roots |
| 77 * to context directories. | |
| 63 */ | 78 */ |
| 64 final ResourceProvider resourceProvider; | 79 AnalysisServerContextDirectoryManager contextDirectoryManager; |
| 65 | 80 |
| 66 /** | 81 /** |
| 67 * A flag indicating whether the server is running. When false, contexts | 82 * A flag indicating whether the server is running. When false, contexts |
| 68 * will no longer be added to [contextWorkQueue], and [performTask] will | 83 * will no longer be added to [contextWorkQueue], and [performTask] will |
| 69 * discard any tasks it finds on [contextWorkQueue]. | 84 * discard any tasks it finds on [contextWorkQueue]. |
| 70 */ | 85 */ |
| 71 bool running; | 86 bool running; |
| 72 | 87 |
| 73 /** | 88 /** |
| 74 * A list of the request handlers used to handle the requests sent to this | 89 * A list of the request handlers used to handle the requests sent to this |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 | 129 |
| 115 /** | 130 /** |
| 116 * A set of the [ServerService]s to send notifications for. | 131 * A set of the [ServerService]s to send notifications for. |
| 117 */ | 132 */ |
| 118 Set<ServerService> serverServices = new Set<ServerService>(); | 133 Set<ServerService> serverServices = new Set<ServerService>(); |
| 119 | 134 |
| 120 /** | 135 /** |
| 121 * Initialize a newly created server to receive requests from and send | 136 * Initialize a newly created server to receive requests from and send |
| 122 * responses to the given [channel]. | 137 * responses to the given [channel]. |
| 123 */ | 138 */ |
| 124 AnalysisServer(this.channel, this.resourceProvider) { | 139 AnalysisServer(this.channel, ResourceProvider resourceProvider) { |
| 140 contextDirectoryManager = new AnalysisServerContextDirectoryManager(this, re sourceProvider); | |
| 125 AnalysisEngine.instance.logger = new AnalysisLogger(); | 141 AnalysisEngine.instance.logger = new AnalysisLogger(); |
| 126 running = true; | 142 running = true; |
| 127 Notification notification = new Notification(CONNECTED_NOTIFICATION); | 143 Notification notification = new Notification(CONNECTED_NOTIFICATION); |
| 128 channel.sendNotification(notification); | 144 channel.sendNotification(notification); |
| 129 channel.listen(handleRequest, onDone: done, onError: error); | 145 channel.listen(handleRequest, onDone: done, onError: error); |
| 130 } | 146 } |
| 131 | 147 |
| 132 /** | 148 /** |
| 133 * If [running] is true, add the given [context] to the list of analysis | 149 * If [running] is true, add the given [context] to the list of analysis |
| 134 * contexts for which analysis work needs to be performed, and ensure that | 150 * contexts for which analysis work needs to be performed, and ensure that |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 * The current implementation is intentionally simplified and expected | 297 * The current implementation is intentionally simplified and expected |
| 282 * that only folders are given each given folder corresponds to the exactly | 298 * that only folders are given each given folder corresponds to the exactly |
| 283 * one context. | 299 * one context. |
| 284 * | 300 * |
| 285 * So, we can start working in parallel on adding services and improving | 301 * So, we can start working in parallel on adding services and improving |
| 286 * projects/contexts support. | 302 * projects/contexts support. |
| 287 */ | 303 */ |
| 288 void setAnalysisRoots(String requestId, | 304 void setAnalysisRoots(String requestId, |
| 289 List<String> includedPaths, | 305 List<String> includedPaths, |
| 290 List<String> excludedPaths) { | 306 List<String> excludedPaths) { |
| 291 // included | 307 try { |
| 292 Set<Folder> includedFolders = new Set<Folder>(); | 308 contextDirectoryManager.setRoots(includedPaths, excludedPaths); |
|
scheglov
2014/05/28 20:28:41
Does it still work for the simplest cases?
Paul Berry
2014/05/28 20:33:32
AFAICT, yes. This CL is just a refactor of existi
| |
| 293 for (int i = 0; i < includedPaths.length; i++) { | 309 } on UnimplementedError catch (e) { |
| 294 String path = includedPaths[i]; | |
| 295 Resource resource = resourceProvider.getResource(path); | |
| 296 if (resource is Folder) { | |
| 297 includedFolders.add(resource); | |
| 298 } else { | |
| 299 // TODO(scheglov) implemented separate files analysis | |
| 300 throw new RequestFailure( | |
| 301 new Response.unsupportedFeature( | |
| 302 requestId, | |
| 303 '$path is not a folder. ' | |
| 304 'Only support for folder analysis is implemented currently.')); | |
| 305 } | |
| 306 } | |
| 307 // excluded | |
| 308 // TODO(scheglov) remove when implemented | |
| 309 if (excludedPaths.isNotEmpty) { | |
| 310 throw new RequestFailure( | 310 throw new RequestFailure( |
| 311 new Response.unsupportedFeature( | 311 new Response.unsupportedFeature( |
| 312 requestId, | 312 requestId, e.message)); |
| 313 'Excluded paths are not supported yet')); | |
| 314 } | |
| 315 Set<Folder> excludedFolders = new Set<Folder>(); | |
| 316 // diff | |
| 317 Set<Folder> currentFolders = new Set<Folder>.from(folderMap.keys); | |
| 318 Set<Folder> newFolders = includedFolders.difference(currentFolders); | |
| 319 Set<Folder> oldFolders = currentFolders.difference(includedFolders); | |
| 320 // remove old contexts | |
| 321 for (Folder folder in oldFolders) { | |
| 322 // TODO(scheglov) implement | |
| 323 } | |
| 324 // add new contexts | |
| 325 for (Folder folder in newFolders) { | |
| 326 PubFolder pubFolder = new PubFolder(defaultSdk, folder); | |
| 327 folderMap[folder] = pubFolder; | |
| 328 addContextToWorkQueue(pubFolder.context); | |
| 329 } | 313 } |
| 330 } | 314 } |
| 331 | 315 |
| 332 /** | 316 /** |
| 333 * Return the [AnalysisContext] that is used to analyze the given [path]. | 317 * Return the [AnalysisContext] that is used to analyze the given [path]. |
| 334 * Return `null` if there is no such context. | 318 * Return `null` if there is no such context. |
| 335 */ | 319 */ |
| 336 AnalysisContext test_getAnalysisContext(String path) { | 320 AnalysisContext test_getAnalysisContext(String path) { |
| 337 for (Folder folder in folderMap.keys) { | 321 for (Folder folder in folderMap.keys) { |
| 338 if (path.startsWith(folder.fullName)) { | 322 if (path.startsWith(folder.fullName)) { |
| 339 return folderMap[folder].context; | 323 return folderMap[folder].context; |
| 340 } | 324 } |
| 341 } | 325 } |
| 342 return null; | 326 return null; |
| 343 } | 327 } |
| 344 | 328 |
| 345 /** | 329 /** |
| 346 * Return the [CompilationUnit] of the Dart file with the given [path]. | 330 * Return the [CompilationUnit] of the Dart file with the given [path]. |
| 347 * Return `null` if the file is not a part of any context. | 331 * Return `null` if the file is not a part of any context. |
| 348 */ | 332 */ |
| 349 CompilationUnit test_getResolvedCompilationUnit(String path) { | 333 CompilationUnit test_getResolvedCompilationUnit(String path) { |
| 350 // prepare AnalysisContext | 334 // prepare AnalysisContext |
| 351 AnalysisContext context = test_getAnalysisContext(path); | 335 AnalysisContext context = test_getAnalysisContext(path); |
| 352 if (context == null) { | 336 if (context == null) { |
| 353 return null; | 337 return null; |
| 354 } | 338 } |
| 355 // prepare sources | 339 // prepare sources |
| 356 File file = resourceProvider.getResource(path); | 340 File file = contextDirectoryManager.resourceProvider.getResource(path); |
| 357 Source unitSource = file.createSource(UriKind.FILE_URI); | 341 Source unitSource = file.createSource(UriKind.FILE_URI); |
| 358 List<Source> librarySources = context.getLibrariesContaining(unitSource); | 342 List<Source> librarySources = context.getLibrariesContaining(unitSource); |
| 359 if (librarySources.isEmpty) { | 343 if (librarySources.isEmpty) { |
| 360 return null; | 344 return null; |
| 361 } | 345 } |
| 362 // get a resolved unit | 346 // get a resolved unit |
| 363 return context.getResolvedCompilationUnit2(unitSource, librarySources[0]); | 347 return context.getResolvedCompilationUnit2(unitSource, librarySources[0]); |
| 364 } | 348 } |
| 365 | 349 |
| 366 /** | 350 /** |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 494 /** | 478 /** |
| 495 * An enumeration of the services provided by the server domain. | 479 * An enumeration of the services provided by the server domain. |
| 496 */ | 480 */ |
| 497 class ServerService extends Enum2<ServerService> { | 481 class ServerService extends Enum2<ServerService> { |
| 498 static const ServerService STATUS = const ServerService('STATUS', 0); | 482 static const ServerService STATUS = const ServerService('STATUS', 0); |
| 499 | 483 |
| 500 static const List<ServerService> VALUES = const [STATUS]; | 484 static const List<ServerService> VALUES = const [STATUS]; |
| 501 | 485 |
| 502 const ServerService(String name, int ordinal) : super(name, ordinal); | 486 const ServerService(String name, int ordinal) : super(name, ordinal); |
| 503 } | 487 } |
| OLD | NEW |