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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
use super::*;

mod display;

mod iters;

/// `class A { }, structure V { }`
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ClassKind {
    /// A function that lazy evaluate the arguments
    Class,
    /// A function that eager evaluate the arguments
    Structure,
}

#[doc = include_str!("readme.md")]
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ClassDeclaration {
    /// The name of the class.
    pub name: IdentifierNode,
    /// The kind of class
    pub kind: ClassKind,
    /// The document of the class
    pub annotations: AnnotationNode,
    /// The parameter arguments of the class.
    pub generic: Option<ParametersList>,
    /// The super class of the class.
    pub inherits: Option<String>,
    /// The traits that the class implements.
    pub implements: Vec<String>,
    /// All fields declared in this block, exclude extensions.
    pub terms: Vec<ClassTerm>,
    /// The range of the number.
    pub span: Range<u32>,
}

impl Debug for ClassDeclaration {
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
        let w = &mut match self.kind {
            ClassKind::Class => f.debug_struct("DefineClass"),
            ClassKind::Structure => f.debug_struct("DefineStructure"),
        };
        // if !self.constraint.is_empty() {
        //     w.field("constraint", &self.constraint);
        // }
        if !self.annotations.is_empty() {
            w.field("annotations", &self.annotations);
        }
        w.field("name", &WrapDisplay::new(&self.name));
        if let Some(s) = &self.generic {
            w.field("generic", s);
        }
        if let Some(s) = &self.inherits {
            w.field("inherits", s);
        }
        if !self.implements.is_empty() {
            w.field("implements", &self.implements);
        }
        if !self.terms.is_empty() {
            w.field("terms", &self.terms);
        }
        w.field("span", &self.span);
        w.finish()
    }
}

/// Valid terms in the class statements
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ClassTerm {
    /// `@expand {}`
    Macro(ProceduralNode),
    /// `field: Type = default`
    Field(FieldDeclaration),
    /// `method()`
    Method(MethodDeclaration),
    /// `domain { }`
    Domain(DomainDeclaration),
}

/// `object: Trait { ... }`
///
/// Construct an anonymous object
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ConstructObjectNode {
    /// The super class of the class.
    pub base_classes: Option<String>,
    /// The traits that the class implements.
    pub bounds: Option<ExpressionKind>,
    /// The range of the node
    pub span: Range<u32>,
}

/// `field: Type = default`
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct FieldDeclaration {
    /// The name of this field
    pub name: IdentifierNode,
    /// The modifiers of the declaration.
    pub annotations: AnnotationNode,
    /// The type hint of this field
    pub typing: Option<ExpressionKind>,
    /// The default value of this field
    pub default: Option<ExpressionKind>,
    /// The range of the declaration.
    pub span: Range<u32>,
}

/// `#attribute modifier Trait::method(): Return / Effect { ... }`
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct MethodDeclaration {
    /// The method name which may associated with a trait.
    pub name: NamePathNode,
    /// The modifiers of the node.
    pub annotations: AnnotationNode,
    /// Thy type parameters of this function
    pub generics: ParametersList,
    /// Thy value parameters of this function
    pub parameters: ParametersList,
    /// `: ReturnType / [EffectType]`
    pub returns: FunctionReturnNode,
    /// `{ body }`
    pub body: Option<StatementBlock>,
    /// The range of the declaration.
    pub span: Range<u32>,
}

impl Debug for MethodDeclaration {
    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
        let w = &mut f.debug_struct("Method");
        if !self.annotations.is_empty() {
            w.field("annotations", &self.annotations);
        }
        w.field("name", &WrapDisplay::new(&self.name));
        if !self.generics.terms.is_empty() {
            w.field("generics", &self.generics);
        }
        if !self.parameters.terms.is_empty() {
            w.field("parameters", &self.parameters);
        }
        if let Some(s) = &self.returns.typing {
            w.field("returns", s);
        }
        if let Some(s) = &self.body {
            w.field("body", s);
        }
        w.field("span", &self.span);
        w.finish()
    }
}

/// `domain { field; method(); domain {} }`
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct DomainDeclaration {
    /// The annotations of the domain
    pub annotations: AnnotationNode,
    /// The range of the declaration.
    pub body: Vec<ClassTerm>,
    /// The range of the declaration.
    pub span: Range<u32>,
}

impl ValkyrieNode for ConstructObjectNode {
    fn get_range(&self) -> Range<usize> {
        Range { start: self.span.start as usize, end: self.span.end as usize }
    }
}

// impl ClassDeclare {
//     pub fn get_namepath(&self) -> Iter<'_, ValkyrieIdentifier> {
//         self.namepath.iter()
//     }
//     pub fn mut_namepath(&mut self) -> &mut Vec<ValkyrieIdentifier> {
//         &mut self.namepath
//     }
//     pub fn get_modifiers(&self) -> Iter<'_, ValkyrieIdentifier> {
//         self.modifiers.iter()
//     }
//     pub fn mut_modifiers(&mut self) -> &mut Vec<ValkyrieIdentifier> {
//         &mut self.modifiers
//     }
//     pub fn get_statement(&self) -> Iter<'_, ValkyrieASTNode> {
//         self.statements.iter()
//     }
//     pub fn mut_statement(&mut self) -> &mut Vec<ValkyrieASTNode> {
//         &mut self.statements
//     }
//     pub fn to_node(self, file: FileID, range: &Range<usize>) -> ValkyrieASTNode {
//         ValkyrieASTKind::Class(box self).to_node(file, range)
//     }
// }