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