yog_script_analyze/ast/
indexer.rs1use super::{Accessor, Method, MethodBody, Name, Param, Type, value_param};
7use crate::source::token::Span;
8use crate::system::INDEXER;
9use crate::words::{get, set};
10
11const ACCESSOR_SEP: char = '_';
13
14#[derive(Debug, Clone, PartialEq)]
15pub struct Indexer {
16 pub ty: Type,
17 pub params: Vec<Param>,
18 pub accessors: Vec<Accessor>,
19 pub span: Span,
20}
21
22pub fn accessor_name(word: &str) -> String {
24 format!("{word}{ACCESSOR_SEP}{INDEXER}")
25}
26
27impl Indexer {
28 pub fn getter(&self) -> Option<Method> {
30 let body = self.accessor(get::WORD.text)?;
31 Some(self.method(
32 get::WORD.text,
33 Some(self.ty.clone()),
34 self.params.clone(),
35 body,
36 ))
37 }
38
39 pub fn setter(&self) -> Option<Method> {
41 let body = self.accessor(set::WORD.text)?;
42 let mut params = self.params.clone();
43 let at = Name {
44 text: set::WORD.text.to_string(),
45 span: self.span,
46 };
47 params.push(value_param(&self.ty, &at));
48 Some(self.method(set::WORD.text, None, params, body))
49 }
50
51 fn accessor(&self, word: &str) -> Option<Option<MethodBody>> {
53 self.accessors
54 .iter()
55 .find(|a| a.name.text == word)
56 .map(|a| a.body.clone())
57 }
58
59 fn method(
60 &self,
61 word: &str,
62 ret: Option<Type>,
63 params: Vec<Param>,
64 body: Option<MethodBody>,
65 ) -> Method {
66 Method {
67 ret,
68 name: Name {
69 text: accessor_name(word),
70 span: self.span,
71 },
72 generics: Vec::new(),
73 params,
74 constraints: Vec::new(),
75 requires: None,
76 body,
77 }
78 }
79}