2016-05-11 6 views
5

Sto provando a creare un'estensione di sintassi che espanda un attributo nelle chiamate. Prima:Come modificare tutti gli elementi di una cassa in un plug-in del compilatore?

#[flame] 
fn flamed() { 
    .. 
} 

Dopo:

fn flamed() { 
    flame::start_guard("flamed"); 
    .. 
} 

Questo già works. Tuttavia, mi piacerebbe anche che funzionasse se ho l'attributo #[flame] a livello di cassa (come #![flame]). È possibile e se sì, come?

+0

Che cosa esattamente cosa si aspetta l'attributo cassa per fare? Inserisci la chiamata in ogni funzione della cassa? –

+2

Hai provato a catturare 'ItemKind :: Mod' in https://github.com/llogiq/flamer/blob/f4828cc91768109fa66f8cbbe57a285c0477c436/src/lib.rs#L29 e iterando sul suo contenuto (in modo ricorsivo)? – huon

+0

@Lukas Kalbertodt: esattamente. – llogiq

risposta

2

@ commento di Huon

Hai provato cattura ItemKind :: Mod in github.com/llogiq/flamer/blob/... e l'iterazione di suo contenuto (ricorsivamente)?

era azzeccato - ho appena aggiunto un commit che gestisce gli elementi mod e tratto camminandoli. Probabilmente aggiungerò anche il codice per gestire le funzioni per gestire gli elementi interni e fns.

Il codice simile a questo:

fn flame_item(i: &Item) -> Item { 
    let base = i.clone(); 
    Item { 
     node: match i.node { 
      ItemKind::Mod(ref m) => 
       ItemKind::Mod(flame_mod(m)), 
      ItemKind::Trait(unsafety, ref generic, ref bounds, ref tis) => 
       ItemKind::Trait(unsafety, 
           generic.clone(), 
           bounds.clone(), 
           flame_items(tis)), 
     .. // other item types as usual: items, traitimpls, implitems 

      _ => return base 
     }, 
     ..base 
    } 
} 

fn flame_mod(m: &Mod) -> Mod { 
    Mod { 
     inner: m.inner, 
     items: m.items.iter().map(|i| P(flame_item(i))).collect() 
    } 
} 

fn flame_items(items: &[TraitItem]) -> Vec<TraitItem> { 
    items.iter().map(flame_trait_item).collect() 
} 
Problemi correlati