1 //! Used by plugin crates to tell `rustc` about the plugins they provide.
3 use rustc::lint::LintStore;
4 use rustc::session::Session;
6 use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
7 use syntax_expand::base::MacroExpanderFn;
8 use syntax::symbol::Symbol;
10 use syntax::feature_gate::AttributeType;
13 use std::borrow::ToOwned;
15 /// Structure used to register plugins.
17 /// A plugin registrar function takes an `&mut Registry` and should call
18 /// methods to register its plugins.
20 /// This struct has public fields and other methods for use by `rustc`
21 /// itself. They are not documented here, and plugin authors should
23 pub struct Registry<'a> {
24 /// Compiler session. Useful if you want to emit diagnostic messages
25 /// from the plugin registrar.
26 pub sess: &'a Session,
28 /// The `LintStore` allows plugins to register new lints.
29 pub lint_store: &'a mut LintStore,
32 pub args_hidden: Option<Vec<ast::NestedMetaItem>>,
38 pub syntax_exts: Vec<NamedSyntaxExtension>,
41 pub llvm_passes: Vec<String>,
44 pub attributes: Vec<(Symbol, AttributeType)>,
47 impl<'a> Registry<'a> {
49 pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> {
61 /// Gets the plugin's arguments, if any.
63 /// These are specified inside the `plugin` crate attribute as
66 /// #![plugin(my_plugin_name(... args ...))]
69 /// Returns empty slice in case the plugin was loaded
70 /// with `--extra-plugins`
71 pub fn args(&self) -> &[ast::NestedMetaItem] {
72 self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
75 /// Register a syntax extension of any kind.
77 /// This is the most general hook into `libsyntax`'s expansion behavior.
78 pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
79 self.syntax_exts.push((name, extension));
82 /// Register a macro of the usual kind.
84 /// This is a convenience wrapper for `register_syntax_extension`.
85 /// It builds for you a `SyntaxExtensionKind::LegacyBang` that calls `expander`,
86 /// and also takes care of interning the macro's name.
87 pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
88 let kind = SyntaxExtensionKind::LegacyBang(Box::new(expander));
89 let ext = SyntaxExtension::default(kind, self.sess.edition());
90 self.register_syntax_extension(Symbol::intern(name), ext);
93 /// Register an LLVM pass.
95 /// Registration with LLVM itself is handled through static C++ objects with
96 /// constructors. This method simply adds a name to the list of passes to
98 pub fn register_llvm_pass(&mut self, name: &str) {
99 self.llvm_passes.push(name.to_owned());
102 /// Register an attribute with an attribute type.
104 /// Registered attributes will bypass the `custom_attribute` feature gate.
105 /// `Whitelisted` attributes will additionally not trigger the `unused_attribute`
106 /// lint. `CrateLevel` attributes will not be allowed on anything other than a crate.
107 pub fn register_attribute(&mut self, name: Symbol, ty: AttributeType) {
108 self.attributes.push((name, ty));