1use crate::proc_macro::TokenStream;
8
9use crate::{
10 kparser::{DummyTracer, KParserError},
11 kproc_macros::KTokenStream,
12 proc_macro::TokenTree,
13};
14use std::collections::HashMap;
15use std::fmt::Display;
16
17use super::{
18 fmt::{fmt_generics, fmt_ty},
19 kimpl::parse_impl,
20 kstruct::parse_struct,
21 ktrait::parse_trait,
22};
23
24pub trait TopLevelAST {
25 fn span(&self) -> TokenTree;
26
27 fn is_trait(&self) -> bool {
28 false
29 }
30
31 fn is_struct(&self) -> bool {
32 false
33 }
34
35 fn is_impl(&self) -> bool {
36 false
37 }
38
39 fn is_fn(&self) -> bool {
40 false
41 }
42}
43
44pub enum TopLevelNode {
45 Struct(StructToken),
46 Trait(TraitToken),
47 Impl(ImplToken),
48 Fn(MethodDeclToken),
49}
50
51impl Display for TopLevelNode {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 match self {
54 Self::Impl(node) => write!(f, "{node}"),
55 Self::Struct(node) => write!(f, "{node}"),
56 Self::Trait(node) => write!(f, "{node}"),
57 Self::Fn(node) => write!(f, "{node}"),
58 }
59 }
60}
61
62impl From<StructToken> for TopLevelNode {
63 fn from(value: StructToken) -> Self {
64 TopLevelNode::Struct(value)
65 }
66}
67
68impl From<ImplToken> for TopLevelNode {
69 fn from(value: ImplToken) -> Self {
70 TopLevelNode::Impl(value)
71 }
72}
73
74impl From<TraitToken> for TopLevelNode {
75 fn from(value: TraitToken) -> Self {
76 TopLevelNode::Trait(value)
77 }
78}
79
80impl From<MethodDeclToken> for TopLevelNode {
81 fn from(value: MethodDeclToken) -> Self {
82 TopLevelNode::Fn(value)
83 }
84}
85
86#[derive(Debug)]
95pub struct StructToken {
96 pub attrs: HashMap<String, AttrToken>,
97 pub visibility: Option<TokenTree>,
98 pub name: TokenTree,
99 pub fields: Vec<FieldToken>,
100 pub generics: Option<GenericParams>,
101}
102
103impl TopLevelAST for StructToken {
104 fn span(&self) -> TokenTree {
105 self.name.clone()
106 }
107
108 fn is_struct(&self) -> bool {
109 true
110 }
111}
112
113impl Default for StructToken {
114 fn default() -> Self {
115 panic!()
116 }
117}
118
119impl TryFrom<&TokenStream> for StructToken {
120 type Error = KParserError;
121
122 fn try_from(value: &TokenStream) -> Result<Self, Self::Error> {
123 let mut stream = KTokenStream::new(value);
124 parse_struct(&mut stream, &DummyTracer {})
125 }
126}
127
128impl Display for StructToken {
129 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130 write!(f, "")
131 }
132}
133
134#[derive(Debug, Clone)]
138pub struct GenericParams {
139 pub params: Vec<GenericParam>,
140}
141
142#[derive(Debug, Clone)]
143pub enum GenericParam {
144 LifetimeParam(LifetimeParam),
145 TypeParam(TyToken),
146 Bounds(Bound), }
148
149impl GenericParam {
150 pub fn add_bound(&mut self, bound: Bound) {
151 match self {
152 Self::TypeParam(param) => param.bounds.push(bound),
153 Self::LifetimeParam(param) => param.bounds.push(bound),
154 Self::Bounds(params) => params.add_bound(bound),
155 }
156 }
157}
158
159impl Display for GenericParam {
160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161 match self {
162 Self::LifetimeParam(param) => write!(f, "{param}"),
163 Self::TypeParam(param) => write!(f, "{param}"),
164 Self::Bounds(bounds) => write!(f, "{bounds}"),
165 }
166 }
167}
168
169#[derive(Clone, Debug)]
170pub enum Bound {
171 Lifetime(LifetimeParam),
172 Trait(TypeParam),
173}
174
175impl Bound {
176 pub fn add_bound(&mut self, bound: Bound) {
177 match self {
178 Self::Trait(param) => param.bounds.push(bound),
179 Self::Lifetime(param) => param.bounds.push(bound),
180 }
181 }
182}
183
184impl std::fmt::Display for Bound {
185 fn fmt(&self, _f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
186 unimplemented!()
187 }
188}
189
190#[derive(Debug, Clone)]
192pub struct LifetimeParam {
193 pub lifetime_or_label: TokenTree,
194 pub bounds: Vec<Bound>,
195}
196
197impl std::fmt::Display for LifetimeParam {
198 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
199 let mut code = format!("'{}", self.lifetime_or_label);
200 if !self.bounds.is_empty() {
201 code += &format!(
202 " {}",
203 self.bounds
204 .iter()
205 .map(|bound| format!("{bound} +"))
206 .collect::<String>()
207 );
208 code = code.strip_suffix('+').unwrap_or(&code).to_owned();
209 }
210 write!(f, "{code}")
211 }
212}
213
214#[derive(Debug, Clone)]
215pub struct TypeParam {
216 pub identifier: TokenTree,
217 pub bounds: Vec<Bound>,
218}
219
220impl Display for GenericParams {
221 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
222 let gen = fmt_generics(self);
223 write!(f, "{gen}")
224 }
225}
226
227#[derive(Debug)]
231pub struct FieldToken {
232 pub attrs: HashMap<String, AttrToken>,
233 pub visibility: Option<TokenTree>,
234 pub identifier: TokenTree,
235 pub ty: TyToken,
236}
237
238impl Display for FieldToken {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 let mut vis = String::new();
241 if let Some(viss) = &self.visibility {
242 vis = viss.to_string()
243 }
244 write!(f, "{} {}: {}", vis, self.identifier, self.ty)
245 }
246}
247
248#[derive(Debug, Clone)]
253pub enum TyKind {
254 ImplTrait,
255 Parenthesized,
256 TraitObject,
257 TypePath,
258 TupleType,
259 NeverType,
260 RawPointerType,
261 ReferenceType,
262 ArrayType,
263 SliceType,
264 InferredType,
265 QualifiedPathInType,
266 BareFunctionType,
267 MacroInvocation,
268}
269
270#[derive(Debug, Clone)]
278pub struct TyToken {
279 pub kind: TyKind,
280 pub ref_tok: Option<TokenTree>,
281 pub mut_tok: Option<TokenTree>,
282 pub identifier: TokenTree,
283 pub dyn_tok: Option<TokenTree>,
284 pub lifetime: Option<LifetimeParam>,
285 pub generics: Option<Vec<TyToken>>,
286 pub bounds: Vec<Bound>,
287}
288
289impl Display for TyToken {
290 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
291 let code = fmt_ty(self);
292 write!(f, "{code}")
293 }
294}
295
296#[derive(Debug, Clone)]
335pub struct CondAttributeToken {
336 pub name: TokenTree,
338 pub value: AttributeToken,
340}
341
342#[derive(Debug, Clone)]
353pub struct AttributeToken {
354 pub name: TokenTree,
356 pub value: Option<TokenTree>,
358}
359
360#[derive(Debug, Clone)]
361pub enum AttrToken {
362 Attr(AttributeToken),
363 CondAttr(CondAttributeToken),
364}
365
366impl AttrToken {
367 pub fn name(&self) -> String {
371 match self {
372 Self::Attr(tok) => tok.name.to_string(),
373 Self::CondAttr(tok) => tok.name.to_string(),
374 }
375 }
376
377 pub fn attribute(&self) -> AttributeToken {
381 match self {
382 Self::Attr(attr) => attr.to_owned(),
383 Self::CondAttr(attr) => attr.value.clone(),
384 }
385 }
386
387 pub fn is_conditional(&self) -> bool {
389 match self {
390 Self::Attr(_) => false,
391 Self::CondAttr(_) => true,
392 }
393 }
394}
395
396#[derive(Debug)]
401pub struct ImplToken {
402 pub attributes: HashMap<String, AttrToken>,
403 pub generics: Option<GenericParams>,
404 pub name: TokenTree,
406 pub for_ty: Option<TyToken>,
410 pub raw_block: TokenStream,
417 pub functions: Vec<MethodDeclToken>,
418}
419
420impl TopLevelAST for ImplToken {
421 fn span(&self) -> TokenTree {
422 self.name.clone()
423 }
424
425 fn is_impl(&self) -> bool {
426 true
427 }
428}
429
430impl TryFrom<&TokenStream> for ImplToken {
431 type Error = KParserError;
432
433 fn try_from(value: &TokenStream) -> Result<Self, Self::Error> {
434 let mut stream = KTokenStream::new(value);
435 parse_impl(&mut stream, &DummyTracer {})
436 }
437}
438
439impl Default for ImplToken {
440 fn default() -> Self {
441 panic!()
442 }
443}
444
445impl Display for ImplToken {
446 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
447 write!(f, "impl {} {{ {} }}", self.name, self.raw_block)
449 }
450}
451
452#[derive(Debug)]
457pub struct TraitToken {
458 pub attrs: HashMap<String, AttrToken>,
459 pub visibility: Option<TokenTree>,
460 pub ident: TokenTree,
461 pub generics: Option<GenericParams>,
462 pub inn_attrs: Option<AttrToken>,
463 pub associated_items: Vec<AssociatedItem>,
464 pub raw_block: TokenStream,
465 pub functions: Vec<MethodDeclToken>,
466}
467
468impl TopLevelAST for TraitToken {
469 fn span(&self) -> TokenTree {
470 self.ident.clone()
471 }
472
473 fn is_trait(&self) -> bool {
474 true
475 }
476}
477
478impl TryFrom<&TokenStream> for TraitToken {
479 type Error = KParserError;
480
481 fn try_from(value: &TokenStream) -> Result<Self, Self::Error> {
482 let mut stream = KTokenStream::new(value);
483 parse_trait(&mut stream, &DummyTracer {})
484 }
485}
486
487impl Default for TraitToken {
488 fn default() -> Self {
489 panic!()
490 }
491}
492
493impl Display for TraitToken {
494 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
495 write!(f, "")
496 }
497}
498
499#[derive(Debug)]
504pub enum AssociatedItem {
505 AssociatedFn(FnDeclTok),
506 AssociatedMethod(MethodDeclToken),
507 }
509
510#[derive(Debug)]
515pub struct MethodDeclToken {
516 pub attrs: HashMap<String, AttrToken>,
517 pub visibility: Option<TokenTree>,
518 pub qualifier: Option<TokenTree>,
522 pub ident: TokenTree,
523 pub generics: Option<GenericParams>,
524 pub raw_params: TokenStream,
525 pub params: Vec<(TokenTree, TyToken)>,
531 pub return_ty: Option<TyToken>,
532 pub raw_body: Option<TokenStream>,
533}
534
535impl Default for MethodDeclToken {
536 fn default() -> Self {
537 unimplemented!()
538 }
539}
540
541impl Display for MethodDeclToken {
542 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
543 write!(f, "")
544 }
545}
546
547impl TopLevelAST for MethodDeclToken {
548 fn span(&self) -> TokenTree {
549 self.ident.clone()
550 }
551
552 fn is_fn(&self) -> bool {
553 true
554 }
555}
556
557pub type FnDeclTok = MethodDeclToken;