Skip to main content

ezno_checker/features/
assignments.rs

1use source_map::SpanWithSource;
2
3use crate::{
4	types::properties::{PropertyKey, Publicity},
5	TypeId,
6};
7
8use super::operations::{LogicalOperator, MathematicalOrBitwiseOperation};
9
10/// A single or multiple items to assign to
11pub enum Assignable<A: crate::ASTImplementation> {
12	Reference(Reference),
13	ObjectDestructuring(Vec<AssignableObjectDestructuringField<A>>, Option<AssignableSpread<A>>),
14	ArrayDestructuring(Vec<AssignableArrayDestructuringField<A>>, Option<AssignableSpread<A>>),
15}
16
17/// TODO Can this use lifetimes?
18#[derive(Clone)]
19pub enum Reference {
20	Variable(String, SpanWithSource),
21	Property {
22		on: TypeId,
23		with: PropertyKey<'static>,
24		publicity: Publicity,
25		position: SpanWithSource,
26	},
27}
28
29pub enum AssignableObjectDestructuringField<A: crate::ASTImplementation> {
30	/// `{ x: y }`
31	Mapped {
32		key: PropertyKey<'static>,
33		name: Assignable<A>,
34		default_value: Option<Box<A::Expression<'static>>>,
35		position: SpanWithSource,
36	},
37}
38
39pub struct AssignableSpread<A: crate::ASTImplementation>(
40	pub Box<Assignable<A>>,
41	pub SpanWithSource,
42);
43
44pub enum AssignableArrayDestructuringField<A: crate::ASTImplementation> {
45	Name(Assignable<A>, Option<Box<A::Expression<'static>>>),
46	Comment { content: String, is_multiline: bool, position: SpanWithSource },
47	None,
48}
49
50/// Increment and decrement are are not binary add subtract as they cast their lhs to number
51pub enum AssignmentKind {
52	Assign,
53	PureUpdate(MathematicalOrBitwiseOperation),
54	ConditionalUpdate(LogicalOperator),
55	IncrementOrDecrement(IncrementOrDecrement, AssignmentReturnStatus),
56}
57
58pub enum IncrementOrDecrement {
59	Increment,
60	Decrement,
61}
62
63/// Used for example for `++x` returns the new value, whereas `x++` returns the previous value (yay for *incredible useful and clear* semantics)
64pub enum AssignmentReturnStatus {
65	Previous,
66	New,
67}
68
69impl Reference {
70	#[must_use]
71	pub fn get_position(&self) -> SpanWithSource {
72		match self {
73			Reference::Variable(_, position) | Reference::Property { position, .. } => *position,
74		}
75	}
76
77	/// `is_empty` => for when edit in progress in playground / LSP
78	#[must_use]
79	pub fn is_empty(&self) -> bool {
80		match self {
81			Reference::Variable(name, _) => name.is_empty(),
82			Reference::Property { with, .. } => {
83				matches!(with, PropertyKey::String(n) if n.is_empty())
84			}
85		}
86	}
87
88	/// for LSP
89	#[must_use]
90	pub fn new_empty_variable_reference(position: SpanWithSource) -> Self {
91		Self::Variable(String::new(), position)
92	}
93}