Как изменить все элементы ящика в плагине компилятора?

Я пытаюсь создать расширение синтаксиса, которое расширяет атрибут в вызовах. До:

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

После:

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

Это уже работает. Тем не менее, я также хотел бы, чтобы это работало, если у меня есть #[flame] атрибут на уровне ящика (как #![flame]). Возможно ли это и если да, то как?

1 ответ

Решение

@huon's comment

Вы пытались поймать ItemKind::Mod в github.com/llogiq/flamer/blob/… и перебирать его содержимое (рекурсивно)?

был на месте - я просто добавил коммит, который обрабатывает мод и черты предметов, обходя их. Я также, вероятно, добавлю код для функций ходьбы для обработки внутренних элементов и фн.

Код выглядит так:

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()
}
Другие вопросы по тегам