Skip to content

Commit bf5efee

Browse files
committed
Initial import of the Aster syntax::ast builder library
This imports the [aster](https://github.com/serde-rs/serde) library into the Rust repository as an unstable library. Aster is a `syntax::ast` builder, that simplifies the generation of rust AST. It abstracts away many of the default options, and shields the user from fields being added, removed, or restructured in many circumstances. This allows a library like [Serde](https://github.com/serde-rs/serde) to be much more reliably compiled on nightly, which has not been broken by aster in the past couple months. This is specifically being done for the Servo project, which has started to use Serde and has gotten broken a few times because of the lag between libsyntax changes and the requisite changes needed to be made in Aster.
1 parent a48c29d commit bf5efee

38 files changed

+8090
-1
lines changed

mk/crates.mk

+2-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ TARGET_CRATES := libc std flate arena term \
5353
serialize getopts collections test rand \
5454
log graphviz core rbml alloc \
5555
rustc_unicode rustc_bitflags \
56-
alloc_system
56+
alloc_system aster
5757
RUSTC_CRATES := rustc rustc_typeck rustc_borrowck rustc_resolve rustc_driver \
5858
rustc_trans rustc_back rustc_llvm rustc_privacy rustc_lint \
5959
rustc_data_structures rustc_platform_intrinsics
@@ -104,6 +104,7 @@ DEPS_rand := core
104104
DEPS_log := std
105105
DEPS_fmt_macros = std
106106
DEPS_alloc_system := core libc
107+
DEPS_aster := std syntax
107108

108109
TOOL_DEPS_compiletest := test getopts
109110
TOOL_DEPS_rustdoc := rustdoc

src/libaster/attr.rs

+299
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::iter::IntoIterator;
12+
13+
use syntax::ast;
14+
use syntax::attr;
15+
use syntax::codemap::{DUMMY_SP, Span, respan};
16+
use syntax::parse::token;
17+
use syntax::ptr::P;
18+
19+
use invoke::{Invoke, Identity};
20+
use lit::LitBuilder;
21+
use str::ToInternedString;
22+
23+
//////////////////////////////////////////////////////////////////////////////
24+
25+
pub struct AttrBuilder<F=Identity> {
26+
callback: F,
27+
span: Span,
28+
style: ast::AttrStyle,
29+
is_sugared_doc: bool,
30+
}
31+
32+
impl AttrBuilder {
33+
pub fn new() -> Self {
34+
AttrBuilder::new_with_callback(Identity)
35+
}
36+
}
37+
38+
impl<F> AttrBuilder<F>
39+
where F: Invoke<ast::Attribute>,
40+
{
41+
pub fn new_with_callback(callback: F) -> Self {
42+
AttrBuilder {
43+
callback: callback,
44+
span: DUMMY_SP,
45+
style: ast::AttrOuter,
46+
is_sugared_doc: false,
47+
}
48+
}
49+
50+
pub fn span(mut self, span: Span) -> Self {
51+
self.span = span;
52+
self
53+
}
54+
55+
pub fn inner(mut self) -> Self {
56+
self.style = ast::AttrInner;
57+
self
58+
}
59+
60+
pub fn build_meta_item(self, item: P<ast::MetaItem>) -> F::Result {
61+
let attr = respan(self.span, ast::Attribute_ {
62+
id: attr::mk_attr_id(),
63+
style: self.style,
64+
value: item,
65+
is_sugared_doc: self.is_sugared_doc,
66+
});
67+
self.callback.invoke(attr)
68+
}
69+
70+
pub fn build_meta_item_(self, item: ast::MetaItem_) -> F::Result {
71+
let item = P(respan(self.span, item));
72+
self.build_meta_item(item)
73+
}
74+
75+
pub fn word<T>(self, word: T) -> F::Result
76+
where T: ToInternedString
77+
{
78+
self.build_meta_item_(ast::MetaWord(word.to_interned_string()))
79+
}
80+
81+
pub fn list<T>(self, word: T) -> AttrListBuilder<Self>
82+
where T: ToInternedString
83+
{
84+
AttrListBuilder::new_with_callback(word, self)
85+
}
86+
87+
pub fn name_value<T>(self, name: T) -> LitBuilder<AttrNameValueBuilder<Self>>
88+
where T: ToInternedString,
89+
{
90+
LitBuilder::new_with_callback(AttrNameValueBuilder {
91+
callback: self,
92+
name: name.to_interned_string(),
93+
})
94+
}
95+
96+
pub fn automatically_derived(self) -> F::Result {
97+
self.word("automatically_derived")
98+
}
99+
100+
pub fn inline(self) -> F::Result {
101+
self.word("inline")
102+
}
103+
104+
pub fn test(self) -> F::Result {
105+
self.word("test")
106+
}
107+
108+
pub fn allow<I, T>(self, iter: I) -> F::Result
109+
where I: IntoIterator<Item=T>,
110+
T: ToInternedString,
111+
{
112+
self.list("allow").words(iter).build()
113+
}
114+
115+
pub fn warn<I, T>(self, iter: I) -> F::Result
116+
where I: IntoIterator<Item=T>,
117+
T: ToInternedString,
118+
{
119+
self.list("warn").words(iter).build()
120+
}
121+
122+
pub fn deny<I, T>(self, iter: I) -> F::Result
123+
where I: IntoIterator<Item=T>,
124+
T: ToInternedString,
125+
{
126+
self.list("deny").words(iter).build()
127+
}
128+
129+
pub fn features<I, T>(self, iter: I) -> F::Result
130+
where I: IntoIterator<Item=T>,
131+
T: ToInternedString,
132+
{
133+
self.list("feature").words(iter).build()
134+
}
135+
136+
pub fn plugins<I, T>(self, iter: I) -> F::Result
137+
where I: IntoIterator<Item=T>,
138+
T: ToInternedString,
139+
{
140+
self.list("plugin").words(iter).build()
141+
}
142+
143+
/**
144+
* Create a #[doc = "..."] node. Note that callers of this must make sure to prefix their
145+
* comments with either "///" or "/\*\*" if an outer comment, or "//!" or "/\*!" if an inner
146+
* comment.
147+
*/
148+
pub fn doc<T>(mut self, doc: T) -> F::Result
149+
where T: ToInternedString,
150+
{
151+
self.is_sugared_doc = true;
152+
self.name_value("doc").str(doc)
153+
}
154+
}
155+
156+
impl<F> Invoke<P<ast::MetaItem>> for AttrBuilder<F>
157+
where F: Invoke<ast::Attribute>,
158+
{
159+
type Result = F::Result;
160+
161+
fn invoke(self, item: P<ast::MetaItem>) -> F::Result {
162+
self.build_meta_item(item)
163+
}
164+
}
165+
166+
impl<F> Invoke<ast::MetaItem_> for AttrBuilder<F>
167+
where F: Invoke<ast::Attribute>,
168+
{
169+
type Result = F::Result;
170+
171+
fn invoke(self, item: ast::MetaItem_) -> F::Result {
172+
self.build_meta_item_(item)
173+
}
174+
}
175+
176+
//////////////////////////////////////////////////////////////////////////////
177+
178+
pub struct AttrListBuilder<F> {
179+
callback: F,
180+
span: Span,
181+
name: token::InternedString,
182+
items: Vec<P<ast::MetaItem>>,
183+
}
184+
185+
impl<F> AttrListBuilder<F>
186+
where F: Invoke<P<ast::MetaItem>>,
187+
{
188+
pub fn new_with_callback<T>(name: T, callback: F) -> Self
189+
where T: ToInternedString,
190+
{
191+
AttrListBuilder {
192+
callback: callback,
193+
span: DUMMY_SP,
194+
name: name.to_interned_string(),
195+
items: vec![],
196+
}
197+
}
198+
199+
pub fn span(mut self, span: Span) -> Self {
200+
self.span = span;
201+
self
202+
}
203+
204+
pub fn with_meta_items<I>(mut self, iter: I) -> Self
205+
where I: IntoIterator<Item=P<ast::MetaItem>>,
206+
{
207+
self.items.extend(iter);
208+
self
209+
}
210+
211+
pub fn with_meta_items_<I>(self, iter: I) -> Self
212+
where I: IntoIterator<Item=ast::MetaItem_>,
213+
{
214+
let iter = iter.into_iter();
215+
let span = self.span;
216+
self.with_meta_items(iter.map(|item| P(respan(span, item))))
217+
}
218+
219+
pub fn with_meta_item(mut self, item: P<ast::MetaItem>) -> Self {
220+
self.items.push(item);
221+
self
222+
}
223+
224+
pub fn with_meta_item_(self, item: ast::MetaItem_) -> Self {
225+
let span = self.span;
226+
self.with_meta_item(P(respan(span, item)))
227+
}
228+
229+
pub fn words<I, T>(self, iter: I) -> Self
230+
where I: IntoIterator<Item=T>,
231+
T: ToInternedString,
232+
{
233+
let iter = iter.into_iter();
234+
self.with_meta_items_(iter.map(|word| ast::MetaWord(word.to_interned_string())))
235+
}
236+
237+
pub fn word<T>(self, word: T) -> Self
238+
where T: ToInternedString,
239+
{
240+
self.with_meta_item_(ast::MetaWord(word.to_interned_string()))
241+
}
242+
243+
pub fn list<T>(self, name: T) -> AttrListBuilder<Self>
244+
where T: ToInternedString,
245+
{
246+
AttrListBuilder::new_with_callback(name, self)
247+
}
248+
249+
pub fn name_value<T>(self, name: T) -> LitBuilder<AttrNameValueBuilder<Self>>
250+
where T: ToInternedString,
251+
{
252+
LitBuilder::new_with_callback(AttrNameValueBuilder {
253+
callback: self,
254+
name: name.to_interned_string(),
255+
})
256+
}
257+
258+
pub fn build(self) -> F::Result {
259+
let item = respan(self.span, ast::MetaList(self.name, self.items));
260+
self.callback.invoke(P(item))
261+
}
262+
}
263+
264+
impl<F> Invoke<P<ast::MetaItem>> for AttrListBuilder<F>
265+
where F: Invoke<P<ast::MetaItem>>,
266+
{
267+
type Result = Self;
268+
269+
fn invoke(self, item: P<ast::MetaItem>) -> Self {
270+
self.with_meta_item(item)
271+
}
272+
}
273+
274+
impl<F> Invoke<ast::MetaItem_> for AttrListBuilder<F>
275+
where F: Invoke<P<ast::MetaItem>>,
276+
{
277+
type Result = Self;
278+
279+
fn invoke(self, item: ast::MetaItem_) -> Self {
280+
self.with_meta_item_(item)
281+
}
282+
}
283+
284+
//////////////////////////////////////////////////////////////////////////////
285+
286+
pub struct AttrNameValueBuilder<F> {
287+
callback: F,
288+
name: token::InternedString,
289+
}
290+
291+
impl<F: Invoke<ast::MetaItem_>> Invoke<P<ast::Lit>> for AttrNameValueBuilder<F> {
292+
type Result = F::Result;
293+
294+
fn invoke(self, value: P<ast::Lit>) -> F::Result {
295+
let item = ast::MetaNameValue(self.name, (*value).clone());
296+
self.callback.invoke(item)
297+
}
298+
}
299+

0 commit comments

Comments
 (0)