Remove several grab-bag includes from the v8.h header.
[platform/upstream/v8.git] / src / expression-classifier.h
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
3 // found in the LICENSE file.
4
5 #ifndef V8_EXPRESSION_CLASSIFIER_H
6 #define V8_EXPRESSION_CLASSIFIER_H
7
8 #include "src/messages.h"
9 #include "src/scanner.h"
10 #include "src/token.h"
11
12 namespace v8 {
13 namespace internal {
14
15
16 class ExpressionClassifier {
17  public:
18   struct Error {
19     Error()
20         : location(Scanner::Location::invalid()),
21           message(MessageTemplate::kNone),
22           arg(nullptr) {}
23
24     Scanner::Location location;
25     MessageTemplate::Template message;
26     const char* arg;
27   };
28
29   enum TargetProduction {
30     ExpressionProduction = 1 << 0,
31     BindingPatternProduction = 1 << 1,
32     AssignmentPatternProduction = 1 << 2,
33     DistinctFormalParametersProduction = 1 << 3,
34     StrictModeFormalParametersProduction = 1 << 4,
35     StrongModeFormalParametersProduction = 1 << 5,
36     ArrowFormalParametersProduction = 1 << 6,
37
38     PatternProductions =
39         (BindingPatternProduction | AssignmentPatternProduction),
40     FormalParametersProductions = (DistinctFormalParametersProduction |
41                                    StrictModeFormalParametersProduction |
42                                    StrongModeFormalParametersProduction),
43     StandardProductions = ExpressionProduction | PatternProductions,
44     AllProductions = (StandardProductions | FormalParametersProductions |
45                       ArrowFormalParametersProduction)
46   };
47
48   ExpressionClassifier()
49       : invalid_productions_(0), duplicate_finder_(nullptr) {}
50
51   explicit ExpressionClassifier(DuplicateFinder* duplicate_finder)
52       : invalid_productions_(0), duplicate_finder_(duplicate_finder) {}
53
54   bool is_valid(unsigned productions) const {
55     return (invalid_productions_ & productions) == 0;
56   }
57
58   DuplicateFinder* duplicate_finder() const { return duplicate_finder_; }
59
60   bool is_valid_expression() const { return is_valid(ExpressionProduction); }
61
62   bool is_valid_binding_pattern() const {
63     return is_valid(BindingPatternProduction);
64   }
65
66   bool is_valid_assignment_pattern() const {
67     return is_valid(AssignmentPatternProduction);
68   }
69
70   bool is_valid_arrow_formal_parameters() const {
71     return is_valid(ArrowFormalParametersProduction);
72   }
73
74   bool is_valid_formal_parameter_list_without_duplicates() const {
75     return is_valid(DistinctFormalParametersProduction);
76   }
77
78   // Note: callers should also check
79   // is_valid_formal_parameter_list_without_duplicates().
80   bool is_valid_strict_mode_formal_parameters() const {
81     return is_valid(StrictModeFormalParametersProduction);
82   }
83
84   // Note: callers should also check is_valid_strict_mode_formal_parameters()
85   // and is_valid_formal_parameter_list_without_duplicates().
86   bool is_valid_strong_mode_formal_parameters() const {
87     return is_valid(StrongModeFormalParametersProduction);
88   }
89
90   const Error& expression_error() const { return expression_error_; }
91
92   const Error& binding_pattern_error() const { return binding_pattern_error_; }
93
94   const Error& assignment_pattern_error() const {
95     return assignment_pattern_error_;
96   }
97
98   const Error& arrow_formal_parameters_error() const {
99     return arrow_formal_parameters_error_;
100   }
101
102   const Error& duplicate_formal_parameter_error() const {
103     return duplicate_formal_parameter_error_;
104   }
105
106   const Error& strict_mode_formal_parameter_error() const {
107     return strict_mode_formal_parameter_error_;
108   }
109
110   const Error& strong_mode_formal_parameter_error() const {
111     return strong_mode_formal_parameter_error_;
112   }
113
114   void RecordExpressionError(const Scanner::Location& loc,
115                              MessageTemplate::Template message,
116                              const char* arg = nullptr) {
117     if (!is_valid_expression()) return;
118     invalid_productions_ |= ExpressionProduction;
119     expression_error_.location = loc;
120     expression_error_.message = message;
121     expression_error_.arg = arg;
122   }
123
124   void RecordBindingPatternError(const Scanner::Location& loc,
125                                  MessageTemplate::Template message,
126                                  const char* arg = nullptr) {
127     if (!is_valid_binding_pattern()) return;
128     invalid_productions_ |= BindingPatternProduction;
129     binding_pattern_error_.location = loc;
130     binding_pattern_error_.message = message;
131     binding_pattern_error_.arg = arg;
132   }
133
134   void RecordAssignmentPatternError(const Scanner::Location& loc,
135                                     MessageTemplate::Template message,
136                                     const char* arg = nullptr) {
137     if (!is_valid_assignment_pattern()) return;
138     invalid_productions_ |= AssignmentPatternProduction;
139     assignment_pattern_error_.location = loc;
140     assignment_pattern_error_.message = message;
141     assignment_pattern_error_.arg = arg;
142   }
143
144   void RecordArrowFormalParametersError(const Scanner::Location& loc,
145                                         MessageTemplate::Template message,
146                                         const char* arg = nullptr) {
147     if (!is_valid_arrow_formal_parameters()) return;
148     invalid_productions_ |= ArrowFormalParametersProduction;
149     arrow_formal_parameters_error_.location = loc;
150     arrow_formal_parameters_error_.message = message;
151     arrow_formal_parameters_error_.arg = arg;
152   }
153
154   void RecordDuplicateFormalParameterError(const Scanner::Location& loc) {
155     if (!is_valid_formal_parameter_list_without_duplicates()) return;
156     invalid_productions_ |= DistinctFormalParametersProduction;
157     duplicate_formal_parameter_error_.location = loc;
158     duplicate_formal_parameter_error_.message = MessageTemplate::kParamDupe;
159     duplicate_formal_parameter_error_.arg = nullptr;
160   }
161
162   // Record a binding that would be invalid in strict mode.  Confusingly this
163   // is not the same as StrictFormalParameterList, which simply forbids
164   // duplicate bindings.
165   void RecordStrictModeFormalParameterError(const Scanner::Location& loc,
166                                             MessageTemplate::Template message,
167                                             const char* arg = nullptr) {
168     if (!is_valid_strict_mode_formal_parameters()) return;
169     invalid_productions_ |= StrictModeFormalParametersProduction;
170     strict_mode_formal_parameter_error_.location = loc;
171     strict_mode_formal_parameter_error_.message = message;
172     strict_mode_formal_parameter_error_.arg = arg;
173   }
174
175   void RecordStrongModeFormalParameterError(const Scanner::Location& loc,
176                                             MessageTemplate::Template message,
177                                             const char* arg = nullptr) {
178     if (!is_valid_strong_mode_formal_parameters()) return;
179     invalid_productions_ |= StrongModeFormalParametersProduction;
180     strong_mode_formal_parameter_error_.location = loc;
181     strong_mode_formal_parameter_error_.message = message;
182     strong_mode_formal_parameter_error_.arg = arg;
183   }
184
185   void Accumulate(const ExpressionClassifier& inner,
186                   unsigned productions = StandardProductions) {
187     // Propagate errors from inner, but don't overwrite already recorded
188     // errors.
189     unsigned non_arrow_inner_invalid_productions =
190         inner.invalid_productions_ & ~ArrowFormalParametersProduction;
191     if (non_arrow_inner_invalid_productions == 0) return;
192     unsigned non_arrow_productions =
193         productions & ~ArrowFormalParametersProduction;
194     unsigned errors =
195         non_arrow_productions & non_arrow_inner_invalid_productions;
196     errors &= ~invalid_productions_;
197     if (errors != 0) {
198       invalid_productions_ |= errors;
199       if (errors & ExpressionProduction)
200         expression_error_ = inner.expression_error_;
201       if (errors & BindingPatternProduction)
202         binding_pattern_error_ = inner.binding_pattern_error_;
203       if (errors & AssignmentPatternProduction)
204         assignment_pattern_error_ = inner.assignment_pattern_error_;
205       if (errors & DistinctFormalParametersProduction)
206         duplicate_formal_parameter_error_ =
207             inner.duplicate_formal_parameter_error_;
208       if (errors & StrictModeFormalParametersProduction)
209         strict_mode_formal_parameter_error_ =
210             inner.strict_mode_formal_parameter_error_;
211       if (errors & StrongModeFormalParametersProduction)
212         strong_mode_formal_parameter_error_ =
213             inner.strong_mode_formal_parameter_error_;
214     }
215
216     // As an exception to the above, the result continues to be a valid arrow
217     // formal parameters if the inner expression is a valid binding pattern.
218     if (productions & ArrowFormalParametersProduction &&
219         is_valid_arrow_formal_parameters() &&
220         !inner.is_valid_binding_pattern()) {
221       invalid_productions_ |= ArrowFormalParametersProduction;
222       arrow_formal_parameters_error_ = inner.binding_pattern_error_;
223     }
224   }
225
226  private:
227   unsigned invalid_productions_;
228   Error expression_error_;
229   Error binding_pattern_error_;
230   Error assignment_pattern_error_;
231   Error arrow_formal_parameters_error_;
232   Error duplicate_formal_parameter_error_;
233   Error strict_mode_formal_parameter_error_;
234   Error strong_mode_formal_parameter_error_;
235   DuplicateFinder* duplicate_finder_;
236 };
237 }
238 }  // v8::internal
239
240 #endif  // V8_EXPRESSION_CLASSIFIER_H