typr_core/components/language/
var.rs1#![allow(
2 dead_code,
3 unused_variables,
4 unused_imports,
5 unreachable_code,
6 unused_assignments
7)]
8use crate::components::context::Context;
9use crate::components::error_message::help_data::HelpData;
10use crate::components::error_message::locatable::Locatable;
11use crate::components::language::Lang;
12use crate::components::r#type::function_type::FunctionType;
13use crate::components::r#type::tchar::Tchar;
14use crate::components::r#type::type_system::TypeSystem;
15use crate::components::r#type::Type;
16use crate::processes::parsing::elements::is_pascal_case;
17use crate::processes::transpiling::translatable::RTranslatable;
18use crate::processes::type_checking::typing;
19use crate::utils::builder;
20use serde::{Deserialize, Serialize};
21use std::fmt;
22
23type Name = String;
24type IsPackageOpaque = bool;
25
26#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, Eq, Hash)]
27pub enum Permission {
28 Private,
29 Public,
30}
31
32impl fmt::Display for Permission {
33 fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 match self {
35 Permission::Private => write!(f, "private"),
36 Permission::Public => write!(f, "public"),
37 }
38 }
39}
40
41impl From<Permission> for bool {
42 fn from(val: Permission) -> Self {
43 match val {
44 Permission::Public => true,
45 _ => false,
46 }
47 }
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize, Hash)]
51pub struct Var {
52 pub name: Name,
53 pub is_opaque: IsPackageOpaque,
54 pub related_type: Type,
55 pub help_data: HelpData,
56}
57
58impl PartialEq for Var {
59 fn eq(&self, other: &Self) -> bool {
60 self.name == other.name
61 && self.is_opaque == other.is_opaque
62 && self.related_type == other.related_type
63 }
64}
65
66impl Eq for Var {}
67
68impl Locatable for Var {
69 fn get_help_data(&self) -> HelpData {
70 self.help_data.clone()
71 }
72}
73
74impl Var {
75 pub fn set_type_from_params(self, params: &[Lang], context: &Context) -> Self {
76 let typ = (params.len() > 0)
77 .then(|| typing(context, ¶ms[0]).value)
78 .unwrap_or_default();
79 self.set_type(typ)
80 }
81
82 pub fn add_backticks_if_percent(self) -> Self {
83 let s = self.get_name();
84 let res = if s.starts_with('%') && s.ends_with('%') {
85 format!("`{}`", s)
86 } else {
87 s.to_string()
88 };
89 self.set_name(&res)
90 }
91
92 pub fn alias(name: &str, params: &[Type]) -> Self {
93 Var::from(name).set_type(Type::Params(params.to_vec(), HelpData::default()))
94 }
95
96 pub fn set_var_related_type(&self, types: &Vec<Type>, context: &Context) -> Var {
97 if types.len() > 0 {
98 let first_arg = types.iter().nth(0).unwrap().clone();
99 self.clone().set_type(first_arg.clone())
100 } else {
101 self.clone()
102 }
103 }
104
105 fn keep_minimal(liste: Vec<Type>, context: &Context) -> Option<Type> {
106 let mut mins: Vec<Type> = Vec::new();
107
108 for candidat in liste {
109 let mut keep_candidat = true;
110 let mut indices_to_delete = Vec::new();
111
112 for (i, existant) in mins.iter().enumerate() {
113 if candidat.is_subtype(existant, context).0 {
114 indices_to_delete.push(i);
115 } else if existant.is_subtype(&candidat, context).0 {
116 keep_candidat = false;
117 break;
118 }
119 }
120
121 if keep_candidat {
122 for &i in indices_to_delete.iter().rev() {
123 mins.remove(i);
124 }
125 mins.push(candidat);
126 }
127 }
128 if mins.iter().any(|x| !x.is_interface()) {
130 mins.iter().cloned().skip_while(|x| x.is_interface()).next()
131 } else {
132 mins.iter().cloned().next()
133 }
134 }
135
136 pub fn get_functions_from_name(&self, context: &Context) -> Vec<FunctionType> {
137 context
138 .get_functions_from_name(&self.get_name())
139 .iter()
140 .flat_map(|(_, typ)| typ.clone().to_function_type())
141 .collect()
142 }
143
144 pub fn from_language(l: Lang) -> Option<Var> {
145 match l {
146 Lang::Variable(name, muta, typ, h) => Some(Var {
147 name,
148 is_opaque: muta,
149 related_type: typ,
150 help_data: h,
151 }),
152 _ => None,
153 }
154 }
155
156 pub fn from_type(t: Type) -> Option<Var> {
157 match t {
158 Type::Alias(name, concret_types, opacity, h) => {
159 let var = Var::from_name(&name)
160 .set_type(Type::Params(
161 concret_types.to_vec(),
162 concret_types.clone().into(),
163 ))
164 .set_help_data(h)
165 .set_opacity(opacity);
166 Some(var)
167 }
168 Type::Char(val, h) => {
169 let var = Var::from_name(&val.get_val()).set_help_data(h);
170 Some(var)
171 }
172 _ => None,
173 }
174 }
175
176 pub fn from_name(name: &str) -> Self {
177 Var {
178 name: name.to_string(),
179 is_opaque: false,
180 related_type: builder::empty_type(),
181 help_data: HelpData::default(),
182 }
183 }
184
185 pub fn to_language(self) -> Lang {
186 Lang::Variable(self.name, self.is_opaque, self.related_type, self.help_data)
187 }
188
189 pub fn set_name(self, s: &str) -> Var {
190 Var {
191 name: s.to_string(),
192 is_opaque: self.is_opaque,
193 related_type: self.related_type,
194 help_data: self.help_data,
195 }
196 }
197
198 pub fn set_type(self, typ: Type) -> Var {
199 let typ = match typ {
200 Type::Function(params, _, h) => {
201 if params.len() >= 1 {
202 params[0].clone()
203 } else {
204 Type::Any(h)
205 }
206 }
207 _ => typ,
208 };
209 Var {
210 name: self.name,
211 is_opaque: self.is_opaque,
212 related_type: typ,
213 help_data: self.help_data,
214 }
215 }
216
217 pub fn set_type_raw(self, typ: Type) -> Var {
218 Var {
219 name: self.name,
220 is_opaque: self.is_opaque,
221 related_type: typ,
222 help_data: self.help_data,
223 }
224 }
225
226 pub fn set_opacity(self, opa: bool) -> Var {
227 Var {
228 name: self.name,
229 is_opaque: opa,
230 related_type: self.related_type,
231 help_data: self.help_data,
232 }
233 }
234
235 pub fn get_name(&self) -> String {
236 self.name.to_string()
237 }
238
239 pub fn get_type(&self) -> Type {
240 self.related_type.clone()
241 }
242
243 pub fn get_help_data(&self) -> HelpData {
244 self.help_data.clone()
245 }
246
247 pub fn match_with(&self, var: &Var, context: &Context) -> bool {
248 (self.get_name() == var.get_name())
249 && self.get_type().is_subtype(&var.get_type(), context).0
250 }
251
252 pub fn set_help_data(self, h: HelpData) -> Var {
253 Var {
254 name: self.name,
255 is_opaque: self.is_opaque,
256 related_type: self.related_type,
257 help_data: h,
258 }
259 }
260
261 pub fn is_imported(&self) -> bool {
262 self.is_variable() && self.is_opaque.clone()
263 }
264
265 pub fn is_alias(&self) -> bool {
266 match self.get_type() {
267 Type::Params(_, _) => true,
268 _ => false,
269 }
270 }
271
272 pub fn is_variable(&self) -> bool {
273 !self.is_alias()
274 }
275
276 pub fn is_opaque(&self) -> bool {
277 self.is_alias() && self.is_opaque
278 }
279
280 pub fn get_opacity(&self) -> bool {
281 self.is_opaque
282 }
283
284 pub fn to_alias_type(self) -> Type {
285 Type::Alias(
286 self.get_name(),
287 vec![],
288 self.get_opacity(),
289 self.get_help_data(),
290 )
291 }
292
293 pub fn to_alias_lang(self) -> Lang {
294 Lang::Alias(
295 Box::new(self.clone().to_language()),
296 vec![],
297 builder::unknown_function_type(),
298 self.get_help_data(),
299 )
300 }
301
302 pub fn to_let(self) -> Lang {
303 Lang::Let(
304 Box::new(self.clone().to_language()),
305 builder::unknown_function_type(),
306 Box::new(builder::empty_lang()),
307 self.get_help_data(),
308 )
309 }
310
311 pub fn contains(&self, s: &str) -> bool {
312 self.get_name().contains(s)
313 }
314
315 pub fn replace(self, old: &str, new: &str) -> Self {
316 let res = self.get_name().replace(old, new);
317 self.set_name(&res)
318 }
319
320 pub fn display_type(self, cont: &Context) -> Self {
321 if !self.get_name().contains(".") {
322 let type_str = match self.get_type() {
323 Type::Empty(_) | Type::Any(_) => "".to_string(),
324 ty => ".".to_string() + &cont.get_class(&ty).replace("'", ""),
325 };
326 let new_name = if self.contains("`") {
327 "`".to_string() + &self.get_name().replace("`", "") + &type_str + "`"
328 } else {
329 self.get_name() + &type_str
330 };
331 self.set_name(&new_name)
332 } else {
333 self
334 }
335 }
336
337 pub fn get_digit(&self, s: &str) -> i8 {
338 self.get_name()[s.len()..].parse::<i8>().unwrap()
339 }
340
341 pub fn add_digit(self, d: i8) -> Self {
342 self.clone().set_name(&(self.get_name() + &d.to_string()))
343 }
344
345 pub fn exist(&self, context: &Context) -> Option<Self> {
346 context.variable_exist(self.clone())
347 }
348}
349
350impl fmt::Display for Var {
351 fn fmt(self: &Self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 write!(f, "{}<{}>", self.name, self.related_type)
353 }
354}
355
356impl Default for Var {
357 fn default() -> Self {
358 Var {
359 name: "".to_string(),
360 is_opaque: false,
361 related_type: Type::Empty(HelpData::default()),
362 help_data: HelpData::default(),
363 }
364 }
365}
366
367impl RTranslatable<String> for Var {
368 fn to_r(&self, _: &Context) -> String {
369 format!("{}", self.name)
370 }
371}
372
373impl TryFrom<Lang> for Var {
374 type Error = ();
375
376 fn try_from(value: Lang) -> Result<Self, Self::Error> {
377 match value {
378 Lang::Variable(name, muta, typ, h) => Ok(Var {
379 name,
380 is_opaque: muta,
381 related_type: typ,
382 help_data: h,
383 }),
384 _ => Err(()),
385 }
386 }
387}
388
389impl TryFrom<Box<Lang>> for Var {
390 type Error = ();
391
392 fn try_from(value: Box<Lang>) -> Result<Self, Self::Error> {
393 Var::try_from((*value).clone())
394 }
395}
396
397impl TryFrom<&Box<Lang>> for Var {
398 type Error = ();
399
400 fn try_from(value: &Box<Lang>) -> Result<Self, Self::Error> {
401 Var::try_from((*value).clone())
402 }
403}
404
405impl From<&str> for Var {
406 fn from(val: &str) -> Self {
407 Var {
408 name: val.to_string(),
409 is_opaque: false,
410 related_type: Type::Empty(HelpData::default()),
411 help_data: HelpData::default(),
412 }
413 }
414}
415
416impl TryFrom<Type> for Var {
417 type Error = String;
418
419 fn try_from(value: Type) -> Result<Self, Self::Error> {
420 match value {
421 Type::Char(tchar, h) => match tchar {
422 Tchar::Val(name) => {
423 let var = if is_pascal_case(&name) {
424 Var::from_name(&name)
425 .set_help_data(h)
426 .set_type(builder::params_type())
427 } else {
428 Var::from_name(&name).set_help_data(h)
429 };
430 Ok(var)
431 }
432 _ => todo!(),
433 },
434 _ => Err("From type to Var, not possible".to_string()),
435 }
436 }
437}