from datetime import datetime
from textwrap import indent
from ast import *
from util import *
@linewise
def do_collect_macros_body(se, target1, target2):
if not isinstance(se, (Struct, Enum)):
return
yield 'match (%s, %s) {' % (target1, target2)
for v, path in variants_paths(se):
yield ' (&%s,' % struct_pattern(v, path, '1')
yield ' &%s) => {' % struct_pattern(v, path, '2')
for f in v.fields:
if 'mac_table_seq' in f.attrs:
yield ' collect_macros_seq(%s1, %s2, cx);' % (f.name, f.name)
else:
yield ' CollectMacros::collect_macros(%s1, %s2, cx);' % (f.name, f.name)
yield ' },'
yield ' (_, _) => {},'
yield '}'
if 'mac_table_record' in se.attrs:
yield 'if let Some(invoc) = MaybeInvoc::as_invoc(%s) {' % target1
yield ' match MaybeInvoc::as_invoc(%s) {' % target2
yield ' Some(InvocKind::Attrs(..)) => {}'
yield ' Some(_) => panic!("impossible: found macro invocation in expanded AST"),'
yield ' None => cx.record_one_macro(%s.id, invoc, MacNodeRef::%s(new)),' % \
(target1, se.name)
yield ' }'
yield '}'
@linewise
def do_collect_macros_impl(d):
yield '#[allow(unused)]'
yield 'impl CollectMacros for %s {' % d.name
yield " fn collect_macros<'a>(old: &'a Self, new: &'a Self, cx: &mut Ctxt<'a>) {"
yield indent(do_collect_macros_body(d, 'old', 'new'), ' ')
yield ' }'
yield '}'
@linewise
def generate(decls):
yield '// AUTOMATICALLY GENERATED - DO NOT EDIT'
yield '// Produced %s by process_ast.py' % (datetime.now(),)
yield ''
for d in decls:
if 'mac_table_custom' not in d.attrs:
yield do_collect_macros_impl(d)