| 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; |
| 11 | 11 |
| 12 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element; | 12 import 'package:analysis_server/plugin/protocol/protocol.dart' |
| 13 hide AnalysisOptions, Element; |
| 13 import 'package:analysis_server/src/analysis_logger.dart'; | 14 import 'package:analysis_server/src/analysis_logger.dart'; |
| 14 import 'package:analysis_server/src/channel/channel.dart'; | 15 import 'package:analysis_server/src/channel/channel.dart'; |
| 15 import 'package:analysis_server/src/context_manager.dart'; | 16 import 'package:analysis_server/src/context_manager.dart'; |
| 16 import 'package:analysis_server/src/operation/operation.dart'; | 17 import 'package:analysis_server/src/operation/operation.dart'; |
| 17 import 'package:analysis_server/src/operation/operation_analysis.dart'; | 18 import 'package:analysis_server/src/operation/operation_analysis.dart'; |
| 18 import 'package:analysis_server/src/operation/operation_queue.dart'; | 19 import 'package:analysis_server/src/operation/operation_queue.dart'; |
| 19 import 'package:analysis_server/src/plugin/server_plugin.dart'; | 20 import 'package:analysis_server/src/plugin/server_plugin.dart'; |
| 20 import 'package:analysis_server/src/services/correction/namespace.dart'; | 21 import 'package:analysis_server/src/services/correction/namespace.dart'; |
| 21 import 'package:analysis_server/src/services/index/index.dart'; | 22 import 'package:analysis_server/src/services/index/index.dart'; |
| 22 import 'package:analysis_server/src/services/search/search_engine.dart'; | 23 import 'package:analysis_server/src/services/search/search_engine.dart'; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 */ | 134 */ |
| 134 bool statusAnalyzing = false; | 135 bool statusAnalyzing = false; |
| 135 | 136 |
| 136 /** | 137 /** |
| 137 * A list of the request handlers used to handle the requests sent to this | 138 * A list of the request handlers used to handle the requests sent to this |
| 138 * server. | 139 * server. |
| 139 */ | 140 */ |
| 140 List<RequestHandler> handlers; | 141 List<RequestHandler> handlers; |
| 141 | 142 |
| 142 /** | 143 /** |
| 143 * The current default [DartSdk]. | 144 * The function used to create a new SDK using the default SDK. |
| 144 */ | 145 */ |
| 145 final DartSdk defaultSdk; | 146 final SdkCreator defaultSdkCreator; |
| 147 |
| 148 /** |
| 149 * The object used to manage the SDK's known to this server. |
| 150 */ |
| 151 DartSdkManager sdkManager; |
| 146 | 152 |
| 147 /** | 153 /** |
| 148 * The instrumentation service that is to be used by this analysis server. | 154 * The instrumentation service that is to be used by this analysis server. |
| 149 */ | 155 */ |
| 150 final InstrumentationService instrumentationService; | 156 final InstrumentationService instrumentationService; |
| 151 | 157 |
| 152 /** | 158 /** |
| 153 * A table mapping [Folder]s to the [AnalysisContext]s associated with them. | 159 * A table mapping [Folder]s to the [AnalysisContext]s associated with them. |
| 154 */ | 160 */ |
| 155 final Map<Folder, AnalysisContext> folderMap = | 161 final Map<Folder, AnalysisContext> folderMap = |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 * exceptions to show up in unit tests, but it should be set to false when | 299 * exceptions to show up in unit tests, but it should be set to false when |
| 294 * running a full analysis server. | 300 * running a full analysis server. |
| 295 */ | 301 */ |
| 296 AnalysisServer( | 302 AnalysisServer( |
| 297 this.channel, | 303 this.channel, |
| 298 this.resourceProvider, | 304 this.resourceProvider, |
| 299 PubPackageMapProvider packageMapProvider, | 305 PubPackageMapProvider packageMapProvider, |
| 300 Index _index, | 306 Index _index, |
| 301 this.serverPlugin, | 307 this.serverPlugin, |
| 302 this.options, | 308 this.options, |
| 303 this.defaultSdk, | 309 this.defaultSdkCreator, |
| 304 this.instrumentationService, | 310 this.instrumentationService, |
| 305 {ResolverProvider packageResolverProvider: null, | 311 {ResolverProvider packageResolverProvider: null, |
| 306 EmbeddedResolverProvider embeddedResolverProvider: null, | 312 EmbeddedResolverProvider embeddedResolverProvider: null, |
| 307 this.rethrowExceptions: true}) | 313 this.rethrowExceptions: true}) |
| 308 : index = _index, | 314 : index = _index, |
| 309 searchEngine = _index != null ? createSearchEngine(_index) : null { | 315 searchEngine = _index != null ? createSearchEngine(_index) : null { |
| 310 _performance = performanceDuringStartup; | 316 _performance = performanceDuringStartup; |
| 311 operationQueue = new ServerOperationQueue(); | 317 operationQueue = new ServerOperationQueue(); |
| 312 contextManager = new ContextManagerImpl( | 318 contextManager = new ContextManagerImpl( |
| 313 resourceProvider, | 319 resourceProvider, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 335 onAnalysisComplete.then((_) { | 341 onAnalysisComplete.then((_) { |
| 336 performanceAfterStartup = new ServerPerformance(); | 342 performanceAfterStartup = new ServerPerformance(); |
| 337 _performance = performanceAfterStartup; | 343 _performance = performanceAfterStartup; |
| 338 }); | 344 }); |
| 339 }); | 345 }); |
| 340 Notification notification = | 346 Notification notification = |
| 341 new ServerConnectedParams(VERSION).toNotification(); | 347 new ServerConnectedParams(VERSION).toNotification(); |
| 342 channel.sendNotification(notification); | 348 channel.sendNotification(notification); |
| 343 channel.listen(handleRequest, onDone: done, onError: error); | 349 channel.listen(handleRequest, onDone: done, onError: error); |
| 344 handlers = serverPlugin.createDomains(this); | 350 handlers = serverPlugin.createDomains(this); |
| 351 sdkManager = new DartSdkManager(defaultSdkCreator); |
| 345 } | 352 } |
| 346 | 353 |
| 347 /** | 354 /** |
| 348 * The [Future] that completes when analysis is complete. | 355 * The [Future] that completes when analysis is complete. |
| 349 */ | 356 */ |
| 350 Future get onAnalysisComplete { | 357 Future get onAnalysisComplete { |
| 351 if (isAnalysisComplete()) { | 358 if (isAnalysisComplete()) { |
| 352 return new Future.value(); | 359 return new Future.value(); |
| 353 } | 360 } |
| 354 if (_onAnalysisCompleteCompleter == null) { | 361 if (_onAnalysisCompleteCompleter == null) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 * notify interested parties that the file has been (at least partially) | 427 * notify interested parties that the file has been (at least partially) |
| 421 * analyzed. | 428 * analyzed. |
| 422 */ | 429 */ |
| 423 void fileAnalyzed(ChangeNotice notice) { | 430 void fileAnalyzed(ChangeNotice notice) { |
| 424 if (contextManager.isInAnalysisRoot(notice.source.fullName)) { | 431 if (contextManager.isInAnalysisRoot(notice.source.fullName)) { |
| 425 _onFileAnalyzedController.add(notice); | 432 _onFileAnalyzedController.add(notice); |
| 426 } | 433 } |
| 427 } | 434 } |
| 428 | 435 |
| 429 /** | 436 /** |
| 437 * Return one of the SDKs that has been created, or `null` if no SDKs have |
| 438 * been created yet. |
| 439 */ |
| 440 DartSdk findSdk() { |
| 441 DartSdk sdk = sdkManager.anySdk; |
| 442 if (sdk != null) { |
| 443 return sdk; |
| 444 } |
| 445 // TODO(brianwilkerson) Should we create an SDK using the default options? |
| 446 return null; |
| 447 } |
| 448 |
| 449 /** |
| 430 * Return the preferred [AnalysisContext] for analyzing the given [path]. | 450 * Return the preferred [AnalysisContext] for analyzing the given [path]. |
| 431 * This will be the context that explicitly contains the path, if any such | 451 * This will be the context that explicitly contains the path, if any such |
| 432 * context exists, otherwise it will be the first analysis context that | 452 * context exists, otherwise it will be the first analysis context that |
| 433 * implicitly analyzes it. Return `null` if no context is analyzing the | 453 * implicitly analyzes it. Return `null` if no context is analyzing the |
| 434 * path. | 454 * path. |
| 435 */ | 455 */ |
| 436 AnalysisContext getAnalysisContext(String path) { | 456 AnalysisContext getAnalysisContext(String path) { |
| 437 return getContextSourcePair(path).context; | 457 return getContextSourcePair(path).context; |
| 438 } | 458 } |
| 439 | 459 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 * a `null` context and a `file` [Source] is returned. | 523 * a `null` context and a `file` [Source] is returned. |
| 504 * | 524 * |
| 505 * If the [path] doesn't represent a file, a [ContextSourcePair] with a `null` | 525 * If the [path] doesn't represent a file, a [ContextSourcePair] with a `null` |
| 506 * context and `null` [Source] is returned. | 526 * context and `null` [Source] is returned. |
| 507 * | 527 * |
| 508 * Does not return `null`. | 528 * Does not return `null`. |
| 509 */ | 529 */ |
| 510 ContextSourcePair getContextSourcePair(String path) { | 530 ContextSourcePair getContextSourcePair(String path) { |
| 511 // try SDK | 531 // try SDK |
| 512 { | 532 { |
| 513 Uri uri = resourceProvider.pathContext.toUri(path); | 533 DartSdk sdk = findSdk(); |
| 514 Source sdkSource = defaultSdk.fromFileUri(uri); | 534 if (sdk != null) { |
| 515 if (sdkSource != null) { | 535 Uri uri = resourceProvider.pathContext.toUri(path); |
| 516 AnalysisContext sdkContext = defaultSdk.context; | 536 Source sdkSource = sdk.fromFileUri(uri); |
| 517 return new ContextSourcePair(sdkContext, sdkSource); | 537 if (sdkSource != null) { |
| 538 return new ContextSourcePair(sdk.context, sdkSource); |
| 539 } |
| 518 } | 540 } |
| 519 } | 541 } |
| 520 // try to find the deep-most containing context | 542 // try to find the deep-most containing context |
| 521 Resource resource = resourceProvider.getResource(path); | 543 Resource resource = resourceProvider.getResource(path); |
| 522 if (resource is! File) { | 544 if (resource is! File) { |
| 523 return new ContextSourcePair(null, null); | 545 return new ContextSourcePair(null, null); |
| 524 } | 546 } |
| 525 File file = resource; | 547 File file = resource; |
| 526 { | 548 { |
| 527 AnalysisContext containingContext = getContainingContext(path); | 549 AnalysisContext containingContext = getContainingContext(path); |
| (...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1452 AnalysisEngine.instance.logger.logError( | 1474 AnalysisEngine.instance.logger.logError( |
| 1453 'Invalid glob pattern: "$pattern"', | 1475 'Invalid glob pattern: "$pattern"', |
| 1454 new CaughtException(exception, stackTrace)); | 1476 new CaughtException(exception, stackTrace)); |
| 1455 } | 1477 } |
| 1456 } | 1478 } |
| 1457 } | 1479 } |
| 1458 return _analyzedFilesGlobs; | 1480 return _analyzedFilesGlobs; |
| 1459 } | 1481 } |
| 1460 | 1482 |
| 1461 @override | 1483 @override |
| 1462 AnalysisContext addContext(Folder folder, FolderDisposition disposition) { | 1484 AnalysisOptions get defaultAnalysisOptions => |
| 1485 analysisServer.defaultContextOptions; |
| 1486 |
| 1487 @override |
| 1488 AnalysisContext addContext( |
| 1489 Folder folder, AnalysisOptions options, FolderDisposition disposition) { |
| 1463 InternalAnalysisContext context = | 1490 InternalAnalysisContext context = |
| 1464 AnalysisEngine.instance.createAnalysisContext(); | 1491 AnalysisEngine.instance.createAnalysisContext(); |
| 1465 context.contentCache = analysisServer.overlayState; | 1492 context.contentCache = analysisServer.overlayState; |
| 1466 analysisServer.folderMap[folder] = context; | 1493 analysisServer.folderMap[folder] = context; |
| 1467 _locateEmbedderYamls(context, disposition); | 1494 _locateEmbedderYamls(context, disposition); |
| 1468 context.sourceFactory = _createSourceFactory(context, disposition, folder); | 1495 context.sourceFactory = |
| 1469 context.analysisOptions = | 1496 _createSourceFactory(context, options, disposition, folder); |
| 1470 new AnalysisOptionsImpl.from(analysisServer.defaultContextOptions); | 1497 context.analysisOptions = options; |
| 1471 analysisServer._onContextsChangedController | 1498 analysisServer._onContextsChangedController |
| 1472 .add(new ContextsChangedEvent(added: [context])); | 1499 .add(new ContextsChangedEvent(added: [context])); |
| 1473 analysisServer.schedulePerformAnalysisOperation(context); | 1500 analysisServer.schedulePerformAnalysisOperation(context); |
| 1474 return context; | 1501 return context; |
| 1475 } | 1502 } |
| 1476 | 1503 |
| 1477 @override | 1504 @override |
| 1478 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { | 1505 void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { |
| 1479 AnalysisContext context = analysisServer.folderMap[contextFolder]; | 1506 AnalysisContext context = analysisServer.folderMap[contextFolder]; |
| 1480 if (context != null) { | 1507 if (context != null) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 return file.exists; | 1556 return file.exists; |
| 1530 } | 1557 } |
| 1531 } | 1558 } |
| 1532 return false; | 1559 return false; |
| 1533 } | 1560 } |
| 1534 | 1561 |
| 1535 @override | 1562 @override |
| 1536 void updateContextPackageUriResolver( | 1563 void updateContextPackageUriResolver( |
| 1537 Folder contextFolder, FolderDisposition disposition) { | 1564 Folder contextFolder, FolderDisposition disposition) { |
| 1538 AnalysisContext context = analysisServer.folderMap[contextFolder]; | 1565 AnalysisContext context = analysisServer.folderMap[contextFolder]; |
| 1539 context.sourceFactory = | 1566 context.sourceFactory = _createSourceFactory( |
| 1540 _createSourceFactory(context, disposition, contextFolder); | 1567 context, context.analysisOptions, disposition, contextFolder); |
| 1541 analysisServer._onContextsChangedController | 1568 analysisServer._onContextsChangedController |
| 1542 .add(new ContextsChangedEvent(changed: [context])); | 1569 .add(new ContextsChangedEvent(changed: [context])); |
| 1543 analysisServer.schedulePerformAnalysisOperation(context); | 1570 analysisServer.schedulePerformAnalysisOperation(context); |
| 1544 } | 1571 } |
| 1545 | 1572 |
| 1546 void _computingPackageMap(bool computing) { | 1573 void _computingPackageMap(bool computing) { |
| 1547 if (analysisServer.serverServices.contains(ServerService.STATUS)) { | 1574 if (analysisServer.serverServices.contains(ServerService.STATUS)) { |
| 1548 PubStatus pubStatus = new PubStatus(computing); | 1575 PubStatus pubStatus = new PubStatus(computing); |
| 1549 ServerStatusParams params = new ServerStatusParams(pub: pubStatus); | 1576 ServerStatusParams params = new ServerStatusParams(pub: pubStatus); |
| 1550 analysisServer.sendNotification(params.toNotification()); | 1577 analysisServer.sendNotification(params.toNotification()); |
| 1551 } | 1578 } |
| 1552 } | 1579 } |
| 1553 | 1580 |
| 1554 /** | 1581 /** |
| 1555 * Set up a [SourceFactory] that resolves packages as appropriate for the | 1582 * Set up a [SourceFactory] that resolves packages as appropriate for the |
| 1556 * given [disposition]. | 1583 * given [disposition]. |
| 1557 */ | 1584 */ |
| 1558 SourceFactory _createSourceFactory(InternalAnalysisContext context, | 1585 SourceFactory _createSourceFactory(InternalAnalysisContext context, |
| 1559 FolderDisposition disposition, Folder folder) { | 1586 AnalysisOptions options, FolderDisposition disposition, Folder folder) { |
| 1560 List<UriResolver> resolvers = []; | 1587 List<UriResolver> resolvers = []; |
| 1561 List<UriResolver> packageUriResolvers = | 1588 List<UriResolver> packageUriResolvers = |
| 1562 disposition.createPackageUriResolvers(resourceProvider); | 1589 disposition.createPackageUriResolvers(resourceProvider); |
| 1563 | 1590 |
| 1564 EmbedderUriResolver embedderUriResolver; | 1591 EmbedderUriResolver embedderUriResolver; |
| 1565 | 1592 |
| 1566 // First check for a resolver provider. | 1593 // First check for a resolver provider. |
| 1567 ContextManager contextManager = analysisServer.contextManager; | 1594 ContextManager contextManager = analysisServer.contextManager; |
| 1568 if (contextManager is ContextManagerImpl) { | 1595 if (contextManager is ContextManagerImpl) { |
| 1569 EmbeddedResolverProvider resolverProvider = | 1596 EmbeddedResolverProvider resolverProvider = |
| 1570 contextManager.embeddedUriResolverProvider; | 1597 contextManager.embeddedUriResolverProvider; |
| 1571 if (resolverProvider != null) { | 1598 if (resolverProvider != null) { |
| 1572 embedderUriResolver = resolverProvider(folder); | 1599 embedderUriResolver = resolverProvider(folder); |
| 1573 } | 1600 } |
| 1574 } | 1601 } |
| 1575 | 1602 |
| 1576 // If no embedded URI resolver was provided, defer to a locator-backed one. | 1603 // If no embedded URI resolver was provided, defer to a locator-backed one. |
| 1577 embedderUriResolver ??= | 1604 embedderUriResolver ??= |
| 1578 new EmbedderUriResolver(context.embedderYamlLocator.embedderYamls); | 1605 new EmbedderUriResolver(context.embedderYamlLocator.embedderYamls); |
| 1579 if (embedderUriResolver.length == 0) { | 1606 if (embedderUriResolver.length == 0) { |
| 1580 // The embedder uri resolver has no mappings. Use the default Dart SDK | 1607 // The embedder uri resolver has no mappings. Use the default Dart SDK |
| 1581 // uri resolver. | 1608 // uri resolver. |
| 1582 resolvers.add(new DartUriResolver(analysisServer.defaultSdk)); | 1609 resolvers.add(new DartUriResolver( |
| 1610 analysisServer.sdkManager.getSdkForOptions(options))); |
| 1583 } else { | 1611 } else { |
| 1584 // The embedder uri resolver has mappings, use it instead of the default | 1612 // The embedder uri resolver has mappings, use it instead of the default |
| 1585 // Dart SDK uri resolver. | 1613 // Dart SDK uri resolver. |
| 1586 resolvers.add(embedderUriResolver); | 1614 resolvers.add(embedderUriResolver); |
| 1587 } | 1615 } |
| 1588 | 1616 |
| 1589 resolvers.addAll(packageUriResolvers); | 1617 resolvers.addAll(packageUriResolvers); |
| 1590 resolvers.add(new ResourceUriResolver(resourceProvider)); | 1618 resolvers.add(new ResourceUriResolver(resourceProvider)); |
| 1591 return new SourceFactory(resolvers, disposition.packages); | 1619 return new SourceFactory(resolvers, disposition.packages); |
| 1592 } | 1620 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1699 /** | 1727 /** |
| 1700 * The [PerformanceTag] for time spent in server request handlers. | 1728 * The [PerformanceTag] for time spent in server request handlers. |
| 1701 */ | 1729 */ |
| 1702 static PerformanceTag serverRequests = new PerformanceTag('serverRequests'); | 1730 static PerformanceTag serverRequests = new PerformanceTag('serverRequests'); |
| 1703 | 1731 |
| 1704 /** | 1732 /** |
| 1705 * The [PerformanceTag] for time spent in split store microtasks. | 1733 * The [PerformanceTag] for time spent in split store microtasks. |
| 1706 */ | 1734 */ |
| 1707 static PerformanceTag splitStore = new PerformanceTag('splitStore'); | 1735 static PerformanceTag splitStore = new PerformanceTag('splitStore'); |
| 1708 } | 1736 } |
| OLD | NEW |