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 |