Skip to content

Commit

Permalink
Add optional prefix string as per llogiq#16
Browse files Browse the repository at this point in the history
  • Loading branch information
antonok-edm committed Jul 8, 2018
1 parent 42cf2df commit b765eae
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 10 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ You should then be able to annotate every item (or even the whole crate) with
instrumentations for subitems of `#[flame]`d items. Note that this only
instruments the annotated methods, it does not print out the results.

The `flame` annotation can also take an optional parameter specifying a string
to prefix to enclosed method names. This is especially useful when annotating
multiple methods with the same name, but in different modules.

```
#[flame("prefix")]
fn method_name() {
//The corresponding block on the flamegraph will be named "prefix::method_name"
}
```

Refer to [flame's documentation](https://docs.rs/flame) to see how output works.

License: Apache 2.0
44 changes: 35 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ extern crate syntax;

use rustc_plugin::registry::Registry;
use syntax::ast::{Attribute, Block, Expr, ExprKind, Ident, Item, ItemKind, Mac,
MetaItem, Constness};
MetaItem, Constness, MetaItemKind, LitKind};
use syntax::fold::{self, Folder};
use syntax::ptr::P;
use syntax::codemap::{DUMMY_SP, Span};
Expand All @@ -15,22 +15,40 @@ use syntax::feature_gate::AttributeType;
use syntax::symbol::Symbol;
use syntax::util::small_vector::SmallVector;

pub fn insert_flame_guard(cx: &mut ExtCtxt, _span: Span, _mi: &MetaItem,
pub fn insert_flame_guard(cx: &mut ExtCtxt, _span: Span, mi: &MetaItem,
a: Annotatable) -> Annotatable {
let opt_ident = match mi.node {
MetaItemKind::Word => None,
MetaItemKind::List(ref v) => {
if v.len() != 1 {
None
} else {
match v.get(0).unwrap().literal() {
None => None,
Some(l) => match l.node {
LitKind::Str(s, _style) => Some(s),
_ => None,
}
}
}
},
MetaItemKind::NameValue(_) => None,
};
match a {
Annotatable::Item(i) => Annotatable::Item(
Flamer { cx: cx, ident: i.ident }.fold_item(i).expect_one("expected exactly one item")),
Flamer { cx: cx, ident: i.ident, opt_ident: opt_ident }.fold_item(i).expect_one("expected exactly one item")),
Annotatable::TraitItem(i) => Annotatable::TraitItem(
i.map(|i| Flamer { cx, ident: i.ident }.fold_trait_item(i).expect_one("expected exactly one item"))),
i.map(|i| Flamer { cx, ident: i.ident, opt_ident: opt_ident }.fold_trait_item(i).expect_one("expected exactly one item"))),
Annotatable::ImplItem(i) => Annotatable::ImplItem(
i.map(|i| Flamer { cx, ident: i.ident }.fold_impl_item(i).expect_one("expected exactly one item"))),
i.map(|i| Flamer { cx, ident: i.ident, opt_ident: opt_ident }.fold_impl_item(i).expect_one("expected exactly one item"))),
a => a
}
}

struct Flamer<'a, 'cx: 'a> {
ident: Ident,
cx: &'a mut ExtCtxt<'cx>,
opt_ident: Option<Symbol>,
}

impl<'a, 'cx> Folder for Flamer<'a, 'cx> {
Expand Down Expand Up @@ -70,10 +88,18 @@ impl<'a, 'cx> Folder for Flamer<'a, 'cx> {
fn fold_block(&mut self, block: P<Block>) -> P<Block> {
block.map(|block| {
let name = self.cx.expr_str(DUMMY_SP, self.ident.name);
quote_block!(self.cx, {
let _name = ::flame::start_guard($name);
$block
}).into_inner()
if let Some(opt_name) = self.opt_ident {
let prefix = self.cx.expr_str(DUMMY_SP, opt_name);
quote_block!(self.cx, {
let _name = ::flame::start_guard(format!("{}::{}", $prefix, $name));
$block
}).into_inner()
} else {
quote_block!(self.cx, {
let _name = ::flame::start_guard($name);
$block
}).into_inner()
}
})
}

Expand Down
35 changes: 35 additions & 0 deletions tests/opt_name.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// test double attrs

#![feature(plugin, custom_attribute)]
#![plugin(flamer)]
#![flame("e")]

extern crate flame;

#[flame]
fn a() {
// nothing to do here
}

fn b() {
a()
}

#[noflame]
fn c() {
b()
}

#[test]
fn main() {
c();
let spans = flame::spans();
assert_eq!(1, spans.len());
let roots = &spans[0];
println!("{:?}",roots);
// if more than 2 roots, a() was flamed twice or c was flamed
// main is missing because main isn't closed here
assert_eq!("e::b", roots.name);
assert_eq!(1, roots.children.len());
assert_eq!("a", roots.children[0].name);
}

0 comments on commit b765eae

Please sign in to comment.