easy-plugin 0.6.2

A compiler plugin that makes it easier to write compiler plugins.
// Copyright 2016 Kyle Mayes
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Conversion of parsing results into other AST entities.

use std::rc::{Rc};

use syntax::abi::{Abi};
use syntax::ast::*;
use syntax::attr::{ThinAttributes};
use syntax::codemap::{self, Span, Spanned};
use syntax::parse::token::{self, BinOpToken, DelimToken, Nonterminal};
use syntax::parse::token::{SpecialMacroVar, Token};
use syntax::ptr::{P};

use super::{PluginResult, ToError};

//================================================
// Functions
//================================================

__easy_plugin_convert!(attr: Attribute(attr.node.value.node) -> MetaItemKind, [
    Word(ts) -> (String),
    List(ts, _) -> (String, Vec<P<MetaItem>>),
    NameValue(ts, _) -> (String, Lit),
]);

__easy_plugin_convert!(expr: Expr(expr.node) -> ExprKind, [
    Box(_) -> (P<Expr>),
    InPlace(_, _) -> (P<Expr>, P<Expr>),
    Vec(_) -> (Vec<P<Expr>>),
    Call(_, _) -> (P<Expr>, Vec<P<Expr>>),
    MethodCall(_, _, _) -> (SpannedIdent, Vec<P<Ty>>, Vec<P<Expr>>),
    Tup(_) -> (Vec<P<Expr>>),
    Binary(_, _, _) -> (BinOp, P<Expr>, P<Expr>),
    Unary(_, _) -> (UnOp, P<Expr>),
    Lit(_) -> (P<Lit>),
    Cast(_, _) -> (P<Expr>, P<Ty>),
    Type(_, _) -> (P<Expr>, P<Ty>),
    If(_, _, _) -> (P<Expr>, P<Block>, Option<P<Expr>>),
    IfLet(_, _, _, _) -> (P<Pat>, P<Expr>, P<Block>, Option<P<Expr>>),
    While(_, _, _) -> (P<Expr>, P<Block>, Option<SpannedIdent>),
    WhileLet(_, _, _, _) -> (P<Pat>, P<Expr>, P<Block>, Option<SpannedIdent>),
    ForLoop(_, _, _, _) -> (P<Pat>, P<Expr>, P<Block>, Option<SpannedIdent>),
    Loop(_, _) -> (P<Block>, Option<SpannedIdent>),
    Match(_, _) -> (P<Expr>, Vec<Arm>),
    Closure(_, _, _, _) -> (CaptureBy, P<FnDecl>, P<Block>, Span),
    Block(_) -> (P<Block>),
    Assign(_, _) -> (P<Expr>, P<Expr>),
    AssignOp(_, _, _) -> (BinOp, P<Expr>, P<Expr>),
    Field(_, _) -> (P<Expr>, SpannedIdent),
    TupField(_, _) -> (P<Expr>, Spanned<usize>),
    Index(_, _) -> (P<Expr>, P<Expr>),
    Range(_, _, _) -> (Option<P<Expr>>, Option<P<Expr>>, RangeLimits),
    Path(_, _) -> (Option<QSelf>, Path),
    AddrOf(_, _) -> (Mutability, P<Expr>),
    Break(_) -> (Option<SpannedIdent>),
    Again(_) -> (Option<SpannedIdent>),
    Ret(_) -> (Option<P<Expr>>),
    InlineAsm(_) -> (InlineAsm),
    Mac(_) -> (Mac),
    Struct(_, _, _) -> (Path, Vec<Field>, Option<P<Expr>>),
    Repeat(_, _) -> (P<Expr>, P<Expr>),
    Paren(_) -> (P<Expr>),
    Try(_) -> (P<Expr>),
]);

__easy_plugin_convert!(item: Item(item.node) -> ItemKind, [
    ExternCrate(masts) -> (Option<String>),
    Use(_) -> (P<ViewPath>),
    Static(_, _, _) -> (P<Ty>, Mutability, P<Expr>),
    Const(_, _) -> (P<Ty>, P<Expr>),
    Fn(_, _, _, _, _, _) -> (P<FnDecl>, Unsafety, Constness, Abi, Generics, P<Block>),
    Mod(_) -> (Mod),
    ForeignMod(_) -> (ForeignMod),
    Ty(_, _) -> (P<Ty>, Generics),
    Enum(_, _) -> (EnumDef, Generics),
    Struct(_, _) -> (VariantData, Generics),
    Trait(_, _, _, _) -> (Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
    DefaultImpl(_, _) -> (Unsafety, TraitRef),
    Impl(_, _, _, _, _, _) -> (Unsafety, ImplPolarity, Generics, Option<TraitRef>, P<Ty>, Vec<ImplItem>),
    Mac(_) -> (Mac),
]);

__easy_plugin_convert!(lit: Lit(lit.node) -> LitKind, [
    Str(ts, _) -> (String, StrStyle),
    ByteStr(_) -> (Rc<Vec<u8>>),
    Byte(_) -> (u8),
    Char(_) -> (char),
    Int(_, _) -> (u64, LitIntType),
    Float(ts, _) -> (String, FloatTy),
    FloatUnsuffixed(ts) -> (String),
    Bool(_) -> (bool),
]);

__easy_plugin_convert!(meta: MetaItem(meta.node) -> MetaItemKind, [
    Word(ts) -> (String),
    List(ts, _) -> (String, Vec<P<MetaItem>>),
    NameValue(ts, _) -> (String, Lit),
]);

__easy_plugin_convert!(pat: Pat(pat.node) -> PatKind, [
    Wild() -> (),
    Ident(_, _, _) -> (BindingMode, SpannedIdent, Option<P<Pat>>),
    Struct(_, _, _) -> (Path, Vec<Spanned<FieldPat>>, bool),
    TupleStruct(_, _, _) -> (Path, Vec<P<Pat>>, Option<usize>),
    Path(_) -> (Path),
    QPath(_, _) -> (QSelf, Path),
    Tuple(_, _) -> (Vec<P<Pat>>, Option<usize>),
    Box(_) -> (P<Pat>),
    Ref(_, _) -> (P<Pat>, Mutability),
    Lit(_) -> (P<Expr>),
    Range(_, _) -> (P<Expr>, P<Expr>),
    Vec(_, _, _) -> (Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
    Mac(_) -> (Mac),
]);

__easy_plugin_convert!(stmt: Stmt(stmt.node) -> StmtKind, [
    Decl(_, _) -> (P<Decl>, NodeId),
    Expr(_, _) -> (P<Expr>, NodeId),
    Semi(_, _) -> (P<Expr>, NodeId),
    Mac(_, _, _) -> (P<Mac>, MacStmtStyle, ThinAttributes),
]);

__easy_plugin_convert!(ty: Ty(ty.node) -> TyKind, [
    Vec(_) -> (P<Ty>),
    FixedLengthVec(_, _) -> (P<Ty>, P<Expr>),
    Ptr(_) -> (MutTy),
    Rptr(_, _) -> (Option<Lifetime>, MutTy),
    BareFn(_) -> (P<BareFnTy>),
    Tup(_) -> (Vec<P<Ty>>),
    Path(_, _) -> (Option<QSelf>, Path),
    ObjectSum(_, _) -> (P<Ty>, TyParamBounds),
    PolyTraitRef(_) -> (TyParamBounds),
    Paren(_) -> (P<Ty>),
    Typeof(_) -> (P<Expr>),
    Infer() -> (),
    Mac(_) -> (Mac),
]);

__easy_plugin_convert!(tok: [Spanned<Token>](tok.node) -> Token, [
    Eq() -> (),
    Lt() -> (),
    Le() -> (),
    EqEq() -> (),
    Ne() -> (),
    Ge() -> (),
    Gt() -> (),
    AndAnd() -> (),
    OrOr() -> (),
    Not() -> (),
    Tilde() -> (),
    BinOp(_) -> (BinOpToken),
    BinOpEq(_) -> (BinOpToken),
    At() -> (),
    Dot() -> (),
    DotDot() -> (),
    DotDotDot() -> (),
    Comma() -> (),
    Semi() -> (),
    Colon() -> (),
    ModSep() -> (),
    RArrow() -> (),
    LArrow() -> (),
    FatArrow() -> (),
    Pound() -> (),
    Dollar() -> (),
    Question() -> (),
    OpenDelim(_) -> (DelimToken),
    CloseDelim(_) -> (DelimToken),
    Literal(_, masts) -> (token::Lit, Option<String>),
    Ident(_) -> (Ident),
    Underscore() -> (),
    Lifetime(_) -> (Ident),
    Interpolated(_) -> (Nonterminal),
    DocComment(asts) -> (String),
    MatchNt(_, _) -> (Ident, Ident),
    SubstNt(_) -> (Ident),
    SpecialVarNt(_) -> (SpecialMacroVar),
    Whitespace() -> (),
    Comment() -> (),
    Shebang(asts) -> (String),
    Eof() -> (),
]);

/// Returns the `TokenTree::Delimited` value in the supplied `TokenTree`.
pub fn tt_to_delimited(tt: &TokenTree) -> PluginResult<Rc<Delimited>> {
    match *tt {
        TokenTree::Delimited(_, ref delimited) => Ok(delimited.clone()),
        _ => tt.to_error("expected `TokenTree::Delimited` tt"),
    }
}

/// Returns the `TokenTree::Token` value in the supplied `TokenTree`.
pub fn tt_to_token(tt: &TokenTree) -> PluginResult<Spanned<Token>> {
    match *tt {
        TokenTree::Token(span, ref token) => Ok(codemap::respan(span, token.clone())),
        _ => tt.to_error("expected `TokenTree::Token` tt"),
    }
}

/// Returns the `TokenTree::Sequence` value in the supplied `TokenTree`.
pub fn tt_to_sequence(tt: &TokenTree) -> PluginResult<Rc<SequenceRepetition>> {
    match *tt {
        TokenTree::Sequence(_, ref sequence) => Ok(sequence.clone()),
        _ => tt.to_error("expected `TokenTree::Sequence` tt"),
    }
}