blob: 768a9488632675359f9fcb43df6ef8c05368456f [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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#include "src/ast/ast.h"
6#include "src/messages.h"
7#include "src/parsing/parameter-initializer-rewriter.h"
8#include "src/parsing/parser.h"
9
10namespace v8 {
11
12namespace internal {
13
14void Parser::PatternRewriter::DeclareAndInitializeVariables(
15 Block* block, const DeclarationDescriptor* declaration_descriptor,
16 const DeclarationParsingResult::Declaration* declaration,
17 ZoneList<const AstRawString*>* names, bool* ok) {
18 PatternRewriter rewriter;
19
20 rewriter.scope_ = declaration_descriptor->scope;
21 rewriter.parser_ = declaration_descriptor->parser;
22 rewriter.context_ = BINDING;
23 rewriter.pattern_ = declaration->pattern;
24 rewriter.initializer_position_ = declaration->initializer_position;
25 rewriter.block_ = block;
26 rewriter.descriptor_ = declaration_descriptor;
27 rewriter.names_ = names;
28 rewriter.ok_ = ok;
29 rewriter.recursion_level_ = 0;
30
31 rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
32}
33
34
35void Parser::PatternRewriter::RewriteDestructuringAssignment(
Ben Murdoch097c5b22016-05-18 11:27:45 +010036 Parser* parser, RewritableExpression* to_rewrite, Scope* scope) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000037 PatternRewriter rewriter;
38
39 DCHECK(!to_rewrite->is_rewritten());
40
41 bool ok = true;
42 rewriter.scope_ = scope;
43 rewriter.parser_ = parser;
44 rewriter.context_ = ASSIGNMENT;
45 rewriter.pattern_ = to_rewrite;
46 rewriter.block_ = nullptr;
47 rewriter.descriptor_ = nullptr;
48 rewriter.names_ = nullptr;
49 rewriter.ok_ = &ok;
50 rewriter.recursion_level_ = 0;
51
52 rewriter.RecurseIntoSubpattern(rewriter.pattern_, nullptr);
53 DCHECK(ok);
54}
55
56
57Expression* Parser::PatternRewriter::RewriteDestructuringAssignment(
58 Parser* parser, Assignment* assignment, Scope* scope) {
59 DCHECK_NOT_NULL(assignment);
60 DCHECK_EQ(Token::ASSIGN, assignment->op());
Ben Murdoch097c5b22016-05-18 11:27:45 +010061 auto to_rewrite = parser->factory()->NewRewritableExpression(assignment);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000062 RewriteDestructuringAssignment(parser, to_rewrite, scope);
63 return to_rewrite->expression();
64}
65
66
67bool Parser::PatternRewriter::IsAssignmentContext(PatternContext c) const {
68 return c == ASSIGNMENT || c == ASSIGNMENT_INITIALIZER;
69}
70
71
72bool Parser::PatternRewriter::IsBindingContext(PatternContext c) const {
73 return c == BINDING || c == INITIALIZER;
74}
75
76
77Parser::PatternRewriter::PatternContext
78Parser::PatternRewriter::SetAssignmentContextIfNeeded(Expression* node) {
79 PatternContext old_context = context();
Ben Murdoch097c5b22016-05-18 11:27:45 +010080 // AssignmentExpressions may occur in the Initializer position of a
81 // SingleNameBinding. Such expressions should not prompt a change in the
82 // pattern's context.
83 if (node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN &&
84 !IsInitializerContext()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000085 set_context(ASSIGNMENT);
86 }
87 return old_context;
88}
89
90
91Parser::PatternRewriter::PatternContext
92Parser::PatternRewriter::SetInitializerContextIfNeeded(Expression* node) {
93 // Set appropriate initializer context for BindingElement and
94 // AssignmentElement nodes
95 PatternContext old_context = context();
96 bool is_destructuring_assignment =
Ben Murdoch097c5b22016-05-18 11:27:45 +010097 node->IsRewritableExpression() &&
98 !node->AsRewritableExpression()->is_rewritten();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000099 bool is_assignment =
100 node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN;
101 if (is_destructuring_assignment || is_assignment) {
102 switch (old_context) {
103 case BINDING:
104 set_context(INITIALIZER);
105 break;
106 case ASSIGNMENT:
107 set_context(ASSIGNMENT_INITIALIZER);
108 break;
109 default:
110 break;
111 }
112 }
113 return old_context;
114}
115
116
117void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
118 Expression* value = current_value_;
119
120 if (IsAssignmentContext()) {
121 // In an assignment context, simply perform the assignment
122 Assignment* assignment = factory()->NewAssignment(
123 Token::ASSIGN, pattern, value, pattern->position());
124 block_->statements()->Add(
125 factory()->NewExpressionStatement(assignment, pattern->position()),
126 zone());
127 return;
128 }
129
130 descriptor_->scope->RemoveUnresolved(pattern);
131
132 // Declare variable.
133 // Note that we *always* must treat the initial value via a separate init
134 // assignment for variables and constants because the value must be assigned
135 // when the variable is encountered in the source. But the variable/constant
136 // is declared (and set to 'undefined') upon entering the function within
137 // which the variable or constant is declared. Only function variables have
138 // an initial value in the declaration (because they are initialized upon
139 // entering the function).
140 //
141 // If we have a legacy const declaration, in an inner scope, the proxy
142 // is always bound to the declared variable (independent of possibly
143 // surrounding 'with' statements).
144 // For let/const declarations in harmony mode, we can also immediately
145 // pre-resolve the proxy because it resides in the same scope as the
146 // declaration.
147 const AstRawString* name = pattern->raw_name();
148 VariableProxy* proxy = parser_->NewUnresolved(name, descriptor_->mode);
149 Declaration* declaration = factory()->NewVariableDeclaration(
150 proxy, descriptor_->mode, descriptor_->scope,
151 descriptor_->declaration_pos);
152 Variable* var =
153 parser_->Declare(declaration, descriptor_->declaration_kind,
154 descriptor_->mode != VAR, ok_, descriptor_->hoist_scope);
155 if (!*ok_) return;
156 DCHECK_NOT_NULL(var);
157 DCHECK(!proxy->is_resolved() || proxy->var() == var);
158 var->set_initializer_position(initializer_position_);
159
160 DCHECK(initializer_position_ != RelocInfo::kNoPosition);
161
162 Scope* declaration_scope = IsLexicalVariableMode(descriptor_->mode)
163 ? descriptor_->scope
164 : descriptor_->scope->DeclarationScope();
165 if (declaration_scope->num_var_or_const() > kMaxNumFunctionLocals) {
166 parser_->ReportMessage(MessageTemplate::kTooManyVariables);
167 *ok_ = false;
168 return;
169 }
170 if (names_) {
171 names_->Add(name, zone());
172 }
173
174 // Initialize variables if needed. A
175 // declaration of the form:
176 //
177 // var v = x;
178 //
179 // is syntactic sugar for:
180 //
181 // var v; v = x;
182 //
183 // In particular, we need to re-lookup 'v' (in scope_, not
184 // declaration_scope) as it may be a different 'v' than the 'v' in the
185 // declaration (e.g., if we are inside a 'with' statement or 'catch'
186 // block).
187 //
188 // However, note that const declarations are different! A const
189 // declaration of the form:
190 //
191 // const c = x;
192 //
193 // is *not* syntactic sugar for:
194 //
195 // const c; c = x;
196 //
197 // The "variable" c initialized to x is the same as the declared
198 // one - there is no re-lookup (see the last parameter of the
199 // Declare() call above).
200 Scope* initialization_scope = IsImmutableVariableMode(descriptor_->mode)
201 ? declaration_scope
202 : descriptor_->scope;
203
204
205 // Global variable declarations must be compiled in a specific
206 // way. When the script containing the global variable declaration
207 // is entered, the global variable must be declared, so that if it
208 // doesn't exist (on the global object itself, see ES5 errata) it
209 // gets created with an initial undefined value. This is handled
210 // by the declarations part of the function representing the
211 // top-level global code; see Runtime::DeclareGlobalVariable. If
212 // it already exists (in the object or in a prototype), it is
213 // *not* touched until the variable declaration statement is
214 // executed.
215 //
216 // Executing the variable declaration statement will always
217 // guarantee to give the global object an own property.
218 // This way, global variable declarations can shadow
219 // properties in the prototype chain, but only after the variable
220 // declaration statement has been executed. This is important in
221 // browsers where the global object (window) has lots of
222 // properties defined in prototype objects.
223 if (initialization_scope->is_script_scope() &&
224 !IsLexicalVariableMode(descriptor_->mode)) {
225 // Compute the arguments for the runtime
226 // call.test-parsing/InitializedDeclarationsInStrictForOfError
227 ZoneList<Expression*>* arguments =
228 new (zone()) ZoneList<Expression*>(3, zone());
229 // We have at least 1 parameter.
230 arguments->Add(
231 factory()->NewStringLiteral(name, descriptor_->declaration_pos),
232 zone());
233 CallRuntime* initialize;
234
235 if (IsImmutableVariableMode(descriptor_->mode)) {
236 arguments->Add(value, zone());
237 value = NULL; // zap the value to avoid the unnecessary assignment
238
239 // Construct the call to Runtime_InitializeConstGlobal
240 // and add it to the initialization statement block.
241 // Note that the function does different things depending on
242 // the number of arguments (1 or 2).
243 initialize =
244 factory()->NewCallRuntime(Runtime::kInitializeConstGlobal, arguments,
245 descriptor_->initialization_pos);
246 } else {
247 // Add language mode.
248 // We may want to pass singleton to avoid Literal allocations.
249 LanguageMode language_mode = initialization_scope->language_mode();
250 arguments->Add(factory()->NewNumberLiteral(language_mode,
251 descriptor_->declaration_pos),
252 zone());
253
254 // Be careful not to assign a value to the global variable if
255 // we're in a with. The initialization value should not
256 // necessarily be stored in the global object in that case,
257 // which is why we need to generate a separate assignment node.
258 if (value != NULL && !descriptor_->scope->inside_with()) {
259 arguments->Add(value, zone());
260 value = NULL; // zap the value to avoid the unnecessary assignment
261 // Construct the call to Runtime_InitializeVarGlobal
262 // and add it to the initialization statement block.
263 initialize =
264 factory()->NewCallRuntime(Runtime::kInitializeVarGlobal, arguments,
265 descriptor_->declaration_pos);
266 } else {
267 initialize = NULL;
268 }
269 }
270
271 if (initialize != NULL) {
272 block_->statements()->Add(
273 factory()->NewExpressionStatement(initialize, RelocInfo::kNoPosition),
274 zone());
275 }
276 } else if (value != nullptr && (descriptor_->mode == CONST_LEGACY ||
277 IsLexicalVariableMode(descriptor_->mode))) {
278 // Constant initializations always assign to the declared constant which
279 // is always at the function scope level. This is only relevant for
280 // dynamically looked-up variables and constants (the
281 // start context for constant lookups is always the function context,
282 // while it is the top context for var declared variables). Sigh...
283 // For 'let' and 'const' declared variables in harmony mode the
284 // initialization also always assigns to the declared variable.
285 DCHECK_NOT_NULL(proxy);
286 DCHECK_NOT_NULL(proxy->var());
287 DCHECK_NOT_NULL(value);
288 // Add break location for destructured sub-pattern.
289 int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
290 Assignment* assignment =
291 factory()->NewAssignment(Token::INIT, proxy, value, pos);
292 block_->statements()->Add(
293 factory()->NewExpressionStatement(assignment, pos), zone());
294 value = NULL;
295 }
296
297 // Add an assignment node to the initialization statement block if we still
298 // have a pending initialization value.
299 if (value != NULL) {
300 DCHECK(descriptor_->mode == VAR);
301 // 'var' initializations are simply assignments (with all the consequences
302 // if they are inside a 'with' statement - they may change a 'with' object
303 // property).
304 VariableProxy* proxy = initialization_scope->NewUnresolved(factory(), name);
305 // Add break location for destructured sub-pattern.
306 int pos = IsSubPattern() ? pattern->position() : RelocInfo::kNoPosition;
307 Assignment* assignment =
308 factory()->NewAssignment(Token::INIT, proxy, value, pos);
309 block_->statements()->Add(
310 factory()->NewExpressionStatement(assignment, pos), zone());
311 }
312}
313
314
315Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
316 auto temp = scope()->NewTemporary(ast_value_factory()->empty_string());
317 if (value != nullptr) {
318 auto assignment = factory()->NewAssignment(
319 Token::ASSIGN, factory()->NewVariableProxy(temp), value,
320 RelocInfo::kNoPosition);
321
322 block_->statements()->Add(
323 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
324 zone());
325 }
326 return temp;
327}
328
329
Ben Murdoch097c5b22016-05-18 11:27:45 +0100330void Parser::PatternRewriter::VisitRewritableExpression(
331 RewritableExpression* node) {
332 // If this is not a destructuring assignment...
333 if (!IsAssignmentContext() || !node->expression()->IsAssignment()) {
334 // Mark the node as rewritten to prevent redundant rewriting, and
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000335 // perform BindingPattern rewriting
336 DCHECK(!node->is_rewritten());
337 node->Rewrite(node->expression());
338 return node->expression()->Accept(this);
339 }
340
341 if (node->is_rewritten()) return;
342 DCHECK(IsAssignmentContext());
343 Assignment* assign = node->expression()->AsAssignment();
344 DCHECK_NOT_NULL(assign);
345 DCHECK_EQ(Token::ASSIGN, assign->op());
346
347 auto initializer = assign->value();
348 auto value = initializer;
349
350 if (IsInitializerContext()) {
351 // let {<pattern> = <init>} = <value>
352 // becomes
353 // temp = <value>;
354 // <pattern> = temp === undefined ? <init> : temp;
355 auto temp_var = CreateTempVar(current_value_);
356 Expression* is_undefined = factory()->NewCompareOperation(
357 Token::EQ_STRICT, factory()->NewVariableProxy(temp_var),
358 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
359 RelocInfo::kNoPosition);
360 value = factory()->NewConditional(is_undefined, initializer,
361 factory()->NewVariableProxy(temp_var),
362 RelocInfo::kNoPosition);
363 }
364
365 PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
366 int pos = assign->position();
367 Block* old_block = block_;
368 block_ = factory()->NewBlock(nullptr, 8, false, pos);
369 Variable* temp = nullptr;
370 Expression* pattern = assign->target();
371 Expression* old_value = current_value_;
372 current_value_ = value;
373 if (pattern->IsObjectLiteral()) {
374 VisitObjectLiteral(pattern->AsObjectLiteral(), &temp);
375 } else {
376 DCHECK(pattern->IsArrayLiteral());
377 VisitArrayLiteral(pattern->AsArrayLiteral(), &temp);
378 }
379 DCHECK_NOT_NULL(temp);
380 current_value_ = old_value;
381 Expression* expr = factory()->NewDoExpression(block_, temp, pos);
382 node->Rewrite(expr);
383 block_ = old_block;
384 if (block_) {
385 block_->statements()->Add(factory()->NewExpressionStatement(expr, pos),
386 zone());
387 }
388 return set_context(old_context);
389}
390
391
392void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
393 Variable** temp_var) {
394 auto temp = *temp_var = CreateTempVar(current_value_);
395
396 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
397
398 for (ObjectLiteralProperty* property : *pattern->properties()) {
399 PatternContext context = SetInitializerContextIfNeeded(property->value());
400 RecurseIntoSubpattern(
401 property->value(),
402 factory()->NewProperty(factory()->NewVariableProxy(temp),
403 property->key(), RelocInfo::kNoPosition));
404 set_context(context);
405 }
406}
407
408
409void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) {
410 Variable* temp_var = nullptr;
411 VisitObjectLiteral(node, &temp_var);
412}
413
414
415void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
416 Variable** temp_var) {
417 auto temp = *temp_var = CreateTempVar(current_value_);
418
419 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
420
421 auto iterator = CreateTempVar(parser_->GetIterator(
422 factory()->NewVariableProxy(temp), factory(), RelocInfo::kNoPosition));
423 auto done = CreateTempVar(
424 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
425 auto result = CreateTempVar();
426 auto v = CreateTempVar();
427
428 Spread* spread = nullptr;
429 for (Expression* value : *node->values()) {
430 if (value->IsSpread()) {
431 spread = value->AsSpread();
432 break;
433 }
434
435 PatternContext context = SetInitializerContextIfNeeded(value);
436 // if (!done) {
437 // result = IteratorNext(iterator);
438 // v = (done = result.done) ? undefined : result.value;
439 // }
440 auto next_block =
441 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
442 next_block->statements()->Add(factory()->NewExpressionStatement(
443 parser_->BuildIteratorNextResult(
444 factory()->NewVariableProxy(iterator),
445 result, RelocInfo::kNoPosition),
446 RelocInfo::kNoPosition),
447 zone());
448
449 auto assign_to_done = factory()->NewAssignment(
450 Token::ASSIGN, factory()->NewVariableProxy(done),
451 factory()->NewProperty(
452 factory()->NewVariableProxy(result),
453 factory()->NewStringLiteral(ast_value_factory()->done_string(),
454 RelocInfo::kNoPosition),
455 RelocInfo::kNoPosition),
456 RelocInfo::kNoPosition);
457 auto next_value = factory()->NewConditional(
458 assign_to_done, factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
459 factory()->NewProperty(
460 factory()->NewVariableProxy(result),
461 factory()->NewStringLiteral(ast_value_factory()->value_string(),
462 RelocInfo::kNoPosition),
463 RelocInfo::kNoPosition),
464 RelocInfo::kNoPosition);
465 next_block->statements()->Add(
466 factory()->NewExpressionStatement(
467 factory()->NewAssignment(Token::ASSIGN,
468 factory()->NewVariableProxy(v), next_value,
469 RelocInfo::kNoPosition),
470 RelocInfo::kNoPosition),
471 zone());
472
473 auto if_statement = factory()->NewIfStatement(
474 factory()->NewUnaryOperation(Token::NOT,
475 factory()->NewVariableProxy(done),
476 RelocInfo::kNoPosition),
477 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
478 RelocInfo::kNoPosition);
479 block_->statements()->Add(if_statement, zone());
480
481 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) {
482 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v));
483 }
484 set_context(context);
485 }
486
487 if (spread != nullptr) {
488 // array = [];
489 // if (!done) %concat_iterable_to_array(array, iterator);
490 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
491 auto array = CreateTempVar(factory()->NewArrayLiteral(
492 empty_exprs,
493 // Reuse pattern's literal index - it is unused since there is no
494 // actual literal allocated.
495 node->literal_index(), is_strong(scope()->language_mode()),
496 RelocInfo::kNoPosition));
497
498 auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
499 arguments->Add(factory()->NewVariableProxy(array), zone());
500 arguments->Add(factory()->NewVariableProxy(iterator), zone());
501 auto spread_into_array_call =
502 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX,
503 arguments, RelocInfo::kNoPosition);
504
505 auto if_statement = factory()->NewIfStatement(
506 factory()->NewUnaryOperation(Token::NOT,
507 factory()->NewVariableProxy(done),
508 RelocInfo::kNoPosition),
509 factory()->NewExpressionStatement(spread_into_array_call,
510 RelocInfo::kNoPosition),
511 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
512 RelocInfo::kNoPosition);
513 block_->statements()->Add(if_statement, zone());
514
515 RecurseIntoSubpattern(spread->expression(),
516 factory()->NewVariableProxy(array));
517 }
518}
519
520
521void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
522 Variable* temp_var = nullptr;
523 VisitArrayLiteral(node, &temp_var);
524}
525
526
527void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
528 // let {<pattern> = <init>} = <value>
529 // becomes
530 // temp = <value>;
531 // <pattern> = temp === undefined ? <init> : temp;
532 DCHECK_EQ(Token::ASSIGN, node->op());
533
534 auto initializer = node->value();
535 auto value = initializer;
536 auto temp = CreateTempVar(current_value_);
537
538 if (IsInitializerContext()) {
539 Expression* is_undefined = factory()->NewCompareOperation(
540 Token::EQ_STRICT, factory()->NewVariableProxy(temp),
541 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
542 RelocInfo::kNoPosition);
543 value = factory()->NewConditional(is_undefined, initializer,
544 factory()->NewVariableProxy(temp),
545 RelocInfo::kNoPosition);
546 }
547
548 if (IsBindingContext() &&
549 descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
550 scope()->is_arrow_scope()) {
551 RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
552 scope()->outer_scope(), scope());
553 }
554
555 PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
556 RecurseIntoSubpattern(node->target(), value);
557 set_context(old_context);
558}
559
560
561// =============== AssignmentPattern only ==================
562
563void Parser::PatternRewriter::VisitProperty(v8::internal::Property* node) {
564 DCHECK(IsAssignmentContext());
565 auto value = current_value_;
566
567 Assignment* assignment =
568 factory()->NewAssignment(Token::ASSIGN, node, value, node->position());
569
570 block_->statements()->Add(
571 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
572 zone());
573}
574
575
576// =============== UNREACHABLE =============================
577
578void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); }
579
580#define NOT_A_PATTERN(Node) \
581 void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \
582 UNREACHABLE(); \
583 }
584
585NOT_A_PATTERN(BinaryOperation)
586NOT_A_PATTERN(Block)
587NOT_A_PATTERN(BreakStatement)
588NOT_A_PATTERN(Call)
589NOT_A_PATTERN(CallNew)
590NOT_A_PATTERN(CallRuntime)
591NOT_A_PATTERN(CaseClause)
592NOT_A_PATTERN(ClassLiteral)
593NOT_A_PATTERN(CompareOperation)
594NOT_A_PATTERN(Conditional)
595NOT_A_PATTERN(ContinueStatement)
596NOT_A_PATTERN(CountOperation)
597NOT_A_PATTERN(DebuggerStatement)
598NOT_A_PATTERN(DoExpression)
599NOT_A_PATTERN(DoWhileStatement)
600NOT_A_PATTERN(EmptyStatement)
601NOT_A_PATTERN(EmptyParentheses)
602NOT_A_PATTERN(ExportDeclaration)
603NOT_A_PATTERN(ExpressionStatement)
604NOT_A_PATTERN(ForInStatement)
605NOT_A_PATTERN(ForOfStatement)
606NOT_A_PATTERN(ForStatement)
607NOT_A_PATTERN(FunctionDeclaration)
608NOT_A_PATTERN(FunctionLiteral)
609NOT_A_PATTERN(IfStatement)
610NOT_A_PATTERN(ImportDeclaration)
611NOT_A_PATTERN(Literal)
612NOT_A_PATTERN(NativeFunctionLiteral)
613NOT_A_PATTERN(RegExpLiteral)
614NOT_A_PATTERN(ReturnStatement)
615NOT_A_PATTERN(SloppyBlockFunctionStatement)
616NOT_A_PATTERN(Spread)
617NOT_A_PATTERN(SuperPropertyReference)
618NOT_A_PATTERN(SuperCallReference)
619NOT_A_PATTERN(SwitchStatement)
620NOT_A_PATTERN(ThisFunction)
621NOT_A_PATTERN(Throw)
622NOT_A_PATTERN(TryCatchStatement)
623NOT_A_PATTERN(TryFinallyStatement)
624NOT_A_PATTERN(UnaryOperation)
625NOT_A_PATTERN(VariableDeclaration)
626NOT_A_PATTERN(WhileStatement)
627NOT_A_PATTERN(WithStatement)
628NOT_A_PATTERN(Yield)
629
630#undef NOT_A_PATTERN
631} // namespace internal
632} // namespace v8