| 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 |