Hi, I am looking for methods to instrument rust statements and I am wondering whether rust compiler plugin is the right approach. Demonstration of my intent:
before:
foo();
after: checkfoo(); foo();
Rust compiler plugin provides several ways to extend syntax,
-
register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension)
, register a syntax extension of any kind. -
register_custom_derive(&mut self, name: ast::Name, extension: SyntaxExtension)
, register legacy custom derives -
register_macro(&mut self, name: &str, expander: MacroExpanderFn)
, register a macro of the usual kind. -
register_early_lint_pass(&mut self, lint_pass: EarlyLintPassObject)
, register a compiler lint pass -
register_late_lint_pass(&mut self, lint_pass: LateLintPassObject)
, register a compiler lint pass register_lint_group(&mut self, name: &'static str, to: Vec<&'static Lint>)
-
register_mir_pass(&mut self, pass: Box<for<'pcx> MirMapPass<'pcx>>)
, register a MIR pass -
pub fn register_llvm_pass(&mut self, name: &str)
, register an LLVM pass, this is handled through static C++ objects with constructors. This method simply adds a name to the list of passes to execute. -
register_attribute(&mut self, name: String, ty: AttributeType)
, register an attribute with an attribute type. Registered attributes will bypass thecustom_attribute
feature gate.
I am considering to use register_syntax_extension
to register a new extension, SyntaxExtension
is defined as :
pub enum SyntaxExtension { MultiDecorator(Box<MultiItemDecorator>), MultiModifier(Box<MultiItemModifier>), ProcMacro(Box<ProcMacro>), AttrProcMacro(Box<AttrProcMacro>), NormalTT(Box<TTMacroExpander>, Option<Span>, bool), IdentTT(Box<IdentMacroExpander>, Option<Span>, bool), CustomDerive(Box<MultiItemModifier>), }
Through comparison, I determined I can delare a MulitiModifier
to annotate the job.
// `meta_item` is the annotation, and `item` is the item being modified.
pub trait MultiItemModifier {
fn expand(&self,
ecx: &mut ExtCtxt,
span: Span,
meta_item: &ast::MetaItem,
item: Annotatable)
-> Vec<Annotatable>;
}
The question is the Annotatable
is not applied to 'statements':
#[derive(Debug,Clone)]
pub enum Annotatable {
Item(P<ast::Item>),
TraitItem(P<ast::TraitItem>),
ImplItem(P<ast::ImplItem>),
}
Item
,TraitItem
, ImplItem
, don't have a 'statement
' type. So I wondering is it plausible to instrument the statement using the 'SyntaxExtension
'?