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

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ObjectInitializer {
    pub location: Location,
    pub fields: Vec<Rc<InitializerField>>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum InitializerField {
    Field {
        name: (FieldName, Location),
        /// Non-null operator used for destructuring.
        non_null: bool,
        value: Option<Rc<Expression>>,
    },
    Rest((Rc<Expression>, Location)),
}

impl InitializerField {
    pub fn location(&self) -> Location {
        match self {
            Self::Field { ref name, ref value, .. } => {
                value.clone().map_or(name.1.clone(), |v| name.1.combine_with(v.location()))
            },
            Self::Rest((_, ref l)) => l.clone(),
        }
    }

    pub fn shorthand(&self) -> Option<&QualifiedIdentifier> {
        if let Self::Field { name, .. } = self {
            if let FieldName::Identifier(qid) = &name.0 {
                Some(qid)
            } else {
                None
            }
        } else {
            None
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FieldName {
    Identifier(QualifiedIdentifier),
    Brackets(Rc<Expression>),
    StringLiteral(Rc<Expression>),
    NumericLiteral(Rc<Expression>),
}

impl FieldName {
    pub(crate) fn id(&self) -> Option<&QualifiedIdentifier> {
        let Self::Identifier(id) = &self else {
            return None;
        };
        Some(id)
    }

    pub fn id_equals(&self, name: &str) -> bool {
        self.id().map(|name1| name == name1.to_identifier_name_or_asterisk().map(|id| id.0.clone()).unwrap_or("".into())).unwrap_or(false)
    }
}