11
11
//! Used by `rustc` when loading a plugin, or a crate with exported macros.
12
12
13
13
use session:: Session ;
14
- use metadata:: creader:: CrateReader ;
14
+ use metadata:: creader:: { CrateOrString , CrateReader } ;
15
15
use plugin:: registry:: Registry ;
16
16
17
17
use std:: mem;
@@ -44,11 +44,11 @@ pub struct Plugins {
44
44
pub registrars : Vec < PluginRegistrar > ,
45
45
}
46
46
47
- struct PluginLoader < ' a > {
47
+ pub struct PluginLoader < ' a > {
48
48
sess : & ' a Session ,
49
49
span_whitelist : HashSet < Span > ,
50
50
reader : CrateReader < ' a > ,
51
- plugins : Plugins ,
51
+ pub plugins : Plugins ,
52
52
}
53
53
54
54
impl < ' a > PluginLoader < ' a > {
@@ -67,7 +67,7 @@ impl<'a> PluginLoader<'a> {
67
67
68
68
/// Read plugin metadata and dynamically load registrar functions.
69
69
pub fn load_plugins ( sess : & Session , krate : & ast:: Crate ,
70
- addl_plugins : Option < Plugins > ) -> Plugins {
70
+ addl_plugins : Option < Vec < String > > ) -> Plugins {
71
71
let mut loader = PluginLoader :: new ( sess) ;
72
72
73
73
// We need to error on `#[macro_use] extern crate` when it isn't at the
@@ -79,19 +79,14 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
79
79
80
80
visit:: walk_crate ( & mut loader, krate) ;
81
81
82
- let mut plugins = loader. plugins ;
83
-
84
- match addl_plugins {
85
- Some ( addl_plugins) => {
86
- // Add in the additional plugins requested by the frontend
87
- let Plugins { macros : addl_macros, registrars : addl_registrars } = addl_plugins;
88
- plugins. macros . extend ( addl_macros. into_iter ( ) ) ;
89
- plugins. registrars . extend ( addl_registrars. into_iter ( ) ) ;
82
+ if let Some ( plugins) = addl_plugins {
83
+ for plugin in plugins. iter ( ) {
84
+ loader. load_plugin ( CrateOrString :: Str ( plugin. as_slice ( ) ) ,
85
+ None , None , None )
90
86
}
91
- None => ( )
92
87
}
93
88
94
- return plugins;
89
+ return loader . plugins ;
95
90
}
96
91
97
92
// note that macros aren't expanded yet, and therefore macros can't add plugins.
@@ -160,22 +155,39 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
160
155
}
161
156
}
162
157
158
+ self . load_plugin ( CrateOrString :: Krate ( vi) , plugin_attr, macro_selection, Some ( reexport) )
159
+ }
160
+
161
+ fn visit_mac ( & mut self , _: & ast:: Mac ) {
162
+ // bummer... can't see plugins inside macros.
163
+ // do nothing.
164
+ }
165
+ }
166
+
167
+ impl < ' a > PluginLoader < ' a > {
168
+ pub fn load_plugin < ' b > ( & mut self ,
169
+ c : CrateOrString < ' b > ,
170
+ plugin_attr : Option < P < ast:: MetaItem > > ,
171
+ macro_selection : Option < HashSet < token:: InternedString > > ,
172
+ reexport : Option < HashSet < token:: InternedString > > ) {
163
173
let mut macros = vec ! [ ] ;
164
174
let mut registrar = None ;
165
175
166
- let load_macros = match macro_selection. as_ref ( ) {
167
- Some ( sel) => sel. len ( ) != 0 || reexport . len ( ) != 0 ,
168
- None => true ,
176
+ let load_macros = match ( macro_selection. as_ref ( ) , reexport . as_ref ( ) ) {
177
+ ( Some ( sel) , Some ( re ) ) => sel. len ( ) != 0 || re . len ( ) != 0 ,
178
+ _ => true ,
169
179
} ;
170
180
let load_registrar = plugin_attr. is_some ( ) ;
171
181
172
- if load_macros && !self . span_whitelist . contains ( & vi. span ) {
173
- self . sess . span_err ( vi. span , "an `extern crate` loading macros must be at \
174
- the crate root") ;
175
- }
182
+ if let CrateOrString :: Krate ( vi) = c {
183
+ if load_macros && !self . span_whitelist . contains ( & vi. span ) {
184
+ self . sess . span_err ( vi. span , "an `extern crate` loading macros must be at \
185
+ the crate root") ;
186
+ }
187
+ }
176
188
177
189
if load_macros || load_registrar {
178
- let pmd = self . reader . read_plugin_metadata ( vi ) ;
190
+ let pmd = self . reader . read_plugin_metadata ( c ) ;
179
191
if load_macros {
180
192
macros = pmd. exported_macros ( ) ;
181
193
}
@@ -190,29 +202,26 @@ impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
190
202
None => true ,
191
203
Some ( sel) => sel. contains ( & name) ,
192
204
} ;
193
- def. export = reexport. contains ( & name) ;
205
+ def. export = if let Some ( ref re) = reexport {
206
+ re. contains ( & name)
207
+ } else {
208
+ false // Don't reexport macros from crates loaded from the command line
209
+ } ;
194
210
self . plugins . macros . push ( def) ;
195
211
}
196
212
197
213
if let Some ( ( lib, symbol) ) = registrar {
198
- let fun = self . dylink_registrar ( vi , lib, symbol) ;
214
+ let fun = self . dylink_registrar ( c , lib, symbol) ;
199
215
self . plugins . registrars . push ( PluginRegistrar {
200
216
fun : fun,
201
217
args : plugin_attr. unwrap ( ) ,
202
218
} ) ;
203
219
}
204
220
}
205
221
206
- fn visit_mac ( & mut self , _: & ast:: Mac ) {
207
- // bummer... can't see plugins inside macros.
208
- // do nothing.
209
- }
210
- }
211
-
212
- impl < ' a > PluginLoader < ' a > {
213
222
// Dynamically link a registrar function into the compiler process.
214
- fn dylink_registrar ( & mut self ,
215
- vi : & ast :: ViewItem ,
223
+ fn dylink_registrar < ' b > ( & mut self ,
224
+ c : CrateOrString < ' b > ,
216
225
path : Path ,
217
226
symbol : String ) -> PluginRegistrarFun {
218
227
// Make sure the path contains a / or the linker will search for it.
@@ -223,7 +232,13 @@ impl<'a> PluginLoader<'a> {
223
232
// this is fatal: there are almost certainly macros we need
224
233
// inside this crate, so continue would spew "macro undefined"
225
234
// errors
226
- Err ( err) => self . sess . span_fatal ( vi. span , & err[ ] )
235
+ Err ( err) => {
236
+ if let CrateOrString :: Krate ( cr) = c {
237
+ self . sess . span_fatal ( cr. span , & err[ ] )
238
+ } else {
239
+ self . sess . fatal ( & err[ ] )
240
+ }
241
+ }
227
242
} ;
228
243
229
244
unsafe {
@@ -233,7 +248,13 @@ impl<'a> PluginLoader<'a> {
233
248
mem:: transmute :: < * mut u8 , PluginRegistrarFun > ( registrar)
234
249
}
235
250
// again fatal if we can't register macros
236
- Err ( err) => self . sess . span_fatal ( vi. span , & err[ ] )
251
+ Err ( err) => {
252
+ if let CrateOrString :: Krate ( cr) = c {
253
+ self . sess . span_fatal ( cr. span , & err[ ] )
254
+ } else {
255
+ self . sess . fatal ( & err[ ] )
256
+ }
257
+ }
237
258
} ;
238
259
239
260
// Intentionally leak the dynamic library. We can't ever unload it
0 commit comments