yog_script_analyze/ast/
indexer.rs1use super::{Accessor, Method, MethodBody, Name, Param, Type, value_param};
7use crate::source::token::Span;
8use crate::words::{get, set};
9use yog_script_ids::clr::INDEXER;
10
11use yog_script_ids::clr::ACCESSOR_SEP;
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 get: Option<Box<Method>>,
23 set: Option<Box<Method>>,
24}
25
26pub fn accessor_name(word: &str) -> String {
28 format!("{word}{ACCESSOR_SEP}{INDEXER}")
29}
30
31impl Indexer {
32 pub fn new(ty: Type, params: Vec<Param>, accessors: Vec<Accessor>, span: Span) -> Self {
35 let mut ix = Indexer {
36 ty,
37 params,
38 accessors,
39 span,
40 get: None,
41 set: None,
42 };
43 ix.get = ix.accessor(get::WORD.text).map(|body| {
44 Box::new(ix.method(get::WORD.text, Some(ix.ty.clone()), ix.params.clone(), body))
45 });
46 ix.set = ix.accessor(set::WORD.text).map(|body| {
47 let mut params = ix.params.clone();
48 let at = Name {
49 text: set::WORD.text.to_string(),
50 span: ix.span,
51 };
52 params.push(value_param(&ix.ty, &at));
53 Box::new(ix.method(set::WORD.text, None, params, body))
54 });
55 ix
56 }
57
58 pub fn getter(&self) -> Option<&Method> {
60 self.get.as_deref()
61 }
62
63 pub fn setter(&self) -> Option<&Method> {
65 self.set.as_deref()
66 }
67
68 fn accessor(&self, word: &str) -> Option<Option<MethodBody>> {
70 self.accessors
71 .iter()
72 .find(|a| a.name.text == word)
73 .map(|a| a.body.clone())
74 }
75
76 fn method(
77 &self,
78 word: &str,
79 ret: Option<Type>,
80 params: Vec<Param>,
81 body: Option<MethodBody>,
82 ) -> Method {
83 Method {
84 ret,
85 name: Name {
86 text: accessor_name(word),
87 span: self.span,
88 },
89 explicit: None,
90 generics: Vec::new(),
91 params,
92 constraints: Vec::new(),
93 requires: None,
94 body,
95 }
96 }
97}