| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 analyzer.src.plugin.plugin_configuration; | 5 library analyzer.src.plugin.plugin_configuration; |
| 6 | 6 |
| 7 import 'package:analyzer/plugin/options.dart'; | 7 import 'package:analyzer/plugin/options.dart'; |
| 8 import 'package:yaml/yaml.dart'; | 8 import 'package:yaml/yaml.dart'; |
| 9 | 9 |
| 10 const _analyzerOptionScope = 'analyzer'; | 10 const _analyzerOptionScope = 'analyzer'; |
| 11 | 11 |
| 12 const _pluginOptionScope = 'plugins'; | 12 const _pluginOptionScope = 'plugins'; |
| 13 | 13 |
| 14 /// Parse the given string into a plugin manifest. |
| 15 PluginManifest parsePluginManifestString(String manifestSource) { |
| 16 var yaml = loadYaml(manifestSource); |
| 17 if (yaml == null) { |
| 18 return null; |
| 19 } |
| 20 _verifyMap(yaml, 'plugin manifest'); |
| 21 Iterable<String> pluginHost = _parseHosts(yaml['contributes_to']); |
| 22 PluginInfo plugin = _parsePlugin(yaml); |
| 23 return new PluginManifest(contributesTo: pluginHost, plugin: plugin); |
| 24 } |
| 25 |
| 26 String _asString(dynamic yaml) { |
| 27 if (yaml != null && yaml is! String) { |
| 28 throw new PluginConfigFormatException( |
| 29 'Unable to parse pugin manifest, ' |
| 30 'expected `String`, got `${yaml.runtimeType}`', |
| 31 yaml); |
| 32 } |
| 33 return yaml; |
| 34 } |
| 35 |
| 36 Iterable<String> _parseHosts(dynamic yaml) { |
| 37 List<String> hosts = <String>[]; |
| 38 if (yaml is String) { |
| 39 hosts.add(yaml); |
| 40 } else if (yaml is YamlList) { |
| 41 yaml.forEach((h) { |
| 42 hosts.add(_asString(h)); |
| 43 }); |
| 44 } |
| 45 return hosts; |
| 46 } |
| 47 |
| 48 PluginInfo _parsePlugin(dynamic yaml) { |
| 49 if (yaml != null) { |
| 50 _verifyMap(yaml, 'plugin manifest'); |
| 51 return new PluginInfo._fromYaml(details: yaml); |
| 52 } |
| 53 return null; |
| 54 } |
| 55 |
| 14 PluginInfo _processPluginMapping(dynamic name, dynamic details) { | 56 PluginInfo _processPluginMapping(dynamic name, dynamic details) { |
| 15 if (name is String) { | 57 if (name is String) { |
| 16 if (details is String) { | 58 if (details is String) { |
| 17 return new PluginInfo(name: name, version: details); | 59 return new PluginInfo(name: name, version: details); |
| 18 } | 60 } |
| 19 if (details is YamlMap) { | 61 if (details is YamlMap) { |
| 20 return new PluginInfo( | 62 return new PluginInfo._fromYaml(name: name, details: details); |
| 21 name: name, | |
| 22 version: details['version'], | |
| 23 className: details['class_name'], | |
| 24 libraryUri: details['library_uri'], | |
| 25 packageName: details['package_name'], | |
| 26 path: details['path']); | |
| 27 } | 63 } |
| 28 } | 64 } |
| 29 | 65 |
| 30 return null; | 66 return null; |
| 31 } | 67 } |
| 32 | 68 |
| 69 _verifyMap(dynamic yaml, String context) { |
| 70 if (yaml is! YamlMap) { |
| 71 throw new PluginConfigFormatException( |
| 72 'Unable to parse $context, ' |
| 73 'expected `YamlMap`, got `${yaml.runtimeType}`', |
| 74 yaml); |
| 75 } |
| 76 } |
| 77 |
| 33 /// A callback for error handling. | 78 /// A callback for error handling. |
| 34 typedef ErrorHandler(Exception e); | 79 typedef ErrorHandler(Exception e); |
| 35 | 80 |
| 36 /// Describes plugin configuration information as extracted from an | 81 /// Describes plugin configuration information as extracted from an |
| 37 /// analysis options map. | 82 /// analysis options map or plugin manifest. |
| 38 class PluginConfig { | 83 class PluginConfig { |
| 39 final Iterable<PluginInfo> plugins; | 84 final Iterable<PluginInfo> plugins; |
| 40 PluginConfig(this.plugins); | 85 PluginConfig(this.plugins); |
| 41 | 86 |
| 42 /// Create a plugin configuration from an options map. | 87 /// Create a plugin configuration from an options map. |
| 43 factory PluginConfig.fromOptions(Map<String, YamlNode> options) { | 88 factory PluginConfig.fromOptions(Map<String, YamlNode> options) { |
| 44 List<PluginInfo> plugins = []; | 89 List<PluginInfo> plugins = []; |
| 45 var analyzerOptions = options[_analyzerOptionScope]; | 90 var analyzerOptions = options[_analyzerOptionScope]; |
| 46 if (analyzerOptions != null) { | 91 if (analyzerOptions != null) { |
| 47 if (analyzerOptions is YamlMap) { | 92 if (analyzerOptions is YamlMap) { |
| 48 var pluginConfig = analyzerOptions[_pluginOptionScope]; | 93 var pluginConfig = analyzerOptions[_pluginOptionScope]; |
| 49 if (pluginConfig is YamlMap) { | 94 if (pluginConfig is YamlMap) { |
| 50 pluginConfig.forEach((name, details) { | 95 pluginConfig.forEach((name, details) { |
| 51 var plugin = _processPluginMapping(name, details); | 96 var plugin = _processPluginMapping(name, details); |
| 52 if (plugin != null) { | 97 if (plugin != null) { |
| 53 plugins.add(plugin); | 98 plugins.add(plugin); |
| 54 } | 99 } |
| 55 }); | 100 }); |
| 56 } else { | 101 } else { |
| 57 // Anything but an empty list of plugins is treated as a format error. | 102 // Anything but an empty list of plugins is treated as a format error. |
| 58 if (pluginConfig != null) { | 103 if (pluginConfig != null) { |
| 59 throw new PluginConfigFormatException( | 104 throw new PluginConfigFormatException( |
| 60 'Unrecognized plugin config format (expected `YamlMap`, got `${p
luginConfig.runtimeType}`)', | 105 'Unrecognized plugin config format, expected `YamlMap`, got `${p
luginConfig.runtimeType}`', |
| 61 pluginConfig); | 106 pluginConfig); |
| 62 } | 107 } |
| 63 } | 108 } |
| 64 } | 109 } |
| 65 } | 110 } |
| 66 | 111 |
| 67 return new PluginConfig(plugins); | 112 return new PluginConfig(plugins); |
| 68 } | 113 } |
| 69 } | 114 } |
| 70 | 115 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 final String libraryUri; | 155 final String libraryUri; |
| 111 final String packageName; | 156 final String packageName; |
| 112 final String path; | 157 final String path; |
| 113 PluginInfo( | 158 PluginInfo( |
| 114 {this.name, | 159 {this.name, |
| 115 this.version, | 160 this.version, |
| 116 this.className, | 161 this.className, |
| 117 this.libraryUri, | 162 this.libraryUri, |
| 118 this.packageName, | 163 this.packageName, |
| 119 this.path}); | 164 this.path}); |
| 165 |
| 166 factory PluginInfo._fromYaml({String name, YamlMap details}) => |
| 167 new PluginInfo( |
| 168 name: name, |
| 169 version: _asString(details['version']), |
| 170 className: _asString(details['class_name']), |
| 171 libraryUri: _asString(details['library_uri']), |
| 172 packageName: _asString(details['package_name']), |
| 173 path: _asString(details['path'])); |
| 120 } | 174 } |
| 175 |
| 176 /// Plugin manifests accompany plugin packages, providing |
| 177 /// configuration information for published plugins. |
| 178 /// |
| 179 /// Provisionally, plugin manifests live in a file `plugin.yaml` |
| 180 /// at the root of the plugin package. |
| 181 /// |
| 182 /// my_plugin/ |
| 183 /// bin/ |
| 184 /// lib/ |
| 185 /// plugin.yaml |
| 186 /// pubspec.yaml |
| 187 /// |
| 188 /// Provisional manifest file format: |
| 189 /// |
| 190 /// class_name: MyAnalyzerPlugin |
| 191 /// library_uri: 'my_plugin/my_analyzer_plugin.dart' |
| 192 /// contributes_to: analyzer |
| 193 class PluginManifest { |
| 194 PluginInfo plugin; |
| 195 Iterable<String> contributesTo; |
| 196 PluginManifest({this.plugin, this.contributesTo}); |
| 197 } |
| OLD | NEW |