mxmlextrema_as3parser/parser/
context.rs1use crate::ns::*;
2
3#[derive(Clone)]
5pub struct ParserExpressionContext {
6 pub min_precedence: OperatorPrecedence,
7 pub allow_in: bool,
8 pub allow_assignment: bool,
9}
10
11impl Default for ParserExpressionContext {
12 fn default() -> Self {
13 Self {
14 min_precedence: OperatorPrecedence::List,
15 allow_in: true,
16 allow_assignment: true,
17 }
18 }
19}
20
21#[derive(Clone)]
22pub enum ParserDirectiveContext {
23 Default,
24 TopLevel,
25 PackageBlock,
26 ClassBlock {
27 name: String,
28 },
29 InterfaceBlock,
30 EnumBlock,
31 ConstructorBlock {
32 super_statement_found: Rc<Cell<bool>>,
33 },
34 WithControl {
35 super_statement_found: Option<Rc<Cell<bool>>>,
36 to_be_labeled: Option<String>,
37 control_context: ParserControlFlowContext,
38 labels: HashMap<String, ParserControlFlowContext>,
39 },
40}
41
42impl ParserDirectiveContext {
43 pub fn may_contain_super_statement(&self) -> bool {
44 matches!(self, Self::ConstructorBlock { .. }) || matches!(self, Self::WithControl { .. })
45 }
46
47 pub fn super_statement_found(&self) -> bool {
48 match self {
49 Self::ConstructorBlock { super_statement_found } => super_statement_found.get(),
50 Self::WithControl { super_statement_found, .. } => super_statement_found.as_ref().or(Some(&Rc::new(Cell::new(false)))).unwrap().get(),
51 _ => false,
52 }
53 }
54
55 pub fn set_super_statement_found(&self, value: bool) {
56 match self {
57 Self::ConstructorBlock { super_statement_found } => { super_statement_found.set(value) },
58 Self::WithControl { super_statement_found, .. } => {
59 if let Some(found) = super_statement_found.as_ref() {
60 found.set(value);
61 }
62 },
63 _ => {},
64 }
65 }
66
67 pub fn function_name_is_constructor(&self, name: &(String, Location)) -> bool {
68 if let ParserDirectiveContext::ClassBlock { name: ref name_1 } = self {
69 &name.0 == name_1
70 } else {
71 false
72 }
73 }
74
75 pub fn is_top_level_or_package(&self) -> bool {
76 matches!(self, ParserDirectiveContext::TopLevel) || matches!(self, ParserDirectiveContext::PackageBlock)
77 }
78
79 pub fn is_type_block(&self) -> bool {
80 match self {
81 Self::ClassBlock { .. } |
82 Self::InterfaceBlock |
83 Self::EnumBlock => true,
84 _ => false,
85 }
86 }
87
88 pub fn clone_control(&self) -> Self {
89 match self {
90 Self::WithControl { .. } => self.clone(),
91 _ => Self::Default,
92 }
93 }
94
95 pub fn override_control_context(&self, label_only: bool, mut context: ParserControlFlowContext) -> Self {
96 let mut prev_context = None;
97 let mut label = None;
98 let mut super_statement_found: Option<Rc<Cell<bool>>> = None;
99 let mut labels = match self {
100 Self::WithControl { control_context, labels, to_be_labeled: label1, super_statement_found: super_found_1 } => {
101 prev_context = Some(control_context.clone());
102 label = label1.clone();
103 super_statement_found = super_found_1.clone();
104 labels.clone()
105 },
106 _ => HashMap::new(),
107 };
108 if let Some(label) = label.clone() {
109 labels.insert(label, context.clone());
110 }
111 if label_only {
112 context = prev_context.unwrap_or(ParserControlFlowContext {
113 breakable: false,
114 iteration: false,
115 });
116 }
117 Self::WithControl { control_context: context, labels, to_be_labeled: None, super_statement_found }
118 }
119
120 pub fn put_label(&self, label: String) -> Self {
121 match self {
122 Self::WithControl { control_context, labels, to_be_labeled: _, super_statement_found } => Self::WithControl {
123 to_be_labeled: Some(label),
124 control_context: control_context.clone(),
125 labels: labels.clone(),
126 super_statement_found: super_statement_found.clone(),
127 },
128 _ => Self::WithControl {
129 to_be_labeled: Some(label),
130 control_context: ParserControlFlowContext {
131 breakable: false,
132 iteration: false,
133 },
134 labels: HashMap::new(),
135 super_statement_found: match self {
136 Self::ConstructorBlock { super_statement_found } => Some(super_statement_found.clone()),
137 _ => None,
138 },
139 },
140 }
141 }
142
143 pub fn is_label_defined(&self, label: String) -> bool {
144 self.resolve_label(label).is_some()
145 }
146
147 pub fn resolve_label(&self, label: String) -> Option<ParserControlFlowContext> {
148 if let Self::WithControl { labels, .. } = &self { labels.get(&label).map(|c| c.clone()) } else { None }
149 }
150
151 pub fn is_break_allowed(&self, label: Option<String>) -> bool {
152 if let Some(label) = label {
153 let context = self.resolve_label(label);
154 if let Some(context) = context { context.breakable } else { false }
155 } else {
156 if let Self::WithControl { control_context, .. } = &self { control_context.breakable } else { false }
157 }
158 }
159
160 pub fn is_continue_allowed(&self, label: Option<String>) -> bool {
161 if let Some(label) = label {
162 let context = self.resolve_label(label);
163 if let Some(context) = context { context.iteration } else { false }
164 } else {
165 if let Self::WithControl { control_context, .. } = &self { control_context.iteration } else { false }
166 }
167 }
168}
169
170#[derive(Clone)]
171pub struct ParserControlFlowContext {
172 pub breakable: bool,
173 pub iteration: bool,
174}