@@ -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,16 @@ 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" ) ;
122142 }
123143 "macro_use" => {
124144 let names = attr. meta_item_list ( ) ;
@@ -160,10 +180,7 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
160180 }
161181 }
162182
163- self . load_plugin ( CrateOrString :: Krate ( item) ,
164- plugin_attr,
165- macro_selection,
166- Some ( reexport) )
183+ self . load_macros ( item, macro_selection, Some ( reexport) )
167184 }
168185
169186 fn visit_mac ( & mut self , _: & ast:: Mac ) {
@@ -173,38 +190,25 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
173190}
174191
175192impl < ' a > PluginLoader < ' a > {
176- pub fn load_plugin < ' b > ( & mut self ,
177- c : CrateOrString < ' b > ,
178- plugin_attr : Option < P < ast:: MetaItem > > ,
193+ pub fn load_macros < ' b > ( & mut self ,
194+ vi : & ast:: Item ,
179195 macro_selection : Option < HashSet < token:: InternedString > > ,
180196 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") ;
197+ if let ( Some ( sel) , Some ( re) ) = ( macro_selection. as_ref ( ) , reexport. as_ref ( ) ) {
198+ if sel. is_empty ( ) && re. is_empty ( ) {
199+ return ;
194200 }
195- }
201+ }
196202
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- }
203+ if !self . span_whitelist . contains ( & vi. span ) {
204+ self . sess . span_err ( vi. span , "an `extern crate` loading macros must be at \
205+ the crate root") ;
206+ return ;
205207 }
206208
207- for mut def in macros {
209+ let pmd = self . reader . read_plugin_metadata ( CrateOrString :: Krate ( vi) ) ;
210+
211+ for mut def in pmd. exported_macros ( ) {
208212 let name = token:: get_ident ( def. ident ) ;
209213 def. use_locally = match macro_selection. as_ref ( ) {
210214 None => true ,
@@ -217,12 +221,21 @@ impl<'a> PluginLoader<'a> {
217221 } ;
218222 self . plugins . macros . push ( def) ;
219223 }
224+ }
225+
226+ pub fn load_plugin < ' b > ( & mut self ,
227+ c : CrateOrString < ' b > ,
228+ args : Vec < P < ast:: MetaItem > > ) {
229+ let registrar = {
230+ let pmd = self . reader . read_plugin_metadata ( c) ;
231+ pmd. plugin_registrar ( )
232+ } ;
220233
221234 if let Some ( ( lib, symbol) ) = registrar {
222235 let fun = self . dylink_registrar ( c, lib, symbol) ;
223236 self . plugins . registrars . push ( PluginRegistrar {
224237 fun : fun,
225- args : plugin_attr . unwrap ( ) ,
238+ args : args ,
226239 } ) ;
227240 }
228241 }
0 commit comments