OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_EXPRESSION_CLASSIFIER_H | 5 #ifndef V8_EXPRESSION_CLASSIFIER_H |
6 #define V8_EXPRESSION_CLASSIFIER_H | 6 #define V8_EXPRESSION_CLASSIFIER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 const Error& strong_mode_formal_parameter_error() const { | 112 const Error& strong_mode_formal_parameter_error() const { |
113 return strong_mode_formal_parameter_error_; | 113 return strong_mode_formal_parameter_error_; |
114 } | 114 } |
115 | 115 |
116 void RecordExpressionError(const Scanner::Location& loc, | 116 void RecordExpressionError(const Scanner::Location& loc, |
117 MessageTemplate::Template message, | 117 MessageTemplate::Template message, |
118 const char* arg = nullptr) { | 118 const char* arg = nullptr) { |
119 if (!is_valid_expression()) return; | 119 if (!is_valid_expression()) return; |
120 invalid_productions_ |= ExpressionProduction; | 120 invalid_productions_ |= ExpressionProduction; |
121 expression_error_.location = loc; | 121 expression_error_.location = loc; |
122 class ExpressionClassifier { | |
123 public: | |
124 struct Error { | |
125 Error() | |
126 : location(Scanner::Location::invalid()), | |
127 message(MessageTemplate::kNone), | |
128 arg(nullptr) {} | |
129 | |
130 Scanner::Location location; | |
131 MessageTemplate::Template message; | |
132 const char* arg; | |
133 | |
134 bool HasError() const { return location.IsValid(); } | |
135 }; | |
136 | |
137 ExpressionClassifier() : duplicate_finder_(nullptr) {} | |
138 | |
139 explicit ExpressionClassifier(DuplicateFinder* duplicate_finder) | |
140 : duplicate_finder_(duplicate_finder) {} | |
141 | |
142 DuplicateFinder* duplicate_finder() const { return duplicate_finder_; } | |
143 | |
144 bool is_valid_expression() const { return !expression_error_.HasError(); } | |
145 | |
146 bool is_valid_binding_pattern() const { | |
147 return !binding_pattern_error_.HasError(); | |
148 } | |
149 | |
150 bool is_valid_assignment_pattern() const { | |
151 return !assignment_pattern_error_.HasError(); | |
152 } | |
153 | |
154 bool is_valid_arrow_formal_parameters() const { | |
155 return !arrow_formal_parameters_error_.HasError(); | |
156 } | |
157 | |
158 bool is_valid_formal_parameter_list_without_duplicates() const { | |
159 return !duplicate_formal_parameter_error_.HasError(); | |
160 } | |
161 | |
162 // Note: callers should also check | |
163 // is_valid_formal_parameter_list_without_duplicates(). | |
164 bool is_valid_strict_mode_formal_parameters() const { | |
165 return !strict_mode_formal_parameter_error_.HasError(); | |
166 } | |
167 | |
168 // Note: callers should also check | |
169 // is_valid_strict_mode_formal_parameters() | |
170 // and is_valid_formal_parameter_list_without_duplicates(). | |
171 bool is_valid_strong_mode_formal_parameters() const { | |
172 return !strong_mode_formal_parameter_error_.HasError(); | |
173 } | |
174 | |
175 const Error& expression_error() const { return expression_error_; } | |
176 | |
177 const Error& binding_pattern_error() const { | |
178 return binding_pattern_error_; | |
179 } | |
180 | |
181 const Error& assignment_pattern_error() const { | |
182 return assignment_pattern_error_; | |
183 } | |
184 | |
185 const Error& arrow_formal_parameters_error() const { | |
186 return arrow_formal_parameters_error_; | |
187 } | |
188 | |
189 const Error& duplicate_formal_parameter_error() const { | |
190 return duplicate_formal_parameter_error_; | |
191 } | |
192 | |
193 const Error& strict_mode_formal_parameter_error() const { | |
194 return strict_mode_formal_parameter_error_; | |
195 } | |
196 | |
197 const Error& strong_mode_formal_parameter_error() const { | |
198 return strong_mode_formal_parameter_error_; | |
199 } | |
200 | |
201 void RecordExpressionError(const Scanner::Location& loc, | |
202 MessageTemplate::Template message, | |
203 const char* arg = nullptr) { | |
204 if (!is_valid_expression()) return; | |
205 expression_error_.location = loc; | |
206 expression_error_.message = message; | |
207 expression_error_.arg = arg; | |
208 } | |
209 | |
210 void RecordBindingPatternError(const Scanner::Location& loc, | |
211 MessageTemplate::Template message, | |
212 const char* arg = nullptr) { | |
213 if (!is_valid_binding_pattern()) return; | |
214 binding_pattern_error_.location = loc; | |
215 binding_pattern_error_.message = message; | |
216 binding_pattern_error_.arg = arg; | |
217 } | |
218 | |
219 void RecordAssignmentPatternError(const Scanner::Location& loc, | |
220 MessageTemplate::Template message, | |
221 const char* arg = nullptr) { | |
222 if (!is_valid_assignment_pattern()) return; | |
223 assignment_pattern_error_.location = loc; | |
224 assignment_pattern_error_.message = message; | |
225 assignment_pattern_error_.arg = arg; | |
226 } | |
227 | |
228 void RecordArrowFormalParametersError(const Scanner::Location& loc, | |
229 MessageTemplate::Template message, | |
230 const char* arg = nullptr) { | |
231 if (!is_valid_arrow_formal_parameters()) return; | |
232 arrow_formal_parameters_error_.location = loc; | |
233 arrow_formal_parameters_error_.message = message; | |
234 arrow_formal_parameters_error_.arg = arg; | |
235 } | |
236 | |
237 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { | |
238 if (!is_valid_formal_parameter_list_without_duplicates()) return; | |
239 duplicate_formal_parameter_error_.location = loc; | |
240 duplicate_formal_parameter_error_.message = | |
241 MessageTemplate::kStrictParamDupe; | |
242 duplicate_formal_parameter_error_.arg = nullptr; | |
243 } | |
244 | |
245 // Record a binding that would be invalid in strict mode. Confusingly | |
246 // this | |
247 // is not the same as StrictFormalParameterList, which simply forbids | |
248 // duplicate bindings. | |
249 void RecordStrictModeFormalParameterError( | |
250 const Scanner::Location& loc, MessageTemplate::Template message, | |
251 const char* arg = nullptr) { | |
252 if (!is_valid_strict_mode_formal_parameters()) return; | |
253 strict_mode_formal_parameter_error_.location = loc; | |
254 strict_mode_formal_parameter_error_.message = message; | |
255 strict_mode_formal_parameter_error_.arg = arg; | |
256 } | |
257 | |
258 void RecordStrongModeFormalParameterError( | |
259 const Scanner::Location& loc, MessageTemplate::Template message, | |
260 const char* arg = nullptr) { | |
261 if (!is_valid_strong_mode_formal_parameters()) return; | |
262 strong_mode_formal_parameter_error_.location = loc; | |
263 strong_mode_formal_parameter_error_.message = message; | |
264 strong_mode_formal_parameter_error_.arg = arg; | |
265 } | |
266 | |
267 enum TargetProduction { | |
268 ExpressionProduction = 1 << 0, | |
269 BindingPatternProduction = 1 << 1, | |
270 AssignmentPatternProduction = 1 << 2, | |
271 FormalParametersProduction = 1 << 3, | |
272 ArrowFormalParametersProduction = 1 << 4, | |
273 StandardProductions = (ExpressionProduction | BindingPatternProduction | | |
274 AssignmentPatternProduction), | |
275 PatternProductions = | |
276 BindingPatternProduction | AssignmentPatternProduction, | |
277 AllProductions = (StandardProductions | FormalParametersProduction | | |
278 ArrowFormalParametersProduction), | |
279 }; | |
280 | |
281 void Accumulate(const ExpressionClassifier& inner, | |
282 unsigned productions = StandardProductions) { | |
283 if (productions & ExpressionProduction && is_valid_expression()) { | |
284 expression_error_ = inner.expression_error_; | |
285 } | |
286 if (productions & BindingPatternProduction && | |
287 is_valid_binding_pattern()) { | |
288 binding_pattern_error_ = inner.binding_pattern_error_; | |
289 } | |
290 if (productions & AssignmentPatternProduction && | |
291 is_valid_assignment_pattern()) { | |
292 assignment_pattern_error_ = inner.assignment_pattern_error_; | |
293 } | |
294 if (productions & FormalParametersProduction) { | |
295 if (is_valid_formal_parameter_list_without_duplicates()) { | |
296 duplicate_formal_parameter_error_ = | |
297 inner.duplicate_formal_parameter_error_; | |
298 } | |
299 if (is_valid_strict_mode_formal_parameters()) { | |
300 strict_mode_formal_parameter_error_ = | |
301 inner.strict_mode_formal_parameter_error_; | |
302 } | |
303 if (is_valid_strong_mode_formal_parameters()) { | |
304 strong_mode_formal_parameter_error_ = | |
305 inner.strong_mode_formal_parameter_error_; | |
306 } | |
307 } | |
308 if (productions & ArrowFormalParametersProduction && | |
309 is_valid_arrow_formal_parameters()) { | |
310 // The result continues to be a valid arrow formal parameters if the | |
311 // inner expression is a valid binding pattern. | |
312 arrow_formal_parameters_error_ = inner.binding_pattern_error_; | |
313 } | |
314 } | |
315 | |
316 void AccumulateReclassifyingAsPattern(const ExpressionClassifier& inner) { | |
317 Accumulate(inner, AllProductions & ~PatternProductions); | |
318 if (!inner.is_valid_expression()) { | |
319 if (is_valid_binding_pattern()) { | |
320 binding_pattern_error_ = inner.expression_error(); | |
321 } | |
322 if (is_valid_assignment_pattern()) { | |
323 assignment_pattern_error_ = inner.expression_error(); | |
324 } | |
325 } | |
326 } | |
327 | |
328 private: | |
329 Error expression_error_; | |
330 Error binding_pattern_error_; | |
331 Error assignment_pattern_error_; | |
332 Error arrow_formal_parameters_error_; | |
333 Error duplicate_formal_parameter_error_; | |
334 Error strict_mode_formal_parameter_error_; | |
335 Error strong_mode_formal_parameter_error_; | |
336 DuplicateFinder* duplicate_finder_; | |
337 }; | |
338 expression_error_.message = message; | 122 expression_error_.message = message; |
339 expression_error_.arg = arg; | 123 expression_error_.arg = arg; |
340 } | 124 } |
341 | 125 |
342 void RecordBindingPatternError(const Scanner::Location& loc, | 126 void RecordBindingPatternError(const Scanner::Location& loc, |
343 MessageTemplate::Template message, | 127 MessageTemplate::Template message, |
344 const char* arg = nullptr) { | 128 const char* arg = nullptr) { |
345 if (!is_valid_binding_pattern()) return; | 129 if (!is_valid_binding_pattern()) return; |
346 invalid_productions_ |= BindingPatternProduction; | 130 invalid_productions_ |= BindingPatternProduction; |
347 binding_pattern_error_.location = loc; | 131 binding_pattern_error_.location = loc; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 Error arrow_formal_parameters_error_; | 246 Error arrow_formal_parameters_error_; |
463 Error duplicate_formal_parameter_error_; | 247 Error duplicate_formal_parameter_error_; |
464 Error strict_mode_formal_parameter_error_; | 248 Error strict_mode_formal_parameter_error_; |
465 Error strong_mode_formal_parameter_error_; | 249 Error strong_mode_formal_parameter_error_; |
466 DuplicateFinder* duplicate_finder_; | 250 DuplicateFinder* duplicate_finder_; |
467 }; | 251 }; |
468 } | 252 } |
469 } // v8::internal | 253 } // v8::internal |
470 | 254 |
471 #endif // V8_EXPRESSION_CLASSIFIER_H | 255 #endif // V8_EXPRESSION_CLASSIFIER_H |
OLD | NEW |