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

Side by Side Diff: src/parsing/preparser.cc

Issue 2323763002: [parser] Refactor of Parse*Statement*, part 4 (Closed)
Patch Set: Rebase Created 4 years, 3 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 | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 #include <cmath> 5 #include <cmath>
6 6
7 #include "src/allocation.h" 7 #include "src/allocation.h"
8 #include "src/base/logging.h" 8 #include "src/base/logging.h"
9 #include "src/conversions-inl.h" 9 #include "src/conversions-inl.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 *ok = false; 157 *ok = false;
158 return Statement::Default(); 158 return Statement::Default();
159 } 159 }
160 } 160 }
161 // PreParser is not able to parse "export default" yet (since PreParser is 161 // PreParser is not able to parse "export default" yet (since PreParser is
162 // at the moment only used for functions, and it cannot occur 162 // at the moment only used for functions, and it cannot occur
163 // there). TODO(marja): update this when it is. 163 // there). TODO(marja): update this when it is.
164 return ParseHoistableDeclaration(pos, flags, nullptr, false, ok); 164 return ParseHoistableDeclaration(pos, flags, nullptr, false, ok);
165 } 165 }
166 166
167 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
168 ZoneList<const AstRawString*>* names,
169 AllowLabelledFunctionStatement allow_function, bool* ok) {
170 // ExpressionStatement | LabelledStatement ::
171 // Expression ';'
172 // Identifier ':' Statement
173
174 switch (peek()) {
175 case Token::FUNCTION:
176 case Token::LBRACE:
177 UNREACHABLE(); // Always handled by the callers.
178 case Token::CLASS:
179 ReportUnexpectedToken(Next());
180 *ok = false;
181 return Statement::Default();
182
183 default:
184 break;
185 }
186
187 bool starts_with_identifier = peek_any_identifier();
188 ExpressionClassifier classifier(this);
189 Expression expr = ParseExpressionCoverGrammar(true, CHECK_OK);
190 ValidateExpression(CHECK_OK);
191
192 // Even if the expression starts with an identifier, it is not necessarily an
193 // identifier. For example, "foo + bar" starts with an identifier but is not
194 // an identifier.
195 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
196 // Expression is a single identifier, and not, e.g., a parenthesized
197 // identifier.
198 DCHECK(!expr.AsIdentifier().IsEnum());
199 DCHECK(!parsing_module_ || !expr.AsIdentifier().IsAwait());
200 DCHECK(is_sloppy(language_mode()) ||
201 !IsFutureStrictReserved(expr.AsIdentifier()));
202 Consume(Token::COLON);
203 // ES#sec-labelled-function-declarations Labelled Function Declarations
204 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
205 if (allow_function == kAllowLabelledFunctionStatement) {
206 return ParseFunctionDeclaration(ok);
207 } else {
208 return ParseScopedStatement(names, true, ok);
209 }
210 }
211 Statement statement =
212 ParseStatement(nullptr, kDisallowLabelledFunctionStatement, ok);
213 return statement.IsJumpStatement() ? Statement::Default() : statement;
214 // Preparsing is disabled for extensions (because the extension details
215 // aren't passed to lazily compiled functions), so we don't
216 // accept "native function" in the preparser.
217 }
218 // Parsed expression statement.
219 ExpectSemicolon(CHECK_OK);
220 return Statement::ExpressionStatement(expr);
221 }
222
223 PreParser::Statement PreParser::ParseIfStatement(
224 ZoneList<const AstRawString*>* labels, bool* ok) {
225 // IfStatement ::
226 // 'if' '(' Expression ')' Statement ('else' Statement)?
227
228 Expect(Token::IF, CHECK_OK);
229 Expect(Token::LPAREN, CHECK_OK);
230 ParseExpression(true, CHECK_OK);
231 Expect(Token::RPAREN, CHECK_OK);
232 Statement stat = ParseScopedStatement(labels, false, CHECK_OK);
233 if (peek() == Token::ELSE) {
234 Next();
235 Statement else_stat = ParseScopedStatement(labels, false, CHECK_OK);
236 stat = (stat.IsJumpStatement() && else_stat.IsJumpStatement()) ?
237 Statement::Jump() : Statement::Default();
238 } else {
239 stat = Statement::Default();
240 }
241 return stat;
242 }
243
244
245 PreParser::Statement PreParser::ParseContinueStatement(bool* ok) {
246 // ContinueStatement ::
247 // 'continue' [no line terminator] Identifier? ';'
248
249 Expect(Token::CONTINUE, CHECK_OK);
250 Token::Value tok = peek();
251 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
252 tok != Token::SEMICOLON &&
253 tok != Token::RBRACE &&
254 tok != Token::EOS) {
255 // ECMA allows "eval" or "arguments" as labels even in strict mode.
256 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
257 }
258 ExpectSemicolon(CHECK_OK);
259 return Statement::Jump();
260 }
261
262 PreParser::Statement PreParser::ParseBreakStatement(
263 ZoneList<const AstRawString*>* labels, bool* ok) {
264 // BreakStatement ::
265 // 'break' [no line terminator] Identifier? ';'
266
267 Expect(Token::BREAK, CHECK_OK);
268 Token::Value tok = peek();
269 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
270 tok != Token::SEMICOLON &&
271 tok != Token::RBRACE &&
272 tok != Token::EOS) {
273 // ECMA allows "eval" or "arguments" as labels even in strict mode.
274 ParseIdentifier(kAllowRestrictedIdentifiers, CHECK_OK);
275 }
276 ExpectSemicolon(CHECK_OK);
277 return Statement::Jump();
278 }
279
280
281 PreParser::Statement PreParser::ParseReturnStatement(bool* ok) {
282 // ReturnStatement ::
283 // 'return' [no line terminator] Expression? ';'
284
285 // Consume the return token. It is necessary to do before
286 // reporting any errors on it, because of the way errors are
287 // reported (underlining).
288 Expect(Token::RETURN, CHECK_OK);
289
290 // An ECMAScript program is considered syntactically incorrect if it
291 // contains a return statement that is not within the body of a
292 // function. See ECMA-262, section 12.9, page 67.
293 // This is not handled during preparsing.
294
295 Token::Value tok = peek();
296 if (!scanner()->HasAnyLineTerminatorBeforeNext() &&
297 tok != Token::SEMICOLON &&
298 tok != Token::RBRACE &&
299 tok != Token::EOS) {
300 // Because of the return code rewriting that happens in case of a subclass
301 // constructor we don't want to accept tail calls, therefore we don't set
302 // ReturnExprScope to kInsideValidReturnStatement here.
303 ReturnExprContext return_expr_context =
304 IsSubclassConstructor(function_state_->kind())
305 ? function_state_->return_expr_context()
306 : ReturnExprContext::kInsideValidReturnStatement;
307
308 ReturnExprScope maybe_allow_tail_calls(function_state_,
309 return_expr_context);
310 ParseExpression(true, CHECK_OK);
311 }
312 ExpectSemicolon(CHECK_OK);
313 return Statement::Jump();
314 }
315
316 PreParser::Statement PreParser::ParseWithStatement(
317 ZoneList<const AstRawString*>* labels, bool* ok) {
318 // WithStatement ::
319 // 'with' '(' Expression ')' Statement
320 Expect(Token::WITH, CHECK_OK);
321 if (is_strict(language_mode())) {
322 ReportMessageAt(scanner()->location(), MessageTemplate::kStrictWith);
323 *ok = false;
324 return Statement::Default();
325 }
326 Expect(Token::LPAREN, CHECK_OK);
327 ParseExpression(true, CHECK_OK);
328 Expect(Token::RPAREN, CHECK_OK);
329
330 Scope* with_scope = NewScope(WITH_SCOPE);
331 BlockState block_state(&scope_state_, with_scope);
332 ParseScopedStatement(labels, true, CHECK_OK);
333 return Statement::Default();
334 }
335
336 PreParser::Statement PreParser::ParseSwitchStatement( 167 PreParser::Statement PreParser::ParseSwitchStatement(
337 ZoneList<const AstRawString*>* labels, bool* ok) { 168 ZoneList<const AstRawString*>* labels, bool* ok) {
338 // SwitchStatement :: 169 // SwitchStatement ::
339 // 'switch' '(' Expression ')' '{' CaseClause* '}' 170 // 'switch' '(' Expression ')' '{' CaseClause* '}'
340 171
341 Expect(Token::SWITCH, CHECK_OK); 172 Expect(Token::SWITCH, CHECK_OK);
342 Expect(Token::LPAREN, CHECK_OK); 173 Expect(Token::LPAREN, CHECK_OK);
343 ParseExpression(true, CHECK_OK); 174 ParseExpression(true, CHECK_OK);
344 Expect(Token::RPAREN, CHECK_OK); 175 Expect(Token::RPAREN, CHECK_OK);
345 176
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 631
801 body->Add(PreParserStatement::ExpressionStatement(return_value), zone()); 632 body->Add(PreParserStatement::ExpressionStatement(return_value), zone());
802 } 633 }
803 634
804 #undef CHECK_OK 635 #undef CHECK_OK
805 #undef CHECK_OK_CUSTOM 636 #undef CHECK_OK_CUSTOM
806 637
807 638
808 } // namespace internal 639 } // namespace internal
809 } // namespace v8 640 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698