2016-05-11 9 views
5

Ich versuche eine Syntaxerweiterung zu erstellen, die ein Attribut in Aufrufe erweitert. Vorher:Wie ändert man alle Elemente einer Kiste in einem Compiler-Plugin?

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

Nach:

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

Diese bereits works. Allerdings würde es auch funktionieren, wenn ich das Attribut #[flame] auf der Kiste-Ebene (wie #![flame]) hätte. Ist das möglich und wenn ja, wie?

+0

Was genau Sie die Kiste Attribut erwarten, zu tun? Fügen Sie den Anruf in jede Funktion der Kiste ein? –

+2

Haben Sie versucht, 'ItemKind :: Mod' in https://github.com/llogiq/flamer/blob/f4828cc91768109fa66f8cbbe57a285c0477c436/src/lib.rs#L29 abzufangen und über seinen Inhalt (rekursiv) zu iterieren? – huon

+0

@Lukas Kalbertodt: genau. – llogiq

Antwort

2

@ Kommentar des huon

Haben Sie versucht, fangen ItemKind :: Mod in github.com/llogiq/flamer/blob/... und Iteration über seinen Inhalt (rekursiv)?

war genau richtig - ich habe gerade ein Commit hinzugefügt, das Mod- und Trait-Elemente behandelt, indem Sie sie gehen. Ich werde auch wahrscheinlich Code hinzufügen, um Funktionen zu gehen, um innere Gegenstände und fns zu behandeln.

Der Code sieht wie folgt aus:

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() 
}