kodept_ast/graph/
any_node.rs1use std::fmt::Debug;
2
3use derive_more::{Display, From, TryInto};
4#[cfg(feature = "serde")]
5use serde::{Deserialize, Serialize};
6use strum::{EnumDiscriminants, IntoStaticStr, VariantArray, VariantNames};
7
8use kodept_core::{ConvertibleToMut, ConvertibleToRef};
9
10use crate::*;
11use crate::graph::Identifiable;
12use crate::graph::node_id::GenericNodeId;
13
14#[derive(Debug, PartialEq, From, TryInto, EnumDiscriminants, IntoStaticStr, VariantNames)]
15#[strum_discriminants(derive(VariantArray, Display))]
16#[strum_discriminants(cfg_attr(feature = "serde", derive(Serialize, Deserialize)))]
17#[strum_discriminants(name(AnyNodeD))]
18#[try_into(owned, ref, ref_mut)]
19#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
20pub enum AnyNode {
21 FileDecl(FileDecl),
22 ModDecl(ModDecl),
23 StructDecl(StructDecl),
24 EnumDecl(EnumDecl),
25 TyParam(TyParam),
26 NonTyParam(NonTyParam),
27 TyName(TyName),
28 VarDecl(VarDecl),
29 InitVar(InitVar),
30 BodyFnDecl(BodyFnDecl),
31 Exprs(Exprs),
32 Appl(Appl),
33 Lambda(Lambda),
34 Ref(Ref),
35 Acc(Acc),
36 NumLit(NumLit),
37 CharLit(CharLit),
38 StrLit(StrLit),
39 TupleLit(TupleLit),
40 IfExpr(IfExpr),
41 ElifExpr(ElifExpr),
42 ElseExpr(ElseExpr),
43 BinExpr(BinExpr),
44 UnExpr(UnExpr),
45 AbstFnDecl(AbstFnDecl),
46 ProdTy(ProdTy),
47}
48
49macro_rules! folding {
50 ($this:expr; $bind:ident => $usage:expr) => {
51 match $this {
52 AnyNode::FileDecl($bind) => $usage,
53 AnyNode::ModDecl($bind) => $usage,
54 AnyNode::StructDecl($bind) => $usage,
55 AnyNode::EnumDecl($bind) => $usage,
56 AnyNode::TyParam($bind) => $usage,
57 AnyNode::NonTyParam($bind) => $usage,
58 AnyNode::TyName($bind) => $usage,
59 AnyNode::VarDecl($bind) => $usage,
60 AnyNode::InitVar($bind) => $usage,
61 AnyNode::BodyFnDecl($bind) => $usage,
62 AnyNode::Exprs($bind) => $usage,
63 AnyNode::Appl($bind) => $usage,
64 AnyNode::Lambda($bind) => $usage,
65 AnyNode::Ref($bind) => $usage,
66 AnyNode::Acc($bind) => $usage,
67 AnyNode::NumLit($bind) => $usage,
68 AnyNode::CharLit($bind) => $usage,
69 AnyNode::StrLit($bind) => $usage,
70 AnyNode::TupleLit($bind) => $usage,
71 AnyNode::IfExpr($bind) => $usage,
72 AnyNode::ElifExpr($bind) => $usage,
73 AnyNode::ElseExpr($bind) => $usage,
74 AnyNode::BinExpr($bind) => $usage,
75 AnyNode::UnExpr($bind) => $usage,
76 AnyNode::AbstFnDecl($bind) => $usage,
77 AnyNode::ProdTy($bind) => $usage,
78 }
79 };
80}
81
82#[deprecated]
83pub type GenericASTNode = AnyNode;
84
85pub trait SubEnum {
86 const VARIANTS: &'static [AnyNodeD];
87
88 #[inline]
89 fn contains(node: &AnyNode) -> bool {
90 Self::VARIANTS.contains(&node.describe())
91 }
92}
93
94impl SubEnum for AnyNode {
95 const VARIANTS: &'static [AnyNodeD] = AnyNodeD::VARIANTS;
96}
97
98impl Identifiable for AnyNode {
99 #[inline]
100 fn get_id(&self) -> GenericNodeId {
101 folding!(self; x => x.get_id().widen())
102 }
103
104 #[inline]
105 fn set_id(&self, value: GenericNodeId) {
106 folding!(self; x => x.set_id(value.narrow()));
107 }
108}
109
110impl AnyNode {
111 #[inline]
112 pub fn describe(&self) -> AnyNodeD {
113 self.into()
114 }
115
116 #[inline]
117 pub fn name(&self) -> &'static str {
118 self.into()
119 }
120
121 pub fn try_cast<T>(&self) -> Option<&T>
122 where
123 AnyNode: ConvertibleToRef<T>,
124 {
125 self.try_as_ref()
126 }
127
128 pub fn tru_cast_mut<T>(&mut self) -> Option<&mut T> where AnyNode: ConvertibleToMut<T> {
129 self.try_as_mut()
130 }
131}