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
//! Field AST node. //! use super::Node; use gc::{Finalize, Trace}; use std::fmt; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; /// This property accessor provides access to an object's properties by using the /// [dot notation][mdn]. /// /// In the object.property syntax, the property must be a valid JavaScript identifier. /// (In the ECMAScript standard, the names of properties are technically "IdentifierNames", not /// "Identifiers", so reserved words can be used but are not recommended). /// /// One can think of an object as an associative array (a.k.a. map, dictionary, hash, lookup /// table). The keys in this array are the names of the object's properties. /// /// It's typical when speaking of an object's properties to make a distinction between /// properties and methods. However, the property/method distinction is little more than a /// convention. A method is simply a property that can be called (for example, if it has a /// reference to a Function instance as its value). /// /// More information: /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] /// /// [spec]: https://tc39.es/ecma262/#sec-property-accessors /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors#Dot_notation #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Clone, Debug, Trace, Finalize, PartialEq)] pub struct GetConstField { obj: Box<Node>, field: Box<str>, } impl GetConstField { /// Creates a `GetConstField` AST node. pub fn new<V, L>(value: V, label: L) -> Self where V: Into<Node>, L: Into<Box<str>>, { Self { obj: Box::new(value.into()), field: label.into(), } } /// Gets the original object from where to get the field from. pub fn obj(&self) -> &Node { &self.obj } /// Gets the name of the field to retrieve. pub fn field(&self) -> &str { &self.field } } impl fmt::Display for GetConstField { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}.{}", self.obj(), self.field()) } } impl From<GetConstField> for Node { fn from(get_const_field: GetConstField) -> Self { Self::GetConstField(get_const_field) } } /// This property accessor provides access to an object's properties by using the /// [bracket notation][mdn]. /// /// In the object[property_name] syntax, the property_name is just a string or /// [Symbol][symbol]. So, it can be any string, including '1foo', '!bar!', or even ' ' (a /// space). /// /// One can think of an object as an associative array (a.k.a. map, dictionary, hash, lookup /// table). The keys in this array are the names of the object's properties. /// /// It's typical when speaking of an object's properties to make a distinction between /// properties and methods. However, the property/method distinction is little more than a /// convention. A method is simply a property that can be called (for example, if it has a /// reference to a Function instance as its value). /// /// More information: /// - [ECMAScript reference][spec] /// - [MDN documentation][mdn] /// /// [spec]: https://tc39.es/ecma262/#sec-property-accessors /// [symbol]: https://developer.mozilla.org/en-US/docs/Glossary/Symbol /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_accessors#Bracket_notation #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[derive(Clone, Debug, Trace, Finalize, PartialEq)] pub struct GetField { obj: Box<Node>, field: Box<Node>, } impl GetField { pub fn obj(&self) -> &Node { &self.obj } pub fn field(&self) -> &Node { &self.field } /// Creates a `GetField` AST node. pub fn new<V, F>(value: V, field: F) -> Self where V: Into<Node>, F: Into<Node>, { Self { obj: Box::new(value.into()), field: Box::new(field.into()), } } } impl fmt::Display for GetField { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}[{}]", self.obj(), self.field()) } } impl From<GetField> for Node { fn from(get_field: GetField) -> Self { Self::GetField(get_field) } }