new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/.cargo-checksum.json
@@ -0,0 +1,1 @@
+{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"9dbd7d392dd88808cd252ab186b368db6e37ca75a34757ba94b12e48467e6075","src/arm.rs":"83b6ba22ded921ae45e02888e879b2ae73d4659db53e6552675433c3c2e0ed21","src/attr.rs":"d1eff83ec39e77033c3d8fde744405faf65756744d53518765b83a5813424478","src/block.rs":"71e2268ba151b7ee60a2fe0b0b3a7cf3e2ce3bff4fb0ee260db70ad9b1cd8826","src/constant.rs":"471b0ffc52684733a598a43e08b1719bf6852c26eca74e7f5105f0f964543980","src/ctx.rs":"738213a64a96cfe3beba6d08d82d89d48dc384b37fe726621b324bac5c017859","src/expr.rs":"db6613923e5fd016f69ea6283a9c99ddc10a73183c8a5acedb983f224720c9ab","src/fn_decl.rs":"85c30d78942bb7cda0c6bddcf55f1a35b3581a99fb15e33f3abf2763b84f8073","src/generics.rs":"5bce5cb6f7331eb75ecf8cd236b0f0ae19838a014ee931de25605a783234a125","src/ident.rs":"d4fd728f2f3c6fe85bce20f573496ef64696cfa46343009f394b32868e308c78","src/invoke.rs":"03f52dd0b135e8ffcc52c3802cdf8d516ef4a53e393ce4bdd82ced19fd106b88","src/item.rs":"c6857ba95397a6db3cd8bb5a88794eeeb8920ee5a1cce8a7d47d34c681cf32f9","src/lib.rs":"92f93d3aa081b7107c6132cbcf7bfa20a0e21f6456f54accd7561a7a246d7c39","src/lifetime.rs":"348ecc239aafa45128c7e214635b6cc597e093c33a22c204c0c55a48b3a0b5a1","src/lit.rs":"b7c0c677fef8b86f8178a722a004efa066b11bf268642137307689d2bec9b405","src/mac.rs":"98d6fadb0c774a55410fe51559b984e7831934198b6fc5e80ba371e94de562a1","src/method.rs":"bce543c148022170decd0cff9af3b37781323bcdf0dc35e23beec5f200dbc549","src/name.rs":"1444a9e79dca2ada73519e64c6a46050153ae5f02e5c8ce5ad6a5581f8be641a","src/pat.rs":"0c3c0cb22054d09a2b7df277e4c05023c079d655d54b66a6bf732d56d58971e0","src/path.rs":"dfeeae8d90e4f670b5a66f1c15dbfc8f2ea1cd0b9bda5eebe876f7163b860c58","src/qpath.rs":"bb00b9d63d6be1caf40a3eb0395834ec1025543060fcc0e7955835e231b6e6f8","src/self_.rs":"565780ba85ba851675331cd60dbe8a43f5eb87c318f6cc3b11bb7ba77a0d53fa","src/stmt.rs":"99e577b1417ff66c3057454ca27266a19329c6896b0f36259dcbdba0ff0005fb","src/str.rs":"c3efbf7b15cb2333f683e357db62d22311e833ee4330347eb23c66c5a0603ecf","src/struct_field.rs":"189fa910e236fea815d85c6b4535a76e6e7151a9d113a806bb60c6a192c7042b","src/ty.rs":"c569ff2833e939bc8537310cf13b4eedebe2e0a3e63ea62e232f7856a00fb988","src/ty_param.rs":"ae253dfaf964ac5e9bbb6d5aedb631bb491c5e602c9cf9038c886dd2707e48e6","src/variant.rs":"7fed49d694e029c81b4b70095e00704f1c67ef6357d122157d305f85dd95a512","src/variant_data.rs":"346198e982a2549ed4942ac7c6581f222f6284392afd9c0898acbfa53f58ffd3","src/where_predicate.rs":"f8bb7d2ea112986196f62c3deae58afe7e78d6b1c5bc622aeb3ecd51d77e7e10"},"package":"88bb8ecdf6a7eaddb7bfd872ebf5e085d343ca42ce98c582dba8046e3450b524"}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "aster"
+version = "0.34.0"
+authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
+license = "MIT/Apache-2.0"
+description = "A libsyntax ast builder"
+repository = "https://github.com/serde-rs/aster"
+include = ["Cargo.toml", "src/**/*.rs"]
+
+[features]
+with-syntex = ["syntex_syntax"]
+unstable-testing = ["clippy", "compiletest_rs"]
+
+[dependencies]
+syntex_syntax = { version = "^0.50.0", optional = true }
+clippy = { version = "0.*", optional = true }
+compiletest_rs = { version = "^0.2.0", optional = true }
+
+[[test]]
+name = "test"
+path = "tests/test.rs"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/arm.rs
@@ -0,0 +1,241 @@
+#![cfg_attr(feature = "unstable", allow(should_implement_trait))]
+
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use attr::AttrBuilder;
+use expr::ExprBuilder;
+use invoke::{Invoke, Identity};
+use pat::PatBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArmBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ attrs: Vec<ast::Attribute>,
+}
+
+impl ArmBuilder {
+ pub fn new() -> Self {
+ ArmBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> ArmBuilder<F>
+ where F: Invoke<ast::Arm>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ ArmBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ attrs: Vec::new(),
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_attrs<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Attribute>,
+ {
+ self.attrs.extend(iter);
+ self
+ }
+
+ pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+ self.attrs.push(attr);
+ self
+ }
+
+ pub fn attr(self) -> AttrBuilder<Self> {
+ AttrBuilder::with_callback(self)
+ }
+
+ pub fn with_pats<I>(self, iter: I) -> ArmPatBuilder<F>
+ where I: IntoIterator<Item=P<ast::Pat>>,
+ {
+ ArmPatBuilder {
+ callback: self.callback,
+ span: self.span,
+ attrs: self.attrs,
+ pats: iter.into_iter().collect(),
+ }
+ }
+
+ pub fn with_pat(self, pat: P<ast::Pat>) -> ArmPatBuilder<F> {
+ ArmPatBuilder {
+ callback: self.callback,
+ span: self.span,
+ attrs: self.attrs,
+ pats: vec![pat],
+ }
+ }
+
+ pub fn pat(self) -> PatBuilder<Self> {
+ PatBuilder::with_callback(self)
+ }
+
+ /*
+ pub fn with_guard(self, guard: Option<P<ast::Expr>>) -> ExprBuilder<ArmBodyBuilder<F>> {
+ ExprBuilder::with_callback(ArmBodyBuilder {
+ builder: self,
+ guard: guard,
+ })
+ }
+
+ pub fn guard(self) -> ExprBuilder<Self> {
+ ExprBuilder::with_callback(self)
+ }
+
+ pub fn body(self) -> ExprBuilder<ArmBodyBuilder<F>> {
+ self.with_guard(None)
+ }
+
+ pub fn build_arm_(self,
+ guard: Option<P<ast::Expr>>,
+ body: P<ast::Expr>) -> F::Result {
+ self.callback.invoke(ast::Arm {
+ attrs: self.attrs,
+ pats: self.pats,
+ guard: guard,
+ body: body,
+ })
+ }
+ */
+}
+
+impl<F> Invoke<ast::Attribute> for ArmBuilder<F>
+ where F: Invoke<ast::Arm>,
+{
+ type Result = Self;
+
+ fn invoke(self, attr: ast::Attribute) -> Self {
+ self.with_attr(attr)
+ }
+}
+
+impl<F> Invoke<P<ast::Pat>> for ArmBuilder<F>
+ where F: Invoke<ast::Arm>,
+{
+ type Result = ArmPatBuilder<F>;
+
+ fn invoke(self, pat: P<ast::Pat>) -> ArmPatBuilder<F> {
+ self.with_pat(pat)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArmPatBuilder<F> {
+ callback: F,
+ span: Span,
+ attrs: Vec<ast::Attribute>,
+ pats: Vec<P<ast::Pat>>,
+}
+
+impl<F> ArmPatBuilder<F>
+ where F: Invoke<ast::Arm>,
+{
+ pub fn with_pats<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::Pat>>,
+ {
+ self.pats.extend(iter);
+ self
+ }
+
+ pub fn with_pat(mut self, pat: P<ast::Pat>) -> Self {
+ self.pats.push(pat);
+ self
+ }
+
+ pub fn pat(self) -> PatBuilder<Self> {
+ let span = self.span;
+ PatBuilder::with_callback(self).span(span)
+ }
+
+ pub fn with_guard(self, guard: Option<P<ast::Expr>>) -> ArmBodyBuilder<F> {
+ ArmBodyBuilder {
+ builder: self,
+ guard: guard,
+ }
+ }
+
+ pub fn guard(self) -> ExprBuilder<Self> {
+ let span = self.span;
+ ExprBuilder::with_callback(self).span(span)
+ }
+
+ pub fn body(self) -> ExprBuilder<ArmBodyBuilder<F>> {
+ ArmBodyBuilder {
+ builder: self,
+ guard: None,
+ }.body()
+ }
+
+ pub fn build_arm_(self,
+ guard: Option<P<ast::Expr>>,
+ body: P<ast::Expr>) -> F::Result {
+ self.callback.invoke(ast::Arm {
+ attrs: self.attrs,
+ pats: self.pats,
+ guard: guard,
+ body: body,
+ })
+ }
+}
+
+impl<F> Invoke<P<ast::Pat>> for ArmPatBuilder<F>
+ where F: Invoke<ast::Arm>,
+{
+ type Result = Self;
+
+ fn invoke(self, pat: P<ast::Pat>) -> Self {
+ self.with_pat(pat)
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ArmPatBuilder<F>
+ where F: Invoke<ast::Arm>,
+{
+ type Result = ArmBodyBuilder<F>;
+
+ fn invoke(self, guard: P<ast::Expr>) -> ArmBodyBuilder<F> {
+ self.with_guard(Some(guard))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArmBodyBuilder<F> {
+ builder: ArmPatBuilder<F>,
+ guard: Option<P<ast::Expr>>,
+}
+
+impl<F> ArmBodyBuilder<F>
+ where F: Invoke<ast::Arm>,
+{
+ pub fn body(self) -> ExprBuilder<ArmBodyBuilder<F>> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self, body: P<ast::Expr>) -> F::Result {
+ self.builder.build_arm_(self.guard, body)
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ArmBodyBuilder<F>
+ where F: Invoke<ast::Arm>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, body: P<ast::Expr>) -> F::Result {
+ self.build(body)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/attr.rs
@@ -0,0 +1,291 @@
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::attr;
+use syntax::codemap::{DUMMY_SP, Span, respan};
+use syntax::parse::token;
+use syntax::ptr::P;
+
+use invoke::{Invoke, Identity};
+use lit::LitBuilder;
+use str::ToInternedString;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct AttrBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ style: ast::AttrStyle,
+ is_sugared_doc: bool,
+}
+
+impl AttrBuilder {
+ pub fn new() -> Self {
+ AttrBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> AttrBuilder<F>
+ where F: Invoke<ast::Attribute>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ AttrBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ style: ast::AttrStyle::Outer,
+ is_sugared_doc: false,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn inner(mut self) -> Self {
+ self.style = ast::AttrStyle::Inner;
+ self
+ }
+
+ pub fn build_meta_item(self, item: P<ast::MetaItem>) -> F::Result {
+ let attr = respan(self.span, ast::Attribute_ {
+ id: attr::mk_attr_id(),
+ style: self.style,
+ value: item,
+ is_sugared_doc: self.is_sugared_doc,
+ });
+ self.callback.invoke(attr)
+ }
+
+ pub fn build_meta_item_(self, item: ast::MetaItemKind) -> F::Result {
+ let item = P(respan(self.span, item));
+ self.build_meta_item(item)
+ }
+
+ pub fn word<T>(self, word: T) -> F::Result
+ where T: ToInternedString
+ {
+ self.build_meta_item_(ast::MetaItemKind::Word(word.to_interned_string()))
+ }
+
+ pub fn list<T>(self, word: T) -> AttrListBuilder<Self>
+ where T: ToInternedString
+ {
+ AttrListBuilder::with_callback(word, self)
+ }
+
+ pub fn name_value<T>(self, name: T) -> LitBuilder<AttrNameValueBuilder<Self>>
+ where T: ToInternedString,
+ {
+ LitBuilder::with_callback(AttrNameValueBuilder {
+ callback: self,
+ name: name.to_interned_string(),
+ })
+ }
+
+ pub fn automatically_derived(self) -> F::Result {
+ self.word("automatically_derived")
+ }
+
+ pub fn inline(self) -> F::Result {
+ self.word("inline")
+ }
+
+ pub fn test(self) -> F::Result {
+ self.word("test")
+ }
+
+ pub fn allow<I, T>(self, iter: I) -> F::Result
+ where I: IntoIterator<Item=T>,
+ T: ToInternedString,
+ {
+ self.list("allow").words(iter).build()
+ }
+
+ pub fn warn<I, T>(self, iter: I) -> F::Result
+ where I: IntoIterator<Item=T>,
+ T: ToInternedString,
+ {
+ self.list("warn").words(iter).build()
+ }
+
+ pub fn deny<I, T>(self, iter: I) -> F::Result
+ where I: IntoIterator<Item=T>,
+ T: ToInternedString,
+ {
+ self.list("deny").words(iter).build()
+ }
+
+ pub fn features<I, T>(self, iter: I) -> F::Result
+ where I: IntoIterator<Item=T>,
+ T: ToInternedString,
+ {
+ self.list("feature").words(iter).build()
+ }
+
+ pub fn plugins<I, T>(self, iter: I) -> F::Result
+ where I: IntoIterator<Item=T>,
+ T: ToInternedString,
+ {
+ self.list("plugin").words(iter).build()
+ }
+
+ /**
+ * Create a #[doc = "..."] node. Note that callers of this must make sure to prefix their
+ * comments with either "///" or "/\*\*" if an outer comment, or "//!" or "/\*!" if an inner
+ * comment.
+ */
+ pub fn doc<T>(mut self, doc: T) -> F::Result
+ where T: ToInternedString,
+ {
+ self.is_sugared_doc = true;
+ self.name_value("doc").str(doc)
+ }
+}
+
+impl<F> Invoke<P<ast::MetaItem>> for AttrBuilder<F>
+ where F: Invoke<ast::Attribute>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, item: P<ast::MetaItem>) -> F::Result {
+ self.build_meta_item(item)
+ }
+}
+
+impl<F> Invoke<ast::MetaItemKind> for AttrBuilder<F>
+ where F: Invoke<ast::Attribute>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, item: ast::MetaItemKind) -> F::Result {
+ self.build_meta_item_(item)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct AttrListBuilder<F> {
+ callback: F,
+ span: Span,
+ name: token::InternedString,
+ items: Vec<ast::NestedMetaItem>,
+}
+
+impl<F> AttrListBuilder<F>
+ where F: Invoke<P<ast::MetaItem>>,
+{
+ pub fn with_callback<T>(name: T, callback: F) -> Self
+ where T: ToInternedString,
+ {
+ AttrListBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ name: name.to_interned_string(),
+ items: vec![],
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_meta_items<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::MetaItem>>,
+ {
+ let span = self.span;
+ self.items.extend(iter.into_iter().map(|meta_item| {
+ respan(span, ast::NestedMetaItemKind::MetaItem(meta_item))
+ }));
+ self
+ }
+
+ pub fn with_meta_items_<I>(self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::MetaItemKind>,
+ {
+ let iter = iter.into_iter();
+ let span = self.span;
+ self.with_meta_items(iter.map(|item| P(respan(span, item))))
+ }
+
+ pub fn with_meta_item(mut self, item: P<ast::MetaItem>) -> Self {
+ self.items.push(respan(self.span, ast::NestedMetaItemKind::MetaItem(item)));
+ self
+ }
+
+ pub fn with_meta_item_kind(self, item: ast::MetaItemKind) -> Self {
+ let span = self.span;
+ self.with_meta_item(P(respan(span, item)))
+ }
+
+ pub fn words<I, T>(self, iter: I) -> Self
+ where I: IntoIterator<Item=T>,
+ T: ToInternedString,
+ {
+ let iter = iter.into_iter();
+ self.with_meta_items_(iter.map(|word| ast::MetaItemKind::Word(word.to_interned_string())))
+ }
+
+ pub fn word<T>(self, word: T) -> Self
+ where T: ToInternedString,
+ {
+ self.with_meta_item_kind(ast::MetaItemKind::Word(word.to_interned_string()))
+ }
+
+ pub fn list<T>(self, name: T) -> AttrListBuilder<Self>
+ where T: ToInternedString,
+ {
+ AttrListBuilder::with_callback(name, self)
+ }
+
+ pub fn name_value<T>(self, name: T) -> LitBuilder<AttrNameValueBuilder<Self>>
+ where T: ToInternedString,
+ {
+ LitBuilder::with_callback(AttrNameValueBuilder {
+ callback: self,
+ name: name.to_interned_string(),
+ })
+ }
+
+ pub fn build(self) -> F::Result {
+ let item = respan(self.span, ast::MetaItemKind::List(self.name, self.items));
+ self.callback.invoke(P(item))
+ }
+}
+
+impl<F> Invoke<P<ast::MetaItem>> for AttrListBuilder<F>
+ where F: Invoke<P<ast::MetaItem>>,
+{
+ type Result = Self;
+
+ fn invoke(self, item: P<ast::MetaItem>) -> Self {
+ self.with_meta_item(item)
+ }
+}
+
+impl<F> Invoke<ast::MetaItemKind> for AttrListBuilder<F>
+ where F: Invoke<P<ast::MetaItem>>,
+{
+ type Result = Self;
+
+ fn invoke(self, item: ast::MetaItemKind) -> Self {
+ self.with_meta_item_kind(item)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct AttrNameValueBuilder<F> {
+ callback: F,
+ name: token::InternedString,
+}
+
+impl<F: Invoke<ast::MetaItemKind>> Invoke<P<ast::Lit>> for AttrNameValueBuilder<F> {
+ type Result = F::Result;
+
+ fn invoke(self, value: P<ast::Lit>) -> F::Result {
+ let item = ast::MetaItemKind::NameValue(self.name, (*value).clone());
+ self.callback.invoke(item)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/block.rs
@@ -0,0 +1,110 @@
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use expr::ExprBuilder;
+use invoke::{Invoke, Identity};
+use stmt::StmtBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct BlockBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ stmts: Vec<ast::Stmt>,
+ block_check_mode: ast::BlockCheckMode,
+}
+
+impl BlockBuilder {
+ pub fn new() -> Self {
+ BlockBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> BlockBuilder<F>
+ where F: Invoke<P<ast::Block>>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ BlockBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ stmts: Vec::new(),
+ block_check_mode: ast::BlockCheckMode::Default,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn unsafe_(mut self) -> Self {
+ let source = ast::UnsafeSource::CompilerGenerated;
+ self.block_check_mode = ast::BlockCheckMode::Unsafe(source);
+ self
+ }
+
+ pub fn with_stmts<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Stmt>
+ {
+ self.stmts.extend(iter);
+ self
+ }
+
+ pub fn with_stmt(mut self, stmt: ast::Stmt) -> Self {
+ self.stmts.push(stmt);
+ self
+ }
+
+ pub fn stmt(self) -> StmtBuilder<Self> {
+ let span = self.span;
+ StmtBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build_expr(self, expr: P<ast::Expr>) -> F::Result {
+ self.build_(Some(expr))
+ }
+
+ pub fn expr(self) -> ExprBuilder<Self> {
+ let span = self.span;
+ ExprBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self) -> F::Result {
+ self.build_(None)
+ }
+
+ fn build_(mut self, expr: Option<P<ast::Expr>>) -> F::Result {
+ self.stmts.extend(expr.map(|expr| {
+ StmtBuilder::new().span(expr.span).build_expr(expr)
+ }));
+ self.callback.invoke(P(ast::Block {
+ stmts: self.stmts,
+ id: ast::DUMMY_NODE_ID,
+ rules: self.block_check_mode,
+ span: self.span,
+ }))
+ }
+}
+
+impl<F> Invoke<ast::Stmt> for BlockBuilder<F>
+ where F: Invoke<P<ast::Block>>,
+{
+ type Result = Self;
+
+ fn invoke(self, stmt: ast::Stmt) -> Self {
+ self.with_stmt(stmt)
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for BlockBuilder<F>
+ where F: Invoke<P<ast::Block>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.build_expr(expr)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/constant.rs
@@ -0,0 +1,88 @@
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use expr::ExprBuilder;
+use invoke::{Invoke, Identity};
+use ty::TyBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct Const {
+ pub ty: P<ast::Ty>,
+ pub expr: Option<P<ast::Expr>>,
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ConstBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ expr: Option<P<ast::Expr>>,
+}
+
+impl ConstBuilder {
+ pub fn new() -> Self {
+ ConstBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> ConstBuilder<F>
+ where F: Invoke<Const>,
+{
+ pub fn with_callback(callback: F) -> Self
+ where F: Invoke<Const>,
+ {
+ ConstBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ expr: None,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_expr(mut self, expr: P<ast::Expr>) -> Self {
+ self.expr = Some(expr);
+ self
+ }
+
+ pub fn expr(self) -> ExprBuilder<Self> {
+ ExprBuilder::with_callback(self)
+ }
+
+ pub fn ty(self) -> TyBuilder<Self> {
+ let span = self.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self, ty: P<ast::Ty>) -> F::Result {
+ self.callback.invoke(Const {
+ ty: ty,
+ expr: self.expr,
+ })
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ConstBuilder<F>
+ where F: Invoke<Const>,
+{
+ type Result = Self;
+
+ fn invoke(self, expr: P<ast::Expr>) -> Self {
+ self.with_expr(expr)
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ConstBuilder<F>
+ where F: Invoke<Const>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+ self.build(ty)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/ctx.rs
@@ -0,0 +1,17 @@
+use syntax::ast;
+use syntax::parse::token;
+
+//////////////////////////////////////////////////////////////////////////////
+
+#[derive(Copy)]
+pub struct Ctx;
+
+impl Ctx {
+ pub fn new() -> Ctx {
+ Ctx
+ }
+
+ pub fn intern(&self, name: &str) -> ast::Name {
+ token::intern(name)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/expr.rs
@@ -0,0 +1,2181 @@
+#![cfg_attr(feature = "unstable-testing", allow(should_implement_trait))]
+
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span, Spanned, respan};
+use syntax::ptr::P;
+
+use arm::ArmBuilder;
+use attr::AttrBuilder;
+use block::BlockBuilder;
+use fn_decl::FnDeclBuilder;
+use ident::ToIdent;
+use invoke::{Invoke, Identity};
+use lit::LitBuilder;
+use mac::MacBuilder;
+use pat::PatBuilder;
+use path::{IntoPath, PathBuilder};
+use qpath::QPathBuilder;
+use str::ToInternedString;
+use ty::TyBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ attrs: Vec<ast::Attribute>,
+}
+
+impl ExprBuilder {
+ pub fn new() -> Self {
+ ExprBuilder::with_callback(Identity)
+ }
+}
+
+macro_rules! signed_int_method {
+ ($ty:ident, $unsigned:ident) => {
+ pub fn $ty(self, val: $ty) -> F::Result {
+ if val == ::std::$ty::MIN {
+ self.neg().lit().$ty(val as $unsigned)
+ } else if val < 0 {
+ self.neg().lit().$ty(-val as $unsigned)
+ } else {
+ self.lit().$ty(val as $unsigned)
+ }
+ }
+ };
+}
+
+impl<F> ExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ ExprBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ attrs: vec![],
+ }
+ }
+
+ pub fn build(self, expr: P<ast::Expr>) -> F::Result {
+ self.callback.invoke(expr)
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+ self.attrs.push(attr);
+ self
+ }
+
+ pub fn attr(self) -> AttrBuilder<Self> {
+ AttrBuilder::with_callback(self)
+ }
+
+ pub fn build_expr_kind(self, expr: ast::ExprKind) -> F::Result {
+ let expr = P(ast::Expr {
+ id: ast::DUMMY_NODE_ID,
+ node: expr,
+ span: self.span,
+ attrs: self.attrs.clone().into(),
+ });
+ self.build(expr)
+ }
+
+ pub fn build_path(self, path: ast::Path) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Path(None, path))
+ }
+
+ pub fn build_qpath(self, qself: ast::QSelf, path: ast::Path) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Path(Some(qself), path))
+ }
+
+ pub fn path(self) -> PathBuilder<Self> {
+ let span = self.span;
+ PathBuilder::with_callback(self).span(span)
+ }
+
+ pub fn qpath(self) -> QPathBuilder<Self> {
+ let span = self.span;
+ QPathBuilder::with_callback(self).span(span)
+ }
+
+ pub fn id<I>(self, id: I) -> F::Result
+ where I: ToIdent
+ {
+ self.path().id(id).build()
+ }
+
+ pub fn build_lit(self, lit: P<ast::Lit>) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Lit(lit))
+ }
+
+ pub fn lit(self) -> LitBuilder<Self> {
+ LitBuilder::with_callback(self)
+ }
+
+ pub fn bool(self, value: bool) -> F::Result {
+ self.lit().bool(value)
+ }
+
+ pub fn true_(self) -> F::Result {
+ self.bool(true)
+ }
+
+ pub fn false_(self) -> F::Result {
+ self.bool(false)
+ }
+
+ pub fn int(self, value: i64) -> F::Result {
+ if value == ::std::i64::MIN {
+ self.neg().lit().int(value as u64)
+ } else if value < 0 {
+ self.neg().lit().int(-value as u64)
+ } else {
+ self.lit().int(value as u64)
+ }
+ }
+
+ pub fn uint(self, value: u64) -> F::Result {
+ self.lit().uint(value as u64)
+ }
+
+ signed_int_method!(i8, u8);
+ signed_int_method!(i16, u16);
+ signed_int_method!(i32, u32);
+ signed_int_method!(i64, u64);
+ signed_int_method!(isize, usize);
+
+ pub fn usize(self, value: usize) -> F::Result {
+ self.lit().usize(value)
+ }
+
+ pub fn u8(self, value: u8) -> F::Result {
+ self.lit().u8(value)
+ }
+
+ pub fn u16(self, value: u16) -> F::Result {
+ self.lit().u16(value)
+ }
+
+ pub fn u32(self, value: u32) -> F::Result {
+ self.lit().u32(value)
+ }
+
+ pub fn u64(self, value: u64) -> F::Result {
+ self.lit().u64(value)
+ }
+
+ pub fn f32<S>(self, value: S) -> F::Result
+ where S: ToInternedString,
+ {
+ self.lit().f32(value)
+ }
+
+ pub fn f64<S>(self, value: S) -> F::Result
+ where S: ToInternedString,
+ {
+ self.lit().f64(value)
+ }
+
+ pub fn str<S>(self, value: S) -> F::Result
+ where S: ToInternedString,
+ {
+ self.lit().str(value)
+ }
+
+ pub fn build_unary(self, unop: ast::UnOp, expr: P<ast::Expr>) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Unary(unop, expr))
+ }
+
+ pub fn build_deref(self, expr: P<ast::Expr>) -> F::Result {
+ self.build_unary(ast::UnOp::Deref, expr)
+ }
+
+ pub fn build_not(self, expr: P<ast::Expr>) -> F::Result {
+ self.build_unary(ast::UnOp::Not, expr)
+ }
+
+ pub fn build_neg(self, expr: P<ast::Expr>) -> F::Result {
+ self.build_unary(ast::UnOp::Neg, expr)
+ }
+
+ pub fn unary(self, unop: ast::UnOp) -> ExprBuilder<ExprUnaryBuilder<F>> {
+ let span = self.span;
+ ExprBuilder::with_callback(ExprUnaryBuilder {
+ builder: self,
+ unop: unop,
+ }).span(span)
+ }
+
+ pub fn deref(self) -> ExprBuilder<ExprUnaryBuilder<F>> {
+ self.unary(ast::UnOp::Deref)
+ }
+
+ pub fn not(self) -> ExprBuilder<ExprUnaryBuilder<F>> {
+ self.unary(ast::UnOp::Not)
+ }
+
+ pub fn neg(self) -> ExprBuilder<ExprUnaryBuilder<F>> {
+ self.unary(ast::UnOp::Neg)
+ }
+
+ pub fn build_binary(self,
+ binop: ast::BinOpKind,
+ lhs: P<ast::Expr>,
+ rhs: P<ast::Expr>) -> F::Result {
+ let binop = respan(self.span, binop);
+ self.build_expr_kind(ast::ExprKind::Binary(binop, lhs, rhs))
+ }
+
+ pub fn build_add(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Add, lhs, rhs)
+ }
+
+ pub fn build_sub(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Sub, lhs, rhs)
+ }
+
+ pub fn build_mul(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Mul, lhs, rhs)
+ }
+
+ pub fn build_div(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Div, lhs, rhs)
+ }
+
+ pub fn build_rem(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Rem, lhs, rhs)
+ }
+
+ pub fn build_and(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::And, lhs, rhs)
+ }
+
+ pub fn build_or(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Or, lhs, rhs)
+ }
+
+ pub fn build_bit_xor(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::BitXor, lhs, rhs)
+ }
+
+ pub fn build_bit_and(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::BitAnd, lhs, rhs)
+ }
+
+ pub fn build_bit_or(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::BitOr, lhs, rhs)
+ }
+
+ pub fn build_shl(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Shl, lhs, rhs)
+ }
+
+ pub fn build_shr(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Shr, lhs, rhs)
+ }
+
+ pub fn build_eq(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Eq, lhs, rhs)
+ }
+
+ pub fn build_lt(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Lt, lhs, rhs)
+ }
+
+ pub fn build_le(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Le, lhs, rhs)
+ }
+
+ pub fn build_ne(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Ne, lhs, rhs)
+ }
+
+ pub fn build_ge(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Ge, lhs, rhs)
+ }
+
+ pub fn build_gt(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_binary(ast::BinOpKind::Gt, lhs, rhs)
+ }
+
+ pub fn binary(self, binop: ast::BinOpKind) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ let span = self.span;
+ ExprBuilder::with_callback(ExprBinaryLhsBuilder {
+ builder: self,
+ binop: binop,
+ }).span(span)
+ }
+
+ pub fn add(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Add)
+ }
+
+ pub fn sub(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Sub)
+ }
+
+ pub fn mul(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Mul)
+ }
+
+ pub fn div(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Div)
+ }
+
+ pub fn rem(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Rem)
+ }
+
+ pub fn and(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::And)
+ }
+
+ pub fn or(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Or)
+ }
+
+ pub fn bit_xor(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::BitXor)
+ }
+
+ pub fn bit_and(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::BitAnd)
+ }
+
+ pub fn bit_or(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::BitOr)
+ }
+
+ pub fn shl(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Shl)
+ }
+
+ pub fn shr(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Shr)
+ }
+
+ pub fn eq(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Eq)
+ }
+
+ pub fn lt(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Lt)
+ }
+
+ pub fn le(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Le)
+ }
+
+ pub fn ne(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Ne)
+ }
+
+ pub fn ge(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Ge)
+ }
+
+ pub fn gt(self) -> ExprBuilder<ExprBinaryLhsBuilder<F>> {
+ self.binary(ast::BinOpKind::Gt)
+ }
+
+ pub fn ref_(self) -> ExprBuilder<ExprRefBuilder<F>> {
+ let span = self.span;
+ ExprBuilder::with_callback(ExprRefBuilder {
+ builder: self,
+ mutability: ast::Mutability::Immutable,
+ }).span(span)
+ }
+
+ pub fn mut_ref(self) -> ExprBuilder<ExprRefBuilder<F>> {
+ let span = self.span;
+ ExprBuilder::with_callback(ExprRefBuilder {
+ builder: self,
+ mutability: ast::Mutability::Mutable,
+ }).span(span)
+ }
+
+ pub fn break_(self) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Break(None))
+ }
+
+ pub fn break_to<I>(self, label: I) -> F::Result
+ where I: ToIdent,
+ {
+ let label = respan(self.span, label.to_ident());
+ self.build_expr_kind(ast::ExprKind::Break(Some(label)))
+ }
+
+ pub fn continue_(self) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Continue(None))
+ }
+
+ pub fn continue_to<I>(self, label: I) -> F::Result
+ where I: ToIdent,
+ {
+ let label = respan(self.span, label.to_ident());
+ self.build_expr_kind(ast::ExprKind::Continue(Some(label)))
+ }
+
+ pub fn return_(self) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Ret(None))
+ }
+
+ pub fn return_expr(self) -> ExprBuilder<ExprReturnBuilder<F>> {
+ let span = self.span;
+ ExprBuilder::with_callback(ExprReturnBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn unit(self) -> F::Result {
+ self.tuple().build()
+ }
+
+ pub fn tuple(self) -> ExprTupleBuilder<F> {
+ ExprTupleBuilder {
+ builder: self,
+ exprs: Vec::new(),
+ }
+ }
+
+ pub fn struct_path<P>(self, path: P) -> ExprStructPathBuilder<F>
+ where P: IntoPath,
+ {
+ let span = self.span;
+ let path = path.into_path();
+ ExprStructPathBuilder {
+ builder: self,
+ span: span,
+ path: path,
+ fields: vec![],
+ }
+ }
+
+ pub fn struct_id<T>(self, id: T) -> ExprStructPathBuilder<F>
+ where T: ToIdent,
+ {
+ self.struct_().id(id).build()
+ }
+
+ pub fn struct_(self) -> PathBuilder<ExprStructBuilder<F>> {
+ PathBuilder::with_callback(ExprStructBuilder {
+ builder: self,
+ })
+ }
+
+ pub fn self_(self) -> F::Result {
+ self.id("self")
+ }
+
+ pub fn none(self) -> F::Result {
+ self.path()
+ .global()
+ .id("std").id("option").id("Option").id("None")
+ .build()
+ }
+
+ pub fn some(self) -> ExprBuilder<ExprPathBuilder<F>> {
+ let path = PathBuilder::new()
+ .span(self.span)
+ .global()
+ .id("std").id("option").id("Option").id("Some")
+ .build();
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprPathBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ pub fn ok(self) -> ExprBuilder<ExprPathBuilder<F>> {
+ let path = PathBuilder::new()
+ .span(self.span)
+ .global()
+ .id("std").id("result").id("Result").id("Ok")
+ .build();
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprPathBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ pub fn err(self) -> ExprBuilder<ExprPathBuilder<F>> {
+ let path = PathBuilder::new()
+ .span(self.span)
+ .global()
+ .id("std").id("result").id("Result").id("Err")
+ .build();
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprPathBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ /// Implement a call for `::std::convert::From::from(value)`
+ pub fn from(self) -> ExprBuilder<ExprPathBuilder<F>> {
+ let path = PathBuilder::new()
+ .span(self.span)
+ .global()
+ .ids(&["std", "convert", "From", "from"])
+ .build();
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprPathBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ pub fn phantom_data(self) -> F::Result {
+ self.path()
+ .global()
+ .ids(&["std", "marker", "PhantomData"])
+ .build()
+ }
+
+ pub fn call(self) -> ExprBuilder<ExprCallBuilder<F>> {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprCallBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn method_call<I>(self, id: I) -> ExprBuilder<ExprMethodCallBuilder<F>>
+ where I: ToIdent,
+ {
+ let id = respan(self.span, id.to_ident());
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprMethodCallBuilder {
+ builder: self,
+ id: id,
+ }).span(span)
+ }
+
+ pub fn build_block(self, block: P<ast::Block>) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Block(block))
+ }
+
+ pub fn block(self) -> BlockBuilder<Self> {
+ BlockBuilder::with_callback(self)
+ }
+
+ pub fn build_assign(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Assign(lhs, rhs))
+ }
+
+ pub fn assign(self) -> ExprBuilder<ExprAssignBuilder<F>> {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprAssignBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn build_assign_op(self,
+ binop: ast::BinOpKind,
+ lhs: P<ast::Expr>,
+ rhs: P<ast::Expr>) -> F::Result {
+ let binop = respan(self.span, binop);
+ self.build_expr_kind(ast::ExprKind::AssignOp(binop, lhs, rhs))
+ }
+
+ pub fn assign_op(self, binop: ast::BinOpKind) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprAssignOpBuilder {
+ builder: self,
+ binop: binop,
+ }).span(span)
+ }
+
+ pub fn add_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::Add)
+ }
+
+ pub fn sub_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::Sub)
+ }
+
+ pub fn mul_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::Mul)
+ }
+
+ pub fn rem_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::Rem)
+ }
+
+ pub fn and_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::And)
+ }
+
+ pub fn or_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::Or)
+ }
+
+ pub fn bit_xor_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::BitXor)
+ }
+
+ pub fn bit_and_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::BitAnd)
+ }
+
+ pub fn bit_or_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::BitOr)
+ }
+
+ pub fn bit_shl_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::Shl)
+ }
+
+ pub fn bit_shr_assign(self) -> ExprBuilder<ExprAssignOpBuilder<F>> {
+ self.assign_op(ast::BinOpKind::Shr)
+ }
+
+ pub fn build_index(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Index(lhs, rhs))
+ }
+
+ pub fn index(self) -> ExprBuilder<ExprIndexBuilder<F>> {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprIndexBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn range(self) -> ExprRangeBuilder<F> {
+ ExprRangeBuilder {
+ builder: self,
+ }
+ }
+
+ pub fn build_repeat(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Repeat(lhs, rhs))
+ }
+
+ pub fn repeat(self) -> ExprBuilder<ExprRepeatBuilder<F>> {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprRepeatBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn loop_(self) -> ExprLoopBuilder<F> {
+ let span = self.span;
+
+ ExprLoopBuilder {
+ builder: self,
+ span: span,
+ label: None,
+ }
+ }
+
+ pub fn if_(self) -> ExprBuilder<ExprIfBuilder<F>> {
+ let span = self.span;
+ ExprBuilder::with_callback(ExprIfBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn match_(self) -> ExprBuilder<ExprMatchBuilder<F>> {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprMatchBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn paren(self) -> ExprBuilder<ExprParenBuilder<F>> {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprParenBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn field<I>(self, id: I) -> ExprBuilder<ExprFieldBuilder<F>>
+ where I: ToIdent,
+ {
+ let id = respan(self.span, id.to_ident());
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprFieldBuilder {
+ builder: self,
+ id: id,
+ }).span(span)
+ }
+
+ pub fn tup_field(self, index: usize) -> ExprBuilder<ExprTupFieldBuilder<F>> {
+ let index = respan(self.span, index);
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprTupFieldBuilder {
+ builder: self,
+ index: index,
+ }).span(span)
+ }
+
+ pub fn box_(self) -> ExprBuilder<ExprPathBuilder<F>> {
+ let path = PathBuilder::new()
+ .span(self.span)
+ .global()
+ .id("std").id("boxed").id("Box").id("new")
+ .build();
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprPathBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ pub fn rc(self) -> ExprBuilder<ExprPathBuilder<F>> {
+ let path = PathBuilder::new()
+ .span(self.span)
+ .global()
+ .id("std").id("rc").id("Rc").id("new")
+ .build();
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprPathBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ pub fn arc(self) -> ExprBuilder<ExprPathBuilder<F>> {
+ let path = PathBuilder::new()
+ .span(self.span)
+ .global()
+ .id("std").id("arc").id("Arc").id("new")
+ .build();
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprPathBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ pub fn default(self) -> F::Result {
+ let path = PathBuilder::new()
+ .span(self.span)
+ .global()
+ .ids(&["std", "default", "Default", "default"])
+ .build();
+
+ self.call()
+ .build_path(path)
+ .build()
+ }
+
+ pub fn slice(self) -> ExprSliceBuilder<F> {
+ ExprSliceBuilder {
+ builder: self,
+ exprs: Vec::new(),
+ }
+ }
+
+ pub fn vec(self) -> ExprSliceBuilder<ExprVecBuilder<F>> {
+ ExprBuilder::with_callback(ExprVecBuilder {
+ builder: self,
+ }).slice()
+ }
+
+ /// Represents an equivalent to `try!(...)`. Generates:
+ ///
+ /// match $expr {
+ /// ::std::result::Result::Ok(expr) => expr,
+ /// ::std::result::Result::Err(err) => {
+ /// return ::std::result::Result::Err(::std::convert::From::from(err))
+ /// }
+ /// }
+ pub fn try(self) -> ExprBuilder<ExprTryBuilder<F>> {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprTryBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ pub fn closure(self) -> ExprClosureBuilder<F> {
+ ExprClosureBuilder {
+ span: self.span,
+ builder: self,
+ capture_by: ast::CaptureBy::Ref,
+ }
+ }
+
+ pub fn while_(self) -> ExprBuilder<ExprWhileBuilder<F>> {
+ ExprBuilder::with_callback(ExprWhileBuilder {
+ builder: self,
+ })
+ }
+
+ pub fn type_(self) -> ExprBuilder<ExprTypeBuilder<F>> {
+ ExprBuilder::with_callback(ExprTypeBuilder {
+ builder: self,
+ })
+ }
+
+ pub fn build_mac(self, mac: ast::Mac) -> F::Result {
+ self.build_expr_kind(ast::ExprKind::Mac(mac))
+ }
+
+ pub fn mac(self) -> MacBuilder<Self> {
+ let span = self.span;
+ MacBuilder::with_callback(self).span(span)
+ }
+}
+
+impl<F> Invoke<ast::Attribute> for ExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = Self;
+
+ fn invoke(self, attr: ast::Attribute) -> Self {
+ self.with_attr(attr)
+ }
+}
+
+impl<F> Invoke<P<ast::Lit>> for ExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, lit: P<ast::Lit>) -> F::Result {
+ self.build_lit(lit)
+ }
+}
+
+impl<F> Invoke<ast::Path> for ExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, path: ast::Path) -> F::Result {
+ self.build_path(path)
+ }
+}
+
+impl<F> Invoke<(ast::QSelf, ast::Path)> for ExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, (qself, path): (ast::QSelf, ast::Path)) -> F::Result {
+ self.build_qpath(qself, path)
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, block: P<ast::Block>) -> F::Result {
+ self.build_block(block)
+ }
+}
+
+impl<F> Invoke<ast::Mac> for ExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, mac: ast::Mac) -> F::Result {
+ self.build_mac(mac)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprUnaryBuilder<F> {
+ builder: ExprBuilder<F>,
+ unop: ast::UnOp,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprUnaryBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.builder.build_unary(self.unop, expr)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprBinaryLhsBuilder<F> {
+ builder: ExprBuilder<F>,
+ binop: ast::BinOpKind,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprBinaryLhsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprBuilder<ExprBinaryRhsBuilder<F>>;
+
+ fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprBinaryRhsBuilder<F>> {
+ ExprBuilder::with_callback(ExprBinaryRhsBuilder {
+ builder: self.builder,
+ binop: self.binop,
+ lhs: lhs,
+ })
+ }
+}
+
+pub struct ExprBinaryRhsBuilder<F> {
+ builder: ExprBuilder<F>,
+ binop: ast::BinOpKind,
+ lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprBinaryRhsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+ self.builder.build_binary(self.binop, self.lhs, rhs)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprReturnBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprReturnBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Ret(Some(expr)))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTupleBuilder<F> {
+ builder: ExprBuilder<F>,
+ exprs: Vec<P<ast::Expr>>,
+}
+
+impl<F: Invoke<P<ast::Expr>>> ExprTupleBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ pub fn with_exprs<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::Expr>>,
+ {
+ self.exprs.extend(iter);
+ self
+ }
+
+ pub fn expr(self) -> ExprBuilder<Self> {
+ ExprBuilder::with_callback(self)
+ }
+
+ pub fn build(self) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Tup(self.exprs))
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprTupleBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ type Result = ExprTupleBuilder<F>;
+
+ fn invoke(mut self, expr: P<ast::Expr>) -> Self {
+ self.exprs.push(expr);
+ self
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprStructBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<ast::Path> for ExprStructBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ type Result = ExprStructPathBuilder<F>;
+
+ fn invoke(self, path: ast::Path) -> ExprStructPathBuilder<F> {
+ self.builder.struct_path(path)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprStructPathBuilder<F> {
+ builder: ExprBuilder<F>,
+ span: Span,
+ path: ast::Path,
+ fields: Vec<ast::Field>,
+}
+
+impl<F> ExprStructPathBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_fields<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Field>,
+ {
+ self.fields.extend(iter);
+ self
+ }
+
+ pub fn with_id_exprs<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=(ast::Ident, P<ast::Expr>)>,
+ {
+ for (id, expr) in iter {
+ self = self.field(id).build(expr);
+ }
+
+ self
+ }
+
+ pub fn field<I>(self, id: I) -> ExprBuilder<ExprStructFieldBuilder<I, F>>
+ where I: ToIdent,
+ {
+ let span = self.span;
+
+ ExprBuilder::with_callback(ExprStructFieldBuilder {
+ builder: self,
+ id: id,
+ }).span(span)
+ }
+
+ pub fn build_with(self) -> ExprBuilder<Self> {
+ ExprBuilder::with_callback(self)
+ }
+
+ pub fn build(self) -> F::Result {
+ let expr_kind = ast::ExprKind::Struct(self.path, self.fields, None);
+ self.builder.build_expr_kind(expr_kind)
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprStructPathBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ let expr_kind = ast::ExprKind::Struct(self.path, self.fields, Some(expr));
+ self.builder.build_expr_kind(expr_kind)
+ }
+}
+
+pub struct ExprStructFieldBuilder<I, F> {
+ builder: ExprStructPathBuilder<F>,
+ id: I,
+}
+
+impl<I, F> Invoke<P<ast::Expr>> for ExprStructFieldBuilder<I, F>
+ where I: ToIdent,
+ F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprStructPathBuilder<F>;
+
+ fn invoke(mut self, expr: P<ast::Expr>) -> ExprStructPathBuilder<F> {
+ let field = ast::Field {
+ ident: respan(self.builder.span, self.id.to_ident()),
+ expr: expr,
+ span: self.builder.span,
+ is_shorthand: false,
+ };
+ self.builder.fields.push(field);
+ self.builder
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprCallBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprCallBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprCallArgsBuilder<F>;
+
+ fn invoke(self, expr: P<ast::Expr>) -> ExprCallArgsBuilder<F> {
+ ExprCallArgsBuilder {
+ builder: self.builder,
+ fn_: expr,
+ args: vec![],
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprCallArgsBuilder<F> {
+ builder: ExprBuilder<F>,
+ fn_: P<ast::Expr>,
+ args: Vec<P<ast::Expr>>,
+}
+
+impl<F> ExprCallArgsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn with_args<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::Expr>>,
+ {
+ self.args.extend(iter);
+ self
+ }
+
+ pub fn with_arg(mut self, arg: P<ast::Expr>) -> Self {
+ self.args.push(arg);
+ self
+ }
+
+ pub fn arg(self) -> ExprBuilder<Self> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Call(self.fn_, self.args))
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprCallArgsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = Self;
+
+ fn invoke(self, arg: P<ast::Expr>) -> Self {
+ self.with_arg(arg)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprMethodCallBuilder<F> {
+ builder: ExprBuilder<F>,
+ id: ast::SpannedIdent,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprMethodCallBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprMethodCallArgsBuilder<F>;
+
+ fn invoke(self, expr: P<ast::Expr>) -> ExprMethodCallArgsBuilder<F> {
+ ExprMethodCallArgsBuilder {
+ builder: self.builder,
+ id: self.id,
+ tys: vec![],
+ args: vec![expr],
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprMethodCallArgsBuilder<F> {
+ builder: ExprBuilder<F>,
+ id: ast::SpannedIdent,
+ tys: Vec<P<ast::Ty>>,
+ args: Vec<P<ast::Expr>>,
+}
+
+impl<F> ExprMethodCallArgsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn with_tys<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::Ty>>,
+ {
+ self.tys.extend(iter);
+ self
+ }
+
+ pub fn with_ty(mut self, ty: P<ast::Ty>) -> Self {
+ self.tys.push(ty);
+ self
+ }
+
+ pub fn ty(self) -> TyBuilder<Self> {
+ let span = self.builder.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+
+ pub fn with_args<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::Expr>>,
+ {
+ self.args.extend(iter);
+ self
+ }
+
+ pub fn with_arg(mut self, arg: P<ast::Expr>) -> Self {
+ self.args.push(arg);
+ self
+ }
+
+ pub fn arg(self) -> ExprBuilder<Self> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::MethodCall(self.id, self.tys, self.args))
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ExprMethodCallArgsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = Self;
+
+ fn invoke(self, ty: P<ast::Ty>) -> Self {
+ self.with_ty(ty)
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprMethodCallArgsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = Self;
+
+ fn invoke(self, arg: P<ast::Expr>) -> Self {
+ self.with_arg(arg)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRefBuilder<F> {
+ builder: ExprBuilder<F>,
+ mutability: ast::Mutability,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRefBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::AddrOf(self.mutability, expr))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprPathBuilder<F> {
+ builder: ExprBuilder<F>,
+ path: ast::Path,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprPathBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, arg: P<ast::Expr>) -> F::Result {
+ self.builder.call()
+ .build_path(self.path)
+ .with_arg(arg)
+ .build()
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprAssignBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprAssignBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprBuilder<ExprAssignLhsBuilder<F>>;
+
+ fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprAssignLhsBuilder<F>> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(ExprAssignLhsBuilder {
+ builder: self.builder,
+ lhs: lhs,
+ }).span(span)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprAssignLhsBuilder<F> {
+ builder: ExprBuilder<F>,
+ lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprAssignLhsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+ self.builder.build_assign(self.lhs, rhs)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprAssignOpBuilder<F> {
+ builder: ExprBuilder<F>,
+ binop: ast::BinOpKind,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprAssignOpBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprBuilder<ExprAssignOpLhsBuilder<F>>;
+
+ fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprAssignOpLhsBuilder<F>> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(ExprAssignOpLhsBuilder {
+ builder: self.builder,
+ binop: self.binop,
+ lhs: lhs,
+ }).span(span)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprAssignOpLhsBuilder<F> {
+ builder: ExprBuilder<F>,
+ binop: ast::BinOpKind,
+ lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprAssignOpLhsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+ self.builder.build_assign_op(self.binop, self.lhs, rhs)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIndexBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprIndexBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprBuilder<ExprIndexLhsBuilder<F>>;
+
+ fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprIndexLhsBuilder<F>> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(ExprIndexLhsBuilder {
+ builder: self.builder,
+ lhs: lhs,
+ }).span(span)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIndexLhsBuilder<F> {
+ builder: ExprBuilder<F>,
+ lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprIndexLhsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+ self.builder.build_index(self.lhs, rhs)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRangeBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> ExprRangeBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn from(self) -> ExprBuilder<Self> {
+ ExprBuilder::with_callback(self)
+ }
+
+ pub fn to(self) -> ExprBuilder<ExprRangeToBuilder<F>> {
+ self.from_opt(None).to()
+ }
+
+ pub fn to_inclusive(self) -> ExprBuilder<ExprRangeToBuilder<F>> {
+ self.from_opt(None).to_inclusive()
+ }
+
+ pub fn from_opt(self, from: Option<P<ast::Expr>>) -> ExprRangeFromBuilder<F> {
+ ExprRangeFromBuilder {
+ builder: self.builder,
+ from: from,
+ }
+ }
+
+ pub fn build(self) -> F::Result {
+ self.from_opt(None).build()
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRangeBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprRangeFromBuilder<F>;
+
+ fn invoke(self, from: P<ast::Expr>) -> ExprRangeFromBuilder<F> {
+ self.from_opt(Some(from))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRangeFromBuilder<F> {
+ builder: ExprBuilder<F>,
+ from: Option<P<ast::Expr>>,
+}
+
+impl<F> ExprRangeFromBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn to(self) -> ExprBuilder<ExprRangeToBuilder<F>> {
+ ExprBuilder::with_callback(ExprRangeToBuilder {
+ builder: self,
+ limit: ast::RangeLimits::HalfOpen,
+ })
+ }
+
+ pub fn to_inclusive(self) -> ExprBuilder<ExprRangeToBuilder<F>> {
+ ExprBuilder::with_callback(ExprRangeToBuilder {
+ builder: self,
+ limit: ast::RangeLimits::Closed,
+ })
+ }
+
+ pub fn build(self) -> F::Result {
+ self.to_opt(None, ast::RangeLimits::HalfOpen)
+ }
+
+ pub fn to_opt(self, to: Option<P<ast::Expr>>, limit: ast::RangeLimits) -> F::Result {
+ let kind = ast::ExprKind::Range(self.from, to, limit);
+ self.builder.build_expr_kind(kind)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRangeToBuilder<F> {
+ builder: ExprRangeFromBuilder<F>,
+ limit: ast::RangeLimits,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRangeToBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.builder.to_opt(Some(expr), self.limit)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRepeatBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRepeatBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprBuilder<ExprRepeatLhsBuilder<F>>;
+
+ fn invoke(self, lhs: P<ast::Expr>) -> ExprBuilder<ExprRepeatLhsBuilder<F>> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(ExprRepeatLhsBuilder {
+ builder: self.builder,
+ lhs: lhs,
+ }).span(span)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprRepeatLhsBuilder<F> {
+ builder: ExprBuilder<F>,
+ lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprRepeatLhsBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, rhs: P<ast::Expr>) -> F::Result {
+ self.builder.build_repeat(self.lhs, rhs)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprLoopBuilder<F> {
+ builder: ExprBuilder<F>,
+ span: Span,
+ label: Option<Spanned<ast::Ident>>,
+}
+
+impl<F> ExprLoopBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn label<I>(mut self, id: I) -> Self
+ where I: ToIdent,
+ {
+ self.label = Some(respan(self.span, id.to_ident()));
+ self
+ }
+
+ pub fn block(self) -> BlockBuilder<Self> {
+ BlockBuilder::with_callback(self)
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprLoopBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, block: P<ast::Block>) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Loop(block, self.label))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIfBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprIfBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprIfThenBuilder<F>;
+
+ fn invoke(self, condition: P<ast::Expr>) -> ExprIfThenBuilder<F> {
+ ExprIfThenBuilder {
+ builder: self.builder,
+ condition: condition,
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIfThenBuilder<F> {
+ builder: ExprBuilder<F>,
+ condition: P<ast::Expr>,
+}
+
+impl<F> ExprIfThenBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn build_then(self, block: P<ast::Block>) -> ExprIfThenElseBuilder<F> {
+ ExprIfThenElseBuilder {
+ builder: self.builder,
+ condition: self.condition,
+ then: block,
+ else_ifs: Vec::new(),
+ }
+ }
+
+ pub fn then(self) -> BlockBuilder<Self> {
+ BlockBuilder::with_callback(self)
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprIfThenBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprIfThenElseBuilder<F>;
+
+ fn invoke(self, block: P<ast::Block>) -> ExprIfThenElseBuilder<F> {
+ self.build_then(block)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprIfThenElseBuilder<F> {
+ builder: ExprBuilder<F>,
+ condition: P<ast::Expr>,
+ then: P<ast::Block>,
+ else_ifs: Vec<(P<ast::Expr>, P<ast::Block>)>,
+}
+
+impl<F> ExprIfThenElseBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn else_if(self) -> ExprBuilder<ExprElseIfBuilder<F>> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(ExprElseIfBuilder {
+ builder: self,
+ }).span(span)
+ }
+
+ fn build_else_expr(self, mut else_: P<ast::Expr>) -> F::Result {
+ for (cond, block) in self.else_ifs.into_iter().rev() {
+ else_ = ExprBuilder::new().if_()
+ .build(cond)
+ .build_then(block)
+ .build_else_expr(else_);
+ }
+
+ self.builder.build_expr_kind(ast::ExprKind::If(self.condition, self.then, Some(else_)))
+ }
+
+ pub fn build_else(self, block: P<ast::Block>) -> F::Result {
+ let else_ = ExprBuilder::new().build_block(block);
+ self.build_else_expr(else_)
+ }
+
+ pub fn else_(self) -> BlockBuilder<Self> {
+ BlockBuilder::with_callback(self)
+ }
+
+ pub fn build(self) -> F::Result {
+ let mut else_ifs = self.else_ifs.into_iter().rev();
+
+ let else_ = match else_ifs.next() {
+ Some((cond, block)) => {
+ let mut else_ = ExprBuilder::new().if_()
+ .build(cond)
+ .build_then(block)
+ .build();
+
+ for (cond, block) in else_ifs.into_iter().rev() {
+ else_ = ExprBuilder::new().if_()
+ .build(cond)
+ .build_then(block)
+ .build_else_expr(else_);
+ }
+
+ Some(else_)
+ }
+ None => None
+ };
+
+ self.builder.build_expr_kind(ast::ExprKind::If(self.condition, self.then, else_))
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprIfThenElseBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, block: P<ast::Block>) -> F::Result {
+ self.build_else(block)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprElseIfBuilder<F> {
+ builder: ExprIfThenElseBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprElseIfBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprElseIfThenBuilder<F>;
+
+ fn invoke(self, expr: P<ast::Expr>) -> ExprElseIfThenBuilder<F> {
+ ExprElseIfThenBuilder {
+ builder: self.builder,
+ condition: expr,
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprElseIfThenBuilder<F> {
+ builder: ExprIfThenElseBuilder<F>,
+ condition: P<ast::Expr>,
+}
+
+impl<F> ExprElseIfThenBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn build_then(mut self, block: P<ast::Block>) -> ExprIfThenElseBuilder<F> {
+ self.builder.else_ifs.push((self.condition, block));
+ self.builder
+ }
+
+ pub fn then(self) -> BlockBuilder<Self> {
+ BlockBuilder::with_callback(self)
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprElseIfThenBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprIfThenElseBuilder<F>;
+
+ fn invoke(self, block: P<ast::Block>) -> ExprIfThenElseBuilder<F> {
+ self.build_then(block)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprMatchBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprMatchBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprMatchArmBuilder<F>;
+
+ fn invoke(self, expr: P<ast::Expr>) -> ExprMatchArmBuilder<F> {
+ ExprMatchArmBuilder {
+ builder: self.builder,
+ expr: expr,
+ arms: Vec::new(),
+ }
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprMatchArmBuilder<F> {
+ builder: ExprBuilder<F>,
+ expr: P<ast::Expr>,
+ arms: Vec<ast::Arm>,
+}
+
+impl<F> ExprMatchArmBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn with_arms<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Arm>,
+ {
+ self.arms.extend(iter);
+ self
+ }
+
+ pub fn with_arm(mut self, arm: ast::Arm) -> Self {
+ self.arms.push(arm);
+ self
+ }
+
+ pub fn arm(self) -> ArmBuilder<Self> {
+ ArmBuilder::with_callback(self)
+ }
+
+ pub fn build(self) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Match(self.expr, self.arms))
+ }
+}
+
+impl<F> Invoke<ast::Arm> for ExprMatchArmBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = Self;
+
+ fn invoke(self, arm: ast::Arm) -> Self {
+ self.with_arm(arm)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprParenBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprParenBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Paren(expr))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprFieldBuilder<F> {
+ builder: ExprBuilder<F>,
+ id: ast::SpannedIdent,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprFieldBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Field(expr, self.id))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTupFieldBuilder<F> {
+ builder: ExprBuilder<F>,
+ index: Spanned<usize>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprTupFieldBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::TupField(expr, self.index))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprSliceBuilder<F> {
+ builder: ExprBuilder<F>,
+ exprs: Vec<P<ast::Expr>>,
+}
+
+impl<F: Invoke<P<ast::Expr>>> ExprSliceBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ pub fn with_exprs<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::Expr>>,
+ {
+ self.exprs.extend(iter);
+ self
+ }
+
+ pub fn expr(self) -> ExprBuilder<Self> {
+ let span = self.builder.span;
+ ExprBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Vec(self.exprs))
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprSliceBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ type Result = ExprSliceBuilder<F>;
+
+ fn invoke(mut self, expr: P<ast::Expr>) -> Self {
+ self.exprs.push(expr);
+ self
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprVecBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprVecBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ let qpath = ExprBuilder::new().qpath()
+ .ty().slice().infer()
+ .id("into_vec");
+
+ self.builder.call()
+ .build(qpath)
+ .arg().box_().build(expr)
+ .build()
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTryBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprTryBuilder<F>
+ where F: Invoke<P<ast::Expr>>
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ // ::std::result::Result::Ok(value) => value,
+ let ok_arm = ArmBuilder::new().span(self.builder.span)
+ .pat().ok().id("value")
+ .body().id("value");
+
+ // ::std::result::Result::Err(err) =>
+ // return ::std::convert::From::from(err),
+ let err_arm = ArmBuilder::new().span(self.builder.span)
+ .pat().err().id("err")
+ .body().return_expr().err().from().id("err");
+
+ // match $expr {
+ // $ok_arm,
+ // $err_arm,
+ // }
+ self.builder.match_().build(expr.clone())
+ .with_arm(ok_arm)
+ .with_arm(err_arm)
+ .build()
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprClosureBuilder<F> {
+ builder: ExprBuilder<F>,
+ capture_by: ast::CaptureBy,
+ span: Span,
+}
+
+impl<F> ExprClosureBuilder<F> {
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn by_value(mut self) -> Self {
+ self.capture_by = ast::CaptureBy::Value;
+ self
+ }
+
+ pub fn by_ref(mut self) -> Self {
+ self.capture_by = ast::CaptureBy::Ref;
+ self
+ }
+
+ pub fn fn_decl(self) -> FnDeclBuilder<Self> {
+ FnDeclBuilder::with_callback(self)
+ }
+
+ pub fn build_fn_decl(self, fn_decl: P<ast::FnDecl>) -> ExprClosureExprBuilder<F> {
+ ExprClosureExprBuilder {
+ builder: self.builder,
+ capture_by: self.capture_by,
+ fn_decl: fn_decl,
+ span: self.span,
+ }
+ }
+}
+
+impl<F> Invoke<P<ast::FnDecl>> for ExprClosureBuilder<F> {
+ type Result = ExprClosureExprBuilder<F>;
+
+ fn invoke(self, fn_decl: P<ast::FnDecl>) -> ExprClosureExprBuilder<F> {
+ self.build_fn_decl(fn_decl)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprClosureExprBuilder<F> {
+ builder: ExprBuilder<F>,
+ capture_by: ast::CaptureBy,
+ fn_decl: P<ast::FnDecl>,
+ span: Span,
+}
+
+impl<F> ExprClosureExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn expr(self) -> ExprBuilder<Self> {
+ let span = self.span;
+ ExprBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build_expr(self, expr: P<ast::Expr>) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Closure(self.capture_by, self.fn_decl, expr, self.span))
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprClosureExprBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, expr: P<ast::Expr>) -> F::Result {
+ self.build_expr(expr)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprWhileBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprWhileBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = ExprWhileBlockBuilder<F>;
+
+ fn invoke(self, condition: P<ast::Expr>) -> ExprWhileBlockBuilder<F> {
+ ExprWhileBlockBuilder {
+ span: self.builder.span,
+ builder: self.builder,
+ condition: condition,
+ pat: None,
+ label: None,
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprWhileBlockBuilder<F> {
+ builder: ExprBuilder<F>,
+ condition: P<ast::Expr>,
+ pat: Option<P<ast::Pat>>,
+ span: Span,
+ label: Option<ast::SpannedIdent>,
+}
+
+impl<F> ExprWhileBlockBuilder<F> {
+ pub fn pat(self) -> PatBuilder<Self> {
+ PatBuilder::with_callback(self)
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn label<I>(mut self, id: I) -> Self
+ where I: ToIdent,
+ {
+ self.label = Some(respan(self.span, id.to_ident()));
+ self
+ }
+
+ pub fn build_pat(mut self, pat: P<ast::Pat>) -> Self {
+ self.pat = Some(pat);
+ self
+ }
+}
+
+impl<F> ExprWhileBlockBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ pub fn block(self) -> BlockBuilder<Self> {
+ BlockBuilder::with_callback(self)
+ }
+
+ pub fn build_block(self, block: P<ast::Block>) -> F::Result {
+ match self.pat {
+ Some(p) => self.builder.build_expr_kind(ast::ExprKind::WhileLet(
+ p, self.condition, block, self.label)),
+ None => self.builder.build_expr_kind(ast::ExprKind::While(
+ self.condition, block, self.label)),
+ }
+ }
+}
+
+impl<F> Invoke<P<ast::Pat>> for ExprWhileBlockBuilder<F> {
+ type Result = Self;
+
+ fn invoke(self, pat: P<ast::Pat>) -> Self {
+ self.build_pat(pat)
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ExprWhileBlockBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, block: P<ast::Block>) -> F::Result {
+ self.build_block(block)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTypeBuilder<F> {
+ builder: ExprBuilder<F>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for ExprTypeBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = TyBuilder<ExprTypeTyBuilder<F>>;
+
+ fn invoke(self, expr: P<ast::Expr>) -> TyBuilder<ExprTypeTyBuilder<F>> {
+ TyBuilder::with_callback(ExprTypeTyBuilder {
+ builder: self.builder,
+ expr: expr,
+ })
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ExprTypeTyBuilder<F> {
+ builder: ExprBuilder<F>,
+ expr: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Ty>> for ExprTypeTyBuilder<F>
+ where F: Invoke<P<ast::Expr>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+ self.builder.build_expr_kind(ast::ExprKind::Type(self.expr, ty))
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/fn_decl.rs
@@ -0,0 +1,262 @@
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span, respan};
+use syntax::ptr::P;
+
+use ident::ToIdent;
+use invoke::{Invoke, Identity};
+use pat::PatBuilder;
+use self_::SelfBuilder;
+use ty::TyBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct FnDeclBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ args: Vec<ast::Arg>,
+ variadic: bool,
+}
+
+impl FnDeclBuilder {
+ pub fn new() -> FnDeclBuilder {
+ FnDeclBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> FnDeclBuilder<F>
+ where F: Invoke<P<ast::FnDecl>>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ FnDeclBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ args: Vec::new(),
+ variadic: false,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn variadic(mut self) -> Self {
+ self.variadic = true;
+ self
+ }
+
+ pub fn with_self(self, explicit_self: ast::ExplicitSelf) -> Self {
+ let self_ident = respan(self.span, "self".to_ident());
+ self.with_arg(ast::Arg::from_self(explicit_self, self_ident))
+ }
+
+ pub fn self_(self) -> SelfBuilder<Self> {
+ SelfBuilder::with_callback(self)
+ }
+
+ pub fn with_arg(mut self, arg: ast::Arg) -> Self {
+ self.args.push(arg);
+ self
+ }
+
+ pub fn with_args<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Arg>
+ {
+ self.args.extend(iter);
+ self
+ }
+
+ pub fn arg(self) -> ArgBuilder<Self> {
+ ArgBuilder::with_callback(self)
+ }
+
+ pub fn arg_id<T>(self, id: T) -> ArgPatBuilder<Self>
+ where T: ToIdent,
+ {
+ self.arg().pat().id(id)
+ }
+
+ pub fn arg_ref_id<T>(self, id: T) -> ArgPatBuilder<Self>
+ where T: ToIdent,
+ {
+ self.arg().ref_id(id)
+ }
+
+ pub fn arg_mut_id<T>(self, id: T) -> ArgPatBuilder<Self>
+ where T: ToIdent,
+ {
+ self.arg().mut_id(id)
+ }
+
+ pub fn arg_ref_mut_id<T>(self, id: T) -> ArgPatBuilder<Self>
+ where T: ToIdent,
+ {
+ self.arg().ref_mut_id(id)
+ }
+
+ pub fn no_return(self) -> F::Result {
+ self.return_().never()
+ }
+
+ pub fn default_return(self) -> F::Result {
+ let ret_ty = ast::FunctionRetTy::Default(self.span);
+ self.build(ret_ty)
+ }
+
+ pub fn build_return(self, ty: P<ast::Ty>) -> F::Result {
+ self.build(ast::FunctionRetTy::Ty(ty))
+ }
+
+ pub fn return_(self) -> TyBuilder<Self> {
+ let span = self.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self, output: ast::FunctionRetTy) -> F::Result {
+ self.callback.invoke(P(ast::FnDecl {
+ inputs: self.args,
+ output: output,
+ variadic: self.variadic,
+ }))
+ }
+}
+
+impl<F> Invoke<ast::Arg> for FnDeclBuilder<F>
+ where F: Invoke<P<ast::FnDecl>>
+{
+ type Result = Self;
+
+ fn invoke(self, arg: ast::Arg) -> Self {
+ self.with_arg(arg)
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for FnDeclBuilder<F>
+ where F: Invoke<P<ast::FnDecl>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+ self.build_return(ty)
+ }
+}
+
+impl<F> Invoke<ast::ExplicitSelf> for FnDeclBuilder<F>
+ where F: Invoke<P<ast::FnDecl>>,
+{
+ type Result = Self;
+
+ fn invoke(self, explicit_self: ast::ExplicitSelf) -> Self {
+ self.with_self(explicit_self)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArgBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+}
+
+impl ArgBuilder {
+ pub fn new() -> Self {
+ ArgBuilder::with_callback( Identity)
+ }
+}
+
+impl<F> ArgBuilder<F>
+ where F: Invoke<ast::Arg>,
+{
+ pub fn with_callback(callback: F) -> ArgBuilder<F> {
+ ArgBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_pat(self, pat: P<ast::Pat>) -> ArgPatBuilder<F> {
+ ArgPatBuilder {
+ callback: self.callback,
+ span: self.span,
+ pat: pat,
+ }
+ }
+
+ pub fn pat(self) -> PatBuilder<Self> {
+ PatBuilder::with_callback(self)
+ }
+
+ pub fn id<T>(self, id: T) -> ArgPatBuilder<F>
+ where T: ToIdent,
+ {
+ self.pat().id(id)
+ }
+
+ pub fn ref_id<T>(self, id: T) -> ArgPatBuilder<F>
+ where T: ToIdent,
+ {
+ self.pat().ref_id(id)
+ }
+
+ pub fn mut_id<T>(self, id: T) -> ArgPatBuilder<F>
+ where T: ToIdent,
+ {
+ self.pat().mut_id(id)
+ }
+
+ pub fn ref_mut_id<T>(self, id: T) -> ArgPatBuilder<F>
+ where T: ToIdent,
+ {
+ self.pat().ref_mut_id(id)
+ }
+}
+
+impl<F> Invoke<P<ast::Pat>> for ArgBuilder<F>
+ where F: Invoke<ast::Arg>
+{
+ type Result = ArgPatBuilder<F>;
+
+ fn invoke(self, pat: P<ast::Pat>) -> Self::Result {
+ self.with_pat(pat)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ArgPatBuilder<F> {
+ callback: F,
+ span: Span,
+ pat: P<ast::Pat>,
+}
+
+impl<F> ArgPatBuilder<F>
+ where F: Invoke<ast::Arg>
+{
+ pub fn with_ty(self, ty: P<ast::Ty>) -> F::Result {
+ self.callback.invoke(ast::Arg {
+ id: ast::DUMMY_NODE_ID,
+ ty: ty,
+ pat: self.pat,
+ })
+ }
+
+ pub fn ty(self) -> TyBuilder<Self> {
+ let span = self.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ArgPatBuilder<F>
+ where F: Invoke<ast::Arg>
+{
+ type Result = F::Result;
+
+ fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+ self.with_ty(ty)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/generics.rs
@@ -0,0 +1,254 @@
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use ident::ToIdent;
+use invoke::{Invoke, Identity};
+use lifetime::{IntoLifetime, IntoLifetimeDef, LifetimeDefBuilder};
+use name::ToName;
+use path::IntoPath;
+use ty_param::TyParamBuilder;
+use where_predicate::WherePredicateBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct GenericsBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ lifetimes: Vec<ast::LifetimeDef>,
+ ty_params: Vec<ast::TyParam>,
+ predicates: Vec<ast::WherePredicate>,
+}
+
+impl GenericsBuilder {
+ pub fn new() -> Self {
+ GenericsBuilder::with_callback(Identity)
+ }
+
+ pub fn from_generics(generics: ast::Generics) -> Self {
+ GenericsBuilder::from_generics_with_callback(generics, Identity)
+ }
+}
+
+impl<F> GenericsBuilder<F>
+ where F: Invoke<ast::Generics>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ GenericsBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ lifetimes: Vec::new(),
+ ty_params: Vec::new(),
+ predicates: Vec::new(),
+ }
+ }
+
+ pub fn from_generics_with_callback(generics: ast::Generics, callback: F) -> Self {
+ GenericsBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ lifetimes: generics.lifetimes,
+ ty_params: generics.ty_params.into_vec(),
+ predicates: generics.where_clause.predicates,
+ }
+ }
+
+ pub fn with(self, generics: ast::Generics) -> Self {
+ self.with_lifetimes(generics.lifetimes.into_iter())
+ .with_ty_params(generics.ty_params.into_iter())
+ .with_predicates(generics.where_clause.predicates.into_iter())
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_lifetimes<I, L>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=L>,
+ L: IntoLifetimeDef,
+ {
+ let iter = iter.into_iter().map(|lifetime_def| lifetime_def.into_lifetime_def());
+ self.lifetimes.extend(iter);
+ self
+ }
+
+ pub fn with_lifetime_names<I, N>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=N>,
+ N: ToName,
+ {
+ for name in iter {
+ self = self.lifetime_name(name);
+ }
+ self
+ }
+
+ pub fn with_lifetime(mut self, lifetime: ast::LifetimeDef) -> Self {
+ self.lifetimes.push(lifetime);
+ self
+ }
+
+ pub fn lifetime_name<N>(self, name: N) -> Self
+ where N: ToName,
+ {
+ self.lifetime(name).build()
+ }
+
+ pub fn lifetime<N>(self, name: N) -> LifetimeDefBuilder<Self>
+ where N: ToName,
+ {
+ LifetimeDefBuilder::with_callback(name, self)
+ }
+
+ pub fn with_ty_params<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::TyParam>,
+ {
+ self.ty_params.extend(iter);
+ self
+ }
+
+ pub fn with_ty_param_ids<I, T>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=T>,
+ T: ToIdent,
+ {
+ for id in iter {
+ self = self.ty_param_id(id);
+ }
+ self
+ }
+
+ pub fn with_ty_param(mut self, ty_param: ast::TyParam) -> Self {
+ self.ty_params.push(ty_param);
+ self
+ }
+
+ pub fn ty_param_id<I>(self, id: I) -> Self
+ where I: ToIdent,
+ {
+ self.ty_param(id).build()
+ }
+
+ pub fn ty_param<I>(self, id: I) -> TyParamBuilder<Self>
+ where I: ToIdent,
+ {
+ let span = self.span;
+ TyParamBuilder::with_callback(id, self).span(span)
+ }
+
+ pub fn with_predicates<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::WherePredicate>,
+ {
+ self.predicates.extend(iter);
+ self
+ }
+
+ pub fn with_predicate(mut self, predicate: ast::WherePredicate) -> Self {
+ self.predicates.push(predicate);
+ self
+ }
+
+ pub fn predicate(self) -> WherePredicateBuilder<Self> {
+ WherePredicateBuilder::with_callback(self)
+ }
+
+ pub fn add_lifetime_bound<L>(mut self, lifetime: L) -> Self
+ where L: IntoLifetime,
+ {
+ let lifetime = lifetime.into_lifetime();
+
+ for lifetime_def in &mut self.lifetimes {
+ lifetime_def.bounds.push(lifetime);
+ }
+
+ for ty_param in &mut self.ty_params {
+ *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
+ .lifetime_bound(lifetime)
+ .build();
+ }
+
+ self
+ }
+
+ pub fn add_ty_param_bound<P>(mut self, path: P) -> Self
+ where P: IntoPath,
+ {
+ let path = path.into_path();
+
+ for ty_param in &mut self.ty_params {
+ *ty_param = TyParamBuilder::from_ty_param(ty_param.clone())
+ .trait_bound(path.clone()).build()
+ .build();
+ }
+
+ self
+ }
+
+ pub fn strip_bounds(self) -> Self {
+ self.strip_lifetimes()
+ .strip_ty_params()
+ .strip_predicates()
+ }
+
+ pub fn strip_lifetimes(mut self) -> Self {
+ for lifetime in &mut self.lifetimes {
+ lifetime.bounds = vec![];
+ }
+ self
+ }
+
+ pub fn strip_ty_params(mut self) -> Self {
+ for ty_param in &mut self.ty_params {
+ ty_param.bounds = P::new();
+ }
+ self
+ }
+
+ pub fn strip_predicates(mut self) -> Self {
+ self.predicates = vec![];
+ self
+ }
+
+ pub fn build(self) -> F::Result {
+ self.callback.invoke(ast::Generics {
+ lifetimes: self.lifetimes,
+ ty_params: P::from_vec(self.ty_params),
+ where_clause: ast::WhereClause {
+ id: ast::DUMMY_NODE_ID,
+ predicates: self.predicates,
+ },
+ span: self.span,
+ })
+ }
+}
+
+impl<F> Invoke<ast::LifetimeDef> for GenericsBuilder<F>
+ where F: Invoke<ast::Generics>,
+{
+ type Result = Self;
+
+ fn invoke(self, lifetime: ast::LifetimeDef) -> Self {
+ self.with_lifetime(lifetime)
+ }
+}
+
+impl<F> Invoke<ast::TyParam> for GenericsBuilder<F>
+ where F: Invoke<ast::Generics>,
+{
+ type Result = Self;
+
+ fn invoke(self, ty_param: ast::TyParam) -> Self {
+ self.with_ty_param(ty_param)
+ }
+}
+
+impl<F> Invoke<ast::WherePredicate> for GenericsBuilder<F>
+ where F: Invoke<ast::Generics>,
+{
+ type Result = Self;
+
+ fn invoke(self, predicate: ast::WherePredicate) -> Self {
+ self.with_predicate(predicate)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/ident.rs
@@ -0,0 +1,45 @@
+use syntax::ast;
+
+use name::ToName;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub trait ToIdent {
+ fn to_ident(&self) -> ast::Ident;
+}
+
+impl ToIdent for ast::Ident {
+ fn to_ident(&self) -> ast::Ident {
+ *self
+ }
+}
+
+impl ToIdent for ast::Name {
+ fn to_ident(&self) -> ast::Ident {
+ ast::Ident::with_empty_ctxt(*self)
+ }
+}
+
+impl<'a> ToIdent for &'a str {
+ fn to_ident(&self) -> ast::Ident {
+ self.to_name().to_ident()
+ }
+}
+
+impl ToIdent for String {
+ fn to_ident(&self) -> ast::Ident {
+ (&**self).to_ident()
+ }
+}
+
+impl<'a, T> ToIdent for &'a T where T: ToIdent {
+ fn to_ident(&self) -> ast::Ident {
+ (**self).to_ident()
+ }
+}
+
+impl<'a, T> ToIdent for &'a mut T where T: ToIdent {
+ fn to_ident(&self) -> ast::Ident {
+ (**self).to_ident()
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/invoke.rs
@@ -0,0 +1,16 @@
+pub trait Invoke<A> {
+ type Result;
+
+ fn invoke(self, arg: A) -> Self::Result;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#[derive(Copy, Clone)]
+pub struct Identity;
+
+impl<A> Invoke<A> for Identity {
+ type Result = A;
+
+ fn invoke(self, arg: A) -> A { arg }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/item.rs
@@ -0,0 +1,1490 @@
+#![cfg_attr(feature = "unstable", allow(wrong_self_convention))]
+
+use std::iter::IntoIterator;
+
+use syntax::abi::Abi;
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span, respan};
+use syntax::parse::token::keywords;
+use syntax::ptr::P;
+
+use attr::AttrBuilder;
+use block::BlockBuilder;
+use constant::{Const, ConstBuilder};
+use fn_decl::FnDeclBuilder;
+use generics::GenericsBuilder;
+use ident::ToIdent;
+use invoke::{Invoke, Identity};
+use mac::MacBuilder;
+use method::MethodSigBuilder;
+use path::PathBuilder;
+use struct_field::StructFieldBuilder;
+use ty::TyBuilder;
+use ty_param::TyParamBoundBuilder;
+use variant::VariantBuilder;
+use variant_data::{
+ VariantDataBuilder,
+ VariantDataStructBuilder,
+ VariantDataTupleBuilder,
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ attrs: Vec<ast::Attribute>,
+ vis: ast::Visibility,
+}
+
+impl ItemBuilder {
+ pub fn new() -> Self {
+ ItemBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> ItemBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ ItemBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ attrs: vec![],
+ vis: ast::Visibility::Inherited,
+ }
+ }
+
+ pub fn build(self, item: P<ast::Item>) -> F::Result {
+ self.callback.invoke(item)
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_attrs<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Attribute>,
+ {
+ self.attrs.extend(iter);
+ self
+ }
+
+ pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+ self.attrs.push(attr);
+ self
+ }
+
+ pub fn attr(self) -> AttrBuilder<Self> {
+ AttrBuilder::with_callback(self)
+ }
+
+ pub fn pub_(mut self) -> Self {
+ self.vis = ast::Visibility::Public;
+ self
+ }
+
+ pub fn build_item_kind<T>(self, id: T, item_kind: ast::ItemKind) -> F::Result
+ where T: ToIdent,
+ {
+ let item = ast::Item {
+ ident: id.to_ident(),
+ attrs: self.attrs,
+ id: ast::DUMMY_NODE_ID,
+ node: item_kind,
+ vis: self.vis,
+ span: self.span,
+ };
+ self.callback.invoke(P(item))
+ }
+
+ pub fn fn_<T>(self, id: T) -> FnDeclBuilder<ItemFnDeclBuilder<F>>
+ where T: ToIdent,
+ {
+ let id = id.to_ident();
+ let span = self.span;
+ FnDeclBuilder::with_callback(ItemFnDeclBuilder {
+ builder: self,
+ span: span,
+ id: id,
+ })
+ }
+
+ pub fn build_use(self, view_path: ast::ViewPath_) -> F::Result {
+ let item = ast::ItemKind::Use(P(respan(self.span, view_path)));
+ self.build_item_kind(keywords::Invalid.ident(), item)
+ }
+
+ pub fn use_(self) -> PathBuilder<ItemUseBuilder<F>> {
+ PathBuilder::with_callback(ItemUseBuilder {
+ builder: self,
+ })
+ }
+
+ pub fn struct_<T>(self, id: T) -> ItemStructBuilder<F>
+ where T: ToIdent,
+ {
+ let id = id.to_ident();
+ let generics = GenericsBuilder::new().build();
+
+ ItemStructBuilder {
+ is_union: false,
+ builder: self,
+ id: id,
+ generics: generics,
+ }
+ }
+
+ pub fn union_<T>(self, id: T) -> ItemStructBuilder<F>
+ where T: ToIdent,
+ {
+ let id = id.to_ident();
+ let generics = GenericsBuilder::new().build();
+
+ ItemStructBuilder {
+ is_union: true,
+ builder: self,
+ id: id,
+ generics: generics,
+ }
+ }
+
+ pub fn unit_struct<T>(self, id: T) -> F::Result
+ where T: ToIdent,
+ {
+ let id = id.to_ident();
+ let data = VariantDataBuilder::new().unit();
+ let generics = GenericsBuilder::new().build();
+
+ let struct_ = ast::ItemKind::Struct(data, generics);
+ self.build_item_kind(id, struct_)
+ }
+
+ pub fn tuple_struct<T>(self, id: T) -> ItemTupleStructBuilder<F>
+ where T: ToIdent,
+ {
+ let id = id.to_ident();
+ let generics = GenericsBuilder::new().build();
+
+ ItemTupleStructBuilder {
+ builder: self,
+ id: id,
+ generics: generics,
+ fields: vec![],
+ }
+ }
+
+ pub fn enum_<T>(self, id: T) -> ItemEnumBuilder<F>
+ where T: ToIdent,
+ {
+ let id = id.to_ident();
+ let span = self.span;
+ let generics = GenericsBuilder::new().span(span).build();
+
+ ItemEnumBuilder {
+ builder: self,
+ id: id,
+ generics: generics,
+ variants: vec![],
+ }
+ }
+
+ pub fn extern_crate<T>(self, id: T) -> ItemExternCrateBuilder<F>
+ where T: ToIdent,
+ {
+ let id = id.to_ident();
+
+ ItemExternCrateBuilder {
+ builder: self,
+ id: id,
+ }
+ }
+
+ pub fn mac(self) -> MacBuilder<ItemMacBuilder<F>> {
+ self.mac_id(keywords::Invalid.ident())
+ }
+
+ pub fn mac_id<T>(self, id: T) -> MacBuilder<ItemMacBuilder<F>>
+ where T: ToIdent,
+ {
+ let span = self.span;
+ MacBuilder::with_callback(ItemMacBuilder {
+ builder: self,
+ id: id.to_ident(),
+ }).span(span)
+ }
+
+ pub fn type_<T>(self, id: T) -> ItemTyBuilder<F>
+ where T: ToIdent,
+ {
+ let id = id.to_ident();
+ let generics = GenericsBuilder::new().build();
+
+ ItemTyBuilder {
+ builder: self,
+ id: id,
+ generics: generics,
+ }
+ }
+
+ pub fn trait_<T>(self, id: T) -> ItemTraitBuilder<F>
+ where T: ToIdent,
+ {
+ ItemTraitBuilder {
+ builder: self,
+ id: id.to_ident(),
+ unsafety: ast::Unsafety::Normal,
+ generics: GenericsBuilder::new().build(),
+ bounds: vec![],
+ items: vec![],
+ }
+ }
+
+ pub fn impl_(self) -> ItemImplBuilder<F> {
+ let generics = GenericsBuilder::new().build();
+
+ ItemImplBuilder {
+ builder: self,
+ unsafety: ast::Unsafety::Normal,
+ polarity: ast::ImplPolarity::Positive,
+ generics: generics,
+ trait_ref: None,
+ items: vec![],
+ }
+ }
+
+ pub fn const_<T>(self, id: T) -> ConstBuilder<ItemConstBuilder<F>>
+ where T: ToIdent,
+ {
+ ConstBuilder::with_callback(ItemConstBuilder {
+ builder: self,
+ id: id.to_ident(),
+ })
+ }
+}
+
+impl<F> Invoke<ast::Attribute> for ItemBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, attr: ast::Attribute) -> Self {
+ self.with_attr(attr)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemFnDeclBuilder<F> {
+ builder: ItemBuilder<F>,
+ span: Span,
+ id: ast::Ident,
+}
+
+impl<F> Invoke<P<ast::FnDecl>> for ItemFnDeclBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = ItemFnBuilder<F>;
+
+ fn invoke(self, fn_decl: P<ast::FnDecl>) -> ItemFnBuilder<F> {
+ let generics = GenericsBuilder::new().build();
+
+ ItemFnBuilder {
+ builder: self.builder,
+ span: self.span,
+ id: self.id,
+ fn_decl: fn_decl,
+ unsafety: ast::Unsafety::Normal,
+ constness: ast::Constness::NotConst,
+ abi: Abi::Rust,
+ generics: generics,
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemFnBuilder<F> {
+ builder: ItemBuilder<F>,
+ span: Span,
+ id: ast::Ident,
+ fn_decl: P<ast::FnDecl>,
+ unsafety: ast::Unsafety,
+ constness: ast::Constness,
+ abi: Abi,
+ generics: ast::Generics,
+}
+
+impl<F> ItemFnBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn unsafe_(mut self) -> Self {
+ self.unsafety = ast::Unsafety::Unsafe;
+ self
+ }
+
+ pub fn const_(mut self) -> Self {
+ self.constness = ast::Constness::Const;
+ self
+ }
+
+ pub fn abi(mut self, abi: Abi) -> Self {
+ self.abi = abi;
+ self
+ }
+
+ pub fn generics(self) -> GenericsBuilder<Self> {
+ GenericsBuilder::with_callback(self)
+ }
+
+ pub fn build(self, block: P<ast::Block>) -> F::Result {
+ self.builder.build_item_kind(self.id, ast::ItemKind::Fn(
+ self.fn_decl,
+ self.unsafety,
+ respan(self.span, self.constness),
+ self.abi,
+ self.generics,
+ block,
+ ))
+ }
+
+ pub fn block(self) -> BlockBuilder<Self> {
+ BlockBuilder::with_callback(self)
+ }
+}
+
+impl<F> Invoke<ast::Generics> for ItemFnBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(mut self, generics: ast::Generics) -> Self {
+ self.generics = generics;
+ self
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ItemFnBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, block: P<ast::Block>) -> F::Result {
+ self.build(block)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemUseBuilder<F> {
+ builder: ItemBuilder<F>,
+}
+
+impl<F> Invoke<ast::Path> for ItemUseBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = ItemUsePathBuilder<F>;
+
+ fn invoke(self, path: ast::Path) -> ItemUsePathBuilder<F> {
+ ItemUsePathBuilder {
+ builder: self.builder,
+ path: path,
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemUsePathBuilder<F> {
+ builder: ItemBuilder<F>,
+ path: ast::Path,
+}
+
+impl<F> ItemUsePathBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn as_<T>(self, id: T) -> F::Result
+ where T: ToIdent,
+ {
+ self.builder.build_use(ast::ViewPathSimple(id.to_ident(), self.path))
+ }
+
+ pub fn build(self) -> F::Result {
+ let id = {
+ let segment = self.path.segments.last().expect("path with no segments!");
+ segment.identifier
+ };
+ self.as_(id)
+ }
+
+ pub fn glob(self) -> F::Result {
+ self.builder.build_use(ast::ViewPathGlob(self.path))
+ }
+
+ pub fn list(self) -> ItemUsePathListBuilder<F> {
+ let span = self.builder.span;
+ ItemUsePathListBuilder {
+ builder: self.builder,
+ span: span,
+ path: self.path,
+ idents: Vec::new(),
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemUsePathListBuilder<F> {
+ builder: ItemBuilder<F>,
+ span: Span,
+ path: ast::Path,
+ idents: Vec<ast::PathListItem>,
+}
+
+impl<F> ItemUsePathListBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn self_(mut self) -> Self {
+ self.idents.push(respan(self.span, ast::PathListItem_ {
+ name: keywords::SelfValue.ident(),
+ rename: None,
+ id: ast::DUMMY_NODE_ID,
+ }));
+ self
+ }
+
+ pub fn id<T>(mut self, id: T) -> Self
+ where T: ToIdent,
+ {
+ self.idents.push(respan(self.span, ast::PathListItem_ {
+ name: id.to_ident(),
+ rename: None,
+ id: ast::DUMMY_NODE_ID,
+ }));
+ self
+ }
+
+ pub fn build(self) -> F::Result {
+ self.builder.build_use(ast::ViewPathList(self.path, self.idents))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemStructBuilder<F> {
+ is_union: bool,
+ builder: ItemBuilder<F>,
+ id: ast::Ident,
+ generics: ast::Generics,
+}
+
+impl<F> ItemStructBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn with_generics(mut self, generics: ast::Generics) -> Self {
+ self.generics = generics;
+ self
+ }
+
+ pub fn generics(self) -> GenericsBuilder<Self> {
+ GenericsBuilder::with_callback(self)
+ }
+
+ pub fn with_fields<I>(self, iter: I) -> VariantDataStructBuilder<Self>
+ where I: IntoIterator<Item=ast::StructField>,
+ {
+ let span = self.builder.span;
+ VariantDataBuilder::with_callback(self).span(span).struct_().with_fields(iter)
+ }
+
+ pub fn with_field(self, field: ast::StructField) -> VariantDataStructBuilder<Self> {
+ let span = self.builder.span;
+ VariantDataBuilder::with_callback(self).span(span).struct_().with_field(field)
+ }
+
+ pub fn field<T>(self, id: T) -> StructFieldBuilder<VariantDataStructBuilder<Self>>
+ where T: ToIdent,
+ {
+ let span = self.builder.span;
+ VariantDataBuilder::with_callback(self).span(span).struct_().field(id)
+ }
+
+ pub fn build(self) -> F::Result {
+ VariantDataBuilder::with_callback(self).struct_().build()
+ }
+}
+
+impl<F> Invoke<ast::Generics> for ItemStructBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, generics: ast::Generics) -> Self {
+ self.with_generics(generics)
+ }
+}
+
+impl<F> Invoke<ast::VariantData> for ItemStructBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, data: ast::VariantData) -> F::Result {
+ let kind = if self.is_union {
+ ast::ItemKind::Union(data, self.generics)
+ } else {
+ ast::ItemKind::Struct(data, self.generics)
+ };
+
+ self.builder.build_item_kind(self.id, kind)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTupleStructBuilder<F> {
+ builder: ItemBuilder<F>,
+ id: ast::Ident,
+ generics: ast::Generics,
+ fields: Vec<ast::StructField>,
+}
+
+impl<F> ItemTupleStructBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn generics(self) -> GenericsBuilder<Self> {
+ GenericsBuilder::with_callback(self)
+ }
+
+ pub fn with_tys<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::Ty>>,
+ {
+ for ty in iter {
+ self = self.ty().build(ty);
+ }
+ self
+ }
+
+ pub fn ty(self) -> TyBuilder<Self> {
+ let span = self.builder.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+
+ pub fn field(self) -> StructFieldBuilder<Self> {
+ let span = self.builder.span;
+ StructFieldBuilder::unnamed_with_callback(self).span(span)
+ }
+
+ pub fn build(self) -> F::Result {
+ let data = ast::VariantData::Tuple(self.fields, ast::DUMMY_NODE_ID);
+ let struct_ = ast::ItemKind::Struct(data, self.generics);
+ self.builder.build_item_kind(self.id, struct_)
+ }
+}
+
+impl<F> Invoke<ast::Generics> for ItemTupleStructBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(mut self, generics: ast::Generics) -> Self {
+ self.generics = generics;
+ self
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemTupleStructBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, ty: P<ast::Ty>) -> Self {
+ self.field().build_ty(ty)
+ }
+}
+
+impl<F> Invoke<ast::StructField> for ItemTupleStructBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(mut self, field: ast::StructField) -> Self {
+ self.fields.push(field);
+ self
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemEnumBuilder<F> {
+ builder: ItemBuilder<F>,
+ id: ast::Ident,
+ generics: ast::Generics,
+ variants: Vec<ast::Variant>,
+}
+
+impl<F> ItemEnumBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn generics(self) -> GenericsBuilder<Self> {
+ let span = self.builder.span;
+ GenericsBuilder::with_callback(self).span(span)
+ }
+
+ pub fn with_variants<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Variant>,
+ {
+ self.variants.extend(iter);
+ self
+ }
+
+ pub fn with_variant(mut self, variant: ast::Variant) -> Self {
+ self.variants.push(variant);
+ self
+ }
+
+ pub fn with_variant_(self, variant: ast::Variant_) -> Self {
+ let variant = respan(self.builder.span, variant);
+ self.with_variant(variant)
+ }
+
+ pub fn ids<I, T>(mut self, ids: I) -> Self
+ where I: IntoIterator<Item=T>,
+ T: ToIdent,
+ {
+ for id in ids {
+ self = self.id(id);
+ }
+ self
+ }
+
+ pub fn id<T>(self, id: T) -> Self
+ where T: ToIdent,
+ {
+ self.variant(id).unit()
+ }
+
+ pub fn tuple<T>(self, id: T) -> StructFieldBuilder<VariantDataTupleBuilder<VariantBuilder<Self>>>
+ where T: ToIdent,
+ {
+ self.variant(id).tuple()
+ }
+
+ pub fn struct_<T>(self, id: T) -> VariantDataStructBuilder<VariantBuilder<Self>>
+ where T: ToIdent,
+ {
+ self.variant(id).struct_()
+ }
+
+ pub fn variant<T>(self, id: T) -> VariantBuilder<Self>
+ where T: ToIdent,
+ {
+ let span = self.builder.span;
+ VariantBuilder::with_callback(id, self).span(span)
+ }
+
+ pub fn build(self) -> F::Result {
+ let enum_def = ast::EnumDef {
+ variants: self.variants,
+ };
+ let enum_ = ast::ItemKind::Enum(enum_def, self.generics);
+ self.builder.build_item_kind(self.id, enum_)
+ }
+}
+
+impl<F> Invoke<ast::Generics> for ItemEnumBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(mut self, generics: ast::Generics) -> Self {
+ self.generics = generics;
+ self
+ }
+}
+
+impl<F> Invoke<ast::Variant> for ItemEnumBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, variant: ast::Variant) -> Self {
+ self.with_variant(variant)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// A builder for extern crate items
+pub struct ItemExternCrateBuilder<F> {
+ builder: ItemBuilder<F>,
+ id: ast::Ident,
+}
+
+impl<F> ItemExternCrateBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn with_name(self, name: ast::Name) -> F::Result {
+ let extern_ = ast::ItemKind::ExternCrate(Some(name));
+ self.builder.build_item_kind(self.id, extern_)
+ }
+
+ pub fn build(self) -> F::Result {
+ let extern_ = ast::ItemKind::ExternCrate(None);
+ self.builder.build_item_kind(self.id, extern_)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// A builder for macro invocation items.
+///
+/// Specifying the macro path returns a `MacBuilder`, which is used to
+/// add expressions to the macro invocation.
+pub struct ItemMacBuilder<F> {
+ builder: ItemBuilder<F>,
+ id: ast::Ident,
+}
+
+impl<F> Invoke<ast::Mac> for ItemMacBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, mac: ast::Mac) -> F::Result {
+ self.builder.build_item_kind(self.id, ast::ItemKind::Mac(mac))
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTyBuilder<F> {
+ builder: ItemBuilder<F>,
+ id: ast::Ident,
+ generics: ast::Generics,
+}
+
+impl<F> ItemTyBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn generics(self) -> GenericsBuilder<Self> {
+ GenericsBuilder::with_callback(self)
+ }
+
+ pub fn ty(self) -> TyBuilder<Self> {
+ let span = self.builder.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build_ty(self, ty: P<ast::Ty>) -> F::Result {
+ let ty_ = ast::ItemKind::Ty(ty, self.generics);
+ self.builder.build_item_kind(self.id, ty_)
+ }
+}
+
+impl<F> Invoke<ast::Generics> for ItemTyBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(mut self, generics: ast::Generics) -> Self {
+ self.generics = generics;
+ self
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemTyBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+ self.build_ty(ty)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTraitBuilder<F> {
+ builder: ItemBuilder<F>,
+ id: ast::Ident,
+ unsafety: ast::Unsafety,
+ generics: ast::Generics,
+ bounds: Vec<ast::TyParamBound>,
+ items: Vec<ast::TraitItem>,
+}
+
+impl<F> ItemTraitBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn unsafe_(mut self) -> Self {
+ self.unsafety = ast::Unsafety::Unsafe;
+ self
+ }
+
+ pub fn with_generics(mut self, generics: ast::Generics) -> Self {
+ self.generics = generics;
+ self
+ }
+
+ pub fn generics(self) -> GenericsBuilder<Self> {
+ GenericsBuilder::with_callback(self)
+ }
+
+ pub fn with_bounds<I>(mut self, iter: I) -> Self
+ where I: Iterator<Item=ast::TyParamBound>,
+ {
+ self.bounds.extend(iter);
+ self
+ }
+
+ pub fn with_bound(mut self, bound: ast::TyParamBound) -> Self {
+ self.bounds.push(bound);
+ self
+ }
+
+ pub fn bound(self) -> TyParamBoundBuilder<Self> {
+ TyParamBoundBuilder::with_callback(self)
+ }
+
+ pub fn with_items<I>(mut self, items: I) -> Self
+ where I: IntoIterator<Item=ast::TraitItem>,
+ {
+ self.items.extend(items);
+ self
+ }
+
+ pub fn with_item(mut self, item: ast::TraitItem) -> Self {
+ self.items.push(item);
+ self
+ }
+
+ pub fn item<T>(self, id: T) -> ItemTraitItemBuilder<Self>
+ where T: ToIdent,
+ {
+ ItemTraitItemBuilder::with_callback(id, self)
+ }
+
+ pub fn const_<T>(self, id: T) -> ConstBuilder<ItemTraitItemBuilder<Self>>
+ where T: ToIdent,
+ {
+ self.item(id).const_()
+ }
+
+ pub fn method<T>(self, id: T) -> MethodSigBuilder<ItemTraitItemBuilder<Self>>
+ where T: ToIdent,
+ {
+ self.item(id).method()
+ }
+
+ pub fn type_<T>(self, id: T) -> ItemTraitTypeBuilder<Self>
+ where T: ToIdent,
+ {
+ self.item(id).type_()
+ }
+
+ pub fn build(self) -> F::Result {
+ self.builder.build_item_kind(self.id, ast::ItemKind::Trait(
+ self.unsafety,
+ self.generics,
+ P::from_vec(self.bounds),
+ self.items,
+ ))
+ }
+}
+
+impl<F> Invoke<ast::Generics> for ItemTraitBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, generics: ast::Generics) -> Self {
+ self.with_generics(generics)
+ }
+}
+
+impl<F> Invoke<ast::TyParamBound> for ItemTraitBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, bound: ast::TyParamBound) -> Self {
+ self.with_bound(bound)
+ }
+}
+
+impl<F> Invoke<ast::TraitItem> for ItemTraitBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, item: ast::TraitItem) -> Self {
+ self.with_item(item)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTraitItemBuilder<F=Identity> {
+ callback: F,
+ id: ast::Ident,
+ attrs: Vec<ast::Attribute>,
+ span: Span,
+}
+
+impl ItemTraitItemBuilder {
+ pub fn new<T>(id: T) -> Self
+ where T: ToIdent,
+ {
+ Self::with_callback(id, Identity)
+ }
+}
+
+impl<F> ItemTraitItemBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ pub fn with_callback<T>(id: T, callback: F) -> Self
+ where F: Invoke<ast::TraitItem>,
+ T: ToIdent,
+ {
+ ItemTraitItemBuilder {
+ callback: callback,
+ id: id.to_ident(),
+ attrs: vec![],
+ span: DUMMY_SP,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_attrs<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Attribute>,
+ {
+ self.attrs.extend(iter);
+ self
+ }
+
+ pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+ self.attrs.push(attr);
+ self
+ }
+
+ pub fn attr(self) -> AttrBuilder<Self> {
+ AttrBuilder::with_callback(self)
+ }
+
+ pub fn const_(self) -> ConstBuilder<Self> {
+ ConstBuilder::with_callback(self)
+ }
+
+ pub fn method(self) -> MethodSigBuilder<Self> {
+ MethodSigBuilder::with_callback(self)
+ }
+
+ pub fn type_(self) -> ItemTraitTypeBuilder<F> {
+ ItemTraitTypeBuilder {
+ builder: self,
+ bounds: vec![],
+ }
+ }
+
+ pub fn build_item(self, node: ast::TraitItemKind) -> F::Result {
+ let item = ast::TraitItem {
+ id: ast::DUMMY_NODE_ID,
+ ident: self.id,
+ attrs: self.attrs,
+ node: node,
+ span: self.span,
+ };
+ self.callback.invoke(item)
+ }
+}
+
+impl<F> Invoke<ast::Attribute> for ItemTraitItemBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ type Result = Self;
+
+ fn invoke(self, attr: ast::Attribute) -> Self {
+ self.with_attr(attr)
+ }
+}
+
+impl<F> Invoke<Const> for ItemTraitItemBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, const_: Const) -> F::Result {
+ let node = ast::TraitItemKind::Const(
+ const_.ty,
+ const_.expr);
+ self.build_item(node)
+ }
+}
+
+impl<F> Invoke<ast::MethodSig> for ItemTraitItemBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ type Result = ItemTraitMethodBuilder<F>;
+
+ fn invoke(self, method: ast::MethodSig) -> Self::Result {
+ ItemTraitMethodBuilder {
+ builder: self,
+ method: method,
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTraitMethodBuilder<F> {
+ builder: ItemTraitItemBuilder<F>,
+ method: ast::MethodSig,
+}
+
+impl<F> ItemTraitMethodBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ pub fn build_option_block(self, block: Option<P<ast::Block>>) -> F::Result {
+ let node = ast::TraitItemKind::Method(self.method, block);
+ self.builder.build_item(node)
+ }
+
+ pub fn build_block(self, block: P<ast::Block>) -> F::Result {
+ self.build_option_block(Some(block))
+ }
+
+ pub fn build(self) -> F::Result {
+ self.build_option_block(None)
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ItemTraitMethodBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, block: P<ast::Block>) -> Self::Result {
+ self.build_block(block)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemTraitTypeBuilder<F> {
+ builder: ItemTraitItemBuilder<F>,
+ bounds: Vec<ast::TyParamBound>,
+}
+
+impl<F> ItemTraitTypeBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ pub fn with_bounds<I>(mut self, iter: I) -> Self
+ where I: Iterator<Item=ast::TyParamBound>,
+ {
+ self.bounds.extend(iter);
+ self
+ }
+
+ pub fn with_bound(mut self, bound: ast::TyParamBound) -> Self {
+ self.bounds.push(bound);
+ self
+ }
+
+ pub fn bound(self) -> TyParamBoundBuilder<Self> {
+ TyParamBoundBuilder::with_callback(self)
+ }
+
+ pub fn build_option_ty(self, ty: Option<P<ast::Ty>>) -> F::Result {
+ let bounds = P::from_vec(self.bounds);
+ let node = ast::TraitItemKind::Type(bounds, ty);
+ self.builder.build_item(node)
+ }
+
+ pub fn build_ty(self, ty: P<ast::Ty>) -> F::Result {
+ self.build_option_ty(Some(ty))
+ }
+
+ pub fn ty(self) -> TyBuilder<Self> {
+ let span = self.builder.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self) -> F::Result {
+ self.build_option_ty(None)
+ }
+}
+
+impl<F> Invoke<ast::TyParamBound> for ItemTraitTypeBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ type Result = ItemTraitTypeBuilder<F>;
+
+ fn invoke(self, bound: ast::TyParamBound) -> Self::Result {
+ self.with_bound(bound)
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemTraitTypeBuilder<F>
+ where F: Invoke<ast::TraitItem>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, ty: P<ast::Ty>) -> Self::Result {
+ self.build_ty(ty)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemImplBuilder<F> {
+ builder: ItemBuilder<F>,
+ unsafety: ast::Unsafety,
+ polarity: ast::ImplPolarity,
+ generics: ast::Generics,
+ trait_ref: Option<ast::TraitRef>,
+ items: Vec<ast::ImplItem>,
+}
+
+impl<F> ItemImplBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ pub fn unsafe_(mut self) -> Self {
+ self.unsafety = ast::Unsafety::Unsafe;
+ self
+ }
+
+ pub fn negative(mut self) -> Self {
+ self.polarity = ast::ImplPolarity::Negative;
+ self
+ }
+
+ pub fn with_generics(mut self, generics: ast::Generics) -> Self {
+ self.generics = generics;
+ self
+ }
+
+ pub fn generics(self) -> GenericsBuilder<Self> {
+ GenericsBuilder::with_callback(self)
+ }
+
+ pub fn with_trait(mut self, trait_ref: ast::TraitRef) -> Self {
+ self.trait_ref = Some(trait_ref);
+ self
+ }
+
+ pub fn trait_(self) -> PathBuilder<Self> {
+ PathBuilder::with_callback(self)
+ }
+
+ pub fn ty(self) -> TyBuilder<Self> {
+ let span = self.builder.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build_ty(self, ty: P<ast::Ty>) -> F::Result {
+ let ty_ = ast::ItemKind::Impl(
+ self.unsafety,
+ self.polarity,
+ self.generics,
+ self.trait_ref,
+ ty,
+ self.items);
+ self.builder.build_item_kind(keywords::Invalid.ident(), ty_)
+ }
+
+ pub fn with_items<I>(mut self, items: I) -> Self
+ where I: IntoIterator<Item=ast::ImplItem>,
+ {
+ self.items.extend(items);
+ self
+ }
+
+ pub fn with_item(mut self, item: ast::ImplItem) -> Self {
+ self.items.push(item);
+ self
+ }
+
+ pub fn item<T>(self, id: T) -> ItemImplItemBuilder<Self>
+ where T: ToIdent,
+ {
+ ItemImplItemBuilder::with_callback(id, self)
+ }
+
+ pub fn const_<T>(self, id: T) -> ConstBuilder<ItemImplItemBuilder<Self>>
+ where T: ToIdent,
+ {
+ self.item(id).const_()
+ }
+
+ pub fn method<T>(self, id: T) -> MethodSigBuilder<ItemImplItemBuilder<Self>>
+ where T: ToIdent,
+ {
+ self.item(id).method()
+ }
+
+ pub fn type_<T>(self, id: T) -> TyBuilder<ItemImplItemBuilder<Self>>
+ where T: ToIdent,
+ {
+ self.item(id).type_()
+ }
+}
+
+impl<F> Invoke<ast::Generics> for ItemImplBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, generics: ast::Generics) -> Self {
+ self.with_generics(generics)
+ }
+}
+
+impl<F> Invoke<ast::Path> for ItemImplBuilder<F>
+ where F: Invoke<P<ast::Item>>
+{
+ type Result = Self;
+
+ fn invoke(self, path: ast::Path) -> Self {
+ self.with_trait(ast::TraitRef {
+ path: path,
+ ref_id: ast::DUMMY_NODE_ID,
+ })
+ }
+}
+
+impl<F> Invoke<ast::ImplItem> for ItemImplBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = Self;
+
+ fn invoke(self, item: ast::ImplItem) -> Self {
+ self.with_item(item)
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemImplBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+ self.build_ty(ty)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemImplItemBuilder<F=Identity> {
+ callback: F,
+ id: ast::Ident,
+ vis: ast::Visibility,
+ defaultness: ast::Defaultness,
+ attrs: Vec<ast::Attribute>,
+ span: Span,
+}
+
+impl ItemImplItemBuilder {
+ pub fn new<T>(id: T) -> Self
+ where T: ToIdent,
+ {
+ Self::with_callback(id, Identity)
+ }
+}
+
+impl<F> ItemImplItemBuilder<F>
+ where F: Invoke<ast::ImplItem>,
+{
+ pub fn with_callback<T>(id: T, callback: F) -> Self
+ where F: Invoke<ast::ImplItem>,
+ T: ToIdent,
+ {
+ ItemImplItemBuilder {
+ callback: callback,
+ id: id.to_ident(),
+ vis: ast::Visibility::Inherited,
+ defaultness: ast::Defaultness::Final,
+ attrs: vec![],
+ span: DUMMY_SP,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn with_attrs<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=ast::Attribute>,
+ {
+ self.attrs.extend(iter);
+ self
+ }
+
+ pub fn with_attr(mut self, attr: ast::Attribute) -> Self {
+ self.attrs.push(attr);
+ self
+ }
+
+ pub fn attr(self) -> AttrBuilder<Self> {
+ AttrBuilder::with_callback(self)
+ }
+
+ pub fn pub_(mut self) -> Self {
+ self.vis = ast::Visibility::Public;
+ self
+ }
+
+ pub fn default(mut self) -> Self {
+ self.defaultness = ast::Defaultness::Default;
+ self
+ }
+
+ pub fn const_(self) -> ConstBuilder<Self> {
+ ConstBuilder::with_callback(self)
+ }
+
+ pub fn build_method(self, method: ast::MethodSig) -> ItemImplMethodBuilder<F> {
+ ItemImplMethodBuilder {
+ builder: self,
+ method: method,
+ }
+ }
+
+ pub fn method(self) -> MethodSigBuilder<Self> {
+ MethodSigBuilder::with_callback(self)
+ }
+
+ pub fn type_(self) -> TyBuilder<Self> {
+ let span = self.span;
+ TyBuilder::with_callback(self).span(span)
+ }
+
+ pub fn mac(self) -> MacBuilder<Self> {
+ MacBuilder::with_callback(self)
+ }
+
+ pub fn build_item(self, node: ast::ImplItemKind) -> F::Result {
+ let item = ast::ImplItem {
+ id: ast::DUMMY_NODE_ID,
+ ident: self.id,
+ vis: self.vis,
+ defaultness: self.defaultness,
+ attrs: self.attrs,
+ node: node,
+ span: self.span,
+ };
+ self.callback.invoke(item)
+ }
+}
+
+impl<F> Invoke<ast::Attribute> for ItemImplItemBuilder<F>
+ where F: Invoke<ast::ImplItem>,
+{
+ type Result = Self;
+
+ fn invoke(self, attr: ast::Attribute) -> Self {
+ self.with_attr(attr)
+ }
+}
+
+impl<F> Invoke<Const> for ItemImplItemBuilder<F>
+ where F: Invoke<ast::ImplItem>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, const_: Const) -> F::Result {
+ let node = ast::ImplItemKind::Const(const_.ty, const_.expr.expect("an expr is required for a const impl item"));
+ self.build_item(node)
+ }
+}
+
+impl<F> Invoke<ast::MethodSig> for ItemImplItemBuilder<F>
+ where F: Invoke<ast::ImplItem>,
+{
+ type Result = ItemImplMethodBuilder<F>;
+
+ fn invoke(self, method: ast::MethodSig) -> Self::Result {
+ self.build_method(method)
+ }
+}
+
+impl<F> Invoke<P<ast::Ty>> for ItemImplItemBuilder<F>
+ where F: Invoke<ast::ImplItem>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, ty: P<ast::Ty>) -> F::Result {
+ let node = ast::ImplItemKind::Type(ty);
+ self.build_item(node)
+ }
+}
+
+impl<F> Invoke<ast::Mac> for ItemImplItemBuilder<F>
+ where F: Invoke<ast::ImplItem>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, mac: ast::Mac) -> F::Result {
+ let node = ast::ImplItemKind::Macro(mac);
+ self.build_item(node)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemImplMethodBuilder<F> {
+ builder: ItemImplItemBuilder<F>,
+ method: ast::MethodSig,
+}
+
+impl<F> ItemImplMethodBuilder<F>
+ where F: Invoke<ast::ImplItem>,
+{
+ pub fn build_block(self, block: P<ast::Block>) -> F::Result {
+ let node = ast::ImplItemKind::Method(self.method, block);
+ self.builder.build_item(node)
+ }
+
+ pub fn block(self) -> BlockBuilder<Self> {
+ BlockBuilder::with_callback(self)
+ }
+}
+
+impl<F> Invoke<P<ast::Block>> for ItemImplMethodBuilder<F>
+ where F: Invoke<ast::ImplItem>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, block: P<ast::Block>) -> Self::Result {
+ self.build_block(block)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct ItemConstBuilder<F> {
+ builder: ItemBuilder<F>,
+ id: ast::Ident,
+}
+
+impl<F> Invoke<Const> for ItemConstBuilder<F>
+ where F: Invoke<P<ast::Item>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, const_: Const) -> F::Result {
+ let ty = ast::ItemKind::Const(const_.ty, const_.expr.expect("an expr is required for a const item"));
+ self.builder.build_item_kind(self.id, ty)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/lib.rs
@@ -0,0 +1,224 @@
+#![cfg_attr(not(feature = "with-syntex"), feature(rustc_private))]
+#![cfg_attr(feature = "unstable-testing", feature(plugin))]
+#![cfg_attr(feature = "unstable-testing", plugin(clippy))]
+#![cfg_attr(feature = "unstable-testing", allow(wrong_self_convention))]
+
+#[cfg(feature = "with-syntex")]
+extern crate syntex_syntax as syntax;
+
+#[cfg(not(feature = "with-syntex"))]
+extern crate syntax;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::parse::token;
+
+pub mod arm;
+pub mod attr;
+pub mod block;
+pub mod constant;
+pub mod expr;
+pub mod fn_decl;
+pub mod generics;
+pub mod ident;
+pub mod invoke;
+pub mod item;
+pub mod lifetime;
+pub mod lit;
+pub mod mac;
+pub mod method;
+pub mod name;
+pub mod pat;
+pub mod path;
+pub mod qpath;
+pub mod self_;
+pub mod stmt;
+pub mod str;
+pub mod struct_field;
+pub mod ty;
+pub mod ty_param;
+pub mod variant;
+pub mod variant_data;
+pub mod where_predicate;
+
+//////////////////////////////////////////////////////////////////////////////
+
+#[derive(Copy, Clone)]
+pub struct AstBuilder {
+ span: Span,
+}
+
+impl AstBuilder {
+ pub fn new() -> AstBuilder {
+ AstBuilder {
+ span: DUMMY_SP,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn interned_string<S>(&self, s: S) -> token::InternedString
+ where S: str::ToInternedString
+ {
+ s.to_interned_string()
+ }
+
+ pub fn id<I>(&self, id: I) -> ast::Ident
+ where I: ident::ToIdent
+ {
+ id.to_ident()
+ }
+
+ pub fn name<N>(&self, name: N) -> ast::Name
+ where N: name::ToName
+ {
+ name.to_name()
+ }
+
+ pub fn lifetime<L>(&self, lifetime: L) -> ast::Lifetime
+ where L: lifetime::IntoLifetime
+ {
+ lifetime.into_lifetime()
+ }
+
+ pub fn arm(&self) -> arm::ArmBuilder {
+ arm::ArmBuilder::new().span(self.span)
+ }
+
+ pub fn attr(&self) -> attr::AttrBuilder {
+ attr::AttrBuilder::new().span(self.span)
+ }
+
+ pub fn mac(&self) -> mac::MacBuilder {
+ mac::MacBuilder::new().span(self.span)
+ }
+
+ pub fn path(&self) -> path::PathBuilder {
+ path::PathBuilder::new().span(self.span)
+ }
+
+ pub fn qpath(&self) -> qpath::QPathBuilder {
+ qpath::QPathBuilder::new().span(self.span)
+ }
+
+ pub fn ty(&self) -> ty::TyBuilder {
+ ty::TyBuilder::new().span(self.span)
+ }
+
+ pub fn lifetime_def<N>(&self, name: N) -> lifetime::LifetimeDefBuilder
+ where N: name::ToName,
+ {
+ lifetime::LifetimeDefBuilder::new(name)
+ }
+
+ pub fn ty_param<I>(&self, id: I) -> ty_param::TyParamBuilder
+ where I: ident::ToIdent,
+ {
+ ty_param::TyParamBuilder::new(id).span(self.span)
+ }
+
+ pub fn ty_param_bound(&self) -> ty_param::TyParamBoundBuilder {
+ ty_param::TyParamBoundBuilder::new().span(self.span)
+ }
+
+ pub fn from_ty_param(&self, ty_param: ast::TyParam) -> ty_param::TyParamBuilder {
+ ty_param::TyParamBuilder::from_ty_param(ty_param)
+ }
+
+ pub fn generics(&self) -> generics::GenericsBuilder {
+ generics::GenericsBuilder::new().span(self.span)
+ }
+
+ pub fn where_predicate(&self) -> where_predicate::WherePredicateBuilder {
+ where_predicate::WherePredicateBuilder::new().span(self.span)
+ }
+
+ pub fn from_generics(&self, generics: ast::Generics) -> generics::GenericsBuilder {
+ generics::GenericsBuilder::from_generics(generics).span(self.span)
+ }
+
+ pub fn lit(&self) -> lit::LitBuilder {
+ lit::LitBuilder::new().span(self.span)
+ }
+
+ pub fn expr(&self) -> expr::ExprBuilder {
+ expr::ExprBuilder::new().span(self.span)
+ }
+
+ pub fn stmt(&self) -> stmt::StmtBuilder {
+ stmt::StmtBuilder::new().span(self.span)
+ }
+
+ pub fn block(&self) -> block::BlockBuilder {
+ block::BlockBuilder::new().span(self.span)
+ }
+
+ pub fn pat(&self) -> pat::PatBuilder {
+ pat::PatBuilder::new().span(self.span)
+ }
+
+ pub fn fn_decl(&self) -> fn_decl::FnDeclBuilder {
+ fn_decl::FnDeclBuilder::new().span(self.span)
+ }
+
+ pub fn method_sig(&self) -> method::MethodSigBuilder {
+ method::MethodSigBuilder::new().span(self.span)
+ }
+
+ pub fn self_(&self) -> self_::SelfBuilder {
+ self_::SelfBuilder::new().span(self.span)
+ }
+
+ pub fn arg(&self) -> fn_decl::ArgBuilder {
+ fn_decl::ArgBuilder::new().span(self.span)
+ }
+
+ pub fn variant_data(&self) -> variant_data::VariantDataBuilder {
+ variant_data::VariantDataBuilder::new().span(self.span)
+ }
+
+ pub fn variant<T>(&self, id: T) -> variant::VariantBuilder
+ where T: ident::ToIdent,
+ {
+ variant::VariantBuilder::new(id).span(self.span)
+ }
+
+ pub fn struct_field<T>(&self, id: T) -> struct_field::StructFieldBuilder
+ where T: ident::ToIdent,
+ {
+ struct_field::StructFieldBuilder::named(id).span(self.span)
+ }
+
+ pub fn tuple_field(&self) -> struct_field::StructFieldBuilder {
+ struct_field::StructFieldBuilder::unnamed().span(self.span)
+ }
+
+ pub fn item(&self) -> item::ItemBuilder {
+ item::ItemBuilder::new().span(self.span)
+ }
+
+ pub fn trait_item<T>(&self, id: T) -> item::ItemTraitItemBuilder
+ where T: ident::ToIdent,
+ {
+ item::ItemTraitItemBuilder::new(id).span(self.span)
+ }
+
+ pub fn impl_item<T>(&self, id: T) -> item::ItemImplItemBuilder
+ where T: ident::ToIdent,
+ {
+ item::ItemImplItemBuilder::new(id).span(self.span)
+ }
+
+ pub fn const_(&self) -> constant::ConstBuilder {
+ constant::ConstBuilder::new().span(self.span)
+ }
+}
+
+impl Default for AstBuilder {
+ fn default() -> Self {
+ AstBuilder::new()
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/lifetime.rs
@@ -0,0 +1,118 @@
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP};
+
+use invoke::{Invoke, Identity};
+use name::ToName;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub trait IntoLifetime {
+ fn into_lifetime(self) -> ast::Lifetime;
+}
+
+impl IntoLifetime for ast::Lifetime {
+ fn into_lifetime(self) -> ast::Lifetime {
+ self
+ }
+}
+
+impl<'a> IntoLifetime for &'a str {
+ fn into_lifetime(self) -> ast::Lifetime {
+ ast::Lifetime {
+ id: ast::DUMMY_NODE_ID,
+ span: DUMMY_SP,
+ name: self.to_name(),
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub trait IntoLifetimeDef {
+ fn into_lifetime_def(self) -> ast::LifetimeDef;
+}
+
+impl IntoLifetimeDef for ast::LifetimeDef {
+ fn into_lifetime_def(self) -> ast::LifetimeDef {
+ self
+ }
+}
+
+impl IntoLifetimeDef for ast::Lifetime {
+ fn into_lifetime_def(self) -> ast::LifetimeDef {
+ ast::LifetimeDef {
+ attrs: ast::ThinVec::new(),
+ lifetime: self,
+ bounds: vec![],
+ }
+ }
+}
+
+impl<'a> IntoLifetimeDef for &'a str {
+ fn into_lifetime_def(self) -> ast::LifetimeDef {
+ self.into_lifetime().into_lifetime_def()
+ }
+}
+
+impl IntoLifetimeDef for String {
+ fn into_lifetime_def(self) -> ast::LifetimeDef {
+ (*self).into_lifetime().into_lifetime_def()
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct LifetimeDefBuilder<F=Identity> {
+ callback: F,
+ lifetime: ast::Lifetime,
+ bounds: Vec<ast::Lifetime>,
+}
+
+impl LifetimeDefBuilder {
+ pub fn new<N>(name: N) -> Self
+ where N: ToName,
+ {
+ LifetimeDefBuilder::with_callback(name, Identity)
+ }
+}
+
+impl<F> LifetimeDefBuilder<F>
+ where F: Invoke<ast::LifetimeDef>,
+{
+ pub fn with_callback<N>(name: N, callback: F) -> Self
+ where N: ToName,
+ {
+ let lifetime = ast::Lifetime {
+ id: ast::DUMMY_NODE_ID,
+ span: DUMMY_SP,
+ name: name.to_name(),
+ };
+
+ LifetimeDefBuilder {
+ callback: callback,
+ lifetime: lifetime,
+ bounds: Vec::new(),
+ }
+ }
+
+ pub fn bound<N>(mut self, name: N) -> Self
+ where N: ToName,
+ {
+ let lifetime = ast::Lifetime {
+ id: ast::DUMMY_NODE_ID,
+ span: DUMMY_SP,
+ name: name.to_name(),
+ };
+
+ self.bounds.push(lifetime);
+ self
+ }
+
+ pub fn build(self) -> F::Result {
+ self.callback.invoke(ast::LifetimeDef {
+ attrs: ast::ThinVec::new(),
+ lifetime: self.lifetime,
+ bounds: self.bounds,
+ })
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/lit.rs
@@ -0,0 +1,153 @@
+use std::convert::Into;
+use std::rc::Rc;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span};
+use syntax::ptr::P;
+
+use invoke::{Invoke, Identity};
+
+use str::ToInternedString;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct LitBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+}
+
+impl LitBuilder {
+ pub fn new() -> LitBuilder {
+ LitBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> LitBuilder<F>
+ where F: Invoke<P<ast::Lit>>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ LitBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> LitBuilder<F> {
+ self.span = span;
+ self
+ }
+
+ pub fn build_lit(self, lit: ast::LitKind) -> F::Result {
+ self.callback.invoke(P(ast::Lit {
+ span: self.span,
+ node: lit,
+ }))
+ }
+
+ pub fn bool(self, value: bool) -> F::Result {
+ self.build_lit(ast::LitKind::Bool(value))
+ }
+
+ pub fn true_(self) -> F::Result {
+ self.bool(true)
+ }
+
+ pub fn false_(self) -> F::Result {
+ self.bool(false)
+ }
+
+ pub fn int(self, value: u64) -> F::Result {
+ self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Unsuffixed))
+ }
+
+ fn build_int(self, value: u64, ty: ast::IntTy) -> F::Result {
+ self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Signed(ty)))
+ }
+
+ pub fn isize(self, value: usize) -> F::Result {
+ self.build_int(value as u64, ast::IntTy::Is)
+ }
+
+ pub fn i8(self, value: u8) -> F::Result {
+ self.build_int(value as u64, ast::IntTy::I8)
+ }
+
+ pub fn i16(self, value: u16) -> F::Result {
+ self.build_int(value as u64, ast::IntTy::I16)
+ }
+
+ pub fn i32(self, value: u32) -> F::Result {
+ self.build_int(value as u64, ast::IntTy::I32)
+ }
+
+ pub fn i64(self, value: u64) -> F::Result {
+ self.build_int(value as u64, ast::IntTy::I64)
+ }
+
+ pub fn uint(self, value: u64) -> F::Result {
+ self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Unsuffixed))
+ }
+
+ fn build_uint(self, value: u64, ty: ast::UintTy) -> F::Result {
+ self.build_lit(ast::LitKind::Int(value, ast::LitIntType::Unsigned(ty)))
+ }
+
+ pub fn usize(self, value: usize) -> F::Result {
+ self.build_uint(value as u64, ast::UintTy::Us)
+ }
+
+ pub fn u8(self, value: u8) -> F::Result {
+ self.build_uint(value as u64, ast::UintTy::U8)
+ }
+
+ pub fn u16(self, value: u16) -> F::Result {
+ self.build_uint(value as u64, ast::UintTy::U16)
+ }
+
+ pub fn u32(self, value: u32) -> F::Result {
+ self.build_uint(value as u64, ast::UintTy::U32)
+ }
+
+ pub fn u64(self, value: u64) -> F::Result {
+ self.build_uint(value, ast::UintTy::U64)
+ }
+
+ fn build_float<S>(self, value: S, ty: ast::FloatTy) -> F::Result
+ where S: ToInternedString,
+ {
+ self.build_lit(ast::LitKind::Float(value.to_interned_string(), ty))
+ }
+
+ pub fn f32<S>(self, value: S) -> F::Result
+ where S: ToInternedString,
+ {
+ self.build_float(value, ast::FloatTy::F32)
+ }
+
+ pub fn f64<S>(self, value: S) -> F::Result
+ where S: ToInternedString,
+ {
+ self.build_float(value, ast::FloatTy::F64)
+ }
+
+ pub fn char(self, value: char) -> F::Result {
+ self.build_lit(ast::LitKind::Char(value))
+ }
+
+ pub fn byte(self, value: u8) -> F::Result {
+ self.build_lit(ast::LitKind::Byte(value))
+ }
+
+ pub fn str<S>(self, value: S) -> F::Result
+ where S: ToInternedString,
+ {
+ let value = value.to_interned_string();
+ self.build_lit(ast::LitKind::Str(value, ast::StrStyle::Cooked))
+ }
+
+ pub fn byte_str<T>(self, value: T) -> F::Result
+ where T: Into<Vec<u8>>,
+ {
+ self.build_lit(ast::LitKind::ByteStr(Rc::new(value.into())))
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/mac.rs
@@ -0,0 +1,144 @@
+use syntax::ast;
+use syntax::codemap::{self, DUMMY_SP, Span, respan};
+use syntax::ext::base::{DummyResolver, ExtCtxt};
+use syntax::ext::expand;
+use syntax::ext::quote::rt::ToTokens;
+use syntax::parse::ParseSess;
+use syntax::ptr::P;
+use syntax::tokenstream::TokenTree;
+
+use expr::ExprBuilder;
+use invoke::{Invoke, Identity};
+use name::ToName;
+use path::PathBuilder;
+
+/// A Builder for macro invocations.
+///
+/// Note that there are no commas added between args, as otherwise
+/// that macro invocations that could be expressed would be limited.
+/// You will need to add all required symbols with `with_arg` or
+/// `with_argss`.
+pub struct MacBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+}
+
+impl MacBuilder {
+ pub fn new() -> Self {
+ MacBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> MacBuilder<F>
+ where F: Invoke<ast::Mac>
+{
+ pub fn with_callback(callback: F) -> Self {
+ MacBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn build_path(self, path: ast::Path) -> MacPathBuilder<F> {
+ MacPathBuilder {
+ callback: self.callback,
+ span: self.span,
+ path: path,
+ tokens: vec![],
+ }
+ }
+
+ pub fn path(self) -> PathBuilder<Self> {
+ let span = self.span;
+ PathBuilder::with_callback(self).span(span)
+ }
+}
+
+impl<F> Invoke<ast::Path> for MacBuilder<F>
+ where F: Invoke<ast::Mac>,
+{
+ type Result = MacPathBuilder<F>;
+
+ fn invoke(self, path: ast::Path) -> Self::Result {
+ self.build_path(path)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct MacPathBuilder<F> {
+ callback: F,
+ span: Span,
+ path: ast::Path,
+ tokens: Vec<TokenTree>,
+}
+
+impl<F> MacPathBuilder<F>
+ where F: Invoke<ast::Mac>,
+{
+ pub fn with_args<I, T>(self, iter: I) -> Self
+ where I: IntoIterator<Item=T>, T: ToTokens
+ {
+ iter.into_iter().fold(self, |self_, expr| self_.with_arg(expr))
+ }
+
+ pub fn with_arg<T>(mut self, expr: T) -> Self
+ where T: ToTokens
+ {
+ let parse_sess = ParseSess::new();
+ let mut macro_loader = DummyResolver;
+ let cx = make_ext_ctxt(&parse_sess, &mut macro_loader);
+ let tokens = expr.to_tokens(&cx);
+ assert!(tokens.len() == 1);
+ self.tokens.push(tokens[0].clone());
+ self
+ }
+
+ pub fn expr(self) -> ExprBuilder<Self> {
+ let span = self.span;
+ ExprBuilder::with_callback(self).span(span)
+ }
+
+ pub fn build(self) -> F::Result {
+ let mac = ast::Mac_ {
+ path: self.path,
+ tts: self.tokens,
+ };
+ self.callback.invoke(respan(self.span, mac))
+ }
+}
+
+impl<F> Invoke<P<ast::Expr>> for MacPathBuilder<F>
+ where F: Invoke<ast::Mac>,
+{
+ type Result = Self;
+
+ fn invoke(self, expr: P<ast::Expr>) -> Self {
+ self.with_arg(expr)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+fn make_ext_ctxt<'a>(sess: &'a ParseSess,
+ macro_loader: &'a mut DummyResolver) -> ExtCtxt<'a> {
+ let info = codemap::ExpnInfo {
+ call_site: codemap::DUMMY_SP,
+ callee: codemap::NameAndSpan {
+ format: codemap::MacroAttribute("test".to_name()),
+ allow_internal_unstable: false,
+ span: None
+ }
+ };
+
+ let ecfg = expand::ExpansionConfig::default(String::new());
+ let mut cx = ExtCtxt::new(sess, ecfg, macro_loader);
+ cx.bt_push(info);
+
+ cx
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/method.rs
@@ -0,0 +1,103 @@
+use syntax::abi::Abi;
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, respan, Span};
+use syntax::ptr::P;
+
+use fn_decl::FnDeclBuilder;
+use generics::GenericsBuilder;
+use invoke::{Invoke, Identity};
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct MethodSigBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+ abi: Abi,
+ generics: ast::Generics,
+ unsafety: ast::Unsafety,
+ constness: ast::Constness,
+}
+
+impl MethodSigBuilder {
+ pub fn new() -> Self {
+ MethodSigBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> MethodSigBuilder<F>
+ where F: Invoke<ast::MethodSig>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ MethodSigBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ abi: Abi::Rust,
+ generics: GenericsBuilder::new().build(),
+ unsafety: ast::Unsafety::Normal,
+ constness: ast::Constness::NotConst,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn unsafe_(mut self) -> Self {
+ self.unsafety = ast::Unsafety::Unsafe;
+ self
+ }
+
+ pub fn const_(mut self) -> Self {
+ self.constness = ast::Constness::Const;
+ self
+ }
+
+ pub fn abi(mut self, abi: Abi) -> Self {
+ self.abi = abi;
+ self
+ }
+
+ pub fn with_generics(mut self, generics: ast::Generics) -> Self {
+ self.generics = generics;
+ self
+ }
+
+ pub fn generics(self) -> GenericsBuilder<Self> {
+ GenericsBuilder::with_callback(self)
+ }
+
+ pub fn build_fn_decl(self, fn_decl: P<ast::FnDecl>) -> F::Result {
+ self.callback.invoke(ast::MethodSig {
+ unsafety: self.unsafety,
+ constness: respan(self.span, self.constness),
+ abi: self.abi,
+ decl: fn_decl,
+ generics: self.generics,
+ })
+ }
+
+ pub fn fn_decl(self) -> FnDeclBuilder<Self> {
+ FnDeclBuilder::with_callback(self)
+ }
+}
+
+impl<F> Invoke<ast::Generics> for MethodSigBuilder<F>
+ where F: Invoke<ast::MethodSig>,
+{
+ type Result = Self;
+
+ fn invoke(self, generics: ast::Generics) -> Self {
+ self.with_generics(generics)
+ }
+}
+
+impl<F> Invoke<P<ast::FnDecl>> for MethodSigBuilder<F>
+ where F: Invoke<ast::MethodSig>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, fn_decl: P<ast::FnDecl>) -> Self::Result {
+ self.build_fn_decl(fn_decl)
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/name.rs
@@ -0,0 +1,32 @@
+use syntax::ast;
+use syntax::parse::token;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub trait ToName {
+ fn to_name(&self) -> ast::Name;
+}
+
+impl ToName for ast::Name {
+ fn to_name(&self) -> ast::Name {
+ *self
+ }
+}
+
+impl<'a> ToName for &'a str {
+ fn to_name(&self) -> ast::Name {
+ token::intern(*self)
+ }
+}
+
+impl<'a, T> ToName for &'a T where T: ToName {
+ fn to_name(&self) -> ast::Name {
+ (**self).to_name()
+ }
+}
+
+impl<'a, T> ToName for &'a mut T where T: ToName {
+ fn to_name(&self) -> ast::Name {
+ (**self).to_name()
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/aster/src/pat.rs
@@ -0,0 +1,558 @@
+use std::iter::IntoIterator;
+
+use syntax::ast;
+use syntax::codemap::{DUMMY_SP, Span, Spanned, respan};
+use syntax::ptr::P;
+
+use invoke::{Invoke, Identity};
+
+use expr::ExprBuilder;
+use ident::ToIdent;
+use path::PathBuilder;
+use qpath::QPathBuilder;
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatBuilder<F=Identity> {
+ callback: F,
+ span: Span,
+}
+
+impl PatBuilder {
+ pub fn new() -> Self {
+ PatBuilder::with_callback(Identity)
+ }
+}
+
+impl<F> PatBuilder<F>
+ where F: Invoke<P<ast::Pat>>,
+{
+ pub fn with_callback(callback: F) -> Self {
+ PatBuilder {
+ callback: callback,
+ span: DUMMY_SP,
+ }
+ }
+
+ pub fn span(mut self, span: Span) -> Self {
+ self.span = span;
+ self
+ }
+
+ pub fn build(self, pat: P<ast::Pat>) -> F::Result {
+ self.callback.invoke(pat)
+ }
+
+ pub fn build_pat_kind(self, pat_kind: ast::PatKind) -> F::Result {
+ let span = self.span;
+ self.build(P(ast::Pat {
+ id: ast::DUMMY_NODE_ID,
+ node: pat_kind,
+ span: span,
+ }))
+ }
+
+ pub fn wild(self) -> F::Result {
+ self.build_pat_kind(ast::PatKind::Wild)
+ }
+
+ pub fn build_id<I>(self, mode: ast::BindingMode, id: I, sub: Option<P<ast::Pat>>) -> F::Result
+ where I: ToIdent,
+ {
+ let id = respan(self.span, id.to_ident());
+
+ self.build_pat_kind(ast::PatKind::Ident(mode, id, sub))
+ }
+
+ pub fn id<I>(self, id: I) -> F::Result
+ where I: ToIdent
+ {
+ let mode = ast::BindingMode::ByValue(ast::Mutability::Immutable);
+ self.build_id(mode, id, None)
+ }
+
+ pub fn mut_id<I>(self, id: I) -> F::Result
+ where I: ToIdent
+ {
+ let mode = ast::BindingMode::ByValue(ast::Mutability::Mutable);
+ self.build_id(mode, id, None)
+ }
+
+ pub fn ref_id<I>(self, id: I) -> F::Result
+ where I: ToIdent
+ {
+ let mode = ast::BindingMode::ByRef(ast::Mutability::Immutable);
+ self.build_id(mode, id, None)
+ }
+
+ pub fn ref_mut_id<I>(self, id: I) -> F::Result
+ where I: ToIdent
+ {
+ let mode = ast::BindingMode::ByRef(ast::Mutability::Mutable);
+ self.build_id(mode, id, None)
+ }
+
+ pub fn enum_(self) -> PathBuilder<PatEnumBuilder<F>> {
+ PathBuilder::with_callback(PatEnumBuilder(self))
+ }
+
+ pub fn struct_(self) -> PathBuilder<PatStructBuilder<F>> {
+ PathBuilder::with_callback(PatStructBuilder(self))
+ }
+
+ pub fn expr(self) -> ExprBuilder<PatExprBuilder<F>> {
+ ExprBuilder::with_callback(PatExprBuilder(self))
+ }
+
+ pub fn build_path(self, path: ast::Path) -> F::Result {
+ self.build_pat_kind(ast::PatKind::Path(None, path))
+ }
+
+ pub fn build_qpath(self, qself: ast::QSelf, path: ast::Path) -> F::Result {
+ self.build_pat_kind(ast::PatKind::Path(Some(qself), path))
+ }
+
+ pub fn path(self) -> PathBuilder<Self> {
+ PathBuilder::with_callback(self)
+ }
+
+ pub fn qpath(self) -> QPathBuilder<Self> {
+ QPathBuilder::with_callback(self)
+ }
+
+ pub fn build_range(self, lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> F::Result {
+ self.build_pat_kind(ast::PatKind::Range(lhs, rhs))
+ }
+
+ pub fn range(self) -> ExprBuilder<PatRangeBuilder<F>> {
+ ExprBuilder::with_callback(PatRangeBuilder(self))
+ }
+
+ pub fn tuple(self) -> PatTupleBuilder<F> {
+ PatTupleBuilder {
+ builder: self,
+ pats: Vec::new(),
+ wild: None,
+ }
+ }
+
+ pub fn ref_(self) -> PatBuilder<PatRefBuilder<F>> {
+ PatBuilder::with_callback(PatRefBuilder {
+ builder: self,
+ mutability: ast::Mutability::Immutable,
+ })
+ }
+
+ pub fn ref_mut(self) -> PatBuilder<PatRefBuilder<F>> {
+ PatBuilder::with_callback(PatRefBuilder {
+ builder: self,
+ mutability: ast::Mutability::Mutable,
+ })
+ }
+
+ pub fn some(self) -> PatBuilder<PatEnumPathPatBuilder<F>> {
+ let path = PathBuilder::new().span(self.span)
+ .global()
+ .ids(&["std", "option", "Option", "Some"])
+ .build();
+
+ let span = self.span;
+ PatBuilder::with_callback(PatEnumPathPatBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ pub fn none(self) -> F::Result {
+ let path = PathBuilder::new().span(self.span)
+ .global()
+ .ids(&["std", "option", "Option", "None"])
+ .build();
+
+ self.enum_()
+ .build(path)
+ .build()
+ }
+
+ pub fn ok(self) -> PatBuilder<PatEnumPathPatBuilder<F>> {
+ let path = PathBuilder::new().span(self.span)
+ .global()
+ .ids(&["std", "result", "Result", "Ok"])
+ .build();
+
+ let span = self.span;
+ PatBuilder::with_callback(PatEnumPathPatBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+
+ pub fn err(self) -> PatBuilder<PatEnumPathPatBuilder<F>> {
+ let path = PathBuilder::new().span(self.span)
+ .global()
+ .ids(&["std", "result", "Result", "Err"])
+ .build();
+
+ let span = self.span;
+ PatBuilder::with_callback(PatEnumPathPatBuilder {
+ builder: self,
+ path: path,
+ }).span(span)
+ }
+}
+
+impl<F> Invoke<ast::Path> for PatBuilder<F>
+ where F: Invoke<P<ast::Pat>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, path: ast::Path) -> F::Result {
+ self.build_path(path)
+ }
+}
+
+impl<F> Invoke<(ast::QSelf, ast::Path)> for PatBuilder<F>
+ where F: Invoke<P<ast::Pat>>,
+{
+ type Result = F::Result;
+
+ fn invoke(self, (qself, path): (ast::QSelf, ast::Path)) -> F::Result {
+ self.build_qpath(qself, path)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatRangeBuilder<F>(PatBuilder<F>);
+
+impl<F> Invoke<P<ast::Expr>> for PatRangeBuilder<F>
+ where F: Invoke<P<ast::Pat>>
+{
+ type Result = ExprBuilder<PatRangeExprBuilder<F>>;
+
+ fn invoke(self, lhs: P<ast::Expr>) -> Self::Result {
+ ExprBuilder::with_callback(PatRangeExprBuilder {
+ builder: self.0,
+ lhs: lhs,
+ })
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatRangeExprBuilder<F> {
+ builder: PatBuilder<F>,
+ lhs: P<ast::Expr>,
+}
+
+impl<F> Invoke<P<ast::Expr>> for PatRangeExprBuilder<F>
+ where F: Invoke<P<ast::Pat>>
+{
+ type Result = F::Result;
+
+ fn invoke(self, rhs: P<ast::Expr>) -> Self::Result {
+ self.builder.build_range(self.lhs, rhs)
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatEnumBuilder<F>(PatBuilder<F>);
+
+impl<F> Invoke<ast::Path> for PatEnumBuilder<F> {
+ type Result = PatEnumPathBuilder<F>;
+
+ fn invoke(self, path: ast::Path) -> PatEnumPathBuilder<F> {
+ PatEnumPathBuilder {
+ builder: self.0,
+ path: path,
+ pats: Vec::new(),
+ wild: None,
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatEnumPathBuilder<F> {
+ builder: PatBuilder<F>,
+ path: ast::Path,
+ pats: Vec<P<ast::Pat>>,
+ wild: Option<usize>,
+}
+
+impl<F> PatEnumPathBuilder<F>
+ where F: Invoke<P<ast::Pat>>,
+{
+ pub fn with_pats<I>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=P<ast::Pat>>,
+ {
+ self.pats.extend(iter);
+ self
+ }
+
+ pub fn with_pat(mut self, pat: P<ast::Pat>) -> Self {
+ self.pats.push(pat);
+ self
+ }
+
+ pub fn pat(self) -> PatBuilder<Self> {
+ PatBuilder::with_callback(self)
+ }
+
+ pub fn with_ids<I, T>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=T>,
+ T: ToIdent,
+ {
+ for id in iter {
+ self = self.id(id);
+ }
+ self
+ }
+
+ pub fn id<I>(self, id: I) -> Self
+ where I: ToIdent
+ {
+ self.pat().id(id)
+ }
+
+ pub fn wild(mut self) -> Self {
+ self.wild = Some(self.pats.len());
+ self
+ }
+
+ pub fn build(self) -> F::Result {
+ self.builder.build_pat_kind(ast::PatKind::TupleStruct(
+ self.path,
+ self.pats,
+ self.wild))
+ }
+}
+
+impl<F> Invoke<P<ast::Pat>> for PatEnumPathBuilder<F>
+ where F: Invoke<P<ast::Pat>>,
+{
+ type Result = Self;
+
+ fn invoke(mut self, pat: P<ast::Pat>) -> Self {
+ self.pats.push(pat);
+ self
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatEnumPathPatBuilder<F> {
+ builder: PatBuilder<F>,
+ path: ast::Path,
+}
+
+impl<F> Invoke<P<ast::Pat>> for PatEnumPathPatBuilder<F>
+ where F: Invoke<P<ast::Pat>>
+{
+ type Result = F::Result;
+
+ fn invoke(self, pat: P<ast::Pat>) -> F::Result {
+ self.builder.enum_()
+ .build(self.path)
+ .with_pat(pat)
+ .build()
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatStructBuilder<F>(PatBuilder<F>);
+
+impl<F> Invoke<ast::Path> for PatStructBuilder<F> {
+ type Result = PatStructPathBuilder<F>;
+
+ fn invoke(self, path: ast::Path) -> PatStructPathBuilder<F> {
+ PatStructPathBuilder {
+ builder: self.0,
+ path: path,
+ pats: Vec::new(),
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+pub struct PatStructPathBuilder<F> {
+ builder: PatBuilder<F>,
+ path: ast::Path,
+ pats: Vec<Spanned<ast::FieldPat>>,
+}
+
+impl<F> PatStructPathBuilder<F>
+ where F: Invoke<P<ast::Pat>>,
+{
+ pub fn with_field_pat(mut self, pat: ast::FieldPat) -> Self {
+ self.pats.push(respan(self.builder.span, pat));
+ self
+ }
+
+ pub fn with_pats<I, T>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=(T, P<ast::Pat>)>,
+ T: ToIdent,
+ {
+ for (id, pat) in iter {
+ self = self.pat(id).build(pat);
+ }
+ self
+ }
+
+ pub fn pat<I>(self, id: I) -> PatBuilder<PatStructFieldBuilder<F>>
+ where I: ToIdent,
+ {
+ PatBuilder::with_callback(PatStructFieldBuilder {
+ builder: self,
+ id: id.to_ident(),
+ })
+ }
+
+ pub fn with_ids<I, T>(mut self, iter: I) -> Self
+ where I: IntoIterator<Item=T>,
+ T: ToIdent,
+ {
+ for id in iter {
+ self = self.id(id);
+ }
+ self
+ }
+
+ pub fn mut_id<I>(self, id: I) -> Self
+ where I: ToIdent,
+ {
+ let id = id.to_ident();
+ let span = self.builder.span;
+ let pat = PatBuilder::new().span(span).mut_id(id);