| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 import 'dart:collection'; | 6 import 'dart:collection'; |
| 7 import 'dart:convert'; | 7 import 'dart:convert'; |
| 8 import 'dart:io' show Platform, Process, ProcessResult; | 8 import 'dart:io' show Platform, Process, ProcessResult; |
| 9 | 9 |
| 10 import 'package:analysis_server/src/plugin/notification_manager.dart'; | 10 import 'package:analysis_server/src/plugin/notification_manager.dart'; |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 * The object used to manage the receiving and sending of notifications. | 284 * The object used to manage the receiving and sending of notifications. |
| 285 */ | 285 */ |
| 286 final NotificationManager notificationManager; | 286 final NotificationManager notificationManager; |
| 287 | 287 |
| 288 /** | 288 /** |
| 289 * The instrumentation service that is being used by the analysis server. | 289 * The instrumentation service that is being used by the analysis server. |
| 290 */ | 290 */ |
| 291 final InstrumentationService instrumentationService; | 291 final InstrumentationService instrumentationService; |
| 292 | 292 |
| 293 /** | 293 /** |
| 294 * The list of globs used to match plugin paths that have been whitelisted. | |
| 295 */ | |
| 296 List<Glob> _whitelistGlobs; | |
| 297 | |
| 298 /** | |
| 299 * A table mapping the paths of plugins to information about those plugins. | 294 * A table mapping the paths of plugins to information about those plugins. |
| 300 */ | 295 */ |
| 301 Map<String, PluginInfo> _pluginMap = <String, PluginInfo>{}; | 296 Map<String, PluginInfo> _pluginMap = <String, PluginInfo>{}; |
| 302 | 297 |
| 303 /** | 298 /** |
| 304 * The parameters for the last 'analysis.setPriorityFiles' request that was | 299 * The parameters for the last 'analysis.setPriorityFiles' request that was |
| 305 * received from the client. Because plugins are lazily discovered, this needs | 300 * received from the client. Because plugins are lazily discovered, this needs |
| 306 * to be retained so that it can be sent after a plugin has been started. | 301 * to be retained so that it can be sent after a plugin has been started. |
| 307 */ | 302 */ |
| 308 AnalysisSetPriorityFilesParams _analysisSetPriorityFilesParams; | 303 AnalysisSetPriorityFilesParams _analysisSetPriorityFilesParams; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 319 * discovered, the state needs to be retained so that it can be sent after a | 314 * discovered, the state needs to be retained so that it can be sent after a |
| 320 * plugin has been started. | 315 * plugin has been started. |
| 321 */ | 316 */ |
| 322 Map<String, dynamic> _overlayState = <String, dynamic>{}; | 317 Map<String, dynamic> _overlayState = <String, dynamic>{}; |
| 323 | 318 |
| 324 /** | 319 /** |
| 325 * Initialize a newly created plugin manager. The notifications from the | 320 * Initialize a newly created plugin manager. The notifications from the |
| 326 * running plugins will be handled by the given [notificationManager]. | 321 * running plugins will be handled by the given [notificationManager]. |
| 327 */ | 322 */ |
| 328 PluginManager(this.resourceProvider, this.byteStorePath, this.sdkPath, | 323 PluginManager(this.resourceProvider, this.byteStorePath, this.sdkPath, |
| 329 this.notificationManager, this.instrumentationService) { | 324 this.notificationManager, this.instrumentationService); |
| 330 // TODO(brianwilkerson) Figure out the right list of plugin paths. | |
| 331 _whitelistGlobs = <Glob>[ | |
| 332 new Glob(resourceProvider.pathContext.separator, | |
| 333 '**/angular_analyzer_plugin/tools/analyzer_plugin'), | |
| 334 new Glob(resourceProvider.pathContext.separator, | |
| 335 '**angular/tools/analyzer_plugin') | |
| 336 ]; | |
| 337 } | |
| 338 | 325 |
| 339 /** | 326 /** |
| 340 * Return a list of all of the plugins that are currently known. | 327 * Return a list of all of the plugins that are currently known. |
| 341 */ | 328 */ |
| 342 @visibleForTesting | 329 @visibleForTesting |
| 343 List<PluginInfo> get plugins => _pluginMap.values.toList(); | 330 List<PluginInfo> get plugins => _pluginMap.values.toList(); |
| 344 | 331 |
| 345 /** | 332 /** |
| 346 * Add the plugin with the given [path] to the list of plugins that should be | 333 * Add the plugin with the given [path] to the list of plugins that should be |
| 347 * used when analyzing code for the given [contextRoot]. If the plugin had not | 334 * used when analyzing code for the given [contextRoot]. If the plugin had not |
| 348 * yet been started, then it will be started by this method. | 335 * yet been started, then it will be started by this method. |
| 349 */ | 336 */ |
| 350 Future<Null> addPluginToContextRoot( | 337 Future<Null> addPluginToContextRoot( |
| 351 analyzer.ContextRoot contextRoot, String path) async { | 338 analyzer.ContextRoot contextRoot, String path) async { |
| 352 if (!_isWhitelisted(path)) { | |
| 353 return; | |
| 354 } | |
| 355 PluginInfo plugin = _pluginMap[path]; | 339 PluginInfo plugin = _pluginMap[path]; |
| 356 bool isNew = plugin == null; | 340 bool isNew = plugin == null; |
| 357 if (isNew) { | 341 if (isNew) { |
| 358 List<String> pluginPaths = pathsFor(path); | 342 List<String> pluginPaths = pathsFor(path); |
| 359 if (pluginPaths == null) { | 343 if (pluginPaths == null) { |
| 360 return; | 344 return; |
| 361 } | 345 } |
| 362 plugin = new DiscoveredPluginInfo(path, pluginPaths[0], pluginPaths[1], | 346 plugin = new DiscoveredPluginInfo(path, pluginPaths[0], pluginPaths[1], |
| 363 notificationManager, instrumentationService); | 347 notificationManager, instrumentationService); |
| 364 _pluginMap[path] = plugin; | 348 _pluginMap[path] = plugin; |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 606 } | 590 } |
| 607 | 591 |
| 608 /** | 592 /** |
| 609 * Stop all of the plugins that are currently running. | 593 * Stop all of the plugins that are currently running. |
| 610 */ | 594 */ |
| 611 Future<List<Null>> stopAll() { | 595 Future<List<Null>> stopAll() { |
| 612 return Future.wait(_pluginMap.values.map((PluginInfo info) => info.stop())); | 596 return Future.wait(_pluginMap.values.map((PluginInfo info) => info.stop())); |
| 613 } | 597 } |
| 614 | 598 |
| 615 /** | 599 /** |
| 616 * Whitelist all plugins. | |
| 617 */ | |
| 618 @visibleForTesting | |
| 619 void whitelistEverything() { | |
| 620 _whitelistGlobs = <Glob>[ | |
| 621 new Glob(resourceProvider.pathContext.separator, '**/*') | |
| 622 ]; | |
| 623 } | |
| 624 | |
| 625 /** | |
| 626 * Compute the paths to be returned by the enclosing method given that the | 600 * Compute the paths to be returned by the enclosing method given that the |
| 627 * plugin should exist in the given [pluginFolder]. | 601 * plugin should exist in the given [pluginFolder]. |
| 628 */ | 602 */ |
| 629 List<String> _computePaths(Folder pluginFolder, | 603 List<String> _computePaths(Folder pluginFolder, |
| 630 {bool runPub: false, Workspace workspace}) { | 604 {bool runPub: false, Workspace workspace}) { |
| 631 File pluginFile = pluginFolder | 605 File pluginFile = pluginFolder |
| 632 .getChildAssumingFolder('bin') | 606 .getChildAssumingFolder('bin') |
| 633 .getChildAssumingFile('plugin.dart'); | 607 .getChildAssumingFile('plugin.dart'); |
| 634 if (!pluginFile.exists) { | 608 if (!pluginFile.exists) { |
| 635 return null; | 609 return null; |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 734 } catch (exception) { | 708 } catch (exception) { |
| 735 // If we are not able to produce a .packages file, return null so that | 709 // If we are not able to produce a .packages file, return null so that |
| 736 // callers will not try to load the plugin. | 710 // callers will not try to load the plugin. |
| 737 return null; | 711 return null; |
| 738 } | 712 } |
| 739 } | 713 } |
| 740 return packagesFile; | 714 return packagesFile; |
| 741 } | 715 } |
| 742 | 716 |
| 743 /** | 717 /** |
| 744 * Return `true` if the plugin with the given [path] has been whitelisted. | |
| 745 */ | |
| 746 bool _isWhitelisted(String path) { | |
| 747 for (Glob glob in _whitelistGlobs) { | |
| 748 if (glob.matches(path)) { | |
| 749 return true; | |
| 750 } | |
| 751 } | |
| 752 return false; | |
| 753 } | |
| 754 | |
| 755 /** | |
| 756 * Return the names of packages that are listed as dependencies in the given | 718 * Return the names of packages that are listed as dependencies in the given |
| 757 * [pubspecFile]. | 719 * [pubspecFile]. |
| 758 */ | 720 */ |
| 759 Iterable<String> _readDependecies(File pubspecFile) { | 721 Iterable<String> _readDependecies(File pubspecFile) { |
| 760 YamlDocument document = loadYamlDocument(pubspecFile.readAsStringSync(), | 722 YamlDocument document = loadYamlDocument(pubspecFile.readAsStringSync(), |
| 761 sourceUrl: pubspecFile.toUri()); | 723 sourceUrl: pubspecFile.toUri()); |
| 762 YamlNode contents = document.contents; | 724 YamlNode contents = document.contents; |
| 763 if (contents is YamlMap) { | 725 if (contents is YamlMap) { |
| 764 YamlNode dependencies = contents['dependencies']; | 726 YamlNode dependencies = contents['dependencies']; |
| 765 if (dependencies is YamlMap) { | 727 if (dependencies is YamlMap) { |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1040 * The completer that will be used to complete the future when the response is | 1002 * The completer that will be used to complete the future when the response is |
| 1041 * received from the plugin. | 1003 * received from the plugin. |
| 1042 */ | 1004 */ |
| 1043 final Completer<Response> completer; | 1005 final Completer<Response> completer; |
| 1044 | 1006 |
| 1045 /** | 1007 /** |
| 1046 * Initialize a pending request. | 1008 * Initialize a pending request. |
| 1047 */ | 1009 */ |
| 1048 _PendingRequest(this.method, this.requestTime, this.completer); | 1010 _PendingRequest(this.method, this.requestTime, this.completer); |
| 1049 } | 1011 } |
| OLD | NEW |