]> git.lizzy.rs Git - rust.git/blob - src/librustc_plugin/registry.rs
Rollup merge of #65753 - csmoe:derive_fold, r=Centril
[rust.git] / src / librustc_plugin / registry.rs
1 //! Used by plugin crates to tell `rustc` about the plugins they provide.
2
3 use rustc::lint::LintStore;
4 use rustc::session::Session;
5
6 use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
7 use syntax_expand::base::MacroExpanderFn;
8 use syntax::symbol::Symbol;
9 use syntax::ast;
10 use syntax::feature_gate::AttributeType;
11 use syntax_pos::Span;
12
13 use std::borrow::ToOwned;
14
15 /// Structure used to register plugins.
16 ///
17 /// A plugin registrar function takes an `&mut Registry` and should call
18 /// methods to register its plugins.
19 ///
20 /// This struct has public fields and other methods for use by `rustc`
21 /// itself. They are not documented here, and plugin authors should
22 /// not use them.
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,
27
28     /// The `LintStore` allows plugins to register new lints.
29     pub lint_store: &'a mut LintStore,
30
31     #[doc(hidden)]
32     pub args_hidden: Option<Vec<ast::NestedMetaItem>>,
33
34     #[doc(hidden)]
35     pub krate_span: Span,
36
37     #[doc(hidden)]
38     pub syntax_exts: Vec<NamedSyntaxExtension>,
39
40     #[doc(hidden)]
41     pub llvm_passes: Vec<String>,
42
43     #[doc(hidden)]
44     pub attributes: Vec<(Symbol, AttributeType)>,
45 }
46
47 impl<'a> Registry<'a> {
48     #[doc(hidden)]
49     pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> {
50         Registry {
51             sess,
52             lint_store,
53             args_hidden: None,
54             krate_span,
55             syntax_exts: vec![],
56             llvm_passes: vec![],
57             attributes: vec![],
58         }
59     }
60
61     /// Gets the plugin's arguments, if any.
62     ///
63     /// These are specified inside the `plugin` crate attribute as
64     ///
65     /// ```no_run
66     /// #![plugin(my_plugin_name(... args ...))]
67     /// ```
68     ///
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(&[])
73     }
74
75     /// Register a syntax extension of any kind.
76     ///
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));
80     }
81
82     /// Register a macro of the usual kind.
83     ///
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);
91     }
92
93     /// Register an LLVM pass.
94     ///
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
97     /// execute.
98     pub fn register_llvm_pass(&mut self, name: &str) {
99         self.llvm_passes.push(name.to_owned());
100     }
101
102     /// Register an attribute with an attribute type.
103     ///
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));
109     }
110 }