MCPcopy Create free account
hub / github.com/PLSysSec/wave / rewrite_mod

Function rewrite_mod

tools/fuzz-gen/src/extern_spec_rewriter.rs:15–69  ·  view source on GitHub ↗

Process external specifications in Rust modules marked with the #[extern_spec] attribute. Nested modules are processed recursively. Specifications are collected from functions and function stubs. Modules are rewritten so that their name does not clash with the module they are specifying.

(item_mod: &mut syn::ItemMod, path: &mut syn::Path)

Source from the content-addressed store, hash-verified

13/// Modules are rewritten so that their name does not clash with the module
14/// they are specifying.
15pub fn rewrite_mod(item_mod: &mut syn::ItemMod, path: &mut syn::Path) -> syn::Result<()> {
16 if item_mod.content.is_none() {
17 return Ok(())
18 }
19
20 path.segments.push(syn::PathSegment { ident: item_mod.ident.clone(), arguments: syn::PathArguments::None });
21 let name_generator = NameGenerator::new();
22 item_mod.ident = syn::Ident::new(&name_generator.generate_mod_name(&item_mod.ident),
23 item_mod.span());
24
25 for item in item_mod.content.as_mut().unwrap().1.iter_mut() {
26 match item {
27 syn::Item::Fn(item_fn) => {
28 rewrite_fn(item_fn, path);
29 },
30 syn::Item::Mod(inner_mod) => {
31 rewrite_mod(inner_mod, path)?;
32 },
33 syn::Item::Verbatim(tokens) => {
34 // Transforms function stubs (functions with a `;` after the
35 // signature instead of the body) into functions, then
36 // processes them.
37 let mut new_tokens = TokenStream::new();
38 for mut token in tokens.clone().into_iter() {
39 if let TokenTree::Punct(punct) = &mut token {
40 if punct.as_char() == ';' {
41 new_tokens.extend(Group::new(proc_macro2::Delimiter::Brace, TokenStream::new()).to_token_stream());
42 continue;
43 }
44 }
45 new_tokens.extend(token.to_token_stream());
46 }
47 let res: Result<syn::Item, _> = syn::parse2(new_tokens);
48 if res.is_err() {
49 return Err(syn::Error::new(
50 item.span(),
51 "invalid function signature",
52 ))
53 }
54
55 let mut item = res.unwrap();
56 if let syn::Item::Fn(item_fn) = &mut item {
57 rewrite_fn(item_fn, path);
58 }
59 *tokens = quote!(#item)
60 }
61 syn::Item::Use(_) => {}
62 _ => return Err(syn::Error::new(
63 item.span(),
64 "unexpected item",
65 ))
66 }
67 }
68 Ok(())
69}
70
71/// Rewrite a specification function to a call to the specified function.
72/// The result of this rewriting is then parsed in `ExternSpecResolver`.

Callers

nothing calls this directly

Calls 4

rewrite_fnFunction · 0.85
generate_mod_nameMethod · 0.80
into_iterMethod · 0.80
pushMethod · 0.45

Tested by

no test coverage detected