yarnspinner_compiler/output/
declaration.rs1use crate::prelude::*;
8use antlr_rust::rule_context::CustomRuleContext;
9use antlr_rust::token::Token;
10use antlr_rust::token_factory::TokenFactory;
11use std::fmt::{Debug, Display};
12use std::ops::Range;
13use yarnspinner_core::prelude::*;
14use yarnspinner_core::types::Type;
15
16#[derive(Debug, Clone, PartialEq)]
22#[cfg_attr(feature = "bevy", derive(Reflect))]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24#[cfg_attr(feature = "bevy", reflect(Debug, PartialEq))]
25#[cfg_attr(
26 all(feature = "bevy", feature = "serde"),
27 reflect(Serialize, Deserialize)
28)]
29pub struct Declaration {
30 pub name: String,
32
33 pub default_value: Option<YarnValue>,
36
37 pub description: Option<String>,
39
40 pub source_file_name: DeclarationSource,
45
46 pub source_node_name: Option<String>,
51
52 pub is_implicit: bool,
58
59 pub r#type: Type,
62
63 pub range: Option<Range<Position>>,
70}
71
72impl Declaration {
73 pub fn source_file_line(&self) -> Option<usize> {
79 self.range.as_ref()?.start.line.into()
80 }
81
82 #[doc(hidden)]
83 pub fn new(name: impl Into<String>, r#type: impl Into<Type>) -> Self {
84 Self {
85 name: name.into(),
86 r#type: r#type.into(),
87 default_value: Default::default(),
88 description: Default::default(),
89 source_file_name: Default::default(),
90 source_node_name: Default::default(),
91 is_implicit: Default::default(),
92 range: Default::default(),
93 }
94 }
95
96 #[doc(hidden)]
97 pub fn with_type(mut self, r#type: impl Into<Type>) -> Self {
98 self.r#type = r#type.into();
99 self
100 }
101
102 #[doc(hidden)]
103 pub fn with_default_value(mut self, default_value: impl Into<YarnValue>) -> Self {
104 self.default_value = Some(default_value.into());
105 self
106 }
107
108 #[doc(hidden)]
109 pub fn with_name(mut self, name: impl Into<String>) -> Self {
110 self.name = name.into();
111 self
112 }
113
114 #[doc(hidden)]
115 pub fn with_description(mut self, description: impl Into<String>) -> Self {
116 self.description = Some(description.into());
117 self
118 }
119
120 #[doc(hidden)]
121 pub fn with_description_optional(mut self, description: impl Into<Option<String>>) -> Self {
122 self.description = description.into();
123 self
124 }
125
126 #[doc(hidden)]
127 pub fn with_source_file_name(mut self, source_file_name: impl Into<DeclarationSource>) -> Self {
128 self.source_file_name = source_file_name.into();
129 self
130 }
131
132 #[doc(hidden)]
133 pub fn with_source_node_name(mut self, source_node_name: impl Into<String>) -> Self {
134 self.source_node_name = Some(source_node_name.into());
135 self
136 }
137
138 #[doc(hidden)]
139 pub fn with_source_node_name_optional(
140 mut self,
141 source_node_name: impl Into<Option<String>>,
142 ) -> Self {
143 self.source_node_name = source_node_name.into();
144 self
145 }
146
147 #[doc(hidden)]
148 pub fn with_implicit(mut self) -> Self {
149 self.is_implicit = true;
150 self
151 }
152
153 #[doc(hidden)]
154 pub fn with_range(mut self, range: impl Into<Range<Position>>) -> Self {
155 self.range = Some(range.into());
156 self
157 }
158
159 #[doc(hidden)]
160 pub fn eq(&self, other: &Self, epsilon: f32) -> bool {
161 self.name == other.name
162 && self.description == other.description
163 && self.source_file_name == other.source_file_name
164 && self.source_node_name == other.source_node_name
165 && self.is_implicit == other.is_implicit
166 && self.r#type == other.r#type
167 && self.range == other.range
168 && match (&self.default_value, &other.default_value) {
169 (Some(a), Some(b)) => a.eq(b, epsilon),
170 (None, None) => true,
171 _ => false,
172 }
173 }
174}
175
176#[derive(Debug, Clone, PartialEq, Eq, Default)]
182#[cfg_attr(feature = "bevy", derive(Reflect))]
183#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
184#[cfg_attr(feature = "bevy", reflect(Debug, PartialEq, Default))]
185#[cfg_attr(
186 all(feature = "bevy", feature = "serde"),
187 reflect(Serialize, Deserialize)
188)]
189pub enum DeclarationSource {
190 #[default]
192 External,
193 File(String),
195}
196
197impl<T> From<T> for DeclarationSource
198where
199 T: Into<String>,
200{
201 fn from(file_name: T) -> Self {
202 Self::File(file_name.into())
203 }
204}
205
206pub(crate) trait ParserRuleContextExtRangeSource<'input>:
207 ParserRuleContextExt<'input>
208where
209 <<<<Self as CustomRuleContext<'input>>::TF as TokenFactory<'input>>::Inner as Token>::Data as ToOwned>::Owned:
210 Into<String>,
211{
212 fn range(&self) -> Range<Position> {
213 let start = Position {
214 line: self.start().get_line_as_usize().saturating_sub(1),
215 character: self.start().get_column_as_usize(),
216 };
217 let text: String = self.stop().get_text().to_owned().into();
218 let stop = Position {
219 line: self.stop().get_line_as_usize().saturating_sub(1),
220 character: self.stop().get_column_as_usize() + text.len(),
221 };
222 start..stop
223 }
224}
225
226impl<'input, T: ParserRuleContextExt<'input>> ParserRuleContextExtRangeSource<'input> for T where
227 <<<<T as CustomRuleContext<'input>>::TF as TokenFactory<'input>>::Inner as Token>::Data as ToOwned>::Owned:
228 Into<String>
229{
230}
231
232impl Display for DeclarationSource {
233 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
234 match self {
235 Self::External => write!(f, "(External)"),
236 Self::File(file_name) => write!(f, "{}", file_name),
237 }
238 }
239}
240
241#[derive(Debug, Clone, PartialEq, Eq, Hash)]
242pub(crate) struct DeferredTypeDiagnostic {
243 pub(crate) name: String,
244 pub(crate) diagnostic: Diagnostic,
245}