Skip to content
This repository has been archived by the owner on May 6, 2020. It is now read-only.

Commit

Permalink
Auto merge of #103 - habnabit:new-features, r=erickt
Browse files Browse the repository at this point in the history
Add some more methods

I needed these methods, so I added them.
  • Loading branch information
homu committed Sep 1, 2016
2 parents 9b6758a + 9397bff commit 04dae55
Show file tree
Hide file tree
Showing 7 changed files with 551 additions and 0 deletions.
228 changes: 228 additions & 0 deletions src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ 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;
Expand Down Expand Up @@ -801,6 +802,26 @@ impl<F> ExprBuilder<F>
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,
})
}
}

impl<F> Invoke<ast::Attribute> for ExprBuilder<F>
Expand Down Expand Up @@ -1850,3 +1871,210 @@ impl<F> Invoke<P<ast::Expr>> for ExprTryBuilder<F>
.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>) -> ExprClosureBlockBuilder<F> {
ExprClosureBlockBuilder {
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 = ExprClosureBlockBuilder<F>;

fn invoke(self, fn_decl: P<ast::FnDecl>) -> ExprClosureBlockBuilder<F> {
self.build_fn_decl(fn_decl)
}
}

//////////////////////////////////////////////////////////////////////////////

pub struct ExprClosureBlockBuilder<F> {
builder: ExprBuilder<F>,
capture_by: ast::CaptureBy,
fn_decl: P<ast::FnDecl>,
span: Span,
}

impl<F> ExprClosureBlockBuilder<F>
where F: Invoke<P<ast::Expr>>,
{
pub fn expr(self) -> ExprBuilder<BlockBuilder<Self>> {
self.block().expr()
}

pub fn block(self) -> BlockBuilder<Self> {
BlockBuilder::with_callback(self)
}

pub fn build_block(self, block: P<ast::Block>) -> F::Result {
self.builder.build_expr_kind(ast::ExprKind::Closure(self.capture_by, self.fn_decl, block, self.span))
}
}

impl<F> Invoke<P<ast::Block>> for ExprClosureBlockBuilder<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 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))
}
}
31 changes: 31 additions & 0 deletions src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,20 @@ impl<F> PatBuilder<F>
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,
})
}
}

impl<F> Invoke<ast::Path> for PatBuilder<F>
Expand Down Expand Up @@ -447,3 +461,20 @@ impl<F> Invoke<P<ast::Pat>> for PatTupleBuilder<F>
self.with_pat(pat)
}
}

//////////////////////////////////////////////////////////////////////////////

pub struct PatRefBuilder<F> {
builder: PatBuilder<F>,
mutability: ast::Mutability,
}

impl<F> Invoke<P<ast::Pat>> for PatRefBuilder<F>
where F: Invoke<P<ast::Pat>>
{
type Result = F::Result;

fn invoke(self, pat: P<ast::Pat>) -> F::Result {
self.builder.build_pat_kind(ast::PatKind::Ref(pat, self.mutability))
}
}
37 changes: 37 additions & 0 deletions src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,29 @@ impl<F> PathSegmentBuilder<F>
}).span(span)
}

pub fn no_return(self) -> F::Result {
self.build_return(None)
}

pub fn return_(self) -> TyBuilder<PathSegmentReturnBuilder<F>> {
TyBuilder::with_callback(PathSegmentReturnBuilder(self))
}

pub fn build_return(self, output: Option<P<ast::Ty>>) -> F::Result {
let data = ast::ParenthesizedParameterData {
span: self.span,
inputs: self.tys,
output: output,
};

let parameters = ast::PathParameters::Parenthesized(data);

self.callback.invoke(ast::PathSegment {
identifier: self.id,
parameters: parameters,
})
}

pub fn build(self) -> F::Result {
let data = ast::AngleBracketedParameterData {
lifetimes: self.lifetimes,
Expand Down Expand Up @@ -326,3 +349,17 @@ impl<F> Invoke<P<ast::Ty>> for TypeBindingBuilder<F>
})
}
}

//////////////////////////////////////////////////////////////////////////////

pub struct PathSegmentReturnBuilder<F>(PathSegmentBuilder<F>);

impl<F> Invoke<P<ast::Ty>> for PathSegmentReturnBuilder<F>
where F: Invoke<ast::PathSegment>
{
type Result = F::Result;

fn invoke(self, ty: P<ast::Ty>) -> Self::Result {
self.0.build_return(Some(ty))
}
}
1 change: 1 addition & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod test_fn_decl;
mod test_generics;
mod test_item;
mod test_lit;
mod test_pat;
mod test_path;
mod test_stmt;
mod test_struct_field;
Expand Down
Loading

0 comments on commit 04dae55

Please sign in to comment.