1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use std::cell::RefCell;
use crate::ast::expression::Expression;
use crate::ast::identifier::Identifier;
use crate::{declare_container_node, impl_container_node_defaults, node_child_fn, node_optional_child_fn};
use crate::format::Writer;
use crate::r#type::r#type::Type;
use crate::traits::node_trait::NodeTrait;
use crate::traits::resolved::Resolve;
use crate::traits::write::Write;

declare_container_node!(
    Argument,
    pub(crate) name: Option<usize>,
    pub(crate) value: usize,
    pub(crate) resolved: RefCell<Option<ArgumentResolved>>
);

impl_container_node_defaults!(Argument);

impl Argument {

    node_optional_child_fn!(name, Identifier);

    node_child_fn!(value, Expression);

    pub fn get_type(&self) -> &Type {
        &self.value().resolved().r#type
    }

    pub fn resolve(&self, resolved: ArgumentResolved) {
        *(unsafe { &mut *self.resolved.as_ptr() }) = Some(resolved);
    }

    pub fn resolved(&self) -> &ArgumentResolved {
        (unsafe { &*self.resolved.as_ptr() }).as_ref().unwrap()
    }

    pub fn is_resolved(&self) -> bool {
        self.resolved.borrow().is_some()
    }

    pub fn resolved_name(&self) -> Option<&str> {
        if let Some(name) = self.name() {
            Some(name.name())
        } else {
            if self.is_resolved() {
                Some(self.resolved().name.as_str())
            } else {
                None
            }
        }
    }
}

#[derive(Debug)]
pub struct ArgumentResolved {
    pub name: String,
    pub expect: Type,
    pub completion_expect: Option<Type>,
}

impl Write for Argument {
    fn write<'a>(&'a self, writer: &mut Writer<'a>) {
        writer.write_children(self, self.children.values());
    }
}