rust_code_analysis/
ast.rs1use serde::ser::{SerializeStruct, Serializer};
2use serde::{Deserialize, Serialize};
3
4use crate::*;
5
6pub type Span = Option<(usize, usize, usize, usize)>;
14
15#[derive(Debug, Deserialize, Serialize)]
17pub struct AstPayload {
18 pub id: String,
20 pub file_name: String,
22 pub code: String,
24 pub comment: bool,
26 pub span: bool,
29}
30
31#[derive(Debug, Serialize)]
33pub struct AstResponse {
34 pub id: String,
36 pub root: Option<AstNode>,
40}
41
42#[derive(Debug)]
44pub struct AstNode {
45 pub r#type: &'static str,
47 pub value: String,
49 pub span: Span,
51 pub children: Vec<AstNode>,
53}
54
55impl Serialize for AstNode {
56 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
57 where
58 S: Serializer,
59 {
60 let mut st = serializer.serialize_struct("Node", 4)?;
61 st.serialize_field("Type", &self.r#type)?;
62 st.serialize_field("TextValue", &self.value)?;
63 st.serialize_field("Span", &self.span)?;
64 st.serialize_field("Children", &self.children)?;
65 st.end()
66 }
67}
68
69impl AstNode {
70 pub fn new(r#type: &'static str, value: String, span: Span, children: Vec<AstNode>) -> Self {
71 Self {
72 r#type,
73 value,
74 span,
75 children,
76 }
77 }
78}
79
80fn build<T: ParserTrait>(parser: &T, span: bool, comment: bool) -> Option<AstNode> {
81 let code = parser.get_code();
82 let root = parser.get_root();
83 let mut cursor = root.object().walk();
84 let mut node_stack = Vec::new();
85 let mut child_stack = Vec::new();
86
87 node_stack.push(root);
88 child_stack.push(Vec::new());
89
90 loop {
94 let ts_node = node_stack.last().unwrap();
95 cursor.reset(ts_node.object());
96 if cursor.goto_first_child() {
97 let node = cursor.node();
98 child_stack.push(Vec::with_capacity(node.child_count()));
99 node_stack.push(Node::new(node));
100 } else {
101 loop {
102 let ts_node = node_stack.pop().unwrap();
103 if let Some(node) = T::Checker::get_ast_node(
104 &ts_node,
105 code,
106 child_stack.pop().unwrap(),
107 span,
108 comment,
109 ) {
110 if !child_stack.is_empty() {
111 child_stack.last_mut().unwrap().push(node);
112 } else {
113 return Some(node);
114 }
115 }
116 if let Some(next_node) = ts_node.object().next_sibling() {
117 child_stack.push(Vec::with_capacity(next_node.child_count()));
118 node_stack.push(Node::new(next_node));
119 break;
120 }
121 }
122 }
123 }
124}
125
126pub struct AstCallback {
127 _guard: (),
128}
129
130pub struct AstCfg {
132 pub id: String,
134 pub comment: bool,
136 pub span: bool,
139}
140
141impl Callback for AstCallback {
142 type Res = AstResponse;
143 type Cfg = AstCfg;
144
145 fn call<T: ParserTrait>(cfg: Self::Cfg, parser: &T) -> Self::Res {
146 AstResponse {
147 id: cfg.id,
148 root: build(parser, cfg.span, cfg.comment),
149 }
150 }
151}
152