@@ -18,9 +18,10 @@ use std::mem;
1818use std:: env;
1919use std:: dynamic_lib:: DynamicLibrary ;
2020use std:: collections:: HashSet ;
21+ use std:: borrow:: ToOwned ;
2122use syntax:: ast;
2223use syntax:: attr;
23- use syntax:: codemap:: Span ;
24+ use syntax:: codemap:: { Span , COMMAND_LINE_SP } ;
2425use syntax:: parse:: token;
2526use syntax:: ptr:: P ;
2627use syntax:: visit;
@@ -33,7 +34,7 @@ pub type PluginRegistrarFun =
3334
3435pub struct PluginRegistrar {
3536 pub fun : PluginRegistrarFun ,
36- pub args : P < ast:: MetaItem > ,
37+ pub args : Vec < P < ast:: MetaItem > > ,
3738}
3839
3940/// Information about loaded plugins.
@@ -81,10 +82,34 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
8182
8283 visit:: walk_crate ( & mut loader, krate) ;
8384
85+ for attr in & krate. attrs {
86+ if !attr. check_name ( "plugin" ) {
87+ continue ;
88+ }
89+
90+ let plugins = match attr. meta_item_list ( ) {
91+ Some ( xs) => xs,
92+ None => {
93+ sess. span_err ( attr. span , "malformed plugin attribute" ) ;
94+ continue ;
95+ }
96+ } ;
97+
98+ for plugin in plugins {
99+ if plugin. value_str ( ) . is_some ( ) {
100+ sess. span_err ( attr. span , "malformed plugin attribute" ) ;
101+ continue ;
102+ }
103+
104+ let args = plugin. meta_item_list ( ) . map ( ToOwned :: to_owned) . unwrap_or_default ( ) ;
105+ loader. load_plugin ( CrateOrString :: Str ( plugin. span , & * plugin. name ( ) ) ,
106+ args) ;
107+ }
108+ }
109+
84110 if let Some ( plugins) = addl_plugins {
85111 for plugin in plugins {
86- loader. load_plugin ( CrateOrString :: Str ( & plugin) ,
87- None , None , None )
112+ loader. load_plugin ( CrateOrString :: Str ( COMMAND_LINE_SP , & plugin) , vec ! [ ] ) ;
88113 }
89114 }
90115
@@ -104,21 +129,19 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
104129 }
105130
106131 // Parse the attributes relating to macro / plugin loading.
107- let mut plugin_attr = None ;
108132 let mut macro_selection = Some ( HashSet :: new ( ) ) ; // None => load all
109133 let mut reexport = HashSet :: new ( ) ;
110134 for attr in & item. attrs {
111135 let mut used = true ;
112136 match & attr. name ( ) [ ] {
113137 "phase" => {
114- self . sess . span_err ( attr. span , "#[phase] is deprecated; use \
115- #[macro_use], #[plugin], and/or #[no_link]") ;
138+ self . sess . span_err ( attr. span , "#[phase] is deprecated" ) ;
116139 }
117140 "plugin" => {
118- if plugin_attr . is_some ( ) {
119- self . sess . span_err ( attr. span , "#[plugin] specified multiple times" ) ;
120- }
121- plugin_attr = Some ( attr . node . value . clone ( ) ) ;
141+ self . sess . span_err ( attr . span , "#[plugin] on `extern crate` is deprecated" ) ;
142+ self . sess . span_help ( attr. span , & format ! ( "use a crate attribute instead, \
143+ i.e. #![plugin({})]" ,
144+ item . ident . as_str ( ) ) [ ] ) ;
122145 }
123146 "macro_use" => {
124147 let names = attr. meta_item_list ( ) ;
@@ -160,10 +183,7 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
160183 }
161184 }
162185
163- self . load_plugin ( CrateOrString :: Krate ( item) ,
164- plugin_attr,
165- macro_selection,
166- Some ( reexport) )
186+ self . load_macros ( item, macro_selection, Some ( reexport) )
167187 }
168188
169189 fn visit_mac ( & mut self , _: & ast:: Mac ) {
@@ -173,38 +193,25 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
173193}
174194
175195impl < ' a > PluginLoader < ' a > {
176- pub fn load_plugin < ' b > ( & mut self ,
177- c : CrateOrString < ' b > ,
178- plugin_attr : Option < P < ast:: MetaItem > > ,
196+ pub fn load_macros < ' b > ( & mut self ,
197+ vi : & ast:: Item ,
179198 macro_selection : Option < HashSet < token:: InternedString > > ,
180199 reexport : Option < HashSet < token:: InternedString > > ) {
181- let mut macros = vec ! [ ] ;
182- let mut registrar = None ;
183-
184- let load_macros = match ( macro_selection. as_ref ( ) , reexport. as_ref ( ) ) {
185- ( Some ( sel) , Some ( re) ) => sel. len ( ) != 0 || re. len ( ) != 0 ,
186- _ => true ,
187- } ;
188- let load_registrar = plugin_attr. is_some ( ) ;
189-
190- if let CrateOrString :: Krate ( vi) = c {
191- if load_macros && !self . span_whitelist . contains ( & vi. span ) {
192- self . sess . span_err ( vi. span , "an `extern crate` loading macros must be at \
193- the crate root") ;
200+ if let ( Some ( sel) , Some ( re) ) = ( macro_selection. as_ref ( ) , reexport. as_ref ( ) ) {
201+ if sel. is_empty ( ) && re. is_empty ( ) {
202+ return ;
194203 }
195- }
204+ }
196205
197- if load_macros || load_registrar {
198- let pmd = self . reader . read_plugin_metadata ( c) ;
199- if load_macros {
200- macros = pmd. exported_macros ( ) ;
201- }
202- if load_registrar {
203- registrar = pmd. plugin_registrar ( ) ;
204- }
206+ if !self . span_whitelist . contains ( & vi. span ) {
207+ self . sess . span_err ( vi. span , "an `extern crate` loading macros must be at \
208+ the crate root") ;
209+ return ;
205210 }
206211
207- for mut def in macros {
212+ let pmd = self . reader . read_plugin_metadata ( CrateOrString :: Krate ( vi) ) ;
213+
214+ for mut def in pmd. exported_macros ( ) {
208215 let name = token:: get_ident ( def. ident ) ;
209216 def. use_locally = match macro_selection. as_ref ( ) {
210217 None => true ,
@@ -217,12 +224,21 @@ impl<'a> PluginLoader<'a> {
217224 } ;
218225 self . plugins . macros . push ( def) ;
219226 }
227+ }
228+
229+ pub fn load_plugin < ' b > ( & mut self ,
230+ c : CrateOrString < ' b > ,
231+ args : Vec < P < ast:: MetaItem > > ) {
232+ let registrar = {
233+ let pmd = self . reader . read_plugin_metadata ( c) ;
234+ pmd. plugin_registrar ( )
235+ } ;
220236
221237 if let Some ( ( lib, symbol) ) = registrar {
222238 let fun = self . dylink_registrar ( c, lib, symbol) ;
223239 self . plugins . registrars . push ( PluginRegistrar {
224240 fun : fun,
225- args : plugin_attr . unwrap ( ) ,
241+ args : args ,
226242 } ) ;
227243 }
228244 }
0 commit comments