xidl_parser/typed_ast/
annotation.rs1use super::*;
2use serde::{Deserialize, Serialize};
3use xidl_parser_derive::Parser;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct AnnotationAppl {
7 pub name: AnnotationName,
8 pub params: Option<AnnotationParams>,
9 pub is_extend: bool,
10 pub extra: Vec<AnnotationAppl>,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub enum AnnotationName {
15 ScopedName(ScopedName),
16 Builtin(String),
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub enum AnnotationParams {
21 ConstExpr(ConstExpr),
22 Params(Vec<AnnotationApplParam>),
23 Raw(String),
24}
25
26#[derive(Debug, Clone, Parser, Serialize, Deserialize)]
27pub struct AnnotationApplParam {
28 pub ident: Identifier,
29 pub value: Option<ConstExpr>,
30}
31
32impl<'a> crate::parser::FromTreeSitter<'a> for AnnotationAppl {
33 fn from_node(
34 node: tree_sitter::Node<'a>,
35 ctx: &mut crate::parser::ParseContext<'a>,
36 ) -> crate::error::ParserResult<Self> {
37 let kind_id = node.kind_id();
38 let is_extend = kind_id == xidl_parser_derive::node_id!("extend_annotation_appl");
39 if !is_extend {
40 assert_eq!(kind_id, xidl_parser_derive::node_id!("annotation_appl"));
41 }
42 let raw = ctx.node_text(&node)?.to_string();
43
44 let mut custom_body = None;
45 let mut builtin_body = None;
46 let mut extra = Vec::new();
47 for ch in node.children(&mut node.walk()) {
48 match ch.kind_id() {
49 xidl_parser_derive::node_id!("annotation_appl_custom_body") => {
50 custom_body = Some(ch);
51 }
52 xidl_parser_derive::node_id!("annotation_appl_builtin_body") => {
53 builtin_body = Some(ch);
54 }
55 xidl_parser_derive::node_id!("annotation_appl")
56 | xidl_parser_derive::node_id!("extend_annotation_appl") => {
57 extra.push(AnnotationAppl::from_node(ch, ctx)?);
58 }
59 _ => {}
60 }
61 }
62
63 if let Some(custom_body) = custom_body {
64 let mut scoped_name = None;
65 let mut params = None;
66 for ch in custom_body.children(&mut custom_body.walk()) {
67 match ch.kind_id() {
68 xidl_parser_derive::node_id!("scoped_name") => {
69 scoped_name = Some(ScopedName::from_node(ch, ctx)?);
70 }
71 xidl_parser_derive::node_id!("annotation_appl_params") => {
72 params = Some(AnnotationParams::from_node(ch, ctx)?);
73 }
74 _ => {}
75 }
76 }
77 let scoped_name = scoped_name.ok_or_else(|| {
78 crate::error::ParseError::UnexpectedNode(
79 "annotation_appl_custom_body missing scoped_name".to_string(),
80 )
81 })?;
82 return Ok(Self {
83 name: AnnotationName::ScopedName(scoped_name),
84 params,
85 is_extend,
86 extra,
87 });
88 }
89
90 let source = builtin_body
91 .map(|node| ctx.node_text(&node))
92 .transpose()?
93 .unwrap_or(raw.as_str());
94 let source = source.trim().strip_prefix("//@").unwrap_or(source);
95 let raw = source.trim().strip_prefix('@').unwrap_or(source).trim();
96 let (name, args) = match raw.split_once('(') {
97 Some((name, rest)) => {
98 let args = rest.strip_suffix(')').unwrap_or(rest).trim();
99 (name.trim(), Some(args))
100 }
101 None => (raw, None),
102 };
103
104 Ok(Self {
105 name: AnnotationName::Builtin(name.to_string()),
106 params: args.map(|value| AnnotationParams::Raw(value.to_string())),
107 is_extend,
108 extra,
109 })
110 }
111}
112
113impl<'a> crate::parser::FromTreeSitter<'a> for AnnotationParams {
114 fn from_node(
115 node: tree_sitter::Node<'a>,
116 ctx: &mut crate::parser::ParseContext<'a>,
117 ) -> crate::error::ParserResult<Self> {
118 assert_eq!(
119 node.kind_id(),
120 xidl_parser_derive::node_id!("annotation_appl_params")
121 );
122
123 let mut const_expr = None;
124 let mut params = vec![];
125 for ch in node.children(&mut node.walk()) {
126 match ch.kind_id() {
127 xidl_parser_derive::node_id!("const_expr") => {
128 const_expr = Some(ConstExpr::from_node(ch, ctx)?);
129 }
130 xidl_parser_derive::node_id!("annotation_appl_param") => {
131 params.push(AnnotationApplParam::from_node(ch, ctx)?);
132 }
133 _ => {}
134 }
135 }
136
137 if let Some(const_expr) = const_expr {
138 return Ok(Self::ConstExpr(const_expr));
139 }
140 if !params.is_empty() {
141 return Ok(Self::Params(params));
142 }
143
144 Err(crate::error::ParseError::UnexpectedNode(
145 "annotation_appl_params missing content".to_string(),
146 ))
147 }
148}