kproc_parser/rust/
kfunc.rs1use crate::kparser::{KParserError, KParserTracer};
4use crate::kproc_macros::KTokenStream;
5use crate::proc_macro::TokenTree;
6use crate::rust::core::{check_and_parse_bounds, check_and_parse_return_type};
7use crate::rust::kattr::check_and_parse_cond_attribute;
8use crate::rust::ty::parse_ty;
9use crate::{build_error, check, parse_visibility, trace};
10
11use super::ast_nodes::{MethodDeclToken, TyToken};
12use super::core::{check_and_parse_fn_qualifier, check_is_fun_with_visibility};
13
14pub fn parse_fn(
32 toks: &mut KTokenStream,
33 tracer: &dyn KParserTracer,
34) -> Result<MethodDeclToken, KParserError> {
35 trace!(tracer, "Start parsing fn");
36
37 let attrs = check_and_parse_cond_attribute(toks, tracer);
38 let visibility = check_is_fun_with_visibility(toks).then(|| parse_visibility!(toks).unwrap());
39 let qualifier = check_and_parse_fn_qualifier(toks);
40 let fn_tok = toks.advance();
41 check!("fn", fn_tok)?;
42
43 let ident = toks.advance();
44 trace!(
45 tracer,
46 "function name {ident} and next tok: {:?}",
47 toks.peek()
48 );
49 let generics = check_and_parse_bounds(toks, tracer)?;
50 trace!(tracer, "starting parsing fn params");
51 let raw_params = toks.unwrap_group_as_stream();
52 let mut params_stream: KTokenStream = raw_params.clone().into();
53 let params = parse_fn_params(&mut params_stream, tracer)?;
54 trace!(tracer, "fn parametes {:?}", params);
55 toks.next();
56
57 let rt_ty = check_and_parse_return_type(toks, tracer)?;
59 trace!(
60 tracer,
61 "return type {:?} next should be the body function: {:?}",
62 rt_ty,
63 toks.peek()
64 );
65
66 let body = if toks.is_group() {
69 let body = toks.unwrap_group_as_stream();
70 toks.next();
71 Some(body)
72 } else {
73 let toks = toks.advance();
74 check!(";", toks)?;
75 None
76 };
77
78 let method = MethodDeclToken {
79 attrs,
80 visibility,
81 qualifier,
82 ident,
83 generics,
84 raw_params,
85 params,
86 raw_body: body,
87 return_ty: rt_ty,
88 };
89 Ok(method)
90}
91
92pub fn parse_fn_params(
93 raw_params: &mut KTokenStream,
94 tracer: &dyn KParserTracer,
95) -> Result<Vec<(TokenTree, TyToken)>, KParserError> {
96 trace!(
97 tracer,
98 "parsing fn params from the following source: {:?}",
99 raw_params
100 );
101 let mut params = Vec::new();
102 while !raw_params.is_end() {
106 if raw_params.match_tok("&") || raw_params.match_tok("self") | raw_params.match_tok("mut") {
109 while !raw_params.is_end() && !raw_params.match_tok(",") {
110 trace!(tracer, "`self` found `{:?}`", raw_params.advance());
111 }
112 if raw_params.is_end() {
113 trace!(tracer, "end of the params stream.");
114 break;
115 }
116 if raw_params.match_tok(",") {
117 check!(",", raw_params.advance())?;
118 }
119 }
120 let ident = raw_params.advance();
121 trace!(tracer, "parameters name `{ident}`");
122 check!(":", raw_params.advance())?;
123 let ty = parse_ty(raw_params, tracer)?.ok_or(build_error!(
124 ident.clone(),
125 "fails to parse the rust type, this is a bug, please open a issue"
126 ))?;
127 trace!(tracer, "param found `{ident}: {ty}`");
128 params.push((ident, ty));
129 }
132 Ok(params)
133}