1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use lint::{LintPassObject, LintId, Lint};
use session::Session;
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
use syntax::ext::base::{IdentTT, Decorator, Modifier, MultiModifier, MacroRulesTT};
use syntax::ext::base::MacroExpanderFn;
use syntax::codemap::Span;
use syntax::parse::token;
use syntax::ptr::P;
use syntax::ast;
use std::collections::HashMap;
use std::borrow::ToOwned;
pub struct Registry<'a> {
pub sess: &'a Session,
#[doc(hidden)]
pub args_hidden: Option<Vec<P<ast::MetaItem>>>,
#[doc(hidden)]
pub krate_span: Span,
#[doc(hidden)]
pub syntax_exts: Vec<NamedSyntaxExtension>,
#[doc(hidden)]
pub lint_passes: Vec<LintPassObject>,
#[doc(hidden)]
pub lint_groups: HashMap<&'static str, Vec<LintId>>,
#[doc(hidden)]
pub llvm_passes: Vec<String>,
}
impl<'a> Registry<'a> {
#[doc(hidden)]
pub fn new(sess: &'a Session, krate: &ast::Crate) -> Registry<'a> {
Registry {
sess: sess,
args_hidden: None,
krate_span: krate.span,
syntax_exts: vec!(),
lint_passes: vec!(),
lint_groups: HashMap::new(),
llvm_passes: vec!(),
}
}
pub fn args<'b>(&'b self) -> &'b Vec<P<ast::MetaItem>> {
self.args_hidden.as_ref().expect("args not set")
}
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
self.syntax_exts.push((name, match extension {
NormalTT(ext, _, allow_internal_unstable) => {
NormalTT(ext, Some(self.krate_span), allow_internal_unstable)
}
IdentTT(ext, _, allow_internal_unstable) => {
IdentTT(ext, Some(self.krate_span), allow_internal_unstable)
}
Decorator(ext) => Decorator(ext),
Modifier(ext) => Modifier(ext),
MultiModifier(ext) => MultiModifier(ext),
MacroRulesTT => {
self.sess.err("plugin tried to register a new MacroRulesTT");
return;
}
}));
}
pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
self.register_syntax_extension(token::intern(name),
NormalTT(Box::new(expander), None, false));
}
pub fn register_lint_pass(&mut self, lint_pass: LintPassObject) {
self.lint_passes.push(lint_pass);
}
pub fn register_lint_group(&mut self, name: &'static str, to: Vec<&'static Lint>) {
self.lint_groups.insert(name, to.into_iter().map(|x| LintId::of(x)).collect());
}
pub fn register_llvm_pass(&mut self, name: &str) {
self.llvm_passes.push(name.to_owned());
}
}