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)
// }
// }