Crate easy_plugin [−] [src]
This crate provides a compiler plugin, easy_plugin!
, which makes it easier to write compiler
plugins.
easy_plugin!
generates a wrapper function around your plugin function which handles argument
parsing and error reporting for you, significantly reducing the time it takes to write a plugin.
First, here is a trivial example.
#![feature(plugin, plugin_registrar, rustc_private)] #![plugin(easy_plugin)] #[allow(plugin_as_library)] extern crate easy_plugin; use easy_plugin::{PluginResult}; // rustc_plugin and syntax imports... easy_plugin! { struct Arguments { $a:ident } /// My plugin. pub fn expand_plugin( context: &mut ExtCtxt, span: Span, arguments: Arguments ) -> PluginResult<Box<MacResult>> { println!("{:?}", arguments.a); Ok(DummyResult::any(span)) } } #[plugin_registrar] pub fn plugin_registrar(registry: &mut Registry) { registry.register_macro("plugin", expand_plugin); }
In this example, note that the arguments of the plugin function expand_plugin
differ from a
typical plugin function in that the last argument is of type Arguments
rather than
&[TokenTree]
. This is because the generated wrapper function handles argument parsing for you.
The definition of the Arguments
struct above expand_plugin
provides the argument
specification and the generated wrapper function parses the arguments and stores them in an
instance of Arguments
.
In this example, the argument specification consists of $a:ident
, which means that the only
argument this plugin will accept is a single identifier which will be stored in a field named
a
in the Arguments
struct. For more information on argument specifications, see the relevant
section below.
If the arguments do not match the argument specification or your plugin function returns Err
,
the wrapper function will report an error with ExtCtxt::span_err
for you.
Note that the expand_plugin
function is public and has a documentation comment. The visibility
and attributes applied to your plugin function (including documentation comments) will be
applied to the wrapper function. In this example, the wrapper function will be public and have
a documentation comment.
Specifications
Plugin argument specifications are very similar to the argument specifications you are used to writing for macros. There are two primary differences: no restrictions on ordering and additional types of named specifiers.
Name | Description | Storage Type |
---|---|---|
attr |
An attribute. | Attribute |
binop |
A binary operator. | Spanned<BinOpToken> |
block |
A brace-delimited statement sequence. | P<Block> |
delim |
A delimited token tree sequence. | Spanned<Delimited> |
expr |
An expression. | P<Expr> |
ident |
An identifier. | Spanned<Ident> |
item |
An item. | P<Item> |
lftm |
A lifetime. | Spanned<Name> |
lit |
A literal. | Lit |
meta |
A "meta" item, as found in attributes. | P<MetaItem> |
pat |
A pattern. | P<Pat> |
path |
A qualified name. | Path |
stmt |
A single statement. | Stmt |
ty |
A type. | P<Ty> |
tok |
A single token. | Spanned<Token> |
tt |
A single token tree. | TokenTree |
In addition to the specifiers above, there is also a specifier for each extractor
function. For example, the specifier for the
extractor::lit_to_str
function is lit_str
. The storage type
for these specifiers is the return type of the corresponding extractor
function.
For example, the storage type of the lit_str
specifier is (String, StrStyle)
.
Sequences
Plugin argument specifications support sequences that are very similar to the sequences in macro argument specifications. For example, the following plugin argument specification matches zero or more comma-separated parenthesized binary expressions.
$(($left:ident $operator:binop $right:ident)), *
In addition to the *
and +
sequence operators, there is also a ?
operator which allows for
sequences with either zero or one repetitions. This operator does not support separators. For
example, the following plugin argument specification can match either a binary expression or
nothing at all.
$($left:ident $operator:binop $right:ident)?
Named specifiers that occur in sequences cannot be stored directly as their storage type because
there may be more than one or none at all. For this reason, named specifiers that occur in
sequences have the storage type of either Vec<$type>
or Option<$type>
where $type
is the
base storage type. Vec<$type>
is used for *
and +
sequences and Option<$type>
is used
for ?
sequences.
An additional level of Vec
is added for each sequence level. For example, in the plugin
argument specification below, $b:ident
occurs two sequences deep. The storage type for b
in
this case would be Vec<Vec<syntax::ast::Ident>>
.
$($a:ident $($b:ident)*)*
Named Sequences
There are also named sequences, which behave rather differently than regular sequences. Named
sequences cannot contain named specifiers and instead consist of specific token trees that you
wish to be counted. For example, the following plugin argument specification will match
either pub struct { }
or just struct { }
.
$public:(pub)? struct { }
These named sequences allow the usage of the same suffixes as regular sequences. The *
, +
,
and ?
operators are supported and separators are supported for the *
and +
operators. For
example, the following plugin argument specification matches any number of comma-separated A
s.
$a:(A), *
Because named sequences are counted, the storage types are simply usize
for *
and +
named
sequences and bool
for ?
named sequences.
Enums
There are also enumerated specifiers, which allow for a choice of possible values. For example, the following plugin argument specification will match either an identifier or a meta item.
$e:{A($a:ident), B($b:meta)}
The storage types for enumerated specifiers are generated enums. For example, the storage type
for e
above would be the following enum.
#[derive(Debug)] enum e_Enum { A { a: Spanned<Ident> }, B { b: P<MetaItem> }, }
Reexports
pub use parsers::arguments::*; |
pub use parsers::specification::*; |
Modules
extractor |
Functions for extracting the values in AST entities. |
Traits
PluginResultExt |
Extends |
ToError |
A type that can be extended into a |
Type Definitions
PluginResult |