mxmlextrema_as3parser/tree/
function_definition.rs

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
use crate::ns::*;
use serde::{Serialize, Deserialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionDefinition {
    pub location: Location,
    pub asdoc: Option<Rc<Asdoc>>,
    pub attributes: Vec<Attribute>,
    pub name: FunctionName,
    pub common: Rc<FunctionCommon>,
}

impl FunctionDefinition {
    /// Indicates whether the function definition is not a getter, setter,
    /// or constructor.
    pub fn is_normal(&self) -> bool {
        matches!(self.name, FunctionName::Identifier(_))
    }
    pub fn is_getter(&self) -> bool {
        matches!(self.name, FunctionName::Getter(_))
    }
    pub fn is_setter(&self) -> bool {
        matches!(self.name, FunctionName::Setter(_))
    }
    pub fn is_constructor(&self) -> bool {
        matches!(self.name, FunctionName::Constructor(_))
    }
    pub fn name_identifier(&self) -> (String, Location) {
        match &self.name {
            FunctionName::Identifier(name) => name.clone(),
            FunctionName::Getter(name) => name.clone(),
            FunctionName::Setter(name) => name.clone(),
            FunctionName::Constructor(name) => name.clone(),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FunctionName {
    Identifier((String, Location)),
    Getter((String, Location)),
    Setter((String, Location)),
    /// A `FunctionName` is a `Constructor` variant
    /// when the corresponding function definition is a constructor.
    Constructor((String, Location)),
}

impl FunctionName {
    pub fn location(&self) -> Location {
        match self {
            Self::Identifier((_, l)) => l.clone(),
            Self::Getter((_, l)) => l.clone(),
            Self::Setter((_, l)) => l.clone(),
            Self::Constructor((_, l)) => l.clone(),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionCommon {
    pub location: Location,
    /// Indicates whether the corresponding function
    /// contains the `yield` operator.
    pub contains_yield: bool,
    /// Indicates whether the corresponding function
    /// contains the `await` operator.
    pub contains_await: bool,
    pub signature: FunctionSignature,
    pub body: Option<FunctionBody>,
}

impl FunctionCommon {
    pub(crate) fn has_block_body(&self) -> bool {
        if let Some(ref body) = self.body { matches!(body, FunctionBody::Block(_)) } else { false }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FunctionSignature {
    pub location: Location,
    pub this_parameter: Option<Rc<ThisParameter>>,
    pub parameters: Vec<Rc<Parameter>>,
    pub result_type: Option<Rc<Expression>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ThisParameter {
    pub location: Location,
    pub type_annotation: Rc<Expression>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Parameter {
    pub location: Location,
    pub kind: ParameterKind,
    pub destructuring: TypedDestructuring,
    pub default_value: Option<Rc<Expression>>,
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[repr(u32)]
pub enum ParameterKind {
    Required = 1,
    Optional = 2,
    Rest = 3,
}

impl ParameterKind {
    pub fn may_be_followed_by(&self, other: Self) -> bool {
        (*self as u32) <= (other as u32)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FunctionBody {
    Expression(Rc<Expression>),
    Block(Rc<Block>),
}