Chromium Code Reviews| 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_PARSING_EXPRESSION_CLASSIFIER_H | 5 #ifndef V8_PARSING_EXPRESSION_CLASSIFIER_H |
| 6 #define V8_PARSING_EXPRESSION_CLASSIFIER_H | 6 #define V8_PARSING_EXPRESSION_CLASSIFIER_H |
| 7 | 7 |
| 8 #include "src/messages.h" | 8 #include "src/messages.h" |
| 9 #include "src/parsing/scanner.h" | 9 #include "src/parsing/scanner.h" |
| 10 #include "src/parsing/token.h" | 10 #include "src/parsing/token.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 | 14 |
| 15 | 15 |
| 16 #define ERROR_CODES(T) \ | |
| 17 T(ExpressionProduction, 0) \ | |
| 18 T(FormalParameterInitializerProduction, 1) \ | |
| 19 T(BindingPatternProduction, 2) \ | |
| 20 T(AssignmentPatternProduction, 3) \ | |
| 21 T(DistinctFormalParametersProduction, 4) \ | |
| 22 T(StrictModeFormalParametersProduction, 5) \ | |
| 23 T(StrongModeFormalParametersProduction, 6) \ | |
|
caitp (gmail)
2016/02/18 16:50:22
I feel like we could probably just take this oppor
nickie
2016/02/19 08:56:31
I assumed strong mode removal would be an independ
| |
| 24 T(ArrowFormalParametersProduction, 7) \ | |
| 25 T(LetPatternProduction, 8) \ | |
| 26 T(CoverInitializedNameProduction, 9) | |
| 27 | |
| 28 | |
| 16 template <typename Traits> | 29 template <typename Traits> |
| 17 class ExpressionClassifier { | 30 class ExpressionClassifier { |
| 18 public: | 31 public: |
| 32 enum ErrorKind : unsigned { | |
| 33 #define DEFINE_ERROR_KIND(NAME, CODE) k##NAME = CODE, | |
| 34 ERROR_CODES(DEFINE_ERROR_KIND) | |
| 35 #undef DEFINE_ERROR_KIND | |
| 36 kUnusedError = 15 // Larger than error codes; should fit in 4 bits | |
| 37 }; | |
| 38 | |
| 19 struct Error { | 39 struct Error { |
| 20 Error() | 40 V8_INLINE Error() |
| 21 : location(Scanner::Location::invalid()), | 41 : location(Scanner::Location::invalid()), |
| 22 message(MessageTemplate::kNone), | 42 message(MessageTemplate::kNone), |
| 43 kind(kUnusedError), | |
| 23 type(kSyntaxError), | 44 type(kSyntaxError), |
| 24 arg(nullptr) {} | 45 arg(nullptr) {} |
| 46 V8_INLINE explicit Error(Scanner::Location loc, | |
| 47 MessageTemplate::Template msg, ErrorKind k, | |
| 48 const char* a = nullptr, | |
| 49 ParseErrorType t = kSyntaxError) | |
| 50 : location(loc), message(msg), kind(k), type(t), arg(a) {} | |
| 25 | 51 |
| 26 Scanner::Location location; | 52 Scanner::Location location; |
| 27 MessageTemplate::Template message : 30; | 53 MessageTemplate::Template message : 26; |
| 54 ErrorKind kind : 4; | |
| 28 ParseErrorType type : 2; | 55 ParseErrorType type : 2; |
| 29 const char* arg; | 56 const char* arg; |
| 30 }; | 57 }; |
| 31 | 58 |
| 32 enum TargetProduction { | 59 enum TargetProduction : unsigned { |
| 33 ExpressionProduction = 1 << 0, | 60 #define DEFINE_PRODUCTION(NAME, CODE) NAME = 1 << CODE, |
| 34 FormalParameterInitializerProduction = 1 << 1, | 61 ERROR_CODES(DEFINE_PRODUCTION) |
| 35 BindingPatternProduction = 1 << 2, | 62 #undef DEFINE_PRODUCTION |
| 36 AssignmentPatternProduction = 1 << 3, | |
| 37 DistinctFormalParametersProduction = 1 << 4, | |
| 38 StrictModeFormalParametersProduction = 1 << 5, | |
| 39 StrongModeFormalParametersProduction = 1 << 6, | |
| 40 ArrowFormalParametersProduction = 1 << 7, | |
| 41 LetPatternProduction = 1 << 8, | |
| 42 CoverInitializedNameProduction = 1 << 9, | |
| 43 | 63 |
| 44 ExpressionProductions = | 64 ExpressionProductions = |
| 45 (ExpressionProduction | FormalParameterInitializerProduction), | 65 (ExpressionProduction | FormalParameterInitializerProduction), |
| 46 PatternProductions = (BindingPatternProduction | | 66 PatternProductions = (BindingPatternProduction | |
| 47 AssignmentPatternProduction | LetPatternProduction), | 67 AssignmentPatternProduction | LetPatternProduction), |
| 48 FormalParametersProductions = (DistinctFormalParametersProduction | | 68 FormalParametersProductions = (DistinctFormalParametersProduction | |
| 49 StrictModeFormalParametersProduction | | 69 StrictModeFormalParametersProduction | |
| 50 StrongModeFormalParametersProduction), | 70 StrongModeFormalParametersProduction), |
| 51 StandardProductions = ExpressionProductions | PatternProductions, | 71 StandardProductions = ExpressionProductions | PatternProductions, |
| 52 AllProductions = | 72 AllProductions = |
| 53 (StandardProductions | FormalParametersProductions | | 73 (StandardProductions | FormalParametersProductions | |
| 54 ArrowFormalParametersProduction | CoverInitializedNameProduction) | 74 ArrowFormalParametersProduction | CoverInitializedNameProduction) |
| 55 }; | 75 }; |
| 56 | 76 |
| 57 enum FunctionProperties { NonSimpleParameter = 1 << 0 }; | 77 enum FunctionProperties : unsigned { |
| 78 NonSimpleParameter = 1 << 0 | |
| 79 }; | |
| 58 | 80 |
| 59 explicit ExpressionClassifier(const Traits* t) | 81 explicit ExpressionClassifier(const Traits* t) |
| 60 : zone_(t->zone()), | 82 : zone_(t->zone()), |
| 61 non_patterns_to_rewrite_(t->GetNonPatternList()), | 83 non_patterns_to_rewrite_(t->GetNonPatternList()), |
| 62 invalid_productions_(0), | 84 invalid_productions_(0), |
| 63 function_properties_(0), | 85 function_properties_(0), |
| 86 reported_errors_(t->GetReportedErrorList()), | |
| 64 duplicate_finder_(nullptr) { | 87 duplicate_finder_(nullptr) { |
| 88 reported_errors_begin_ = reported_errors_end_ = reported_errors_->length(); | |
| 65 non_pattern_begin_ = non_patterns_to_rewrite_->length(); | 89 non_pattern_begin_ = non_patterns_to_rewrite_->length(); |
| 66 } | 90 } |
| 67 | 91 |
| 68 ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder) | 92 ExpressionClassifier(const Traits* t, DuplicateFinder* duplicate_finder) |
| 69 : zone_(t->zone()), | 93 : zone_(t->zone()), |
| 70 non_patterns_to_rewrite_(t->GetNonPatternList()), | 94 non_patterns_to_rewrite_(t->GetNonPatternList()), |
| 71 invalid_productions_(0), | 95 invalid_productions_(0), |
| 72 function_properties_(0), | 96 function_properties_(0), |
| 97 reported_errors_(t->GetReportedErrorList()), | |
| 73 duplicate_finder_(duplicate_finder) { | 98 duplicate_finder_(duplicate_finder) { |
| 99 reported_errors_begin_ = reported_errors_end_ = reported_errors_->length(); | |
| 74 non_pattern_begin_ = non_patterns_to_rewrite_->length(); | 100 non_pattern_begin_ = non_patterns_to_rewrite_->length(); |
| 75 } | 101 } |
| 76 | 102 |
| 77 ~ExpressionClassifier() { Discard(); } | 103 ~ExpressionClassifier() { Discard(); } |
| 78 | 104 |
| 79 bool is_valid(unsigned productions) const { | 105 V8_INLINE bool is_valid(unsigned productions) const { |
| 80 return (invalid_productions_ & productions) == 0; | 106 return (invalid_productions_ & productions) == 0; |
| 81 } | 107 } |
| 82 | 108 |
| 83 DuplicateFinder* duplicate_finder() const { return duplicate_finder_; } | 109 V8_INLINE DuplicateFinder* duplicate_finder() const { |
| 110 return duplicate_finder_; | |
| 111 } | |
| 84 | 112 |
| 85 bool is_valid_expression() const { return is_valid(ExpressionProduction); } | 113 V8_INLINE bool is_valid_expression() const { |
| 114 return is_valid(ExpressionProduction); | |
| 115 } | |
| 86 | 116 |
| 87 bool is_valid_formal_parameter_initializer() const { | 117 V8_INLINE bool is_valid_formal_parameter_initializer() const { |
| 88 return is_valid(FormalParameterInitializerProduction); | 118 return is_valid(FormalParameterInitializerProduction); |
| 89 } | 119 } |
| 90 | 120 |
| 91 bool is_valid_binding_pattern() const { | 121 V8_INLINE bool is_valid_binding_pattern() const { |
| 92 return is_valid(BindingPatternProduction); | 122 return is_valid(BindingPatternProduction); |
| 93 } | 123 } |
| 94 | 124 |
| 95 bool is_valid_assignment_pattern() const { | 125 V8_INLINE bool is_valid_assignment_pattern() const { |
| 96 return is_valid(AssignmentPatternProduction); | 126 return is_valid(AssignmentPatternProduction); |
| 97 } | 127 } |
| 98 | 128 |
| 99 bool is_valid_arrow_formal_parameters() const { | 129 V8_INLINE bool is_valid_arrow_formal_parameters() const { |
| 100 return is_valid(ArrowFormalParametersProduction); | 130 return is_valid(ArrowFormalParametersProduction); |
| 101 } | 131 } |
| 102 | 132 |
| 103 bool is_valid_formal_parameter_list_without_duplicates() const { | 133 V8_INLINE bool is_valid_formal_parameter_list_without_duplicates() const { |
| 104 return is_valid(DistinctFormalParametersProduction); | 134 return is_valid(DistinctFormalParametersProduction); |
| 105 } | 135 } |
| 106 | 136 |
| 107 // Note: callers should also check | 137 // Note: callers should also check |
| 108 // is_valid_formal_parameter_list_without_duplicates(). | 138 // is_valid_formal_parameter_list_without_duplicates(). |
| 109 bool is_valid_strict_mode_formal_parameters() const { | 139 V8_INLINE bool is_valid_strict_mode_formal_parameters() const { |
| 110 return is_valid(StrictModeFormalParametersProduction); | 140 return is_valid(StrictModeFormalParametersProduction); |
| 111 } | 141 } |
| 112 | 142 |
| 113 // Note: callers should also check is_valid_strict_mode_formal_parameters() | 143 // Note: callers should also check is_valid_strict_mode_formal_parameters() |
| 114 // and is_valid_formal_parameter_list_without_duplicates(). | 144 // and is_valid_formal_parameter_list_without_duplicates(). |
| 115 bool is_valid_strong_mode_formal_parameters() const { | 145 V8_INLINE bool is_valid_strong_mode_formal_parameters() const { |
| 116 return is_valid(StrongModeFormalParametersProduction); | 146 return is_valid(StrongModeFormalParametersProduction); |
| 117 } | 147 } |
| 118 | 148 |
| 119 bool is_valid_let_pattern() const { return is_valid(LetPatternProduction); } | 149 V8_INLINE bool is_valid_let_pattern() const { |
| 120 | 150 return is_valid(LetPatternProduction); |
| 121 const Error& expression_error() const { return expression_error_; } | |
| 122 | |
| 123 const Error& formal_parameter_initializer_error() const { | |
| 124 return formal_parameter_initializer_error_; | |
| 125 } | 151 } |
| 126 | 152 |
| 127 const Error& binding_pattern_error() const { return binding_pattern_error_; } | 153 V8_INLINE const Error& expression_error() const { |
| 128 | 154 return reported_error(kExpressionProduction); |
| 129 const Error& assignment_pattern_error() const { | |
| 130 return assignment_pattern_error_; | |
| 131 } | 155 } |
| 132 | 156 |
| 133 const Error& arrow_formal_parameters_error() const { | 157 V8_INLINE const Error& formal_parameter_initializer_error() const { |
| 134 return arrow_formal_parameters_error_; | 158 return reported_error(kFormalParameterInitializerProduction); |
| 135 } | 159 } |
| 136 | 160 |
| 137 const Error& duplicate_formal_parameter_error() const { | 161 V8_INLINE const Error& binding_pattern_error() const { |
|
caitp (gmail)
2016/02/18 16:57:47
maybe if you added like a `accessor_name` paramete
nickie
2016/02/19 08:56:31
While the error codes and the bit flags are named
| |
| 138 return duplicate_formal_parameter_error_; | 162 return reported_error(kBindingPatternProduction); |
| 139 } | 163 } |
| 140 | 164 |
| 141 const Error& strict_mode_formal_parameter_error() const { | 165 V8_INLINE const Error& assignment_pattern_error() const { |
| 142 return strict_mode_formal_parameter_error_; | 166 return reported_error(kAssignmentPatternProduction); |
| 143 } | 167 } |
| 144 | 168 |
| 145 const Error& strong_mode_formal_parameter_error() const { | 169 V8_INLINE const Error& arrow_formal_parameters_error() const { |
| 146 return strong_mode_formal_parameter_error_; | 170 return reported_error(kArrowFormalParametersProduction); |
| 147 } | 171 } |
| 148 | 172 |
| 149 const Error& let_pattern_error() const { return let_pattern_error_; } | 173 V8_INLINE const Error& duplicate_formal_parameter_error() const { |
| 174 return reported_error(kDistinctFormalParametersProduction); | |
| 175 } | |
| 150 | 176 |
| 151 bool has_cover_initialized_name() const { | 177 V8_INLINE const Error& strict_mode_formal_parameter_error() const { |
| 178 return reported_error(kStrictModeFormalParametersProduction); | |
| 179 } | |
| 180 | |
| 181 V8_INLINE const Error& strong_mode_formal_parameter_error() const { | |
| 182 return reported_error(kStrongModeFormalParametersProduction); | |
| 183 } | |
| 184 | |
| 185 V8_INLINE const Error& let_pattern_error() const { | |
| 186 return reported_error(kLetPatternProduction); | |
| 187 } | |
| 188 | |
| 189 V8_INLINE bool has_cover_initialized_name() const { | |
| 152 return !is_valid(CoverInitializedNameProduction); | 190 return !is_valid(CoverInitializedNameProduction); |
| 153 } | 191 } |
| 154 const Error& cover_initialized_name_error() const { | 192 |
| 155 return cover_initialized_name_error_; | 193 V8_INLINE const Error& cover_initialized_name_error() const { |
| 194 return reported_error(kCoverInitializedNameProduction); | |
| 156 } | 195 } |
| 157 | 196 |
| 158 bool is_simple_parameter_list() const { | 197 V8_INLINE bool is_simple_parameter_list() const { |
| 159 return !(function_properties_ & NonSimpleParameter); | 198 return !(function_properties_ & NonSimpleParameter); |
| 160 } | 199 } |
| 161 | 200 |
| 162 void RecordNonSimpleParameter() { | 201 V8_INLINE void RecordNonSimpleParameter() { |
| 163 function_properties_ |= NonSimpleParameter; | 202 function_properties_ |= NonSimpleParameter; |
| 164 } | 203 } |
| 165 | 204 |
| 166 void RecordExpressionError(const Scanner::Location& loc, | 205 void RecordExpressionError(const Scanner::Location& loc, |
| 167 MessageTemplate::Template message, | 206 MessageTemplate::Template message, |
| 168 const char* arg = nullptr) { | 207 const char* arg = nullptr) { |
| 169 if (!is_valid_expression()) return; | 208 if (!is_valid_expression()) return; |
| 170 invalid_productions_ |= ExpressionProduction; | 209 invalid_productions_ |= ExpressionProduction; |
| 171 expression_error_.location = loc; | 210 Add(Error(loc, message, kExpressionProduction, arg)); |
| 172 expression_error_.message = message; | |
| 173 expression_error_.arg = arg; | |
| 174 } | 211 } |
| 175 | 212 |
| 176 void RecordExpressionError(const Scanner::Location& loc, | 213 void RecordExpressionError(const Scanner::Location& loc, |
| 177 MessageTemplate::Template message, | 214 MessageTemplate::Template message, |
| 178 ParseErrorType type, const char* arg = nullptr) { | 215 ParseErrorType type, const char* arg = nullptr) { |
| 179 if (!is_valid_expression()) return; | 216 if (!is_valid_expression()) return; |
| 180 invalid_productions_ |= ExpressionProduction; | 217 invalid_productions_ |= ExpressionProduction; |
| 181 expression_error_.location = loc; | 218 Add(Error(loc, message, kExpressionProduction, arg, type)); |
| 182 expression_error_.message = message; | |
| 183 expression_error_.arg = arg; | |
| 184 expression_error_.type = type; | |
| 185 } | 219 } |
| 186 | 220 |
| 187 void RecordFormalParameterInitializerError(const Scanner::Location& loc, | 221 void RecordFormalParameterInitializerError(const Scanner::Location& loc, |
| 188 MessageTemplate::Template message, | 222 MessageTemplate::Template message, |
| 189 const char* arg = nullptr) { | 223 const char* arg = nullptr) { |
| 190 if (!is_valid_formal_parameter_initializer()) return; | 224 if (!is_valid_formal_parameter_initializer()) return; |
| 191 invalid_productions_ |= FormalParameterInitializerProduction; | 225 invalid_productions_ |= FormalParameterInitializerProduction; |
| 192 formal_parameter_initializer_error_.location = loc; | 226 Add(Error(loc, message, kFormalParameterInitializerProduction, arg)); |
| 193 formal_parameter_initializer_error_.message = message; | 227 } |
| 194 formal_parameter_initializer_error_.arg = arg; | 228 |
| 229 static Error BindingPatternError(const Scanner::Location& loc, | |
| 230 MessageTemplate::Template message, | |
| 231 const char* arg = nullptr) { | |
| 232 return Error(loc, message, kBindingPatternProduction, arg); | |
| 233 } | |
| 234 | |
| 235 void RecordBindingPatternError(const Error& e) { | |
| 236 if (!is_valid_binding_pattern()) return; | |
| 237 invalid_productions_ |= BindingPatternProduction; | |
| 238 Add(e); | |
| 195 } | 239 } |
| 196 | 240 |
| 197 void RecordBindingPatternError(const Scanner::Location& loc, | 241 void RecordBindingPatternError(const Scanner::Location& loc, |
| 198 MessageTemplate::Template message, | 242 MessageTemplate::Template message, |
| 199 const char* arg = nullptr) { | 243 const char* arg = nullptr) { |
| 200 if (!is_valid_binding_pattern()) return; | 244 RecordBindingPatternError(BindingPatternError(loc, message, arg)); |
| 201 invalid_productions_ |= BindingPatternProduction; | 245 } |
| 202 binding_pattern_error_.location = loc; | 246 |
| 203 binding_pattern_error_.message = message; | 247 static Error AssignmentPatternError(const Scanner::Location& loc, |
| 204 binding_pattern_error_.arg = arg; | 248 MessageTemplate::Template message, |
| 249 const char* arg = nullptr) { | |
| 250 return Error(loc, message, kAssignmentPatternProduction, arg); | |
| 251 } | |
| 252 | |
| 253 void RecordAssignmentPatternError(const Error& e) { | |
| 254 if (!is_valid_assignment_pattern()) return; | |
| 255 invalid_productions_ |= AssignmentPatternProduction; | |
| 256 Add(e); | |
| 205 } | 257 } |
| 206 | 258 |
| 207 void RecordAssignmentPatternError(const Scanner::Location& loc, | 259 void RecordAssignmentPatternError(const Scanner::Location& loc, |
| 208 MessageTemplate::Template message, | 260 MessageTemplate::Template message, |
| 209 const char* arg = nullptr) { | 261 const char* arg = nullptr) { |
| 210 if (!is_valid_assignment_pattern()) return; | 262 RecordAssignmentPatternError(AssignmentPatternError(loc, message, arg)); |
| 211 invalid_productions_ |= AssignmentPatternProduction; | |
| 212 assignment_pattern_error_.location = loc; | |
| 213 assignment_pattern_error_.message = message; | |
| 214 assignment_pattern_error_.arg = arg; | |
| 215 } | 263 } |
| 216 | 264 |
| 217 void RecordPatternError(const Scanner::Location& loc, | 265 void RecordPatternError(const Scanner::Location& loc, |
| 218 MessageTemplate::Template message, | 266 MessageTemplate::Template message, |
| 219 const char* arg = nullptr) { | 267 const char* arg = nullptr) { |
| 220 RecordBindingPatternError(loc, message, arg); | 268 RecordBindingPatternError(loc, message, arg); |
| 221 RecordAssignmentPatternError(loc, message, arg); | 269 RecordAssignmentPatternError(loc, message, arg); |
| 222 } | 270 } |
| 223 | 271 |
| 224 void RecordArrowFormalParametersError(const Scanner::Location& loc, | 272 void RecordArrowFormalParametersError(const Scanner::Location& loc, |
| 225 MessageTemplate::Template message, | 273 MessageTemplate::Template message, |
| 226 const char* arg = nullptr) { | 274 const char* arg = nullptr) { |
| 227 if (!is_valid_arrow_formal_parameters()) return; | 275 if (!is_valid_arrow_formal_parameters()) return; |
| 228 invalid_productions_ |= ArrowFormalParametersProduction; | 276 invalid_productions_ |= ArrowFormalParametersProduction; |
| 229 arrow_formal_parameters_error_.location = loc; | 277 Add(Error(loc, message, kArrowFormalParametersProduction, arg)); |
| 230 arrow_formal_parameters_error_.message = message; | |
| 231 arrow_formal_parameters_error_.arg = arg; | |
| 232 } | 278 } |
| 233 | 279 |
| 234 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { | 280 void RecordDuplicateFormalParameterError(const Scanner::Location& loc) { |
| 235 if (!is_valid_formal_parameter_list_without_duplicates()) return; | 281 if (!is_valid_formal_parameter_list_without_duplicates()) return; |
| 236 invalid_productions_ |= DistinctFormalParametersProduction; | 282 invalid_productions_ |= DistinctFormalParametersProduction; |
| 237 duplicate_formal_parameter_error_.location = loc; | 283 Add(Error(loc, MessageTemplate::kParamDupe, |
| 238 duplicate_formal_parameter_error_.message = MessageTemplate::kParamDupe; | 284 kDistinctFormalParametersProduction)); |
| 239 duplicate_formal_parameter_error_.arg = nullptr; | |
| 240 } | 285 } |
| 241 | 286 |
| 242 // Record a binding that would be invalid in strict mode. Confusingly this | 287 // Record a binding that would be invalid in strict mode. Confusingly this |
| 243 // is not the same as StrictFormalParameterList, which simply forbids | 288 // is not the same as StrictFormalParameterList, which simply forbids |
| 244 // duplicate bindings. | 289 // duplicate bindings. |
| 245 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, | 290 void RecordStrictModeFormalParameterError(const Scanner::Location& loc, |
| 246 MessageTemplate::Template message, | 291 MessageTemplate::Template message, |
| 247 const char* arg = nullptr) { | 292 const char* arg = nullptr) { |
| 248 if (!is_valid_strict_mode_formal_parameters()) return; | 293 if (!is_valid_strict_mode_formal_parameters()) return; |
| 249 invalid_productions_ |= StrictModeFormalParametersProduction; | 294 invalid_productions_ |= StrictModeFormalParametersProduction; |
| 250 strict_mode_formal_parameter_error_.location = loc; | 295 Add(Error(loc, message, kStrictModeFormalParametersProduction, arg)); |
| 251 strict_mode_formal_parameter_error_.message = message; | |
| 252 strict_mode_formal_parameter_error_.arg = arg; | |
| 253 } | 296 } |
| 254 | 297 |
| 255 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, | 298 void RecordStrongModeFormalParameterError(const Scanner::Location& loc, |
| 256 MessageTemplate::Template message, | 299 MessageTemplate::Template message, |
| 257 const char* arg = nullptr) { | 300 const char* arg = nullptr) { |
| 258 if (!is_valid_strong_mode_formal_parameters()) return; | 301 if (!is_valid_strong_mode_formal_parameters()) return; |
| 259 invalid_productions_ |= StrongModeFormalParametersProduction; | 302 invalid_productions_ |= StrongModeFormalParametersProduction; |
| 260 strong_mode_formal_parameter_error_.location = loc; | 303 Add(Error(loc, message, kStrongModeFormalParametersProduction, arg)); |
| 261 strong_mode_formal_parameter_error_.message = message; | |
| 262 strong_mode_formal_parameter_error_.arg = arg; | |
| 263 } | 304 } |
| 264 | 305 |
| 265 void RecordLetPatternError(const Scanner::Location& loc, | 306 void RecordLetPatternError(const Scanner::Location& loc, |
| 266 MessageTemplate::Template message, | 307 MessageTemplate::Template message, |
| 267 const char* arg = nullptr) { | 308 const char* arg = nullptr) { |
| 268 if (!is_valid_let_pattern()) return; | 309 if (!is_valid_let_pattern()) return; |
| 269 invalid_productions_ |= LetPatternProduction; | 310 invalid_productions_ |= LetPatternProduction; |
| 270 let_pattern_error_.location = loc; | 311 Add(Error(loc, message, kLetPatternProduction, arg)); |
| 271 let_pattern_error_.message = message; | |
| 272 let_pattern_error_.arg = arg; | |
| 273 } | 312 } |
| 274 | 313 |
| 275 void RecordCoverInitializedNameError(const Scanner::Location& loc, | 314 void RecordCoverInitializedNameError(const Scanner::Location& loc, |
| 276 MessageTemplate::Template message, | 315 MessageTemplate::Template message, |
| 277 const char* arg = nullptr) { | 316 const char* arg = nullptr) { |
| 278 if (has_cover_initialized_name()) return; | 317 if (has_cover_initialized_name()) return; |
| 279 invalid_productions_ |= CoverInitializedNameProduction; | 318 invalid_productions_ |= CoverInitializedNameProduction; |
| 280 cover_initialized_name_error_.location = loc; | 319 Add(Error(loc, message, kCoverInitializedNameProduction, arg)); |
| 281 cover_initialized_name_error_.message = message; | |
| 282 cover_initialized_name_error_.arg = arg; | |
| 283 } | 320 } |
| 284 | 321 |
| 285 void ForgiveCoverInitializedNameError() { | 322 void ForgiveCoverInitializedNameError() { |
| 323 if (!(invalid_productions_ & CoverInitializedNameProduction)) return; | |
| 286 invalid_productions_ &= ~CoverInitializedNameProduction; | 324 invalid_productions_ &= ~CoverInitializedNameProduction; |
| 287 cover_initialized_name_error_ = Error(); | 325 Error& e = reported_error(kCoverInitializedNameProduction); |
| 326 e.kind = kUnusedError; | |
| 288 } | 327 } |
| 289 | 328 |
| 290 void ForgiveAssignmentPatternError() { | 329 void ForgiveAssignmentPatternError() { |
| 330 if (!(invalid_productions_ & AssignmentPatternProduction)) return; | |
| 291 invalid_productions_ &= ~AssignmentPatternProduction; | 331 invalid_productions_ &= ~AssignmentPatternProduction; |
| 292 assignment_pattern_error_ = Error(); | 332 Error& e = reported_error(kAssignmentPatternProduction); |
| 333 e.kind = kUnusedError; | |
| 293 } | 334 } |
| 294 | 335 |
| 295 void Accumulate(ExpressionClassifier* inner, | 336 void Accumulate(ExpressionClassifier* inner, |
| 296 unsigned productions = StandardProductions, | 337 unsigned productions = StandardProductions, |
| 297 bool merge_non_patterns = true) { | 338 bool merge_non_patterns = true) { |
| 339 DCHECK_EQ(inner->reported_errors_, reported_errors_); | |
| 340 DCHECK_EQ(inner->reported_errors_begin_, reported_errors_end_); | |
| 341 DCHECK_EQ(inner->reported_errors_end_, reported_errors_->length()); | |
| 298 if (merge_non_patterns) MergeNonPatterns(inner); | 342 if (merge_non_patterns) MergeNonPatterns(inner); |
| 299 // Propagate errors from inner, but don't overwrite already recorded | 343 // Propagate errors from inner, but don't overwrite already recorded |
| 300 // errors. | 344 // errors. |
| 301 unsigned non_arrow_inner_invalid_productions = | 345 unsigned non_arrow_inner_invalid_productions = |
| 302 inner->invalid_productions_ & ~ArrowFormalParametersProduction; | 346 inner->invalid_productions_ & ~ArrowFormalParametersProduction; |
| 303 if (non_arrow_inner_invalid_productions == 0) return; | 347 int next = inner->reported_errors_begin_; |
| 304 unsigned non_arrow_productions = | 348 if (non_arrow_inner_invalid_productions) { |
| 305 productions & ~ArrowFormalParametersProduction; | 349 unsigned non_arrow_productions = |
| 306 unsigned errors = | 350 productions & ~ArrowFormalParametersProduction; |
| 307 non_arrow_productions & non_arrow_inner_invalid_productions; | 351 unsigned errors = |
| 308 errors &= ~invalid_productions_; | 352 non_arrow_productions & non_arrow_inner_invalid_productions; |
| 309 if (errors != 0) { | 353 errors &= ~invalid_productions_; |
| 310 invalid_productions_ |= errors; | |
| 311 if (errors & ExpressionProduction) | |
| 312 expression_error_ = inner->expression_error_; | |
| 313 if (errors & FormalParameterInitializerProduction) | |
| 314 formal_parameter_initializer_error_ = | |
| 315 inner->formal_parameter_initializer_error_; | |
| 316 if (errors & BindingPatternProduction) | |
| 317 binding_pattern_error_ = inner->binding_pattern_error_; | |
| 318 if (errors & AssignmentPatternProduction) | |
| 319 assignment_pattern_error_ = inner->assignment_pattern_error_; | |
| 320 if (errors & DistinctFormalParametersProduction) | |
| 321 duplicate_formal_parameter_error_ = | |
| 322 inner->duplicate_formal_parameter_error_; | |
| 323 if (errors & StrictModeFormalParametersProduction) | |
| 324 strict_mode_formal_parameter_error_ = | |
| 325 inner->strict_mode_formal_parameter_error_; | |
| 326 if (errors & StrongModeFormalParametersProduction) | |
| 327 strong_mode_formal_parameter_error_ = | |
| 328 inner->strong_mode_formal_parameter_error_; | |
| 329 if (errors & LetPatternProduction) | |
| 330 let_pattern_error_ = inner->let_pattern_error_; | |
| 331 if (errors & CoverInitializedNameProduction) | |
| 332 cover_initialized_name_error_ = inner->cover_initialized_name_error_; | |
| 333 } | |
| 334 | 354 |
| 335 // As an exception to the above, the result continues to be a valid arrow | 355 // As an exception to the above, the result continues to be a valid arrow |
| 336 // formal parameters if the inner expression is a valid binding pattern. | 356 // formal parameters if the inner expression is a valid binding pattern. |
| 337 if (productions & ArrowFormalParametersProduction && | 357 if (productions & ArrowFormalParametersProduction && |
| 338 is_valid_arrow_formal_parameters()) { | 358 is_valid_arrow_formal_parameters()) { |
| 339 // Also copy function properties if expecting an arrow function | 359 // Also copy function properties if expecting an arrow function |
| 340 // parameter. | 360 // parameter. |
| 341 function_properties_ |= inner->function_properties_; | 361 function_properties_ |= inner->function_properties_; |
| 342 | 362 |
| 343 if (!inner->is_valid_binding_pattern()) { | 363 if (!inner->is_valid_binding_pattern()) |
| 344 invalid_productions_ |= ArrowFormalParametersProduction; | 364 errors |= ArrowFormalParametersProduction; |
| 345 arrow_formal_parameters_error_ = inner->binding_pattern_error_; | 365 } |
| 366 | |
| 367 if (errors != 0) { | |
| 368 invalid_productions_ |= errors; | |
| 369 int arrow_index = inner->reported_errors_end_; | |
| 370 for (int i = inner->reported_errors_begin_; | |
| 371 i < inner->reported_errors_end_; i++) { | |
| 372 if (reported_errors_->at(i).kind == kUnusedError || | |
| 373 reported_errors_->at(i).kind == kArrowFormalParametersProduction) | |
| 374 continue; | |
| 375 if (errors & (1 << reported_errors_->at(i).kind)) | |
| 376 Move(next++, i); | |
| 377 if (reported_errors_->at(i).kind == kBindingPatternProduction && | |
| 378 errors & ArrowFormalParametersProduction) { | |
| 379 if (next <= i) { | |
| 380 Move(next, i); | |
| 381 reported_errors_->at(next++).kind = | |
| 382 kArrowFormalParametersProduction; | |
| 383 } else { | |
| 384 DCHECK_EQ(next, i+1); | |
| 385 arrow_index = i; | |
| 386 } | |
| 387 } | |
| 388 } | |
| 389 if (arrow_index < inner->reported_errors_end_) { | |
| 390 Add(reported_errors_->at(arrow_index)); | |
| 391 reported_errors_->at(next++).kind = kArrowFormalParametersProduction; | |
| 392 } | |
| 346 } | 393 } |
| 347 } | 394 } |
| 395 DCHECK_EQ(reported_errors_end_, next); | |
| 396 reported_errors_->Rewind(next); | |
| 397 inner->reported_errors_begin_ = inner->reported_errors_end_ = next; | |
| 348 } | 398 } |
| 349 | 399 |
| 350 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } | 400 V8_INLINE int GetNonPatternBegin() const { return non_pattern_begin_; } |
| 351 | 401 |
| 352 V8_INLINE void Discard() { | 402 V8_INLINE void Discard() { |
| 403 if (reported_errors_end_ == reported_errors_->length()) { | |
| 404 reported_errors_->Rewind(reported_errors_begin_); | |
| 405 reported_errors_end_ = reported_errors_begin_; | |
| 406 } | |
| 407 DCHECK_EQ(reported_errors_begin_, reported_errors_end_); | |
| 353 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length()); | 408 DCHECK_LE(non_pattern_begin_, non_patterns_to_rewrite_->length()); |
| 354 non_patterns_to_rewrite_->Rewind(non_pattern_begin_); | 409 non_patterns_to_rewrite_->Rewind(non_pattern_begin_); |
| 355 } | 410 } |
| 356 | 411 |
| 357 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) { | 412 V8_INLINE void MergeNonPatterns(ExpressionClassifier* inner) { |
| 358 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_); | 413 DCHECK_LE(non_pattern_begin_, inner->non_pattern_begin_); |
| 359 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length(); | 414 inner->non_pattern_begin_ = inner->non_patterns_to_rewrite_->length(); |
| 360 } | 415 } |
| 361 | 416 |
| 362 private: | 417 private: |
| 418 V8_INLINE Error& reported_error(ErrorKind kind) const { | |
| 419 if (invalid_productions_ & (1 << kind)) { | |
| 420 for (int i = reported_errors_begin_; i < reported_errors_end_; i++) { | |
| 421 if (reported_errors_->at(i).kind == kind) | |
| 422 return reported_errors_->at(i); | |
| 423 } | |
| 424 } | |
| 425 // We should only be looking for an error when we know that one has | |
| 426 // been reported. But we're not... So this is to make sure we have | |
| 427 // the same behaviour. | |
| 428 static Error none; | |
| 429 return none; | |
| 430 } | |
| 431 | |
| 432 V8_INLINE void Add(const Error& e) { | |
| 433 DCHECK_EQ(reported_errors_end_, reported_errors_->length()); | |
| 434 reported_errors_->Add(e, zone_); | |
|
caitp (gmail)
2016/02/18 16:57:47
It might be worth having the very commonly used on
nickie
2016/02/19 08:56:31
If you could suggest a subset, I could try to benc
caitp (gmail)
2016/02/19 09:07:28
the main one is Object/Array Literals vs Assignmen
nickie
2016/02/19 09:25:50
One way to go then is to always store BindingPatte
| |
| 435 reported_errors_end_++; | |
| 436 } | |
| 437 | |
| 438 V8_INLINE void Move(int next, int i) { | |
| 439 DCHECK_EQ(reported_errors_end_, next); | |
| 440 DCHECK_LE(next, i); | |
| 441 DCHECK_LT(i, reported_errors_->length()); | |
| 442 if (next < i) reported_errors_->at(next++) = reported_errors_->at(i); | |
| 443 reported_errors_end_++; | |
| 444 } | |
| 445 | |
| 363 Zone* zone_; | 446 Zone* zone_; |
| 364 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_; | 447 ZoneList<typename Traits::Type::Expression>* non_patterns_to_rewrite_; |
| 365 int non_pattern_begin_; | 448 int non_pattern_begin_; |
| 366 unsigned invalid_productions_; | 449 unsigned invalid_productions_ : 14; |
| 367 unsigned function_properties_; | 450 unsigned function_properties_ : 2; |
| 368 Error expression_error_; | 451 ZoneList<Error>* reported_errors_; |
| 369 Error formal_parameter_initializer_error_; | 452 int reported_errors_begin_; |
| 370 Error binding_pattern_error_; | 453 int reported_errors_end_; |
| 371 Error assignment_pattern_error_; | |
| 372 Error arrow_formal_parameters_error_; | |
| 373 Error duplicate_formal_parameter_error_; | |
| 374 Error strict_mode_formal_parameter_error_; | |
| 375 Error strong_mode_formal_parameter_error_; | |
| 376 Error let_pattern_error_; | |
| 377 Error cover_initialized_name_error_; | |
| 378 DuplicateFinder* duplicate_finder_; | 454 DuplicateFinder* duplicate_finder_; |
| 379 }; | 455 }; |
| 380 | 456 |
| 381 | 457 |
| 458 #undef ERROR_CODES | |
| 459 | |
| 460 | |
| 382 } // namespace internal | 461 } // namespace internal |
| 383 } // namespace v8 | 462 } // namespace v8 |
| 384 | 463 |
| 385 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H | 464 #endif // V8_PARSING_EXPRESSION_CLASSIFIER_H |
| OLD | NEW |