Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: src/expression-classifier.h

Issue 1170153003: [destructuring] Refactor duplicate parameter name detection. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « BUILD.gn ('k') | src/parser.h » ('j') | src/preparser.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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
OLDNEW
« no previous file with comments | « BUILD.gn ('k') | src/parser.h » ('j') | src/preparser.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698