Skip to content

Commit

Permalink
feat(macro): add the hook proc macro
Browse files Browse the repository at this point in the history
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
  • Loading branch information
vincenzopalazzo committed Feb 20, 2024
1 parent d29a851 commit a242690
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
67 changes: 67 additions & 0 deletions plugin_macros/src/hook.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
//! Hook proc macro implementation
//!
//! Author: Vincenzo Palazzo <vincenzopalazzo@member.fsf.org>
use std::process::abort;

use convert_case::{Case, Casing};

use kproc_parser::kparser::{DummyTracer, KParserTracer, Result};
use kproc_parser::kproc_macros::KTokenStream;
use kproc_parser::proc_macro::TokenStream;
use kproc_parser::rust::ast_nodes::MethodDeclToken;
use kproc_parser::rust::kparser::RustParser;

use crate::attr_parser::AttributeParser;

struct RPCHook {
original_name: String,

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / clippy

fields `original_name`, `struct_name`, and `fn_name` are never read

warning: fields `original_name`, `struct_name`, and `fn_name` are never read --> plugin_macros/src/hook.rs:17:5 | 16 | struct RPCHook { | ------- fields in this struct 17 | original_name: String, | ^^^^^^^^^^^^^ 18 | struct_name: String, | ^^^^^^^^^^^ 19 | fn_name: String, | ^^^^^^^ | = note: `#[warn(dead_code)]` on by default

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

fields `original_name`, `struct_name`, and `fn_name` are never read

Check warning on line 17 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

fields `original_name`, `struct_name`, and `fn_name` are never read
struct_name: String,
fn_name: String,
}

struct HookMethodMacro {
on: String,
}

pub(crate) fn parse(attr: TokenStream, item: TokenStream) -> TokenStream {
let tracer = DummyTracer;
let parser = RustParser::with_tracer(&tracer);
let fn_ast = parser.parse_fn(&item);

let mut attr = KTokenStream::new(&attr);
let parser = AttributeParser::parse(&mut attr, &tracer);
if let Err(err) = parser {
err.emit();
abort();
}
let parser = parser.unwrap();
let hook = HookMethodMacro {
on: parser.get("on").unwrap().to_owned(),
};
let meta = generate_hook_call(hook, fn_ast)
.map_err(|err| {
err.emit();
abort();
})
.unwrap();
generate_hook_method(meta, &tracer)
}

fn generate_hook_call(hook: HookMethodMacro, fun_dec: MethodDeclToken) -> Result<RPCHook> {
let struct_name = format!("On{}", hook.on.as_str().to_case(Case::Pascal));
let Some((_, ty)) = fun_dec.params.first() else {
panic!("TODO: we need to return an error, but for now the list of params is empty");
};
let Some(ty) = ty.generics.clone().and_then(|gen| gen.first().cloned()) else {

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `ty`

warning: unused variable: `ty` --> plugin_macros/src/hook.rs:55:14 | 55 | let Some(ty) = ty.generics.clone().and_then(|gen| gen.first().cloned()) else { | ^^ help: if this is intentional, prefix it with an underscore: `_ty` | = note: `#[warn(unused_variables)]` on by default

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `ty`

Check warning on line 55 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `ty`
panic!("TODO: we need to return an error , but or now the inner generics is None")
};
Ok(RPCHook {
original_name: hook.on,
struct_name,
fn_name: fun_dec.ident.to_string(),
})
}

fn generate_hook_method<T: KParserTracer>(method_call: RPCHook, tracer: &T) -> TokenStream {

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `tracer`

warning: unused variable: `tracer` --> plugin_macros/src/hook.rs:65:65 | 65 | fn generate_hook_method<T: KParserTracer>(method_call: RPCHook, tracer: &T) -> TokenStream { | ^^^^^^ help: if this is intentional, prefix it with an underscore: `_tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / clippy

unused variable: `method_call`

warning: unused variable: `method_call` --> plugin_macros/src/hook.rs:65:43 | 65 | fn generate_hook_method<T: KParserTracer>(method_call: RPCHook, tracer: &T) -> TokenStream { | ^^^^^^^^^^^ help: if this is intentional, prefix it with an underscore: `_method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (stable)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (nightly)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `tracer`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `method_call`

Check warning on line 65 in plugin_macros/src/hook.rs

View workflow job for this annotation

GitHub Actions / Build (beta)

unused variable: `tracer`
"".parse().unwrap()
}
10 changes: 10 additions & 0 deletions plugin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use kproc_parser::kparser::KParserTracer;
use kproc_parser::proc_macro::TokenStream;

mod hook;
mod notification;
mod plugin;
mod rpc_method;
Expand Down Expand Up @@ -106,3 +107,12 @@ pub fn rpc_method(attr: TokenStream, item: TokenStream) -> TokenStream {
pub fn notification(attr: TokenStream, item: TokenStream) -> TokenStream {
notification::parse(attr, item)
}

/// procedural macros that can be used wit the following code
/// ```no_run
///
/// ```
#[proc_macro_attribute]
pub fn hook(attr: TokenStream, item: TokenStream) -> TokenStream {
hook::parse(attr, item)
}

0 comments on commit a242690

Please sign in to comment.