LCOV - code coverage report
Current view: top level - test/cctest - test-parsing.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2264 2334 97.0 %
Date: 2019-04-17 Functions: 272 294 92.5 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Redistribution and use in source and binary forms, with or without
       3             : // modification, are permitted provided that the following conditions are
       4             : // met:
       5             : //
       6             : //     * Redistributions of source code must retain the above copyright
       7             : //       notice, this list of conditions and the following disclaimer.
       8             : //     * Redistributions in binary form must reproduce the above
       9             : //       copyright notice, this list of conditions and the following
      10             : //       disclaimer in the documentation and/or other materials provided
      11             : //       with the distribution.
      12             : //     * Neither the name of Google Inc. nor the names of its
      13             : //       contributors may be used to endorse or promote products derived
      14             : //       from this software without specific prior written permission.
      15             : //
      16             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      17             : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      18             : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
      19             : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
      20             : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      21             : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
      22             : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      23             : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      24             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      25             : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
      26             : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      27             : 
      28             : #include <stdio.h>
      29             : #include <stdlib.h>
      30             : #include <string.h>
      31             : 
      32             : #include <memory>
      33             : 
      34             : #include "src/v8.h"
      35             : 
      36             : #include "src/api-inl.h"
      37             : #include "src/ast/ast-value-factory.h"
      38             : #include "src/ast/ast.h"
      39             : #include "src/base/enum-set.h"
      40             : #include "src/compiler.h"
      41             : #include "src/execution.h"
      42             : #include "src/flags.h"
      43             : #include "src/isolate.h"
      44             : #include "src/objects-inl.h"
      45             : #include "src/objects.h"
      46             : #include "src/parsing/parse-info.h"
      47             : #include "src/parsing/parser.h"
      48             : #include "src/parsing/parsing.h"
      49             : #include "src/parsing/preparser.h"
      50             : #include "src/parsing/rewriter.h"
      51             : #include "src/parsing/scanner-character-streams.h"
      52             : #include "src/parsing/token.h"
      53             : #include "src/zone/zone-list-inl.h"  // crbug.com/v8/8816
      54             : 
      55             : #include "test/cctest/cctest.h"
      56             : #include "test/cctest/scope-test-helper.h"
      57             : #include "test/cctest/unicode-helpers.h"
      58             : 
      59             : namespace v8 {
      60             : namespace internal {
      61             : namespace test_parsing {
      62             : 
      63             : namespace {
      64             : 
      65             : int* global_use_counts = nullptr;
      66             : 
      67          30 : void MockUseCounterCallback(v8::Isolate* isolate,
      68             :                             v8::Isolate::UseCounterFeature feature) {
      69          30 :   ++global_use_counts[feature];
      70          30 : }
      71             : 
      72             : }  // namespace
      73             : 
      74           0 : bool TokenIsAutoSemicolon(Token::Value token) {
      75         560 :   switch (token) {
      76             :     case Token::SEMICOLON:
      77             :     case Token::EOS:
      78             :     case Token::RBRACE:
      79             :       return true;
      80             :     default:
      81           0 :       return false;
      82             :   }
      83             : }
      84             : 
      85       26644 : TEST(AutoSemicolonToken) {
      86        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
      87             :     Token::Value token = static_cast<Token::Value>(i);
      88         560 :     CHECK_EQ(TokenIsAutoSemicolon(token), Token::IsAutoSemicolon(token));
      89             :   }
      90           5 : }
      91             : 
      92           0 : bool TokenIsAnyIdentifier(Token::Value token) {
      93         560 :   switch (token) {
      94             :     case Token::IDENTIFIER:
      95             :     case Token::GET:
      96             :     case Token::SET:
      97             :     case Token::ASYNC:
      98             :     case Token::AWAIT:
      99             :     case Token::YIELD:
     100             :     case Token::LET:
     101             :     case Token::STATIC:
     102             :     case Token::FUTURE_STRICT_RESERVED_WORD:
     103             :     case Token::ESCAPED_STRICT_RESERVED_WORD:
     104             :       return true;
     105             :     default:
     106           0 :       return false;
     107             :   }
     108             : }
     109             : 
     110       26644 : TEST(AnyIdentifierToken) {
     111        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     112             :     Token::Value token = static_cast<Token::Value>(i);
     113         560 :     CHECK_EQ(TokenIsAnyIdentifier(token), Token::IsAnyIdentifier(token));
     114             :   }
     115           5 : }
     116             : 
     117           0 : bool TokenIsCallable(Token::Value token) {
     118         560 :   switch (token) {
     119             :     case Token::SUPER:
     120             :     case Token::IDENTIFIER:
     121             :     case Token::GET:
     122             :     case Token::SET:
     123             :     case Token::ASYNC:
     124             :     case Token::AWAIT:
     125             :     case Token::YIELD:
     126             :     case Token::LET:
     127             :     case Token::STATIC:
     128             :     case Token::FUTURE_STRICT_RESERVED_WORD:
     129             :     case Token::ESCAPED_STRICT_RESERVED_WORD:
     130             :       return true;
     131             :     default:
     132           0 :       return false;
     133             :   }
     134             : }
     135             : 
     136       26644 : TEST(CallableToken) {
     137        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     138             :     Token::Value token = static_cast<Token::Value>(i);
     139         560 :     CHECK_EQ(TokenIsCallable(token), Token::IsCallable(token));
     140             :   }
     141           5 : }
     142             : 
     143           0 : bool TokenIsValidIdentifier(Token::Value token, LanguageMode language_mode,
     144             :                             bool is_generator, bool disallow_await) {
     145        4480 :   switch (token) {
     146             :     case Token::IDENTIFIER:
     147             :     case Token::GET:
     148             :     case Token::SET:
     149             :     case Token::ASYNC:
     150             :       return true;
     151             :     case Token::YIELD:
     152          40 :       return !is_generator && is_sloppy(language_mode);
     153             :     case Token::AWAIT:
     154          40 :       return !disallow_await;
     155             :     case Token::LET:
     156             :     case Token::STATIC:
     157             :     case Token::FUTURE_STRICT_RESERVED_WORD:
     158             :     case Token::ESCAPED_STRICT_RESERVED_WORD:
     159           0 :       return is_sloppy(language_mode);
     160             :     default:
     161           0 :       return false;
     162             :   }
     163             :   UNREACHABLE();
     164             : }
     165             : 
     166       26644 : TEST(IsValidIdentifierToken) {
     167        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     168             :     Token::Value token = static_cast<Token::Value>(i);
     169        2800 :     for (size_t raw_language_mode = 0; raw_language_mode < LanguageModeSize;
     170             :          raw_language_mode++) {
     171        1120 :       LanguageMode mode = static_cast<LanguageMode>(raw_language_mode);
     172        5600 :       for (int is_generator = 0; is_generator < 2; is_generator++) {
     173       11200 :         for (int disallow_await = 0; disallow_await < 2; disallow_await++) {
     174        4480 :           CHECK_EQ(
     175             :               TokenIsValidIdentifier(token, mode, is_generator, disallow_await),
     176             :               Token::IsValidIdentifier(token, mode, is_generator,
     177             :                                        disallow_await));
     178             :         }
     179             :       }
     180             :     }
     181             :   }
     182           5 : }
     183             : 
     184           0 : bool TokenIsStrictReservedWord(Token::Value token) {
     185         560 :   switch (token) {
     186             :     case Token::LET:
     187             :     case Token::YIELD:
     188             :     case Token::STATIC:
     189             :     case Token::FUTURE_STRICT_RESERVED_WORD:
     190             :     case Token::ESCAPED_STRICT_RESERVED_WORD:
     191             :       return true;
     192             :     default:
     193           0 :       return false;
     194             :   }
     195             :   UNREACHABLE();
     196             : }
     197             : 
     198       26644 : TEST(IsStrictReservedWord) {
     199        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     200             :     Token::Value token = static_cast<Token::Value>(i);
     201         560 :     CHECK_EQ(TokenIsStrictReservedWord(token),
     202             :              Token::IsStrictReservedWord(token));
     203             :   }
     204           5 : }
     205             : 
     206           0 : bool TokenIsLiteral(Token::Value token) {
     207         560 :   switch (token) {
     208             :     case Token::NULL_LITERAL:
     209             :     case Token::TRUE_LITERAL:
     210             :     case Token::FALSE_LITERAL:
     211             :     case Token::NUMBER:
     212             :     case Token::SMI:
     213             :     case Token::BIGINT:
     214             :     case Token::STRING:
     215             :       return true;
     216             :     default:
     217           0 :       return false;
     218             :   }
     219             :   UNREACHABLE();
     220             : }
     221             : 
     222       26644 : TEST(IsLiteralToken) {
     223        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     224             :     Token::Value token = static_cast<Token::Value>(i);
     225         560 :     CHECK_EQ(TokenIsLiteral(token), Token::IsLiteral(token));
     226             :   }
     227           5 : }
     228             : 
     229           0 : bool TokenIsAssignmentOp(Token::Value token) {
     230        1115 :   switch (token) {
     231             :     case Token::INIT:
     232             :     case Token::ASSIGN:
     233             : #define T(name, string, precedence) case Token::name:
     234             :       BINARY_OP_TOKEN_LIST(T, EXPAND_BINOP_ASSIGN_TOKEN)
     235             : #undef T
     236             :       return true;
     237             :     default:
     238           0 :       return false;
     239             :   }
     240             : }
     241             : 
     242       26644 : TEST(AssignmentOp) {
     243        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     244             :     Token::Value token = static_cast<Token::Value>(i);
     245         560 :     CHECK_EQ(TokenIsAssignmentOp(token), Token::IsAssignmentOp(token));
     246             :   }
     247           5 : }
     248             : 
     249           0 : bool TokenIsArrowOrAssignmentOp(Token::Value token) {
     250        1115 :   return token == Token::ARROW || TokenIsAssignmentOp(token);
     251             : }
     252             : 
     253       26644 : TEST(ArrowOrAssignmentOp) {
     254        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     255             :     Token::Value token = static_cast<Token::Value>(i);
     256         560 :     CHECK_EQ(TokenIsArrowOrAssignmentOp(token),
     257             :              Token::IsArrowOrAssignmentOp(token));
     258             :   }
     259           5 : }
     260             : 
     261           0 : bool TokenIsBinaryOp(Token::Value token) {
     262         560 :   switch (token) {
     263             :     case Token::COMMA:
     264             :     case Token::OR:
     265             :     case Token::AND:
     266             : #define T(name, string, precedence) case Token::name:
     267             :       BINARY_OP_TOKEN_LIST(T, EXPAND_BINOP_TOKEN)
     268             : #undef T
     269             :       return true;
     270             :     default:
     271           0 :       return false;
     272             :   }
     273             : }
     274             : 
     275       26644 : TEST(BinaryOp) {
     276        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     277             :     Token::Value token = static_cast<Token::Value>(i);
     278         560 :     CHECK_EQ(TokenIsBinaryOp(token), Token::IsBinaryOp(token));
     279             :   }
     280           5 : }
     281             : 
     282           0 : bool TokenIsCompareOp(Token::Value token) {
     283         560 :   switch (token) {
     284             :     case Token::EQ:
     285             :     case Token::EQ_STRICT:
     286             :     case Token::NE:
     287             :     case Token::NE_STRICT:
     288             :     case Token::LT:
     289             :     case Token::GT:
     290             :     case Token::LTE:
     291             :     case Token::GTE:
     292             :     case Token::INSTANCEOF:
     293             :     case Token::IN:
     294             :       return true;
     295             :     default:
     296           0 :       return false;
     297             :   }
     298             : }
     299             : 
     300       26644 : TEST(CompareOp) {
     301        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     302             :     Token::Value token = static_cast<Token::Value>(i);
     303         560 :     CHECK_EQ(TokenIsCompareOp(token), Token::IsCompareOp(token));
     304             :   }
     305           5 : }
     306             : 
     307           0 : bool TokenIsOrderedRelationalCompareOp(Token::Value token) {
     308         560 :   switch (token) {
     309             :     case Token::LT:
     310             :     case Token::GT:
     311             :     case Token::LTE:
     312             :     case Token::GTE:
     313             :       return true;
     314             :     default:
     315           0 :       return false;
     316             :   }
     317             : }
     318             : 
     319       26644 : TEST(IsOrderedRelationalCompareOp) {
     320        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     321             :     Token::Value token = static_cast<Token::Value>(i);
     322         560 :     CHECK_EQ(TokenIsOrderedRelationalCompareOp(token),
     323             :              Token::IsOrderedRelationalCompareOp(token));
     324             :   }
     325           5 : }
     326             : 
     327           0 : bool TokenIsEqualityOp(Token::Value token) {
     328         560 :   switch (token) {
     329             :     case Token::EQ:
     330             :     case Token::EQ_STRICT:
     331             :       return true;
     332             :     default:
     333           0 :       return false;
     334             :   }
     335             : }
     336             : 
     337       26644 : TEST(IsEqualityOp) {
     338        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     339             :     Token::Value token = static_cast<Token::Value>(i);
     340         560 :     CHECK_EQ(TokenIsEqualityOp(token), Token::IsEqualityOp(token));
     341             :   }
     342           5 : }
     343             : 
     344           0 : bool TokenIsBitOp(Token::Value token) {
     345             :   switch (token) {
     346             :     case Token::BIT_OR:
     347             :     case Token::BIT_XOR:
     348             :     case Token::BIT_AND:
     349             :     case Token::SHL:
     350             :     case Token::SAR:
     351             :     case Token::SHR:
     352             :     case Token::BIT_NOT:
     353             :       return true;
     354             :     default:
     355           0 :       return false;
     356             :   }
     357             : }
     358             : 
     359       26644 : TEST(IsBitOp) {
     360        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     361             :     Token::Value token = static_cast<Token::Value>(i);
     362         560 :     CHECK_EQ(TokenIsBitOp(token), Token::IsBitOp(token));
     363             :   }
     364           5 : }
     365             : 
     366           0 : bool TokenIsUnaryOp(Token::Value token) {
     367        1120 :   switch (token) {
     368             :     case Token::NOT:
     369             :     case Token::BIT_NOT:
     370             :     case Token::DELETE:
     371             :     case Token::TYPEOF:
     372             :     case Token::VOID:
     373             :     case Token::ADD:
     374             :     case Token::SUB:
     375             :       return true;
     376             :     default:
     377           0 :       return false;
     378             :   }
     379             : }
     380             : 
     381       26644 : TEST(IsUnaryOp) {
     382        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     383             :     Token::Value token = static_cast<Token::Value>(i);
     384         560 :     CHECK_EQ(TokenIsUnaryOp(token), Token::IsUnaryOp(token));
     385             :   }
     386           5 : }
     387             : 
     388           0 : bool TokenIsPropertyOrCall(Token::Value token) {
     389         560 :   switch (token) {
     390             :     case Token::TEMPLATE_SPAN:
     391             :     case Token::TEMPLATE_TAIL:
     392             :     case Token::PERIOD:
     393             :     case Token::LBRACK:
     394             :     case Token::LPAREN:
     395             :       return true;
     396             :     default:
     397           0 :       return false;
     398             :   }
     399             : }
     400             : 
     401       26644 : TEST(IsPropertyOrCall) {
     402        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     403             :     Token::Value token = static_cast<Token::Value>(i);
     404         560 :     CHECK_EQ(TokenIsPropertyOrCall(token), Token::IsPropertyOrCall(token));
     405             :   }
     406           5 : }
     407             : 
     408           0 : bool TokenIsMember(Token::Value token) {
     409         560 :   switch (token) {
     410             :     case Token::TEMPLATE_SPAN:
     411             :     case Token::TEMPLATE_TAIL:
     412             :     case Token::PERIOD:
     413             :     case Token::LBRACK:
     414             :       return true;
     415             :     default:
     416           0 :       return false;
     417             :   }
     418             : }
     419             : 
     420           0 : bool TokenIsTemplate(Token::Value token) {
     421         560 :   switch (token) {
     422             :     case Token::TEMPLATE_SPAN:
     423             :     case Token::TEMPLATE_TAIL:
     424             :       return true;
     425             :     default:
     426           0 :       return false;
     427             :   }
     428             : }
     429             : 
     430           0 : bool TokenIsProperty(Token::Value token) {
     431         560 :   switch (token) {
     432             :     case Token::PERIOD:
     433             :     case Token::LBRACK:
     434             :       return true;
     435             :     default:
     436           0 :       return false;
     437             :   }
     438             : }
     439             : 
     440       26644 : TEST(IsMember) {
     441        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     442             :     Token::Value token = static_cast<Token::Value>(i);
     443         560 :     CHECK_EQ(TokenIsMember(token), Token::IsMember(token));
     444             :   }
     445           5 : }
     446             : 
     447       26644 : TEST(IsTemplate) {
     448        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     449             :     Token::Value token = static_cast<Token::Value>(i);
     450         560 :     CHECK_EQ(TokenIsTemplate(token), Token::IsTemplate(token));
     451             :   }
     452           5 : }
     453             : 
     454       26644 : TEST(IsProperty) {
     455        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     456             :     Token::Value token = static_cast<Token::Value>(i);
     457         560 :     CHECK_EQ(TokenIsProperty(token), Token::IsProperty(token));
     458             :   }
     459           5 : }
     460             : 
     461           0 : bool TokenIsCountOp(Token::Value token) {
     462        1085 :   switch (token) {
     463             :     case Token::INC:
     464             :     case Token::DEC:
     465             :       return true;
     466             :     default:
     467           0 :       return false;
     468             :   }
     469             : }
     470             : 
     471       26644 : TEST(IsCountOp) {
     472        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     473             :     Token::Value token = static_cast<Token::Value>(i);
     474         560 :     CHECK_EQ(TokenIsCountOp(token), Token::IsCountOp(token));
     475             :   }
     476           5 : }
     477             : 
     478       26644 : TEST(IsUnaryOrCountOp) {
     479        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     480             :     Token::Value token = static_cast<Token::Value>(i);
     481        1085 :     CHECK_EQ(TokenIsUnaryOp(token) || TokenIsCountOp(token),
     482             :              Token::IsUnaryOrCountOp(token));
     483             :   }
     484           5 : }
     485             : 
     486           0 : bool TokenIsShiftOp(Token::Value token) {
     487         560 :   switch (token) {
     488             :     case Token::SHL:
     489             :     case Token::SAR:
     490             :     case Token::SHR:
     491             :       return true;
     492             :     default:
     493           0 :       return false;
     494             :   }
     495             : }
     496             : 
     497       26644 : TEST(IsShiftOp) {
     498        1125 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     499             :     Token::Value token = static_cast<Token::Value>(i);
     500         560 :     CHECK_EQ(TokenIsShiftOp(token), Token::IsShiftOp(token));
     501             :   }
     502           5 : }
     503             : 
     504       26644 : TEST(ScanKeywords) {
     505             :   struct KeywordToken {
     506             :     const char* keyword;
     507             :     i::Token::Value token;
     508             :   };
     509             : 
     510             :   static const KeywordToken keywords[] = {
     511             : #define KEYWORD(t, s, d) { s, i::Token::t },
     512             :       TOKEN_LIST(IGNORE_TOKEN, KEYWORD)
     513             : #undef KEYWORD
     514             :           {nullptr, i::Token::IDENTIFIER}};
     515             : 
     516             :   KeywordToken key_token;
     517             :   char buffer[32];
     518         435 :   for (int i = 0; (key_token = keywords[i]).keyword != nullptr; i++) {
     519             :     const char* keyword = key_token.keyword;
     520         215 :     size_t length = strlen(key_token.keyword);
     521         215 :     CHECK(static_cast<int>(sizeof(buffer)) >= length);
     522             :     {
     523         215 :       auto stream = i::ScannerStream::ForTesting(keyword, length);
     524         430 :       i::Scanner scanner(stream.get(), false);
     525         215 :       scanner.Initialize();
     526         215 :       CHECK_EQ(key_token.token, scanner.Next());
     527         215 :       CHECK_EQ(i::Token::EOS, scanner.Next());
     528             :     }
     529             :     // Removing characters will make keyword matching fail.
     530             :     {
     531         215 :       auto stream = i::ScannerStream::ForTesting(keyword, length - 1);
     532         430 :       i::Scanner scanner(stream.get(), false);
     533         215 :       scanner.Initialize();
     534         215 :       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     535         215 :       CHECK_EQ(i::Token::EOS, scanner.Next());
     536             :     }
     537             :     // Adding characters will make keyword matching fail.
     538             :     static const char chars_to_append[] = { 'z', '0', '_' };
     539        1505 :     for (int j = 0; j < static_cast<int>(arraysize(chars_to_append)); ++j) {
     540             :       i::MemMove(buffer, keyword, length);
     541         645 :       buffer[length] = chars_to_append[j];
     542         645 :       auto stream = i::ScannerStream::ForTesting(buffer, length + 1);
     543        1290 :       i::Scanner scanner(stream.get(), false);
     544         645 :       scanner.Initialize();
     545         645 :       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     546         645 :       CHECK_EQ(i::Token::EOS, scanner.Next());
     547             :     }
     548             :     // Replacing characters will make keyword matching fail.
     549             :     {
     550             :       i::MemMove(buffer, keyword, length);
     551         215 :       buffer[length - 1] = '_';
     552         215 :       auto stream = i::ScannerStream::ForTesting(buffer, length);
     553         430 :       i::Scanner scanner(stream.get(), false);
     554         215 :       scanner.Initialize();
     555         215 :       CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     556         215 :       CHECK_EQ(i::Token::EOS, scanner.Next());
     557             :     }
     558             :   }
     559           5 : }
     560             : 
     561             : 
     562       26644 : TEST(ScanHTMLEndComments) {
     563           5 :   v8::V8::Initialize();
     564           5 :   v8::Isolate* isolate = CcTest::isolate();
     565             :   i::Isolate* i_isolate = CcTest::i_isolate();
     566          10 :   v8::HandleScope handles(isolate);
     567             : 
     568             :   // Regression test. See:
     569             :   //    http://code.google.com/p/chromium/issues/detail?id=53548
     570             :   // Tests that --> is correctly interpreted as comment-to-end-of-line if there
     571             :   // is only whitespace before it on the line (with comments considered as
     572             :   // whitespace, even a multiline-comment containing a newline).
     573             :   // This was not the case if it occurred before the first real token
     574             :   // in the input.
     575             :   // clang-format off
     576             :   const char* tests[] = {
     577             :       // Before first real token.
     578             :       "-->",
     579             :       "--> is eol-comment",
     580             :       "--> is eol-comment\nvar y = 37;\n",
     581             :       "\n --> is eol-comment\nvar y = 37;\n",
     582             :       "\n-->is eol-comment\nvar y = 37;\n",
     583             :       "\n-->\nvar y = 37;\n",
     584             :       "/* precomment */ --> is eol-comment\nvar y = 37;\n",
     585             :       "/* precomment */-->eol-comment\nvar y = 37;\n",
     586             :       "\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
     587             :       "\n/*precomment*/-->eol-comment\nvar y = 37;\n",
     588             :       // After first real token.
     589             :       "var x = 42;\n--> is eol-comment\nvar y = 37;\n",
     590             :       "var x = 42;\n/* precomment */ --> is eol-comment\nvar y = 37;\n",
     591             :       "x/* precomment\n */ --> is eol-comment\nvar y = 37;\n",
     592             :       "var x = 42; /* precomment\n */ --> is eol-comment\nvar y = 37;\n",
     593             :       "var x = 42;/*\n*/-->is eol-comment\nvar y = 37;\n",
     594             :       // With multiple comments preceding HTMLEndComment
     595             :       "/* MLC \n */ /* SLDC */ --> is eol-comment\nvar y = 37;\n",
     596             :       "/* MLC \n */ /* SLDC1 */ /* SLDC2 */ --> is eol-comment\nvar y = 37;\n",
     597             :       "/* MLC1 \n */ /* MLC2 \n */ --> is eol-comment\nvar y = 37;\n",
     598             :       "/* SLDC */ /* MLC \n */ --> is eol-comment\nvar y = 37;\n",
     599             :       "/* MLC1 \n */ /* SLDC1 */ /* MLC2 \n */ /* SLDC2 */ --> is eol-comment\n"
     600             :           "var y = 37;\n",
     601             :       nullptr
     602           5 :   };
     603             : 
     604             :   const char* fail_tests[] = {
     605             :       "x --> is eol-comment\nvar y = 37;\n",
     606             :       "\"\\n\" --> is eol-comment\nvar y = 37;\n",
     607             :       "x/* precomment */ --> is eol-comment\nvar y = 37;\n",
     608             :       "var x = 42; --> is eol-comment\nvar y = 37;\n",
     609             :       nullptr
     610           5 :   };
     611             :   // clang-format on
     612             : 
     613             :   // Parser/Scanner needs a stack limit.
     614           5 :   i_isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
     615           5 :                                           128 * 1024);
     616             :   uintptr_t stack_limit = i_isolate->stack_guard()->real_climit();
     617         205 :   for (int i = 0; tests[i]; i++) {
     618             :     const char* source = tests[i];
     619         100 :     auto stream = i::ScannerStream::ForTesting(source);
     620         200 :     i::Scanner scanner(stream.get(), false);
     621         100 :     scanner.Initialize();
     622         200 :     i::Zone zone(i_isolate->allocator(), ZONE_NAME);
     623             :     i::AstValueFactory ast_value_factory(
     624         100 :         &zone, i_isolate->ast_string_constants(), HashSeed(i_isolate));
     625             :     i::PendingCompilationErrorHandler pending_error_handler;
     626             :     i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
     627             :                            &pending_error_handler,
     628             :                            i_isolate->counters()->runtime_call_stats(),
     629         200 :                            i_isolate->logger());
     630         100 :     i::PreParser::PreParseResult result = preparser.PreParseProgram();
     631         100 :     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
     632         100 :     CHECK(!pending_error_handler.has_pending_error());
     633             :   }
     634             : 
     635          45 :   for (int i = 0; fail_tests[i]; i++) {
     636             :     const char* source = fail_tests[i];
     637          20 :     auto stream = i::ScannerStream::ForTesting(source);
     638          40 :     i::Scanner scanner(stream.get(), false);
     639          20 :     scanner.Initialize();
     640          40 :     i::Zone zone(i_isolate->allocator(), ZONE_NAME);
     641             :     i::AstValueFactory ast_value_factory(
     642          20 :         &zone, i_isolate->ast_string_constants(), HashSeed(i_isolate));
     643             :     i::PendingCompilationErrorHandler pending_error_handler;
     644             :     i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
     645             :                            &pending_error_handler,
     646             :                            i_isolate->counters()->runtime_call_stats(),
     647          40 :                            i_isolate->logger());
     648          20 :     i::PreParser::PreParseResult result = preparser.PreParseProgram();
     649             :     // Even in the case of a syntax error, kPreParseSuccess is returned.
     650          20 :     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
     651          20 :     CHECK(pending_error_handler.has_pending_error() ||
     652             :           pending_error_handler.has_error_unidentifiable_by_preparser());
     653             :   }
     654           5 : }
     655             : 
     656       26644 : TEST(ScanHtmlComments) {
     657             :   const char* src = "a <!-- b --> c";
     658             :   // Disallow HTML comments.
     659             :   {
     660           5 :     auto stream = i::ScannerStream::ForTesting(src);
     661          10 :     i::Scanner scanner(stream.get(), true);
     662           5 :     scanner.Initialize();
     663           5 :     CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     664           5 :     CHECK_EQ(i::Token::ILLEGAL, scanner.Next());
     665             :   }
     666             : 
     667             :   // Skip HTML comments:
     668             :   {
     669           5 :     auto stream = i::ScannerStream::ForTesting(src);
     670          10 :     i::Scanner scanner(stream.get(), false);
     671           5 :     scanner.Initialize();
     672           5 :     CHECK_EQ(i::Token::IDENTIFIER, scanner.Next());
     673           5 :     CHECK_EQ(i::Token::EOS, scanner.Next());
     674             :   }
     675           5 : }
     676             : 
     677             : class ScriptResource : public v8::String::ExternalOneByteStringResource {
     678             :  public:
     679             :   ScriptResource(const char* data, size_t length)
     680             :       : data_(data), length_(length) { }
     681             : 
     682             :   const char* data() const override { return data_; }
     683             :   size_t length() const override { return length_; }
     684             : 
     685             :  private:
     686             :   const char* data_;
     687             :   size_t length_;
     688             : };
     689             : 
     690             : 
     691       26644 : TEST(StandAlonePreParser) {
     692           5 :   v8::V8::Initialize();
     693             :   i::Isolate* i_isolate = CcTest::i_isolate();
     694             : 
     695           5 :   i_isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
     696           5 :                                           128 * 1024);
     697             : 
     698             :   const char* programs[] = {"{label: 42}",
     699             :                             "var x = 42;",
     700             :                             "function foo(x, y) { return x + y; }",
     701             :                             "%ArgleBargle(glop);",
     702             :                             "var x = new new Function('this.x = 42');",
     703             :                             "var f = (x, y) => x + y;",
     704           5 :                             nullptr};
     705             : 
     706             :   uintptr_t stack_limit = i_isolate->stack_guard()->real_climit();
     707          65 :   for (int i = 0; programs[i]; i++) {
     708          30 :     auto stream = i::ScannerStream::ForTesting(programs[i]);
     709          60 :     i::Scanner scanner(stream.get(), false);
     710          30 :     scanner.Initialize();
     711             : 
     712          60 :     i::Zone zone(i_isolate->allocator(), ZONE_NAME);
     713             :     i::AstValueFactory ast_value_factory(
     714          30 :         &zone, i_isolate->ast_string_constants(), HashSeed(i_isolate));
     715             :     i::PendingCompilationErrorHandler pending_error_handler;
     716             :     i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
     717             :                            &pending_error_handler,
     718             :                            i_isolate->counters()->runtime_call_stats(),
     719          60 :                            i_isolate->logger());
     720             :     preparser.set_allow_natives(true);
     721          30 :     i::PreParser::PreParseResult result = preparser.PreParseProgram();
     722          30 :     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
     723          30 :     CHECK(!pending_error_handler.has_pending_error());
     724             :   }
     725           5 : }
     726             : 
     727             : 
     728       26644 : TEST(StandAlonePreParserNoNatives) {
     729           5 :   v8::V8::Initialize();
     730             : 
     731             :   i::Isolate* isolate = CcTest::i_isolate();
     732           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
     733           5 :                                         128 * 1024);
     734             : 
     735             :   const char* programs[] = {"%ArgleBargle(glop);", "var x = %_IsSmi(42);",
     736           5 :                             nullptr};
     737             : 
     738             :   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
     739          25 :   for (int i = 0; programs[i]; i++) {
     740          10 :     auto stream = i::ScannerStream::ForTesting(programs[i]);
     741          20 :     i::Scanner scanner(stream.get(), false);
     742          10 :     scanner.Initialize();
     743             : 
     744             :     // Preparser defaults to disallowing natives syntax.
     745          20 :     i::Zone zone(isolate->allocator(), ZONE_NAME);
     746             :     i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
     747          10 :                                          HashSeed(isolate));
     748             :     i::PendingCompilationErrorHandler pending_error_handler;
     749             :     i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
     750             :                            &pending_error_handler,
     751             :                            isolate->counters()->runtime_call_stats(),
     752          20 :                            isolate->logger());
     753          10 :     i::PreParser::PreParseResult result = preparser.PreParseProgram();
     754          10 :     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
     755          10 :     CHECK(pending_error_handler.has_pending_error() ||
     756             :           pending_error_handler.has_error_unidentifiable_by_preparser());
     757             :   }
     758           5 : }
     759             : 
     760             : 
     761       26644 : TEST(RegressChromium62639) {
     762           5 :   v8::V8::Initialize();
     763             :   i::Isolate* isolate = CcTest::i_isolate();
     764             : 
     765           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
     766           5 :                                         128 * 1024);
     767             : 
     768             :   const char* program = "var x = 'something';\n"
     769             :                         "escape: function() {}";
     770             :   // Fails parsing expecting an identifier after "function".
     771             :   // Before fix, didn't check *ok after Expect(Token::Identifier, ok),
     772             :   // and then used the invalid currently scanned literal. This always
     773             :   // failed in debug mode, and sometimes crashed in release mode.
     774             : 
     775           5 :   auto stream = i::ScannerStream::ForTesting(program);
     776          10 :   i::Scanner scanner(stream.get(), false);
     777           5 :   scanner.Initialize();
     778          10 :   i::Zone zone(isolate->allocator(), ZONE_NAME);
     779             :   i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
     780           5 :                                        HashSeed(isolate));
     781             :   i::PendingCompilationErrorHandler pending_error_handler;
     782             :   i::PreParser preparser(&zone, &scanner, isolate->stack_guard()->real_climit(),
     783             :                          &ast_value_factory, &pending_error_handler,
     784             :                          isolate->counters()->runtime_call_stats(),
     785          10 :                          isolate->logger());
     786           5 :   i::PreParser::PreParseResult result = preparser.PreParseProgram();
     787             :   // Even in the case of a syntax error, kPreParseSuccess is returned.
     788           5 :   CHECK_EQ(i::PreParser::kPreParseSuccess, result);
     789           5 :   CHECK(pending_error_handler.has_pending_error() ||
     790             :         pending_error_handler.has_error_unidentifiable_by_preparser());
     791           5 : }
     792             : 
     793             : 
     794       26644 : TEST(PreParseOverflow) {
     795           5 :   v8::V8::Initialize();
     796             :   i::Isolate* isolate = CcTest::i_isolate();
     797             : 
     798           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
     799           5 :                                         128 * 1024);
     800             : 
     801             :   size_t kProgramSize = 1024 * 1024;
     802           5 :   std::unique_ptr<char[]> program(i::NewArray<char>(kProgramSize + 1));
     803             :   memset(program.get(), '(', kProgramSize);
     804           5 :   program[kProgramSize] = '\0';
     805             : 
     806             :   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
     807             : 
     808           5 :   auto stream = i::ScannerStream::ForTesting(program.get(), kProgramSize);
     809          10 :   i::Scanner scanner(stream.get(), false);
     810           5 :   scanner.Initialize();
     811             : 
     812          10 :   i::Zone zone(isolate->allocator(), ZONE_NAME);
     813             :   i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
     814           5 :                                        HashSeed(isolate));
     815             :   i::PendingCompilationErrorHandler pending_error_handler;
     816             :   i::PreParser preparser(
     817             :       &zone, &scanner, stack_limit, &ast_value_factory, &pending_error_handler,
     818          10 :       isolate->counters()->runtime_call_stats(), isolate->logger());
     819           5 :   i::PreParser::PreParseResult result = preparser.PreParseProgram();
     820           5 :   CHECK_EQ(i::PreParser::kPreParseStackOverflow, result);
     821           5 : }
     822             : 
     823          35 : void TestStreamScanner(i::Utf16CharacterStream* stream,
     824             :                        i::Token::Value* expected_tokens,
     825             :                        int skip_pos = 0,  // Zero means not skipping.
     826             :                        int skip_to = 0) {
     827          70 :   i::Scanner scanner(stream, false);
     828          35 :   scanner.Initialize();
     829             : 
     830             :   int i = 0;
     831             :   do {
     832         190 :     i::Token::Value expected = expected_tokens[i];
     833         190 :     i::Token::Value actual = scanner.Next();
     834         190 :     CHECK_EQ(i::Token::String(expected), i::Token::String(actual));
     835         190 :     if (scanner.location().end_pos == skip_pos) {
     836          30 :       scanner.SeekForward(skip_to);
     837             :     }
     838         190 :     i++;
     839         190 :   } while (expected_tokens[i] != i::Token::ILLEGAL);
     840          35 : }
     841             : 
     842             : 
     843       26644 : TEST(StreamScanner) {
     844           5 :   v8::V8::Initialize();
     845             :   const char* str1 = "{ foo get for : */ <- \n\n /*foo*/ bib";
     846             :   std::unique_ptr<i::Utf16CharacterStream> stream1(
     847           5 :       i::ScannerStream::ForTesting(str1));
     848             :   i::Token::Value expectations1[] = {
     849             :       i::Token::LBRACE, i::Token::IDENTIFIER, i::Token::GET, i::Token::FOR,
     850             :       i::Token::COLON,  i::Token::MUL,        i::Token::DIV, i::Token::LT,
     851           5 :       i::Token::SUB,    i::Token::IDENTIFIER, i::Token::EOS, i::Token::ILLEGAL};
     852           5 :   TestStreamScanner(stream1.get(), expectations1, 0, 0);
     853             : 
     854             :   const char* str2 = "case default const {THIS\nPART\nSKIPPED} do";
     855             :   std::unique_ptr<i::Utf16CharacterStream> stream2(
     856           5 :       i::ScannerStream::ForTesting(str2));
     857             :   i::Token::Value expectations2[] = {
     858             :       i::Token::CASE,
     859             :       i::Token::DEFAULT,
     860             :       i::Token::CONST,
     861             :       i::Token::LBRACE,
     862             :       // Skipped part here
     863             :       i::Token::RBRACE,
     864             :       i::Token::DO,
     865             :       i::Token::EOS,
     866             :       i::Token::ILLEGAL
     867           5 :   };
     868             :   CHECK_EQ('{', str2[19]);
     869             :   CHECK_EQ('}', str2[37]);
     870           5 :   TestStreamScanner(stream2.get(), expectations2, 20, 37);
     871             : 
     872             :   const char* str3 = "{}}}}";
     873             :   i::Token::Value expectations3[] = {
     874             :       i::Token::LBRACE,
     875             :       i::Token::RBRACE,
     876             :       i::Token::RBRACE,
     877             :       i::Token::RBRACE,
     878             :       i::Token::RBRACE,
     879             :       i::Token::EOS,
     880             :       i::Token::ILLEGAL
     881           5 :   };
     882             :   // Skip zero-four RBRACEs.
     883          55 :   for (int i = 0; i <= 4; i++) {
     884          25 :      expectations3[6 - i] = i::Token::ILLEGAL;
     885          25 :      expectations3[5 - i] = i::Token::EOS;
     886             :      std::unique_ptr<i::Utf16CharacterStream> stream3(
     887          25 :          i::ScannerStream::ForTesting(str3));
     888          50 :      TestStreamScanner(stream3.get(), expectations3, 1, 1 + i);
     889             :   }
     890           5 : }
     891             : 
     892         110 : void TestScanRegExp(const char* re_source, const char* expected) {
     893         110 :   auto stream = i::ScannerStream::ForTesting(re_source);
     894             :   i::HandleScope scope(CcTest::i_isolate());
     895         220 :   i::Scanner scanner(stream.get(), false);
     896         110 :   scanner.Initialize();
     897             : 
     898             :   i::Token::Value start = scanner.peek();
     899         110 :   CHECK(start == i::Token::DIV || start == i::Token::ASSIGN_DIV);
     900         110 :   CHECK(scanner.ScanRegExpPattern());
     901         110 :   scanner.Next();  // Current token is now the regexp literal.
     902         220 :   i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
     903             :   i::AstValueFactory ast_value_factory(
     904             :       &zone, CcTest::i_isolate()->ast_string_constants(),
     905         110 :       HashSeed(CcTest::i_isolate()));
     906             :   const i::AstRawString* current_symbol =
     907         110 :       scanner.CurrentSymbol(&ast_value_factory);
     908         110 :   ast_value_factory.Internalize(CcTest::i_isolate());
     909             :   i::Handle<i::String> val = current_symbol->string();
     910             :   i::DisallowHeapAllocation no_alloc;
     911         110 :   i::String::FlatContent content = val->GetFlatContent(no_alloc);
     912         110 :   CHECK(content.IsOneByte());
     913             :   i::Vector<const uint8_t> actual = content.ToOneByteVector();
     914         910 :   for (int i = 0; i < actual.length(); i++) {
     915         400 :     CHECK_NE('\0', expected[i]);
     916         800 :     CHECK_EQ(expected[i], actual[i]);
     917             :   }
     918         110 : }
     919             : 
     920             : 
     921       26644 : TEST(RegExpScanning) {
     922           5 :   v8::V8::Initialize();
     923             : 
     924             :   // RegExp token with added garbage at the end. The scanner should only
     925             :   // scan the RegExp until the terminating slash just before "flipperwald".
     926           5 :   TestScanRegExp("/b/flipperwald", "b");
     927             :   // Incomplete escape sequences doesn't hide the terminating slash.
     928           5 :   TestScanRegExp("/\\x/flipperwald", "\\x");
     929           5 :   TestScanRegExp("/\\u/flipperwald", "\\u");
     930           5 :   TestScanRegExp("/\\u1/flipperwald", "\\u1");
     931           5 :   TestScanRegExp("/\\u12/flipperwald", "\\u12");
     932           5 :   TestScanRegExp("/\\u123/flipperwald", "\\u123");
     933           5 :   TestScanRegExp("/\\c/flipperwald", "\\c");
     934           5 :   TestScanRegExp("/\\c//flipperwald", "\\c");
     935             :   // Slashes inside character classes are not terminating.
     936           5 :   TestScanRegExp("/[/]/flipperwald", "[/]");
     937           5 :   TestScanRegExp("/[\\s-/]/flipperwald", "[\\s-/]");
     938             :   // Incomplete escape sequences inside a character class doesn't hide
     939             :   // the end of the character class.
     940           5 :   TestScanRegExp("/[\\c/]/flipperwald", "[\\c/]");
     941           5 :   TestScanRegExp("/[\\c]/flipperwald", "[\\c]");
     942           5 :   TestScanRegExp("/[\\x]/flipperwald", "[\\x]");
     943           5 :   TestScanRegExp("/[\\x1]/flipperwald", "[\\x1]");
     944           5 :   TestScanRegExp("/[\\u]/flipperwald", "[\\u]");
     945           5 :   TestScanRegExp("/[\\u1]/flipperwald", "[\\u1]");
     946           5 :   TestScanRegExp("/[\\u12]/flipperwald", "[\\u12]");
     947           5 :   TestScanRegExp("/[\\u123]/flipperwald", "[\\u123]");
     948             :   // Escaped ']'s wont end the character class.
     949           5 :   TestScanRegExp("/[\\]/]/flipperwald", "[\\]/]");
     950             :   // Escaped slashes are not terminating.
     951           5 :   TestScanRegExp("/\\//flipperwald", "\\/");
     952             :   // Starting with '=' works too.
     953           5 :   TestScanRegExp("/=/", "=");
     954           5 :   TestScanRegExp("/=?/", "=?");
     955           5 : }
     956             : 
     957       26644 : TEST(ScopeUsesArgumentsSuperThis) {
     958             :   static const struct {
     959             :     const char* prefix;
     960             :     const char* suffix;
     961             :   } surroundings[] = {
     962             :     { "function f() {", "}" },
     963             :     { "var f = () => {", "};" },
     964             :     { "class C { constructor() {", "} }" },
     965             :   };
     966             : 
     967             :   enum Expected {
     968             :     NONE = 0,
     969             :     ARGUMENTS = 1,
     970             :     SUPER_PROPERTY = 1 << 1,
     971             :     THIS = 1 << 2,
     972             :     EVAL = 1 << 4
     973             :   };
     974             : 
     975             :   // clang-format off
     976             :   static const struct {
     977             :     const char* body;
     978             :     int expected;
     979             :   } source_data[] = {
     980             :     {"", NONE},
     981             :     {"return this", THIS},
     982             :     {"return arguments", ARGUMENTS},
     983             :     {"return super.x", SUPER_PROPERTY},
     984             :     {"return arguments[0]", ARGUMENTS},
     985             :     {"return this + arguments[0]", ARGUMENTS | THIS},
     986             :     {"return this + arguments[0] + super.x",
     987             :      ARGUMENTS | SUPER_PROPERTY | THIS},
     988             :     {"return x => this + x", THIS},
     989             :     {"return x => super.f() + x", SUPER_PROPERTY},
     990             :     {"this.foo = 42;", THIS},
     991             :     {"this.foo();", THIS},
     992             :     {"if (foo()) { this.f() }", THIS},
     993             :     {"if (foo()) { super.f() }", SUPER_PROPERTY},
     994             :     {"if (arguments.length) { this.f() }", ARGUMENTS | THIS},
     995             :     {"while (true) { this.f() }", THIS},
     996             :     {"while (true) { super.f() }", SUPER_PROPERTY},
     997             :     {"if (true) { while (true) this.foo(arguments) }", ARGUMENTS | THIS},
     998             :     // Multiple nesting levels must work as well.
     999             :     {"while (true) { while (true) { while (true) return this } }", THIS},
    1000             :     {"while (true) { while (true) { while (true) return super.f() } }",
    1001             :      SUPER_PROPERTY},
    1002             :     {"if (1) { return () => { while (true) new this() } }", THIS},
    1003             :     {"return function (x) { return this + x }", NONE},
    1004             :     {"return { m(x) { return super.m() + x } }", NONE},
    1005             :     {"var x = function () { this.foo = 42 };", NONE},
    1006             :     {"var x = { m() { super.foo = 42 } };", NONE},
    1007             :     {"if (1) { return function () { while (true) new this() } }", NONE},
    1008             :     {"if (1) { return { m() { while (true) super.m() } } }", NONE},
    1009             :     {"return function (x) { return () => this }", NONE},
    1010             :     {"return { m(x) { return () => super.m() } }", NONE},
    1011             :     // Flags must be correctly set when using block scoping.
    1012             :     {"\"use strict\"; while (true) { let x; this, arguments; }",
    1013             :      THIS},
    1014             :     {"\"use strict\"; while (true) { let x; this, super.f(), arguments; }",
    1015             :      SUPER_PROPERTY | THIS},
    1016             :     {"\"use strict\"; if (foo()) { let x; this.f() }", THIS},
    1017             :     {"\"use strict\"; if (foo()) { let x; super.f() }", SUPER_PROPERTY},
    1018             :     {"\"use strict\"; if (1) {"
    1019             :      "  let x; return { m() { return this + super.m() + arguments } }"
    1020             :      "}",
    1021             :      NONE},
    1022             :     {"eval(42)", EVAL},
    1023             :     {"if (1) { eval(42) }", EVAL},
    1024             :     {"eval('super.x')", EVAL},
    1025             :     {"eval('this.x')", EVAL},
    1026             :     {"eval('arguments')", EVAL},
    1027             :   };
    1028             :   // clang-format on
    1029             : 
    1030             :   i::Isolate* isolate = CcTest::i_isolate();
    1031             :   i::Factory* factory = isolate->factory();
    1032             : 
    1033          10 :   v8::HandleScope handles(CcTest::isolate());
    1034           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1035             :   v8::Context::Scope context_scope(context);
    1036             : 
    1037           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    1038           5 :                                         128 * 1024);
    1039             : 
    1040          35 :   for (unsigned j = 0; j < arraysize(surroundings); ++j) {
    1041        1155 :     for (unsigned i = 0; i < arraysize(source_data); ++i) {
    1042             :       // Super property is only allowed in constructor and method.
    1043         570 :       if (((source_data[i].expected & SUPER_PROPERTY) ||
    1044         270 :            (source_data[i].expected == NONE)) && j != 2) {
    1045         180 :         continue;
    1046             :       }
    1047         780 :       int kProgramByteSize = i::StrLength(surroundings[j].prefix) +
    1048         390 :                              i::StrLength(surroundings[j].suffix) +
    1049         780 :                              i::StrLength(source_data[i].body);
    1050         390 :       i::ScopedVector<char> program(kProgramByteSize + 1);
    1051             :       i::SNPrintF(program, "%s%s%s", surroundings[j].prefix,
    1052         390 :                   source_data[i].body, surroundings[j].suffix);
    1053             :       i::Handle<i::String> source =
    1054         780 :           factory->NewStringFromUtf8(i::CStrVector(program.start()))
    1055         390 :               .ToHandleChecked();
    1056         390 :       i::Handle<i::Script> script = factory->NewScript(source);
    1057         780 :       i::ParseInfo info(isolate, script);
    1058             :       // The information we're checking is only produced when eager parsing.
    1059             :       info.set_allow_lazy_parsing(false);
    1060         390 :       CHECK(i::parsing::ParseProgram(&info, isolate));
    1061         390 :       CHECK(i::Rewriter::Rewrite(&info));
    1062         390 :       info.ast_value_factory()->Internalize(isolate);
    1063         390 :       CHECK(i::DeclarationScope::Analyze(&info));
    1064         390 :       i::DeclarationScope::AllocateScopeInfos(&info, isolate);
    1065         390 :       CHECK_NOT_NULL(info.literal());
    1066             : 
    1067             :       i::DeclarationScope* script_scope = info.literal()->scope();
    1068         390 :       CHECK(script_scope->is_script_scope());
    1069             : 
    1070             :       i::Scope* scope = script_scope->inner_scope();
    1071             :       DCHECK_NOT_NULL(scope);
    1072             :       DCHECK_NULL(scope->sibling());
    1073             :       // Adjust for constructor scope.
    1074         390 :       if (j == 2) {
    1075             :         scope = scope->inner_scope();
    1076             :         DCHECK_NOT_NULL(scope);
    1077             :         DCHECK_NULL(scope->sibling());
    1078             :       }
    1079             :       // Arrows themselves never get an arguments object.
    1080         470 :       if ((source_data[i].expected & ARGUMENTS) != 0 &&
    1081          80 :           !scope->AsDeclarationScope()->is_arrow_scope()) {
    1082          55 :         CHECK_NOT_NULL(scope->AsDeclarationScope()->arguments());
    1083             :       }
    1084         780 :       if (IsClassConstructor(scope->AsDeclarationScope()->function_kind())) {
    1085         190 :         CHECK_EQ((source_data[i].expected & SUPER_PROPERTY) != 0 ||
    1086             :                      (source_data[i].expected & EVAL) != 0,
    1087             :                  scope->AsDeclarationScope()->NeedsHomeObject());
    1088             :       } else {
    1089         200 :         CHECK_EQ((source_data[i].expected & SUPER_PROPERTY) != 0,
    1090             :                  scope->AsDeclarationScope()->NeedsHomeObject());
    1091             :       }
    1092         390 :       if ((source_data[i].expected & THIS) != 0) {
    1093             :         // Currently the is_used() flag is conservative; all variables in a
    1094             :         // script scope are marked as used.
    1095         410 :         CHECK(scope->GetReceiverScope()->receiver()->is_used());
    1096             :       }
    1097         390 :       if (is_sloppy(scope->language_mode())) {
    1098         360 :         CHECK_EQ((source_data[i].expected & EVAL) != 0,
    1099             :                  scope->AsDeclarationScope()->calls_sloppy_eval());
    1100             :       }
    1101             :     }
    1102             :   }
    1103           5 : }
    1104             : 
    1105          75 : static void CheckParsesToNumber(const char* source) {
    1106          75 :   v8::V8::Initialize();
    1107         150 :   HandleAndZoneScope handles;
    1108             : 
    1109             :   i::Isolate* isolate = CcTest::i_isolate();
    1110             :   i::Factory* factory = isolate->factory();
    1111             : 
    1112          75 :   std::string full_source = "function f() { return ";
    1113             :   full_source += source;
    1114             :   full_source += "; }";
    1115             : 
    1116             :   i::Handle<i::String> source_code =
    1117         150 :       factory->NewStringFromUtf8(i::CStrVector(full_source.c_str()))
    1118          75 :           .ToHandleChecked();
    1119             : 
    1120          75 :   i::Handle<i::Script> script = factory->NewScript(source_code);
    1121             : 
    1122         150 :   i::ParseInfo info(isolate, script);
    1123             :   info.set_allow_lazy_parsing(false);
    1124             :   info.set_toplevel(true);
    1125             : 
    1126          75 :   CHECK(i::parsing::ParseProgram(&info, isolate));
    1127             : 
    1128         150 :   CHECK_EQ(1, info.scope()->declarations()->LengthForTest());
    1129          75 :   i::Declaration* decl = info.scope()->declarations()->AtForTest(0);
    1130          75 :   i::FunctionLiteral* fun = decl->AsFunctionDeclaration()->fun();
    1131          75 :   CHECK_EQ(fun->body()->length(), 1);
    1132         150 :   CHECK(fun->body()->at(0)->IsReturnStatement());
    1133          75 :   i::ReturnStatement* ret = fun->body()->at(0)->AsReturnStatement();
    1134          75 :   i::Literal* lit = ret->expression()->AsLiteral();
    1135          75 :   CHECK(lit->IsNumberLiteral());
    1136          75 : }
    1137             : 
    1138             : 
    1139       26644 : TEST(ParseNumbers) {
    1140           5 :   CheckParsesToNumber("1.");
    1141           5 :   CheckParsesToNumber("1.34");
    1142           5 :   CheckParsesToNumber("134");
    1143           5 :   CheckParsesToNumber("134e44");
    1144           5 :   CheckParsesToNumber("134.e44");
    1145           5 :   CheckParsesToNumber("134.44e44");
    1146           5 :   CheckParsesToNumber(".44");
    1147             : 
    1148           5 :   CheckParsesToNumber("-1.");
    1149           5 :   CheckParsesToNumber("-1.0");
    1150           5 :   CheckParsesToNumber("-1.34");
    1151           5 :   CheckParsesToNumber("-134");
    1152           5 :   CheckParsesToNumber("-134e44");
    1153           5 :   CheckParsesToNumber("-134.e44");
    1154           5 :   CheckParsesToNumber("-134.44e44");
    1155           5 :   CheckParsesToNumber("-.44");
    1156           5 : }
    1157             : 
    1158             : 
    1159       26644 : TEST(ScopePositions) {
    1160             :   // Test the parser for correctly setting the start and end positions
    1161             :   // of a scope. We check the scope positions of exactly one scope
    1162             :   // nested in the global scope of a program. 'inner source' is the
    1163             :   // source code that determines the part of the source belonging
    1164             :   // to the nested scope. 'outer_prefix' and 'outer_suffix' are
    1165             :   // parts of the source that belong to the global scope.
    1166             :   struct SourceData {
    1167             :     const char* outer_prefix;
    1168             :     const char* inner_source;
    1169             :     const char* outer_suffix;
    1170             :     i::ScopeType scope_type;
    1171             :     i::LanguageMode language_mode;
    1172             :   };
    1173             : 
    1174             :   const SourceData source_data[] = {
    1175             :       {"  with ({}) ", "{ block; }", " more;", i::WITH_SCOPE,
    1176             :        i::LanguageMode::kSloppy},
    1177             :       {"  with ({}) ", "{ block; }", "; more;", i::WITH_SCOPE,
    1178             :        i::LanguageMode::kSloppy},
    1179             :       {"  with ({}) ",
    1180             :        "{\n"
    1181             :        "    block;\n"
    1182             :        "  }",
    1183             :        "\n"
    1184             :        "  more;",
    1185             :        i::WITH_SCOPE, i::LanguageMode::kSloppy},
    1186             :       {"  with ({}) ", "statement;", " more;", i::WITH_SCOPE,
    1187             :        i::LanguageMode::kSloppy},
    1188             :       {"  with ({}) ", "statement",
    1189             :        "\n"
    1190             :        "  more;",
    1191             :        i::WITH_SCOPE, i::LanguageMode::kSloppy},
    1192             :       {"  with ({})\n"
    1193             :        "    ",
    1194             :        "statement;",
    1195             :        "\n"
    1196             :        "  more;",
    1197             :        i::WITH_SCOPE, i::LanguageMode::kSloppy},
    1198             :       {"  try {} catch ", "(e) { block; }", " more;", i::CATCH_SCOPE,
    1199             :        i::LanguageMode::kSloppy},
    1200             :       {"  try {} catch ", "(e) { block; }", "; more;", i::CATCH_SCOPE,
    1201             :        i::LanguageMode::kSloppy},
    1202             :       {"  try {} catch ",
    1203             :        "(e) {\n"
    1204             :        "    block;\n"
    1205             :        "  }",
    1206             :        "\n"
    1207             :        "  more;",
    1208             :        i::CATCH_SCOPE, i::LanguageMode::kSloppy},
    1209             :       {"  try {} catch ", "(e) { block; }", " finally { block; } more;",
    1210             :        i::CATCH_SCOPE, i::LanguageMode::kSloppy},
    1211             :       {"  start;\n"
    1212             :        "  ",
    1213             :        "{ let block; }", " more;", i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1214             :       {"  start;\n"
    1215             :        "  ",
    1216             :        "{ let block; }", "; more;", i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1217             :       {"  start;\n"
    1218             :        "  ",
    1219             :        "{\n"
    1220             :        "    let block;\n"
    1221             :        "  }",
    1222             :        "\n"
    1223             :        "  more;",
    1224             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1225             :       {"  start;\n"
    1226             :        "  function fun",
    1227             :        "(a,b) { infunction; }", " more;", i::FUNCTION_SCOPE,
    1228             :        i::LanguageMode::kSloppy},
    1229             :       {"  start;\n"
    1230             :        "  function fun",
    1231             :        "(a,b) {\n"
    1232             :        "    infunction;\n"
    1233             :        "  }",
    1234             :        "\n"
    1235             :        "  more;",
    1236             :        i::FUNCTION_SCOPE, i::LanguageMode::kSloppy},
    1237             :       {"  start;\n", "(a,b) => a + b", "; more;", i::FUNCTION_SCOPE,
    1238             :        i::LanguageMode::kSloppy},
    1239             :       {"  start;\n", "(a,b) => { return a+b; }", "\nmore;", i::FUNCTION_SCOPE,
    1240             :        i::LanguageMode::kSloppy},
    1241             :       {"  start;\n"
    1242             :        "  (function fun",
    1243             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1244             :        i::LanguageMode::kSloppy},
    1245             :       {"  for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
    1246             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1247             :       {"  for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
    1248             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1249             :       {"  for ",
    1250             :        "(let x = 1 ; x < 10; ++ x) {\n"
    1251             :        "    block;\n"
    1252             :        "  }",
    1253             :        "\n"
    1254             :        "  more;",
    1255             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1256             :       {"  for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
    1257             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1258             :       {"  for ", "(let x = 1 ; x < 10; ++ x) statement",
    1259             :        "\n"
    1260             :        "  more;",
    1261             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1262             :       {"  for ",
    1263             :        "(let x = 1 ; x < 10; ++ x)\n"
    1264             :        "    statement;",
    1265             :        "\n"
    1266             :        "  more;",
    1267             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1268             :       {"  for ", "(let x in {}) { block; }", " more;", i::BLOCK_SCOPE,
    1269             :        i::LanguageMode::kStrict},
    1270             :       {"  for ", "(let x in {}) { block; }", "; more;", i::BLOCK_SCOPE,
    1271             :        i::LanguageMode::kStrict},
    1272             :       {"  for ",
    1273             :        "(let x in {}) {\n"
    1274             :        "    block;\n"
    1275             :        "  }",
    1276             :        "\n"
    1277             :        "  more;",
    1278             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1279             :       {"  for ", "(let x in {}) statement;", " more;", i::BLOCK_SCOPE,
    1280             :        i::LanguageMode::kStrict},
    1281             :       {"  for ", "(let x in {}) statement",
    1282             :        "\n"
    1283             :        "  more;",
    1284             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1285             :       {"  for ",
    1286             :        "(let x in {})\n"
    1287             :        "    statement;",
    1288             :        "\n"
    1289             :        "  more;",
    1290             :        i::BLOCK_SCOPE, i::LanguageMode::kStrict},
    1291             :       // Check that 6-byte and 4-byte encodings of UTF-8 strings do not throw
    1292             :       // the preparser off in terms of byte offsets.
    1293             :       // 2 surrogates, encode a character that doesn't need a surrogate.
    1294             :       {"  'foo\xED\xA0\x81\xED\xB0\x89';\n"
    1295             :        "  (function fun",
    1296             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1297             :        i::LanguageMode::kSloppy},
    1298             :       // 4-byte encoding.
    1299             :       {"  'foo\xF0\x90\x90\x8A';\n"
    1300             :        "  (function fun",
    1301             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1302             :        i::LanguageMode::kSloppy},
    1303             :       // 3-byte encoding of \u0FFF.
    1304             :       {"  'foo\xE0\xBF\xBF';\n"
    1305             :        "  (function fun",
    1306             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1307             :        i::LanguageMode::kSloppy},
    1308             :       // 3-byte surrogate, followed by broken 2-byte surrogate w/ impossible 2nd
    1309             :       // byte and last byte missing.
    1310             :       {"  'foo\xED\xA0\x81\xED\x89';\n"
    1311             :        "  (function fun",
    1312             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1313             :        i::LanguageMode::kSloppy},
    1314             :       // Broken 3-byte encoding of \u0FFF with missing last byte.
    1315             :       {"  'foo\xE0\xBF';\n"
    1316             :        "  (function fun",
    1317             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1318             :        i::LanguageMode::kSloppy},
    1319             :       // Broken 3-byte encoding of \u0FFF with missing 2 last bytes.
    1320             :       {"  'foo\xE0';\n"
    1321             :        "  (function fun",
    1322             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1323             :        i::LanguageMode::kSloppy},
    1324             :       // Broken 3-byte encoding of \u00FF should be a 2-byte encoding.
    1325             :       {"  'foo\xE0\x83\xBF';\n"
    1326             :        "  (function fun",
    1327             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1328             :        i::LanguageMode::kSloppy},
    1329             :       // Broken 3-byte encoding of \u007F should be a 2-byte encoding.
    1330             :       {"  'foo\xE0\x81\xBF';\n"
    1331             :        "  (function fun",
    1332             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1333             :        i::LanguageMode::kSloppy},
    1334             :       // Unpaired lead surrogate.
    1335             :       {"  'foo\xED\xA0\x81';\n"
    1336             :        "  (function fun",
    1337             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1338             :        i::LanguageMode::kSloppy},
    1339             :       // Unpaired lead surrogate where the following code point is a 3-byte
    1340             :       // sequence.
    1341             :       {"  'foo\xED\xA0\x81\xE0\xBF\xBF';\n"
    1342             :        "  (function fun",
    1343             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1344             :        i::LanguageMode::kSloppy},
    1345             :       // Unpaired lead surrogate where the following code point is a 4-byte
    1346             :       // encoding of a trail surrogate.
    1347             :       {"  'foo\xED\xA0\x81\xF0\x8D\xB0\x89';\n"
    1348             :        "  (function fun",
    1349             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1350             :        i::LanguageMode::kSloppy},
    1351             :       // Unpaired trail surrogate.
    1352             :       {"  'foo\xED\xB0\x89';\n"
    1353             :        "  (function fun",
    1354             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1355             :        i::LanguageMode::kSloppy},
    1356             :       // 2-byte encoding of \u00FF.
    1357             :       {"  'foo\xC3\xBF';\n"
    1358             :        "  (function fun",
    1359             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1360             :        i::LanguageMode::kSloppy},
    1361             :       // Broken 2-byte encoding of \u00FF with missing last byte.
    1362             :       {"  'foo\xC3';\n"
    1363             :        "  (function fun",
    1364             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1365             :        i::LanguageMode::kSloppy},
    1366             :       // Broken 2-byte encoding of \u007F should be a 1-byte encoding.
    1367             :       {"  'foo\xC1\xBF';\n"
    1368             :        "  (function fun",
    1369             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1370             :        i::LanguageMode::kSloppy},
    1371             :       // Illegal 5-byte encoding.
    1372             :       {"  'foo\xF8\xBF\xBF\xBF\xBF';\n"
    1373             :        "  (function fun",
    1374             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1375             :        i::LanguageMode::kSloppy},
    1376             :       // Illegal 6-byte encoding.
    1377             :       {"  'foo\xFC\xBF\xBF\xBF\xBF\xBF';\n"
    1378             :        "  (function fun",
    1379             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1380             :        i::LanguageMode::kSloppy},
    1381             :       // Illegal 0xFE byte
    1382             :       {"  'foo\xFE\xBF\xBF\xBF\xBF\xBF\xBF';\n"
    1383             :        "  (function fun",
    1384             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1385             :        i::LanguageMode::kSloppy},
    1386             :       // Illegal 0xFF byte
    1387             :       {"  'foo\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF';\n"
    1388             :        "  (function fun",
    1389             :        "(a,b) { infunction; }", ")();", i::FUNCTION_SCOPE,
    1390             :        i::LanguageMode::kSloppy},
    1391             :       {"  'foo';\n"
    1392             :        "  (function fun",
    1393             :        "(a,b) { 'bar\xED\xA0\x81\xED\xB0\x8B'; }", ")();", i::FUNCTION_SCOPE,
    1394             :        i::LanguageMode::kSloppy},
    1395             :       {"  'foo';\n"
    1396             :        "  (function fun",
    1397             :        "(a,b) { 'bar\xF0\x90\x90\x8C'; }", ")();", i::FUNCTION_SCOPE,
    1398             :        i::LanguageMode::kSloppy},
    1399           5 :       {nullptr, nullptr, nullptr, i::EVAL_SCOPE, i::LanguageMode::kSloppy}};
    1400             : 
    1401             :   i::Isolate* isolate = CcTest::i_isolate();
    1402             :   i::Factory* factory = isolate->factory();
    1403             : 
    1404          10 :   v8::HandleScope handles(CcTest::isolate());
    1405           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1406             :   v8::Context::Scope context_scope(context);
    1407             : 
    1408           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    1409           5 :                                         128 * 1024);
    1410             : 
    1411         515 :   for (int i = 0; source_data[i].outer_prefix; i++) {
    1412         255 :     int kPrefixLen = Utf8LengthHelper(source_data[i].outer_prefix);
    1413         255 :     int kInnerLen = Utf8LengthHelper(source_data[i].inner_source);
    1414         255 :     int kSuffixLen = Utf8LengthHelper(source_data[i].outer_suffix);
    1415             :     int kPrefixByteLen = i::StrLength(source_data[i].outer_prefix);
    1416             :     int kInnerByteLen = i::StrLength(source_data[i].inner_source);
    1417             :     int kSuffixByteLen = i::StrLength(source_data[i].outer_suffix);
    1418         255 :     int kProgramSize = kPrefixLen + kInnerLen + kSuffixLen;
    1419         255 :     int kProgramByteSize = kPrefixByteLen + kInnerByteLen + kSuffixByteLen;
    1420         255 :     i::ScopedVector<char> program(kProgramByteSize + 1);
    1421             :     i::SNPrintF(program, "%s%s%s",
    1422             :                          source_data[i].outer_prefix,
    1423             :                          source_data[i].inner_source,
    1424         255 :                          source_data[i].outer_suffix);
    1425             : 
    1426             :     // Parse program source.
    1427         510 :     i::Handle<i::String> source = factory->NewStringFromUtf8(
    1428             :         i::CStrVector(program.start())).ToHandleChecked();
    1429         255 :     CHECK_EQ(source->length(), kProgramSize);
    1430         255 :     i::Handle<i::Script> script = factory->NewScript(source);
    1431         510 :     i::ParseInfo info(isolate, script);
    1432         255 :     info.set_language_mode(source_data[i].language_mode);
    1433         255 :     i::parsing::ParseProgram(&info, isolate);
    1434         255 :     CHECK_NOT_NULL(info.literal());
    1435             : 
    1436             :     // Check scope types and positions.
    1437             :     i::Scope* scope = info.literal()->scope();
    1438         255 :     CHECK(scope->is_script_scope());
    1439         255 :     CHECK_EQ(0, scope->start_position());
    1440         255 :     CHECK_EQ(scope->end_position(), kProgramSize);
    1441             : 
    1442             :     i::Scope* inner_scope = scope->inner_scope();
    1443             :     DCHECK_NOT_NULL(inner_scope);
    1444             :     DCHECK_NULL(inner_scope->sibling());
    1445         255 :     CHECK_EQ(inner_scope->scope_type(), source_data[i].scope_type);
    1446         255 :     CHECK_EQ(inner_scope->start_position(), kPrefixLen);
    1447             :     // The end position of a token is one position after the last
    1448             :     // character belonging to that token.
    1449         255 :     CHECK_EQ(inner_scope->end_position(), kPrefixLen + kInnerLen);
    1450             :   }
    1451           5 : }
    1452             : 
    1453             : 
    1454       26644 : TEST(DiscardFunctionBody) {
    1455             :   // Test that inner function bodies are discarded if possible.
    1456             :   // See comments in ParseFunctionLiteral in parser.cc.
    1457             :   const char* discard_sources[] = {
    1458             :       "(function f() { function g() { var a; } })();",
    1459             :       "(function f() { function g() { { function h() { } } } })();",
    1460             :       /* TODO(conradw): In future it may be possible to apply this optimisation
    1461             :        * to these productions.
    1462             :       "(function f() { 0, function g() { var a; } })();",
    1463             :       "(function f() { 0, { g() { var a; } } })();",
    1464             :       "(function f() { 0, class c { g() { var a; } } })();", */
    1465           5 :       nullptr};
    1466             : 
    1467             :   i::Isolate* isolate = CcTest::i_isolate();
    1468             :   i::Factory* factory = isolate->factory();
    1469          10 :   v8::HandleScope handles(CcTest::isolate());
    1470             :   i::FunctionLiteral* function;
    1471             : 
    1472          25 :   for (int i = 0; discard_sources[i]; i++) {
    1473             :     const char* source = discard_sources[i];
    1474             :     i::Handle<i::String> source_code =
    1475          20 :         factory->NewStringFromUtf8(i::CStrVector(source)).ToHandleChecked();
    1476          10 :     i::Handle<i::Script> script = factory->NewScript(source_code);
    1477          20 :     i::ParseInfo info(isolate, script);
    1478          10 :     i::parsing::ParseProgram(&info, isolate);
    1479             :     function = info.literal();
    1480          10 :     CHECK_NOT_NULL(function);
    1481          10 :     CHECK_EQ(1, function->body()->length());
    1482             :     i::FunctionLiteral* inner =
    1483          10 :         function->body()->first()->AsExpressionStatement()->expression()->
    1484          20 :         AsCall()->expression()->AsFunctionLiteral();
    1485             :     i::Scope* inner_scope = inner->scope();
    1486             :     i::FunctionLiteral* fun = nullptr;
    1487          10 :     if (!inner_scope->declarations()->is_empty()) {
    1488             :       fun = inner_scope->declarations()
    1489             :                 ->AtForTest(0)
    1490             :                 ->AsFunctionDeclaration()
    1491          10 :                 ->fun();
    1492             :     } else {
    1493             :       // TODO(conradw): This path won't be hit until the other test cases can be
    1494             :       // uncommented.
    1495           0 :       UNREACHABLE();
    1496             :       CHECK(inner->ShouldEagerCompile());
    1497             :       CHECK_GE(2, inner->body()->length());
    1498             :       i::Expression* exp = inner->body()->at(1)->AsExpressionStatement()->
    1499             :                            expression()->AsBinaryOperation()->right();
    1500             :       if (exp->IsFunctionLiteral()) {
    1501             :         fun = exp->AsFunctionLiteral();
    1502             :       } else if (exp->IsObjectLiteral()) {
    1503             :         fun = exp->AsObjectLiteral()->properties()->at(0)->value()->
    1504             :               AsFunctionLiteral();
    1505             :       } else {
    1506             :         fun = exp->AsClassLiteral()->properties()->at(0)->value()->
    1507             :               AsFunctionLiteral();
    1508             :       }
    1509             :     }
    1510          10 :     CHECK(!fun->ShouldEagerCompile());
    1511             :   }
    1512           5 : }
    1513             : 
    1514             : 
    1515           0 : const char* ReadString(unsigned* start) {
    1516           0 :   int length = start[0];
    1517           0 :   char* result = i::NewArray<char>(length + 1);
    1518           0 :   for (int i = 0; i < length; i++) {
    1519           0 :     result[i] = start[i + 1];
    1520             :   }
    1521           0 :   result[length] = '\0';
    1522           0 :   return result;
    1523             : }
    1524             : 
    1525             : enum ParserFlag {
    1526             :   kAllowLazy,
    1527             :   kAllowNatives,
    1528             :   kAllowHarmonyPublicFields,
    1529             :   kAllowHarmonyPrivateFields,
    1530             :   kAllowHarmonyPrivateMethods,
    1531             :   kAllowHarmonyStaticFields,
    1532             :   kAllowHarmonyDynamicImport,
    1533             :   kAllowHarmonyImportMeta,
    1534             :   kAllowHarmonyNumericSeparator
    1535             : };
    1536             : 
    1537             : enum ParserSyncTestResult {
    1538             :   kSuccessOrError,
    1539             :   kSuccess,
    1540             :   kError
    1541             : };
    1542             : 
    1543      525089 : void SetGlobalFlags(base::EnumSet<ParserFlag> flags) {
    1544      525089 :   i::FLAG_allow_natives_syntax = flags.contains(kAllowNatives);
    1545      525089 :   i::FLAG_harmony_public_fields = flags.contains(kAllowHarmonyPublicFields);
    1546      525089 :   i::FLAG_harmony_private_fields = flags.contains(kAllowHarmonyPrivateFields);
    1547      525089 :   i::FLAG_harmony_private_methods = flags.contains(kAllowHarmonyPrivateMethods);
    1548      525089 :   i::FLAG_harmony_static_fields = flags.contains(kAllowHarmonyStaticFields);
    1549      525089 :   i::FLAG_harmony_dynamic_import = flags.contains(kAllowHarmonyDynamicImport);
    1550      525089 :   i::FLAG_harmony_import_meta = flags.contains(kAllowHarmonyImportMeta);
    1551             :   i::FLAG_harmony_numeric_separator =
    1552      525089 :       flags.contains(kAllowHarmonyNumericSeparator);
    1553      525089 : }
    1554             : 
    1555      524109 : void SetParserFlags(i::PreParser* parser, base::EnumSet<ParserFlag> flags) {
    1556             :   parser->set_allow_natives(flags.contains(kAllowNatives));
    1557             :   parser->set_allow_harmony_public_fields(
    1558             :       flags.contains(kAllowHarmonyPublicFields));
    1559             :   parser->set_allow_harmony_private_fields(
    1560             :       flags.contains(kAllowHarmonyPrivateFields));
    1561             :   parser->set_allow_harmony_private_methods(
    1562             :       flags.contains(kAllowHarmonyPrivateMethods));
    1563             :   parser->set_allow_harmony_static_fields(
    1564             :       flags.contains(kAllowHarmonyStaticFields));
    1565             :   parser->set_allow_harmony_dynamic_import(
    1566             :       flags.contains(kAllowHarmonyDynamicImport));
    1567             :   parser->set_allow_harmony_import_meta(
    1568             :       flags.contains(kAllowHarmonyImportMeta));
    1569             :   parser->set_allow_harmony_numeric_separator(
    1570             :       flags.contains(kAllowHarmonyNumericSeparator));
    1571      524109 : }
    1572             : 
    1573      525089 : void TestParserSyncWithFlags(i::Handle<i::String> source,
    1574             :                              base::EnumSet<ParserFlag> flags,
    1575             :                              ParserSyncTestResult result,
    1576             :                              bool is_module = false, bool test_preparser = true,
    1577             :                              bool ignore_error_msg = false) {
    1578             :   i::Isolate* isolate = CcTest::i_isolate();
    1579             :   i::Factory* factory = isolate->factory();
    1580             : 
    1581             :   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
    1582             : 
    1583             :   // Preparse the data.
    1584             :   i::PendingCompilationErrorHandler pending_error_handler;
    1585      525089 :   if (test_preparser) {
    1586             :     std::unique_ptr<i::Utf16CharacterStream> stream(
    1587      524109 :         i::ScannerStream::For(isolate, source));
    1588     1048218 :     i::Scanner scanner(stream.get(), is_module);
    1589     1048218 :     i::Zone zone(isolate->allocator(), ZONE_NAME);
    1590             :     i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
    1591      524109 :                                          HashSeed(isolate));
    1592             :     i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
    1593             :                            &pending_error_handler,
    1594             :                            isolate->counters()->runtime_call_stats(),
    1595     1048218 :                            isolate->logger(), -1, is_module);
    1596      524109 :     SetParserFlags(&preparser, flags);
    1597      524109 :     scanner.Initialize();
    1598      524109 :     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    1599      524109 :     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    1600             :   }
    1601             : 
    1602             :   // Parse the data
    1603             :   i::FunctionLiteral* function;
    1604             :   {
    1605      525089 :     SetGlobalFlags(flags);
    1606      525089 :     i::Handle<i::Script> script = factory->NewScript(source);
    1607     1050178 :     i::ParseInfo info(isolate, script);
    1608             :     info.set_allow_lazy_parsing(flags.contains(kAllowLazy));
    1609      525089 :     if (is_module) info.set_module();
    1610      525089 :     i::parsing::ParseProgram(&info, isolate);
    1611             :     function = info.literal();
    1612             :   }
    1613             : 
    1614             :   // Check that preparsing fails iff parsing fails.
    1615      525089 :   if (function == nullptr) {
    1616             :     // Extract exception from the parser.
    1617      277550 :     CHECK(isolate->has_pending_exception());
    1618             :     i::Handle<i::JSObject> exception_handle(
    1619             :         i::JSObject::cast(isolate->pending_exception()), isolate);
    1620             :     i::Handle<i::String> message_string = i::Handle<i::String>::cast(
    1621      555100 :         i::JSReceiver::GetProperty(isolate, exception_handle, "message")
    1622             :             .ToHandleChecked());
    1623             :     isolate->clear_pending_exception();
    1624             : 
    1625      277550 :     if (result == kSuccess) {
    1626           0 :       FATAL(
    1627             :           "Parser failed on:\n"
    1628             :           "\t%s\n"
    1629             :           "with error:\n"
    1630             :           "\t%s\n"
    1631             :           "However, we expected no error.",
    1632           0 :           source->ToCString().get(), message_string->ToCString().get());
    1633             :     }
    1634             : 
    1635      277550 :     if (test_preparser && !pending_error_handler.has_pending_error() &&
    1636             :         !pending_error_handler.has_error_unidentifiable_by_preparser()) {
    1637           0 :       FATAL(
    1638             :           "Parser failed on:\n"
    1639             :           "\t%s\n"
    1640             :           "with error:\n"
    1641             :           "\t%s\n"
    1642             :           "However, the preparser succeeded",
    1643           0 :           source->ToCString().get(), message_string->ToCString().get());
    1644             :     }
    1645             :     // Check that preparser and parser produce the same error, except for cases
    1646             :     // where we do not track errors in the preparser.
    1647      277550 :     if (test_preparser && !ignore_error_msg &&
    1648             :         !pending_error_handler.has_error_unidentifiable_by_preparser()) {
    1649             :       i::Handle<i::String> preparser_message =
    1650        3042 :           pending_error_handler.FormatErrorMessageForTest(CcTest::i_isolate());
    1651        3042 :       if (!i::String::Equals(isolate, message_string, preparser_message)) {
    1652           0 :         FATAL(
    1653             :             "Expected parser and preparser to produce the same error on:\n"
    1654             :             "\t%s\n"
    1655             :             "However, found the following error messages\n"
    1656             :             "\tparser:    %s\n"
    1657             :             "\tpreparser: %s\n",
    1658             :             source->ToCString().get(), message_string->ToCString().get(),
    1659           0 :             preparser_message->ToCString().get());
    1660             :       }
    1661             :     }
    1662      247539 :   } else if (test_preparser && pending_error_handler.has_pending_error()) {
    1663           0 :     FATAL(
    1664             :         "Preparser failed on:\n"
    1665             :         "\t%s\n"
    1666             :         "with error:\n"
    1667             :         "\t%s\n"
    1668             :         "However, the parser succeeded",
    1669             :         source->ToCString().get(),
    1670             :         pending_error_handler.FormatErrorMessageForTest(CcTest::i_isolate())
    1671             :             ->ToCString()
    1672           0 :             .get());
    1673      247539 :   } else if (result == kError) {
    1674           0 :     FATAL(
    1675             :         "Expected error on:\n"
    1676             :         "\t%s\n"
    1677             :         "However, parser and preparser succeeded",
    1678           0 :         source->ToCString().get());
    1679             :   }
    1680      525089 : }
    1681             : 
    1682      134163 : void TestParserSync(const char* source, const ParserFlag* varying_flags,
    1683             :                     size_t varying_flags_length,
    1684             :                     ParserSyncTestResult result = kSuccessOrError,
    1685             :                     const ParserFlag* always_true_flags = nullptr,
    1686             :                     size_t always_true_flags_length = 0,
    1687             :                     const ParserFlag* always_false_flags = nullptr,
    1688             :                     size_t always_false_flags_length = 0,
    1689             :                     bool is_module = false, bool test_preparser = true,
    1690             :                     bool ignore_error_msg = false) {
    1691             :   i::Handle<i::String> str =
    1692             :       CcTest::i_isolate()
    1693             :           ->factory()
    1694      402489 :           ->NewStringFromUtf8(Vector<const char>(source, strlen(source)))
    1695      134163 :           .ToHandleChecked();
    1696     1184341 :   for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
    1697             :     base::EnumSet<ParserFlag> flags;
    1698     2606873 :     for (size_t flag_index = 0; flag_index < varying_flags_length;
    1699             :          ++flag_index) {
    1700     1040892 :       if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]);
    1701             :     }
    1702      823549 :     for (size_t flag_index = 0; flag_index < always_true_flags_length;
    1703             :          ++flag_index) {
    1704      149230 :       flags.Add(always_true_flags[flag_index]);
    1705             :     }
    1706      525089 :     for (size_t flag_index = 0; flag_index < always_false_flags_length;
    1707             :          ++flag_index) {
    1708           0 :       flags.Remove(always_false_flags[flag_index]);
    1709             :     }
    1710      525089 :     TestParserSyncWithFlags(str, flags, result, is_module, test_preparser,
    1711      525089 :                             ignore_error_msg);
    1712             :   }
    1713      134163 : }
    1714             : 
    1715             : 
    1716       26640 : TEST(ParserSync) {
    1717             :   const char* context_data[][2] = {{"", ""},
    1718             :                                    {"{", "}"},
    1719             :                                    {"if (true) ", " else {}"},
    1720             :                                    {"if (true) {} else ", ""},
    1721             :                                    {"if (true) ", ""},
    1722             :                                    {"do ", " while (false)"},
    1723             :                                    {"while (false) ", ""},
    1724             :                                    {"for (;;) ", ""},
    1725             :                                    {"with ({})", ""},
    1726             :                                    {"switch (12) { case 12: ", "}"},
    1727             :                                    {"switch (12) { default: ", "}"},
    1728             :                                    {"switch (12) { ", "case 12: }"},
    1729             :                                    {"label2: ", ""},
    1730           1 :                                    {nullptr, nullptr}};
    1731             : 
    1732             :   const char* statement_data[] = {
    1733             :       "{}", "var x", "var x = 1", "const x", "const x = 1", ";", "12",
    1734             :       "if (false) {} else ;", "if (false) {} else {}", "if (false) {} else 12",
    1735             :       "if (false) ;", "if (false) {}", "if (false) 12", "do {} while (false)",
    1736             :       "for (;;) ;", "for (;;) {}", "for (;;) 12", "continue", "continue label",
    1737             :       "continue\nlabel", "break", "break label", "break\nlabel",
    1738             :       // TODO(marja): activate once parsing 'return' is merged into ParserBase.
    1739             :       // "return",
    1740             :       // "return  12",
    1741             :       // "return\n12",
    1742             :       "with ({}) ;", "with ({}) {}", "with ({}) 12", "switch ({}) { default: }",
    1743             :       "label3: ", "throw", "throw  12", "throw\n12", "try {} catch(e) {}",
    1744             :       "try {} finally {}", "try {} catch(e) {} finally {}", "debugger",
    1745           1 :       nullptr};
    1746             : 
    1747           1 :   const char* termination_data[] = {"", ";", "\n", ";\n", "\n;", nullptr};
    1748             : 
    1749           2 :   v8::HandleScope handles(CcTest::isolate());
    1750           1 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1751             :   v8::Context::Scope context_scope(context);
    1752             : 
    1753           1 :   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    1754           2 :       i::GetCurrentStackPosition() - 128 * 1024);
    1755             : 
    1756          27 :   for (int i = 0; context_data[i][0] != nullptr; ++i) {
    1757         923 :     for (int j = 0; statement_data[j] != nullptr; ++j) {
    1758        5005 :       for (int k = 0; termination_data[k] != nullptr; ++k) {
    1759             :         int kPrefixLen = i::StrLength(context_data[i][0]);
    1760             :         int kStatementLen = i::StrLength(statement_data[j]);
    1761             :         int kTerminationLen = i::StrLength(termination_data[k]);
    1762        2275 :         int kSuffixLen = i::StrLength(context_data[i][1]);
    1763        2275 :         int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen
    1764        2275 :             + kSuffixLen + i::StrLength("label: for (;;) {  }");
    1765             : 
    1766             :         // Plug the source code pieces together.
    1767        2275 :         i::ScopedVector<char> program(kProgramSize + 1);
    1768             :         int length = i::SNPrintF(program,
    1769             :             "label: for (;;) { %s%s%s%s }",
    1770             :             context_data[i][0],
    1771             :             statement_data[j],
    1772             :             termination_data[k],
    1773        2275 :             context_data[i][1]);
    1774        2275 :         CHECK_EQ(length, kProgramSize);
    1775        2275 :         TestParserSync(program.start(), nullptr, 0);
    1776             :       }
    1777             :     }
    1778             :   }
    1779             : 
    1780             :   // Neither Harmony numeric literals nor our natives syntax have any
    1781             :   // interaction with the flags above, so test these separately to reduce
    1782             :   // the combinatorial explosion.
    1783           1 :   TestParserSync("0o1234", nullptr, 0);
    1784           1 :   TestParserSync("0b1011", nullptr, 0);
    1785             : 
    1786             :   static const ParserFlag flags3[] = { kAllowNatives };
    1787           1 :   TestParserSync("%DebugPrint(123)", flags3, arraysize(flags3));
    1788           1 : }
    1789             : 
    1790             : 
    1791       26644 : TEST(StrictOctal) {
    1792             :   // Test that syntax error caused by octal literal is reported correctly as
    1793             :   // such (issue 2220).
    1794           5 :   v8::V8::Initialize();
    1795           5 :   v8::Isolate* isolate = CcTest::isolate();
    1796          10 :   v8::HandleScope scope(isolate);
    1797          10 :   v8::Context::Scope context_scope(v8::Context::New(isolate));
    1798             : 
    1799          10 :   v8::TryCatch try_catch(isolate);
    1800             :   const char* script =
    1801             :       "\"use strict\";       \n"
    1802             :       "a = function() {      \n"
    1803             :       "  b = function() {    \n"
    1804             :       "    01;               \n"
    1805             :       "  };                  \n"
    1806             :       "};                    \n";
    1807           5 :   v8_compile(v8_str(script));
    1808           5 :   CHECK(try_catch.HasCaught());
    1809          10 :   v8::String::Utf8Value exception(isolate, try_catch.Exception());
    1810           5 :   CHECK_EQ(0,
    1811             :            strcmp("SyntaxError: Octal literals are not allowed in strict mode.",
    1812             :                   *exception));
    1813           5 : }
    1814             : 
    1815        1580 : void RunParserSyncTest(
    1816             :     const char* context_data[][2], const char* statement_data[],
    1817             :     ParserSyncTestResult result, const ParserFlag* flags = nullptr,
    1818             :     int flags_len = 0, const ParserFlag* always_true_flags = nullptr,
    1819             :     int always_true_len = 0, const ParserFlag* always_false_flags = nullptr,
    1820             :     int always_false_len = 0, bool is_module = false,
    1821             :     bool test_preparser = true, bool ignore_error_msg = false) {
    1822        3160 :   v8::HandleScope handles(CcTest::isolate());
    1823        1580 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1824             :   v8::Context::Scope context_scope(context);
    1825             : 
    1826        1580 :   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    1827        3160 :       i::GetCurrentStackPosition() - 128 * 1024);
    1828             : 
    1829             :   // Experimental feature flags should not go here; pass the flags as
    1830             :   // always_true_flags if the test needs them.
    1831             :   static const ParserFlag default_flags[] = {
    1832             :     kAllowLazy,
    1833             :     kAllowNatives,
    1834             :   };
    1835             :   ParserFlag* generated_flags = nullptr;
    1836        1580 :   if (flags == nullptr) {
    1837             :     flags = default_flags;
    1838             :     flags_len = arraysize(default_flags);
    1839        1560 :     if (always_true_flags != nullptr || always_false_flags != nullptr) {
    1840             :       // Remove always_true/false_flags from default_flags (if present).
    1841         190 :       CHECK((always_true_flags != nullptr) == (always_true_len > 0));
    1842         190 :       CHECK((always_false_flags != nullptr) == (always_false_len > 0));
    1843         190 :       generated_flags = new ParserFlag[flags_len + always_true_len];
    1844             :       int flag_index = 0;
    1845         950 :       for (int i = 0; i < flags_len; ++i) {
    1846             :         bool use_flag = true;
    1847        1520 :         for (int j = 0; use_flag && j < always_true_len; ++j) {
    1848         570 :           if (flags[i] == always_true_flags[j]) use_flag = false;
    1849             :         }
    1850         380 :         for (int j = 0; use_flag && j < always_false_len; ++j) {
    1851           0 :           if (flags[i] == always_false_flags[j]) use_flag = false;
    1852             :         }
    1853         380 :         if (use_flag) generated_flags[flag_index++] = flags[i];
    1854             :       }
    1855             :       flags_len = flag_index;
    1856             :       flags = generated_flags;
    1857             :     }
    1858             :   }
    1859       15270 :   for (int i = 0; context_data[i][0] != nullptr; ++i) {
    1860      270615 :     for (int j = 0; statement_data[j] != nullptr; ++j) {
    1861      131885 :       int kPrefixLen = i::StrLength(context_data[i][0]);
    1862             :       int kStatementLen = i::StrLength(statement_data[j]);
    1863      131885 :       int kSuffixLen = i::StrLength(context_data[i][1]);
    1864      131885 :       int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
    1865             : 
    1866             :       // Plug the source code pieces together.
    1867      131885 :       i::ScopedVector<char> program(kProgramSize + 1);
    1868      131885 :       int length = i::SNPrintF(program,
    1869             :                                "%s%s%s",
    1870             :                                context_data[i][0],
    1871             :                                statement_data[j],
    1872      131885 :                                context_data[i][1]);
    1873      131885 :       PrintF("%s\n", program.start());
    1874      131885 :       CHECK_EQ(length, kProgramSize);
    1875      131885 :       TestParserSync(program.start(), flags, flags_len, result,
    1876             :                      always_true_flags, always_true_len, always_false_flags,
    1877             :                      always_false_len, is_module, test_preparser,
    1878      131885 :                      ignore_error_msg);
    1879             :     }
    1880             :   }
    1881        1580 :   delete[] generated_flags;
    1882        1580 : }
    1883             : 
    1884           0 : void RunModuleParserSyncTest(
    1885             :     const char* context_data[][2], const char* statement_data[],
    1886             :     ParserSyncTestResult result, const ParserFlag* flags = nullptr,
    1887             :     int flags_len = 0, const ParserFlag* always_true_flags = nullptr,
    1888             :     int always_true_len = 0, const ParserFlag* always_false_flags = nullptr,
    1889             :     int always_false_len = 0, bool test_preparser = true,
    1890             :     bool ignore_error_msg = false) {
    1891           0 :   RunParserSyncTest(context_data, statement_data, result, flags, flags_len,
    1892             :                     always_true_flags, always_true_len, always_false_flags,
    1893          95 :                     always_false_len, true, test_preparser, ignore_error_msg);
    1894           0 : }
    1895             : 
    1896       26644 : TEST(NumericSeparator) {
    1897          10 :   v8::HandleScope handles(CcTest::isolate());
    1898           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1899             :   v8::Context::Scope context_scope(context);
    1900             : 
    1901             :   const char* context_data[][2] = {
    1902           5 :       {"", ""}, {"\"use strict\";", ""}, {nullptr, nullptr}};
    1903             :   const char* statement_data[] = {
    1904             :       "1_0_0_0", "1_0e+1",  "1_0e+1_0", "0xF_F_FF", "0o7_7_7", "0b0_1_0_1_0",
    1905           5 :       ".3_2_1",  "0.0_2_1", "1_0.0_1",  ".0_1_2",   nullptr};
    1906             : 
    1907             :   static const ParserFlag flags[] = {kAllowHarmonyNumericSeparator};
    1908             :   RunParserSyncTest(context_data, statement_data, kSuccess, nullptr, 0, flags,
    1909           5 :                     1);
    1910             : 
    1911           5 :   RunParserSyncTest(context_data, statement_data, kError);
    1912           5 : }
    1913             : 
    1914       26644 : TEST(NumericSeparatorErrors) {
    1915          10 :   v8::HandleScope handles(CcTest::isolate());
    1916           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1917             :   v8::Context::Scope context_scope(context);
    1918             : 
    1919             :   const char* context_data[][2] = {
    1920           5 :       {"", ""}, {"\"use strict\";", ""}, {nullptr, nullptr}};
    1921             :   const char* statement_data[] = {
    1922             :       "1_0_0_0_", "1e_1",    "1e+_1", "1_e+1",  "1__0",    "0x_1",
    1923             :       "0x1__1",   "0x1_",    "0_x1",  "0_x_1",  "0b_0101", "0b11_",
    1924             :       "0b1__1",   "0_b1",    "0_b_1", "0o777_", "0o_777",  "0o7__77",
    1925           5 :       "0.0_2_1_", "0.0__21", "0_.01", "0._01",  nullptr};
    1926             : 
    1927             :   static const ParserFlag flags[] = {kAllowHarmonyNumericSeparator};
    1928             :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0, flags, 1,
    1929           5 :                     nullptr, 0, false, true, true);
    1930             : 
    1931           5 :   RunParserSyncTest(context_data, statement_data, kError);
    1932           5 : }
    1933             : 
    1934       26644 : TEST(NumericSeparatorImplicitOctalsErrors) {
    1935          10 :   v8::HandleScope handles(CcTest::isolate());
    1936           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1937             :   v8::Context::Scope context_scope(context);
    1938             : 
    1939             :   const char* context_data[][2] = {
    1940           5 :       {"", ""}, {"\"use strict\";", ""}, {nullptr, nullptr}};
    1941             :   const char* statement_data[] = {"00_122",  "0_012",  "07_7_7",
    1942             :                                   "0_7_7_7", "0_777",  "07_7_7_",
    1943           5 :                                   "07__77",  "0__777", nullptr};
    1944             : 
    1945             :   static const ParserFlag flags[] = {kAllowHarmonyNumericSeparator};
    1946             :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0, flags, 1,
    1947           5 :                     nullptr, 0, false, true, true);
    1948             : 
    1949           5 :   RunParserSyncTest(context_data, statement_data, kError);
    1950           5 : }
    1951             : 
    1952       26644 : TEST(NumericSeparatorUnicodeEscapeSequencesErrors) {
    1953          10 :   v8::HandleScope handles(CcTest::isolate());
    1954           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1955             :   v8::Context::Scope context_scope(context);
    1956             : 
    1957             :   const char* context_data[][2] = {
    1958           5 :       {"", ""}, {"'use strict'", ""}, {nullptr, nullptr}};
    1959             :   // https://github.com/tc39/proposal-numeric-separator/issues/25
    1960           5 :   const char* statement_data[] = {"\\u{10_FFFF}", nullptr};
    1961             : 
    1962             :   static const ParserFlag flags[] = {kAllowHarmonyNumericSeparator};
    1963           5 :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0, flags, 1);
    1964             : 
    1965           5 :   RunParserSyncTest(context_data, statement_data, kError);
    1966           5 : }
    1967             : 
    1968       26644 : TEST(ErrorsEvalAndArguments) {
    1969             :   // Tests that both preparsing and parsing produce the right kind of errors for
    1970             :   // using "eval" and "arguments" as identifiers. Without the strict mode, it's
    1971             :   // ok to use "eval" or "arguments" as identifiers. With the strict mode, it
    1972             :   // isn't.
    1973             :   const char* context_data[][2] = {
    1974             :       {"\"use strict\";", ""},
    1975             :       {"var eval; function test_func() {\"use strict\"; ", "}"},
    1976           5 :       {nullptr, nullptr}};
    1977             : 
    1978             :   const char* statement_data[] = {"var eval;",
    1979             :                                   "var arguments",
    1980             :                                   "var foo, eval;",
    1981             :                                   "var foo, arguments;",
    1982             :                                   "try { } catch (eval) { }",
    1983             :                                   "try { } catch (arguments) { }",
    1984             :                                   "function eval() { }",
    1985             :                                   "function arguments() { }",
    1986             :                                   "function foo(eval) { }",
    1987             :                                   "function foo(arguments) { }",
    1988             :                                   "function foo(bar, eval) { }",
    1989             :                                   "function foo(bar, arguments) { }",
    1990             :                                   "(eval) => { }",
    1991             :                                   "(arguments) => { }",
    1992             :                                   "(foo, eval) => { }",
    1993             :                                   "(foo, arguments) => { }",
    1994             :                                   "eval = 1;",
    1995             :                                   "arguments = 1;",
    1996             :                                   "var foo = eval = 1;",
    1997             :                                   "var foo = arguments = 1;",
    1998             :                                   "++eval;",
    1999             :                                   "++arguments;",
    2000             :                                   "eval++;",
    2001             :                                   "arguments++;",
    2002           5 :                                   nullptr};
    2003             : 
    2004           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2005           5 : }
    2006             : 
    2007             : 
    2008       26644 : TEST(NoErrorsEvalAndArgumentsSloppy) {
    2009             :   // Tests that both preparsing and parsing accept "eval" and "arguments" as
    2010             :   // identifiers when needed.
    2011             :   const char* context_data[][2] = {
    2012           5 :       {"", ""}, {"function test_func() {", "}"}, {nullptr, nullptr}};
    2013             : 
    2014             :   const char* statement_data[] = {"var eval;",
    2015             :                                   "var arguments",
    2016             :                                   "var foo, eval;",
    2017             :                                   "var foo, arguments;",
    2018             :                                   "try { } catch (eval) { }",
    2019             :                                   "try { } catch (arguments) { }",
    2020             :                                   "function eval() { }",
    2021             :                                   "function arguments() { }",
    2022             :                                   "function foo(eval) { }",
    2023             :                                   "function foo(arguments) { }",
    2024             :                                   "function foo(bar, eval) { }",
    2025             :                                   "function foo(bar, arguments) { }",
    2026             :                                   "eval = 1;",
    2027             :                                   "arguments = 1;",
    2028             :                                   "var foo = eval = 1;",
    2029             :                                   "var foo = arguments = 1;",
    2030             :                                   "++eval;",
    2031             :                                   "++arguments;",
    2032             :                                   "eval++;",
    2033             :                                   "arguments++;",
    2034           5 :                                   nullptr};
    2035             : 
    2036           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2037           5 : }
    2038             : 
    2039             : 
    2040       26644 : TEST(NoErrorsEvalAndArgumentsStrict) {
    2041             :   const char* context_data[][2] = {
    2042             :       {"\"use strict\";", ""},
    2043             :       {"function test_func() { \"use strict\";", "}"},
    2044             :       {"() => { \"use strict\"; ", "}"},
    2045           5 :       {nullptr, nullptr}};
    2046             : 
    2047             :   const char* statement_data[] = {"eval;",
    2048             :                                   "arguments;",
    2049             :                                   "var foo = eval;",
    2050             :                                   "var foo = arguments;",
    2051             :                                   "var foo = { eval: 1 };",
    2052             :                                   "var foo = { arguments: 1 };",
    2053             :                                   "var foo = { }; foo.eval = {};",
    2054             :                                   "var foo = { }; foo.arguments = {};",
    2055           5 :                                   nullptr};
    2056             : 
    2057           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2058           5 : }
    2059             : 
    2060             : #define FUTURE_STRICT_RESERVED_WORDS_NO_LET(V) \
    2061             :   V(implements)                                \
    2062             :   V(interface)                                 \
    2063             :   V(package)                                   \
    2064             :   V(private)                                   \
    2065             :   V(protected)                                 \
    2066             :   V(public)                                    \
    2067             :   V(static)                                    \
    2068             :   V(yield)
    2069             : 
    2070             : #define FUTURE_STRICT_RESERVED_WORDS(V) \
    2071             :   V(let)                                \
    2072             :   FUTURE_STRICT_RESERVED_WORDS_NO_LET(V)
    2073             : 
    2074             : #define LIMITED_FUTURE_STRICT_RESERVED_WORDS_NO_LET(V) \
    2075             :   V(implements)                                        \
    2076             :   V(static)                                            \
    2077             :   V(yield)
    2078             : 
    2079             : #define LIMITED_FUTURE_STRICT_RESERVED_WORDS(V) \
    2080             :   V(let)                                        \
    2081             :   LIMITED_FUTURE_STRICT_RESERVED_WORDS_NO_LET(V)
    2082             : 
    2083             : #define FUTURE_STRICT_RESERVED_STATEMENTS(NAME) \
    2084             :   "var " #NAME ";",                             \
    2085             :   "var foo, " #NAME ";",                        \
    2086             :   "try { } catch (" #NAME ") { }",              \
    2087             :   "function " #NAME "() { }",                   \
    2088             :   "(function " #NAME "() { })",                 \
    2089             :   "function foo(" #NAME ") { }",                \
    2090             :   "function foo(bar, " #NAME ") { }",           \
    2091             :   #NAME " = 1;",                                \
    2092             :   #NAME " += 1;",                               \
    2093             :   "var foo = " #NAME " = 1;",                   \
    2094             :   "++" #NAME ";",                               \
    2095             :   #NAME " ++;",
    2096             : 
    2097             : // clang-format off
    2098             : #define FUTURE_STRICT_RESERVED_LEX_BINDINGS(NAME) \
    2099             :   "let " #NAME ";",                               \
    2100             :   "for (let " #NAME "; false; ) {}",              \
    2101             :   "for (let " #NAME " in {}) {}",                 \
    2102             :   "for (let " #NAME " of []) {}",                 \
    2103             :   "const " #NAME " = null;",                      \
    2104             :   "for (const " #NAME " = null; false; ) {}",     \
    2105             :   "for (const " #NAME " in {}) {}",               \
    2106             :   "for (const " #NAME " of []) {}",
    2107             : // clang-format on
    2108             : 
    2109       26644 : TEST(ErrorsFutureStrictReservedWords) {
    2110             :   // Tests that both preparsing and parsing produce the right kind of errors for
    2111             :   // using future strict reserved words as identifiers. Without the strict mode,
    2112             :   // it's ok to use future strict reserved words as identifiers. With the strict
    2113             :   // mode, it isn't.
    2114             :   const char* strict_contexts[][2] = {
    2115             :       {"function test_func() {\"use strict\"; ", "}"},
    2116             :       {"() => { \"use strict\"; ", "}"},
    2117           5 :       {nullptr, nullptr}};
    2118             : 
    2119             :   // clang-format off
    2120             :   const char* statement_data[] {
    2121             :     LIMITED_FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_STATEMENTS)
    2122             :     LIMITED_FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_LEX_BINDINGS)
    2123             :     nullptr
    2124           5 :   };
    2125             :   // clang-format on
    2126             : 
    2127           5 :   RunParserSyncTest(strict_contexts, statement_data, kError);
    2128             : 
    2129             :   // From ES2015, 13.3.1.1 Static Semantics: Early Errors:
    2130             :   //
    2131             :   // > LexicalDeclaration : LetOrConst BindingList ;
    2132             :   // >
    2133             :   // > - It is a Syntax Error if the BoundNames of BindingList contains "let".
    2134             :   const char* non_strict_contexts[][2] = {{"", ""},
    2135             :                                           {"function test_func() {", "}"},
    2136             :                                           {"() => {", "}"},
    2137           5 :                                           {nullptr, nullptr}};
    2138             :   const char* invalid_statements[] = {
    2139           5 :       FUTURE_STRICT_RESERVED_LEX_BINDINGS(let) nullptr};
    2140             : 
    2141           5 :   RunParserSyncTest(non_strict_contexts, invalid_statements, kError);
    2142           5 : }
    2143             : 
    2144             : #undef LIMITED_FUTURE_STRICT_RESERVED_WORDS
    2145             : 
    2146             : 
    2147       26644 : TEST(NoErrorsFutureStrictReservedWords) {
    2148             :   const char* context_data[][2] = {{"", ""},
    2149             :                                    {"function test_func() {", "}"},
    2150             :                                    {"() => {", "}"},
    2151           5 :                                    {nullptr, nullptr}};
    2152             : 
    2153             :   // clang-format off
    2154             :   const char* statement_data[] = {
    2155             :     FUTURE_STRICT_RESERVED_WORDS(FUTURE_STRICT_RESERVED_STATEMENTS)
    2156             :     FUTURE_STRICT_RESERVED_WORDS_NO_LET(FUTURE_STRICT_RESERVED_LEX_BINDINGS)
    2157             :     nullptr
    2158           5 :   };
    2159             :   // clang-format on
    2160             : 
    2161           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2162           5 : }
    2163             : 
    2164             : 
    2165       26644 : TEST(ErrorsReservedWords) {
    2166             :   // Tests that both preparsing and parsing produce the right kind of errors for
    2167             :   // using future reserved words as identifiers. These tests don't depend on the
    2168             :   // strict mode.
    2169             :   const char* context_data[][2] = {
    2170             :       {"", ""},
    2171             :       {"\"use strict\";", ""},
    2172             :       {"var eval; function test_func() {", "}"},
    2173             :       {"var eval; function test_func() {\"use strict\"; ", "}"},
    2174             :       {"var eval; () => {", "}"},
    2175             :       {"var eval; () => {\"use strict\"; ", "}"},
    2176           5 :       {nullptr, nullptr}};
    2177             : 
    2178             :   const char* statement_data[] = {"var super;",
    2179             :                                   "var foo, super;",
    2180             :                                   "try { } catch (super) { }",
    2181             :                                   "function super() { }",
    2182             :                                   "function foo(super) { }",
    2183             :                                   "function foo(bar, super) { }",
    2184             :                                   "(super) => { }",
    2185             :                                   "(bar, super) => { }",
    2186             :                                   "super = 1;",
    2187             :                                   "var foo = super = 1;",
    2188             :                                   "++super;",
    2189             :                                   "super++;",
    2190             :                                   "function foo super",
    2191           5 :                                   nullptr};
    2192             : 
    2193           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2194           5 : }
    2195             : 
    2196             : 
    2197       26644 : TEST(NoErrorsLetSloppyAllModes) {
    2198             :   // In sloppy mode, it's okay to use "let" as identifier.
    2199             :   const char* context_data[][2] = {{"", ""},
    2200             :                                    {"function f() {", "}"},
    2201             :                                    {"(function f() {", "})"},
    2202           5 :                                    {nullptr, nullptr}};
    2203             : 
    2204             :   const char* statement_data[] = {
    2205             :       "var let;",
    2206             :       "var foo, let;",
    2207             :       "try { } catch (let) { }",
    2208             :       "function let() { }",
    2209             :       "(function let() { })",
    2210             :       "function foo(let) { }",
    2211             :       "function foo(bar, let) { }",
    2212             :       "let = 1;",
    2213             :       "var foo = let = 1;",
    2214             :       "let * 2;",
    2215             :       "++let;",
    2216             :       "let++;",
    2217             :       "let: 34",
    2218             :       "function let(let) { let: let(let + let(0)); }",
    2219             :       "({ let: 1 })",
    2220             :       "({ get let() { 1 } })",
    2221             :       "let(100)",
    2222             :       "L: let\nx",
    2223             :       "L: let\n{x}",
    2224           5 :       nullptr};
    2225             : 
    2226           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2227           5 : }
    2228             : 
    2229             : 
    2230       26644 : TEST(NoErrorsYieldSloppyAllModes) {
    2231             :   // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
    2232             :   // generator (see other test).
    2233             :   const char* context_data[][2] = {{"", ""},
    2234             :                                    {"function not_gen() {", "}"},
    2235             :                                    {"(function not_gen() {", "})"},
    2236           5 :                                    {nullptr, nullptr}};
    2237             : 
    2238             :   const char* statement_data[] = {
    2239             :       "var yield;",
    2240             :       "var foo, yield;",
    2241             :       "try { } catch (yield) { }",
    2242             :       "function yield() { }",
    2243             :       "(function yield() { })",
    2244             :       "function foo(yield) { }",
    2245             :       "function foo(bar, yield) { }",
    2246             :       "yield = 1;",
    2247             :       "var foo = yield = 1;",
    2248             :       "yield * 2;",
    2249             :       "++yield;",
    2250             :       "yield++;",
    2251             :       "yield: 34",
    2252             :       "function yield(yield) { yield: yield (yield + yield(0)); }",
    2253             :       "({ yield: 1 })",
    2254             :       "({ get yield() { 1 } })",
    2255             :       "yield(100)",
    2256             :       "yield[100]",
    2257           5 :       nullptr};
    2258             : 
    2259           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2260           5 : }
    2261             : 
    2262             : 
    2263       26644 : TEST(NoErrorsYieldSloppyGeneratorsEnabled) {
    2264             :   // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
    2265             :   // generator (see next test).
    2266             :   const char* context_data[][2] = {
    2267             :       {"", ""},
    2268             :       {"function not_gen() {", "}"},
    2269             :       {"function * gen() { function not_gen() {", "} }"},
    2270             :       {"(function not_gen() {", "})"},
    2271             :       {"(function * gen() { (function not_gen() {", "}) })"},
    2272           5 :       {nullptr, nullptr}};
    2273             : 
    2274             :   const char* statement_data[] = {
    2275             :       "var yield;",
    2276             :       "var foo, yield;",
    2277             :       "try { } catch (yield) { }",
    2278             :       "function yield() { }",
    2279             :       "(function yield() { })",
    2280             :       "function foo(yield) { }",
    2281             :       "function foo(bar, yield) { }",
    2282             :       "function * yield() { }",
    2283             :       "yield = 1;",
    2284             :       "var foo = yield = 1;",
    2285             :       "yield * 2;",
    2286             :       "++yield;",
    2287             :       "yield++;",
    2288             :       "yield: 34",
    2289             :       "function yield(yield) { yield: yield (yield + yield(0)); }",
    2290             :       "({ yield: 1 })",
    2291             :       "({ get yield() { 1 } })",
    2292             :       "yield(100)",
    2293             :       "yield[100]",
    2294           5 :       nullptr};
    2295             : 
    2296           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2297           5 : }
    2298             : 
    2299             : 
    2300       26644 : TEST(ErrorsYieldStrict) {
    2301             :   const char* context_data[][2] = {
    2302             :       {"\"use strict\";", ""},
    2303             :       {"\"use strict\"; function not_gen() {", "}"},
    2304             :       {"function test_func() {\"use strict\"; ", "}"},
    2305             :       {"\"use strict\"; function * gen() { function not_gen() {", "} }"},
    2306             :       {"\"use strict\"; (function not_gen() {", "})"},
    2307             :       {"\"use strict\"; (function * gen() { (function not_gen() {", "}) })"},
    2308             :       {"() => {\"use strict\"; ", "}"},
    2309           5 :       {nullptr, nullptr}};
    2310             : 
    2311             :   const char* statement_data[] = {"var yield;",
    2312             :                                   "var foo, yield;",
    2313             :                                   "try { } catch (yield) { }",
    2314             :                                   "function yield() { }",
    2315             :                                   "(function yield() { })",
    2316             :                                   "function foo(yield) { }",
    2317             :                                   "function foo(bar, yield) { }",
    2318             :                                   "function * yield() { }",
    2319             :                                   "(function * yield() { })",
    2320             :                                   "yield = 1;",
    2321             :                                   "var foo = yield = 1;",
    2322             :                                   "++yield;",
    2323             :                                   "yield++;",
    2324             :                                   "yield: 34;",
    2325           5 :                                   nullptr};
    2326             : 
    2327           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2328           5 : }
    2329             : 
    2330             : 
    2331       26644 : TEST(ErrorsYieldSloppy) {
    2332             :   const char* context_data[][2] = {{"", ""},
    2333             :                                    {"function not_gen() {", "}"},
    2334             :                                    {"(function not_gen() {", "})"},
    2335           5 :                                    {nullptr, nullptr}};
    2336             : 
    2337           5 :   const char* statement_data[] = {"(function * yield() { })", nullptr};
    2338             : 
    2339           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2340           5 : }
    2341             : 
    2342             : 
    2343       26644 : TEST(NoErrorsGenerator) {
    2344             :   // clang-format off
    2345             :   const char* context_data[][2] = {
    2346             :     { "function * gen() {", "}" },
    2347             :     { "(function * gen() {", "})" },
    2348             :     { "(function * () {", "})" },
    2349             :     { nullptr, nullptr }
    2350           5 :   };
    2351             : 
    2352             :   const char* statement_data[] = {
    2353             :     // A generator without a body is valid.
    2354             :     ""
    2355             :     // Valid yield expressions inside generators.
    2356             :     "yield 2;",
    2357             :     "yield * 2;",
    2358             :     "yield * \n 2;",
    2359             :     "yield yield 1;",
    2360             :     "yield * yield * 1;",
    2361             :     "yield 3 + (yield 4);",
    2362             :     "yield * 3 + (yield * 4);",
    2363             :     "(yield * 3) + (yield * 4);",
    2364             :     "yield 3; yield 4;",
    2365             :     "yield * 3; yield * 4;",
    2366             :     "(function (yield) { })",
    2367             :     "(function yield() { })",
    2368             :     "yield { yield: 12 }",
    2369             :     "yield /* comment */ { yield: 12 }",
    2370             :     "yield * \n { yield: 12 }",
    2371             :     "yield /* comment */ * \n { yield: 12 }",
    2372             :     // You can return in a generator.
    2373             :     "yield 1; return",
    2374             :     "yield * 1; return",
    2375             :     "yield 1; return 37",
    2376             :     "yield * 1; return 37",
    2377             :     "yield 1; return 37; yield 'dead';",
    2378             :     "yield * 1; return 37; yield * 'dead';",
    2379             :     // Yield is still a valid key in object literals.
    2380             :     "({ yield: 1 })",
    2381             :     "({ get yield() { } })",
    2382             :     // And in assignment pattern computed properties
    2383             :     "({ [yield]: x } = { })",
    2384             :     // Yield without RHS.
    2385             :     "yield;",
    2386             :     "yield",
    2387             :     "yield\n",
    2388             :     "yield /* comment */"
    2389             :     "yield // comment\n"
    2390             :     "(yield)",
    2391             :     "[yield]",
    2392             :     "{yield}",
    2393             :     "yield, yield",
    2394             :     "yield; yield",
    2395             :     "(yield) ? yield : yield",
    2396             :     "(yield) \n ? yield : yield",
    2397             :     // If there is a newline before the next token, we don't look for RHS.
    2398             :     "yield\nfor (;;) {}",
    2399             :     "x = class extends (yield) {}",
    2400             :     "x = class extends f(yield) {}",
    2401             :     "x = class extends (null, yield) { }",
    2402             :     "x = class extends (a ? null : yield) { }",
    2403             :     nullptr
    2404           5 :   };
    2405             :   // clang-format on
    2406             : 
    2407           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2408           5 : }
    2409             : 
    2410             : 
    2411       26644 : TEST(ErrorsYieldGenerator) {
    2412             :   // clang-format off
    2413             :   const char* context_data[][2] = {
    2414             :     { "function * gen() {", "}" },
    2415             :     { "\"use strict\"; function * gen() {", "}" },
    2416             :     { nullptr, nullptr }
    2417           5 :   };
    2418             : 
    2419             :   const char* statement_data[] = {
    2420             :     // Invalid yield expressions inside generators.
    2421             :     "var yield;",
    2422             :     "var foo, yield;",
    2423             :     "try { } catch (yield) { }",
    2424             :     "function yield() { }",
    2425             :     // The name of the NFE is bound in the generator, which does not permit
    2426             :     // yield to be an identifier.
    2427             :     "(function * yield() { })",
    2428             :     // Yield isn't valid as a formal parameter for generators.
    2429             :     "function * foo(yield) { }",
    2430             :     "(function * foo(yield) { })",
    2431             :     "yield = 1;",
    2432             :     "var foo = yield = 1;",
    2433             :     "++yield;",
    2434             :     "yield++;",
    2435             :     "yield *",
    2436             :     "(yield *)",
    2437             :     // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which
    2438             :     // is invalid.
    2439             :     "yield 3 + yield 4;",
    2440             :     "yield: 34",
    2441             :     "yield ? 1 : 2",
    2442             :     // Parses as yield (/ yield): invalid.
    2443             :     "yield / yield",
    2444             :     "+ yield",
    2445             :     "+ yield 3",
    2446             :     // Invalid (no newline allowed between yield and *).
    2447             :     "yield\n*3",
    2448             :     // Invalid (we see a newline, so we parse {yield:42} as a statement, not an
    2449             :     // object literal, and yield is not a valid label).
    2450             :     "yield\n{yield: 42}",
    2451             :     "yield /* comment */\n {yield: 42}",
    2452             :     "yield //comment\n {yield: 42}",
    2453             :     // Destructuring binding and assignment are both disallowed
    2454             :     "var [yield] = [42];",
    2455             :     "var {foo: yield} = {a: 42};",
    2456             :     "[yield] = [42];",
    2457             :     "({a: yield} = {a: 42});",
    2458             :     // Also disallow full yield expressions on LHS
    2459             :     "var [yield 24] = [42];",
    2460             :     "var {foo: yield 24} = {a: 42};",
    2461             :     "[yield 24] = [42];",
    2462             :     "({a: yield 24} = {a: 42});",
    2463             :     "for (yield 'x' in {});",
    2464             :     "for (yield 'x' of {});",
    2465             :     "for (yield 'x' in {} in {});",
    2466             :     "for (yield 'x' in {} of {});",
    2467             :     "class C extends yield { }",
    2468             :     nullptr
    2469           5 :   };
    2470             :   // clang-format on
    2471             : 
    2472           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2473           5 : }
    2474             : 
    2475             : 
    2476       26644 : TEST(ErrorsNameOfStrictFunction) {
    2477             :   // Tests that illegal tokens as names of a strict function produce the correct
    2478             :   // errors.
    2479             :   const char* context_data[][2] = {{"function ", ""},
    2480             :                                    {"\"use strict\"; function", ""},
    2481             :                                    {"function * ", ""},
    2482             :                                    {"\"use strict\"; function * ", ""},
    2483           5 :                                    {nullptr, nullptr}};
    2484             : 
    2485             :   const char* statement_data[] = {
    2486             :       "eval() {\"use strict\";}", "arguments() {\"use strict\";}",
    2487             :       "interface() {\"use strict\";}", "yield() {\"use strict\";}",
    2488             :       // Future reserved words are always illegal
    2489           5 :       "super() { }", "super() {\"use strict\";}", nullptr};
    2490             : 
    2491           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2492           5 : }
    2493             : 
    2494             : 
    2495       26644 : TEST(NoErrorsNameOfStrictFunction) {
    2496           5 :   const char* context_data[][2] = {{"function ", ""}, {nullptr, nullptr}};
    2497             : 
    2498             :   const char* statement_data[] = {"eval() { }", "arguments() { }",
    2499           5 :                                   "interface() { }", "yield() { }", nullptr};
    2500             : 
    2501           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2502           5 : }
    2503             : 
    2504             : 
    2505       26644 : TEST(NoErrorsNameOfStrictGenerator) {
    2506           5 :   const char* context_data[][2] = {{"function * ", ""}, {nullptr, nullptr}};
    2507             : 
    2508             :   const char* statement_data[] = {"eval() { }", "arguments() { }",
    2509           5 :                                   "interface() { }", "yield() { }", nullptr};
    2510             : 
    2511           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2512           5 : }
    2513             : 
    2514             : 
    2515       26644 : TEST(ErrorsIllegalWordsAsLabelsSloppy) {
    2516             :   // Using future reserved words as labels is always an error.
    2517             :   const char* context_data[][2] = {{"", ""},
    2518             :                                    {"function test_func() {", "}"},
    2519             :                                    {"() => {", "}"},
    2520           5 :                                    {nullptr, nullptr}};
    2521             : 
    2522             :   const char* statement_data[] = {"super: while(true) { break super; }",
    2523           5 :                                   nullptr};
    2524             : 
    2525           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2526           5 : }
    2527             : 
    2528             : 
    2529       26644 : TEST(ErrorsIllegalWordsAsLabelsStrict) {
    2530             :   // Tests that illegal tokens as labels produce the correct errors.
    2531             :   const char* context_data[][2] = {
    2532             :       {"\"use strict\";", ""},
    2533             :       {"function test_func() {\"use strict\"; ", "}"},
    2534             :       {"() => {\"use strict\"; ", "}"},
    2535           5 :       {nullptr, nullptr}};
    2536             : 
    2537             : #define LABELLED_WHILE(NAME) #NAME ": while (true) { break " #NAME "; }",
    2538             :   const char* statement_data[] = {
    2539             :       "super: while(true) { break super; }",
    2540           5 :       FUTURE_STRICT_RESERVED_WORDS(LABELLED_WHILE) nullptr};
    2541             : #undef LABELLED_WHILE
    2542             : 
    2543           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2544           5 : }
    2545             : 
    2546             : 
    2547       26644 : TEST(NoErrorsIllegalWordsAsLabels) {
    2548             :   // Using eval and arguments as labels is legal even in strict mode.
    2549             :   const char* context_data[][2] = {
    2550             :       {"", ""},
    2551             :       {"function test_func() {", "}"},
    2552             :       {"() => {", "}"},
    2553             :       {"\"use strict\";", ""},
    2554             :       {"\"use strict\"; function test_func() {", "}"},
    2555             :       {"\"use strict\"; () => {", "}"},
    2556           5 :       {nullptr, nullptr}};
    2557             : 
    2558             :   const char* statement_data[] = {"mylabel: while(true) { break mylabel; }",
    2559             :                                   "eval: while(true) { break eval; }",
    2560             :                                   "arguments: while(true) { break arguments; }",
    2561           5 :                                   nullptr};
    2562             : 
    2563           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2564           5 : }
    2565             : 
    2566             : 
    2567       26644 : TEST(NoErrorsFutureStrictReservedAsLabelsSloppy) {
    2568             :   const char* context_data[][2] = {{"", ""},
    2569             :                                    {"function test_func() {", "}"},
    2570             :                                    {"() => {", "}"},
    2571           5 :                                    {nullptr, nullptr}};
    2572             : 
    2573             : #define LABELLED_WHILE(NAME) #NAME ": while (true) { break " #NAME "; }",
    2574             :   const char* statement_data[]{
    2575           5 :       FUTURE_STRICT_RESERVED_WORDS(LABELLED_WHILE) nullptr};
    2576             : #undef LABELLED_WHILE
    2577             : 
    2578           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2579           5 : }
    2580             : 
    2581             : 
    2582       26644 : TEST(ErrorsParenthesizedLabels) {
    2583             :   // Parenthesized identifiers shouldn't be recognized as labels.
    2584             :   const char* context_data[][2] = {{"", ""},
    2585             :                                    {"function test_func() {", "}"},
    2586             :                                    {"() => {", "}"},
    2587           5 :                                    {nullptr, nullptr}};
    2588             : 
    2589             :   const char* statement_data[] = {"(mylabel): while(true) { break mylabel; }",
    2590           5 :                                   nullptr};
    2591             : 
    2592           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2593           5 : }
    2594             : 
    2595             : 
    2596       26644 : TEST(NoErrorsParenthesizedDirectivePrologue) {
    2597             :   // Parenthesized directive prologue shouldn't be recognized.
    2598           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    2599             : 
    2600           5 :   const char* statement_data[] = {"(\"use strict\"); var eval;", nullptr};
    2601             : 
    2602           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2603           5 : }
    2604             : 
    2605             : 
    2606       26644 : TEST(ErrorsNotAnIdentifierName) {
    2607             :   const char* context_data[][2] = {
    2608           5 :       {"", ""}, {"\"use strict\";", ""}, {nullptr, nullptr}};
    2609             : 
    2610             :   const char* statement_data[] = {"var foo = {}; foo.{;",
    2611             :                                   "var foo = {}; foo.};",
    2612             :                                   "var foo = {}; foo.=;",
    2613             :                                   "var foo = {}; foo.888;",
    2614             :                                   "var foo = {}; foo.-;",
    2615             :                                   "var foo = {}; foo.--;",
    2616           5 :                                   nullptr};
    2617             : 
    2618           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2619           5 : }
    2620             : 
    2621             : 
    2622       26644 : TEST(NoErrorsIdentifierNames) {
    2623             :   // Keywords etc. are valid as property names.
    2624             :   const char* context_data[][2] = {
    2625           5 :       {"", ""}, {"\"use strict\";", ""}, {nullptr, nullptr}};
    2626             : 
    2627             :   const char* statement_data[] = {"var foo = {}; foo.if;",
    2628             :                                   "var foo = {}; foo.yield;",
    2629             :                                   "var foo = {}; foo.super;",
    2630             :                                   "var foo = {}; foo.interface;",
    2631             :                                   "var foo = {}; foo.eval;",
    2632             :                                   "var foo = {}; foo.arguments;",
    2633           5 :                                   nullptr};
    2634             : 
    2635           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2636           5 : }
    2637             : 
    2638       26644 : TEST(FunctionDeclaresItselfStrict) {
    2639             :   // Tests that we produce the right kinds of errors when a function declares
    2640             :   // itself strict (we cannot produce there errors as soon as we see the
    2641             :   // offending identifiers, because we don't know at that point whether the
    2642             :   // function is strict or not).
    2643             :   const char* context_data[][2] = {{"function eval() {", "}"},
    2644             :                                    {"function arguments() {", "}"},
    2645             :                                    {"function yield() {", "}"},
    2646             :                                    {"function interface() {", "}"},
    2647             :                                    {"function foo(eval) {", "}"},
    2648             :                                    {"function foo(arguments) {", "}"},
    2649             :                                    {"function foo(yield) {", "}"},
    2650             :                                    {"function foo(interface) {", "}"},
    2651             :                                    {"function foo(bar, eval) {", "}"},
    2652             :                                    {"function foo(bar, arguments) {", "}"},
    2653             :                                    {"function foo(bar, yield) {", "}"},
    2654             :                                    {"function foo(bar, interface) {", "}"},
    2655             :                                    {"function foo(bar, bar) {", "}"},
    2656           5 :                                    {nullptr, nullptr}};
    2657             : 
    2658           5 :   const char* strict_statement_data[] = {"\"use strict\";", nullptr};
    2659             : 
    2660           5 :   const char* non_strict_statement_data[] = {";", nullptr};
    2661             : 
    2662           5 :   RunParserSyncTest(context_data, strict_statement_data, kError);
    2663           5 :   RunParserSyncTest(context_data, non_strict_statement_data, kSuccess);
    2664           5 : }
    2665             : 
    2666             : 
    2667       26644 : TEST(ErrorsTryWithoutCatchOrFinally) {
    2668           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    2669             : 
    2670             :   const char* statement_data[] = {"try { }", "try { } foo();",
    2671             :                                   "try { } catch (e) foo();",
    2672           5 :                                   "try { } finally foo();", nullptr};
    2673             : 
    2674           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2675           5 : }
    2676             : 
    2677             : 
    2678       26644 : TEST(NoErrorsTryCatchFinally) {
    2679           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    2680             : 
    2681             :   const char* statement_data[] = {"try { } catch (e) { }",
    2682             :                                   "try { } catch (e) { } finally { }",
    2683           5 :                                   "try { } finally { }", nullptr};
    2684             : 
    2685           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2686           5 : }
    2687             : 
    2688       26644 : TEST(OptionalCatchBinding) {
    2689             :   // clang-format off
    2690             :   const char* context_data[][2] = {
    2691             :     {"", ""},
    2692             :     {"'use strict';", ""},
    2693             :     {"try {", "} catch (e) { }"},
    2694             :     {"try {} catch (e) {", "}"},
    2695             :     {"try {", "} catch ({e}) { }"},
    2696             :     {"try {} catch ({e}) {", "}"},
    2697             :     {"function f() {", "}"},
    2698             :     { nullptr, nullptr }
    2699           5 :   };
    2700             : 
    2701             :   const char* statement_data[] = {
    2702             :     "try { } catch { }",
    2703             :     "try { } catch { } finally { }",
    2704             :     "try { let e; } catch { let e; }",
    2705             :     "try { let e; } catch { let e; } finally { let e; }",
    2706             :     nullptr
    2707           5 :   };
    2708             :   // clang-format on
    2709             : 
    2710           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2711           5 : }
    2712             : 
    2713       26644 : TEST(ErrorsRegexpLiteral) {
    2714           5 :   const char* context_data[][2] = {{"var r = ", ""}, {nullptr, nullptr}};
    2715             : 
    2716           5 :   const char* statement_data[] = {"/unterminated", nullptr};
    2717             : 
    2718           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2719           5 : }
    2720             : 
    2721             : 
    2722       26644 : TEST(NoErrorsRegexpLiteral) {
    2723           5 :   const char* context_data[][2] = {{"var r = ", ""}, {nullptr, nullptr}};
    2724             : 
    2725           5 :   const char* statement_data[] = {"/foo/", "/foo/g", nullptr};
    2726             : 
    2727           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2728           5 : }
    2729             : 
    2730             : 
    2731       26644 : TEST(NoErrorsNewExpression) {
    2732             :   const char* context_data[][2] = {
    2733           5 :       {"", ""}, {"var f =", ""}, {nullptr, nullptr}};
    2734             : 
    2735             :   const char* statement_data[] = {
    2736             :       "new foo", "new foo();", "new foo(1);", "new foo(1, 2);",
    2737             :       // The first () will be processed as a part of the NewExpression and the
    2738             :       // second () will be processed as part of LeftHandSideExpression.
    2739             :       "new foo()();",
    2740             :       // The first () will be processed as a part of the inner NewExpression and
    2741             :       // the second () will be processed as a part of the outer NewExpression.
    2742             :       "new new foo()();", "new foo.bar;", "new foo.bar();", "new foo.bar.baz;",
    2743             :       "new foo.bar().baz;", "new foo[bar];", "new foo[bar]();",
    2744             :       "new foo[bar][baz];", "new foo[bar]()[baz];",
    2745             :       "new foo[bar].baz(baz)()[bar].baz;",
    2746             :       "new \"foo\"",  // Runtime error
    2747             :       "new 1",        // Runtime error
    2748             :       // This even runs:
    2749             :       "(new new Function(\"this.x = 1\")).x;",
    2750           5 :       "new new Test_Two(String, 2).v(0123).length;", nullptr};
    2751             : 
    2752           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2753           5 : }
    2754             : 
    2755             : 
    2756       26644 : TEST(ErrorsNewExpression) {
    2757             :   const char* context_data[][2] = {
    2758           5 :       {"", ""}, {"var f =", ""}, {nullptr, nullptr}};
    2759             : 
    2760             :   const char* statement_data[] = {"new foo bar", "new ) foo", "new ++foo",
    2761           5 :                                   "new foo ++", nullptr};
    2762             : 
    2763           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2764           5 : }
    2765             : 
    2766             : 
    2767       26644 : TEST(StrictObjectLiteralChecking) {
    2768             :   const char* context_data[][2] = {{"\"use strict\"; var myobject = {", "};"},
    2769             :                                    {"\"use strict\"; var myobject = {", ",};"},
    2770             :                                    {"var myobject = {", "};"},
    2771             :                                    {"var myobject = {", ",};"},
    2772           5 :                                    {nullptr, nullptr}};
    2773             : 
    2774             :   // These are only errors in strict mode.
    2775             :   const char* statement_data[] = {
    2776             :       "foo: 1, foo: 2", "\"foo\": 1, \"foo\": 2", "foo: 1, \"foo\": 2",
    2777             :       "1: 1, 1: 2",     "1: 1, \"1\": 2",
    2778             :       "get: 1, get: 2",  // Not a getter for real, just a property called get.
    2779             :       "set: 1, set: 2",  // Not a setter for real, just a property called set.
    2780           5 :       nullptr};
    2781             : 
    2782           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2783           5 : }
    2784             : 
    2785             : 
    2786       26644 : TEST(ErrorsObjectLiteralChecking) {
    2787             :   // clang-format off
    2788             :   const char* context_data[][2] = {
    2789             :     {"\"use strict\"; var myobject = {", "};"},
    2790             :     {"var myobject = {", "};"},
    2791             :     { nullptr, nullptr }
    2792           5 :   };
    2793             : 
    2794             :   const char* statement_data[] = {
    2795             :     ",",
    2796             :     // Wrong number of parameters
    2797             :     "get bar(x) {}",
    2798             :     "get bar(x, y) {}",
    2799             :     "set bar() {}",
    2800             :     "set bar(x, y) {}",
    2801             :     // Parsing FunctionLiteral for getter or setter fails
    2802             :     "get foo( +",
    2803             :     "get foo() \"error\"",
    2804             :     // Various forbidden forms
    2805             :     "static x: 0",
    2806             :     "static x(){}",
    2807             :     "static async x(){}",
    2808             :     "static get x(){}",
    2809             :     "static get x : 0",
    2810             :     "static x",
    2811             :     "static 0",
    2812             :     "*x: 0",
    2813             :     "*x",
    2814             :     "*get x(){}",
    2815             :     "*set x(y){}",
    2816             :     "get *x(){}",
    2817             :     "set *x(y){}",
    2818             :     "get x*(){}",
    2819             :     "set x*(y){}",
    2820             :     "x = 0",
    2821             :     "* *x(){}",
    2822             :     "x*(){}",
    2823             :     "static async x(){}",
    2824             :     "static async x : 0",
    2825             :     "static async get x : 0",
    2826             :     "async static x(){}",
    2827             :     "*async x(){}",
    2828             :     "async x*(){}",
    2829             :     "async x : 0",
    2830             :     "async 0 : 0",
    2831             :     "async get x(){}",
    2832             :     "async get *x(){}",
    2833             :     "async set x(y){}",
    2834             :     "async get : 0",
    2835             :     nullptr
    2836           5 :   };
    2837             :   // clang-format on
    2838             : 
    2839           5 :   RunParserSyncTest(context_data, statement_data, kError);
    2840           5 : }
    2841             : 
    2842             : 
    2843       26644 : TEST(NoErrorsObjectLiteralChecking) {
    2844             :   // clang-format off
    2845             :   const char* context_data[][2] = {
    2846             :     {"var myobject = {", "};"},
    2847             :     {"var myobject = {", ",};"},
    2848             :     {"\"use strict\"; var myobject = {", "};"},
    2849             :     {"\"use strict\"; var myobject = {", ",};"},
    2850             :     { nullptr, nullptr }
    2851           5 :   };
    2852             : 
    2853             :   const char* statement_data[] = {
    2854             :     "foo: 1, get foo() {}",
    2855             :     "foo: 1, set foo(v) {}",
    2856             :     "\"foo\": 1, get \"foo\"() {}",
    2857             :     "\"foo\": 1, set \"foo\"(v) {}",
    2858             :     "1: 1, get 1() {}",
    2859             :     "1: 1, set 1(v) {}",
    2860             :     "get foo() {}, get foo() {}",
    2861             :     "set foo(_) {}, set foo(v) {}",
    2862             :     "foo: 1, get \"foo\"() {}",
    2863             :     "foo: 1, set \"foo\"(v) {}",
    2864             :     "\"foo\": 1, get foo() {}",
    2865             :     "\"foo\": 1, set foo(v) {}",
    2866             :     "1: 1, get \"1\"() {}",
    2867             :     "1: 1, set \"1\"(v) {}",
    2868             :     "\"1\": 1, get 1() {}",
    2869             :     "\"1\": 1, set 1(v) {}",
    2870             :     "foo: 1, bar: 2",
    2871             :     "\"foo\": 1, \"bar\": 2",
    2872             :     "1: 1, 2: 2",
    2873             :     // Syntax: IdentifierName ':' AssignmentExpression
    2874             :     "foo: bar = 5 + baz",
    2875             :     // Syntax: 'get' PropertyName '(' ')' '{' FunctionBody '}'
    2876             :     "get foo() {}",
    2877             :     "get \"foo\"() {}",
    2878             :     "get 1() {}",
    2879             :     // Syntax: 'set' PropertyName '(' PropertySetParameterList ')'
    2880             :     //     '{' FunctionBody '}'
    2881             :     "set foo(v) {}",
    2882             :     "set \"foo\"(v) {}",
    2883             :     "set 1(v) {}",
    2884             :     // Non-colliding getters and setters -> no errors
    2885             :     "foo: 1, get bar() {}",
    2886             :     "foo: 1, set bar(v) {}",
    2887             :     "\"foo\": 1, get \"bar\"() {}",
    2888             :     "\"foo\": 1, set \"bar\"(v) {}",
    2889             :     "1: 1, get 2() {}",
    2890             :     "1: 1, set 2(v) {}",
    2891             :     "get: 1, get foo() {}",
    2892             :     "set: 1, set foo(_) {}",
    2893             :     // Potentially confusing cases
    2894             :     "get(){}",
    2895             :     "set(){}",
    2896             :     "static(){}",
    2897             :     "async(){}",
    2898             :     "*get() {}",
    2899             :     "*set() {}",
    2900             :     "*static() {}",
    2901             :     "*async(){}",
    2902             :     "get : 0",
    2903             :     "set : 0",
    2904             :     "static : 0",
    2905             :     "async : 0",
    2906             :     // Keywords, future reserved and strict future reserved are also allowed as
    2907             :     // property names.
    2908             :     "if: 4",
    2909             :     "interface: 5",
    2910             :     "super: 6",
    2911             :     "eval: 7",
    2912             :     "arguments: 8",
    2913             :     "async x(){}",
    2914             :     "async 0(){}",
    2915             :     "async get(){}",
    2916             :     "async set(){}",
    2917             :     "async static(){}",
    2918             :     "async async(){}",
    2919             :     "async : 0",
    2920             :     "async(){}",
    2921             :     "*async(){}",
    2922             :     nullptr
    2923           5 :   };
    2924             :   // clang-format on
    2925             : 
    2926           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    2927           5 : }
    2928             : 
    2929             : 
    2930       26644 : TEST(TooManyArguments) {
    2931           5 :   const char* context_data[][2] = {{"foo(", "0)"}, {nullptr, nullptr}};
    2932             : 
    2933             :   using v8::internal::Code;
    2934             :   char statement[Code::kMaxArguments * 2 + 1];
    2935      655345 :   for (int i = 0; i < Code::kMaxArguments; ++i) {
    2936      327670 :     statement[2 * i] = '0';
    2937      327670 :     statement[2 * i + 1] = ',';
    2938             :   }
    2939           5 :   statement[Code::kMaxArguments * 2] = 0;
    2940             : 
    2941           5 :   const char* statement_data[] = {statement, nullptr};
    2942             : 
    2943             :   // The test is quite slow, so run it with a reduced set of flags.
    2944             :   static const ParserFlag empty_flags[] = {kAllowLazy};
    2945           5 :   RunParserSyncTest(context_data, statement_data, kError, empty_flags, 1);
    2946           5 : }
    2947             : 
    2948             : 
    2949       26644 : TEST(StrictDelete) {
    2950             :   // "delete <Identifier>" is not allowed in strict mode.
    2951             :   const char* strict_context_data[][2] = {{"\"use strict\"; ", ""},
    2952           5 :                                           {nullptr, nullptr}};
    2953             : 
    2954           5 :   const char* sloppy_context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    2955             : 
    2956             :   // These are errors in the strict mode.
    2957             :   const char* sloppy_statement_data[] = {"delete foo;",       "delete foo + 1;",
    2958             :                                          "delete (foo);",     "delete eval;",
    2959           5 :                                          "delete interface;", nullptr};
    2960             : 
    2961             :   // These are always OK
    2962             :   const char* good_statement_data[] = {"delete this;",
    2963             :                                        "delete 1;",
    2964             :                                        "delete 1 + 2;",
    2965             :                                        "delete foo();",
    2966             :                                        "delete foo.bar;",
    2967             :                                        "delete foo[bar];",
    2968             :                                        "delete foo--;",
    2969             :                                        "delete --foo;",
    2970             :                                        "delete new foo();",
    2971             :                                        "delete new foo(bar);",
    2972           5 :                                        nullptr};
    2973             : 
    2974             :   // These are always errors
    2975           5 :   const char* bad_statement_data[] = {"delete if;", nullptr};
    2976             : 
    2977           5 :   RunParserSyncTest(strict_context_data, sloppy_statement_data, kError);
    2978           5 :   RunParserSyncTest(sloppy_context_data, sloppy_statement_data, kSuccess);
    2979             : 
    2980           5 :   RunParserSyncTest(strict_context_data, good_statement_data, kSuccess);
    2981           5 :   RunParserSyncTest(sloppy_context_data, good_statement_data, kSuccess);
    2982             : 
    2983           5 :   RunParserSyncTest(strict_context_data, bad_statement_data, kError);
    2984           5 :   RunParserSyncTest(sloppy_context_data, bad_statement_data, kError);
    2985           5 : }
    2986             : 
    2987             : 
    2988       26644 : TEST(NoErrorsDeclsInCase) {
    2989             :   const char* context_data[][2] = {
    2990             :     {"'use strict'; switch(x) { case 1:", "}"},
    2991             :     {"function foo() {'use strict'; switch(x) { case 1:", "}}"},
    2992             :     {"'use strict'; switch(x) { case 1: case 2:", "}"},
    2993             :     {"function foo() {'use strict'; switch(x) { case 1: case 2:", "}}"},
    2994             :     {"'use strict'; switch(x) { default:", "}"},
    2995             :     {"function foo() {'use strict'; switch(x) { default:", "}}"},
    2996             :     {"'use strict'; switch(x) { case 1: default:", "}"},
    2997             :     {"function foo() {'use strict'; switch(x) { case 1: default:", "}}"},
    2998             :     { nullptr, nullptr }
    2999           5 :   };
    3000             : 
    3001             :   const char* statement_data[] = {
    3002             :     "function f() { }",
    3003             :     "class C { }",
    3004             :     "class C extends Q {}",
    3005             :     "function f() { } class C {}",
    3006             :     "function f() { }; class C {}",
    3007             :     "class C {}; function f() {}",
    3008             :     nullptr
    3009           5 :   };
    3010             : 
    3011           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    3012           5 : }
    3013             : 
    3014             : 
    3015       26644 : TEST(InvalidLeftHandSide) {
    3016             :   const char* assignment_context_data[][2] = {
    3017           5 :       {"", " = 1;"}, {"\"use strict\"; ", " = 1;"}, {nullptr, nullptr}};
    3018             : 
    3019             :   const char* prefix_context_data[][2] = {
    3020             :       {"++", ";"}, {"\"use strict\"; ++", ";"}, {nullptr, nullptr},
    3021           5 :   };
    3022             : 
    3023             :   const char* postfix_context_data[][2] = {
    3024           5 :       {"", "++;"}, {"\"use strict\"; ", "++;"}, {nullptr, nullptr}};
    3025             : 
    3026             :   // Good left hand sides for assigment or prefix / postfix operations.
    3027             :   const char* good_statement_data[] = {"foo",
    3028             :                                        "foo.bar",
    3029             :                                        "foo[bar]",
    3030             :                                        "foo()[bar]",
    3031             :                                        "foo().bar",
    3032             :                                        "this.foo",
    3033             :                                        "this[foo]",
    3034             :                                        "new foo()[bar]",
    3035             :                                        "new foo().bar",
    3036             :                                        "foo()",
    3037             :                                        "foo(bar)",
    3038             :                                        "foo[bar]()",
    3039             :                                        "foo.bar()",
    3040             :                                        "this()",
    3041             :                                        "this.foo()",
    3042             :                                        "this[foo].bar()",
    3043             :                                        "this.foo[foo].bar(this)(bar)[foo]()",
    3044           5 :                                        nullptr};
    3045             : 
    3046             :   // Bad left hand sides for assigment or prefix / postfix operations.
    3047             :   const char* bad_statement_data_common[] = {
    3048             :       "2",
    3049             :       "new foo",
    3050             :       "new foo()",
    3051             :       "null",
    3052             :       "if",      // Unexpected token
    3053             :       "{x: 1}",  // Unexpected token
    3054             :       "this",
    3055             :       "\"bar\"",
    3056             :       "(foo + bar)",
    3057             :       "new new foo()[bar]",  // means: new (new foo()[bar])
    3058             :       "new new foo().bar",   // means: new (new foo()[bar])
    3059           5 :       nullptr};
    3060             : 
    3061             :   // These are not okay for assignment, but okay for prefix / postix.
    3062             :   const char* bad_statement_data_for_assignment[] = {"++foo", "foo++",
    3063           5 :                                                      "foo + bar", nullptr};
    3064             : 
    3065           5 :   RunParserSyncTest(assignment_context_data, good_statement_data, kSuccess);
    3066           5 :   RunParserSyncTest(assignment_context_data, bad_statement_data_common, kError);
    3067             :   RunParserSyncTest(assignment_context_data, bad_statement_data_for_assignment,
    3068           5 :                     kError);
    3069             : 
    3070           5 :   RunParserSyncTest(prefix_context_data, good_statement_data, kSuccess);
    3071           5 :   RunParserSyncTest(prefix_context_data, bad_statement_data_common, kError);
    3072             : 
    3073           5 :   RunParserSyncTest(postfix_context_data, good_statement_data, kSuccess);
    3074           5 :   RunParserSyncTest(postfix_context_data, bad_statement_data_common, kError);
    3075           5 : }
    3076             : 
    3077             : 
    3078       26644 : TEST(FuncNameInferrerBasic) {
    3079             :   // Tests that function names are inferred properly.
    3080           5 :   i::FLAG_allow_natives_syntax = true;
    3081           5 :   v8::Isolate* isolate = CcTest::isolate();
    3082          10 :   v8::HandleScope scope(isolate);
    3083           5 :   LocalContext env;
    3084             :   CompileRun("var foo1 = function() {}; "
    3085             :              "var foo2 = function foo3() {}; "
    3086             :              "function not_ctor() { "
    3087             :              "  var foo4 = function() {}; "
    3088             :              "  return %FunctionGetInferredName(foo4); "
    3089             :              "} "
    3090             :              "function Ctor() { "
    3091             :              "  var foo5 = function() {}; "
    3092             :              "  return %FunctionGetInferredName(foo5); "
    3093             :              "} "
    3094             :              "var obj1 = { foo6: function() {} }; "
    3095             :              "var obj2 = { 'foo7': function() {} }; "
    3096             :              "var obj3 = {}; "
    3097             :              "obj3[1] = function() {}; "
    3098             :              "var obj4 = {}; "
    3099             :              "obj4[1] = function foo8() {}; "
    3100             :              "var obj5 = {}; "
    3101             :              "obj5['foo9'] = function() {}; "
    3102             :              "var obj6 = { obj7 : { foo10: function() {} } };");
    3103           5 :   ExpectString("%FunctionGetInferredName(foo1)", "foo1");
    3104             :   // foo2 is not unnamed -> its name is not inferred.
    3105           5 :   ExpectString("%FunctionGetInferredName(foo2)", "");
    3106           5 :   ExpectString("not_ctor()", "foo4");
    3107           5 :   ExpectString("Ctor()", "Ctor.foo5");
    3108           5 :   ExpectString("%FunctionGetInferredName(obj1.foo6)", "obj1.foo6");
    3109           5 :   ExpectString("%FunctionGetInferredName(obj2.foo7)", "obj2.foo7");
    3110           5 :   ExpectString("%FunctionGetInferredName(obj3[1])", "obj3.<computed>");
    3111           5 :   ExpectString("%FunctionGetInferredName(obj4[1])", "");
    3112           5 :   ExpectString("%FunctionGetInferredName(obj5['foo9'])", "obj5.foo9");
    3113           5 :   ExpectString("%FunctionGetInferredName(obj6.obj7.foo10)", "obj6.obj7.foo10");
    3114           5 : }
    3115             : 
    3116             : 
    3117       26644 : TEST(FuncNameInferrerTwoByte) {
    3118             :   // Tests function name inferring in cases where some parts of the inferred
    3119             :   // function name are two-byte strings.
    3120           5 :   i::FLAG_allow_natives_syntax = true;
    3121           5 :   v8::Isolate* isolate = CcTest::isolate();
    3122          10 :   v8::HandleScope scope(isolate);
    3123           5 :   LocalContext env;
    3124             :   uint16_t* two_byte_source = AsciiToTwoByteString(
    3125             :       "var obj1 = { oXj2 : { foo1: function() {} } }; "
    3126           5 :       "%FunctionGetInferredName(obj1.oXj2.foo1)");
    3127           5 :   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
    3128             :   // Make it really non-Latin1 (replace the Xs with a non-Latin1 character).
    3129           5 :   two_byte_source[14] = two_byte_source[78] = two_byte_name[6] = 0x010D;
    3130             :   v8::Local<v8::String> source =
    3131           5 :       v8::String::NewFromTwoByte(isolate, two_byte_source,
    3132             :                                  v8::NewStringType::kNormal)
    3133           5 :           .ToLocalChecked();
    3134           5 :   v8::Local<v8::Value> result = CompileRun(source);
    3135           5 :   CHECK(result->IsString());
    3136             :   v8::Local<v8::String> expected_name =
    3137           5 :       v8::String::NewFromTwoByte(isolate, two_byte_name,
    3138             :                                  v8::NewStringType::kNormal)
    3139             :           .ToLocalChecked();
    3140          10 :   CHECK(result->Equals(isolate->GetCurrentContext(), expected_name).FromJust());
    3141             :   i::DeleteArray(two_byte_source);
    3142             :   i::DeleteArray(two_byte_name);
    3143           5 : }
    3144             : 
    3145             : 
    3146       26644 : TEST(FuncNameInferrerEscaped) {
    3147             :   // The same as FuncNameInferrerTwoByte, except that we express the two-byte
    3148             :   // character as a Unicode escape.
    3149           5 :   i::FLAG_allow_natives_syntax = true;
    3150           5 :   v8::Isolate* isolate = CcTest::isolate();
    3151          10 :   v8::HandleScope scope(isolate);
    3152           5 :   LocalContext env;
    3153             :   uint16_t* two_byte_source = AsciiToTwoByteString(
    3154             :       "var obj1 = { o\\u010dj2 : { foo1: function() {} } }; "
    3155           5 :       "%FunctionGetInferredName(obj1.o\\u010dj2.foo1)");
    3156           5 :   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
    3157             :   // Fix to correspond to the non-ASCII name in two_byte_source.
    3158           5 :   two_byte_name[6] = 0x010D;
    3159             :   v8::Local<v8::String> source =
    3160           5 :       v8::String::NewFromTwoByte(isolate, two_byte_source,
    3161             :                                  v8::NewStringType::kNormal)
    3162           5 :           .ToLocalChecked();
    3163           5 :   v8::Local<v8::Value> result = CompileRun(source);
    3164           5 :   CHECK(result->IsString());
    3165             :   v8::Local<v8::String> expected_name =
    3166           5 :       v8::String::NewFromTwoByte(isolate, two_byte_name,
    3167             :                                  v8::NewStringType::kNormal)
    3168             :           .ToLocalChecked();
    3169          10 :   CHECK(result->Equals(isolate->GetCurrentContext(), expected_name).FromJust());
    3170             :   i::DeleteArray(two_byte_source);
    3171             :   i::DeleteArray(two_byte_name);
    3172           5 : }
    3173             : 
    3174             : 
    3175       26644 : TEST(RegressionLazyFunctionWithErrorWithArg) {
    3176             :   // Test only applies when lazy parsing.
    3177           5 :   if (!i::FLAG_lazy) return;
    3178             : 
    3179             :   // The bug occurred when a lazy function had an error which requires a
    3180             :   // parameter (such as "unknown label" here). The error message was processed
    3181             :   // before the AstValueFactory containing the error message string was
    3182             :   // internalized.
    3183           5 :   v8::Isolate* isolate = CcTest::isolate();
    3184          10 :   v8::HandleScope scope(isolate);
    3185           5 :   LocalContext env;
    3186           5 :   i::FLAG_lazy = true;
    3187             :   CompileRun("function this_is_lazy() {\n"
    3188             :              "  break p;\n"
    3189             :              "}\n"
    3190             :              "this_is_lazy();\n");
    3191             : }
    3192             : 
    3193             : 
    3194       26644 : TEST(SerializationOfMaybeAssignmentFlag) {
    3195             :   i::Isolate* isolate = CcTest::i_isolate();
    3196             :   i::Factory* factory = isolate->factory();
    3197             :   i::HandleScope scope(isolate);
    3198           5 :   LocalContext env;
    3199             : 
    3200             :   const char* src =
    3201             :       "function h() {"
    3202             :       "  var result = [];"
    3203             :       "  function f() {"
    3204             :       "    result.push(2);"
    3205             :       "  }"
    3206             :       "  function assertResult(r) {"
    3207             :       "    f();"
    3208             :       "    result = [];"
    3209             :       "  }"
    3210             :       "  assertResult([2]);"
    3211             :       "  assertResult([2]);"
    3212             :       "  return f;"
    3213             :       "};"
    3214             :       "h();";
    3215             : 
    3216           5 :   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
    3217           5 :   i::SNPrintF(program, "%s", src);
    3218           5 :   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
    3219          10 :   source->PrintOn(stdout);
    3220             :   printf("\n");
    3221          10 :   i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
    3222             :   v8::Local<v8::Value> v = CompileRun(src);
    3223             :   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    3224             :   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
    3225           5 :   i::Context context = f->context();
    3226             :   i::AstValueFactory avf(&zone, isolate->ast_string_constants(),
    3227           5 :                          HashSeed(isolate));
    3228           5 :   const i::AstRawString* name = avf.GetOneByteString("result");
    3229           5 :   avf.Internalize(isolate);
    3230             :   i::Handle<i::String> str = name->string();
    3231           5 :   CHECK(str->IsInternalizedString());
    3232             :   i::DeclarationScope* script_scope =
    3233           5 :       new (&zone) i::DeclarationScope(&zone, &avf);
    3234           5 :   i::Scope* s = i::Scope::DeserializeScopeChain(
    3235             :       isolate, &zone, context->scope_info(), script_scope, &avf,
    3236           5 :       i::Scope::DeserializationMode::kIncludingVariables);
    3237           5 :   CHECK(s != script_scope);
    3238           5 :   CHECK_NOT_NULL(name);
    3239             : 
    3240             :   // Get result from h's function context (that is f's context)
    3241             :   i::Variable* var = s->LookupForTesting(name);
    3242             : 
    3243           5 :   CHECK_NOT_NULL(var);
    3244             :   // Maybe assigned should survive deserialization
    3245           5 :   CHECK_EQ(var->maybe_assigned(), i::kMaybeAssigned);
    3246             :   // TODO(sigurds) Figure out if is_used should survive context serialization.
    3247           5 : }
    3248             : 
    3249             : 
    3250       26644 : TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) {
    3251             :   i::Isolate* isolate = CcTest::i_isolate();
    3252             :   i::Factory* factory = isolate->factory();
    3253             :   i::HandleScope scope(isolate);
    3254           5 :   LocalContext env;
    3255             : 
    3256             :   const char* src =
    3257             :       "function f(x) {"
    3258             :       "    var a = arguments;"
    3259             :       "    function g(i) {"
    3260             :       "      ++a[0];"
    3261             :       "    };"
    3262             :       "    return g;"
    3263             :       "  }"
    3264             :       "f(0);";
    3265             : 
    3266           5 :   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
    3267           5 :   i::SNPrintF(program, "%s", src);
    3268           5 :   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
    3269          10 :   source->PrintOn(stdout);
    3270             :   printf("\n");
    3271          10 :   i::Zone zone(isolate->allocator(), ZONE_NAME);
    3272             :   v8::Local<v8::Value> v = CompileRun(src);
    3273             :   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    3274             :   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
    3275           5 :   i::Context context = f->context();
    3276             :   i::AstValueFactory avf(&zone, isolate->ast_string_constants(),
    3277           5 :                          HashSeed(isolate));
    3278           5 :   const i::AstRawString* name_x = avf.GetOneByteString("x");
    3279           5 :   avf.Internalize(isolate);
    3280             : 
    3281             :   i::DeclarationScope* script_scope =
    3282           5 :       new (&zone) i::DeclarationScope(&zone, &avf);
    3283           5 :   i::Scope* s = i::Scope::DeserializeScopeChain(
    3284             :       isolate, &zone, context->scope_info(), script_scope, &avf,
    3285           5 :       i::Scope::DeserializationMode::kIncludingVariables);
    3286           5 :   CHECK(s != script_scope);
    3287             : 
    3288             :   // Get result from f's function context (that is g's outer context)
    3289             :   i::Variable* var_x = s->LookupForTesting(name_x);
    3290           5 :   CHECK_NOT_NULL(var_x);
    3291           5 :   CHECK_EQ(var_x->maybe_assigned(), i::kMaybeAssigned);
    3292           5 : }
    3293             : 
    3294             : 
    3295       26644 : TEST(InnerAssignment) {
    3296             :   i::Isolate* isolate = CcTest::i_isolate();
    3297             :   i::Factory* factory = isolate->factory();
    3298             :   i::HandleScope scope(isolate);
    3299           5 :   LocalContext env;
    3300             : 
    3301             :   const char* prefix = "function f() {";
    3302             :   const char* midfix = " function g() {";
    3303             :   const char* suffix = "}}; f";
    3304             :   struct {
    3305             :     const char* source;
    3306             :     bool assigned;
    3307             :     bool strict;
    3308             :   } outers[] = {
    3309             :       // Actual assignments.
    3310             :       {"var x; var x = 5;", true, false},
    3311             :       {"var x; { var x = 5; }", true, false},
    3312             :       {"'use strict'; let x; x = 6;", true, true},
    3313             :       {"var x = 5; function x() {}", true, false},
    3314             :       {"var x = 4; var x = 5;", true, false},
    3315             :       {"var [x, x] = [4, 5];", true, false},
    3316             :       {"var x; [x, x] = [4, 5];", true, false},
    3317             :       {"var {a: x, b: x} = {a: 4, b: 5};", true, false},
    3318             :       {"var x = {a: 4, b: (x = 5)};", true, false},
    3319             :       {"var {x=1} = {a: 4, b: (x = 5)};", true, false},
    3320             :       {"var {x} = {x: 4, b: (x = 5)};", true, false},
    3321             :       // Actual non-assignments.
    3322             :       {"var x;", false, false},
    3323             :       {"var x = 5;", false, false},
    3324             :       {"'use strict'; let x;", false, true},
    3325             :       {"'use strict'; let x = 6;", false, true},
    3326             :       {"'use strict'; var x = 0; { let x = 6; }", false, true},
    3327             :       {"'use strict'; var x = 0; { let x; x = 6; }", false, true},
    3328             :       {"'use strict'; let x = 0; { let x = 6; }", false, true},
    3329             :       {"'use strict'; let x = 0; { let x; x = 6; }", false, true},
    3330             :       {"var x; try {} catch (x) { x = 5; }", false, false},
    3331             :       {"function x() {}", false, false},
    3332             :       // Eval approximation.
    3333             :       {"var x; eval('');", true, false},
    3334             :       {"eval(''); var x;", true, false},
    3335             :       {"'use strict'; let x; eval('');", true, true},
    3336             :       {"'use strict'; eval(''); let x;", true, true},
    3337             :       // Non-assignments not recognized, because the analysis is approximative.
    3338             :       {"var x; var x;", true, false},
    3339             :       {"var x = 5; var x;", true, false},
    3340             :       {"var x; { var x; }", true, false},
    3341             :       {"var x; function x() {}", true, false},
    3342             :       {"function x() {}; var x;", true, false},
    3343             :       {"var x; try {} catch (x) { var x = 5; }", true, false},
    3344           5 :   };
    3345             : 
    3346             :   // We set allow_error_in_inner_function to true in cases where our handling of
    3347             :   // assigned variables in lazy inner functions is currently overly pessimistic.
    3348             :   // FIXME(marja): remove it when no longer needed.
    3349             :   struct {
    3350             :     const char* source;
    3351             :     bool assigned;
    3352             :     bool with;
    3353             :     bool allow_error_in_inner_function;
    3354             :   } inners[] = {
    3355             :       // Actual assignments.
    3356             :       {"x = 1;", true, false, false},
    3357             :       {"x++;", true, false, false},
    3358             :       {"++x;", true, false, false},
    3359             :       {"x--;", true, false, false},
    3360             :       {"--x;", true, false, false},
    3361             :       {"{ x = 1; }", true, false, false},
    3362             :       {"'use strict'; { let x; }; x = 0;", true, false, false},
    3363             :       {"'use strict'; { const x = 1; }; x = 0;", true, false, false},
    3364             :       {"'use strict'; { function x() {} }; x = 0;", true, false, false},
    3365             :       {"with ({}) { x = 1; }", true, true, false},
    3366             :       {"eval('');", true, false, false},
    3367             :       {"'use strict'; { let y; eval('') }", true, false, false},
    3368             :       {"function h() { x = 0; }", true, false, false},
    3369             :       {"(function() { x = 0; })", true, false, false},
    3370             :       {"(function() { x = 0; })", true, false, false},
    3371             :       {"with ({}) (function() { x = 0; })", true, true, false},
    3372             :       {"for (x of [1,2,3]) {}", true, false, false},
    3373             :       {"for (x in {a: 1}) {}", true, false, false},
    3374             :       {"for ([x] of [[1],[2],[3]]) {}", true, false, false},
    3375             :       {"for ([x] in {ab: 1}) {}", true, false, false},
    3376             :       {"for ([...x] in {ab: 1}) {}", true, false, false},
    3377             :       {"[x] = [1]", true, false, false},
    3378             :       // Actual non-assignments.
    3379             :       {"", false, false, false},
    3380             :       {"x;", false, false, false},
    3381             :       {"var x;", false, false, false},
    3382             :       {"var x = 8;", false, false, false},
    3383             :       {"var x; x = 8;", false, false, false},
    3384             :       {"'use strict'; let x;", false, false, false},
    3385             :       {"'use strict'; let x = 8;", false, false, false},
    3386             :       {"'use strict'; let x; x = 8;", false, false, false},
    3387             :       {"'use strict'; const x = 8;", false, false, false},
    3388             :       {"function x() {}", false, false, false},
    3389             :       {"function x() { x = 0; }", false, false, true},
    3390             :       {"function h(x) { x = 0; }", false, false, false},
    3391             :       {"'use strict'; { let x; x = 0; }", false, false, false},
    3392             :       {"{ var x; }; x = 0;", false, false, false},
    3393             :       {"with ({}) {}", false, true, false},
    3394             :       {"var x; { with ({}) { x = 1; } }", false, true, false},
    3395             :       {"try {} catch(x) { x = 0; }", false, false, true},
    3396             :       {"try {} catch(x) { with ({}) { x = 1; } }", false, true, true},
    3397             :       // Eval approximation.
    3398             :       {"eval('');", true, false, false},
    3399             :       {"function h() { eval(''); }", true, false, false},
    3400             :       {"(function() { eval(''); })", true, false, false},
    3401             :       // Shadowing not recognized because of eval approximation.
    3402             :       {"var x; eval('');", true, false, false},
    3403             :       {"'use strict'; let x; eval('');", true, false, false},
    3404             :       {"try {} catch(x) { eval(''); }", true, false, false},
    3405             :       {"function x() { eval(''); }", true, false, false},
    3406             :       {"(function(x) { eval(''); })", true, false, false},
    3407           5 :   };
    3408             : 
    3409           5 :   int prefix_len = Utf8LengthHelper(prefix);
    3410           5 :   int midfix_len = Utf8LengthHelper(midfix);
    3411           5 :   int suffix_len = Utf8LengthHelper(suffix);
    3412         315 :   for (unsigned i = 0; i < arraysize(outers); ++i) {
    3413         155 :     const char* outer = outers[i].source;
    3414         155 :     int outer_len = Utf8LengthHelper(outer);
    3415       15035 :     for (unsigned j = 0; j < arraysize(inners); ++j) {
    3416       37200 :       for (unsigned lazy = 0; lazy < 2; ++lazy) {
    3417       15330 :         if (outers[i].strict && inners[j].with) continue;
    3418       14430 :         const char* inner = inners[j].source;
    3419       14430 :         int inner_len = Utf8LengthHelper(inner);
    3420             : 
    3421       14430 :         int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len;
    3422       14430 :         i::ScopedVector<char> program(len + 1);
    3423             : 
    3424             :         i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner,
    3425       14430 :                     suffix);
    3426             : 
    3427       28860 :         std::unique_ptr<i::ParseInfo> info;
    3428       14430 :         if (lazy) {
    3429             :           printf("%s\n", program.start());
    3430             :           v8::Local<v8::Value> v = CompileRun(program.start());
    3431             :           i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    3432             :           i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
    3433             :           i::Handle<i::SharedFunctionInfo> shared =
    3434             :               i::handle(f->shared(), isolate);
    3435       14430 :           info =
    3436        7215 :               std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, shared));
    3437        7215 :           CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
    3438             :         } else {
    3439             :           i::Handle<i::String> source =
    3440        7215 :               factory->InternalizeUtf8String(program.start());
    3441       14430 :           source->PrintOn(stdout);
    3442             :           printf("\n");
    3443        7215 :           i::Handle<i::Script> script = factory->NewScript(source);
    3444       14430 :           info =
    3445        7215 :               std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, script));
    3446             :           info->set_allow_lazy_parsing(false);
    3447        7215 :           CHECK(i::parsing::ParseProgram(info.get(), isolate));
    3448             :         }
    3449       14430 :         CHECK(i::Compiler::Analyze(info.get()));
    3450       14430 :         CHECK_NOT_NULL(info->literal());
    3451             : 
    3452             :         i::Scope* scope = info->literal()->scope();
    3453       14430 :         if (!lazy) {
    3454             :           scope = scope->inner_scope();
    3455             :         }
    3456             :         DCHECK_NOT_NULL(scope);
    3457             :         DCHECK_NULL(scope->sibling());
    3458             :         DCHECK(scope->is_function_scope());
    3459             :         const i::AstRawString* var_name =
    3460       14430 :             info->ast_value_factory()->GetOneByteString("x");
    3461             :         i::Variable* var = scope->LookupForTesting(var_name);
    3462       14430 :         bool expected = outers[i].assigned || inners[j].assigned;
    3463       14430 :         CHECK_NOT_NULL(var);
    3464       14430 :         bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned;
    3465       14430 :         CHECK(is_maybe_assigned == expected ||
    3466             :               (is_maybe_assigned && inners[j].allow_error_in_inner_function));
    3467             :       }
    3468             :     }
    3469             :   }
    3470           5 : }
    3471             : 
    3472       26644 : TEST(MaybeAssignedParameters) {
    3473             :   i::Isolate* isolate = CcTest::i_isolate();
    3474             :   i::HandleScope scope(isolate);
    3475           5 :   LocalContext env;
    3476             : 
    3477             :   struct {
    3478             :     bool arg_assigned;
    3479             :     const char* source;
    3480             :   } tests[] = {
    3481             :       {false, "function f(arg) {}"},
    3482             :       {false, "function f(arg) {g(arg)}"},
    3483             :       {false, "function f(arg) {function h() { g(arg) }; h()}"},
    3484             :       {false, "function f(arg) {function h() { g(arg) }; return h}"},
    3485             :       {false, "function f(arg=1) {}"},
    3486             :       {false, "function f(arg=1) {g(arg)}"},
    3487             :       {false, "function f(arg, arguments) {g(arg); arguments[0] = 42; g(arg)}"},
    3488             :       {false,
    3489             :        "function f(arg, ...arguments) {g(arg); arguments[0] = 42; g(arg)}"},
    3490             :       {false,
    3491             :        "function f(arg, arguments=[]) {g(arg); arguments[0] = 42; g(arg)}"},
    3492             :       {false, "function f(...arg) {g(arg); arguments[0] = 42; g(arg)}"},
    3493             :       {false,
    3494             :        "function f(arg) {g(arg); g(function() {arguments[0] = 42}); g(arg)}"},
    3495             : 
    3496             :       // strict arguments object
    3497             :       {false, "function f(arg, x=1) {g(arg); arguments[0] = 42; g(arg)}"},
    3498             :       {false, "function f(arg, ...x) {g(arg); arguments[0] = 42; g(arg)}"},
    3499             :       {false, "function f(arg=1) {g(arg); arguments[0] = 42; g(arg)}"},
    3500             :       {false,
    3501             :        "function f(arg) {'use strict'; g(arg); arguments[0] = 42; g(arg)}"},
    3502             :       {false, "function f(arg) {g(arg); f.arguments[0] = 42; g(arg)}"},
    3503             :       {false, "function f(arg, args=arguments) {g(arg); args[0] = 42; g(arg)}"},
    3504             : 
    3505             :       {true, "function f(arg) {g(arg); arg = 42; g(arg)}"},
    3506             :       {true, "function f(arg) {g(arg); eval('arg = 42'); g(arg)}"},
    3507             :       {true, "function f(arg) {g(arg); var arg = 42; g(arg)}"},
    3508             :       {true, "function f(arg, x=1) {g(arg); arg = 42; g(arg)}"},
    3509             :       {true, "function f(arg, ...x) {g(arg); arg = 42; g(arg)}"},
    3510             :       {true, "function f(arg=1) {g(arg); arg = 42; g(arg)}"},
    3511             :       {true, "function f(arg) {'use strict'; g(arg); arg = 42; g(arg)}"},
    3512             :       {true, "function f(arg, {a=(g(arg), arg=42)}) {g(arg)}"},
    3513             :       {true, "function f(arg) {g(arg); g(function() {arg = 42}); g(arg)}"},
    3514             :       {true,
    3515             :        "function f(arg) {g(arg); g(function() {eval('arg = 42')}); g(arg)}"},
    3516             :       {true, "function f(arg) {g(arg); g(() => arg = 42); g(arg)}"},
    3517             :       {true, "function f(arg) {g(arg); g(() => eval('arg = 42')); g(arg)}"},
    3518             :       {true, "function f(...arg) {g(arg); eval('arg = 42'); g(arg)}"},
    3519             : 
    3520             :       // sloppy arguments object
    3521             :       {true, "function f(arg) {g(arg); arguments[0] = 42; g(arg)}"},
    3522             :       {true, "function f(arg) {g(arg); h(arguments); g(arg)}"},
    3523             :       {true,
    3524             :        "function f(arg) {((args) => {arguments[0] = 42})(arguments); "
    3525             :        "g(arg)}"},
    3526             :       {true, "function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)}"},
    3527             :       {true, "function f(arg) {g(arg); g(() => arguments[0] = 42); g(arg)}"},
    3528           5 :   };
    3529             : 
    3530             :   const char* suffix = "; f";
    3531             : 
    3532         355 :   for (unsigned i = 0; i < arraysize(tests); ++i) {
    3533         175 :     bool assigned = tests[i].arg_assigned;
    3534         175 :     const char* source = tests[i].source;
    3535         875 :     for (unsigned allow_lazy = 0; allow_lazy < 2; ++allow_lazy) {
    3536         700 :       i::ScopedVector<char> program(Utf8LengthHelper(source) +
    3537         700 :                                     Utf8LengthHelper(suffix) + 1);
    3538         350 :       i::SNPrintF(program, "%s%s", source, suffix);
    3539         700 :       std::unique_ptr<i::ParseInfo> info;
    3540             :       printf("%s\n", program.start());
    3541             :       v8::Local<v8::Value> v = CompileRun(program.start());
    3542             :       i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    3543             :       i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
    3544             :       i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared(), isolate);
    3545         700 :       info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, shared));
    3546             :       info->set_allow_lazy_parsing(allow_lazy);
    3547         350 :       CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
    3548         350 :       CHECK(i::Compiler::Analyze(info.get()));
    3549         350 :       CHECK_NOT_NULL(info->literal());
    3550             : 
    3551             :       i::Scope* scope = info->literal()->scope();
    3552         700 :       CHECK(!scope->AsDeclarationScope()->was_lazily_parsed());
    3553         350 :       CHECK_NULL(scope->sibling());
    3554         350 :       CHECK(scope->is_function_scope());
    3555             :       const i::AstRawString* var_name =
    3556         350 :           info->ast_value_factory()->GetOneByteString("arg");
    3557             :       i::Variable* var = scope->LookupForTesting(var_name);
    3558         350 :       CHECK(var->is_used() || !assigned);
    3559         350 :       bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned;
    3560         350 :       CHECK_EQ(is_maybe_assigned, assigned);
    3561             :     }
    3562             :   }
    3563           5 : }
    3564             : 
    3565       82960 : struct Input {
    3566             :   bool assigned;
    3567             :   std::string source;
    3568             :   std::vector<unsigned> location;  // "Directions" to the relevant scope.
    3569             : };
    3570             : 
    3571       15000 : static void TestMaybeAssigned(Input input, const char* variable, bool module,
    3572             :                               bool allow_lazy_parsing) {
    3573             :   i::Isolate* isolate = CcTest::i_isolate();
    3574             :   i::Factory* factory = isolate->factory();
    3575             :   i::Handle<i::String> string =
    3576       15000 :       factory->InternalizeUtf8String(input.source.c_str());
    3577       30000 :   string->PrintOn(stdout);
    3578             :   printf("\n");
    3579       15000 :   i::Handle<i::Script> script = factory->NewScript(string);
    3580             : 
    3581       30000 :   std::unique_ptr<i::ParseInfo> info;
    3582       30000 :   info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, script));
    3583             :   info->set_module(module);
    3584             :   info->set_allow_lazy_parsing(allow_lazy_parsing);
    3585             : 
    3586       15000 :   CHECK(i::parsing::ParseProgram(info.get(), isolate));
    3587       15000 :   CHECK(i::Compiler::Analyze(info.get()));
    3588             : 
    3589       15000 :   CHECK_NOT_NULL(info->literal());
    3590             :   i::Scope* scope = info->literal()->scope();
    3591       30000 :   CHECK(!scope->AsDeclarationScope()->was_lazily_parsed());
    3592       15000 :   CHECK_NULL(scope->sibling());
    3593       15000 :   CHECK(module ? scope->is_module_scope() : scope->is_script_scope());
    3594             : 
    3595             :   i::Variable* var;
    3596             :   {
    3597             :     // Find the variable.
    3598       15000 :     scope = i::ScopeTestHelper::FindScope(scope, input.location);
    3599             :     const i::AstRawString* var_name =
    3600       15000 :         info->ast_value_factory()->GetOneByteString(variable);
    3601             :     var = scope->LookupForTesting(var_name);
    3602             :   }
    3603             : 
    3604       15000 :   CHECK_NOT_NULL(var);
    3605       26400 :   CHECK_IMPLIES(input.assigned, var->is_used());
    3606             :   STATIC_ASSERT(true == i::kMaybeAssigned);
    3607       15000 :   CHECK_EQ(input.assigned, var->maybe_assigned() == i::kMaybeAssigned);
    3608       15000 : }
    3609             : 
    3610        4200 : static Input wrap(Input input) {
    3611             :   Input result;
    3612        4200 :   result.assigned = input.assigned;
    3613       12600 :   result.source = "function WRAPPED() { " + input.source + " }";
    3614        8400 :   result.location.push_back(0);
    3615        7580 :   for (auto n : input.location) {
    3616        3380 :     result.location.push_back(n);
    3617             :   }
    3618        4200 :   return result;
    3619             : }
    3620             : 
    3621       26644 : TEST(MaybeAssignedInsideLoop) {
    3622             :   i::Isolate* isolate = CcTest::i_isolate();
    3623             :   i::HandleScope scope(isolate);
    3624           5 :   LocalContext env;
    3625             : 
    3626             :   std::vector<unsigned> top;  // Can't use {} in initializers below.
    3627             : 
    3628             :   Input module_and_script_tests[] = {
    3629             :       {true, "for (j=x; j<10; ++j) { foo = j }", top},
    3630             :       {true, "for (j=x; j<10; ++j) { [foo] = [j] }", top},
    3631             :       {true, "for (j=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
    3632             :       {true, "for (j=x; j<10; ++j) { var foo = j }", top},
    3633             :       {true, "for (j=x; j<10; ++j) { var [foo] = [j] }", top},
    3634             :       {true, "for (j=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
    3635             :       {true, "for (j=x; j<10; ++j) { var foo; foo = j }", top},
    3636             :       {true, "for (j=x; j<10; ++j) { var foo; [foo] = [j] }", top},
    3637             :       {true, "for (j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3638             :       {true, "for (j=x; j<10; ++j) { let foo; foo = j }", {0}},
    3639             :       {true, "for (j=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
    3640             :       {true, "for (j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
    3641             :       {false, "for (j=x; j<10; ++j) { let foo = j }", {0}},
    3642             :       {false, "for (j=x; j<10; ++j) { let [foo] = [j] }", {0}},
    3643             :       {false, "for (j=x; j<10; ++j) { const foo = j }", {0}},
    3644             :       {false, "for (j=x; j<10; ++j) { const [foo] = [j] }", {0}},
    3645             :       {false, "for (j=x; j<10; ++j) { function foo() {return j} }", {0}},
    3646             : 
    3647             :       {true, "for ({j}=x; j<10; ++j) { foo = j }", top},
    3648             :       {true, "for ({j}=x; j<10; ++j) { [foo] = [j] }", top},
    3649             :       {true, "for ({j}=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
    3650             :       {true, "for ({j}=x; j<10; ++j) { var foo = j }", top},
    3651             :       {true, "for ({j}=x; j<10; ++j) { var [foo] = [j] }", top},
    3652             :       {true, "for ({j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
    3653             :       {true, "for ({j}=x; j<10; ++j) { var foo; foo = j }", top},
    3654             :       {true, "for ({j}=x; j<10; ++j) { var foo; [foo] = [j] }", top},
    3655             :       {true, "for ({j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3656             :       {true, "for ({j}=x; j<10; ++j) { let foo; foo = j }", {0}},
    3657             :       {true, "for ({j}=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
    3658             :       {true, "for ({j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
    3659             :       {false, "for ({j}=x; j<10; ++j) { let foo = j }", {0}},
    3660             :       {false, "for ({j}=x; j<10; ++j) { let [foo] = [j] }", {0}},
    3661             :       {false, "for ({j}=x; j<10; ++j) { const foo = j }", {0}},
    3662             :       {false, "for ({j}=x; j<10; ++j) { const [foo] = [j] }", {0}},
    3663             :       {false, "for ({j}=x; j<10; ++j) { function foo() {return j} }", {0}},
    3664             : 
    3665             :       {true, "for (var j=x; j<10; ++j) { foo = j }", top},
    3666             :       {true, "for (var j=x; j<10; ++j) { [foo] = [j] }", top},
    3667             :       {true, "for (var j=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
    3668             :       {true, "for (var j=x; j<10; ++j) { var foo = j }", top},
    3669             :       {true, "for (var j=x; j<10; ++j) { var [foo] = [j] }", top},
    3670             :       {true, "for (var j=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
    3671             :       {true, "for (var j=x; j<10; ++j) { var foo; foo = j }", top},
    3672             :       {true, "for (var j=x; j<10; ++j) { var foo; [foo] = [j] }", top},
    3673             :       {true, "for (var j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3674             :       {true, "for (var j=x; j<10; ++j) { let foo; foo = j }", {0}},
    3675             :       {true, "for (var j=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
    3676             :       {true, "for (var j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
    3677             :       {false, "for (var j=x; j<10; ++j) { let foo = j }", {0}},
    3678             :       {false, "for (var j=x; j<10; ++j) { let [foo] = [j] }", {0}},
    3679             :       {false, "for (var j=x; j<10; ++j) { const foo = j }", {0}},
    3680             :       {false, "for (var j=x; j<10; ++j) { const [foo] = [j] }", {0}},
    3681             :       {false, "for (var j=x; j<10; ++j) { function foo() {return j} }", {0}},
    3682             : 
    3683             :       {true, "for (var {j}=x; j<10; ++j) { foo = j }", top},
    3684             :       {true, "for (var {j}=x; j<10; ++j) { [foo] = [j] }", top},
    3685             :       {true, "for (var {j}=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
    3686             :       {true, "for (var {j}=x; j<10; ++j) { var foo = j }", top},
    3687             :       {true, "for (var {j}=x; j<10; ++j) { var [foo] = [j] }", top},
    3688             :       {true, "for (var {j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
    3689             :       {true, "for (var {j}=x; j<10; ++j) { var foo; foo = j }", top},
    3690             :       {true, "for (var {j}=x; j<10; ++j) { var foo; [foo] = [j] }", top},
    3691             :       {true, "for (var {j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3692             :       {true, "for (var {j}=x; j<10; ++j) { let foo; foo = j }", {0}},
    3693             :       {true, "for (var {j}=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
    3694             :       {true, "for (var {j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
    3695             :       {false, "for (var {j}=x; j<10; ++j) { let foo = j }", {0}},
    3696             :       {false, "for (var {j}=x; j<10; ++j) { let [foo] = [j] }", {0}},
    3697             :       {false, "for (var {j}=x; j<10; ++j) { const foo = j }", {0}},
    3698             :       {false, "for (var {j}=x; j<10; ++j) { const [foo] = [j] }", {0}},
    3699             :       {false, "for (var {j}=x; j<10; ++j) { function foo() {return j} }", {0}},
    3700             : 
    3701             :       {true, "for (let j=x; j<10; ++j) { foo = j }", top},
    3702             :       {true, "for (let j=x; j<10; ++j) { [foo] = [j] }", top},
    3703             :       {true, "for (let j=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
    3704             :       {true, "for (let j=x; j<10; ++j) { var foo = j }", top},
    3705             :       {true, "for (let j=x; j<10; ++j) { var [foo] = [j] }", top},
    3706             :       {true, "for (let j=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
    3707             :       {true, "for (let j=x; j<10; ++j) { var foo; foo = j }", top},
    3708             :       {true, "for (let j=x; j<10; ++j) { var foo; [foo] = [j] }", top},
    3709             :       {true, "for (let j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3710             :       {true, "for (let j=x; j<10; ++j) { let foo; foo = j }", {0, 0}},
    3711             :       {true, "for (let j=x; j<10; ++j) { let foo; [foo] = [j] }", {0, 0}},
    3712             :       {true, "for (let j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0, 0}},
    3713             :       {false, "for (let j=x; j<10; ++j) { let foo = j }", {0, 0}},
    3714             :       {false, "for (let j=x; j<10; ++j) { let [foo] = [j] }", {0, 0}},
    3715             :       {false, "for (let j=x; j<10; ++j) { const foo = j }", {0, 0}},
    3716             :       {false, "for (let j=x; j<10; ++j) { const [foo] = [j] }", {0, 0}},
    3717             :       {false,
    3718             :        "for (let j=x; j<10; ++j) { function foo() {return j} }",
    3719             :        {0, 0, 0}},
    3720             : 
    3721             :       {true, "for (let {j}=x; j<10; ++j) { foo = j }", top},
    3722             :       {true, "for (let {j}=x; j<10; ++j) { [foo] = [j] }", top},
    3723             :       {true, "for (let {j}=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
    3724             :       {true, "for (let {j}=x; j<10; ++j) { var foo = j }", top},
    3725             :       {true, "for (let {j}=x; j<10; ++j) { var [foo] = [j] }", top},
    3726             :       {true, "for (let {j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
    3727             :       {true, "for (let {j}=x; j<10; ++j) { var foo; foo = j }", top},
    3728             :       {true, "for (let {j}=x; j<10; ++j) { var foo; [foo] = [j] }", top},
    3729             :       {true, "for (let {j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3730             :       {true, "for (let {j}=x; j<10; ++j) { let foo; foo = j }", {0, 0}},
    3731             :       {true, "for (let {j}=x; j<10; ++j) { let foo; [foo] = [j] }", {0, 0}},
    3732             :       {true,
    3733             :        "for (let {j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }",
    3734             :        {0, 0}},
    3735             :       {false, "for (let {j}=x; j<10; ++j) { let foo = j }", {0, 0}},
    3736             :       {false, "for (let {j}=x; j<10; ++j) { let [foo] = [j] }", {0, 0}},
    3737             :       {false, "for (let {j}=x; j<10; ++j) { const foo = j }", {0, 0}},
    3738             :       {false, "for (let {j}=x; j<10; ++j) { const [foo] = [j] }", {0, 0}},
    3739             :       {false,
    3740             :        "for (let {j}=x; j<10; ++j) { function foo(){return j} }",
    3741             :        {0, 0, 0}},
    3742             : 
    3743             :       {true, "for (j of x) { foo = j }", top},
    3744             :       {true, "for (j of x) { [foo] = [j] }", top},
    3745             :       {true, "for (j of x) { [[foo]=[42]] = [] }", top},
    3746             :       {true, "for (j of x) { var foo = j }", top},
    3747             :       {true, "for (j of x) { var [foo] = [j] }", top},
    3748             :       {true, "for (j of x) { var [[foo]=[42]] = [] }", top},
    3749             :       {true, "for (j of x) { var foo; foo = j }", top},
    3750             :       {true, "for (j of x) { var foo; [foo] = [j] }", top},
    3751             :       {true, "for (j of x) { var foo; [[foo]=[42]] = [] }", top},
    3752             :       {true, "for (j of x) { let foo; foo = j }", {0}},
    3753             :       {true, "for (j of x) { let foo; [foo] = [j] }", {0}},
    3754             :       {true, "for (j of x) { let foo; [[foo]=[42]] = [] }", {0}},
    3755             :       {false, "for (j of x) { let foo = j }", {0}},
    3756             :       {false, "for (j of x) { let [foo] = [j] }", {0}},
    3757             :       {false, "for (j of x) { const foo = j }", {0}},
    3758             :       {false, "for (j of x) { const [foo] = [j] }", {0}},
    3759             :       {false, "for (j of x) { function foo() {return j} }", {0}},
    3760             : 
    3761             :       {true, "for ({j} of x) { foo = j }", top},
    3762             :       {true, "for ({j} of x) { [foo] = [j] }", top},
    3763             :       {true, "for ({j} of x) { [[foo]=[42]] = [] }", top},
    3764             :       {true, "for ({j} of x) { var foo = j }", top},
    3765             :       {true, "for ({j} of x) { var [foo] = [j] }", top},
    3766             :       {true, "for ({j} of x) { var [[foo]=[42]] = [] }", top},
    3767             :       {true, "for ({j} of x) { var foo; foo = j }", top},
    3768             :       {true, "for ({j} of x) { var foo; [foo] = [j] }", top},
    3769             :       {true, "for ({j} of x) { var foo; [[foo]=[42]] = [] }", top},
    3770             :       {true, "for ({j} of x) { let foo; foo = j }", {0}},
    3771             :       {true, "for ({j} of x) { let foo; [foo] = [j] }", {0}},
    3772             :       {true, "for ({j} of x) { let foo; [[foo]=[42]] = [] }", {0}},
    3773             :       {false, "for ({j} of x) { let foo = j }", {0}},
    3774             :       {false, "for ({j} of x) { let [foo] = [j] }", {0}},
    3775             :       {false, "for ({j} of x) { const foo = j }", {0}},
    3776             :       {false, "for ({j} of x) { const [foo] = [j] }", {0}},
    3777             :       {false, "for ({j} of x) { function foo() {return j} }", {0}},
    3778             : 
    3779             :       {true, "for (var j of x) { foo = j }", top},
    3780             :       {true, "for (var j of x) { [foo] = [j] }", top},
    3781             :       {true, "for (var j of x) { [[foo]=[42]] = [] }", top},
    3782             :       {true, "for (var j of x) { var foo = j }", top},
    3783             :       {true, "for (var j of x) { var [foo] = [j] }", top},
    3784             :       {true, "for (var j of x) { var [[foo]=[42]] = [] }", top},
    3785             :       {true, "for (var j of x) { var foo; foo = j }", top},
    3786             :       {true, "for (var j of x) { var foo; [foo] = [j] }", top},
    3787             :       {true, "for (var j of x) { var foo; [[foo]=[42]] = [] }", top},
    3788             :       {true, "for (var j of x) { let foo; foo = j }", {0}},
    3789             :       {true, "for (var j of x) { let foo; [foo] = [j] }", {0}},
    3790             :       {true, "for (var j of x) { let foo; [[foo]=[42]] = [] }", {0}},
    3791             :       {false, "for (var j of x) { let foo = j }", {0}},
    3792             :       {false, "for (var j of x) { let [foo] = [j] }", {0}},
    3793             :       {false, "for (var j of x) { const foo = j }", {0}},
    3794             :       {false, "for (var j of x) { const [foo] = [j] }", {0}},
    3795             :       {false, "for (var j of x) { function foo() {return j} }", {0}},
    3796             : 
    3797             :       {true, "for (var {j} of x) { foo = j }", top},
    3798             :       {true, "for (var {j} of x) { [foo] = [j] }", top},
    3799             :       {true, "for (var {j} of x) { [[foo]=[42]] = [] }", top},
    3800             :       {true, "for (var {j} of x) { var foo = j }", top},
    3801             :       {true, "for (var {j} of x) { var [foo] = [j] }", top},
    3802             :       {true, "for (var {j} of x) { var [[foo]=[42]] = [] }", top},
    3803             :       {true, "for (var {j} of x) { var foo; foo = j }", top},
    3804             :       {true, "for (var {j} of x) { var foo; [foo] = [j] }", top},
    3805             :       {true, "for (var {j} of x) { var foo; [[foo]=[42]] = [] }", top},
    3806             :       {true, "for (var {j} of x) { let foo; foo = j }", {0}},
    3807             :       {true, "for (var {j} of x) { let foo; [foo] = [j] }", {0}},
    3808             :       {true, "for (var {j} of x) { let foo; [[foo]=[42]] = [] }", {0}},
    3809             :       {false, "for (var {j} of x) { let foo = j }", {0}},
    3810             :       {false, "for (var {j} of x) { let [foo] = [j] }", {0}},
    3811             :       {false, "for (var {j} of x) { const foo = j }", {0}},
    3812             :       {false, "for (var {j} of x) { const [foo] = [j] }", {0}},
    3813             :       {false, "for (var {j} of x) { function foo() {return j} }", {0}},
    3814             : 
    3815             :       {true, "for (let j of x) { foo = j }", top},
    3816             :       {true, "for (let j of x) { [foo] = [j] }", top},
    3817             :       {true, "for (let j of x) { [[foo]=[42]] = [] }", top},
    3818             :       {true, "for (let j of x) { var foo = j }", top},
    3819             :       {true, "for (let j of x) { var [foo] = [j] }", top},
    3820             :       {true, "for (let j of x) { var [[foo]=[42]] = [] }", top},
    3821             :       {true, "for (let j of x) { var foo; foo = j }", top},
    3822             :       {true, "for (let j of x) { var foo; [foo] = [j] }", top},
    3823             :       {true, "for (let j of x) { var foo; [[foo]=[42]] = [] }", top},
    3824             :       {true, "for (let j of x) { let foo; foo = j }", {0, 0, 0}},
    3825             :       {true, "for (let j of x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3826             :       {true, "for (let j of x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3827             :       {false, "for (let j of x) { let foo = j }", {0, 0, 0}},
    3828             :       {false, "for (let j of x) { let [foo] = [j] }", {0, 0, 0}},
    3829             :       {false, "for (let j of x) { const foo = j }", {0, 0, 0}},
    3830             :       {false, "for (let j of x) { const [foo] = [j] }", {0, 0, 0}},
    3831             :       {false, "for (let j of x) { function foo() {return j} }", {0, 0, 0}},
    3832             : 
    3833             :       {true, "for (let {j} of x) { foo = j }", top},
    3834             :       {true, "for (let {j} of x) { [foo] = [j] }", top},
    3835             :       {true, "for (let {j} of x) { [[foo]=[42]] = [] }", top},
    3836             :       {true, "for (let {j} of x) { var foo = j }", top},
    3837             :       {true, "for (let {j} of x) { var [foo] = [j] }", top},
    3838             :       {true, "for (let {j} of x) { var [[foo]=[42]] = [] }", top},
    3839             :       {true, "for (let {j} of x) { var foo; foo = j }", top},
    3840             :       {true, "for (let {j} of x) { var foo; [foo] = [j] }", top},
    3841             :       {true, "for (let {j} of x) { var foo; [[foo]=[42]] = [] }", top},
    3842             :       {true, "for (let {j} of x) { let foo; foo = j }", {0, 0, 0}},
    3843             :       {true, "for (let {j} of x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3844             :       {true, "for (let {j} of x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3845             :       {false, "for (let {j} of x) { let foo = j }", {0, 0, 0}},
    3846             :       {false, "for (let {j} of x) { let [foo] = [j] }", {0, 0, 0}},
    3847             :       {false, "for (let {j} of x) { const foo = j }", {0, 0, 0}},
    3848             :       {false, "for (let {j} of x) { const [foo] = [j] }", {0, 0, 0}},
    3849             :       {false, "for (let {j} of x) { function foo() {return j} }", {0, 0, 0}},
    3850             : 
    3851             :       {true, "for (const j of x) { foo = j }", top},
    3852             :       {true, "for (const j of x) { [foo] = [j] }", top},
    3853             :       {true, "for (const j of x) { [[foo]=[42]] = [] }", top},
    3854             :       {true, "for (const j of x) { var foo = j }", top},
    3855             :       {true, "for (const j of x) { var [foo] = [j] }", top},
    3856             :       {true, "for (const j of x) { var [[foo]=[42]] = [] }", top},
    3857             :       {true, "for (const j of x) { var foo; foo = j }", top},
    3858             :       {true, "for (const j of x) { var foo; [foo] = [j] }", top},
    3859             :       {true, "for (const j of x) { var foo; [[foo]=[42]] = [] }", top},
    3860             :       {true, "for (const j of x) { let foo; foo = j }", {0, 0, 0}},
    3861             :       {true, "for (const j of x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3862             :       {true, "for (const j of x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3863             :       {false, "for (const j of x) { let foo = j }", {0, 0, 0}},
    3864             :       {false, "for (const j of x) { let [foo] = [j] }", {0, 0, 0}},
    3865             :       {false, "for (const j of x) { const foo = j }", {0, 0, 0}},
    3866             :       {false, "for (const j of x) { const [foo] = [j] }", {0, 0, 0}},
    3867             :       {false, "for (const j of x) { function foo() {return j} }", {0, 0, 0}},
    3868             : 
    3869             :       {true, "for (const {j} of x) { foo = j }", top},
    3870             :       {true, "for (const {j} of x) { [foo] = [j] }", top},
    3871             :       {true, "for (const {j} of x) { [[foo]=[42]] = [] }", top},
    3872             :       {true, "for (const {j} of x) { var foo = j }", top},
    3873             :       {true, "for (const {j} of x) { var [foo] = [j] }", top},
    3874             :       {true, "for (const {j} of x) { var [[foo]=[42]] = [] }", top},
    3875             :       {true, "for (const {j} of x) { var foo; foo = j }", top},
    3876             :       {true, "for (const {j} of x) { var foo; [foo] = [j] }", top},
    3877             :       {true, "for (const {j} of x) { var foo; [[foo]=[42]] = [] }", top},
    3878             :       {true, "for (const {j} of x) { let foo; foo = j }", {0, 0, 0}},
    3879             :       {true, "for (const {j} of x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3880             :       {true, "for (const {j} of x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3881             :       {false, "for (const {j} of x) { let foo = j }", {0, 0, 0}},
    3882             :       {false, "for (const {j} of x) { let [foo] = [j] }", {0, 0, 0}},
    3883             :       {false, "for (const {j} of x) { const foo = j }", {0, 0, 0}},
    3884             :       {false, "for (const {j} of x) { const [foo] = [j] }", {0, 0, 0}},
    3885             :       {false, "for (const {j} of x) { function foo() {return j} }", {0, 0, 0}},
    3886             : 
    3887             :       {true, "for (j in x) { foo = j }", top},
    3888             :       {true, "for (j in x) { [foo] = [j] }", top},
    3889             :       {true, "for (j in x) { [[foo]=[42]] = [] }", top},
    3890             :       {true, "for (j in x) { var foo = j }", top},
    3891             :       {true, "for (j in x) { var [foo] = [j] }", top},
    3892             :       {true, "for (j in x) { var [[foo]=[42]] = [] }", top},
    3893             :       {true, "for (j in x) { var foo; foo = j }", top},
    3894             :       {true, "for (j in x) { var foo; [foo] = [j] }", top},
    3895             :       {true, "for (j in x) { var foo; [[foo]=[42]] = [] }", top},
    3896             :       {true, "for (j in x) { let foo; foo = j }", {0}},
    3897             :       {true, "for (j in x) { let foo; [foo] = [j] }", {0}},
    3898             :       {true, "for (j in x) { let foo; [[foo]=[42]] = [] }", {0}},
    3899             :       {false, "for (j in x) { let foo = j }", {0}},
    3900             :       {false, "for (j in x) { let [foo] = [j] }", {0}},
    3901             :       {false, "for (j in x) { const foo = j }", {0}},
    3902             :       {false, "for (j in x) { const [foo] = [j] }", {0}},
    3903             :       {false, "for (j in x) { function foo() {return j} }", {0}},
    3904             : 
    3905             :       {true, "for ({j} in x) { foo = j }", top},
    3906             :       {true, "for ({j} in x) { [foo] = [j] }", top},
    3907             :       {true, "for ({j} in x) { [[foo]=[42]] = [] }", top},
    3908             :       {true, "for ({j} in x) { var foo = j }", top},
    3909             :       {true, "for ({j} in x) { var [foo] = [j] }", top},
    3910             :       {true, "for ({j} in x) { var [[foo]=[42]] = [] }", top},
    3911             :       {true, "for ({j} in x) { var foo; foo = j }", top},
    3912             :       {true, "for ({j} in x) { var foo; [foo] = [j] }", top},
    3913             :       {true, "for ({j} in x) { var foo; [[foo]=[42]] = [] }", top},
    3914             :       {true, "for ({j} in x) { let foo; foo = j }", {0}},
    3915             :       {true, "for ({j} in x) { let foo; [foo] = [j] }", {0}},
    3916             :       {true, "for ({j} in x) { let foo; [[foo]=[42]] = [] }", {0}},
    3917             :       {false, "for ({j} in x) { let foo = j }", {0}},
    3918             :       {false, "for ({j} in x) { let [foo] = [j] }", {0}},
    3919             :       {false, "for ({j} in x) { const foo = j }", {0}},
    3920             :       {false, "for ({j} in x) { const [foo] = [j] }", {0}},
    3921             :       {false, "for ({j} in x) { function foo() {return j} }", {0}},
    3922             : 
    3923             :       {true, "for (var j in x) { foo = j }", top},
    3924             :       {true, "for (var j in x) { [foo] = [j] }", top},
    3925             :       {true, "for (var j in x) { [[foo]=[42]] = [] }", top},
    3926             :       {true, "for (var j in x) { var foo = j }", top},
    3927             :       {true, "for (var j in x) { var [foo] = [j] }", top},
    3928             :       {true, "for (var j in x) { var [[foo]=[42]] = [] }", top},
    3929             :       {true, "for (var j in x) { var foo; foo = j }", top},
    3930             :       {true, "for (var j in x) { var foo; [foo] = [j] }", top},
    3931             :       {true, "for (var j in x) { var foo; [[foo]=[42]] = [] }", top},
    3932             :       {true, "for (var j in x) { let foo; foo = j }", {0}},
    3933             :       {true, "for (var j in x) { let foo; [foo] = [j] }", {0}},
    3934             :       {true, "for (var j in x) { let foo; [[foo]=[42]] = [] }", {0}},
    3935             :       {false, "for (var j in x) { let foo = j }", {0}},
    3936             :       {false, "for (var j in x) { let [foo] = [j] }", {0}},
    3937             :       {false, "for (var j in x) { const foo = j }", {0}},
    3938             :       {false, "for (var j in x) { const [foo] = [j] }", {0}},
    3939             :       {false, "for (var j in x) { function foo() {return j} }", {0}},
    3940             : 
    3941             :       {true, "for (var {j} in x) { foo = j }", top},
    3942             :       {true, "for (var {j} in x) { [foo] = [j] }", top},
    3943             :       {true, "for (var {j} in x) { [[foo]=[42]] = [] }", top},
    3944             :       {true, "for (var {j} in x) { var foo = j }", top},
    3945             :       {true, "for (var {j} in x) { var [foo] = [j] }", top},
    3946             :       {true, "for (var {j} in x) { var [[foo]=[42]] = [] }", top},
    3947             :       {true, "for (var {j} in x) { var foo; foo = j }", top},
    3948             :       {true, "for (var {j} in x) { var foo; [foo] = [j] }", top},
    3949             :       {true, "for (var {j} in x) { var foo; [[foo]=[42]] = [] }", top},
    3950             :       {true, "for (var {j} in x) { let foo; foo = j }", {0}},
    3951             :       {true, "for (var {j} in x) { let foo; [foo] = [j] }", {0}},
    3952             :       {true, "for (var {j} in x) { let foo; [[foo]=[42]] = [] }", {0}},
    3953             :       {false, "for (var {j} in x) { let foo = j }", {0}},
    3954             :       {false, "for (var {j} in x) { let [foo] = [j] }", {0}},
    3955             :       {false, "for (var {j} in x) { const foo = j }", {0}},
    3956             :       {false, "for (var {j} in x) { const [foo] = [j] }", {0}},
    3957             :       {false, "for (var {j} in x) { function foo() {return j} }", {0}},
    3958             : 
    3959             :       {true, "for (let j in x) { foo = j }", top},
    3960             :       {true, "for (let j in x) { [foo] = [j] }", top},
    3961             :       {true, "for (let j in x) { [[foo]=[42]] = [] }", top},
    3962             :       {true, "for (let j in x) { var foo = j }", top},
    3963             :       {true, "for (let j in x) { var [foo] = [j] }", top},
    3964             :       {true, "for (let j in x) { var [[foo]=[42]] = [] }", top},
    3965             :       {true, "for (let j in x) { var foo; foo = j }", top},
    3966             :       {true, "for (let j in x) { var foo; [foo] = [j] }", top},
    3967             :       {true, "for (let j in x) { var foo; [[foo]=[42]] = [] }", top},
    3968             :       {true, "for (let j in x) { let foo; foo = j }", {0, 0, 0}},
    3969             :       {true, "for (let j in x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3970             :       {true, "for (let j in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3971             :       {false, "for (let j in x) { let foo = j }", {0, 0, 0}},
    3972             :       {false, "for (let j in x) { let [foo] = [j] }", {0, 0, 0}},
    3973             :       {false, "for (let j in x) { const foo = j }", {0, 0, 0}},
    3974             :       {false, "for (let j in x) { const [foo] = [j] }", {0, 0, 0}},
    3975             :       {false, "for (let j in x) { function foo() {return j} }", {0, 0, 0}},
    3976             : 
    3977             :       {true, "for (let {j} in x) { foo = j }", top},
    3978             :       {true, "for (let {j} in x) { [foo] = [j] }", top},
    3979             :       {true, "for (let {j} in x) { [[foo]=[42]] = [] }", top},
    3980             :       {true, "for (let {j} in x) { var foo = j }", top},
    3981             :       {true, "for (let {j} in x) { var [foo] = [j] }", top},
    3982             :       {true, "for (let {j} in x) { var [[foo]=[42]] = [] }", top},
    3983             :       {true, "for (let {j} in x) { var foo; foo = j }", top},
    3984             :       {true, "for (let {j} in x) { var foo; [foo] = [j] }", top},
    3985             :       {true, "for (let {j} in x) { var foo; [[foo]=[42]] = [] }", top},
    3986             :       {true, "for (let {j} in x) { let foo; foo = j }", {0, 0, 0}},
    3987             :       {true, "for (let {j} in x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3988             :       {true, "for (let {j} in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3989             :       {false, "for (let {j} in x) { let foo = j }", {0, 0, 0}},
    3990             :       {false, "for (let {j} in x) { let [foo] = [j] }", {0, 0, 0}},
    3991             :       {false, "for (let {j} in x) { const foo = j }", {0, 0, 0}},
    3992             :       {false, "for (let {j} in x) { const [foo] = [j] }", {0, 0, 0}},
    3993             :       {false, "for (let {j} in x) { function foo() {return j} }", {0, 0, 0}},
    3994             : 
    3995             :       {true, "for (const j in x) { foo = j }", top},
    3996             :       {true, "for (const j in x) { [foo] = [j] }", top},
    3997             :       {true, "for (const j in x) { [[foo]=[42]] = [] }", top},
    3998             :       {true, "for (const j in x) { var foo = j }", top},
    3999             :       {true, "for (const j in x) { var [foo] = [j] }", top},
    4000             :       {true, "for (const j in x) { var [[foo]=[42]] = [] }", top},
    4001             :       {true, "for (const j in x) { var foo; foo = j }", top},
    4002             :       {true, "for (const j in x) { var foo; [foo] = [j] }", top},
    4003             :       {true, "for (const j in x) { var foo; [[foo]=[42]] = [] }", top},
    4004             :       {true, "for (const j in x) { let foo; foo = j }", {0, 0, 0}},
    4005             :       {true, "for (const j in x) { let foo; [foo] = [j] }", {0, 0, 0}},
    4006             :       {true, "for (const j in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    4007             :       {false, "for (const j in x) { let foo = j }", {0, 0, 0}},
    4008             :       {false, "for (const j in x) { let [foo] = [j] }", {0, 0, 0}},
    4009             :       {false, "for (const j in x) { const foo = j }", {0, 0, 0}},
    4010             :       {false, "for (const j in x) { const [foo] = [j] }", {0, 0, 0}},
    4011             :       {false, "for (const j in x) { function foo() {return j} }", {0, 0, 0}},
    4012             : 
    4013             :       {true, "for (const {j} in x) { foo = j }", top},
    4014             :       {true, "for (const {j} in x) { [foo] = [j] }", top},
    4015             :       {true, "for (const {j} in x) { [[foo]=[42]] = [] }", top},
    4016             :       {true, "for (const {j} in x) { var foo = j }", top},
    4017             :       {true, "for (const {j} in x) { var [foo] = [j] }", top},
    4018             :       {true, "for (const {j} in x) { var [[foo]=[42]] = [] }", top},
    4019             :       {true, "for (const {j} in x) { var foo; foo = j }", top},
    4020             :       {true, "for (const {j} in x) { var foo; [foo] = [j] }", top},
    4021             :       {true, "for (const {j} in x) { var foo; [[foo]=[42]] = [] }", top},
    4022             :       {true, "for (const {j} in x) { let foo; foo = j }", {0, 0, 0}},
    4023             :       {true, "for (const {j} in x) { let foo; [foo] = [j] }", {0, 0, 0}},
    4024             :       {true, "for (const {j} in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    4025             :       {false, "for (const {j} in x) { let foo = j }", {0, 0, 0}},
    4026             :       {false, "for (const {j} in x) { let [foo] = [j] }", {0, 0, 0}},
    4027             :       {false, "for (const {j} in x) { const foo = j }", {0, 0, 0}},
    4028             :       {false, "for (const {j} in x) { const [foo] = [j] }", {0, 0, 0}},
    4029             :       {false, "for (const {j} in x) { function foo() {return j} }", {0, 0, 0}},
    4030             : 
    4031             :       {true, "while (j) { foo = j }", top},
    4032             :       {true, "while (j) { [foo] = [j] }", top},
    4033             :       {true, "while (j) { [[foo]=[42]] = [] }", top},
    4034             :       {true, "while (j) { var foo = j }", top},
    4035             :       {true, "while (j) { var [foo] = [j] }", top},
    4036             :       {true, "while (j) { var [[foo]=[42]] = [] }", top},
    4037             :       {true, "while (j) { var foo; foo = j }", top},
    4038             :       {true, "while (j) { var foo; [foo] = [j] }", top},
    4039             :       {true, "while (j) { var foo; [[foo]=[42]] = [] }", top},
    4040             :       {true, "while (j) { let foo; foo = j }", {0}},
    4041             :       {true, "while (j) { let foo; [foo] = [j] }", {0}},
    4042             :       {true, "while (j) { let foo; [[foo]=[42]] = [] }", {0}},
    4043             :       {false, "while (j) { let foo = j }", {0}},
    4044             :       {false, "while (j) { let [foo] = [j] }", {0}},
    4045             :       {false, "while (j) { const foo = j }", {0}},
    4046             :       {false, "while (j) { const [foo] = [j] }", {0}},
    4047             :       {false, "while (j) { function foo() {return j} }", {0}},
    4048             : 
    4049             :       {true, "do { foo = j } while (j)", top},
    4050             :       {true, "do { [foo] = [j] } while (j)", top},
    4051             :       {true, "do { [[foo]=[42]] = [] } while (j)", top},
    4052             :       {true, "do { var foo = j } while (j)", top},
    4053             :       {true, "do { var [foo] = [j] } while (j)", top},
    4054             :       {true, "do { var [[foo]=[42]] = [] } while (j)", top},
    4055             :       {true, "do { var foo; foo = j } while (j)", top},
    4056             :       {true, "do { var foo; [foo] = [j] } while (j)", top},
    4057             :       {true, "do { var foo; [[foo]=[42]] = [] } while (j)", top},
    4058             :       {true, "do { let foo; foo = j } while (j)", {0}},
    4059             :       {true, "do { let foo; [foo] = [j] } while (j)", {0}},
    4060             :       {true, "do { let foo; [[foo]=[42]] = [] } while (j)", {0}},
    4061             :       {false, "do { let foo = j } while (j)", {0}},
    4062             :       {false, "do { let [foo] = [j] } while (j)", {0}},
    4063             :       {false, "do { const foo = j } while (j)", {0}},
    4064             :       {false, "do { const [foo] = [j] } while (j)", {0}},
    4065             :       {false, "do { function foo() {return j} } while (j)", {0}},
    4066        3005 :   };
    4067             : 
    4068             :   Input script_only_tests[] = {
    4069             :       {true, "for (j=x; j<10; ++j) { function foo() {return j} }", top},
    4070             :       {true, "for ({j}=x; j<10; ++j) { function foo() {return j} }", top},
    4071             :       {true, "for (var j=x; j<10; ++j) { function foo() {return j} }", top},
    4072             :       {true, "for (var {j}=x; j<10; ++j) { function foo() {return j} }", top},
    4073             :       {true, "for (let j=x; j<10; ++j) { function foo() {return j} }", top},
    4074             :       {true, "for (let {j}=x; j<10; ++j) { function foo() {return j} }", top},
    4075             :       {true, "for (j of x) { function foo() {return j} }", top},
    4076             :       {true, "for ({j} of x) { function foo() {return j} }", top},
    4077             :       {true, "for (var j of x) { function foo() {return j} }", top},
    4078             :       {true, "for (var {j} of x) { function foo() {return j} }", top},
    4079             :       {true, "for (let j of x) { function foo() {return j} }", top},
    4080             :       {true, "for (let {j} of x) { function foo() {return j} }", top},
    4081             :       {true, "for (const j of x) { function foo() {return j} }", top},
    4082             :       {true, "for (const {j} of x) { function foo() {return j} }", top},
    4083             :       {true, "for (j in x) { function foo() {return j} }", top},
    4084             :       {true, "for ({j} in x) { function foo() {return j} }", top},
    4085             :       {true, "for (var j in x) { function foo() {return j} }", top},
    4086             :       {true, "for (var {j} in x) { function foo() {return j} }", top},
    4087             :       {true, "for (let j in x) { function foo() {return j} }", top},
    4088             :       {true, "for (let {j} in x) { function foo() {return j} }", top},
    4089             :       {true, "for (const j in x) { function foo() {return j} }", top},
    4090             :       {true, "for (const {j} in x) { function foo() {return j} }", top},
    4091             :       {true, "while (j) { function foo() {return j} }", top},
    4092             :       {true, "do { function foo() {return j} } while (j)", top},
    4093         130 :   };
    4094             : 
    4095        4085 :   for (unsigned i = 0; i < arraysize(module_and_script_tests); ++i) {
    4096        4080 :     Input input = module_and_script_tests[i];
    4097       10200 :     for (unsigned module = 0; module <= 1; ++module) {
    4098       20400 :       for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
    4099             :            ++allow_lazy_parsing) {
    4100        8160 :         TestMaybeAssigned(input, "foo", module, allow_lazy_parsing);
    4101             :       }
    4102        4080 :       TestMaybeAssigned(wrap(input), "foo", module, false);
    4103             :     }
    4104             :   }
    4105             : 
    4106         245 :   for (unsigned i = 0; i < arraysize(script_only_tests); ++i) {
    4107         240 :     Input input = script_only_tests[i];
    4108         600 :     for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
    4109             :          ++allow_lazy_parsing) {
    4110         240 :       TestMaybeAssigned(input, "foo", false, allow_lazy_parsing);
    4111             :     }
    4112         120 :     TestMaybeAssigned(wrap(input), "foo", false, false);
    4113             :   }
    4114           5 : }
    4115             : 
    4116       26644 : TEST(MaybeAssignedTopLevel) {
    4117             :   i::Isolate* isolate = CcTest::i_isolate();
    4118             :   i::HandleScope scope(isolate);
    4119           5 :   LocalContext env;
    4120             : 
    4121             :   const char* prefixes[] = {
    4122             :       "let foo; ",
    4123             :       "let foo = 0; ",
    4124             :       "let [foo] = [1]; ",
    4125             :       "let {foo} = {foo: 2}; ",
    4126             :       "let {foo=3} = {}; ",
    4127             :       "var foo; ",
    4128             :       "var foo = 0; ",
    4129             :       "var [foo] = [1]; ",
    4130             :       "var {foo} = {foo: 2}; ",
    4131             :       "var {foo=3} = {}; ",
    4132             :       "{ var foo; }; ",
    4133             :       "{ var foo = 0; }; ",
    4134             :       "{ var [foo] = [1]; }; ",
    4135             :       "{ var {foo} = {foo: 2}; }; ",
    4136             :       "{ var {foo=3} = {}; }; ",
    4137             :       "function foo() {}; ",
    4138             :       "function* foo() {}; ",
    4139             :       "async function foo() {}; ",
    4140             :       "class foo {}; ",
    4141             :       "class foo extends null {}; ",
    4142           5 :   };
    4143             : 
    4144             :   const char* module_and_script_tests[] = {
    4145             :       "function bar() {foo = 42}; ext(bar); ext(foo)",
    4146             :       "ext(function() {foo++}); ext(foo)",
    4147             :       "bar = () => --foo; ext(bar); ext(foo)",
    4148             :       "function* bar() {eval(ext)}; ext(bar); ext(foo)",
    4149           5 :   };
    4150             : 
    4151             :   const char* script_only_tests[] = {
    4152             :       "",
    4153             :       "{ function foo() {}; }; ",
    4154             :       "{ function* foo() {}; }; ",
    4155             :       "{ async function foo() {}; }; ",
    4156           5 :   };
    4157             : 
    4158         205 :   for (unsigned i = 0; i < arraysize(prefixes); ++i) {
    4159         900 :     for (unsigned j = 0; j < arraysize(module_and_script_tests); ++j) {
    4160         400 :       std::string source(prefixes[i]);
    4161         400 :       source += module_and_script_tests[j];
    4162             :       std::vector<unsigned> top;
    4163        1200 :       Input input({true, source, top});
    4164        2000 :       for (unsigned module = 0; module <= 1; ++module) {
    4165        4000 :         for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
    4166             :              ++allow_lazy_parsing) {
    4167        1600 :           TestMaybeAssigned(input, "foo", module, allow_lazy_parsing);
    4168             :         }
    4169             :       }
    4170             :     }
    4171             :   }
    4172             : 
    4173         205 :   for (unsigned i = 0; i < arraysize(prefixes); ++i) {
    4174         900 :     for (unsigned j = 0; j < arraysize(script_only_tests); ++j) {
    4175         400 :       std::string source(prefixes[i]);
    4176         400 :       source += script_only_tests[j];
    4177             :       std::vector<unsigned> top;
    4178        1200 :       Input input({true, source, top});
    4179        2000 :       for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
    4180             :            ++allow_lazy_parsing) {
    4181         800 :         TestMaybeAssigned(input, "foo", false, allow_lazy_parsing);
    4182             :       }
    4183             :     }
    4184             :   }
    4185           5 : }
    4186             : 
    4187             : namespace {
    4188             : 
    4189           5 : i::Scope* DeserializeFunctionScope(i::Isolate* isolate, i::Zone* zone,
    4190             :                                    i::Handle<i::JSObject> m, const char* name) {
    4191             :   i::AstValueFactory avf(zone, isolate->ast_string_constants(),
    4192           5 :                          HashSeed(isolate));
    4193             :   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(
    4194          10 :       i::JSReceiver::GetProperty(isolate, m, name).ToHandleChecked());
    4195             :   i::DeclarationScope* script_scope =
    4196           5 :       new (zone) i::DeclarationScope(zone, &avf);
    4197           5 :   i::Scope* s = i::Scope::DeserializeScopeChain(
    4198          10 :       isolate, zone, f->context()->scope_info(), script_scope, &avf,
    4199           5 :       i::Scope::DeserializationMode::kIncludingVariables);
    4200           5 :   return s;
    4201             : }
    4202             : 
    4203             : }  // namespace
    4204             : 
    4205       26644 : TEST(AsmModuleFlag) {
    4206           5 :   i::FLAG_validate_asm = false;
    4207             :   i::Isolate* isolate = CcTest::i_isolate();
    4208             :   i::HandleScope scope(isolate);
    4209           5 :   LocalContext env;
    4210             : 
    4211             :   const char* src =
    4212             :       "function m() {"
    4213             :       "  'use asm';"
    4214             :       "  function f() { return 0 };"
    4215             :       "  return { f:f };"
    4216             :       "}"
    4217             :       "m();";
    4218             : 
    4219          10 :   i::Zone zone(isolate->allocator(), ZONE_NAME);
    4220             :   v8::Local<v8::Value> v = CompileRun(src);
    4221             :   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    4222           5 :   i::Handle<i::JSObject> m = i::Handle<i::JSObject>::cast(o);
    4223             : 
    4224             :   // The asm.js module should be marked as such.
    4225           5 :   i::Scope* s = DeserializeFunctionScope(isolate, &zone, m, "f");
    4226          10 :   CHECK(s->IsAsmModule() && s->AsDeclarationScope()->is_asm_module());
    4227           5 : }
    4228             : 
    4229             : 
    4230       26644 : TEST(UseAsmUseCount) {
    4231             :   i::Isolate* isolate = CcTest::i_isolate();
    4232             :   i::HandleScope scope(isolate);
    4233           5 :   LocalContext env;
    4234           5 :   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
    4235           5 :   global_use_counts = use_counts;
    4236           5 :   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
    4237             :   CompileRun("\"use asm\";\n"
    4238             :              "var foo = 1;\n"
    4239             :              "function bar() { \"use asm\"; var baz = 1; }");
    4240           5 :   CHECK_LT(0, use_counts[v8::Isolate::kUseAsm]);
    4241           5 : }
    4242             : 
    4243             : 
    4244       26644 : TEST(StrictModeUseCount) {
    4245             :   i::Isolate* isolate = CcTest::i_isolate();
    4246             :   i::HandleScope scope(isolate);
    4247           5 :   LocalContext env;
    4248           5 :   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
    4249           5 :   global_use_counts = use_counts;
    4250           5 :   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
    4251             :   CompileRun(
    4252             :       "\"use strict\";\n"
    4253             :       "function bar() { var baz = 1; }");  // strict mode inherits
    4254           5 :   CHECK_LT(0, use_counts[v8::Isolate::kStrictMode]);
    4255           5 :   CHECK_EQ(0, use_counts[v8::Isolate::kSloppyMode]);
    4256           5 : }
    4257             : 
    4258             : 
    4259       26644 : TEST(SloppyModeUseCount) {
    4260             :   i::Isolate* isolate = CcTest::i_isolate();
    4261             :   i::HandleScope scope(isolate);
    4262           5 :   LocalContext env;
    4263           5 :   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
    4264           5 :   global_use_counts = use_counts;
    4265             :   // Force eager parsing (preparser doesn't update use counts).
    4266           5 :   i::FLAG_lazy = false;
    4267           5 :   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
    4268             :   CompileRun("function bar() { var baz = 1; }");
    4269           5 :   CHECK_LT(0, use_counts[v8::Isolate::kSloppyMode]);
    4270           5 :   CHECK_EQ(0, use_counts[v8::Isolate::kStrictMode]);
    4271           5 : }
    4272             : 
    4273             : 
    4274       26644 : TEST(BothModesUseCount) {
    4275             :   i::Isolate* isolate = CcTest::i_isolate();
    4276             :   i::HandleScope scope(isolate);
    4277           5 :   LocalContext env;
    4278           5 :   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
    4279           5 :   global_use_counts = use_counts;
    4280             :   // Force eager parsing (preparser doesn't update use counts).
    4281           5 :   i::FLAG_lazy = false;
    4282           5 :   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
    4283             :   CompileRun("function bar() { 'use strict'; var baz = 1; }");
    4284           5 :   CHECK_LT(0, use_counts[v8::Isolate::kSloppyMode]);
    4285           5 :   CHECK_LT(0, use_counts[v8::Isolate::kStrictMode]);
    4286           5 : }
    4287             : 
    4288       26644 : TEST(LineOrParagraphSeparatorAsLineTerminator) {
    4289             :   // Tests that both preparsing and parsing accept U+2028 LINE SEPARATOR and
    4290             :   // U+2029 PARAGRAPH SEPARATOR as LineTerminator symbols outside of string
    4291             :   // literals.
    4292           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    4293             :   const char* statement_data[] = {"\x31\xE2\x80\xA8\x32",  // 1<U+2028>2
    4294             :                                   "\x31\xE2\x80\xA9\x32",  // 1<U+2029>2
    4295           5 :                                   nullptr};
    4296             : 
    4297           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    4298           5 : }
    4299             : 
    4300       26644 : TEST(LineOrParagraphSeparatorInStringLiteral) {
    4301             :   // Tests that both preparsing and parsing don't treat U+2028 LINE SEPARATOR
    4302             :   // and U+2029 PARAGRAPH SEPARATOR as line terminators within string literals.
    4303             :   // https://github.com/tc39/proposal-json-superset
    4304             :   const char* context_data[][2] = {
    4305           5 :       {"\"", "\""}, {"'", "'"}, {nullptr, nullptr}};
    4306             :   const char* statement_data[] = {"\x31\xE2\x80\xA8\x32",  // 1<U+2028>2
    4307             :                                   "\x31\xE2\x80\xA9\x32",  // 1<U+2029>2
    4308           5 :                                   nullptr};
    4309             : 
    4310           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    4311           5 : }
    4312             : 
    4313       26644 : TEST(ErrorsArrowFormalParameters) {
    4314             :   const char* context_data[][2] = {
    4315             :     { "()", "=>{}" },
    4316             :     { "()", "=>{};" },
    4317             :     { "var x = ()", "=>{}" },
    4318             :     { "var x = ()", "=>{};" },
    4319             : 
    4320             :     { "a", "=>{}" },
    4321             :     { "a", "=>{};" },
    4322             :     { "var x = a", "=>{}" },
    4323             :     { "var x = a", "=>{};" },
    4324             : 
    4325             :     { "(a)", "=>{}" },
    4326             :     { "(a)", "=>{};" },
    4327             :     { "var x = (a)", "=>{}" },
    4328             :     { "var x = (a)", "=>{};" },
    4329             : 
    4330             :     { "(...a)", "=>{}" },
    4331             :     { "(...a)", "=>{};" },
    4332             :     { "var x = (...a)", "=>{}" },
    4333             :     { "var x = (...a)", "=>{};" },
    4334             : 
    4335             :     { "(a,b)", "=>{}" },
    4336             :     { "(a,b)", "=>{};" },
    4337             :     { "var x = (a,b)", "=>{}" },
    4338             :     { "var x = (a,b)", "=>{};" },
    4339             : 
    4340             :     { "(a,...b)", "=>{}" },
    4341             :     { "(a,...b)", "=>{};" },
    4342             :     { "var x = (a,...b)", "=>{}" },
    4343             :     { "var x = (a,...b)", "=>{};" },
    4344             : 
    4345             :     { nullptr, nullptr }
    4346           5 :   };
    4347             :   const char* assignment_expression_suffix_data[] = {
    4348             :     "?c:d=>{}",
    4349             :     "=c=>{}",
    4350             :     "()",
    4351             :     "(c)",
    4352             :     "[1]",
    4353             :     "[c]",
    4354             :     ".c",
    4355             :     "-c",
    4356             :     "+c",
    4357             :     "c++",
    4358             :     "`c`",
    4359             :     "`${c}`",
    4360             :     "`template-head${c}`",
    4361             :     "`${c}template-tail`",
    4362             :     "`template-head${c}template-tail`",
    4363             :     "`${c}template-tail`",
    4364             :     nullptr
    4365           5 :   };
    4366             : 
    4367           5 :   RunParserSyncTest(context_data, assignment_expression_suffix_data, kError);
    4368           5 : }
    4369             : 
    4370             : 
    4371       26644 : TEST(ErrorsArrowFunctions) {
    4372             :   // Tests that parser and preparser generate the same kind of errors
    4373             :   // on invalid arrow function syntax.
    4374             : 
    4375             :   // clang-format off
    4376             :   const char* context_data[][2] = {
    4377             :     {"", ";"},
    4378             :     {"v = ", ";"},
    4379             :     {"bar ? (", ") : baz;"},
    4380             :     {"bar ? baz : (", ");"},
    4381             :     {"bar[", "];"},
    4382             :     {"bar, ", ";"},
    4383             :     {"", ", bar;"},
    4384             :     {nullptr, nullptr}
    4385           5 :   };
    4386             : 
    4387             :   const char* statement_data[] = {
    4388             :     "=> 0",
    4389             :     "=>",
    4390             :     "() =>",
    4391             :     "=> {}",
    4392             :     ") => {}",
    4393             :     ", => {}",
    4394             :     "(,) => {}",
    4395             :     "return => {}",
    4396             :     "() => {'value': 42}",
    4397             : 
    4398             :     // Check that the early return introduced in ParsePrimaryExpression
    4399             :     // does not accept stray closing parentheses.
    4400             :     ")",
    4401             :     ") => 0",
    4402             :     "foo[()]",
    4403             :     "()",
    4404             : 
    4405             :     // Parameter lists with extra parens should be recognized as errors.
    4406             :     "(()) => 0",
    4407             :     "((x)) => 0",
    4408             :     "((x, y)) => 0",
    4409             :     "(x, (y)) => 0",
    4410             :     "((x, y, z)) => 0",
    4411             :     "(x, (y, z)) => 0",
    4412             :     "((x, y), z) => 0",
    4413             : 
    4414             :     // Arrow function formal parameters are parsed as StrictFormalParameters,
    4415             :     // which confusingly only implies that there are no duplicates.  Words
    4416             :     // reserved in strict mode, and eval or arguments, are indeed valid in
    4417             :     // sloppy mode.
    4418             :     "eval => { 'use strict'; 0 }",
    4419             :     "arguments => { 'use strict'; 0 }",
    4420             :     "yield => { 'use strict'; 0 }",
    4421             :     "interface => { 'use strict'; 0 }",
    4422             :     "(eval) => { 'use strict'; 0 }",
    4423             :     "(arguments) => { 'use strict'; 0 }",
    4424             :     "(yield) => { 'use strict'; 0 }",
    4425             :     "(interface) => { 'use strict'; 0 }",
    4426             :     "(eval, bar) => { 'use strict'; 0 }",
    4427             :     "(bar, eval) => { 'use strict'; 0 }",
    4428             :     "(bar, arguments) => { 'use strict'; 0 }",
    4429             :     "(bar, yield) => { 'use strict'; 0 }",
    4430             :     "(bar, interface) => { 'use strict'; 0 }",
    4431             :     // TODO(aperez): Detecting duplicates does not work in PreParser.
    4432             :     // "(bar, bar) => {}",
    4433             : 
    4434             :     // The parameter list is parsed as an expression, but only
    4435             :     // a comma-separated list of identifier is valid.
    4436             :     "32 => {}",
    4437             :     "(32) => {}",
    4438             :     "(a, 32) => {}",
    4439             :     "if => {}",
    4440             :     "(if) => {}",
    4441             :     "(a, if) => {}",
    4442             :     "a + b => {}",
    4443             :     "(a + b) => {}",
    4444             :     "(a + b, c) => {}",
    4445             :     "(a, b - c) => {}",
    4446             :     "\"a\" => {}",
    4447             :     "(\"a\") => {}",
    4448             :     "(\"a\", b) => {}",
    4449             :     "(a, \"b\") => {}",
    4450             :     "-a => {}",
    4451             :     "(-a) => {}",
    4452             :     "(-a, b) => {}",
    4453             :     "(a, -b) => {}",
    4454             :     "{} => {}",
    4455             :     "a++ => {}",
    4456             :     "(a++) => {}",
    4457             :     "(a++, b) => {}",
    4458             :     "(a, b++) => {}",
    4459             :     "[] => {}",
    4460             :     "(foo ? bar : baz) => {}",
    4461             :     "(a, foo ? bar : baz) => {}",
    4462             :     "(foo ? bar : baz, a) => {}",
    4463             :     "(a.b, c) => {}",
    4464             :     "(c, a.b) => {}",
    4465             :     "(a['b'], c) => {}",
    4466             :     "(c, a['b']) => {}",
    4467             :     "(...a = b) => b",
    4468             : 
    4469             :     // crbug.com/582626
    4470             :     "(...rest - a) => b",
    4471             :     "(a, ...b - 10) => b",
    4472             : 
    4473             :     nullptr
    4474           5 :   };
    4475             :   // clang-format on
    4476             : 
    4477             :   // The test is quite slow, so run it with a reduced set of flags.
    4478             :   static const ParserFlag flags[] = {kAllowLazy};
    4479             :   RunParserSyncTest(context_data, statement_data, kError, flags,
    4480           5 :                     arraysize(flags));
    4481             : 
    4482             :   // In a context where a concise arrow body is parsed with [~In] variant,
    4483             :   // ensure that an error is reported in both full parser and preparser.
    4484             :   const char* loop_context_data[][2] = {{"for (", "; 0;);"},
    4485           5 :                                         {nullptr, nullptr}};
    4486           5 :   const char* loop_expr_data[] = {"f => 'key' in {}", nullptr};
    4487             :   RunParserSyncTest(loop_context_data, loop_expr_data, kError, flags,
    4488           5 :                     arraysize(flags));
    4489           5 : }
    4490             : 
    4491             : 
    4492       26644 : TEST(NoErrorsArrowFunctions) {
    4493             :   // Tests that parser and preparser accept valid arrow functions syntax.
    4494             :   // clang-format off
    4495             :   const char* context_data[][2] = {
    4496             :     {"", ";"},
    4497             :     {"bar ? (", ") : baz;"},
    4498             :     {"bar ? baz : (", ");"},
    4499             :     {"bar, ", ";"},
    4500             :     {"", ", bar;"},
    4501             :     {nullptr, nullptr}
    4502           5 :   };
    4503             : 
    4504             :   const char* statement_data[] = {
    4505             :     "() => {}",
    4506             :     "() => { return 42 }",
    4507             :     "x => { return x; }",
    4508             :     "(x) => { return x; }",
    4509             :     "(x, y) => { return x + y; }",
    4510             :     "(x, y, z) => { return x + y + z; }",
    4511             :     "(x, y) => { x.a = y; }",
    4512             :     "() => 42",
    4513             :     "x => x",
    4514             :     "x => x * x",
    4515             :     "(x) => x",
    4516             :     "(x) => x * x",
    4517             :     "(x, y) => x + y",
    4518             :     "(x, y, z) => x, y, z",
    4519             :     "(x, y) => x.a = y",
    4520             :     "() => ({'value': 42})",
    4521             :     "x => y => x + y",
    4522             :     "(x, y) => (u, v) => x*u + y*v",
    4523             :     "(x, y) => z => z * (x + y)",
    4524             :     "x => (y, z) => z * (x + y)",
    4525             : 
    4526             :     // Those are comma-separated expressions, with arrow functions as items.
    4527             :     // They stress the code for validating arrow function parameter lists.
    4528             :     "a, b => 0",
    4529             :     "a, b, (c, d) => 0",
    4530             :     "(a, b, (c, d) => 0)",
    4531             :     "(a, b) => 0, (c, d) => 1",
    4532             :     "(a, b => {}, a => a + 1)",
    4533             :     "((a, b) => {}, (a => a + 1))",
    4534             :     "(a, (a, (b, c) => 0))",
    4535             : 
    4536             :     // Arrow has more precedence, this is the same as: foo ? bar : (baz = {})
    4537             :     "foo ? bar : baz => {}",
    4538             : 
    4539             :     // Arrows with non-simple parameters.
    4540             :     "({}) => {}",
    4541             :     "(a, {}) => {}",
    4542             :     "({}, a) => {}",
    4543             :     "([]) => {}",
    4544             :     "(a, []) => {}",
    4545             :     "([], a) => {}",
    4546             :     "(a = b) => {}",
    4547             :     "(a = b, c) => {}",
    4548             :     "(a, b = c) => {}",
    4549             :     "({a}) => {}",
    4550             :     "(x = 9) => {}",
    4551             :     "(x, y = 9) => {}",
    4552             :     "(x = 9, y) => {}",
    4553             :     "(x, y = 9, z) => {}",
    4554             :     "(x, y = 9, z = 8) => {}",
    4555             :     "(...a) => {}",
    4556             :     "(x, ...a) => {}",
    4557             :     "(x = 9, ...a) => {}",
    4558             :     "(x, y = 9, ...a) => {}",
    4559             :     "(x, y = 9, {b}, z = 8, ...a) => {}",
    4560             :     "({a} = {}) => {}",
    4561             :     "([x] = []) => {}",
    4562             :     "({a = 42}) => {}",
    4563             :     "([x = 0]) => {}",
    4564             :     nullptr
    4565           5 :   };
    4566             :   // clang-format on
    4567             : 
    4568           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    4569             : 
    4570             :   static const ParserFlag flags[] = {kAllowLazy};
    4571             :   // In a context where a concise arrow body is parsed with [~In] variant,
    4572             :   // ensure that nested expressions can still use the 'in' operator,
    4573             :   const char* loop_context_data[][2] = {{"for (", "; 0;);"},
    4574           5 :                                         {nullptr, nullptr}};
    4575           5 :   const char* loop_expr_data[] = {"f => ('key' in {})", nullptr};
    4576             :   RunParserSyncTest(loop_context_data, loop_expr_data, kSuccess, flags,
    4577           5 :                     arraysize(flags));
    4578           5 : }
    4579             : 
    4580             : 
    4581       26644 : TEST(ArrowFunctionsSloppyParameterNames) {
    4582             :   const char* strict_context_data[][2] = {{"'use strict'; ", ";"},
    4583             :                                           {"'use strict'; bar ? (", ") : baz;"},
    4584             :                                           {"'use strict'; bar ? baz : (", ");"},
    4585             :                                           {"'use strict'; bar, ", ";"},
    4586             :                                           {"'use strict'; ", ", bar;"},
    4587           5 :                                           {nullptr, nullptr}};
    4588             : 
    4589             :   const char* sloppy_context_data[][2] = {
    4590             :       {"", ";"},      {"bar ? (", ") : baz;"}, {"bar ? baz : (", ");"},
    4591           5 :       {"bar, ", ";"}, {"", ", bar;"},          {nullptr, nullptr}};
    4592             : 
    4593             :   const char* statement_data[] = {"eval => {}",
    4594             :                                   "arguments => {}",
    4595             :                                   "yield => {}",
    4596             :                                   "interface => {}",
    4597             :                                   "(eval) => {}",
    4598             :                                   "(arguments) => {}",
    4599             :                                   "(yield) => {}",
    4600             :                                   "(interface) => {}",
    4601             :                                   "(eval, bar) => {}",
    4602             :                                   "(bar, eval) => {}",
    4603             :                                   "(bar, arguments) => {}",
    4604             :                                   "(bar, yield) => {}",
    4605             :                                   "(bar, interface) => {}",
    4606             :                                   "(interface, eval) => {}",
    4607             :                                   "(interface, arguments) => {}",
    4608             :                                   "(eval, interface) => {}",
    4609             :                                   "(arguments, interface) => {}",
    4610           5 :                                   nullptr};
    4611             : 
    4612           5 :   RunParserSyncTest(strict_context_data, statement_data, kError);
    4613           5 :   RunParserSyncTest(sloppy_context_data, statement_data, kSuccess);
    4614           5 : }
    4615             : 
    4616             : 
    4617       26644 : TEST(ArrowFunctionsYieldParameterNameInGenerator) {
    4618             :   const char* sloppy_function_context_data[][2] = {
    4619           5 :       {"(function f() { (", "); });"}, {nullptr, nullptr}};
    4620             : 
    4621             :   const char* strict_function_context_data[][2] = {
    4622           5 :       {"(function f() {'use strict'; (", "); });"}, {nullptr, nullptr}};
    4623             : 
    4624             :   const char* generator_context_data[][2] = {
    4625             :       {"(function *g() {'use strict'; (", "); });"},
    4626             :       {"(function *g() { (", "); });"},
    4627           5 :       {nullptr, nullptr}};
    4628             : 
    4629             :   const char* arrow_data[] = {
    4630             :       "yield => {}",      "(yield) => {}",       "(a, yield) => {}",
    4631             :       "(yield, a) => {}", "(yield, ...a) => {}", "(a, ...yield) => {}",
    4632           5 :       "({yield}) => {}",  "([yield]) => {}",     nullptr};
    4633             : 
    4634           5 :   RunParserSyncTest(sloppy_function_context_data, arrow_data, kSuccess);
    4635           5 :   RunParserSyncTest(strict_function_context_data, arrow_data, kError);
    4636           5 :   RunParserSyncTest(generator_context_data, arrow_data, kError);
    4637           5 : }
    4638             : 
    4639             : 
    4640       26644 : TEST(SuperNoErrors) {
    4641             :   // Tests that parser and preparser accept 'super' keyword in right places.
    4642             :   const char* context_data[][2] = {{"class C { m() { ", "; } }"},
    4643             :                                    {"class C { m() { k = ", "; } }"},
    4644             :                                    {"class C { m() { foo(", "); } }"},
    4645             :                                    {"class C { m() { () => ", "; } }"},
    4646           5 :                                    {nullptr, nullptr}};
    4647             : 
    4648             :   const char* statement_data[] = {"super.x",       "super[27]",
    4649             :                                   "new super.x",   "new super.x()",
    4650             :                                   "new super[27]", "new super[27]()",
    4651             :                                   "z.super",  // Ok, property lookup.
    4652           5 :                                   nullptr};
    4653             : 
    4654           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    4655           5 : }
    4656             : 
    4657             : 
    4658       26644 : TEST(SuperErrors) {
    4659             :   const char* context_data[][2] = {{"class C { m() { ", "; } }"},
    4660             :                                    {"class C { m() { k = ", "; } }"},
    4661             :                                    {"class C { m() { foo(", "); } }"},
    4662             :                                    {"class C { m() { () => ", "; } }"},
    4663           5 :                                    {nullptr, nullptr}};
    4664             : 
    4665             :   const char* expression_data[] = {"super",
    4666             :                                    "super = x",
    4667             :                                    "y = super",
    4668             :                                    "f(super)",
    4669             :                                    "new super",
    4670             :                                    "new super()",
    4671             :                                    "new super(12, 45)",
    4672             :                                    "new new super",
    4673             :                                    "new new super()",
    4674             :                                    "new new super()()",
    4675           5 :                                    nullptr};
    4676             : 
    4677           5 :   RunParserSyncTest(context_data, expression_data, kError);
    4678           5 : }
    4679             : 
    4680       26644 : TEST(ImportExpressionSuccess) {
    4681             :   // clang-format off
    4682             :   const char* context_data[][2] = {
    4683             :     {"", ""},
    4684             :     {nullptr, nullptr}
    4685           5 :   };
    4686             : 
    4687             :   const char* data[] = {
    4688             :     "import(1)",
    4689             :     "import(y=x)",
    4690             :     "f(...[import(y=x)])",
    4691             :     "x = {[import(y=x)]: 1}",
    4692             :     "var {[import(y=x)]: x} = {}",
    4693             :     "({[import(y=x)]: x} = {})",
    4694             :     "async () => { await import(x) }",
    4695             :     "() => { import(x) }",
    4696             :     "(import(y=x))",
    4697             :     "{import(y=x)}",
    4698             :     "import(import(x))",
    4699             :     "x = import(x)",
    4700             :     "var x = import(x)",
    4701             :     "let x = import(x)",
    4702             :     "for(x of import(x)) {}",
    4703             :     "import(x).then()",
    4704             :     nullptr
    4705           5 :   };
    4706             : 
    4707             :   // clang-format on
    4708             : 
    4709             :   // We ignore test error messages because the error message from the
    4710             :   // parser/preparser is different for the same data depending on the
    4711             :   // context.
    4712             :   // For example, a top level "import(" is parsed as an
    4713             :   // import declaration. The parser parses the import token correctly
    4714             :   // and then shows an "Unexpected token (" error message. The
    4715             :   // preparser does not understand the import keyword (this test is
    4716             :   // run without kAllowHarmonyDynamicImport flag), so this results in
    4717             :   // an "Unexpected token import" error.
    4718           5 :   RunParserSyncTest(context_data, data, kError);
    4719             :   RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
    4720             :                           nullptr, 0, true, true);
    4721             :   static const ParserFlag flags[] = {kAllowHarmonyDynamicImport};
    4722             :   RunParserSyncTest(context_data, data, kSuccess, nullptr, 0, flags,
    4723           5 :                     arraysize(flags));
    4724             :   RunModuleParserSyncTest(context_data, data, kSuccess, nullptr, 0, flags,
    4725             :                           arraysize(flags));
    4726           5 : }
    4727             : 
    4728       26644 : TEST(ImportExpressionErrors) {
    4729             :   {
    4730             :     // clang-format off
    4731             :     const char* context_data[][2] = {
    4732             :       {"", ""},
    4733             :       {"var ", ""},
    4734             :       {"let ", ""},
    4735             :       {"new ", ""},
    4736             :       {nullptr, nullptr}
    4737           5 :     };
    4738             : 
    4739             :     const char* data[] = {
    4740             :       "import(",
    4741             :       "import)",
    4742             :       "import()",
    4743             :       "import('x",
    4744             :       "import('x']",
    4745             :       "import['x')",
    4746             :       "import = x",
    4747             :       "import[",
    4748             :       "import[]",
    4749             :       "import]",
    4750             :       "import[x]",
    4751             :       "import{",
    4752             :       "import{x",
    4753             :       "import{x}",
    4754             :       "import(x, y)",
    4755             :       "import(...y)",
    4756             :       "import(x,)",
    4757             :       "import(,)",
    4758             :       "import(,y)",
    4759             :       "import(;)",
    4760             :       "[import]",
    4761             :       "{import}",
    4762             :       "import+",
    4763             :       "import = 1",
    4764             :       "import.wat",
    4765             :       "new import(x)",
    4766             :       nullptr
    4767           5 :     };
    4768             : 
    4769             :     // clang-format on
    4770           5 :     RunParserSyncTest(context_data, data, kError);
    4771             :     // We ignore the error messages for the reason explained in the
    4772             :     // ImportExpressionSuccess test.
    4773             :     RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
    4774             :                             nullptr, 0, true, true);
    4775             :     static const ParserFlag flags[] = {kAllowHarmonyDynamicImport};
    4776             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4777           5 :                       arraysize(flags));
    4778             : 
    4779             :     // We ignore test error messages because the error message from
    4780             :     // the parser/preparser is different for the same data depending
    4781             :     // on the context.  For example, a top level "import{" is parsed
    4782             :     // as an import declaration. The parser parses the import token
    4783             :     // correctly and then shows an "Unexpected end of input" error
    4784             :     // message because of the '{'. The preparser shows an "Unexpected
    4785             :     // token {" because it's not a valid token in a CallExpression.
    4786             :     RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4787             :                             arraysize(flags), nullptr, 0, true, true);
    4788             :   }
    4789             : 
    4790             :   {
    4791             :     // clang-format off
    4792             :     const char* context_data[][2] = {
    4793             :       {"var ", ""},
    4794             :       {"let ", ""},
    4795             :       {nullptr, nullptr}
    4796           5 :     };
    4797             : 
    4798             :     const char* data[] = {
    4799             :       "import('x')",
    4800             :       nullptr
    4801           5 :     };
    4802             : 
    4803             :     // clang-format on
    4804           5 :     RunParserSyncTest(context_data, data, kError);
    4805             :     RunModuleParserSyncTest(context_data, data, kError);
    4806             : 
    4807             :     static const ParserFlag flags[] = {kAllowHarmonyDynamicImport};
    4808             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4809           5 :                       arraysize(flags));
    4810             :     RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4811             :                             arraysize(flags));
    4812             :   }
    4813             : 
    4814             :   // Import statements as arrow function params and destructuring targets.
    4815             :   {
    4816             :     // clang-format off
    4817             :     const char* context_data[][2] = {
    4818             :       {"(", ") => {}"},
    4819             :       {"(a, ", ") => {}"},
    4820             :       {"(1, ", ") => {}"},
    4821             :       {"let f = ", " => {}"},
    4822             :       {"[", "] = [1];"},
    4823             :       {"{", "} = {'a': 1};"},
    4824             :       {nullptr, nullptr}
    4825           5 :     };
    4826             : 
    4827             :     const char* data[] = {
    4828             :       "import(foo)",
    4829             :       "import(1)",
    4830             :       "import(y=x)",
    4831             :       "import(import(x))",
    4832             :       "import(x).then()",
    4833             :       nullptr
    4834           5 :     };
    4835             : 
    4836             :     // clang-format on
    4837           5 :     RunParserSyncTest(context_data, data, kError);
    4838             :     RunModuleParserSyncTest(context_data, data, kError);
    4839             : 
    4840             :     static const ParserFlag flags[] = {kAllowHarmonyDynamicImport};
    4841             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4842           5 :                       arraysize(flags));
    4843             :     RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4844             :                             arraysize(flags));
    4845             :   }
    4846           5 : }
    4847             : 
    4848       26644 : TEST(SuperCall) {
    4849           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    4850             : 
    4851             :   const char* success_data[] = {
    4852             :       "class C extends B { constructor() { super(); } }",
    4853           5 :       "class C extends B { constructor() { () => super(); } }", nullptr};
    4854             : 
    4855           5 :   RunParserSyncTest(context_data, success_data, kSuccess);
    4856             : 
    4857             :   const char* error_data[] = {"class C { constructor() { super(); } }",
    4858             :                               "class C { method() { super(); } }",
    4859             :                               "class C { method() { () => super(); } }",
    4860             :                               "class C { *method() { super(); } }",
    4861             :                               "class C { get x() { super(); } }",
    4862             :                               "class C { set x(_) { super(); } }",
    4863             :                               "({ method() { super(); } })",
    4864             :                               "({ *method() { super(); } })",
    4865             :                               "({ get x() { super(); } })",
    4866             :                               "({ set x(_) { super(); } })",
    4867             :                               "({ f: function() { super(); } })",
    4868             :                               "(function() { super(); })",
    4869             :                               "var f = function() { super(); }",
    4870             :                               "({ f: function*() { super(); } })",
    4871             :                               "(function*() { super(); })",
    4872             :                               "var f = function*() { super(); }",
    4873           5 :                               nullptr};
    4874             : 
    4875           5 :   RunParserSyncTest(context_data, error_data, kError);
    4876           5 : }
    4877             : 
    4878             : 
    4879       26644 : TEST(SuperNewNoErrors) {
    4880             :   const char* context_data[][2] = {{"class C { constructor() { ", " } }"},
    4881             :                                    {"class C { *method() { ", " } }"},
    4882             :                                    {"class C { get x() { ", " } }"},
    4883             :                                    {"class C { set x(_) { ", " } }"},
    4884             :                                    {"({ method() { ", " } })"},
    4885             :                                    {"({ *method() { ", " } })"},
    4886             :                                    {"({ get x() { ", " } })"},
    4887             :                                    {"({ set x(_) { ", " } })"},
    4888           5 :                                    {nullptr, nullptr}};
    4889             : 
    4890             :   const char* expression_data[] = {"new super.x;", "new super.x();",
    4891             :                                    "() => new super.x;", "() => new super.x();",
    4892           5 :                                    nullptr};
    4893             : 
    4894           5 :   RunParserSyncTest(context_data, expression_data, kSuccess);
    4895           5 : }
    4896             : 
    4897             : 
    4898       26644 : TEST(SuperNewErrors) {
    4899             :   const char* context_data[][2] = {{"class C { method() { ", " } }"},
    4900             :                                    {"class C { *method() { ", " } }"},
    4901             :                                    {"class C { get x() { ", " } }"},
    4902             :                                    {"class C { set x(_) { ", " } }"},
    4903             :                                    {"({ method() { ", " } })"},
    4904             :                                    {"({ *method() { ", " } })"},
    4905             :                                    {"({ get x() { ", " } })"},
    4906             :                                    {"({ set x(_) { ", " } })"},
    4907             :                                    {"({ f: function() { ", " } })"},
    4908             :                                    {"(function() { ", " })"},
    4909             :                                    {"var f = function() { ", " }"},
    4910             :                                    {"({ f: function*() { ", " } })"},
    4911             :                                    {"(function*() { ", " })"},
    4912             :                                    {"var f = function*() { ", " }"},
    4913           5 :                                    {nullptr, nullptr}};
    4914             : 
    4915             :   const char* statement_data[] = {"new super;", "new super();",
    4916             :                                   "() => new super;", "() => new super();",
    4917           5 :                                   nullptr};
    4918             : 
    4919           5 :   RunParserSyncTest(context_data, statement_data, kError);
    4920           5 : }
    4921             : 
    4922             : 
    4923       26644 : TEST(SuperErrorsNonMethods) {
    4924             :   // super is only allowed in methods, accessors and constructors.
    4925             :   const char* context_data[][2] = {{"", ";"},
    4926             :                                    {"k = ", ";"},
    4927             :                                    {"foo(", ");"},
    4928             :                                    {"if (", ") {}"},
    4929             :                                    {"if (true) {", "}"},
    4930             :                                    {"if (false) {} else {", "}"},
    4931             :                                    {"while (true) {", "}"},
    4932             :                                    {"function f() {", "}"},
    4933             :                                    {"class C extends (", ") {}"},
    4934             :                                    {"class C { m() { function f() {", "} } }"},
    4935             :                                    {"({ m() { function f() {", "} } })"},
    4936           5 :                                    {nullptr, nullptr}};
    4937             : 
    4938             :   const char* statement_data[] = {
    4939             :       "super",           "super = x",   "y = super",     "f(super)",
    4940             :       "super.x",         "super[27]",   "super.x()",     "super[27]()",
    4941             :       "super()",         "new super.x", "new super.x()", "new super[27]",
    4942           5 :       "new super[27]()", nullptr};
    4943             : 
    4944           5 :   RunParserSyncTest(context_data, statement_data, kError);
    4945           5 : }
    4946             : 
    4947             : 
    4948       26644 : TEST(NoErrorsMethodDefinition) {
    4949             :   const char* context_data[][2] = {{"({", "});"},
    4950             :                                    {"'use strict'; ({", "});"},
    4951             :                                    {"({*", "});"},
    4952             :                                    {"'use strict'; ({*", "});"},
    4953           5 :                                    {nullptr, nullptr}};
    4954             : 
    4955             :   const char* object_literal_body_data[] = {
    4956             :       "m() {}",       "m(x) { return x; }", "m(x, y) {}, n() {}",
    4957           5 :       "set(x, y) {}", "get(x, y) {}",       nullptr};
    4958             : 
    4959           5 :   RunParserSyncTest(context_data, object_literal_body_data, kSuccess);
    4960           5 : }
    4961             : 
    4962             : 
    4963       26644 : TEST(MethodDefinitionNames) {
    4964             :   const char* context_data[][2] = {{"({", "(x, y) {}});"},
    4965             :                                    {"'use strict'; ({", "(x, y) {}});"},
    4966             :                                    {"({*", "(x, y) {}});"},
    4967             :                                    {"'use strict'; ({*", "(x, y) {}});"},
    4968           5 :                                    {nullptr, nullptr}};
    4969             : 
    4970             :   const char* name_data[] = {
    4971             :       "m", "'m'", "\"m\"", "\"m n\"", "true", "false", "null", "0", "1.2",
    4972             :       "1e1", "1E1", "1e+1", "1e-1",
    4973             : 
    4974             :       // Keywords
    4975             :       "async", "await", "break", "case", "catch", "class", "const", "continue",
    4976             :       "debugger", "default", "delete", "do", "else", "enum", "export",
    4977             :       "extends", "finally", "for", "function", "if", "implements", "import",
    4978             :       "in", "instanceof", "interface", "let", "new", "package", "private",
    4979             :       "protected", "public", "return", "static", "super", "switch", "this",
    4980             :       "throw", "try", "typeof", "var", "void", "while", "with", "yield",
    4981           5 :       nullptr};
    4982             : 
    4983           5 :   RunParserSyncTest(context_data, name_data, kSuccess);
    4984           5 : }
    4985             : 
    4986             : 
    4987       26644 : TEST(MethodDefinitionStrictFormalParamereters) {
    4988             :   const char* context_data[][2] = {{"({method(", "){}});"},
    4989             :                                    {"'use strict'; ({method(", "){}});"},
    4990             :                                    {"({*method(", "){}});"},
    4991             :                                    {"'use strict'; ({*method(", "){}});"},
    4992           5 :                                    {nullptr, nullptr}};
    4993             : 
    4994           5 :   const char* params_data[] = {"x, x", "x, y, x", "var", "const", nullptr};
    4995             : 
    4996           5 :   RunParserSyncTest(context_data, params_data, kError);
    4997           5 : }
    4998             : 
    4999             : 
    5000       26644 : TEST(MethodDefinitionEvalArguments) {
    5001             :   const char* strict_context_data[][2] = {
    5002             :       {"'use strict'; ({method(", "){}});"},
    5003             :       {"'use strict'; ({*method(", "){}});"},
    5004           5 :       {nullptr, nullptr}};
    5005             :   const char* sloppy_context_data[][2] = {
    5006           5 :       {"({method(", "){}});"}, {"({*method(", "){}});"}, {nullptr, nullptr}};
    5007             : 
    5008           5 :   const char* data[] = {"eval", "arguments", nullptr};
    5009             : 
    5010             :   // Fail in strict mode
    5011           5 :   RunParserSyncTest(strict_context_data, data, kError);
    5012             : 
    5013             :   // OK in sloppy mode
    5014           5 :   RunParserSyncTest(sloppy_context_data, data, kSuccess);
    5015           5 : }
    5016             : 
    5017             : 
    5018       26644 : TEST(MethodDefinitionDuplicateEvalArguments) {
    5019             :   const char* context_data[][2] = {{"'use strict'; ({method(", "){}});"},
    5020             :                                    {"'use strict'; ({*method(", "){}});"},
    5021             :                                    {"({method(", "){}});"},
    5022             :                                    {"({*method(", "){}});"},
    5023           5 :                                    {nullptr, nullptr}};
    5024             : 
    5025             :   const char* data[] = {"eval, eval", "eval, a, eval", "arguments, arguments",
    5026           5 :                         "arguments, a, arguments", nullptr};
    5027             : 
    5028             :   // In strict mode, the error is using "eval" or "arguments" as parameter names
    5029             :   // In sloppy mode, the error is that eval / arguments are duplicated
    5030           5 :   RunParserSyncTest(context_data, data, kError);
    5031           5 : }
    5032             : 
    5033             : 
    5034       26644 : TEST(MethodDefinitionDuplicateProperty) {
    5035             :   const char* context_data[][2] = {{"'use strict'; ({", "});"},
    5036           5 :                                    {nullptr, nullptr}};
    5037             : 
    5038             :   const char* params_data[] = {"x: 1, x() {}",
    5039             :                                "x() {}, x: 1",
    5040             :                                "x() {}, get x() {}",
    5041             :                                "x() {}, set x(_) {}",
    5042             :                                "x() {}, x() {}",
    5043             :                                "x() {}, y() {}, x() {}",
    5044             :                                "x() {}, \"x\"() {}",
    5045             :                                "x() {}, 'x'() {}",
    5046             :                                "0() {}, '0'() {}",
    5047             :                                "1.0() {}, 1: 1",
    5048             : 
    5049             :                                "x: 1, *x() {}",
    5050             :                                "*x() {}, x: 1",
    5051             :                                "*x() {}, get x() {}",
    5052             :                                "*x() {}, set x(_) {}",
    5053             :                                "*x() {}, *x() {}",
    5054             :                                "*x() {}, y() {}, *x() {}",
    5055             :                                "*x() {}, *\"x\"() {}",
    5056             :                                "*x() {}, *'x'() {}",
    5057             :                                "*0() {}, *'0'() {}",
    5058             :                                "*1.0() {}, 1: 1",
    5059             : 
    5060           5 :                                nullptr};
    5061             : 
    5062           5 :   RunParserSyncTest(context_data, params_data, kSuccess);
    5063           5 : }
    5064             : 
    5065             : 
    5066       26644 : TEST(ClassExpressionNoErrors) {
    5067             :   const char* context_data[][2] = {
    5068           5 :       {"(", ");"}, {"var C = ", ";"}, {"bar, ", ";"}, {nullptr, nullptr}};
    5069             :   const char* class_data[] = {"class {}",
    5070             :                               "class name {}",
    5071             :                               "class extends F {}",
    5072             :                               "class name extends F {}",
    5073             :                               "class extends (F, G) {}",
    5074             :                               "class name extends (F, G) {}",
    5075             :                               "class extends class {} {}",
    5076             :                               "class name extends class {} {}",
    5077             :                               "class extends class base {} {}",
    5078             :                               "class name extends class base {} {}",
    5079           5 :                               nullptr};
    5080             : 
    5081           5 :   RunParserSyncTest(context_data, class_data, kSuccess);
    5082           5 : }
    5083             : 
    5084             : 
    5085       26644 : TEST(ClassDeclarationNoErrors) {
    5086             :   const char* context_data[][2] = {{"'use strict'; ", ""},
    5087             :                                    {"'use strict'; {", "}"},
    5088             :                                    {"'use strict'; if (true) {", "}"},
    5089           5 :                                    {nullptr, nullptr}};
    5090             :   const char* statement_data[] = {"class name {}",
    5091             :                                   "class name extends F {}",
    5092             :                                   "class name extends (F, G) {}",
    5093             :                                   "class name extends class {} {}",
    5094             :                                   "class name extends class base {} {}",
    5095           5 :                                   nullptr};
    5096             : 
    5097           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    5098           5 : }
    5099             : 
    5100             : 
    5101       26644 : TEST(ClassBodyNoErrors) {
    5102             :   // clang-format off
    5103             :   // Tests that parser and preparser accept valid class syntax.
    5104             :   const char* context_data[][2] = {{"(class {", "});"},
    5105             :                                    {"(class extends Base {", "});"},
    5106             :                                    {"class C {", "}"},
    5107             :                                    {"class C extends Base {", "}"},
    5108           5 :                                    {nullptr, nullptr}};
    5109             :   const char* class_body_data[] = {
    5110             :     ";",
    5111             :     ";;",
    5112             :     "m() {}",
    5113             :     "m() {};",
    5114             :     "; m() {}",
    5115             :     "m() {}; n(x) {}",
    5116             :     "get x() {}",
    5117             :     "set x(v) {}",
    5118             :     "get() {}",
    5119             :     "set() {}",
    5120             :     "*g() {}",
    5121             :     "*g() {};",
    5122             :     "; *g() {}",
    5123             :     "*g() {}; *h(x) {}",
    5124             :     "async *x(){}",
    5125             :     "static() {}",
    5126             :     "get static() {}",
    5127             :     "set static(v) {}",
    5128             :     "static m() {}",
    5129             :     "static get x() {}",
    5130             :     "static set x(v) {}",
    5131             :     "static get() {}",
    5132             :     "static set() {}",
    5133             :     "static static() {}",
    5134             :     "static get static() {}",
    5135             :     "static set static(v) {}",
    5136             :     "*static() {}",
    5137             :     "static *static() {}",
    5138             :     "*get() {}",
    5139             :     "*set() {}",
    5140             :     "static *g() {}",
    5141             :     "async(){}",
    5142             :     "*async(){}",
    5143             :     "static async(){}",
    5144             :     "static *async(){}",
    5145             :     "static async *x(){}",
    5146             : 
    5147             :     // Escaped 'static' should be allowed anywhere
    5148             :     // static-as-PropertyName is.
    5149             :     "st\\u0061tic() {}",
    5150             :     "get st\\u0061tic() {}",
    5151             :     "set st\\u0061tic(v) {}",
    5152             :     "static st\\u0061tic() {}",
    5153             :     "static get st\\u0061tic() {}",
    5154             :     "static set st\\u0061tic(v) {}",
    5155             :     "*st\\u0061tic() {}",
    5156             :     "static *st\\u0061tic() {}",
    5157             : 
    5158             :     "static async x(){}",
    5159             :     "static async(){}",
    5160             :     "static *async(){}",
    5161             :     "async x(){}",
    5162             :     "async 0(){}",
    5163             :     "async get(){}",
    5164             :     "async set(){}",
    5165             :     "async static(){}",
    5166             :     "async async(){}",
    5167             :     "async(){}",
    5168             :     "*async(){}",
    5169           5 :     nullptr};
    5170             :   // clang-format on
    5171             : 
    5172           5 :   RunParserSyncTest(context_data, class_body_data, kSuccess);
    5173           5 : }
    5174             : 
    5175             : 
    5176       26644 : TEST(ClassPropertyNameNoErrors) {
    5177             :   const char* context_data[][2] = {{"(class {", "() {}});"},
    5178             :                                    {"(class { get ", "() {}});"},
    5179             :                                    {"(class { set ", "(v) {}});"},
    5180             :                                    {"(class { static ", "() {}});"},
    5181             :                                    {"(class { static get ", "() {}});"},
    5182             :                                    {"(class { static set ", "(v) {}});"},
    5183             :                                    {"(class { *", "() {}});"},
    5184             :                                    {"(class { static *", "() {}});"},
    5185             :                                    {"class C {", "() {}}"},
    5186             :                                    {"class C { get ", "() {}}"},
    5187             :                                    {"class C { set ", "(v) {}}"},
    5188             :                                    {"class C { static ", "() {}}"},
    5189             :                                    {"class C { static get ", "() {}}"},
    5190             :                                    {"class C { static set ", "(v) {}}"},
    5191             :                                    {"class C { *", "() {}}"},
    5192             :                                    {"class C { static *", "() {}}"},
    5193           5 :                                    {nullptr, nullptr}};
    5194             :   const char* name_data[] = {
    5195             :       "42",       "42.5",  "42e2",  "42e+2",   "42e-2",  "null",
    5196             :       "false",    "true",  "'str'", "\"str\"", "static", "get",
    5197             :       "set",      "var",   "const", "let",     "this",   "class",
    5198             :       "function", "yield", "if",    "else",    "for",    "while",
    5199           5 :       "do",       "try",   "catch", "finally", nullptr};
    5200             : 
    5201           5 :   RunParserSyncTest(context_data, name_data, kSuccess);
    5202           5 : }
    5203             : 
    5204       26644 : TEST(StaticClassFieldsNoErrors) {
    5205             :   // clang-format off
    5206             :   // Tests proposed class fields syntax.
    5207             :   const char* context_data[][2] = {{"(class {", "});"},
    5208             :                                    {"(class extends Base {", "});"},
    5209             :                                    {"class C {", "}"},
    5210             :                                    {"class C extends Base {", "}"},
    5211           5 :                                    {nullptr, nullptr}};
    5212             :   const char* class_body_data[] = {
    5213             :     // Basic syntax
    5214             :     "static a = 0;",
    5215             :     "static a = 0; b",
    5216             :     "static a = 0; b(){}",
    5217             :     "static a = 0; *b(){}",
    5218             :     "static a = 0; ['b'](){}",
    5219             :     "static a;",
    5220             :     "static a; b;",
    5221             :     "static a; b(){}",
    5222             :     "static a; *b(){}",
    5223             :     "static a; ['b'](){}",
    5224             :     "static ['a'] = 0;",
    5225             :     "static ['a'] = 0; b",
    5226             :     "static ['a'] = 0; b(){}",
    5227             :     "static ['a'] = 0; *b(){}",
    5228             :     "static ['a'] = 0; ['b'](){}",
    5229             :     "static ['a'];",
    5230             :     "static ['a']; b;",
    5231             :     "static ['a']; b(){}",
    5232             :     "static ['a']; *b(){}",
    5233             :     "static ['a']; ['b'](){}",
    5234             : 
    5235             :     "static 0 = 0;",
    5236             :     "static 0;",
    5237             :     "static 'a' = 0;",
    5238             :     "static 'a';",
    5239             : 
    5240             :     "static c = [c] = c",
    5241             : 
    5242             :     // ASI
    5243             :     "static a = 0\n",
    5244             :     "static a = 0\n b",
    5245             :     "static a = 0\n b(){}",
    5246             :     "static a\n",
    5247             :     "static a\n b\n",
    5248             :     "static a\n b(){}",
    5249             :     "static a\n *b(){}",
    5250             :     "static a\n ['b'](){}",
    5251             :     "static ['a'] = 0\n",
    5252             :     "static ['a'] = 0\n b",
    5253             :     "static ['a'] = 0\n b(){}",
    5254             :     "static ['a']\n",
    5255             :     "static ['a']\n b\n",
    5256             :     "static ['a']\n b(){}",
    5257             :     "static ['a']\n *b(){}",
    5258             :     "static ['a']\n ['b'](){}",
    5259             : 
    5260             :     "static a = function t() { arguments; }",
    5261             :     "static a = () => function t() { arguments; }",
    5262             : 
    5263             :     // ASI edge cases
    5264             :     "static a\n get",
    5265             :     "static get\n *a(){}",
    5266             :     "static a\n static",
    5267             : 
    5268             :     // Misc edge cases
    5269             :     "static yield",
    5270             :     "static yield = 0",
    5271             :     "static yield\n a",
    5272             :     "static async;",
    5273             :     "static async = 0;",
    5274             :     "static async",
    5275             :     "static async = 0",
    5276             :     "static async\n a(){}",  // a field named async, and a method named a.
    5277             :     "static async\n a",
    5278             :     "static await;",
    5279             :     "static await = 0;",
    5280             :     "static await\n a",
    5281             :     nullptr
    5282           5 :   };
    5283             :   // clang-format on
    5284             : 
    5285             :   static const ParserFlag always_flags[] = {kAllowHarmonyPublicFields,
    5286             :                                             kAllowHarmonyStaticFields};
    5287             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5288           5 :                     always_flags, arraysize(always_flags));
    5289             : 
    5290             :   // Without the static flag, all of these are errors
    5291             :   static const ParserFlag no_static_flags[] = {kAllowHarmonyPublicFields};
    5292             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5293           5 :                     no_static_flags, arraysize(no_static_flags));
    5294           5 : }
    5295             : 
    5296       26644 : TEST(ClassFieldsNoErrors) {
    5297             :   // clang-format off
    5298             :   // Tests proposed class fields syntax.
    5299             :   const char* context_data[][2] = {{"(class {", "});"},
    5300             :                                    {"(class extends Base {", "});"},
    5301             :                                    {"class C {", "}"},
    5302             :                                    {"class C extends Base {", "}"},
    5303           5 :                                    {nullptr, nullptr}};
    5304             :   const char* class_body_data[] = {
    5305             :     // Basic syntax
    5306             :     "a = 0;",
    5307             :     "a = 0; b",
    5308             :     "a = 0; b(){}",
    5309             :     "a = 0; *b(){}",
    5310             :     "a = 0; ['b'](){}",
    5311             :     "a;",
    5312             :     "a; b;",
    5313             :     "a; b(){}",
    5314             :     "a; *b(){}",
    5315             :     "a; ['b'](){}",
    5316             :     "['a'] = 0;",
    5317             :     "['a'] = 0; b",
    5318             :     "['a'] = 0; b(){}",
    5319             :     "['a'] = 0; *b(){}",
    5320             :     "['a'] = 0; ['b'](){}",
    5321             :     "['a'];",
    5322             :     "['a']; b;",
    5323             :     "['a']; b(){}",
    5324             :     "['a']; *b(){}",
    5325             :     "['a']; ['b'](){}",
    5326             : 
    5327             :     "0 = 0;",
    5328             :     "0;",
    5329             :     "'a' = 0;",
    5330             :     "'a';",
    5331             : 
    5332             :     "c = [c] = c",
    5333             : 
    5334             :     // ASI
    5335             :     "a = 0\n",
    5336             :     "a = 0\n b",
    5337             :     "a = 0\n b(){}",
    5338             :     "a\n",
    5339             :     "a\n b\n",
    5340             :     "a\n b(){}",
    5341             :     "a\n *b(){}",
    5342             :     "a\n ['b'](){}",
    5343             :     "['a'] = 0\n",
    5344             :     "['a'] = 0\n b",
    5345             :     "['a'] = 0\n b(){}",
    5346             :     "['a']\n",
    5347             :     "['a']\n b\n",
    5348             :     "['a']\n b(){}",
    5349             :     "['a']\n *b(){}",
    5350             :     "['a']\n ['b'](){}",
    5351             : 
    5352             :     // ASI edge cases
    5353             :     "a\n get",
    5354             :     "get\n *a(){}",
    5355             :     "a\n static",
    5356             : 
    5357             :     "a = function t() { arguments; }",
    5358             :     "a = () => function() { arguments; }",
    5359             : 
    5360             :     // Misc edge cases
    5361             :     "yield",
    5362             :     "yield = 0",
    5363             :     "yield\n a",
    5364             :     "async;",
    5365             :     "async = 0;",
    5366             :     "async",
    5367             :     "async = 0",
    5368             :     "async\n a(){}",  // a field named async, and a method named a.
    5369             :     "async\n a",
    5370             :     "await;",
    5371             :     "await = 0;",
    5372             :     "await\n a",
    5373             :     nullptr
    5374           5 :   };
    5375             :   // clang-format on
    5376             : 
    5377             :   static const ParserFlag always_flags[] = {kAllowHarmonyPublicFields};
    5378             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5379           5 :                     always_flags, arraysize(always_flags));
    5380             : 
    5381             :   static const ParserFlag static_flags[] = {kAllowHarmonyPublicFields,
    5382             :                                             kAllowHarmonyStaticFields};
    5383             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5384           5 :                     static_flags, arraysize(static_flags));
    5385           5 : }
    5386             : 
    5387       26644 : TEST(PrivateMethodsNoErrors) {
    5388             :   // clang-format off
    5389             :   // Tests proposed class methods syntax.
    5390             :   const char* context_data[][2] = {{"(class {", "});"},
    5391             :                                    {"(class extends Base {", "});"},
    5392             :                                    {"class C {", "}"},
    5393             :                                    {"class C extends Base {", "}"},
    5394           5 :                                    {nullptr, nullptr}};
    5395             :   const char* class_body_data[] = {
    5396             :     // Basic syntax
    5397             :     "#a() { }",
    5398             :     "get #a() { }",
    5399             :     "set #a(foo) { }",
    5400             :     "*#a() { }",
    5401             :     "async #a() { }",
    5402             :     "async *#a() { }",
    5403             : 
    5404             :     "#a() { } #b() {}",
    5405             :     "get #a() { } set #a(foo) {}",
    5406             :     "get #a() { } get #b() {} set #a(foo) {}",
    5407             :     "get #a() { } get #b() {} set #a(foo) {} set #b(foo) {}",
    5408             :     "set #a(foo) { } set #b(foo) {}",
    5409             :     "get #a() { } get #b() {}",
    5410             : 
    5411             :     "#a() { } static a() {}",
    5412             :     "#a() { } a() {}",
    5413             :     "#a() { } a() {} static a() {}",
    5414             :     "get #a() { } get a() {} static get a() {}",
    5415             :     "set #a(foo) { } set a(foo) {} static set a(foo) {}",
    5416             : 
    5417             :     "#a() { } get #b() {}",
    5418             :     "#a() { } async #b() {}",
    5419             :     "#a() { } async *#b() {}",
    5420             : 
    5421             :     // With arguments
    5422             :     "#a(...args) { }",
    5423             :     "#a(a = 1) { }",
    5424             :     "get #a() { }",
    5425             :     "set #a(a = (...args) => {}) { }",
    5426             : 
    5427             :     // Misc edge cases
    5428             :     "#get() {}",
    5429             :     "#set() {}",
    5430             :     "#yield() {}",
    5431             :     "#await() {}",
    5432             :     "#async() {}",
    5433             :     "#static() {}",
    5434             :     "#arguments() {}",
    5435             :     "get #yield() {}",
    5436             :     "get #await() {}",
    5437             :     "get #async() {}",
    5438             :     "get #get() {}",
    5439             :     "get #static() {}",
    5440             :     "get #arguments() {}",
    5441             :     "set #yield(test) {}",
    5442             :     "set #async(test) {}",
    5443             :     "set #await(test) {}",
    5444             :     "set #set(test) {}",
    5445             :     "set #static(test) {}",
    5446             :     "set #arguments(test) {}",
    5447             :     "async #yield() {}",
    5448             :     "async #async() {}",
    5449             :     "async #await() {}",
    5450             :     "async #get() {}",
    5451             :     "async #set() {}",
    5452             :     "async #static() {}",
    5453             :     "async #arguments() {}",
    5454             :     "*#async() {}",
    5455             :     "*#await() {}",
    5456             :     "*#yield() {}",
    5457             :     "*#get() {}",
    5458             :     "*#set() {}",
    5459             :     "*#static() {}",
    5460             :     "*#arguments() {}",
    5461             :     "async *#yield() {}",
    5462             :     "async *#async() {}",
    5463             :     "async *#await() {}",
    5464             :     "async *#get() {}",
    5465             :     "async *#set() {}",
    5466             :     "async *#static() {}",
    5467             :     "async *#arguments() {}",
    5468             :     nullptr
    5469           5 :   };
    5470             :   // clang-format on
    5471             : 
    5472           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5473             : 
    5474             :   static const ParserFlag private_methods[] = {kAllowHarmonyPrivateFields,
    5475             :                                                kAllowHarmonyPrivateMethods};
    5476             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5477           5 :                     private_methods, arraysize(private_methods));
    5478           5 : }
    5479             : 
    5480       26644 : TEST(PrivateMethodsAndFieldsNoErrors) {
    5481             :   // clang-format off
    5482             :   // Tests proposed class methods syntax in combination with fields
    5483             :   const char* context_data[][2] = {{"(class {", "});"},
    5484             :                                    {"(class extends Base {", "});"},
    5485             :                                    {"class C {", "}"},
    5486             :                                    {"class C extends Base {", "}"},
    5487           5 :                                    {nullptr, nullptr}};
    5488             :   const char* class_body_data[] = {
    5489             :     // Basic syntax
    5490             :     "#b;#a() { }",
    5491             :     "#b;get #a() { }",
    5492             :     "#b;set #a(foo) { }",
    5493             :     "#b;*#a() { }",
    5494             :     "#b;async #a() { }",
    5495             :     "#b;async *#a() { }",
    5496             :     "#b = 1;#a() { }",
    5497             :     "#b = 1;get #a() { }",
    5498             :     "#b = 1;set #a(foo) { }",
    5499             :     "#b = 1;*#a() { }",
    5500             :     "#b = 1;async #a() { }",
    5501             :     "#b = 1;async *#a() { }",
    5502             : 
    5503             :     // With public fields
    5504             :     "a;#a() { }",
    5505             :     "a;get #a() { }",
    5506             :     "a;set #a(foo) { }",
    5507             :     "a;*#a() { }",
    5508             :     "a;async #a() { }",
    5509             :     "a;async *#a() { }",
    5510             :     "a = 1;#a() { }",
    5511             :     "a = 1;get #a() { }",
    5512             :     "a = 1;set #a(foo) { }",
    5513             :     "a = 1;*#a() { }",
    5514             :     "a = 1;async #a() { }",
    5515             :     "a = 1;async *#a() { }",
    5516             : 
    5517             :     // ASI
    5518             :     "#a = 0\n #b(){}",
    5519             :     "#a\n *#b(){}",
    5520             :     "#a = 0\n get #b(){}",
    5521             :     "#a\n *#b(){}",
    5522             : 
    5523             :     "b = 0\n #b(){}",
    5524             :     "b\n *#b(){}",
    5525             :     "b = 0\n get #b(){}",
    5526             :     "b\n *#b(){}",
    5527             :     nullptr
    5528           5 :   };
    5529             :   // clang-format on
    5530             : 
    5531           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5532             : 
    5533             :   static const ParserFlag private_methods_and_fields[] = {
    5534             :       kAllowHarmonyPrivateFields, kAllowHarmonyPublicFields,
    5535             :       kAllowHarmonyPrivateMethods};
    5536             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5537             :                     private_methods_and_fields,
    5538           5 :                     arraysize(private_methods_and_fields));
    5539           5 : }
    5540             : 
    5541       26644 : TEST(PrivateMethodsErrors) {
    5542             :   // clang-format off
    5543             :   // Tests proposed class methods syntax in combination with fields
    5544             :   const char* context_data[][2] = {{"(class {", "});"},
    5545             :                                    {"(class extends Base {", "});"},
    5546             :                                    {"class C {", "}"},
    5547             :                                    {"class C extends Base {", "}"},
    5548           5 :                                    {nullptr, nullptr}};
    5549             :   const char* class_body_data[] = {
    5550             :     "#a() : 0",
    5551             :     "#a() =",
    5552             :     "#a() => {}",
    5553             :     "#a => {}",
    5554             :     "*#a() = 0",
    5555             :     "*#a() => 0",
    5556             :     "*#a() => {}",
    5557             :     "get #a()[]",
    5558             :     "yield #a()[]",
    5559             :     "yield #a => {}",
    5560             :     "async #a() = 0",
    5561             :     "async #a => {}",
    5562             :     "#a(arguments) {}",
    5563             :     "set #a(arguments) {}",
    5564             : 
    5565             :     "#['a']() { }",
    5566             :     "get #['a']() { }",
    5567             :     "set #['a'](foo) { }",
    5568             :     "*#['a']() { }",
    5569             :     "async #['a']() { }",
    5570             :     "async *#['a]() { }",
    5571             : 
    5572             :     // TODO(joyee): check duplicate accessors
    5573             : 
    5574             :     "#a\n#",
    5575             :     "#a() c",
    5576             :     "#a() #",
    5577             :     "#a(arg) c",
    5578             :     "#a(arg) #",
    5579             :     "#a(arg) #c",
    5580             :     "#a#",
    5581             :     "#a#b",
    5582             :     "#a#b(){}",
    5583             :     "#[test](){}",
    5584             : 
    5585             :     "async *#constructor() {}",
    5586             :     "*#constructor() {}",
    5587             :     "async #constructor() {}",
    5588             :     "set #constructor(test) {}",
    5589             :     "#constructor() {}",
    5590             :     "get #constructor() {}",
    5591             :     nullptr
    5592           5 :   };
    5593             :   // clang-format on
    5594             : 
    5595           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5596             : 
    5597             :   static const ParserFlag private_methods[] = {kAllowHarmonyPrivateFields,
    5598             :                                                kAllowHarmonyPrivateMethods};
    5599             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5600           5 :                     private_methods, arraysize(private_methods));
    5601           5 : }
    5602             : 
    5603             : // Test that private members do not parse outside class bodies
    5604       26644 : TEST(PrivateMembersInNonClassNoErrors) {
    5605             :   // clang-format off
    5606             :   const char* context_data[][2] = {{"", ""},
    5607             :                                    {"({", "})"},
    5608             :                                    {"'use strict'; ({", "});"},
    5609             :                                    {"function() {", "}"},
    5610             :                                    {"() => {", "}"},
    5611             :                                    {"class C { test() {", "} }"},
    5612             :                                    {"const {", "} = {}"},
    5613             :                                    {"({", "} = {})"},
    5614           5 :                                    {nullptr, nullptr}};
    5615             :   const char* class_body_data[] = {
    5616             :     "#a = 1",
    5617             :     "#a = () => {}",
    5618             :     "#a",
    5619             :     "#a() { }",
    5620             :     "get #a() { }",
    5621             :     "set #a(foo) { }",
    5622             :     "*#a() { }",
    5623             :     "async #a() { }",
    5624             :     "async *#a() { }",
    5625             :     nullptr
    5626           5 :   };
    5627             :   // clang-format on
    5628             : 
    5629           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5630             : 
    5631             :   static const ParserFlag private_methods[] = {kAllowHarmonyPrivateFields,
    5632             :                                                kAllowHarmonyPrivateMethods};
    5633             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5634           5 :                     private_methods, arraysize(private_methods));
    5635           5 : }
    5636             : 
    5637       26644 : TEST(PrivateClassFieldsNoErrors) {
    5638             :   // clang-format off
    5639             :   // Tests proposed class fields syntax.
    5640             :   const char* context_data[][2] = {{"(class {", "});"},
    5641             :                                    {"(class extends Base {", "});"},
    5642             :                                    {"class C {", "}"},
    5643             :                                    {"class C extends Base {", "}"},
    5644           5 :                                    {nullptr, nullptr}};
    5645             :   const char* class_body_data[] = {
    5646             :     // Basic syntax
    5647             :     "#a = 0;",
    5648             :     "#a = 0; #b",
    5649             :     "#a = 0; b",
    5650             :     "#a = 0; b(){}",
    5651             :     "#a = 0; *b(){}",
    5652             :     "#a = 0; ['b'](){}",
    5653             :     "#a;",
    5654             :     "#a; #b;",
    5655             :     "#a; b;",
    5656             :     "#a; b(){}",
    5657             :     "#a; *b(){}",
    5658             :     "#a; ['b'](){}",
    5659             : 
    5660             :     // ASI
    5661             :     "#a = 0\n",
    5662             :     "#a = 0\n #b",
    5663             :     "#a = 0\n b",
    5664             :     "#a = 0\n b(){}",
    5665             :     "#a\n",
    5666             :     "#a\n #b\n",
    5667             :     "#a\n b\n",
    5668             :     "#a\n b(){}",
    5669             :     "#a\n *b(){}",
    5670             :     "#a\n ['b'](){}",
    5671             : 
    5672             :     // ASI edge cases
    5673             :     "#a\n get",
    5674             :     "#get\n *a(){}",
    5675             :     "#a\n static",
    5676             : 
    5677             :     "#a = function t() { arguments; }",
    5678             :     "#a = () => function() { arguments; }",
    5679             : 
    5680             :     // Misc edge cases
    5681             :     "#yield",
    5682             :     "#yield = 0",
    5683             :     "#yield\n a",
    5684             :     "#async;",
    5685             :     "#async = 0;",
    5686             :     "#async",
    5687             :     "#async = 0",
    5688             :     "#async\n a(){}",  // a field named async, and a method named a.
    5689             :     "#async\n a",
    5690             :     "#await;",
    5691             :     "#await = 0;",
    5692             :     "#await\n a",
    5693             :     nullptr
    5694           5 :   };
    5695             :   // clang-format on
    5696             : 
    5697           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5698             : 
    5699             :   static const ParserFlag private_fields[] = {kAllowHarmonyPrivateFields};
    5700             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5701           5 :                     private_fields, arraysize(private_fields));
    5702           5 : }
    5703             : 
    5704       26644 : TEST(StaticClassFieldsErrors) {
    5705             :   // clang-format off
    5706             :   // Tests proposed class fields syntax.
    5707             :   const char* context_data[][2] = {{"(class {", "});"},
    5708             :                                    {"(class extends Base {", "});"},
    5709             :                                    {"class C {", "}"},
    5710             :                                    {"class C extends Base {", "}"},
    5711           5 :                                    {nullptr, nullptr}};
    5712             :   const char* class_body_data[] = {
    5713             :     "static a : 0",
    5714             :     "static a =",
    5715             :     "static constructor",
    5716             :     "static prototype",
    5717             :     "static *a = 0",
    5718             :     "static *a",
    5719             :     "static get a",
    5720             :     "static get\n a",
    5721             :     "static yield a",
    5722             :     "static async a = 0",
    5723             :     "static async a",
    5724             : 
    5725             :     "static a = arguments",
    5726             :     "static a = () => arguments",
    5727             :     "static a = () => { arguments }",
    5728             :     "static a = arguments[0]",
    5729             :     "static a = delete arguments[0]",
    5730             :     "static a = f(arguments)",
    5731             :     "static a = () => () => arguments",
    5732             : 
    5733             :     // ASI requires a linebreak
    5734             :     "static a b",
    5735             :     "static a = 0 b",
    5736             : 
    5737             :     "static c = [1] = [c]",
    5738             : 
    5739             :     // ASI requires that the next token is not part of any legal production
    5740             :     "static a = 0\n *b(){}",
    5741             :     "static a = 0\n ['b'](){}",
    5742             :     nullptr
    5743           5 :   };
    5744             :   // clang-format on
    5745             : 
    5746             :   static const ParserFlag no_static_flags[] = {kAllowHarmonyPublicFields};
    5747             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5748           5 :                     no_static_flags, arraysize(no_static_flags));
    5749             : 
    5750             :   static const ParserFlag always_flags[] = {kAllowHarmonyPublicFields,
    5751             :                                             kAllowHarmonyStaticFields};
    5752             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5753           5 :                     always_flags, arraysize(always_flags));
    5754           5 : }
    5755             : 
    5756       26644 : TEST(ClassFieldsErrors) {
    5757             :   // clang-format off
    5758             :   // Tests proposed class fields syntax.
    5759             :   const char* context_data[][2] = {{"(class {", "});"},
    5760             :                                    {"(class extends Base {", "});"},
    5761             :                                    {"class C {", "}"},
    5762             :                                    {"class C extends Base {", "}"},
    5763           5 :                                    {nullptr, nullptr}};
    5764             :   const char* class_body_data[] = {
    5765             :     "a : 0",
    5766             :     "a =",
    5767             :     "constructor",
    5768             :     "*a = 0",
    5769             :     "*a",
    5770             :     "get a",
    5771             :     "yield a",
    5772             :     "async a = 0",
    5773             :     "async a",
    5774             : 
    5775             :     "a = arguments",
    5776             :     "a = () => arguments",
    5777             :     "a = () => { arguments }",
    5778             :     "a = arguments[0]",
    5779             :     "a = delete arguments[0]",
    5780             :     "a = f(arguments)",
    5781             :     "a = () => () => arguments",
    5782             : 
    5783             :     // ASI requires a linebreak
    5784             :     "a b",
    5785             :     "a = 0 b",
    5786             : 
    5787             :     "c = [1] = [c]",
    5788             : 
    5789             :     // ASI requires that the next token is not part of any legal production
    5790             :     "a = 0\n *b(){}",
    5791             :     "a = 0\n ['b'](){}",
    5792             :     "get\n a",
    5793             :     nullptr
    5794           5 :   };
    5795             :   // clang-format on
    5796             : 
    5797             :   static const ParserFlag always_flags[] = {kAllowHarmonyPublicFields};
    5798             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5799           5 :                     always_flags, arraysize(always_flags));
    5800             : 
    5801             :   static const ParserFlag static_flags[] = {kAllowHarmonyPublicFields,
    5802             :                                             kAllowHarmonyStaticFields};
    5803             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5804           5 :                     static_flags, arraysize(static_flags));
    5805           5 : }
    5806             : 
    5807       26644 : TEST(PrivateClassFieldsErrors) {
    5808             :   // clang-format off
    5809             :   // Tests proposed class fields syntax.
    5810             :   const char* context_data[][2] = {{"(class {", "});"},
    5811             :                                    {"(class extends Base {", "});"},
    5812             :                                    {"class C {", "}"},
    5813             :                                    {"class C extends Base {", "}"},
    5814           5 :                                    {nullptr, nullptr}};
    5815             :   const char* class_body_data[] = {
    5816             :     "#a : 0",
    5817             :     "#a =",
    5818             :     "#*a = 0",
    5819             :     "#*a",
    5820             :     "#get a",
    5821             :     "#yield a",
    5822             :     "#async a = 0",
    5823             :     "#async a",
    5824             : 
    5825             :     "#a; #a",
    5826             :     "#a = 1; #a",
    5827             :     "#a; #a = 1;",
    5828             : 
    5829             :     "#constructor",
    5830             :     "#constructor = function() {}",
    5831             : 
    5832             :     "# a = 0",
    5833             :     "#a() { }",
    5834             :     "get #a() { }",
    5835             :     "#get a() { }",
    5836             :     "set #a() { }",
    5837             :     "#set a() { }",
    5838             :     "*#a() { }",
    5839             :     "#*a() { }",
    5840             :     "async #a() { }",
    5841             :     "async *#a() { }",
    5842             :     "async #*a() { }",
    5843             : 
    5844             :     "#0 = 0;",
    5845             :     "#0;",
    5846             :     "#'a' = 0;",
    5847             :     "#'a';",
    5848             : 
    5849             :     "#['a']",
    5850             :     "#['a'] = 1",
    5851             :     "#[a]",
    5852             :     "#[a] = 1",
    5853             : 
    5854             :     "#a = arguments",
    5855             :     "#a = () => arguments",
    5856             :     "#a = () => { arguments }",
    5857             :     "#a = arguments[0]",
    5858             :     "#a = delete arguments[0]",
    5859             :     "#a = f(arguments)",
    5860             :     "#a = () => () => arguments",
    5861             : 
    5862             :     "foo() { delete this.#a }",
    5863             :     "foo() { delete this.x.#a }",
    5864             :     "foo() { delete this.x().#a }",
    5865             : 
    5866             :     "foo() { delete f.#a }",
    5867             :     "foo() { delete f.x.#a }",
    5868             :     "foo() { delete f.x().#a }",
    5869             : 
    5870             :     // ASI requires a linebreak
    5871             :     "#a b",
    5872             :     "#a = 0 b",
    5873             : 
    5874             :     // ASI requires that the next token is not part of any legal production
    5875             :     "#a = 0\n *b(){}",
    5876             :     "#a = 0\n ['b'](){}",
    5877             :     nullptr
    5878           5 :   };
    5879             :   // clang-format on
    5880             : 
    5881           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5882             : 
    5883             :   static const ParserFlag private_fields[] = {kAllowHarmonyPrivateFields};
    5884             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5885           5 :                     private_fields, arraysize(private_fields));
    5886           5 : }
    5887             : 
    5888       26644 : TEST(PrivateStaticClassFieldsNoErrors) {
    5889             :   // clang-format off
    5890             :   // Tests proposed class fields syntax.
    5891             :   const char* context_data[][2] = {{"(class {", "});"},
    5892             :                                    {"(class extends Base {", "});"},
    5893             :                                    {"class C {", "}"},
    5894             :                                    {"class C extends Base {", "}"},
    5895           5 :                                    {nullptr, nullptr}};
    5896             :   const char* class_body_data[] = {
    5897             :     // Basic syntax
    5898             :     "static #a = 0;",
    5899             :     "static #a = 0; b",
    5900             :     "static #a = 0; #b",
    5901             :     "static #a = 0; b(){}",
    5902             :     "static #a = 0; *b(){}",
    5903             :     "static #a = 0; ['b'](){}",
    5904             :     "static #a;",
    5905             :     "static #a; b;",
    5906             :     "static #a; b(){}",
    5907             :     "static #a; *b(){}",
    5908             :     "static #a; ['b'](){}",
    5909             : 
    5910             :     "#prototype",
    5911             :     "#prototype = function() {}",
    5912             : 
    5913             :     // ASI
    5914             :     "static #a = 0\n",
    5915             :     "static #a = 0\n b",
    5916             :     "static #a = 0\n #b",
    5917             :     "static #a = 0\n b(){}",
    5918             :     "static #a\n",
    5919             :     "static #a\n b\n",
    5920             :     "static #a\n #b\n",
    5921             :     "static #a\n b(){}",
    5922             :     "static #a\n *b(){}",
    5923             :     "static #a\n ['b'](){}",
    5924             : 
    5925             :     "static #a = function t() { arguments; }",
    5926             :     "static #a = () => function t() { arguments; }",
    5927             : 
    5928             :     // ASI edge cases
    5929             :     "static #a\n get",
    5930             :     "static #get\n *a(){}",
    5931             :     "static #a\n static",
    5932             : 
    5933             :     // Misc edge cases
    5934             :     "static #yield",
    5935             :     "static #yield = 0",
    5936             :     "static #yield\n a",
    5937             :     "static #async;",
    5938             :     "static #async = 0;",
    5939             :     "static #async",
    5940             :     "static #async = 0",
    5941             :     "static #async\n a(){}",  // a field named async, and a method named a.
    5942             :     "static #async\n a",
    5943             :     "static #await;",
    5944             :     "static #await = 0;",
    5945             :     "static #await\n a",
    5946             :     nullptr
    5947           5 :   };
    5948             :   // clang-format on
    5949             : 
    5950           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5951             : 
    5952             :   static const ParserFlag public_static_fields[] = {kAllowHarmonyPublicFields,
    5953             :                                                     kAllowHarmonyStaticFields};
    5954             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5955           5 :                     public_static_fields, arraysize(public_static_fields));
    5956             : 
    5957             :   static const ParserFlag private_static_fields[] = {
    5958             :       kAllowHarmonyPublicFields, kAllowHarmonyStaticFields,
    5959             :       kAllowHarmonyPrivateFields};
    5960             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5961           5 :                     private_static_fields, arraysize(private_static_fields));
    5962           5 : }
    5963             : 
    5964       26644 : TEST(PrivateStaticClassFieldsErrors) {
    5965             :   // clang-format off
    5966             :   // Tests proposed class fields syntax.
    5967             :   const char* context_data[][2] = {{"(class {", "});"},
    5968             :                                    {"(class extends Base {", "});"},
    5969             :                                    {"class C {", "}"},
    5970             :                                    {"class C extends Base {", "}"},
    5971           5 :                                    {nullptr, nullptr}};
    5972             :   const char* class_body_data[] = {
    5973             :     // Basic syntax
    5974             :     "static #['a'] = 0;",
    5975             :     "static #['a'] = 0; b",
    5976             :     "static #['a'] = 0; #b",
    5977             :     "static #['a'] = 0; b(){}",
    5978             :     "static #['a'] = 0; *b(){}",
    5979             :     "static #['a'] = 0; ['b'](){}",
    5980             :     "static #['a'];",
    5981             :     "static #['a']; b;",
    5982             :     "static #['a']; #b;",
    5983             :     "static #['a']; b(){}",
    5984             :     "static #['a']; *b(){}",
    5985             :     "static #['a']; ['b'](){}",
    5986             : 
    5987             :     "static #0 = 0;",
    5988             :     "static #0;",
    5989             :     "static #'a' = 0;",
    5990             :     "static #'a';",
    5991             : 
    5992             :     "static # a = 0",
    5993             :     "static #get a() { }",
    5994             :     "static #set a() { }",
    5995             :     "static #*a() { }",
    5996             :     "static async #*a() { }",
    5997             : 
    5998             :     "#a = arguments",
    5999             :     "#a = () => arguments",
    6000             :     "#a = () => { arguments }",
    6001             :     "#a = arguments[0]",
    6002             :     "#a = delete arguments[0]",
    6003             :     "#a = f(arguments)",
    6004             :     "#a = () => () => arguments",
    6005             : 
    6006             :     "#a; static #a",
    6007             :     "static #a; #a",
    6008             : 
    6009             :     // TODO(joyee): support static private methods
    6010             :     "static #a() { }",
    6011             :     "static get #a() { }",
    6012             :     "static set #a() { }",
    6013             :     "static *#a() { }",
    6014             :     "static async #a() { }",
    6015             :     "static async *#a() { }",
    6016             : 
    6017             :     // ASI
    6018             :     "static #['a'] = 0\n",
    6019             :     "static #['a'] = 0\n b",
    6020             :     "static #['a'] = 0\n #b",
    6021             :     "static #['a'] = 0\n b(){}",
    6022             :     "static #['a']\n",
    6023             :     "static #['a']\n b\n",
    6024             :     "static #['a']\n #b\n",
    6025             :     "static #['a']\n b(){}",
    6026             :     "static #['a']\n *b(){}",
    6027             :     "static #['a']\n ['b'](){}",
    6028             : 
    6029             :     // ASI requires a linebreak
    6030             :     "static #a b",
    6031             :     "static #a = 0 b",
    6032             : 
    6033             :     // ASI requires that the next token is not part of any legal production
    6034             :     "static #a = 0\n *b(){}",
    6035             :     "static #a = 0\n ['b'](){}",
    6036             : 
    6037             :     "static #a : 0",
    6038             :     "static #a =",
    6039             :     "static #*a = 0",
    6040             :     "static #*a",
    6041             :     "static #get a",
    6042             :     "static #yield a",
    6043             :     "static #async a = 0",
    6044             :     "static #async a",
    6045             :     "static # a = 0",
    6046             : 
    6047             :     "#constructor",
    6048             :     "#constructor = function() {}",
    6049             : 
    6050             :     "foo() { delete this.#a }",
    6051             :     "foo() { delete this.x.#a }",
    6052             :     "foo() { delete this.x().#a }",
    6053             : 
    6054             :     "foo() { delete f.#a }",
    6055             :     "foo() { delete f.x.#a }",
    6056             :     "foo() { delete f.x().#a }",
    6057             :     nullptr
    6058           5 :   };
    6059             :   // clang-format on
    6060             : 
    6061           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6062             : 
    6063             :   static const ParserFlag public_static_fields[] = {kAllowHarmonyPublicFields,
    6064             :                                                     kAllowHarmonyStaticFields};
    6065             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    6066           5 :                     public_static_fields, arraysize(public_static_fields));
    6067             : 
    6068             :   static const ParserFlag private_static_fields[] = {
    6069             :       kAllowHarmonyPublicFields, kAllowHarmonyStaticFields,
    6070             :       kAllowHarmonyPrivateFields};
    6071             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    6072           5 :                     private_static_fields, arraysize(private_static_fields));
    6073           5 : }
    6074             : 
    6075       26644 : TEST(PrivateNameResolutionErrors) {
    6076             :   // clang-format off
    6077             :   const char* context_data[][2] = {
    6078             :       {"class X { bar() { ", " } }"},
    6079             :       {"\"use strict\";", ""},
    6080             :       {nullptr, nullptr}
    6081           5 :   };
    6082             : 
    6083             :   const char* statement_data[] = {
    6084             :     "this.#a",
    6085             :     "this.#a()",
    6086             :     "this.#b.#a",
    6087             :     "this.#b.#a()",
    6088             : 
    6089             :     "foo.#a",
    6090             :     "foo.#a()",
    6091             :     "foo.#b.#a",
    6092             :     "foo.#b.#a()",
    6093             : 
    6094             :     "foo().#a",
    6095             :     "foo().b.#a",
    6096             :     "foo().b().#a",
    6097             :     "foo().b().#a()",
    6098             :     "foo().b().#a.bar",
    6099             :     "foo().b().#a.bar()",
    6100             : 
    6101             :     "foo(this.#a)",
    6102             :     "foo(bar().#a)",
    6103             : 
    6104             :     "new foo.#a",
    6105             :     "new foo.#b.#a",
    6106             :     "new foo.#b.#a()",
    6107             : 
    6108             :     "foo.#if;",
    6109             :     "foo.#yield;",
    6110             :     "foo.#super;",
    6111             :     "foo.#interface;",
    6112             :     "foo.#eval;",
    6113             :     "foo.#arguments;",
    6114             : 
    6115             :     nullptr
    6116           5 :   };
    6117             : 
    6118             :   // clang-format on
    6119           5 :   RunParserSyncTest(context_data, statement_data, kError);
    6120             : 
    6121             :   static const ParserFlag private_fields[] = {kAllowHarmonyPrivateFields};
    6122             :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0,
    6123           5 :                     private_fields, arraysize(private_fields));
    6124           5 : }
    6125             : 
    6126       26644 : TEST(PrivateNameErrors) {
    6127             :   // clang-format off
    6128             :   const char* context_data[][2] = {
    6129             :       {"", ""},
    6130             :       {"function t() { ", " }"},
    6131             :       {"var t => { ", " }"},
    6132             :       {"var t = { [ ", " ] }"},
    6133             :       {"\"use strict\";", ""},
    6134             :       {nullptr, nullptr}
    6135           5 :   };
    6136             : 
    6137             :   const char* statement_data[] = {
    6138             :     "#foo",
    6139             :     "#foo = 1",
    6140             : 
    6141             :     "# a;",
    6142             :     "#\n a;",
    6143             :     "a, # b",
    6144             :     "a, #, b;",
    6145             : 
    6146             :     "foo.#[a];",
    6147             :     "foo.#['a'];",
    6148             : 
    6149             :     "foo()#a",
    6150             :     "foo()#[a]",
    6151             :     "foo()#['a']",
    6152             : 
    6153             :     "super.#a;",
    6154             :     "super.#a = 1;",
    6155             :     "super.#['a']",
    6156             :     "super.#[a]",
    6157             : 
    6158             :     "new.#a",
    6159             :     "new.#[a]",
    6160             : 
    6161             :     "foo.#{;",
    6162             :     "foo.#};",
    6163             :     "foo.#=;",
    6164             :     "foo.#888;",
    6165             :     "foo.#-;",
    6166             :     "foo.#--;",
    6167             :     nullptr
    6168           5 :   };
    6169             : 
    6170             :   // clang-format on
    6171           5 :   RunParserSyncTest(context_data, statement_data, kError);
    6172             : 
    6173             :   static const ParserFlag private_fields[] = {kAllowHarmonyPrivateFields};
    6174             :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0,
    6175           5 :                     private_fields, arraysize(private_fields));
    6176           5 : }
    6177             : 
    6178       26644 : TEST(ClassExpressionErrors) {
    6179             :   const char* context_data[][2] = {
    6180           5 :       {"(", ");"}, {"var C = ", ";"}, {"bar, ", ";"}, {nullptr, nullptr}};
    6181             :   const char* class_data[] = {
    6182             :       "class",
    6183             :       "class name",
    6184             :       "class name extends",
    6185             :       "class extends",
    6186             :       "class {",
    6187             :       "class { m }",
    6188             :       "class { m; n }",
    6189             :       "class { m: 1 }",
    6190             :       "class { m(); n() }",
    6191             :       "class { get m }",
    6192             :       "class { get m() }",
    6193             :       "class { get m() { }",
    6194             :       "class { set m() {} }",      // Missing required parameter.
    6195             :       "class { m() {}, n() {} }",  // No commas allowed.
    6196           5 :       nullptr};
    6197             : 
    6198           5 :   RunParserSyncTest(context_data, class_data, kError);
    6199           5 : }
    6200             : 
    6201             : 
    6202       26644 : TEST(ClassDeclarationErrors) {
    6203             :   const char* context_data[][2] = {
    6204           5 :       {"", ""}, {"{", "}"}, {"if (true) {", "}"}, {nullptr, nullptr}};
    6205             :   const char* class_data[] = {
    6206             :       "class",
    6207             :       "class name",
    6208             :       "class name extends",
    6209             :       "class extends",
    6210             :       "class name {",
    6211             :       "class name { m }",
    6212             :       "class name { m; n }",
    6213             :       "class name { m: 1 }",
    6214             :       "class name { m(); n() }",
    6215             :       "class name { get x }",
    6216             :       "class name { get x() }",
    6217             :       "class name { set x() {) }",  // missing required param
    6218             :       "class {}",                   // Name is required for declaration
    6219             :       "class extends base {}",
    6220             :       "class name { *",
    6221             :       "class name { * }",
    6222             :       "class name { *; }",
    6223             :       "class name { *get x() {} }",
    6224             :       "class name { *set x(_) {} }",
    6225             :       "class name { *static m() {} }",
    6226           5 :       nullptr};
    6227             : 
    6228           5 :   RunParserSyncTest(context_data, class_data, kError);
    6229           5 : }
    6230             : 
    6231       26644 : TEST(ClassAsyncErrors) {
    6232             :   // clang-format off
    6233             :   const char* context_data[][2] = {{"(class {", "});"},
    6234             :                                    {"(class extends Base {", "});"},
    6235             :                                    {"class C {", "}"},
    6236             :                                    {"class C extends Base {", "}"},
    6237           5 :                                    {nullptr, nullptr}};
    6238             :   const char* async_data[] = {
    6239             :     "*async x(){}",
    6240             :     "async *(){}",
    6241             :     "async get x(){}",
    6242             :     "async set x(y){}",
    6243             :     "async x : 0",
    6244             :     "async : 0",
    6245             : 
    6246             :     "async static x(){}",
    6247             : 
    6248             :     "static *async x(){}",
    6249             :     "static async *(){}",
    6250             :     "static async get x(){}",
    6251             :     "static async set x(y){}",
    6252             :     "static async x : 0",
    6253             :     "static async : 0",
    6254             :     nullptr
    6255           5 :   };
    6256             :   // clang-format on
    6257             : 
    6258           5 :   RunParserSyncTest(context_data, async_data, kError);
    6259           5 : }
    6260             : 
    6261       26644 : TEST(ClassNameErrors) {
    6262             :   const char* context_data[][2] = {{"class ", "{}"},
    6263             :                                    {"(class ", "{});"},
    6264             :                                    {"'use strict'; class ", "{}"},
    6265             :                                    {"'use strict'; (class ", "{});"},
    6266           5 :                                    {nullptr, nullptr}};
    6267             :   const char* class_name[] = {"arguments", "eval",    "implements", "interface",
    6268             :                               "let",       "package", "private",    "protected",
    6269             :                               "public",    "static",  "var",        "yield",
    6270           5 :                               nullptr};
    6271             : 
    6272           5 :   RunParserSyncTest(context_data, class_name, kError);
    6273           5 : }
    6274             : 
    6275             : 
    6276       26644 : TEST(ClassGetterParamNameErrors) {
    6277             :   const char* context_data[][2] = {
    6278             :       {"class C { get name(", ") {} }"},
    6279             :       {"(class { get name(", ") {} });"},
    6280             :       {"'use strict'; class C { get name(", ") {} }"},
    6281             :       {"'use strict'; (class { get name(", ") {} })"},
    6282           5 :       {nullptr, nullptr}};
    6283             : 
    6284             :   const char* class_name[] = {"arguments", "eval",    "implements", "interface",
    6285             :                               "let",       "package", "private",    "protected",
    6286             :                               "public",    "static",  "var",        "yield",
    6287           5 :                               nullptr};
    6288             : 
    6289           5 :   RunParserSyncTest(context_data, class_name, kError);
    6290           5 : }
    6291             : 
    6292             : 
    6293       26644 : TEST(ClassStaticPrototypeErrors) {
    6294             :   const char* context_data[][2] = {
    6295           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6296             : 
    6297             :   const char* class_body_data[] = {"static prototype() {}",
    6298             :                                    "static get prototype() {}",
    6299             :                                    "static set prototype(_) {}",
    6300             :                                    "static *prototype() {}",
    6301             :                                    "static 'prototype'() {}",
    6302             :                                    "static *'prototype'() {}",
    6303             :                                    "static prot\\u006ftype() {}",
    6304             :                                    "static 'prot\\u006ftype'() {}",
    6305             :                                    "static get 'prot\\u006ftype'() {}",
    6306             :                                    "static set 'prot\\u006ftype'(_) {}",
    6307             :                                    "static *'prot\\u006ftype'() {}",
    6308           5 :                                    nullptr};
    6309             : 
    6310           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6311           5 : }
    6312             : 
    6313             : 
    6314       26644 : TEST(ClassSpecialConstructorErrors) {
    6315             :   const char* context_data[][2] = {
    6316           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6317             : 
    6318             :   const char* class_body_data[] = {"get constructor() {}",
    6319             :                                    "get constructor(_) {}",
    6320             :                                    "*constructor() {}",
    6321             :                                    "get 'constructor'() {}",
    6322             :                                    "*'constructor'() {}",
    6323             :                                    "get c\\u006fnstructor() {}",
    6324             :                                    "*c\\u006fnstructor() {}",
    6325             :                                    "get 'c\\u006fnstructor'() {}",
    6326             :                                    "get 'c\\u006fnstructor'(_) {}",
    6327             :                                    "*'c\\u006fnstructor'() {}",
    6328           5 :                                    nullptr};
    6329             : 
    6330           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6331           5 : }
    6332             : 
    6333             : 
    6334       26644 : TEST(ClassConstructorNoErrors) {
    6335             :   const char* context_data[][2] = {
    6336           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6337             : 
    6338             :   const char* class_body_data[] = {"constructor() {}",
    6339             :                                    "static constructor() {}",
    6340             :                                    "static get constructor() {}",
    6341             :                                    "static set constructor(_) {}",
    6342             :                                    "static *constructor() {}",
    6343           5 :                                    nullptr};
    6344             : 
    6345           5 :   RunParserSyncTest(context_data, class_body_data, kSuccess);
    6346           5 : }
    6347             : 
    6348             : 
    6349       26644 : TEST(ClassMultipleConstructorErrors) {
    6350             :   const char* context_data[][2] = {
    6351           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6352             : 
    6353             :   const char* class_body_data[] = {"constructor() {}; constructor() {}",
    6354           5 :                                    nullptr};
    6355             : 
    6356           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6357           5 : }
    6358             : 
    6359             : 
    6360       26644 : TEST(ClassMultiplePropertyNamesNoErrors) {
    6361             :   const char* context_data[][2] = {
    6362           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6363             : 
    6364             :   const char* class_body_data[] = {
    6365             :       "constructor() {}; static constructor() {}",
    6366             :       "m() {}; static m() {}",
    6367             :       "m() {}; m() {}",
    6368             :       "static m() {}; static m() {}",
    6369             :       "get m() {}; set m(_) {}; get m() {}; set m(_) {};",
    6370           5 :       nullptr};
    6371             : 
    6372           5 :   RunParserSyncTest(context_data, class_body_data, kSuccess);
    6373           5 : }
    6374             : 
    6375             : 
    6376       26644 : TEST(ClassesAreStrictErrors) {
    6377           5 :   const char* context_data[][2] = {{"", ""}, {"(", ");"}, {nullptr, nullptr}};
    6378             : 
    6379             :   const char* class_body_data[] = {
    6380             :       "class C { method() { with ({}) {} } }",
    6381             :       "class C extends function() { with ({}) {} } {}",
    6382           5 :       "class C { *method() { with ({}) {} } }", nullptr};
    6383             : 
    6384           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6385           5 : }
    6386             : 
    6387             : 
    6388       26644 : TEST(ObjectLiteralPropertyShorthandKeywordsError) {
    6389             :   const char* context_data[][2] = {
    6390           5 :       {"({", "});"}, {"'use strict'; ({", "});"}, {nullptr, nullptr}};
    6391             : 
    6392             :   const char* name_data[] = {
    6393             :       "break",    "case",    "catch",  "class",      "const", "continue",
    6394             :       "debugger", "default", "delete", "do",         "else",  "enum",
    6395             :       "export",   "extends", "false",  "finally",    "for",   "function",
    6396             :       "if",       "import",  "in",     "instanceof", "new",   "null",
    6397             :       "return",   "super",   "switch", "this",       "throw", "true",
    6398             :       "try",      "typeof",  "var",    "void",       "while", "with",
    6399           5 :       nullptr};
    6400             : 
    6401           5 :   RunParserSyncTest(context_data, name_data, kError);
    6402           5 : }
    6403             : 
    6404             : 
    6405       26644 : TEST(ObjectLiteralPropertyShorthandStrictKeywords) {
    6406           5 :   const char* context_data[][2] = {{"({", "});"}, {nullptr, nullptr}};
    6407             : 
    6408             :   const char* name_data[] = {"implements", "interface", "let",    "package",
    6409             :                              "private",    "protected", "public", "static",
    6410           5 :                              "yield",      nullptr};
    6411             : 
    6412           5 :   RunParserSyncTest(context_data, name_data, kSuccess);
    6413             : 
    6414             :   const char* context_strict_data[][2] = {{"'use strict'; ({", "});"},
    6415           5 :                                           {nullptr, nullptr}};
    6416           5 :   RunParserSyncTest(context_strict_data, name_data, kError);
    6417           5 : }
    6418             : 
    6419             : 
    6420       26644 : TEST(ObjectLiteralPropertyShorthandError) {
    6421             :   const char* context_data[][2] = {
    6422           5 :       {"({", "});"}, {"'use strict'; ({", "});"}, {nullptr, nullptr}};
    6423             : 
    6424             :   const char* name_data[] = {"1",   "1.2", "0",     "0.1", "1.0",
    6425           5 :                              "1e1", "0x1", "\"s\"", "'s'", nullptr};
    6426             : 
    6427           5 :   RunParserSyncTest(context_data, name_data, kError);
    6428           5 : }
    6429             : 
    6430             : 
    6431       26644 : TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) {
    6432           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    6433             : 
    6434           5 :   const char* name_data[] = {"function* g() { ({yield}); }", nullptr};
    6435             : 
    6436           5 :   RunParserSyncTest(context_data, name_data, kError);
    6437           5 : }
    6438             : 
    6439             : 
    6440       26644 : TEST(ConstParsingInForIn) {
    6441             :   const char* context_data[][2] = {{"'use strict';", ""},
    6442             :                                    {"function foo(){ 'use strict';", "}"},
    6443           5 :                                    {nullptr, nullptr}};
    6444             : 
    6445             :   const char* data[] = {
    6446             :       "for(const x = 1; ; ) {}", "for(const x = 1, y = 2;;){}",
    6447           5 :       "for(const x in [1,2,3]) {}", "for(const x of [1,2,3]) {}", nullptr};
    6448           5 :   RunParserSyncTest(context_data, data, kSuccess, nullptr, 0, nullptr, 0);
    6449           5 : }
    6450             : 
    6451             : 
    6452       26644 : TEST(StatementParsingInForIn) {
    6453             :   const char* context_data[][2] = {{"", ""},
    6454             :                                    {"'use strict';", ""},
    6455             :                                    {"function foo(){ 'use strict';", "}"},
    6456           5 :                                    {nullptr, nullptr}};
    6457             : 
    6458             :   const char* data[] = {"for(x in {}, {}) {}", "for(var x in {}, {}) {}",
    6459             :                         "for(let x in {}, {}) {}", "for(const x in {}, {}) {}",
    6460           5 :                         nullptr};
    6461             : 
    6462           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6463           5 : }
    6464             : 
    6465             : 
    6466       26644 : TEST(ConstParsingInForInError) {
    6467             :   const char* context_data[][2] = {{"'use strict';", ""},
    6468             :                                    {"function foo(){ 'use strict';", "}"},
    6469           5 :                                    {nullptr, nullptr}};
    6470             : 
    6471             :   const char* data[] = {
    6472             :       "for(const x,y = 1; ; ) {}",         "for(const x = 4 in [1,2,3]) {}",
    6473             :       "for(const x = 4, y in [1,2,3]) {}", "for(const x = 4 of [1,2,3]) {}",
    6474             :       "for(const x = 4, y of [1,2,3]) {}", "for(const x = 1, y = 2 in []) {}",
    6475             :       "for(const x,y in []) {}",           "for(const x = 1, y = 2 of []) {}",
    6476           5 :       "for(const x,y of []) {}",           nullptr};
    6477           5 :   RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0);
    6478           5 : }
    6479             : 
    6480       26644 : TEST(InitializedDeclarationsInForInOf) {
    6481             :   // https://tc39.github.io/ecma262/#sec-initializers-in-forin-statement-heads
    6482             : 
    6483             :   // Initialized declarations only allowed for
    6484             :   // - sloppy mode (not strict mode)
    6485             :   // - for-in (not for-of)
    6486             :   // - var (not let / const)
    6487             : 
    6488             :   // clang-format off
    6489             :   const char* strict_context[][2] = {{"'use strict';", ""},
    6490             :                                      {"function foo(){ 'use strict';", "}"},
    6491             :                                      {"function* foo(){ 'use strict';", "}"},
    6492           5 :                                      {nullptr, nullptr}};
    6493             : 
    6494             :   const char* sloppy_context[][2] = {{"", ""},
    6495             :                                      {"function foo(){ ", "}"},
    6496             :                                      {"function* foo(){ ", "}"},
    6497             :                                      {"function foo(){ var yield = 0; ", "}"},
    6498           5 :                                      {nullptr, nullptr}};
    6499             : 
    6500             :   const char* let_const_var_for_of[] = {
    6501             :       "for (let i = 1 of {}) {}",
    6502             :       "for (let i = void 0 of [1, 2, 3]) {}",
    6503             :       "for (const i = 1 of {}) {}",
    6504             :       "for (const i = void 0 of [1, 2, 3]) {}",
    6505             :       "for (var i = 1 of {}) {}",
    6506             :       "for (var i = void 0 of [1, 2, 3]) {}",
    6507           5 :       nullptr};
    6508             : 
    6509             :   const char* let_const_for_in[] = {
    6510             :       "for (let i = 1 in {}) {}",
    6511             :       "for (let i = void 0 in [1, 2, 3]) {}",
    6512             :       "for (const i = 1 in {}) {}",
    6513             :       "for (const i = void 0 in [1, 2, 3]) {}",
    6514           5 :       nullptr};
    6515             : 
    6516             :   const char* var_for_in[] = {
    6517             :       "for (var i = 1 in {}) {}",
    6518             :       "for (var i = void 0 in [1, 2, 3]) {}",
    6519             :       "for (var i = yield in [1, 2, 3]) {}",
    6520           5 :       nullptr};
    6521             :   // clang-format on
    6522             : 
    6523             :   // The only allowed case is sloppy + var + for-in.
    6524           5 :   RunParserSyncTest(sloppy_context, var_for_in, kSuccess);
    6525             : 
    6526             :   // Everything else is disallowed.
    6527           5 :   RunParserSyncTest(sloppy_context, let_const_var_for_of, kError);
    6528           5 :   RunParserSyncTest(sloppy_context, let_const_for_in, kError);
    6529             : 
    6530           5 :   RunParserSyncTest(strict_context, let_const_var_for_of, kError);
    6531           5 :   RunParserSyncTest(strict_context, let_const_for_in, kError);
    6532           5 :   RunParserSyncTest(strict_context, var_for_in, kError);
    6533           5 : }
    6534             : 
    6535       26644 : TEST(ForInMultipleDeclarationsError) {
    6536             :   const char* context_data[][2] = {{"", ""},
    6537             :                                    {"function foo(){", "}"},
    6538             :                                    {"'use strict';", ""},
    6539             :                                    {"function foo(){ 'use strict';", "}"},
    6540           5 :                                    {nullptr, nullptr}};
    6541             : 
    6542             :   const char* data[] = {"for (var i, j in {}) {}",
    6543             :                         "for (var i, j in [1, 2, 3]) {}",
    6544             :                         "for (var i, j = 1 in {}) {}",
    6545             :                         "for (var i, j = void 0 in [1, 2, 3]) {}",
    6546             : 
    6547             :                         "for (let i, j in {}) {}",
    6548             :                         "for (let i, j in [1, 2, 3]) {}",
    6549             :                         "for (let i, j = 1 in {}) {}",
    6550             :                         "for (let i, j = void 0 in [1, 2, 3]) {}",
    6551             : 
    6552             :                         "for (const i, j in {}) {}",
    6553             :                         "for (const i, j in [1, 2, 3]) {}",
    6554             :                         "for (const i, j = 1 in {}) {}",
    6555             :                         "for (const i, j = void 0 in [1, 2, 3]) {}",
    6556           5 :                         nullptr};
    6557           5 :   RunParserSyncTest(context_data, data, kError);
    6558           5 : }
    6559             : 
    6560             : 
    6561       26644 : TEST(ForOfMultipleDeclarationsError) {
    6562             :   const char* context_data[][2] = {{"", ""},
    6563             :                                    {"function foo(){", "}"},
    6564             :                                    {"'use strict';", ""},
    6565             :                                    {"function foo(){ 'use strict';", "}"},
    6566           5 :                                    {nullptr, nullptr}};
    6567             : 
    6568             :   const char* data[] = {"for (var i, j of {}) {}",
    6569             :                         "for (var i, j of [1, 2, 3]) {}",
    6570             :                         "for (var i, j = 1 of {}) {}",
    6571             :                         "for (var i, j = void 0 of [1, 2, 3]) {}",
    6572             : 
    6573             :                         "for (let i, j of {}) {}",
    6574             :                         "for (let i, j of [1, 2, 3]) {}",
    6575             :                         "for (let i, j = 1 of {}) {}",
    6576             :                         "for (let i, j = void 0 of [1, 2, 3]) {}",
    6577             : 
    6578             :                         "for (const i, j of {}) {}",
    6579             :                         "for (const i, j of [1, 2, 3]) {}",
    6580             :                         "for (const i, j = 1 of {}) {}",
    6581             :                         "for (const i, j = void 0 of [1, 2, 3]) {}",
    6582           5 :                         nullptr};
    6583           5 :   RunParserSyncTest(context_data, data, kError);
    6584           5 : }
    6585             : 
    6586             : 
    6587       26644 : TEST(ForInNoDeclarationsError) {
    6588             :   const char* context_data[][2] = {{"", ""},
    6589             :                                    {"function foo(){", "}"},
    6590             :                                    {"'use strict';", ""},
    6591             :                                    {"function foo(){ 'use strict';", "}"},
    6592           5 :                                    {nullptr, nullptr}};
    6593             : 
    6594           5 :   const char* data[] = {"for (var in {}) {}", "for (const in {}) {}", nullptr};
    6595           5 :   RunParserSyncTest(context_data, data, kError);
    6596           5 : }
    6597             : 
    6598             : 
    6599       26644 : TEST(ForOfNoDeclarationsError) {
    6600             :   const char* context_data[][2] = {{"", ""},
    6601             :                                    {"function foo(){", "}"},
    6602             :                                    {"'use strict';", ""},
    6603             :                                    {"function foo(){ 'use strict';", "}"},
    6604           5 :                                    {nullptr, nullptr}};
    6605             : 
    6606             :   const char* data[] = {"for (var of [1, 2, 3]) {}",
    6607           5 :                         "for (const of [1, 2, 3]) {}", nullptr};
    6608           5 :   RunParserSyncTest(context_data, data, kError);
    6609           5 : }
    6610             : 
    6611             : 
    6612       26644 : TEST(ForOfInOperator) {
    6613             :   const char* context_data[][2] = {{"", ""},
    6614             :                                    {"'use strict';", ""},
    6615             :                                    {"function foo(){ 'use strict';", "}"},
    6616           5 :                                    {nullptr, nullptr}};
    6617             : 
    6618             :   const char* data[] = {"for(x of 'foo' in {}) {}",
    6619             :                         "for(var x of 'foo' in {}) {}",
    6620             :                         "for(let x of 'foo' in {}) {}",
    6621           5 :                         "for(const x of 'foo' in {}) {}", nullptr};
    6622             : 
    6623           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6624           5 : }
    6625             : 
    6626             : 
    6627       26644 : TEST(ForOfYieldIdentifier) {
    6628           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    6629             : 
    6630             :   const char* data[] = {"for(x of yield) {}", "for(var x of yield) {}",
    6631             :                         "for(let x of yield) {}", "for(const x of yield) {}",
    6632           5 :                         nullptr};
    6633             : 
    6634           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6635           5 : }
    6636             : 
    6637             : 
    6638       26644 : TEST(ForOfYieldExpression) {
    6639             :   const char* context_data[][2] = {{"", ""},
    6640             :                                    {"'use strict';", ""},
    6641             :                                    {"function foo(){ 'use strict';", "}"},
    6642           5 :                                    {nullptr, nullptr}};
    6643             : 
    6644             :   const char* data[] = {"function* g() { for(x of yield) {} }",
    6645             :                         "function* g() { for(var x of yield) {} }",
    6646             :                         "function* g() { for(let x of yield) {} }",
    6647           5 :                         "function* g() { for(const x of yield) {} }", nullptr};
    6648             : 
    6649           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6650           5 : }
    6651             : 
    6652             : 
    6653       26644 : TEST(ForOfExpressionError) {
    6654             :   const char* context_data[][2] = {{"", ""},
    6655             :                                    {"'use strict';", ""},
    6656             :                                    {"function foo(){ 'use strict';", "}"},
    6657           5 :                                    {nullptr, nullptr}};
    6658             : 
    6659             :   const char* data[] = {
    6660             :       "for(x of [], []) {}", "for(var x of [], []) {}",
    6661             :       "for(let x of [], []) {}", "for(const x of [], []) {}",
    6662             : 
    6663             :       // AssignmentExpression should be validated statically:
    6664             :       "for(x of { y = 23 }) {}", "for(var x of { y = 23 }) {}",
    6665           5 :       "for(let x of { y = 23 }) {}", "for(const x of { y = 23 }) {}", nullptr};
    6666             : 
    6667           5 :   RunParserSyncTest(context_data, data, kError);
    6668           5 : }
    6669             : 
    6670             : 
    6671       26644 : TEST(InvalidUnicodeEscapes) {
    6672             :   const char* context_data[][2] = {
    6673           5 :       {"", ""}, {"'use strict';", ""}, {nullptr, nullptr}};
    6674             :   const char* data[] = {
    6675             :       "var foob\\u123r = 0;", "var \\u123roo = 0;", "\"foob\\u123rr\"",
    6676             :       // No escapes allowed in regexp flags
    6677             :       "/regex/\\u0069g", "/regex/\\u006g",
    6678             :       // Braces gone wrong
    6679             :       "var foob\\u{c481r = 0;", "var foob\\uc481}r = 0;", "var \\u{0052oo = 0;",
    6680             :       "var \\u0052}oo = 0;", "\"foob\\u{c481r\"", "var foob\\u{}ar = 0;",
    6681             :       // Too high value for the Unicode code point escape
    6682             :       "\"\\u{110000}\"",
    6683             :       // Not a Unicode code point escape
    6684             :       "var foob\\v1234r = 0;", "var foob\\U1234r = 0;",
    6685           5 :       "var foob\\v{1234}r = 0;", "var foob\\U{1234}r = 0;", nullptr};
    6686           5 :   RunParserSyncTest(context_data, data, kError);
    6687           5 : }
    6688             : 
    6689             : 
    6690       26644 : TEST(UnicodeEscapes) {
    6691             :   const char* context_data[][2] = {
    6692           5 :       {"", ""}, {"'use strict';", ""}, {nullptr, nullptr}};
    6693             :   const char* data[] = {
    6694             :       // Identifier starting with escape
    6695             :       "var \\u0052oo = 0;", "var \\u{0052}oo = 0;", "var \\u{52}oo = 0;",
    6696             :       "var \\u{00000000052}oo = 0;",
    6697             :       // Identifier with an escape but not starting with an escape
    6698             :       "var foob\\uc481r = 0;", "var foob\\u{c481}r = 0;",
    6699             :       // String with an escape
    6700             :       "\"foob\\uc481r\"", "\"foob\\{uc481}r\"",
    6701             :       // This character is a valid Unicode character, representable as a
    6702             :       // surrogate pair, not representable as 4 hex digits.
    6703             :       "\"foo\\u{10e6d}\"",
    6704             :       // Max value for the Unicode code point escape
    6705           5 :       "\"\\u{10ffff}\"", nullptr};
    6706           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6707           5 : }
    6708             : 
    6709       26644 : TEST(OctalEscapes) {
    6710             :   const char* sloppy_context_data[][2] = {{"", ""},    // as a directive
    6711             :                                           {"0;", ""},  // as a string literal
    6712           5 :                                           {nullptr, nullptr}};
    6713             : 
    6714             :   const char* strict_context_data[][2] = {
    6715             :       {"'use strict';", ""},     // as a directive before 'use strict'
    6716             :       {"", ";'use strict';"},    // as a directive after 'use strict'
    6717             :       {"'use strict'; 0;", ""},  // as a string literal
    6718           5 :       {nullptr, nullptr}};
    6719             : 
    6720             :   // clang-format off
    6721             :   const char* data[] = {
    6722             :     "'\\1'",
    6723             :     "'\\01'",
    6724             :     "'\\001'",
    6725             :     "'\\08'",
    6726             :     "'\\09'",
    6727           5 :     nullptr};
    6728             :   // clang-format on
    6729             : 
    6730             :   // Permitted in sloppy mode
    6731           5 :   RunParserSyncTest(sloppy_context_data, data, kSuccess);
    6732             : 
    6733             :   // Error in strict mode
    6734           5 :   RunParserSyncTest(strict_context_data, data, kError);
    6735           5 : }
    6736             : 
    6737       26644 : TEST(ScanTemplateLiterals) {
    6738             :   const char* context_data[][2] = {{"'use strict';", ""},
    6739             :                                    {"function foo(){ 'use strict';"
    6740             :                                     "  var a, b, c; return ",
    6741             :                                     "}"},
    6742           5 :                                    {nullptr, nullptr}};
    6743             : 
    6744             :   const char* data[] = {"``",
    6745             :                         "`no-subst-template`",
    6746             :                         "`template-head${a}`",
    6747             :                         "`${a}`",
    6748             :                         "`${a}template-tail`",
    6749             :                         "`template-head${a}template-tail`",
    6750             :                         "`${a}${b}${c}`",
    6751             :                         "`a${a}b${b}c${c}`",
    6752             :                         "`${a}a${b}b${c}c`",
    6753             :                         "`foo\n\nbar\r\nbaz`",
    6754             :                         "`foo\n\n${  bar  }\r\nbaz`",
    6755             :                         "`foo${a /* comment */}`",
    6756             :                         "`foo${a // comment\n}`",
    6757             :                         "`foo${a \n}`",
    6758             :                         "`foo${a \r\n}`",
    6759             :                         "`foo${a \r}`",
    6760             :                         "`foo${/* comment */ a}`",
    6761             :                         "`foo${// comment\na}`",
    6762             :                         "`foo${\n a}`",
    6763             :                         "`foo${\r\n a}`",
    6764             :                         "`foo${\r a}`",
    6765             :                         "`foo${'a' in a}`",
    6766           5 :                         nullptr};
    6767           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6768           5 : }
    6769             : 
    6770             : 
    6771       26644 : TEST(ScanTaggedTemplateLiterals) {
    6772             :   const char* context_data[][2] = {{"'use strict';", ""},
    6773             :                                    {"function foo(){ 'use strict';"
    6774             :                                     "  function tag() {}"
    6775             :                                     "  var a, b, c; return ",
    6776             :                                     "}"},
    6777           5 :                                    {nullptr, nullptr}};
    6778             : 
    6779             :   const char* data[] = {"tag ``",
    6780             :                         "tag `no-subst-template`",
    6781             :                         "tag`template-head${a}`",
    6782             :                         "tag `${a}`",
    6783             :                         "tag `${a}template-tail`",
    6784             :                         "tag   `template-head${a}template-tail`",
    6785             :                         "tag\n`${a}${b}${c}`",
    6786             :                         "tag\r\n`a${a}b${b}c${c}`",
    6787             :                         "tag    `${a}a${b}b${c}c`",
    6788             :                         "tag\t`foo\n\nbar\r\nbaz`",
    6789             :                         "tag\r`foo\n\n${  bar  }\r\nbaz`",
    6790             :                         "tag`foo${a /* comment */}`",
    6791             :                         "tag`foo${a // comment\n}`",
    6792             :                         "tag`foo${a \n}`",
    6793             :                         "tag`foo${a \r\n}`",
    6794             :                         "tag`foo${a \r}`",
    6795             :                         "tag`foo${/* comment */ a}`",
    6796             :                         "tag`foo${// comment\na}`",
    6797             :                         "tag`foo${\n a}`",
    6798             :                         "tag`foo${\r\n a}`",
    6799             :                         "tag`foo${\r a}`",
    6800             :                         "tag`foo${'a' in a}`",
    6801           5 :                         nullptr};
    6802           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6803           5 : }
    6804             : 
    6805             : 
    6806       26644 : TEST(TemplateMaterializedLiterals) {
    6807             :   const char* context_data[][2] = {{"'use strict';\n"
    6808             :                                     "function tag() {}\n"
    6809             :                                     "var a, b, c;\n"
    6810             :                                     "(",
    6811             :                                     ")"},
    6812           5 :                                    {nullptr, nullptr}};
    6813             : 
    6814             :   const char* data[] = {"tag``", "tag`a`", "tag`a${1}b`", "tag`a${1}b${2}c`",
    6815             :                         "``",    "`a`",    "`a${1}b`",    "`a${1}b${2}c`",
    6816           5 :                         nullptr};
    6817             : 
    6818           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6819           5 : }
    6820             : 
    6821             : 
    6822       26644 : TEST(ScanUnterminatedTemplateLiterals) {
    6823             :   const char* context_data[][2] = {{"'use strict';", ""},
    6824             :                                    {"function foo(){ 'use strict';"
    6825             :                                     "  var a, b, c; return ",
    6826             :                                     "}"},
    6827           5 :                                    {nullptr, nullptr}};
    6828             : 
    6829             :   const char* data[] = {"`no-subst-template",
    6830             :                         "`template-head${a}",
    6831             :                         "`${a}template-tail",
    6832             :                         "`template-head${a}template-tail",
    6833             :                         "`${a}${b}${c}",
    6834             :                         "`a${a}b${b}c${c}",
    6835             :                         "`${a}a${b}b${c}c",
    6836             :                         "`foo\n\nbar\r\nbaz",
    6837             :                         "`foo\n\n${  bar  }\r\nbaz",
    6838             :                         "`foo${a /* comment } */`",
    6839             :                         "`foo${a /* comment } `*/",
    6840             :                         "`foo${a // comment}`",
    6841             :                         "`foo${a \n`",
    6842             :                         "`foo${a \r\n`",
    6843             :                         "`foo${a \r`",
    6844             :                         "`foo${/* comment */ a`",
    6845             :                         "`foo${// commenta}`",
    6846             :                         "`foo${\n a`",
    6847             :                         "`foo${\r\n a`",
    6848             :                         "`foo${\r a`",
    6849             :                         "`foo${fn(}`",
    6850             :                         "`foo${1 if}`",
    6851           5 :                         nullptr};
    6852           5 :   RunParserSyncTest(context_data, data, kError);
    6853           5 : }
    6854             : 
    6855             : 
    6856       26644 : TEST(TemplateLiteralsIllegalTokens) {
    6857             :   const char* context_data[][2] = {{"'use strict';", ""},
    6858             :                                    {"function foo(){ 'use strict';"
    6859             :                                     "  var a, b, c; return ",
    6860             :                                     "}"},
    6861           5 :                                    {nullptr, nullptr}};
    6862             :   const char* data[] = {
    6863             :       "`hello\\x`",         "`hello\\x${1}`",       "`hello${1}\\x`",
    6864             :       "`hello${1}\\x${2}`", "`hello\\x\n`",         "`hello\\x\n${1}`",
    6865           5 :       "`hello${1}\\x\n`",   "`hello${1}\\x\n${2}`", nullptr};
    6866             : 
    6867           5 :   RunParserSyncTest(context_data, data, kError);
    6868           5 : }
    6869             : 
    6870             : 
    6871       26644 : TEST(ParseRestParameters) {
    6872             :   const char* context_data[][2] = {{"'use strict';(function(",
    6873             :                                     "){ return args;})(1, [], /regexp/, 'str',"
    6874             :                                     "function(){});"},
    6875             :                                    {"(function(",
    6876             :                                     "){ return args;})(1, [],"
    6877             :                                     "/regexp/, 'str', function(){});"},
    6878           5 :                                    {nullptr, nullptr}};
    6879             : 
    6880             :   const char* data[] = {"...args",
    6881             :                         "a, ...args",
    6882             :                         "...   args",
    6883             :                         "a, ...   args",
    6884             :                         "...\targs",
    6885             :                         "a, ...\targs",
    6886             :                         "...\r\nargs",
    6887             :                         "a, ...\r\nargs",
    6888             :                         "...\rargs",
    6889             :                         "a, ...\rargs",
    6890             :                         "...\t\n\t\t\n  args",
    6891             :                         "a, ...  \n  \n  args",
    6892             :                         "...{ length, 0: a, 1: b}",
    6893             :                         "...{}",
    6894             :                         "...[a, b]",
    6895             :                         "...[]",
    6896             :                         "...[...[a, b, ...c]]",
    6897           5 :                         nullptr};
    6898           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6899           5 : }
    6900             : 
    6901             : 
    6902       26644 : TEST(ParseRestParametersErrors) {
    6903             :   const char* context_data[][2] = {{"'use strict';(function(",
    6904             :                                     "){ return args;}(1, [], /regexp/, 'str',"
    6905             :                                     "function(){});"},
    6906             :                                    {"(function(",
    6907             :                                     "){ return args;}(1, [],"
    6908             :                                     "/regexp/, 'str', function(){});"},
    6909           5 :                                    {nullptr, nullptr}};
    6910             : 
    6911             :   const char* data[] = {"...args, b",
    6912             :                         "a, ...args, b",
    6913             :                         "...args,   b",
    6914             :                         "a, ...args,   b",
    6915             :                         "...args,\tb",
    6916             :                         "a,...args\t,b",
    6917             :                         "...args\r\n, b",
    6918             :                         "a, ... args,\r\nb",
    6919             :                         "...args\r,b",
    6920             :                         "a, ... args,\rb",
    6921             :                         "...args\t\n\t\t\n,  b",
    6922             :                         "a, ... args,  \n  \n  b",
    6923             :                         "a, a, ...args",
    6924             :                         "a,\ta, ...args",
    6925             :                         "a,\ra, ...args",
    6926             :                         "a,\na, ...args",
    6927           5 :                         nullptr};
    6928           5 :   RunParserSyncTest(context_data, data, kError);
    6929           5 : }
    6930             : 
    6931             : 
    6932       26644 : TEST(RestParameterInSetterMethodError) {
    6933             :   const char* context_data[][2] = {
    6934             :       {"'use strict';({ set prop(", ") {} }).prop = 1;"},
    6935             :       {"'use strict';(class { static set prop(", ") {} }).prop = 1;"},
    6936             :       {"'use strict';(new (class { set prop(", ") {} })).prop = 1;"},
    6937             :       {"({ set prop(", ") {} }).prop = 1;"},
    6938             :       {"(class { static set prop(", ") {} }).prop = 1;"},
    6939             :       {"(new (class { set prop(", ") {} })).prop = 1;"},
    6940           5 :       {nullptr, nullptr}};
    6941           5 :   const char* data[] = {"...a", "...arguments", "...eval", nullptr};
    6942             : 
    6943           5 :   RunParserSyncTest(context_data, data, kError);
    6944           5 : }
    6945             : 
    6946             : 
    6947       26644 : TEST(RestParametersEvalArguments) {
    6948             :   // clang-format off
    6949             :   const char* strict_context_data[][2] =
    6950             :       {{"'use strict';(function(",
    6951             :         "){ return;})(1, [], /regexp/, 'str',function(){});"},
    6952           5 :        {nullptr, nullptr}};
    6953             :   const char* sloppy_context_data[][2] =
    6954             :       {{"(function(",
    6955             :         "){ return;})(1, [],/regexp/, 'str', function(){});"},
    6956           5 :        {nullptr, nullptr}};
    6957             : 
    6958             :   const char* data[] = {
    6959             :       "...eval",
    6960             :       "eval, ...args",
    6961             :       "...arguments",
    6962             :       // See https://bugs.chromium.org/p/v8/issues/detail?id=4577
    6963             :       // "arguments, ...args",
    6964           5 :       nullptr};
    6965             :   // clang-format on
    6966             : 
    6967             :   // Fail in strict mode
    6968           5 :   RunParserSyncTest(strict_context_data, data, kError);
    6969             : 
    6970             :   // OK in sloppy mode
    6971           5 :   RunParserSyncTest(sloppy_context_data, data, kSuccess);
    6972           5 : }
    6973             : 
    6974             : 
    6975       26644 : TEST(RestParametersDuplicateEvalArguments) {
    6976             :   const char* context_data[][2] = {
    6977             :       {"'use strict';(function(",
    6978             :        "){ return;})(1, [], /regexp/, 'str',function(){});"},
    6979             :       {"(function(", "){ return;})(1, [],/regexp/, 'str', function(){});"},
    6980           5 :       {nullptr, nullptr}};
    6981             : 
    6982             :   const char* data[] = {"eval, ...eval", "eval, eval, ...args",
    6983             :                         "arguments, ...arguments",
    6984           5 :                         "arguments, arguments, ...args", nullptr};
    6985             : 
    6986             :   // In strict mode, the error is using "eval" or "arguments" as parameter names
    6987             :   // In sloppy mode, the error is that eval / arguments are duplicated
    6988           5 :   RunParserSyncTest(context_data, data, kError);
    6989           5 : }
    6990             : 
    6991             : 
    6992       26644 : TEST(SpreadCall) {
    6993             :   const char* context_data[][2] = {{"function fn() { 'use strict';} fn(", ");"},
    6994             :                                    {"function fn() {} fn(", ");"},
    6995           5 :                                    {nullptr, nullptr}};
    6996             : 
    6997             :   const char* data[] = {"...([1, 2, 3])",
    6998             :                         "...'123', ...'456'",
    6999             :                         "...new Set([1, 2, 3]), 4",
    7000             :                         "1, ...[2, 3], 4",
    7001             :                         "...Array(...[1,2,3,4])",
    7002             :                         "...NaN",
    7003             :                         "0, 1, ...[2, 3, 4], 5, 6, 7, ...'89'",
    7004             :                         "0, 1, ...[2, 3, 4], 5, 6, 7, ...'89', 10",
    7005             :                         "...[0, 1, 2], 3, 4, 5, 6, ...'7', 8, 9",
    7006             :                         "...[0, 1, 2], 3, 4, 5, 6, ...'7', 8, 9, ...[10]",
    7007           5 :                         nullptr};
    7008             : 
    7009           5 :   RunParserSyncTest(context_data, data, kSuccess);
    7010           5 : }
    7011             : 
    7012             : 
    7013       26644 : TEST(SpreadCallErrors) {
    7014             :   const char* context_data[][2] = {{"function fn() { 'use strict';} fn(", ");"},
    7015             :                                    {"function fn() {} fn(", ");"},
    7016           5 :                                    {nullptr, nullptr}};
    7017             : 
    7018           5 :   const char* data[] = {"(...[1, 2, 3])", "......[1,2,3]", nullptr};
    7019             : 
    7020           5 :   RunParserSyncTest(context_data, data, kError);
    7021           5 : }
    7022             : 
    7023             : 
    7024       26644 : TEST(BadRestSpread) {
    7025             :   const char* context_data[][2] = {{"function fn() { 'use strict';", "} fn();"},
    7026             :                                    {"function fn() { ", "} fn();"},
    7027           5 :                                    {nullptr, nullptr}};
    7028             :   const char* data[] = {"return ...[1,2,3];",
    7029             :                         "var ...x = [1,2,3];",
    7030             :                         "var [...x,] = [1,2,3];",
    7031             :                         "var [...x, y] = [1,2,3];",
    7032             :                         "var { x } = {x: ...[1,2,3]}",
    7033           5 :                         nullptr};
    7034           5 :   RunParserSyncTest(context_data, data, kError);
    7035           5 : }
    7036             : 
    7037             : 
    7038       26644 : TEST(LexicalScopingSloppyMode) {
    7039             :   const char* context_data[][2] = {
    7040           5 :       {"", ""}, {"function f() {", "}"}, {"{", "}"}, {nullptr, nullptr}};
    7041             : 
    7042           5 :   const char* good_data[] = {"let = 1;", "for(let = 1;;){}", nullptr};
    7043           5 :   RunParserSyncTest(context_data, good_data, kSuccess);
    7044           5 : }
    7045             : 
    7046             : 
    7047       26644 : TEST(ComputedPropertyName) {
    7048             :   const char* context_data[][2] = {{"({[", "]: 1});"},
    7049             :                                    {"({get [", "]() {}});"},
    7050             :                                    {"({set [", "](_) {}});"},
    7051             :                                    {"({[", "]() {}});"},
    7052             :                                    {"({*[", "]() {}});"},
    7053             :                                    {"(class {get [", "]() {}});"},
    7054             :                                    {"(class {set [", "](_) {}});"},
    7055             :                                    {"(class {[", "]() {}});"},
    7056             :                                    {"(class {*[", "]() {}});"},
    7057           5 :                                    {nullptr, nullptr}};
    7058           5 :   const char* error_data[] = {"1, 2", "var name", nullptr};
    7059             : 
    7060           5 :   RunParserSyncTest(context_data, error_data, kError);
    7061             : 
    7062             :   const char* name_data[] = {"1",  "1 + 2", "'name'", "\"name\"",
    7063           5 :                              "[]", "{}",    nullptr};
    7064             : 
    7065           5 :   RunParserSyncTest(context_data, name_data, kSuccess);
    7066           5 : }
    7067             : 
    7068             : 
    7069       26644 : TEST(ComputedPropertyNameShorthandError) {
    7070           5 :   const char* context_data[][2] = {{"({", "});"}, {nullptr, nullptr}};
    7071           5 :   const char* error_data[] = {"a: 1, [2]", "[1], a: 1", nullptr};
    7072             : 
    7073           5 :   RunParserSyncTest(context_data, error_data, kError);
    7074           5 : }
    7075             : 
    7076             : 
    7077       26644 : TEST(BasicImportExportParsing) {
    7078             :   // clang-format off
    7079             :   const char* kSources[] = {
    7080             :       "export let x = 0;",
    7081             :       "export var y = 0;",
    7082             :       "export const z = 0;",
    7083             :       "export function func() { };",
    7084             :       "export class C { };",
    7085             :       "export { };",
    7086             :       "function f() {}; f(); export { f };",
    7087             :       "var a, b, c; export { a, b as baz, c };",
    7088             :       "var d, e; export { d as dreary, e, };",
    7089             :       "export default function f() {}",
    7090             :       "export default function() {}",
    7091             :       "export default function*() {}",
    7092             :       "export default class C {}",
    7093             :       "export default class {}",
    7094             :       "export default class extends C {}",
    7095             :       "export default 42",
    7096             :       "var x; export default x = 7",
    7097             :       "export { Q } from 'somemodule.js';",
    7098             :       "export * from 'somemodule.js';",
    7099             :       "var foo; export { foo as for };",
    7100             :       "export { arguments } from 'm.js';",
    7101             :       "export { for } from 'm.js';",
    7102             :       "export { yield } from 'm.js'",
    7103             :       "export { static } from 'm.js'",
    7104             :       "export { let } from 'm.js'",
    7105             :       "var a; export { a as b, a as c };",
    7106             :       "var a; export { a as await };",
    7107             :       "var a; export { a as enum };",
    7108             : 
    7109             :       "import 'somemodule.js';",
    7110             :       "import { } from 'm.js';",
    7111             :       "import { a } from 'm.js';",
    7112             :       "import { a, b as d, c, } from 'm.js';",
    7113             :       "import * as thing from 'm.js';",
    7114             :       "import thing from 'm.js';",
    7115             :       "import thing, * as rest from 'm.js';",
    7116             :       "import thing, { a, b, c } from 'm.js';",
    7117             :       "import { arguments as a } from 'm.js';",
    7118             :       "import { for as f } from 'm.js';",
    7119             :       "import { yield as y } from 'm.js';",
    7120             :       "import { static as s } from 'm.js';",
    7121             :       "import { let as l } from 'm.js';",
    7122             : 
    7123             :       "import thing from 'a.js'; export {thing};",
    7124             :       "export {thing}; import thing from 'a.js';",
    7125             :       "import {thing} from 'a.js'; export {thing};",
    7126             :       "export {thing}; import {thing} from 'a.js';",
    7127             :       "import * as thing from 'a.js'; export {thing};",
    7128             :       "export {thing}; import * as thing from 'a.js';",
    7129           5 :   };
    7130             :   // clang-format on
    7131             : 
    7132             :   i::Isolate* isolate = CcTest::i_isolate();
    7133             :   i::Factory* factory = isolate->factory();
    7134             : 
    7135          10 :   v8::HandleScope handles(CcTest::isolate());
    7136           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7137             :   v8::Context::Scope context_scope(context);
    7138             : 
    7139           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7140           5 :                                         128 * 1024);
    7141             : 
    7142         475 :   for (unsigned i = 0; i < arraysize(kSources); ++i) {
    7143             :     i::Handle<i::String> source =
    7144         235 :         factory->NewStringFromAsciiChecked(kSources[i]);
    7145             : 
    7146             :     // Show that parsing as a module works
    7147             :     {
    7148         235 :       i::Handle<i::Script> script = factory->NewScript(source);
    7149         470 :       i::ParseInfo info(isolate, script);
    7150             :       info.set_module();
    7151         235 :       if (!i::parsing::ParseProgram(&info, isolate)) {
    7152             :         i::Handle<i::JSObject> exception_handle(
    7153             :             i::JSObject::cast(isolate->pending_exception()), isolate);
    7154             :         i::Handle<i::String> message_string = i::Handle<i::String>::cast(
    7155           0 :             i::JSReceiver::GetProperty(isolate, exception_handle, "message")
    7156             :                 .ToHandleChecked());
    7157             :         isolate->clear_pending_exception();
    7158             : 
    7159           0 :         FATAL(
    7160             :             "Parser failed on:\n"
    7161             :             "\t%s\n"
    7162             :             "with error:\n"
    7163             :             "\t%s\n"
    7164             :             "However, we expected no error.",
    7165           0 :             source->ToCString().get(), message_string->ToCString().get());
    7166             :       }
    7167             :     }
    7168             : 
    7169             :     // And that parsing a script does not.
    7170             :     {
    7171         235 :       i::Handle<i::Script> script = factory->NewScript(source);
    7172         470 :       i::ParseInfo info(isolate, script);
    7173         235 :       CHECK(!i::parsing::ParseProgram(&info, isolate));
    7174             :       isolate->clear_pending_exception();
    7175             :     }
    7176             :   }
    7177           5 : }
    7178             : 
    7179       26644 : TEST(NamespaceExportParsing) {
    7180             :   // clang-format off
    7181             :   const char* kSources[] = {
    7182             :       "export * as arguments from 'bar'",
    7183             :       "export * as await from 'bar'",
    7184             :       "export * as default from 'bar'",
    7185             :       "export * as enum from 'bar'",
    7186             :       "export * as foo from 'bar'",
    7187             :       "export * as for from 'bar'",
    7188             :       "export * as let from 'bar'",
    7189             :       "export * as static from 'bar'",
    7190             :       "export * as yield from 'bar'",
    7191           5 :   };
    7192             :   // clang-format on
    7193             : 
    7194           5 :   i::FLAG_harmony_namespace_exports = true;
    7195             :   i::Isolate* isolate = CcTest::i_isolate();
    7196             :   i::Factory* factory = isolate->factory();
    7197             : 
    7198          10 :   v8::HandleScope handles(CcTest::isolate());
    7199           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7200             :   v8::Context::Scope context_scope(context);
    7201             : 
    7202           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7203           5 :                                         128 * 1024);
    7204             : 
    7205          95 :   for (unsigned i = 0; i < arraysize(kSources); ++i) {
    7206             :     i::Handle<i::String> source =
    7207          45 :         factory->NewStringFromAsciiChecked(kSources[i]);
    7208          45 :     i::Handle<i::Script> script = factory->NewScript(source);
    7209          90 :     i::ParseInfo info(isolate, script);
    7210             :     info.set_module();
    7211          45 :     CHECK(i::parsing::ParseProgram(&info, isolate));
    7212             :   }
    7213           5 : }
    7214             : 
    7215       26644 : TEST(ImportExportParsingErrors) {
    7216             :   // clang-format off
    7217             :   const char* kErrorSources[] = {
    7218             :       "export {",
    7219             :       "var a; export { a",
    7220             :       "var a; export { a,",
    7221             :       "var a; export { a, ;",
    7222             :       "var a; export { a as };",
    7223             :       "var a, b; export { a as , b};",
    7224             :       "export }",
    7225             :       "var foo, bar; export { foo bar };",
    7226             :       "export { foo };",
    7227             :       "export { , };",
    7228             :       "export default;",
    7229             :       "export default var x = 7;",
    7230             :       "export default let x = 7;",
    7231             :       "export default const x = 7;",
    7232             :       "export *;",
    7233             :       "export * from;",
    7234             :       "export { Q } from;",
    7235             :       "export default from 'module.js';",
    7236             :       "export { for }",
    7237             :       "export { for as foo }",
    7238             :       "export { arguments }",
    7239             :       "export { arguments as foo }",
    7240             :       "var a; export { a, a };",
    7241             :       "var a, b; export { a as b, b };",
    7242             :       "var a, b; export { a as c, b as c };",
    7243             :       "export default function f(){}; export default class C {};",
    7244             :       "export default function f(){}; var a; export { a as default };",
    7245             :       "export function() {}",
    7246             :       "export function*() {}",
    7247             :       "export class {}",
    7248             :       "export class extends C {}",
    7249             : 
    7250             :       "import from;",
    7251             :       "import from 'm.js';",
    7252             :       "import { };",
    7253             :       "import {;",
    7254             :       "import };",
    7255             :       "import { , };",
    7256             :       "import { , } from 'm.js';",
    7257             :       "import { a } from;",
    7258             :       "import { a } 'm.js';",
    7259             :       "import , from 'm.js';",
    7260             :       "import a , from 'm.js';",
    7261             :       "import a { b, c } from 'm.js';",
    7262             :       "import arguments from 'm.js';",
    7263             :       "import eval from 'm.js';",
    7264             :       "import { arguments } from 'm.js';",
    7265             :       "import { eval } from 'm.js';",
    7266             :       "import { a as arguments } from 'm.js';",
    7267             :       "import { for } from 'm.js';",
    7268             :       "import { y as yield } from 'm.js'",
    7269             :       "import { s as static } from 'm.js'",
    7270             :       "import { l as let } from 'm.js'",
    7271             :       "import { a as await } from 'm.js';",
    7272             :       "import { a as enum } from 'm.js';",
    7273             :       "import { x }, def from 'm.js';",
    7274             :       "import def, def2 from 'm.js';",
    7275             :       "import * as x, def from 'm.js';",
    7276             :       "import * as x, * as y from 'm.js';",
    7277             :       "import {x}, {y} from 'm.js';",
    7278             :       "import * as x, {y} from 'm.js';",
    7279             : 
    7280             :       "export *;",
    7281             :       "export * as;",
    7282             :       "export * as foo;",
    7283             :       "export * as foo from;",
    7284             :       "export * as foo from ';",
    7285             :       "export * as ,foo from 'bar'",
    7286           5 :   };
    7287             :   // clang-format on
    7288             : 
    7289             :   i::Isolate* isolate = CcTest::i_isolate();
    7290             :   i::Factory* factory = isolate->factory();
    7291             : 
    7292          10 :   v8::HandleScope handles(CcTest::isolate());
    7293           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7294             :   v8::Context::Scope context_scope(context);
    7295             : 
    7296           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7297           5 :                                         128 * 1024);
    7298             : 
    7299         665 :   for (unsigned i = 0; i < arraysize(kErrorSources); ++i) {
    7300             :     i::Handle<i::String> source =
    7301         330 :         factory->NewStringFromAsciiChecked(kErrorSources[i]);
    7302             : 
    7303         330 :     i::Handle<i::Script> script = factory->NewScript(source);
    7304         660 :     i::ParseInfo info(isolate, script);
    7305             :     info.set_module();
    7306         330 :     CHECK(!i::parsing::ParseProgram(&info, isolate));
    7307             :     isolate->clear_pending_exception();
    7308             :   }
    7309           5 : }
    7310             : 
    7311       26644 : TEST(ModuleTopLevelFunctionDecl) {
    7312             :   // clang-format off
    7313             :   const char* kErrorSources[] = {
    7314             :       "function f() {} function f() {}",
    7315             :       "var f; function f() {}",
    7316             :       "function f() {} var f;",
    7317             :       "function* f() {} function* f() {}",
    7318             :       "var f; function* f() {}",
    7319             :       "function* f() {} var f;",
    7320             :       "function f() {} function* f() {}",
    7321             :       "function* f() {} function f() {}",
    7322           5 :   };
    7323             :   // clang-format on
    7324             : 
    7325             :   i::Isolate* isolate = CcTest::i_isolate();
    7326             :   i::Factory* factory = isolate->factory();
    7327             : 
    7328          10 :   v8::HandleScope handles(CcTest::isolate());
    7329           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7330             :   v8::Context::Scope context_scope(context);
    7331             : 
    7332           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7333           5 :                                         128 * 1024);
    7334             : 
    7335          85 :   for (unsigned i = 0; i < arraysize(kErrorSources); ++i) {
    7336             :     i::Handle<i::String> source =
    7337          40 :         factory->NewStringFromAsciiChecked(kErrorSources[i]);
    7338             : 
    7339          40 :     i::Handle<i::Script> script = factory->NewScript(source);
    7340          80 :     i::ParseInfo info(isolate, script);
    7341             :     info.set_module();
    7342          40 :     CHECK(!i::parsing::ParseProgram(&info, isolate));
    7343             :     isolate->clear_pending_exception();
    7344             :   }
    7345           5 : }
    7346             : 
    7347       26644 : TEST(ModuleAwaitReserved) {
    7348             :   // clang-format off
    7349             :   const char* kErrorSources[] = {
    7350             :       "await;",
    7351             :       "await: ;",
    7352             :       "var await;",
    7353             :       "var [await] = [];",
    7354             :       "var { await } = {};",
    7355             :       "var { x: await } = {};",
    7356             :       "{ var await; }",
    7357             :       "let await;",
    7358             :       "let [await] = [];",
    7359             :       "let { await } = {};",
    7360             :       "let { x: await } = {};",
    7361             :       "{ let await; }",
    7362             :       "const await = null;",
    7363             :       "const [await] = [];",
    7364             :       "const { await } = {};",
    7365             :       "const { x: await } = {};",
    7366             :       "{ const await = null; }",
    7367             :       "function await() {}",
    7368             :       "function f(await) {}",
    7369             :       "function* await() {}",
    7370             :       "function* g(await) {}",
    7371             :       "(function await() {});",
    7372             :       "(function (await) {});",
    7373             :       "(function* await() {});",
    7374             :       "(function* (await) {});",
    7375             :       "(await) => {};",
    7376             :       "await => {};",
    7377             :       "class await {}",
    7378             :       "class C { constructor(await) {} }",
    7379             :       "class C { m(await) {} }",
    7380             :       "class C { static m(await) {} }",
    7381             :       "class C { *m(await) {} }",
    7382             :       "class C { static *m(await) {} }",
    7383             :       "(class await {})",
    7384             :       "(class { constructor(await) {} });",
    7385             :       "(class { m(await) {} });",
    7386             :       "(class { static m(await) {} });",
    7387             :       "(class { *m(await) {} });",
    7388             :       "(class { static *m(await) {} });",
    7389             :       "({ m(await) {} });",
    7390             :       "({ *m(await) {} });",
    7391             :       "({ set p(await) {} });",
    7392             :       "try {} catch (await) {}",
    7393             :       "try {} catch (await) {} finally {}",
    7394             :       nullptr
    7395           5 :   };
    7396             :   // clang-format on
    7397           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    7398             : 
    7399             :   RunModuleParserSyncTest(context_data, kErrorSources, kError);
    7400           5 : }
    7401             : 
    7402       26644 : TEST(ModuleAwaitReservedPreParse) {
    7403           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    7404           5 :   const char* error_data[] = {"function f() { var await = 0; }", nullptr};
    7405             : 
    7406             :   RunModuleParserSyncTest(context_data, error_data, kError);
    7407           5 : }
    7408             : 
    7409       26644 : TEST(ModuleAwaitPermitted) {
    7410             :   // clang-format off
    7411             :   const char* kValidSources[] = {
    7412             :     "({}).await;",
    7413             :     "({ await: null });",
    7414             :     "({ await() {} });",
    7415             :     "({ get await() {} });",
    7416             :     "({ set await(x) {} });",
    7417             :     "(class { await() {} });",
    7418             :     "(class { static await() {} });",
    7419             :     "(class { *await() {} });",
    7420             :     "(class { static *await() {} });",
    7421             :     nullptr
    7422           5 :   };
    7423             :   // clang-format on
    7424           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    7425             : 
    7426             :   RunModuleParserSyncTest(context_data, kValidSources, kSuccess);
    7427           5 : }
    7428             : 
    7429       26644 : TEST(EnumReserved) {
    7430             :   // clang-format off
    7431             :   const char* kErrorSources[] = {
    7432             :       "enum;",
    7433             :       "enum: ;",
    7434             :       "var enum;",
    7435             :       "var [enum] = [];",
    7436             :       "var { enum } = {};",
    7437             :       "var { x: enum } = {};",
    7438             :       "{ var enum; }",
    7439             :       "let enum;",
    7440             :       "let [enum] = [];",
    7441             :       "let { enum } = {};",
    7442             :       "let { x: enum } = {};",
    7443             :       "{ let enum; }",
    7444             :       "const enum = null;",
    7445             :       "const [enum] = [];",
    7446             :       "const { enum } = {};",
    7447             :       "const { x: enum } = {};",
    7448             :       "{ const enum = null; }",
    7449             :       "function enum() {}",
    7450             :       "function f(enum) {}",
    7451             :       "function* enum() {}",
    7452             :       "function* g(enum) {}",
    7453             :       "(function enum() {});",
    7454             :       "(function (enum) {});",
    7455             :       "(function* enum() {});",
    7456             :       "(function* (enum) {});",
    7457             :       "(enum) => {};",
    7458             :       "enum => {};",
    7459             :       "class enum {}",
    7460             :       "class C { constructor(enum) {} }",
    7461             :       "class C { m(enum) {} }",
    7462             :       "class C { static m(enum) {} }",
    7463             :       "class C { *m(enum) {} }",
    7464             :       "class C { static *m(enum) {} }",
    7465             :       "(class enum {})",
    7466             :       "(class { constructor(enum) {} });",
    7467             :       "(class { m(enum) {} });",
    7468             :       "(class { static m(enum) {} });",
    7469             :       "(class { *m(enum) {} });",
    7470             :       "(class { static *m(enum) {} });",
    7471             :       "({ m(enum) {} });",
    7472             :       "({ *m(enum) {} });",
    7473             :       "({ set p(enum) {} });",
    7474             :       "try {} catch (enum) {}",
    7475             :       "try {} catch (enum) {} finally {}",
    7476             :       nullptr
    7477           5 :   };
    7478             :   // clang-format on
    7479           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    7480             : 
    7481             :   RunModuleParserSyncTest(context_data, kErrorSources, kError);
    7482           5 : }
    7483             : 
    7484          85 : static void CheckEntry(const i::ModuleDescriptor::Entry* entry,
    7485             :                        const char* export_name, const char* local_name,
    7486             :                        const char* import_name, int module_request) {
    7487          85 :   CHECK_NOT_NULL(entry);
    7488          85 :   if (export_name == nullptr) {
    7489          35 :     CHECK_NULL(entry->export_name);
    7490             :   } else {
    7491          50 :     CHECK(entry->export_name->IsOneByteEqualTo(export_name));
    7492             :   }
    7493          85 :   if (local_name == nullptr) {
    7494          15 :     CHECK_NULL(entry->local_name);
    7495             :   } else {
    7496          70 :     CHECK(entry->local_name->IsOneByteEqualTo(local_name));
    7497             :   }
    7498          85 :   if (import_name == nullptr) {
    7499          55 :     CHECK_NULL(entry->import_name);
    7500             :   } else {
    7501          30 :     CHECK(entry->import_name->IsOneByteEqualTo(import_name));
    7502             :   }
    7503          85 :   CHECK_EQ(entry->module_request, module_request);
    7504          85 : }
    7505             : 
    7506       26644 : TEST(ModuleParsingInternals) {
    7507             :   i::Isolate* isolate = CcTest::i_isolate();
    7508             :   i::Factory* factory = isolate->factory();
    7509          10 :   v8::HandleScope handles(CcTest::isolate());
    7510           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7511             :   v8::Context::Scope context_scope(context);
    7512           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7513           5 :                                         128 * 1024);
    7514             : 
    7515             :   static const char kSource[] =
    7516             :       "let x = 5;"
    7517             :       "export { x as y };"
    7518             :       "import { q as z } from 'm.js';"
    7519             :       "import n from 'n.js';"
    7520             :       "export { a as b } from 'm.js';"
    7521             :       "export * from 'p.js';"
    7522             :       "export var foo;"
    7523             :       "export function goo() {};"
    7524             :       "export let hoo;"
    7525             :       "export const joo = 42;"
    7526             :       "export default (function koo() {});"
    7527             :       "import 'q.js';"
    7528             :       "let nonexport = 42;"
    7529             :       "import {m as mm} from 'm.js';"
    7530             :       "import {aa} from 'm.js';"
    7531             :       "export {aa as bb, x};"
    7532             :       "import * as loo from 'bar.js';"
    7533             :       "import * as foob from 'bar.js';"
    7534             :       "export {foob};";
    7535           5 :   i::Handle<i::String> source = factory->NewStringFromAsciiChecked(kSource);
    7536           5 :   i::Handle<i::Script> script = factory->NewScript(source);
    7537          10 :   i::ParseInfo info(isolate, script);
    7538             :   info.set_module();
    7539           5 :   CHECK(i::parsing::ParseProgram(&info, isolate));
    7540           5 :   CHECK(i::Compiler::Analyze(&info));
    7541             :   i::FunctionLiteral* func = info.literal();
    7542           5 :   i::ModuleScope* module_scope = func->scope()->AsModuleScope();
    7543             :   i::Scope* outer_scope = module_scope->outer_scope();
    7544           5 :   CHECK(outer_scope->is_script_scope());
    7545           5 :   CHECK_NULL(outer_scope->outer_scope());
    7546           5 :   CHECK(module_scope->is_module_scope());
    7547             :   const i::ModuleDescriptor::Entry* entry;
    7548             :   i::Declaration::List* declarations = module_scope->declarations();
    7549           5 :   CHECK_EQ(13, declarations->LengthForTest());
    7550             : 
    7551           5 :   CHECK(declarations->AtForTest(0)->var()->raw_name()->IsOneByteEqualTo("x"));
    7552           5 :   CHECK(declarations->AtForTest(0)->var()->mode() == i::VariableMode::kLet);
    7553           5 :   CHECK(declarations->AtForTest(0)->var()->binding_needs_init());
    7554           5 :   CHECK(declarations->AtForTest(0)->var()->location() ==
    7555             :         i::VariableLocation::MODULE);
    7556             : 
    7557           5 :   CHECK(declarations->AtForTest(1)->var()->raw_name()->IsOneByteEqualTo("z"));
    7558           5 :   CHECK(declarations->AtForTest(1)->var()->mode() == i::VariableMode::kConst);
    7559           5 :   CHECK(declarations->AtForTest(1)->var()->binding_needs_init());
    7560           5 :   CHECK(declarations->AtForTest(1)->var()->location() ==
    7561             :         i::VariableLocation::MODULE);
    7562             : 
    7563           5 :   CHECK(declarations->AtForTest(2)->var()->raw_name()->IsOneByteEqualTo("n"));
    7564           5 :   CHECK(declarations->AtForTest(2)->var()->mode() == i::VariableMode::kConst);
    7565           5 :   CHECK(declarations->AtForTest(2)->var()->binding_needs_init());
    7566           5 :   CHECK(declarations->AtForTest(2)->var()->location() ==
    7567             :         i::VariableLocation::MODULE);
    7568             : 
    7569           5 :   CHECK(declarations->AtForTest(3)->var()->raw_name()->IsOneByteEqualTo("foo"));
    7570           5 :   CHECK(declarations->AtForTest(3)->var()->mode() == i::VariableMode::kVar);
    7571           5 :   CHECK(!declarations->AtForTest(3)->var()->binding_needs_init());
    7572           5 :   CHECK(declarations->AtForTest(3)->var()->location() ==
    7573             :         i::VariableLocation::MODULE);
    7574             : 
    7575           5 :   CHECK(declarations->AtForTest(4)->var()->raw_name()->IsOneByteEqualTo("goo"));
    7576           5 :   CHECK(declarations->AtForTest(4)->var()->mode() == i::VariableMode::kLet);
    7577           5 :   CHECK(!declarations->AtForTest(4)->var()->binding_needs_init());
    7578           5 :   CHECK(declarations->AtForTest(4)->var()->location() ==
    7579             :         i::VariableLocation::MODULE);
    7580             : 
    7581           5 :   CHECK(declarations->AtForTest(5)->var()->raw_name()->IsOneByteEqualTo("hoo"));
    7582           5 :   CHECK(declarations->AtForTest(5)->var()->mode() == i::VariableMode::kLet);
    7583           5 :   CHECK(declarations->AtForTest(5)->var()->binding_needs_init());
    7584           5 :   CHECK(declarations->AtForTest(5)->var()->location() ==
    7585             :         i::VariableLocation::MODULE);
    7586             : 
    7587           5 :   CHECK(declarations->AtForTest(6)->var()->raw_name()->IsOneByteEqualTo("joo"));
    7588           5 :   CHECK(declarations->AtForTest(6)->var()->mode() == i::VariableMode::kConst);
    7589           5 :   CHECK(declarations->AtForTest(6)->var()->binding_needs_init());
    7590           5 :   CHECK(declarations->AtForTest(6)->var()->location() ==
    7591             :         i::VariableLocation::MODULE);
    7592             : 
    7593           5 :   CHECK(declarations->AtForTest(7)->var()->raw_name()->IsOneByteEqualTo(
    7594             :       ".default"));
    7595           5 :   CHECK(declarations->AtForTest(7)->var()->mode() == i::VariableMode::kConst);
    7596           5 :   CHECK(declarations->AtForTest(7)->var()->binding_needs_init());
    7597           5 :   CHECK(declarations->AtForTest(7)->var()->location() ==
    7598             :         i::VariableLocation::MODULE);
    7599             : 
    7600           5 :   CHECK(declarations->AtForTest(8)->var()->raw_name()->IsOneByteEqualTo(
    7601             :       "nonexport"));
    7602           5 :   CHECK(!declarations->AtForTest(8)->var()->binding_needs_init());
    7603           5 :   CHECK(declarations->AtForTest(8)->var()->location() ==
    7604             :         i::VariableLocation::LOCAL);
    7605             : 
    7606           5 :   CHECK(declarations->AtForTest(9)->var()->raw_name()->IsOneByteEqualTo("mm"));
    7607           5 :   CHECK(declarations->AtForTest(9)->var()->mode() == i::VariableMode::kConst);
    7608           5 :   CHECK(declarations->AtForTest(9)->var()->binding_needs_init());
    7609           5 :   CHECK(declarations->AtForTest(9)->var()->location() ==
    7610             :         i::VariableLocation::MODULE);
    7611             : 
    7612           5 :   CHECK(declarations->AtForTest(10)->var()->raw_name()->IsOneByteEqualTo("aa"));
    7613           5 :   CHECK(declarations->AtForTest(10)->var()->mode() == i::VariableMode::kConst);
    7614           5 :   CHECK(declarations->AtForTest(10)->var()->binding_needs_init());
    7615           5 :   CHECK(declarations->AtForTest(10)->var()->location() ==
    7616             :         i::VariableLocation::MODULE);
    7617             : 
    7618           5 :   CHECK(
    7619             :       declarations->AtForTest(11)->var()->raw_name()->IsOneByteEqualTo("loo"));
    7620           5 :   CHECK(declarations->AtForTest(11)->var()->mode() == i::VariableMode::kConst);
    7621           5 :   CHECK(!declarations->AtForTest(11)->var()->binding_needs_init());
    7622           5 :   CHECK(declarations->AtForTest(11)->var()->location() !=
    7623             :         i::VariableLocation::MODULE);
    7624             : 
    7625           5 :   CHECK(
    7626             :       declarations->AtForTest(12)->var()->raw_name()->IsOneByteEqualTo("foob"));
    7627           5 :   CHECK(declarations->AtForTest(12)->var()->mode() == i::VariableMode::kConst);
    7628           5 :   CHECK(!declarations->AtForTest(12)->var()->binding_needs_init());
    7629           5 :   CHECK(declarations->AtForTest(12)->var()->location() ==
    7630             :         i::VariableLocation::MODULE);
    7631             : 
    7632             :   i::ModuleDescriptor* descriptor = module_scope->module();
    7633           5 :   CHECK_NOT_NULL(descriptor);
    7634             : 
    7635           5 :   CHECK_EQ(5u, descriptor->module_requests().size());
    7636          30 :   for (const auto& elem : descriptor->module_requests()) {
    7637          25 :     if (elem.first->IsOneByteEqualTo("m.js")) {
    7638           5 :       CHECK_EQ(0, elem.second.index);
    7639           5 :       CHECK_EQ(51, elem.second.position);
    7640          20 :     } else if (elem.first->IsOneByteEqualTo("n.js")) {
    7641           5 :       CHECK_EQ(1, elem.second.index);
    7642           5 :       CHECK_EQ(72, elem.second.position);
    7643          15 :     } else if (elem.first->IsOneByteEqualTo("p.js")) {
    7644           5 :       CHECK_EQ(2, elem.second.index);
    7645           5 :       CHECK_EQ(123, elem.second.position);
    7646          10 :     } else if (elem.first->IsOneByteEqualTo("q.js")) {
    7647           5 :       CHECK_EQ(3, elem.second.index);
    7648           5 :       CHECK_EQ(249, elem.second.position);
    7649           5 :     } else if (elem.first->IsOneByteEqualTo("bar.js")) {
    7650           5 :       CHECK_EQ(4, elem.second.index);
    7651           5 :       CHECK_EQ(370, elem.second.position);
    7652             :     } else {
    7653           0 :       UNREACHABLE();
    7654             :     }
    7655             :   }
    7656             : 
    7657           5 :   CHECK_EQ(3, descriptor->special_exports().size());
    7658           5 :   CheckEntry(descriptor->special_exports().at(0), "b", nullptr, "a", 0);
    7659           5 :   CheckEntry(descriptor->special_exports().at(1), nullptr, nullptr, nullptr, 2);
    7660           5 :   CheckEntry(descriptor->special_exports().at(2), "bb", nullptr, "aa",
    7661           5 :              0);  // !!!
    7662             : 
    7663           5 :   CHECK_EQ(8u, descriptor->regular_exports().size());
    7664             :   entry = descriptor->regular_exports()
    7665          10 :               .find(declarations->AtForTest(3)->var()->raw_name())
    7666           5 :               ->second;
    7667           5 :   CheckEntry(entry, "foo", "foo", nullptr, -1);
    7668             :   entry = descriptor->regular_exports()
    7669          10 :               .find(declarations->AtForTest(4)->var()->raw_name())
    7670           5 :               ->second;
    7671           5 :   CheckEntry(entry, "goo", "goo", nullptr, -1);
    7672             :   entry = descriptor->regular_exports()
    7673          10 :               .find(declarations->AtForTest(5)->var()->raw_name())
    7674           5 :               ->second;
    7675           5 :   CheckEntry(entry, "hoo", "hoo", nullptr, -1);
    7676             :   entry = descriptor->regular_exports()
    7677          10 :               .find(declarations->AtForTest(6)->var()->raw_name())
    7678           5 :               ->second;
    7679           5 :   CheckEntry(entry, "joo", "joo", nullptr, -1);
    7680             :   entry = descriptor->regular_exports()
    7681          10 :               .find(declarations->AtForTest(7)->var()->raw_name())
    7682           5 :               ->second;
    7683           5 :   CheckEntry(entry, "default", ".default", nullptr, -1);
    7684             :   entry = descriptor->regular_exports()
    7685          10 :               .find(declarations->AtForTest(12)->var()->raw_name())
    7686           5 :               ->second;
    7687           5 :   CheckEntry(entry, "foob", "foob", nullptr, -1);
    7688             :   // TODO(neis): The next lines are terrible. Find a better way.
    7689           5 :   auto name_x = declarations->AtForTest(0)->var()->raw_name();
    7690           5 :   CHECK_EQ(2u, descriptor->regular_exports().count(name_x));
    7691             :   auto it = descriptor->regular_exports().equal_range(name_x).first;
    7692           5 :   entry = it->second;
    7693           5 :   if (entry->export_name->IsOneByteEqualTo("y")) {
    7694           5 :     CheckEntry(entry, "y", "x", nullptr, -1);
    7695           5 :     entry = (++it)->second;
    7696           5 :     CheckEntry(entry, "x", "x", nullptr, -1);
    7697             :   } else {
    7698           0 :     CheckEntry(entry, "x", "x", nullptr, -1);
    7699           0 :     entry = (++it)->second;
    7700           0 :     CheckEntry(entry, "y", "x", nullptr, -1);
    7701             :   }
    7702             : 
    7703           5 :   CHECK_EQ(2, descriptor->namespace_imports().size());
    7704           5 :   CheckEntry(descriptor->namespace_imports().at(0), nullptr, "loo", nullptr, 4);
    7705           5 :   CheckEntry(descriptor->namespace_imports().at(1), nullptr, "foob", nullptr,
    7706           5 :              4);
    7707             : 
    7708           5 :   CHECK_EQ(4u, descriptor->regular_imports().size());
    7709             :   entry = descriptor->regular_imports()
    7710          10 :               .find(declarations->AtForTest(1)->var()->raw_name())
    7711           5 :               ->second;
    7712           5 :   CheckEntry(entry, nullptr, "z", "q", 0);
    7713             :   entry = descriptor->regular_imports()
    7714          10 :               .find(declarations->AtForTest(2)->var()->raw_name())
    7715           5 :               ->second;
    7716           5 :   CheckEntry(entry, nullptr, "n", "default", 1);
    7717             :   entry = descriptor->regular_imports()
    7718          10 :               .find(declarations->AtForTest(9)->var()->raw_name())
    7719           5 :               ->second;
    7720           5 :   CheckEntry(entry, nullptr, "mm", "m", 0);
    7721             :   entry = descriptor->regular_imports()
    7722          10 :               .find(declarations->AtForTest(10)->var()->raw_name())
    7723           5 :               ->second;
    7724           5 :   CheckEntry(entry, nullptr, "aa", "aa", 0);
    7725           5 : }
    7726             : 
    7727             : 
    7728       26644 : TEST(DuplicateProtoError) {
    7729             :   const char* context_data[][2] = {
    7730           5 :       {"({", "});"}, {"'use strict'; ({", "});"}, {nullptr, nullptr}};
    7731             :   const char* error_data[] = {"__proto__: {}, __proto__: {}",
    7732             :                               "__proto__: {}, \"__proto__\": {}",
    7733             :                               "__proto__: {}, \"__\x70roto__\": {}",
    7734           5 :                               "__proto__: {}, a: 1, __proto__: {}", nullptr};
    7735             : 
    7736           5 :   RunParserSyncTest(context_data, error_data, kError);
    7737           5 : }
    7738             : 
    7739             : 
    7740       26644 : TEST(DuplicateProtoNoError) {
    7741             :   const char* context_data[][2] = {
    7742           5 :       {"({", "});"}, {"'use strict'; ({", "});"}, {nullptr, nullptr}};
    7743             :   const char* error_data[] = {
    7744             :       "__proto__: {}, ['__proto__']: {}",  "__proto__: {}, __proto__() {}",
    7745             :       "__proto__: {}, get __proto__() {}", "__proto__: {}, set __proto__(v) {}",
    7746           5 :       "__proto__: {}, __proto__",          nullptr};
    7747             : 
    7748           5 :   RunParserSyncTest(context_data, error_data, kSuccess);
    7749           5 : }
    7750             : 
    7751             : 
    7752       26644 : TEST(DeclarationsError) {
    7753             :   const char* context_data[][2] = {{"'use strict'; if (true)", ""},
    7754             :                                    {"'use strict'; if (false) {} else", ""},
    7755             :                                    {"'use strict'; while (false)", ""},
    7756             :                                    {"'use strict'; for (;;)", ""},
    7757             :                                    {"'use strict'; for (x in y)", ""},
    7758             :                                    {"'use strict'; do ", " while (false)"},
    7759           5 :                                    {nullptr, nullptr}};
    7760             : 
    7761             :   const char* statement_data[] = {"let x = 1;", "const x = 1;", "class C {}",
    7762           5 :                                   nullptr};
    7763             : 
    7764           5 :   RunParserSyncTest(context_data, statement_data, kError);
    7765           5 : }
    7766             : 
    7767             : 
    7768          20 : void TestLanguageMode(const char* source,
    7769             :                       i::LanguageMode expected_language_mode) {
    7770             :   i::Isolate* isolate = CcTest::i_isolate();
    7771             :   i::Factory* factory = isolate->factory();
    7772          40 :   v8::HandleScope handles(CcTest::isolate());
    7773          20 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7774             :   v8::Context::Scope context_scope(context);
    7775          20 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7776          20 :                                         128 * 1024);
    7777             : 
    7778             :   i::Handle<i::Script> script =
    7779          20 :       factory->NewScript(factory->NewStringFromAsciiChecked(source));
    7780          40 :   i::ParseInfo info(isolate, script);
    7781          20 :   i::parsing::ParseProgram(&info, isolate);
    7782          20 :   CHECK_NOT_NULL(info.literal());
    7783          20 :   CHECK_EQ(expected_language_mode, info.literal()->language_mode());
    7784          20 : }
    7785             : 
    7786             : 
    7787       26644 : TEST(LanguageModeDirectives) {
    7788           5 :   TestLanguageMode("\"use nothing\"", i::LanguageMode::kSloppy);
    7789           5 :   TestLanguageMode("\"use strict\"", i::LanguageMode::kStrict);
    7790             : 
    7791           5 :   TestLanguageMode("var x = 1; \"use strict\"", i::LanguageMode::kSloppy);
    7792             : 
    7793             :   TestLanguageMode("\"use some future directive\"; \"use strict\";",
    7794           5 :                    i::LanguageMode::kStrict);
    7795           5 : }
    7796             : 
    7797             : 
    7798       26644 : TEST(PropertyNameEvalArguments) {
    7799           5 :   const char* context_data[][2] = {{"'use strict';", ""}, {nullptr, nullptr}};
    7800             : 
    7801             :   const char* statement_data[] = {"({eval: 1})",
    7802             :                                   "({arguments: 1})",
    7803             :                                   "({eval() {}})",
    7804             :                                   "({arguments() {}})",
    7805             :                                   "({*eval() {}})",
    7806             :                                   "({*arguments() {}})",
    7807             :                                   "({get eval() {}})",
    7808             :                                   "({get arguments() {}})",
    7809             :                                   "({set eval(_) {}})",
    7810             :                                   "({set arguments(_) {}})",
    7811             : 
    7812             :                                   "class C {eval() {}}",
    7813             :                                   "class C {arguments() {}}",
    7814             :                                   "class C {*eval() {}}",
    7815             :                                   "class C {*arguments() {}}",
    7816             :                                   "class C {get eval() {}}",
    7817             :                                   "class C {get arguments() {}}",
    7818             :                                   "class C {set eval(_) {}}",
    7819             :                                   "class C {set arguments(_) {}}",
    7820             : 
    7821             :                                   "class C {static eval() {}}",
    7822             :                                   "class C {static arguments() {}}",
    7823             :                                   "class C {static *eval() {}}",
    7824             :                                   "class C {static *arguments() {}}",
    7825             :                                   "class C {static get eval() {}}",
    7826             :                                   "class C {static get arguments() {}}",
    7827             :                                   "class C {static set eval(_) {}}",
    7828             :                                   "class C {static set arguments(_) {}}",
    7829             : 
    7830           5 :                                   nullptr};
    7831             : 
    7832           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    7833           5 : }
    7834             : 
    7835             : 
    7836       26644 : TEST(FunctionLiteralDuplicateParameters) {
    7837             :   const char* strict_context_data[][2] = {
    7838             :       {"'use strict';(function(", "){})();"},
    7839             :       {"(function(", ") { 'use strict'; })();"},
    7840             :       {"'use strict'; function fn(", ") {}; fn();"},
    7841             :       {"function fn(", ") { 'use strict'; }; fn();"},
    7842           5 :       {nullptr, nullptr}};
    7843             : 
    7844             :   const char* sloppy_context_data[][2] = {{"(function(", "){})();"},
    7845             :                                           {"(function(", ") {})();"},
    7846             :                                           {"function fn(", ") {}; fn();"},
    7847             :                                           {"function fn(", ") {}; fn();"},
    7848           5 :                                           {nullptr, nullptr}};
    7849             : 
    7850             :   const char* data[] = {
    7851             :       "a, a",
    7852             :       "a, a, a",
    7853             :       "b, a, a",
    7854             :       "a, b, c, c",
    7855             :       "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, w",
    7856           5 :       nullptr};
    7857             : 
    7858           5 :   RunParserSyncTest(strict_context_data, data, kError);
    7859           5 :   RunParserSyncTest(sloppy_context_data, data, kSuccess);
    7860           5 : }
    7861             : 
    7862             : 
    7863       26644 : TEST(ArrowFunctionASIErrors) {
    7864             :   const char* context_data[][2] = {
    7865           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    7866             : 
    7867             :   const char* data[] = {"(a\n=> a)(1)",
    7868             :                         "(a/*\n*/=> a)(1)",
    7869             :                         "((a)\n=> a)(1)",
    7870             :                         "((a)/*\n*/=> a)(1)",
    7871             :                         "((a, b)\n=> a + b)(1, 2)",
    7872             :                         "((a, b)/*\n*/=> a + b)(1, 2)",
    7873           5 :                         nullptr};
    7874           5 :   RunParserSyncTest(context_data, data, kError);
    7875           5 : }
    7876             : 
    7877       26644 : TEST(ObjectSpreadPositiveTests) {
    7878             :   // clang-format off
    7879             :   const char* context_data[][2] = {
    7880             :     {"x = ", ""},
    7881             :     {"'use strict'; x = ", ""},
    7882           5 :     {nullptr, nullptr}};
    7883             : 
    7884             :   // clang-format off
    7885             :   const char* data[] = {
    7886             :     "{ ...y }",
    7887             :     "{ a: 1, ...y }",
    7888             :     "{ b: 1, ...y }",
    7889             :     "{ y, ...y}",
    7890             :     "{ ...z = y}",
    7891             :     "{ ...y, y }",
    7892             :     "{ ...y, ...y}",
    7893             :     "{ a: 1, ...y, b: 1}",
    7894             :     "{ ...y, b: 1}",
    7895             :     "{ ...1}",
    7896             :     "{ ...null}",
    7897             :     "{ ...undefined}",
    7898             :     "{ ...1 in {}}",
    7899             :     "{ ...[]}",
    7900             :     "{ ...async function() { }}",
    7901             :     "{ ...async () => { }}",
    7902             :     "{ ...new Foo()}",
    7903           5 :     nullptr};
    7904             :   // clang-format on
    7905             : 
    7906           5 :   RunParserSyncTest(context_data, data, kSuccess);
    7907           5 : }
    7908             : 
    7909       26644 : TEST(ObjectSpreadNegativeTests) {
    7910             :   const char* context_data[][2] = {
    7911           5 :       {"x = ", ""}, {"'use strict'; x = ", ""}, {nullptr, nullptr}};
    7912             : 
    7913             :   // clang-format off
    7914             :   const char* data[] = {
    7915             :     "{ ...var z = y}",
    7916             :     "{ ...var}",
    7917             :     "{ ...foo bar}",
    7918             :     "{* ...foo}",
    7919             :     "{get ...foo}",
    7920             :     "{set ...foo}",
    7921             :     "{async ...foo}",
    7922           5 :     nullptr};
    7923             : 
    7924           5 :   RunParserSyncTest(context_data, data, kError);
    7925           5 : }
    7926             : 
    7927       26644 : TEST(TemplateEscapesPositiveTests) {
    7928             :   // clang-format off
    7929             :   const char* context_data[][2] = {
    7930             :     {"", ""},
    7931             :     {"'use strict';", ""},
    7932           5 :     {nullptr, nullptr}};
    7933             : 
    7934             :   // clang-format off
    7935             :   const char* data[] = {
    7936             :     "tag`\\08`",
    7937             :     "tag`\\01`",
    7938             :     "tag`\\01${0}right`",
    7939             :     "tag`left${0}\\01`",
    7940             :     "tag`left${0}\\01${1}right`",
    7941             :     "tag`\\1`",
    7942             :     "tag`\\1${0}right`",
    7943             :     "tag`left${0}\\1`",
    7944             :     "tag`left${0}\\1${1}right`",
    7945             :     "tag`\\xg`",
    7946             :     "tag`\\xg${0}right`",
    7947             :     "tag`left${0}\\xg`",
    7948             :     "tag`left${0}\\xg${1}right`",
    7949             :     "tag`\\xAg`",
    7950             :     "tag`\\xAg${0}right`",
    7951             :     "tag`left${0}\\xAg`",
    7952             :     "tag`left${0}\\xAg${1}right`",
    7953             :     "tag`\\u0`",
    7954             :     "tag`\\u0${0}right`",
    7955             :     "tag`left${0}\\u0`",
    7956             :     "tag`left${0}\\u0${1}right`",
    7957             :     "tag`\\u0g`",
    7958             :     "tag`\\u0g${0}right`",
    7959             :     "tag`left${0}\\u0g`",
    7960             :     "tag`left${0}\\u0g${1}right`",
    7961             :     "tag`\\u00g`",
    7962             :     "tag`\\u00g${0}right`",
    7963             :     "tag`left${0}\\u00g`",
    7964             :     "tag`left${0}\\u00g${1}right`",
    7965             :     "tag`\\u000g`",
    7966             :     "tag`\\u000g${0}right`",
    7967             :     "tag`left${0}\\u000g`",
    7968             :     "tag`left${0}\\u000g${1}right`",
    7969             :     "tag`\\u{}`",
    7970             :     "tag`\\u{}${0}right`",
    7971             :     "tag`left${0}\\u{}`",
    7972             :     "tag`left${0}\\u{}${1}right`",
    7973             :     "tag`\\u{-0}`",
    7974             :     "tag`\\u{-0}${0}right`",
    7975             :     "tag`left${0}\\u{-0}`",
    7976             :     "tag`left${0}\\u{-0}${1}right`",
    7977             :     "tag`\\u{g}`",
    7978             :     "tag`\\u{g}${0}right`",
    7979             :     "tag`left${0}\\u{g}`",
    7980             :     "tag`left${0}\\u{g}${1}right`",
    7981             :     "tag`\\u{0`",
    7982             :     "tag`\\u{0${0}right`",
    7983             :     "tag`left${0}\\u{0`",
    7984             :     "tag`left${0}\\u{0${1}right`",
    7985             :     "tag`\\u{\\u{0}`",
    7986             :     "tag`\\u{\\u{0}${0}right`",
    7987             :     "tag`left${0}\\u{\\u{0}`",
    7988             :     "tag`left${0}\\u{\\u{0}${1}right`",
    7989             :     "tag`\\u{110000}`",
    7990             :     "tag`\\u{110000}${0}right`",
    7991             :     "tag`left${0}\\u{110000}`",
    7992             :     "tag`left${0}\\u{110000}${1}right`",
    7993             :     "tag` ${tag`\\u`}`",
    7994             :     "tag` ``\\u`",
    7995             :     "tag`\\u`` `",
    7996             :     "tag`\\u``\\u`",
    7997             :     "` ${tag`\\u`}`",
    7998             :     "` ``\\u`",
    7999           5 :     nullptr};
    8000             :   // clang-format on
    8001             : 
    8002           5 :   RunParserSyncTest(context_data, data, kSuccess);
    8003           5 : }
    8004             : 
    8005       26644 : TEST(TemplateEscapesNegativeTests) {
    8006             :   // clang-format off
    8007             :   const char* context_data[][2] = {
    8008             :     {"", ""},
    8009             :     {"'use strict';", ""},
    8010           5 :     {nullptr, nullptr}};
    8011             : 
    8012             :   // clang-format off
    8013             :   const char* data[] = {
    8014             :     "`\\08`",
    8015             :     "`\\01`",
    8016             :     "`\\01${0}right`",
    8017             :     "`left${0}\\01`",
    8018             :     "`left${0}\\01${1}right`",
    8019             :     "`\\1`",
    8020             :     "`\\1${0}right`",
    8021             :     "`left${0}\\1`",
    8022             :     "`left${0}\\1${1}right`",
    8023             :     "`\\xg`",
    8024             :     "`\\xg${0}right`",
    8025             :     "`left${0}\\xg`",
    8026             :     "`left${0}\\xg${1}right`",
    8027             :     "`\\xAg`",
    8028             :     "`\\xAg${0}right`",
    8029             :     "`left${0}\\xAg`",
    8030             :     "`left${0}\\xAg${1}right`",
    8031             :     "`\\u0`",
    8032             :     "`\\u0${0}right`",
    8033             :     "`left${0}\\u0`",
    8034             :     "`left${0}\\u0${1}right`",
    8035             :     "`\\u0g`",
    8036             :     "`\\u0g${0}right`",
    8037             :     "`left${0}\\u0g`",
    8038             :     "`left${0}\\u0g${1}right`",
    8039             :     "`\\u00g`",
    8040             :     "`\\u00g${0}right`",
    8041             :     "`left${0}\\u00g`",
    8042             :     "`left${0}\\u00g${1}right`",
    8043             :     "`\\u000g`",
    8044             :     "`\\u000g${0}right`",
    8045             :     "`left${0}\\u000g`",
    8046             :     "`left${0}\\u000g${1}right`",
    8047             :     "`\\u{}`",
    8048             :     "`\\u{}${0}right`",
    8049             :     "`left${0}\\u{}`",
    8050             :     "`left${0}\\u{}${1}right`",
    8051             :     "`\\u{-0}`",
    8052             :     "`\\u{-0}${0}right`",
    8053             :     "`left${0}\\u{-0}`",
    8054             :     "`left${0}\\u{-0}${1}right`",
    8055             :     "`\\u{g}`",
    8056             :     "`\\u{g}${0}right`",
    8057             :     "`left${0}\\u{g}`",
    8058             :     "`left${0}\\u{g}${1}right`",
    8059             :     "`\\u{0`",
    8060             :     "`\\u{0${0}right`",
    8061             :     "`left${0}\\u{0`",
    8062             :     "`left${0}\\u{0${1}right`",
    8063             :     "`\\u{\\u{0}`",
    8064             :     "`\\u{\\u{0}${0}right`",
    8065             :     "`left${0}\\u{\\u{0}`",
    8066             :     "`left${0}\\u{\\u{0}${1}right`",
    8067             :     "`\\u{110000}`",
    8068             :     "`\\u{110000}${0}right`",
    8069             :     "`left${0}\\u{110000}`",
    8070             :     "`left${0}\\u{110000}${1}right`",
    8071             :     "`\\1``\\2`",
    8072             :     "tag` ${`\\u`}`",
    8073             :     "`\\u```",
    8074           5 :     nullptr};
    8075             :   // clang-format on
    8076             : 
    8077           5 :   RunParserSyncTest(context_data, data, kError);
    8078           5 : }
    8079             : 
    8080       26644 : TEST(DestructuringPositiveTests) {
    8081             :   const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
    8082             :                                    {"var ", " = {};"},
    8083             :                                    {"'use strict'; const ", " = {};"},
    8084             :                                    {"function f(", ") {}"},
    8085             :                                    {"function f(argument1, ", ") {}"},
    8086             :                                    {"var f = (", ") => {};"},
    8087             :                                    {"var f = (argument1,", ") => {};"},
    8088             :                                    {"try {} catch(", ") {}"},
    8089           5 :                                    {nullptr, nullptr}};
    8090             : 
    8091             :   // clang-format off
    8092             :   const char* data[] = {
    8093             :     "a",
    8094             :     "{ x : y }",
    8095             :     "{ x : y = 1 }",
    8096             :     "{ get, set }",
    8097             :     "{ get = 1, set = 2 }",
    8098             :     "[a]",
    8099             :     "[a = 1]",
    8100             :     "[a,b,c]",
    8101             :     "[a, b = 42, c]",
    8102             :     "{ x : x, y : y }",
    8103             :     "{ x : x = 1, y : y }",
    8104             :     "{ x : x, y : y = 42 }",
    8105             :     "[]",
    8106             :     "{}",
    8107             :     "[{x:x, y:y}, [a,b,c]]",
    8108             :     "[{x:x = 1, y:y = 2}, [a = 3, b = 4, c = 5]]",
    8109             :     "{x}",
    8110             :     "{x, y}",
    8111             :     "{x = 42, y = 15}",
    8112             :     "[a,,b]",
    8113             :     "{42 : x}",
    8114             :     "{42 : x = 42}",
    8115             :     "{42e-2 : x}",
    8116             :     "{42e-2 : x = 42}",
    8117             :     "{x : y, x : z}",
    8118             :     "{'hi' : x}",
    8119             :     "{'hi' : x = 42}",
    8120             :     "{var: x}",
    8121             :     "{var: x = 42}",
    8122             :     "{[x] : z}",
    8123             :     "{[1+1] : z}",
    8124             :     "{[foo()] : z}",
    8125             :     "{}",
    8126             :     "[...rest]",
    8127             :     "[a,b,...rest]",
    8128             :     "[a,,...rest]",
    8129             :     "{ __proto__: x, __proto__: y}",
    8130             :     "{arguments: x}",
    8131             :     "{eval: x}",
    8132             :     "{ x : y, ...z }",
    8133             :     "{ x : y = 1, ...z }",
    8134             :     "{ x : x, y : y, ...z }",
    8135             :     "{ x : x = 1, y : y, ...z }",
    8136             :     "{ x : x, y : y = 42, ...z }",
    8137             :     "[{x:x, y:y, ...z}, [a,b,c]]",
    8138             :     "[{x:x = 1, y:y = 2, ...z}, [a = 3, b = 4, c = 5]]",
    8139             :     "{...x}",
    8140             :     "{x, ...y}",
    8141             :     "{x = 42, y = 15, ...z}",
    8142             :     "{42 : x = 42, ...y}",
    8143             :     "{'hi' : x, ...z}",
    8144             :     "{'hi' : x = 42, ...z}",
    8145             :     "{var: x = 42, ...z}",
    8146             :     "{[x] : z, ...y}",
    8147             :     "{[1+1] : z, ...x}",
    8148             :     "{arguments: x, ...z}",
    8149             :     "{ __proto__: x, __proto__: y, ...z}",
    8150             :     nullptr
    8151           5 :   };
    8152             : 
    8153             :   // clang-format on
    8154           5 :   RunParserSyncTest(context_data, data, kSuccess);
    8155             : 
    8156             :   // v8:5201
    8157             :   {
    8158             :     // clang-format off
    8159             :     const char* sloppy_context_data[][2] = {
    8160             :       {"var ", " = {};"},
    8161             :       {"function f(", ") {}"},
    8162             :       {"function f(argument1, ", ") {}"},
    8163             :       {"var f = (", ") => {};"},
    8164             :       {"var f = (argument1,", ") => {};"},
    8165             :       {"try {} catch(", ") {}"},
    8166             :       {nullptr, nullptr}
    8167           5 :     };
    8168             : 
    8169             :     const char* data[] = {
    8170             :       "{arguments}",
    8171             :       "{eval}",
    8172             :       "{x: arguments}",
    8173             :       "{x: eval}",
    8174             :       "{arguments = false}",
    8175             :       "{eval = false}",
    8176             :       "{...arguments}",
    8177             :       "{...eval}",
    8178             :       nullptr
    8179           5 :     };
    8180             :     // clang-format on
    8181           5 :     RunParserSyncTest(sloppy_context_data, data, kSuccess);
    8182             :   }
    8183           5 : }
    8184             : 
    8185             : 
    8186       26644 : TEST(DestructuringNegativeTests) {
    8187             :   {  // All modes.
    8188             :     const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
    8189             :                                      {"var ", " = {};"},
    8190             :                                      {"'use strict'; const ", " = {};"},
    8191             :                                      {"function f(", ") {}"},
    8192             :                                      {"function f(argument1, ", ") {}"},
    8193             :                                      {"var f = (", ") => {};"},
    8194             :                                      {"var f = ", " => {};"},
    8195             :                                      {"var f = (argument1,", ") => {};"},
    8196             :                                      {"try {} catch(", ") {}"},
    8197           5 :                                      {nullptr, nullptr}};
    8198             : 
    8199             :     // clang-format off
    8200             :     const char* data[] = {
    8201             :         "a++",
    8202             :         "++a",
    8203             :         "delete a",
    8204             :         "void a",
    8205             :         "typeof a",
    8206             :         "--a",
    8207             :         "+a",
    8208             :         "-a",
    8209             :         "~a",
    8210             :         "!a",
    8211             :         "{ x : y++ }",
    8212             :         "[a++]",
    8213             :         "(x => y)",
    8214             :         "(async x => y)",
    8215             :         "((x, z) => y)",
    8216             :         "(async (x, z) => y)",
    8217             :         "a[i]", "a()",
    8218             :         "a.b",
    8219             :         "new a",
    8220             :         "a + a",
    8221             :         "a - a",
    8222             :         "a * a",
    8223             :         "a / a",
    8224             :         "a == a",
    8225             :         "a != a",
    8226             :         "a > a",
    8227             :         "a < a",
    8228             :         "a <<< a",
    8229             :         "a >>> a",
    8230             :         "function a() {}",
    8231             :         "function* a() {}",
    8232             :         "async function a() {}",
    8233             :         "a`bcd`",
    8234             :         "this",
    8235             :         "null",
    8236             :         "true",
    8237             :         "false",
    8238             :         "1",
    8239             :         "'abc'",
    8240             :         "/abc/",
    8241             :         "`abc`",
    8242             :         "class {}",
    8243             :         "{+2 : x}",
    8244             :         "{-2 : x}",
    8245             :         "var",
    8246             :         "[var]",
    8247             :         "{x : {y : var}}",
    8248             :         "{x : x = a+}",
    8249             :         "{x : x = (a+)}",
    8250             :         "{x : x += a}",
    8251             :         "{m() {} = 0}",
    8252             :         "{[1+1]}",
    8253             :         "[...rest, x]",
    8254             :         "[a,b,...rest, x]",
    8255             :         "[a,,...rest, x]",
    8256             :         "[...rest,]",
    8257             :         "[a,b,...rest,]",
    8258             :         "[a,,...rest,]",
    8259             :         "[...rest,...rest1]",
    8260             :         "[a,b,...rest,...rest1]",
    8261             :         "[a,,..rest,...rest1]",
    8262             :         "[x, y, ...z = 1]",
    8263             :         "[...z = 1]",
    8264             :         "[x, y, ...[z] = [1]]",
    8265             :         "[...[z] = [1]]",
    8266             :         "{ x : 3 }",
    8267             :         "{ x : 'foo' }",
    8268             :         "{ x : /foo/ }",
    8269             :         "{ x : `foo` }",
    8270             :         "{ get a() {} }",
    8271             :         "{ set a() {} }",
    8272             :         "{ method() {} }",
    8273             :         "{ *method() {} }",
    8274             :         "...a++",
    8275             :         "...++a",
    8276             :         "...typeof a",
    8277             :         "...[a++]",
    8278             :         "...(x => y)",
    8279             :         "{ ...x, }",
    8280             :         "{ ...x, y }",
    8281             :         "{ y, ...x, y }",
    8282             :         "{ ...x, ...y }",
    8283             :         "{ ...x, ...x }",
    8284             :         "{ ...x, ...x = {} }",
    8285             :         "{ ...x, ...x = ...x }",
    8286             :         "{ ...x, ...x = ...{ x } }",
    8287             :         "{ ,, ...x }",
    8288             :         "{ ...get a() {} }",
    8289             :         "{ ...set a() {} }",
    8290             :         "{ ...method() {} }",
    8291             :         "{ ...function() {} }",
    8292             :         "{ ...*method() {} }",
    8293             :         "{...{x} }",
    8294             :         "{...[x] }",
    8295             :         "{...{ x = 5 } }",
    8296             :         "{...[ x = 5 ] }",
    8297             :         "{...x.f }",
    8298             :         "{...x[0] }",
    8299             :         "async function* a() {}",
    8300             :         nullptr
    8301           5 :     };
    8302             : 
    8303             :     // clang-format on
    8304           5 :     RunParserSyncTest(context_data, data, kError);
    8305             :   }
    8306             : 
    8307             :   {  // All modes.
    8308             :     const char* context_data[][2] = {
    8309             :         {"'use strict'; let ", " = {};"},    {"var ", " = {};"},
    8310             :         {"'use strict'; const ", " = {};"},  {"function f(", ") {}"},
    8311             :         {"function f(argument1, ", ") {}"},  {"var f = (", ") => {};"},
    8312           5 :         {"var f = (argument1,", ") => {};"}, {nullptr, nullptr}};
    8313             : 
    8314             :     // clang-format off
    8315             :     const char* data[] = {
    8316             :         "x => x",
    8317             :         "() => x",
    8318           5 :         nullptr};
    8319             :     // clang-format on
    8320           5 :     RunParserSyncTest(context_data, data, kError);
    8321             :   }
    8322             : 
    8323             :   {  // Strict mode.
    8324             :     const char* context_data[][2] = {
    8325             :         {"'use strict'; var ", " = {};"},
    8326             :         {"'use strict'; let ", " = {};"},
    8327             :         {"'use strict'; const ", " = {};"},
    8328             :         {"'use strict'; function f(", ") {}"},
    8329             :         {"'use strict'; function f(argument1, ", ") {}"},
    8330           5 :         {nullptr, nullptr}};
    8331             : 
    8332             :     // clang-format off
    8333             :     const char* data[] = {
    8334             :       "[arguments]",
    8335             :       "[eval]",
    8336             :       "{ a : arguments }",
    8337             :       "{ a : eval }",
    8338             :       "[public]",
    8339             :       "{ x : private }",
    8340             :       "{ x : arguments }",
    8341             :       "{ x : eval }",
    8342             :       "{ arguments }",
    8343             :       "{ eval }",
    8344             :       "{ arguments = false }"
    8345             :       "{ eval = false }",
    8346             :       "{ ...eval }",
    8347             :       "{ ...arguments }",
    8348           5 :       nullptr};
    8349             : 
    8350             :     // clang-format on
    8351           5 :     RunParserSyncTest(context_data, data, kError);
    8352             :   }
    8353             : 
    8354             :   {  // 'yield' in generators.
    8355             :     const char* context_data[][2] = {
    8356             :         {"function*() { var ", " = {};"},
    8357             :         {"function*() { 'use strict'; let ", " = {};"},
    8358             :         {"function*() { 'use strict'; const ", " = {};"},
    8359           5 :         {nullptr, nullptr}};
    8360             : 
    8361             :     // clang-format off
    8362             :     const char* data[] = {
    8363             :       "yield",
    8364             :       "[yield]",
    8365             :       "{ x : yield }",
    8366           5 :       nullptr};
    8367             :     // clang-format on
    8368           5 :     RunParserSyncTest(context_data, data, kError);
    8369             :   }
    8370             : 
    8371             :   { // Declaration-specific errors
    8372             :     const char* context_data[][2] = {{"'use strict'; var ", ""},
    8373             :                                      {"'use strict'; let ", ""},
    8374             :                                      {"'use strict'; const ", ""},
    8375             :                                      {"'use strict'; for (var ", ";;) {}"},
    8376             :                                      {"'use strict'; for (let ", ";;) {}"},
    8377             :                                      {"'use strict'; for (const ", ";;) {}"},
    8378             :                                      {"var ", ""},
    8379             :                                      {"let ", ""},
    8380             :                                      {"const ", ""},
    8381             :                                      {"for (var ", ";;) {}"},
    8382             :                                      {"for (let ", ";;) {}"},
    8383             :                                      {"for (const ", ";;) {}"},
    8384           5 :                                      {nullptr, nullptr}};
    8385             : 
    8386             :     // clang-format off
    8387             :     const char* data[] = {
    8388             :       "{ a }",
    8389             :       "[ a ]",
    8390             :       "{ ...a }",
    8391             :       nullptr
    8392           5 :     };
    8393             :     // clang-format on
    8394           5 :     RunParserSyncTest(context_data, data, kError);
    8395             :   }
    8396           5 : }
    8397             : 
    8398       26644 : TEST(ObjectRestNegativeTestSlow) {
    8399             :   // clang-format off
    8400             :   const char* context_data[][2] = {
    8401             :     {"var { ", " } = { a: 1};"},
    8402             :     { nullptr, nullptr }
    8403           5 :   };
    8404             : 
    8405             :   using v8::internal::Code;
    8406             :   std::string statement;
    8407      655345 :   for (int i = 0; i < Code::kMaxArguments; ++i) {
    8408     1310680 :     statement += std::to_string(i) + " : " + "x, ";
    8409             :   }
    8410             :   statement += "...y";
    8411             : 
    8412             :   const char* statement_data[] = {
    8413             :     statement.c_str(),
    8414             :     nullptr
    8415           5 :   };
    8416             : 
    8417             :   // clang-format on
    8418             :   // The test is quite slow, so run it with a reduced set of flags.
    8419             :   static const ParserFlag flags[] = {kAllowLazy};
    8420             :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0, flags,
    8421           5 :                     arraysize(flags));
    8422           5 : }
    8423             : 
    8424       26644 : TEST(DestructuringAssignmentPositiveTests) {
    8425             :   const char* context_data[][2] = {
    8426             :       {"'use strict'; let x, y, z; (", " = {});"},
    8427             :       {"var x, y, z; (", " = {});"},
    8428             :       {"'use strict'; let x, y, z; for (x in ", " = {});"},
    8429             :       {"'use strict'; let x, y, z; for (x of ", " = {});"},
    8430             :       {"var x, y, z; for (x in ", " = {});"},
    8431             :       {"var x, y, z; for (x of ", " = {});"},
    8432             :       {"var x, y, z; for (", " in {});"},
    8433             :       {"var x, y, z; for (", " of {});"},
    8434             :       {"'use strict'; var x, y, z; for (", " in {});"},
    8435             :       {"'use strict'; var x, y, z; for (", " of {});"},
    8436             :       {"var x, y, z; m(['a']) ? ", " = {} : rhs"},
    8437             :       {"var x, y, z; m(['b']) ? lhs : ", " = {}"},
    8438             :       {"'use strict'; var x, y, z; m(['a']) ? ", " = {} : rhs"},
    8439             :       {"'use strict'; var x, y, z; m(['b']) ? lhs : ", " = {}"},
    8440           5 :       {nullptr, nullptr}};
    8441             : 
    8442             :   const char* mixed_assignments_context_data[][2] = {
    8443             :       {"'use strict'; let x, y, z; (", " = z = {});"},
    8444             :       {"var x, y, z; (", " = z = {});"},
    8445             :       {"'use strict'; let x, y, z; (x = ", " = z = {});"},
    8446             :       {"var x, y, z; (x = ", " = z = {});"},
    8447             :       {"'use strict'; let x, y, z; for (x in ", " = z = {});"},
    8448             :       {"'use strict'; let x, y, z; for (x in x = ", " = z = {});"},
    8449             :       {"'use strict'; let x, y, z; for (x of ", " = z = {});"},
    8450             :       {"'use strict'; let x, y, z; for (x of x = ", " = z = {});"},
    8451             :       {"var x, y, z; for (x in ", " = z = {});"},
    8452             :       {"var x, y, z; for (x in x = ", " = z = {});"},
    8453             :       {"var x, y, z; for (x of ", " = z = {});"},
    8454             :       {"var x, y, z; for (x of x = ", " = z = {});"},
    8455           5 :       {nullptr, nullptr}};
    8456             : 
    8457             :   // clang-format off
    8458             :   const char* data[] = {
    8459             :     "x",
    8460             : 
    8461             :     "{ x : y }",
    8462             :     "{ x : foo().y }",
    8463             :     "{ x : foo()[y] }",
    8464             :     "{ x : y.z }",
    8465             :     "{ x : y[z] }",
    8466             :     "{ x : { y } }",
    8467             :     "{ x : { foo: y } }",
    8468             :     "{ x : { foo: foo().y } }",
    8469             :     "{ x : { foo: foo()[y] } }",
    8470             :     "{ x : { foo: y.z } }",
    8471             :     "{ x : { foo: y[z] } }",
    8472             :     "{ x : [ y ] }",
    8473             :     "{ x : [ foo().y ] }",
    8474             :     "{ x : [ foo()[y] ] }",
    8475             :     "{ x : [ y.z ] }",
    8476             :     "{ x : [ y[z] ] }",
    8477             : 
    8478             :     "{ x : y = 10 }",
    8479             :     "{ x : foo().y = 10 }",
    8480             :     "{ x : foo()[y] = 10 }",
    8481             :     "{ x : y.z = 10 }",
    8482             :     "{ x : y[z] = 10 }",
    8483             :     "{ x : { y = 10 } = {} }",
    8484             :     "{ x : { foo: y = 10 } = {} }",
    8485             :     "{ x : { foo: foo().y = 10 } = {} }",
    8486             :     "{ x : { foo: foo()[y] = 10 } = {} }",
    8487             :     "{ x : { foo: y.z = 10 } = {} }",
    8488             :     "{ x : { foo: y[z] = 10 } = {} }",
    8489             :     "{ x : [ y = 10 ] = {} }",
    8490             :     "{ x : [ foo().y = 10 ] = {} }",
    8491             :     "{ x : [ foo()[y] = 10 ] = {} }",
    8492             :     "{ x : [ y.z = 10 ] = {} }",
    8493             :     "{ x : [ y[z] = 10 ] = {} }",
    8494             :     "{ z : { __proto__: x, __proto__: y } = z }"
    8495             : 
    8496             :     "[ x ]",
    8497             :     "[ foo().x ]",
    8498             :     "[ foo()[x] ]",
    8499             :     "[ x.y ]",
    8500             :     "[ x[y] ]",
    8501             :     "[ { x } ]",
    8502             :     "[ { x : y } ]",
    8503             :     "[ { x : foo().y } ]",
    8504             :     "[ { x : foo()[y] } ]",
    8505             :     "[ { x : x.y } ]",
    8506             :     "[ { x : x[y] } ]",
    8507             :     "[ [ x ] ]",
    8508             :     "[ [ foo().x ] ]",
    8509             :     "[ [ foo()[x] ] ]",
    8510             :     "[ [ x.y ] ]",
    8511             :     "[ [ x[y] ] ]",
    8512             : 
    8513             :     "[ x = 10 ]",
    8514             :     "[ foo().x = 10 ]",
    8515             :     "[ foo()[x] = 10 ]",
    8516             :     "[ x.y = 10 ]",
    8517             :     "[ x[y] = 10 ]",
    8518             :     "[ { x = 10 } = {} ]",
    8519             :     "[ { x : y = 10 } = {} ]",
    8520             :     "[ { x : foo().y = 10 } = {} ]",
    8521             :     "[ { x : foo()[y] = 10 } = {} ]",
    8522             :     "[ { x : x.y = 10 } = {} ]",
    8523             :     "[ { x : x[y] = 10 } = {} ]",
    8524             :     "[ [ x = 10 ] = {} ]",
    8525             :     "[ [ foo().x = 10 ] = {} ]",
    8526             :     "[ [ foo()[x] = 10 ] = {} ]",
    8527             :     "[ [ x.y = 10 ] = {} ]",
    8528             :     "[ [ x[y] = 10 ] = {} ]",
    8529             :     "{ x : y = 1 }",
    8530             :     "{ x }",
    8531             :     "{ x, y, z }",
    8532             :     "{ x = 1, y: z, z: y }",
    8533             :     "{x = 42, y = 15}",
    8534             :     "[x]",
    8535             :     "[x = 1]",
    8536             :     "[x,y,z]",
    8537             :     "[x, y = 42, z]",
    8538             :     "{ x : x, y : y }",
    8539             :     "{ x : x = 1, y : y }",
    8540             :     "{ x : x, y : y = 42 }",
    8541             :     "[]",
    8542             :     "{}",
    8543             :     "[{x:x, y:y}, [,x,z,]]",
    8544             :     "[{x:x = 1, y:y = 2}, [z = 3, z = 4, z = 5]]",
    8545             :     "[x,,y]",
    8546             :     "[(x),,(y)]",
    8547             :     "[(x)]",
    8548             :     "{42 : x}",
    8549             :     "{42 : x = 42}",
    8550             :     "{42e-2 : x}",
    8551             :     "{42e-2 : x = 42}",
    8552             :     "{'hi' : x}",
    8553             :     "{'hi' : x = 42}",
    8554             :     "{var: x}",
    8555             :     "{var: x = 42}",
    8556             :     "{var: (x) = 42}",
    8557             :     "{[x] : z}",
    8558             :     "{[1+1] : z}",
    8559             :     "{[1+1] : (z)}",
    8560             :     "{[foo()] : z}",
    8561             :     "{[foo()] : (z)}",
    8562             :     "{[foo()] : foo().bar}",
    8563             :     "{[foo()] : foo()['bar']}",
    8564             :     "{[foo()] : this.bar}",
    8565             :     "{[foo()] : this['bar']}",
    8566             :     "{[foo()] : 'foo'.bar}",
    8567             :     "{[foo()] : 'foo'['bar']}",
    8568             :     "[...x]",
    8569             :     "[x,y,...z]",
    8570             :     "[x,,...z]",
    8571             :     "{ x: y }",
    8572             :     "[x, y]",
    8573             :     "[((x, y) => z).x]",
    8574             :     "{x: ((y, z) => z).x}",
    8575             :     "[((x, y) => z)['x']]",
    8576             :     "{x: ((y, z) => z)['x']}",
    8577             : 
    8578             :     "{x: { y = 10 } }",
    8579             :     "[(({ x } = { x: 1 }) => x).a]",
    8580             : 
    8581             :     "{ ...d.x }",
    8582             :     "{ ...c[0]}",
    8583             : 
    8584             :     // v8:4662
    8585             :     "{ x: (y) }",
    8586             :     "{ x: (y) = [] }",
    8587             :     "{ x: (foo.bar) }",
    8588             :     "{ x: (foo['bar']) }",
    8589             :     "[ ...(a) ]",
    8590             :     "[ ...(foo['bar']) ]",
    8591             :     "[ ...(foo.bar) ]",
    8592             :     "[ (y) ]",
    8593             :     "[ (foo.bar) ]",
    8594             :     "[ (foo['bar']) ]",
    8595             : 
    8596           5 :     nullptr};
    8597             :   // clang-format on
    8598           5 :   RunParserSyncTest(context_data, data, kSuccess);
    8599             : 
    8600           5 :   RunParserSyncTest(mixed_assignments_context_data, data, kSuccess);
    8601             : 
    8602             :   const char* empty_context_data[][2] = {
    8603           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    8604             : 
    8605             :   // CoverInitializedName ambiguity handling in various contexts
    8606             :   const char* ambiguity_data[] = {
    8607             :       "var foo = { x = 10 } = {};",
    8608             :       "var foo = { q } = { x = 10 } = {};",
    8609             :       "var foo; foo = { x = 10 } = {};",
    8610             :       "var foo; foo = { q } = { x = 10 } = {};",
    8611             :       "var x; ({ x = 10 } = {});",
    8612             :       "var q, x; ({ q } = { x = 10 } = {});",
    8613             :       "var x; [{ x = 10 } = {}]",
    8614             :       "var x; (true ? { x = true } = {} : { x = false } = {})",
    8615             :       "var q, x; (q, { x = 10 } = {});",
    8616             :       "var { x = 10 } = { x = 20 } = {};",
    8617             :       "var { __proto__: x, __proto__: y } = {}",
    8618             :       "({ __proto__: x, __proto__: y } = {})",
    8619             :       "var { x = 10 } = (o = { x = 20 } = {});",
    8620             :       "var x; (({ x = 10 } = { x = 20 } = {}) => x)({})",
    8621             :       nullptr,
    8622           5 :   };
    8623           5 :   RunParserSyncTest(empty_context_data, ambiguity_data, kSuccess);
    8624           5 : }
    8625             : 
    8626             : 
    8627       26644 : TEST(DestructuringAssignmentNegativeTests) {
    8628             :   const char* context_data[][2] = {
    8629             :       {"'use strict'; let x, y, z; (", " = {});"},
    8630             :       {"var x, y, z; (", " = {});"},
    8631             :       {"'use strict'; let x, y, z; for (x in ", " = {});"},
    8632             :       {"'use strict'; let x, y, z; for (x of ", " = {});"},
    8633             :       {"var x, y, z; for (x in ", " = {});"},
    8634             :       {"var x, y, z; for (x of ", " = {});"},
    8635           5 :       {nullptr, nullptr}};
    8636             : 
    8637             :   // clang-format off
    8638             :   const char* data[] = {
    8639             :     "{ x : ++y }",
    8640             :     "{ x : y * 2 }",
    8641             :     "{ get x() {} }",
    8642             :     "{ set x() {} }",
    8643             :     "{ x: y() }",
    8644             :     "{ this }",
    8645             :     "{ x: this }",
    8646             :     "{ x: this = 1 }",
    8647             :     "{ super }",
    8648             :     "{ x: super }",
    8649             :     "{ x: super = 1 }",
    8650             :     "{ new.target }",
    8651             :     "{ x: new.target }",
    8652             :     "{ x: new.target = 1 }",
    8653             :     "{ import.meta }",
    8654             :     "{ x: import.meta }",
    8655             :     "{ x: import.meta = 1 }",
    8656             :     "[x--]",
    8657             :     "[--x = 1]",
    8658             :     "[x()]",
    8659             :     "[this]",
    8660             :     "[this = 1]",
    8661             :     "[new.target]",
    8662             :     "[new.target = 1]",
    8663             :     "[import.meta]",
    8664             :     "[import.meta = 1]",
    8665             :     "[super]",
    8666             :     "[super = 1]",
    8667             :     "[function f() {}]",
    8668             :     "[async function f() {}]",
    8669             :     "[function* f() {}]",
    8670             :     "[50]",
    8671             :     "[(50)]",
    8672             :     "[(function() {})]",
    8673             :     "[(async function() {})]",
    8674             :     "[(function*() {})]",
    8675             :     "[(foo())]",
    8676             :     "{ x: 50 }",
    8677             :     "{ x: (50) }",
    8678             :     "['str']",
    8679             :     "{ x: 'str' }",
    8680             :     "{ x: ('str') }",
    8681             :     "{ x: (foo()) }",
    8682             :     "{ x: function() {} }",
    8683             :     "{ x: async function() {} }",
    8684             :     "{ x: function*() {} }",
    8685             :     "{ x: (function() {}) }",
    8686             :     "{ x: (async function() {}) }",
    8687             :     "{ x: (function*() {}) }",
    8688             :     "{ x: y } = 'str'",
    8689             :     "[x, y] = 'str'",
    8690             :     "[(x,y) => z]",
    8691             :     "[async(x,y) => z]",
    8692             :     "[async x => z]",
    8693             :     "{x: (y) => z}",
    8694             :     "{x: (y,w) => z}",
    8695             :     "{x: async (y) => z}",
    8696             :     "{x: async (y,w) => z}",
    8697             :     "[x, ...y, z]",
    8698             :     "[...x,]",
    8699             :     "[x, y, ...z = 1]",
    8700             :     "[...z = 1]",
    8701             :     "[x, y, ...[z] = [1]]",
    8702             :     "[...[z] = [1]]",
    8703             : 
    8704             :     "[...++x]",
    8705             :     "[...x--]",
    8706             :     "[...!x]",
    8707             :     "[...x + y]",
    8708             : 
    8709             :     // v8:4657
    8710             :     "({ x: x4, x: (x+=1e4) })",
    8711             :     "(({ x: x4, x: (x+=1e4) }))",
    8712             :     "({ x: x4, x: (x+=1e4) } = {})",
    8713             :     "(({ x: x4, x: (x+=1e4) } = {}))",
    8714             :     "(({ x: x4, x: (x+=1e4) }) = {})",
    8715             :     "({ x: y } = {})",
    8716             :     "(({ x: y } = {}))",
    8717             :     "(({ x: y }) = {})",
    8718             :     "([a])",
    8719             :     "(([a]))",
    8720             :     "([a] = [])",
    8721             :     "(([a] = []))",
    8722             :     "(([a]) = [])",
    8723             : 
    8724             :     // v8:4662
    8725             :     "{ x: ([y]) }",
    8726             :     "{ x: ([y] = []) }",
    8727             :     "{ x: ({y}) }",
    8728             :     "{ x: ({y} = {}) }",
    8729             :     "{ x: (++y) }",
    8730             :     "[ (...[a]) ]",
    8731             :     "[ ...([a]) ]",
    8732             :     "[ ...([a] = [])",
    8733             :     "[ ...[ ( [ a ] ) ] ]",
    8734             :     "[ ([a]) ]",
    8735             :     "[ (...[a]) ]",
    8736             :     "[ ([a] = []) ]",
    8737             :     "[ (++y) ]",
    8738             :     "[ ...(++y) ]",
    8739             : 
    8740             :     "[ x += x ]",
    8741             :     "{ foo: x += x }",
    8742             : 
    8743           5 :     nullptr};
    8744             :   // clang-format on
    8745           5 :   RunParserSyncTest(context_data, data, kError);
    8746             : 
    8747             :   const char* empty_context_data[][2] = {
    8748           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    8749             : 
    8750             :   // CoverInitializedName ambiguity handling in various contexts
    8751             :   const char* ambiguity_data[] = {
    8752             :       "var foo = { x = 10 };", "var foo = { q } = { x = 10 };",
    8753             :       "var foo; foo = { x = 10 };", "var foo; foo = { q } = { x = 10 };",
    8754             :       "var x; ({ x = 10 });", "var q, x; ({ q } = { x = 10 });",
    8755             :       "var x; [{ x = 10 }]", "var x; (true ? { x = true } : { x = false })",
    8756             :       "var q, x; (q, { x = 10 });", "var { x = 10 } = { x = 20 };",
    8757             :       "var { x = 10 } = (o = { x = 20 });",
    8758             :       "var x; (({ x = 10 } = { x = 20 }) => x)({})",
    8759             : 
    8760             :       // Not ambiguous, but uses same context data
    8761             :       "switch([window %= []] = []) { default: }",
    8762             : 
    8763             :       nullptr,
    8764           5 :   };
    8765           5 :   RunParserSyncTest(empty_context_data, ambiguity_data, kError);
    8766             : 
    8767             :   // Strict mode errors
    8768             :   const char* strict_context_data[][2] = {{"'use strict'; (", " = {})"},
    8769             :                                           {"'use strict'; for (", " of {}) {}"},
    8770             :                                           {"'use strict'; for (", " in {}) {}"},
    8771           5 :                                           {nullptr, nullptr}};
    8772             :   const char* strict_data[] = {
    8773             :       "{ eval }", "{ arguments }", "{ foo: eval }", "{ foo: arguments }",
    8774             :       "{ eval = 0 }", "{ arguments = 0 }", "{ foo: eval = 0 }",
    8775             :       "{ foo: arguments = 0 }", "[ eval ]", "[ arguments ]", "[ eval = 0 ]",
    8776             :       "[ arguments = 0 ]",
    8777             : 
    8778             :       // v8:4662
    8779             :       "{ x: (eval) }", "{ x: (arguments) }", "{ x: (eval = 0) }",
    8780             :       "{ x: (arguments = 0) }", "{ x: (eval) = 0 }", "{ x: (arguments) = 0 }",
    8781             :       "[ (eval) ]", "[ (arguments) ]", "[ (eval = 0) ]", "[ (arguments = 0) ]",
    8782             :       "[ (eval) = 0 ]", "[ (arguments) = 0 ]", "[ ...(eval) ]",
    8783             :       "[ ...(arguments) ]", "[ ...(eval = 0) ]", "[ ...(arguments = 0) ]",
    8784             :       "[ ...(eval) = 0 ]", "[ ...(arguments) = 0 ]",
    8785             : 
    8786           5 :       nullptr};
    8787           5 :   RunParserSyncTest(strict_context_data, strict_data, kError);
    8788           5 : }
    8789             : 
    8790             : 
    8791       26644 : TEST(DestructuringDisallowPatternsInForVarIn) {
    8792             :   const char* context_data[][2] = {
    8793           5 :       {"", ""}, {"function f() {", "}"}, {nullptr, nullptr}};
    8794             :   // clang-format off
    8795             :   const char* error_data[] = {
    8796             :     "for (let x = {} in null);",
    8797             :     "for (let x = {} of null);",
    8798           5 :     nullptr};
    8799             :   // clang-format on
    8800           5 :   RunParserSyncTest(context_data, error_data, kError);
    8801             : 
    8802             :   // clang-format off
    8803             :   const char* success_data[] = {
    8804             :     "for (var x = {} in null);",
    8805           5 :     nullptr};
    8806             :   // clang-format on
    8807           5 :   RunParserSyncTest(context_data, success_data, kSuccess);
    8808           5 : }
    8809             : 
    8810             : 
    8811       26644 : TEST(DestructuringDuplicateParams) {
    8812             :   const char* context_data[][2] = {{"'use strict';", ""},
    8813             :                                    {"function outer() { 'use strict';", "}"},
    8814           5 :                                    {nullptr, nullptr}};
    8815             : 
    8816             : 
    8817             :   // clang-format off
    8818             :   const char* error_data[] = {
    8819             :     "function f(x,x){}",
    8820             :     "function f(x, {x : x}){}",
    8821             :     "function f(x, {x}){}",
    8822             :     "function f({x,x}) {}",
    8823             :     "function f([x,x]) {}",
    8824             :     "function f(x, [y,{z:x}]) {}",
    8825             :     "function f([x,{y:x}]) {}",
    8826             :     // non-simple parameter list causes duplicates to be errors in sloppy mode.
    8827             :     "function f(x, x, {a}) {}",
    8828           5 :     nullptr};
    8829             :   // clang-format on
    8830           5 :   RunParserSyncTest(context_data, error_data, kError);
    8831           5 : }
    8832             : 
    8833             : 
    8834       26644 : TEST(DestructuringDuplicateParamsSloppy) {
    8835             :   const char* context_data[][2] = {
    8836           5 :       {"", ""}, {"function outer() {", "}"}, {nullptr, nullptr}};
    8837             : 
    8838             : 
    8839             :   // clang-format off
    8840             :   const char* error_data[] = {
    8841             :     // non-simple parameter list causes duplicates to be errors in sloppy mode.
    8842             :     "function f(x, {x : x}){}",
    8843             :     "function f(x, {x}){}",
    8844             :     "function f({x,x}) {}",
    8845             :     "function f(x, x, {a}) {}",
    8846           5 :     nullptr};
    8847             :   // clang-format on
    8848           5 :   RunParserSyncTest(context_data, error_data, kError);
    8849           5 : }
    8850             : 
    8851             : 
    8852       26644 : TEST(DestructuringDisallowPatternsInSingleParamArrows) {
    8853             :   const char* context_data[][2] = {{"'use strict';", ""},
    8854             :                                    {"function outer() { 'use strict';", "}"},
    8855             :                                    {"", ""},
    8856             :                                    {"function outer() { ", "}"},
    8857           5 :                                    {nullptr, nullptr}};
    8858             : 
    8859             :   // clang-format off
    8860             :   const char* error_data[] = {
    8861             :     "var f = {x} => {};",
    8862             :     "var f = {x,y} => {};",
    8863           5 :     nullptr};
    8864             :   // clang-format on
    8865           5 :   RunParserSyncTest(context_data, error_data, kError);
    8866           5 : }
    8867             : 
    8868             : 
    8869       26644 : TEST(DefaultParametersYieldInInitializers) {
    8870             :   // clang-format off
    8871             :   const char* sloppy_function_context_data[][2] = {
    8872             :     {"(function f(", ") { });"},
    8873             :     {nullptr, nullptr}
    8874           5 :   };
    8875             : 
    8876             :   const char* strict_function_context_data[][2] = {
    8877             :     {"'use strict'; (function f(", ") { });"},
    8878             :     {nullptr, nullptr}
    8879           5 :   };
    8880             : 
    8881             :   const char* sloppy_arrow_context_data[][2] = {
    8882             :     {"((", ")=>{});"},
    8883             :     {nullptr, nullptr}
    8884           5 :   };
    8885             : 
    8886             :   const char* strict_arrow_context_data[][2] = {
    8887             :     {"'use strict'; ((", ")=>{});"},
    8888             :     {nullptr, nullptr}
    8889           5 :   };
    8890             : 
    8891             :   const char* generator_context_data[][2] = {
    8892             :     {"'use strict'; (function *g(", ") { });"},
    8893             :     {"(function *g(", ") { });"},
    8894             :     // Arrow function within generator has the same rules.
    8895             :     {"'use strict'; (function *g() { (", ") => {} });"},
    8896             :     {"(function *g() { (", ") => {} });"},
    8897             :     // And similarly for arrow functions in the parameter list.
    8898             :     {"'use strict'; (function *g(z = (", ") => {}) { });"},
    8899             :     {"(function *g(z = (", ") => {}) { });"},
    8900             :     {nullptr, nullptr}
    8901           5 :   };
    8902             : 
    8903             :   const char* parameter_data[] = {
    8904             :     "x=yield",
    8905             :     "x, y=yield",
    8906             :     "{x=yield}",
    8907             :     "[x=yield]",
    8908             : 
    8909             :     "x=(yield)",
    8910             :     "x, y=(yield)",
    8911             :     "{x=(yield)}",
    8912             :     "[x=(yield)]",
    8913             : 
    8914             :     "x=f(yield)",
    8915             :     "x, y=f(yield)",
    8916             :     "{x=f(yield)}",
    8917             :     "[x=f(yield)]",
    8918             : 
    8919             :     "{x}=yield",
    8920             :     "[x]=yield",
    8921             : 
    8922             :     "{x}=(yield)",
    8923             :     "[x]=(yield)",
    8924             : 
    8925             :     "{x}=f(yield)",
    8926             :     "[x]=f(yield)",
    8927             :     nullptr
    8928           5 :   };
    8929             : 
    8930             :   // Because classes are always in strict mode, these are always errors.
    8931             :   const char* always_error_param_data[] = {
    8932             :     "x = class extends (yield) { }",
    8933             :     "x = class extends f(yield) { }",
    8934             :     "x = class extends (null, yield) { }",
    8935             :     "x = class extends (a ? null : yield) { }",
    8936             :     "[x] = [class extends (a ? null : yield) { }]",
    8937             :     "[x = class extends (a ? null : yield) { }]",
    8938             :     "[x = class extends (a ? null : yield) { }] = [null]",
    8939             :     "x = class { [yield]() { } }",
    8940             :     "x = class { static [yield]() { } }",
    8941             :     "x = class { [(yield, 1)]() { } }",
    8942             :     "x = class { [y = (yield, 1)]() { } }",
    8943             :     nullptr
    8944           5 :   };
    8945             :   // clang-format on
    8946             : 
    8947           5 :   RunParserSyncTest(sloppy_function_context_data, parameter_data, kSuccess);
    8948           5 :   RunParserSyncTest(sloppy_arrow_context_data, parameter_data, kSuccess);
    8949             : 
    8950           5 :   RunParserSyncTest(strict_function_context_data, parameter_data, kError);
    8951           5 :   RunParserSyncTest(strict_arrow_context_data, parameter_data, kError);
    8952             : 
    8953           5 :   RunParserSyncTest(generator_context_data, parameter_data, kError);
    8954           5 :   RunParserSyncTest(generator_context_data, always_error_param_data, kError);
    8955           5 : }
    8956             : 
    8957       26644 : TEST(SpreadArray) {
    8958             :   const char* context_data[][2] = {
    8959           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    8960             : 
    8961             :   // clang-format off
    8962             :   const char* data[] = {
    8963             :     "[...a]",
    8964             :     "[a, ...b]",
    8965             :     "[...a,]",
    8966             :     "[...a, ,]",
    8967             :     "[, ...a]",
    8968             :     "[...a, ...b]",
    8969             :     "[...a, , ...b]",
    8970             :     "[...[...a]]",
    8971             :     "[, ...a]",
    8972             :     "[, , ...a]",
    8973           5 :     nullptr};
    8974             :   // clang-format on
    8975           5 :   RunParserSyncTest(context_data, data, kSuccess);
    8976           5 : }
    8977             : 
    8978             : 
    8979       26644 : TEST(SpreadArrayError) {
    8980             :   const char* context_data[][2] = {
    8981           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    8982             : 
    8983             :   // clang-format off
    8984             :   const char* data[] = {
    8985             :     "[...]",
    8986             :     "[a, ...]",
    8987             :     "[..., ]",
    8988             :     "[..., ...]",
    8989             :     "[ (...a)]",
    8990           5 :     nullptr};
    8991             :   // clang-format on
    8992           5 :   RunParserSyncTest(context_data, data, kError);
    8993           5 : }
    8994             : 
    8995             : 
    8996       26644 : TEST(NewTarget) {
    8997             :   // clang-format off
    8998             :   const char* good_context_data[][2] = {
    8999             :     {"function f() {", "}"},
    9000             :     {"'use strict'; function f() {", "}"},
    9001             :     {"var f = function() {", "}"},
    9002             :     {"'use strict'; var f = function() {", "}"},
    9003             :     {"({m: function() {", "}})"},
    9004             :     {"'use strict'; ({m: function() {", "}})"},
    9005             :     {"({m() {", "}})"},
    9006             :     {"'use strict'; ({m() {", "}})"},
    9007             :     {"({get x() {", "}})"},
    9008             :     {"'use strict'; ({get x() {", "}})"},
    9009             :     {"({set x(_) {", "}})"},
    9010             :     {"'use strict'; ({set x(_) {", "}})"},
    9011             :     {"class C {m() {", "}}"},
    9012             :     {"class C {get x() {", "}}"},
    9013             :     {"class C {set x(_) {", "}}"},
    9014             :     {nullptr}
    9015           5 :   };
    9016             : 
    9017             :   const char* bad_context_data[][2] = {
    9018             :     {"", ""},
    9019             :     {"'use strict';", ""},
    9020             :     {nullptr}
    9021           5 :   };
    9022             : 
    9023             :   const char* data[] = {
    9024             :     "new.target",
    9025             :     "{ new.target }",
    9026             :     "() => { new.target }",
    9027             :     "() => new.target",
    9028             :     "if (1) { new.target }",
    9029             :     "if (1) {} else { new.target }",
    9030             :     "while (0) { new.target }",
    9031             :     "do { new.target } while (0)",
    9032             :     nullptr
    9033           5 :   };
    9034             : 
    9035             :   // clang-format on
    9036             : 
    9037           5 :   RunParserSyncTest(good_context_data, data, kSuccess);
    9038           5 :   RunParserSyncTest(bad_context_data, data, kError);
    9039           5 : }
    9040             : 
    9041       26644 : TEST(ImportMetaSuccess) {
    9042             :   // clang-format off
    9043             :   const char* context_data[][2] = {
    9044             :     {"", ""},
    9045             :     {"'use strict';", ""},
    9046             :     {"function f() {", "}"},
    9047             :     {"'use strict'; function f() {", "}"},
    9048             :     {"var f = function() {", "}"},
    9049             :     {"'use strict'; var f = function() {", "}"},
    9050             :     {"({m: function() {", "}})"},
    9051             :     {"'use strict'; ({m: function() {", "}})"},
    9052             :     {"({m() {", "}})"},
    9053             :     {"'use strict'; ({m() {", "}})"},
    9054             :     {"({get x() {", "}})"},
    9055             :     {"'use strict'; ({get x() {", "}})"},
    9056             :     {"({set x(_) {", "}})"},
    9057             :     {"'use strict'; ({set x(_) {", "}})"},
    9058             :     {"class C {m() {", "}}"},
    9059             :     {"class C {get x() {", "}}"},
    9060             :     {"class C {set x(_) {", "}}"},
    9061             :     {nullptr}
    9062           5 :   };
    9063             : 
    9064             :   const char* data[] = {
    9065             :     "import.meta",
    9066             :     "() => { import.meta }",
    9067             :     "() => import.meta",
    9068             :     "if (1) { import.meta }",
    9069             :     "if (1) {} else { import.meta }",
    9070             :     "while (0) { import.meta }",
    9071             :     "do { import.meta } while (0)",
    9072             :     "import.meta.url",
    9073             :     "import.meta[0]",
    9074             :     "import.meta.couldBeMutable = true",
    9075             :     "import.meta()",
    9076             :     "new import.meta.MagicClass",
    9077             :     "new import.meta",
    9078             :     "t = [...import.meta]",
    9079             :     "f = {...import.meta}",
    9080             :     "delete import.meta",
    9081             :     nullptr
    9082           5 :   };
    9083             : 
    9084             :   // clang-format on
    9085             : 
    9086             :   // Making sure the same *wouldn't* parse without the flags
    9087             :   RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
    9088             :                           nullptr, 0, true, true);
    9089             : 
    9090             :   static const ParserFlag flags[] = {
    9091             :       kAllowHarmonyImportMeta, kAllowHarmonyDynamicImport,
    9092             :   };
    9093             :   // 2.1.1 Static Semantics: Early Errors
    9094             :   // ImportMeta
    9095             :   // * It is an early Syntax Error if Module is not the syntactic goal symbol.
    9096             :   RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    9097           5 :                     arraysize(flags));
    9098             :   // Making sure the same wouldn't parse without the flags either
    9099           5 :   RunParserSyncTest(context_data, data, kError);
    9100             : 
    9101             :   RunModuleParserSyncTest(context_data, data, kSuccess, nullptr, 0, flags,
    9102             :                           arraysize(flags));
    9103           5 : }
    9104             : 
    9105       26644 : TEST(ImportMetaFailure) {
    9106             :   // clang-format off
    9107             :   const char* context_data[][2] = {
    9108             :     {"var ", ""},
    9109             :     {"let ", ""},
    9110             :     {"const ", ""},
    9111             :     {"var [", "] = [1]"},
    9112             :     {"([", "] = [1])"},
    9113             :     {"({", "} = {1})"},
    9114             :     {"var {", " = 1} = 1"},
    9115             :     {"for (var ", " of [1]) {}"},
    9116             :     {"(", ") => {}"},
    9117             :     {"let f = ", " => {}"},
    9118             :     {nullptr}
    9119           5 :   };
    9120             : 
    9121             :   const char* data[] = {
    9122             :     "import.meta",
    9123             :     nullptr
    9124           5 :   };
    9125             : 
    9126             :   // clang-format on
    9127             : 
    9128             :   static const ParserFlag flags[] = {
    9129             :       kAllowHarmonyImportMeta, kAllowHarmonyDynamicImport,
    9130             :   };
    9131             : 
    9132             :   RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    9133           5 :                     arraysize(flags));
    9134             :   RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    9135             :                           arraysize(flags));
    9136             : 
    9137             :   RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
    9138             :                           nullptr, 0, true, true);
    9139           5 :   RunParserSyncTest(context_data, data, kError);
    9140           5 : }
    9141             : 
    9142       26644 : TEST(ConstSloppy) {
    9143             :   // clang-format off
    9144             :   const char* context_data[][2] = {
    9145             :     {"", ""},
    9146             :     {"{", "}"},
    9147             :     {nullptr, nullptr}
    9148           5 :   };
    9149             : 
    9150             :   const char* data[] = {
    9151             :     "const x = 1",
    9152             :     "for (const x = 1; x < 1; x++) {}",
    9153             :     "for (const x in {}) {}",
    9154             :     "for (const x of []) {}",
    9155             :     nullptr
    9156           5 :   };
    9157             :   // clang-format on
    9158           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9159           5 : }
    9160             : 
    9161             : 
    9162       26644 : TEST(LetSloppy) {
    9163             :   // clang-format off
    9164             :   const char* context_data[][2] = {
    9165             :     {"", ""},
    9166             :     {"'use strict';", ""},
    9167             :     {"{", "}"},
    9168             :     {nullptr, nullptr}
    9169           5 :   };
    9170             : 
    9171             :   const char* data[] = {
    9172             :     "let x",
    9173             :     "let x = 1",
    9174             :     "for (let x = 1; x < 1; x++) {}",
    9175             :     "for (let x in {}) {}",
    9176             :     "for (let x of []) {}",
    9177             :     nullptr
    9178           5 :   };
    9179             :   // clang-format on
    9180             : 
    9181           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9182           5 : }
    9183             : 
    9184             : 
    9185       26644 : TEST(LanguageModeDirectivesNonSimpleParameterListErrors) {
    9186             :   // TC39 deemed "use strict" directives to be an error when occurring in the
    9187             :   // body of a function with non-simple parameter list, on 29/7/2015.
    9188             :   // https://goo.gl/ueA7Ln
    9189             :   const char* context_data[][2] = {
    9190             :       {"function f(", ") { 'use strict'; }"},
    9191             :       {"function* g(", ") { 'use strict'; }"},
    9192             :       {"class c { foo(", ") { 'use strict' }"},
    9193             :       {"var a = (", ") => { 'use strict'; }"},
    9194             :       {"var o = { m(", ") { 'use strict'; }"},
    9195             :       {"var o = { *gm(", ") { 'use strict'; }"},
    9196             :       {"var c = { m(", ") { 'use strict'; }"},
    9197             :       {"var c = { *gm(", ") { 'use strict'; }"},
    9198             : 
    9199             :       {"'use strict'; function f(", ") { 'use strict'; }"},
    9200             :       {"'use strict'; function* g(", ") { 'use strict'; }"},
    9201             :       {"'use strict'; class c { foo(", ") { 'use strict' }"},
    9202             :       {"'use strict'; var a = (", ") => { 'use strict'; }"},
    9203             :       {"'use strict'; var o = { m(", ") { 'use strict'; }"},
    9204             :       {"'use strict'; var o = { *gm(", ") { 'use strict'; }"},
    9205             :       {"'use strict'; var c = { m(", ") { 'use strict'; }"},
    9206             :       {"'use strict'; var c = { *gm(", ") { 'use strict'; }"},
    9207             : 
    9208           5 :       {nullptr, nullptr}};
    9209             : 
    9210             :   const char* data[] = {
    9211             :       // TODO(@caitp): support formal parameter initializers
    9212             :       "{}",
    9213             :       "[]",
    9214             :       "[{}]",
    9215             :       "{a}",
    9216             :       "a, {b}",
    9217             :       "a, b, {c, d, e}",
    9218             :       "initializer = true",
    9219             :       "a, b, c = 1",
    9220             :       "...args",
    9221             :       "a, b, ...rest",
    9222             :       "[a, b, ...rest]",
    9223             :       "{ bindingPattern = {} }",
    9224             :       "{ initializedBindingPattern } = { initializedBindingPattern: true }",
    9225           5 :       nullptr};
    9226             : 
    9227           5 :   RunParserSyncTest(context_data, data, kError);
    9228           5 : }
    9229             : 
    9230             : 
    9231       26644 : TEST(LetSloppyOnly) {
    9232             :   // clang-format off
    9233             :   const char* context_data[][2] = {
    9234             :     {"", ""},
    9235             :     {"{", "}"},
    9236             :     {"(function() {", "})()"},
    9237             :     {nullptr, nullptr}
    9238           5 :   };
    9239             : 
    9240             :   const char* data[] = {
    9241             :     "let",
    9242             :     "let = 1",
    9243             :     "for (let = 1; let < 1; let++) {}",
    9244             :     "for (let in {}) {}",
    9245             :     "for (var let = 1; let < 1; let++) {}",
    9246             :     "for (var let in {}) {}",
    9247             :     "for (var [let] = 1; let < 1; let++) {}",
    9248             :     "for (var [let] in {}) {}",
    9249             :     "var let",
    9250             :     "var [let] = []",
    9251             :     nullptr
    9252           5 :   };
    9253             :   // clang-format on
    9254             : 
    9255           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9256             : 
    9257             :   // Some things should be rejected even in sloppy mode
    9258             :   // This addresses BUG(v8:4403).
    9259             : 
    9260             :   // clang-format off
    9261             :   const char* fail_data[] = {
    9262             :     "let let = 1",
    9263             :     "for (let let = 1; let < 1; let++) {}",
    9264             :     "for (let let in {}) {}",
    9265             :     "for (let let of []) {}",
    9266             :     "const let = 1",
    9267             :     "for (const let = 1; let < 1; let++) {}",
    9268             :     "for (const let in {}) {}",
    9269             :     "for (const let of []) {}",
    9270             :     "let [let] = 1",
    9271             :     "for (let [let] = 1; let < 1; let++) {}",
    9272             :     "for (let [let] in {}) {}",
    9273             :     "for (let [let] of []) {}",
    9274             :     "const [let] = 1",
    9275             :     "for (const [let] = 1; let < 1; let++) {}",
    9276             :     "for (const [let] in {}) {}",
    9277             :     "for (const [let] of []) {}",
    9278             : 
    9279             :     // Sprinkle in the escaped version too.
    9280             :     "let l\\u0065t = 1",
    9281             :     "const l\\u0065t = 1",
    9282             :     "let [l\\u0065t] = 1",
    9283             :     "const [l\\u0065t] = 1",
    9284             :     "for (let l\\u0065t in {}) {}",
    9285             :     nullptr
    9286           5 :   };
    9287             :   // clang-format on
    9288             : 
    9289           5 :   RunParserSyncTest(context_data, fail_data, kError);
    9290           5 : }
    9291             : 
    9292             : 
    9293       26644 : TEST(EscapedKeywords) {
    9294             :   // clang-format off
    9295             :   const char* sloppy_context_data[][2] = {
    9296             :     {"", ""},
    9297             :     {nullptr, nullptr}
    9298           5 :   };
    9299             : 
    9300             :   const char* strict_context_data[][2] = {
    9301             :     {"'use strict';", ""},
    9302             :     {nullptr, nullptr}
    9303           5 :   };
    9304             : 
    9305             :   const char* fail_data[] = {
    9306             :     "for (var i = 0; i < 100; ++i) { br\\u0065ak; }",
    9307             :     "cl\\u0061ss Foo {}",
    9308             :     "var x = cl\\u0061ss {}",
    9309             :     "\\u0063onst foo = 1;",
    9310             :     "while (i < 10) { if (i++ & 1) c\\u006fntinue; this.x++; }",
    9311             :     "d\\u0065bugger;",
    9312             :     "d\\u0065lete this.a;",
    9313             :     "\\u0063o { } while(0)",
    9314             :     "if (d\\u006f { true }) {}",
    9315             :     "if (false) { this.a = 1; } \\u0065lse { this.b = 1; }",
    9316             :     "e\\u0078port var foo;",
    9317             :     "try { } catch (e) {} f\\u0069nally { }",
    9318             :     "f\\u006fr (var i = 0; i < 10; ++i);",
    9319             :     "f\\u0075nction fn() {}",
    9320             :     "var f = f\\u0075nction() {}",
    9321             :     "\\u0069f (true) { }",
    9322             :     "\\u0069mport blah from './foo.js';",
    9323             :     "n\\u0065w function f() {}",
    9324             :     "(function() { r\\u0065turn; })()",
    9325             :     "class C extends function() {} { constructor() { sup\\u0065r() } }",
    9326             :     "class C extends function() {} { constructor() { sup\\u0065r.a = 1 } }",
    9327             :     "sw\\u0069tch (this.a) {}",
    9328             :     "var x = th\\u0069s;",
    9329             :     "th\\u0069s.a = 1;",
    9330             :     "thr\\u006fw 'boo';",
    9331             :     "t\\u0072y { true } catch (e) {}",
    9332             :     "var x = typ\\u0065of 'blah'",
    9333             :     "v\\u0061r a = true",
    9334             :     "var v\\u0061r = true",
    9335             :     "(function() { return v\\u006fid 0; })()",
    9336             :     "wh\\u0069le (true) { }",
    9337             :     "w\\u0069th (this.scope) { }",
    9338             :     "(function*() { y\\u0069eld 1; })()",
    9339             :     "(function*() { var y\\u0069eld = 1; })()",
    9340             : 
    9341             :     "var \\u0065num = 1;",
    9342             :     "var { \\u0065num } = {}",
    9343             :     "(\\u0065num = 1);",
    9344             : 
    9345             :     // Null / Boolean literals
    9346             :     "(x === n\\u0075ll);",
    9347             :     "var x = n\\u0075ll;",
    9348             :     "var n\\u0075ll = 1;",
    9349             :     "var { n\\u0075ll } = { 1 };",
    9350             :     "n\\u0075ll = 1;",
    9351             :     "(x === tr\\u0075e);",
    9352             :     "var x = tr\\u0075e;",
    9353             :     "var tr\\u0075e = 1;",
    9354             :     "var { tr\\u0075e } = {};",
    9355             :     "tr\\u0075e = 1;",
    9356             :     "(x === f\\u0061lse);",
    9357             :     "var x = f\\u0061lse;",
    9358             :     "var f\\u0061lse = 1;",
    9359             :     "var { f\\u0061lse } = {};",
    9360             :     "f\\u0061lse = 1;",
    9361             : 
    9362             :     // TODO(caitp): consistent error messages for labeled statements and
    9363             :     // expressions
    9364             :     "switch (this.a) { c\\u0061se 6: break; }",
    9365             :     "try { } c\\u0061tch (e) {}",
    9366             :     "switch (this.a) { d\\u0065fault: break; }",
    9367             :     "class C \\u0065xtends function B() {} {}",
    9368             :     "for (var a i\\u006e this) {}",
    9369             :     "if ('foo' \\u0069n this) {}",
    9370             :     "if (this \\u0069nstanceof Array) {}",
    9371             :     "(n\\u0065w function f() {})",
    9372             :     "(typ\\u0065of 123)",
    9373             :     "(v\\u006fid 0)",
    9374             :     "do { ; } wh\\u0069le (true) { }",
    9375             :     "(function*() { return (n++, y\\u0069eld 1); })()",
    9376             :     "class C { st\\u0061tic bar() {} }",
    9377             :     "class C { st\\u0061tic *bar() {} }",
    9378             :     "class C { st\\u0061tic get bar() {} }",
    9379             :     "class C { st\\u0061tic set bar() {} }",
    9380             :     "(async ()=>{\\u0061wait 100})()",
    9381             :     "({\\u0067et get(){}})",
    9382             :     "({\\u0073et set(){}})",
    9383             :     "(async ()=>{var \\u0061wait = 100})()",
    9384             :     nullptr
    9385           5 :   };
    9386             :   // clang-format on
    9387             : 
    9388           5 :   RunParserSyncTest(sloppy_context_data, fail_data, kError);
    9389           5 :   RunParserSyncTest(strict_context_data, fail_data, kError);
    9390             :   RunModuleParserSyncTest(sloppy_context_data, fail_data, kError);
    9391             : 
    9392             :   // clang-format off
    9393             :   const char* let_data[] = {
    9394             :     "var l\\u0065t = 1;",
    9395             :     "l\\u0065t = 1;",
    9396             :     "(l\\u0065t === 1);",
    9397             :     "(y\\u0069eld);",
    9398             :     "var y\\u0069eld = 1;",
    9399             :     "var { y\\u0069eld } = {};",
    9400             :     nullptr
    9401           5 :   };
    9402             :   // clang-format on
    9403             : 
    9404           5 :   RunParserSyncTest(sloppy_context_data, let_data, kSuccess);
    9405           5 :   RunParserSyncTest(strict_context_data, let_data, kError);
    9406             : 
    9407             :   // Non-errors in sloppy mode
    9408             :   const char* valid_data[] = {"(\\u0069mplements = 1);",
    9409             :                               "var impl\\u0065ments = 1;",
    9410             :                               "var { impl\\u0065ments  } = {};",
    9411             :                               "(\\u0069nterface = 1);",
    9412             :                               "var int\\u0065rface = 1;",
    9413             :                               "var { int\\u0065rface  } = {};",
    9414             :                               "(p\\u0061ckage = 1);",
    9415             :                               "var packa\\u0067e = 1;",
    9416             :                               "var { packa\\u0067e  } = {};",
    9417             :                               "(p\\u0072ivate = 1);",
    9418             :                               "var p\\u0072ivate;",
    9419             :                               "var { p\\u0072ivate } = {};",
    9420             :                               "(prot\\u0065cted);",
    9421             :                               "var prot\\u0065cted = 1;",
    9422             :                               "var { prot\\u0065cted  } = {};",
    9423             :                               "(publ\\u0069c);",
    9424             :                               "var publ\\u0069c = 1;",
    9425             :                               "var { publ\\u0069c } = {};",
    9426             :                               "(st\\u0061tic);",
    9427             :                               "var st\\u0061tic = 1;",
    9428             :                               "var { st\\u0061tic } = {};",
    9429           5 :                               nullptr};
    9430           5 :   RunParserSyncTest(sloppy_context_data, valid_data, kSuccess);
    9431           5 :   RunParserSyncTest(strict_context_data, valid_data, kError);
    9432             :   RunModuleParserSyncTest(strict_context_data, valid_data, kError);
    9433           5 : }
    9434             : 
    9435             : 
    9436       26644 : TEST(MiscSyntaxErrors) {
    9437             :   // clang-format off
    9438             :   const char* context_data[][2] = {
    9439             :     { "'use strict'", "" },
    9440             :     { "", "" },
    9441             :     { nullptr, nullptr }
    9442           5 :   };
    9443             :   const char* error_data[] = {
    9444             :     "for (();;) {}",
    9445             : 
    9446             :     // crbug.com/582626
    9447             :     "{ NaN ,chA((evarA=new t ( l = !.0[((... co -a0([1]))=> greturnkf",
    9448             :     nullptr
    9449           5 :   };
    9450             :   // clang-format on
    9451             : 
    9452           5 :   RunParserSyncTest(context_data, error_data, kError);
    9453           5 : }
    9454             : 
    9455             : 
    9456       26644 : TEST(EscapeSequenceErrors) {
    9457             :   // clang-format off
    9458             :   const char* context_data[][2] = {
    9459             :     { "'", "'" },
    9460             :     { "\"", "\"" },
    9461             :     { "`", "`" },
    9462             :     { "`${'", "'}`" },
    9463             :     { "`${\"", "\"}`" },
    9464             :     { "`${`", "`}`" },
    9465             :     { nullptr, nullptr }
    9466           5 :   };
    9467             :   const char* error_data[] = {
    9468             :     "\\uABCG",
    9469             :     "\\u{ZZ}",
    9470             :     "\\u{FFZ}",
    9471             :     "\\u{FFFFFFFFFF }",
    9472             :     "\\u{110000}",
    9473             :     "\\u{110000",
    9474             :     "\\u{FFFD }",
    9475             :     "\\xZF",
    9476             :     nullptr
    9477           5 :   };
    9478             :   // clang-format on
    9479             : 
    9480           5 :   RunParserSyncTest(context_data, error_data, kError);
    9481           5 : }
    9482             : 
    9483       26644 : TEST(NewTargetErrors) {
    9484             :   // clang-format off
    9485             :   const char* context_data[][2] = {
    9486             :     { "'use strict'", "" },
    9487             :     { "", "" },
    9488             :     { nullptr, nullptr }
    9489           5 :   };
    9490             :   const char* error_data[] = {
    9491             :     "var x = new.target",
    9492             :     "function f() { return new.t\\u0061rget; }",
    9493             :     nullptr
    9494           5 :   };
    9495             :   // clang-format on
    9496           5 :   RunParserSyncTest(context_data, error_data, kError);
    9497           5 : }
    9498             : 
    9499       26644 : TEST(FunctionDeclarationError) {
    9500             :   // clang-format off
    9501             :   const char* strict_context[][2] = {
    9502             :     { "'use strict';", "" },
    9503             :     { "'use strict'; { ", "}" },
    9504             :     {"(function() { 'use strict';", "})()"},
    9505             :     {"(function() { 'use strict'; {", "} })()"},
    9506             :     { nullptr, nullptr }
    9507           5 :   };
    9508             :   const char* sloppy_context[][2] = {
    9509             :     { "", "" },
    9510             :     { "{", "}" },
    9511             :     {"(function() {", "})()"},
    9512             :     {"(function() { {", "} })()"},
    9513             :     { nullptr, nullptr }
    9514           5 :   };
    9515             :   // Invalid in all contexts
    9516             :   const char* error_data[] = {
    9517             :     "try function foo() {} catch (e) {}",
    9518             :     "do function foo() {} while (0);",
    9519             :     "for (;false;) function foo() {}",
    9520             :     "for (var i = 0; i < 1; i++) function f() { };",
    9521             :     "for (var x in {a: 1}) function f() { };",
    9522             :     "for (var x in {}) function f() { };",
    9523             :     "for (var x in {}) function foo() {}",
    9524             :     "for (x in {a: 1}) function f() { };",
    9525             :     "for (x in {}) function f() { };",
    9526             :     "var x; for (x in {}) function foo() {}",
    9527             :     "with ({}) function f() { };",
    9528             :     "do label: function foo() {} while (0);",
    9529             :     "for (;false;) label: function foo() {}",
    9530             :     "for (var i = 0; i < 1; i++) label: function f() { };",
    9531             :     "for (var x in {a: 1}) label: function f() { };",
    9532             :     "for (var x in {}) label: function f() { };",
    9533             :     "for (var x in {}) label: function foo() {}",
    9534             :     "for (x in {a: 1}) label: function f() { };",
    9535             :     "for (x in {}) label: function f() { };",
    9536             :     "var x; for (x in {}) label: function foo() {}",
    9537             :     "with ({}) label: function f() { };",
    9538             :     "if (true) label: function f() {}",
    9539             :     "if (true) {} else label: function f() {}",
    9540             :     "if (true) function* f() { }",
    9541             :     "label: function* f() { }",
    9542             :     "if (true) async function f() { }",
    9543             :     "label: async function f() { }",
    9544             :     "if (true) async function* f() { }",
    9545             :     "label: async function* f() { }",
    9546             :     nullptr
    9547           5 :   };
    9548             :   // Valid only in sloppy mode.
    9549             :   const char* sloppy_data[] = {
    9550             :     "if (true) function foo() {}",
    9551             :     "if (false) {} else function f() { };",
    9552             :     "label: function f() { }",
    9553             :     "label: if (true) function f() { }",
    9554             :     "label: if (true) {} else function f() { }",
    9555             :     "label: label2: function f() { }",
    9556             :     nullptr
    9557           5 :   };
    9558             :   // clang-format on
    9559             : 
    9560             :   // Nothing parses in strict mode without a SyntaxError
    9561           5 :   RunParserSyncTest(strict_context, error_data, kError);
    9562           5 :   RunParserSyncTest(strict_context, sloppy_data, kError);
    9563             : 
    9564             :   // In sloppy mode, sloppy_data is successful
    9565           5 :   RunParserSyncTest(sloppy_context, error_data, kError);
    9566           5 :   RunParserSyncTest(sloppy_context, sloppy_data, kSuccess);
    9567           5 : }
    9568             : 
    9569       26644 : TEST(ExponentiationOperator) {
    9570             :   // clang-format off
    9571             :   const char* context_data[][2] = {
    9572             :     { "var O = { p: 1 }, x = 10; ; if (", ") { foo(); }" },
    9573             :     { "var O = { p: 1 }, x = 10; ; (", ")" },
    9574             :     { "var O = { p: 1 }, x = 10; foo(", ")" },
    9575             :     { nullptr, nullptr }
    9576           5 :   };
    9577             :   const char* data[] = {
    9578             :     "(delete O.p) ** 10",
    9579             :     "(delete x) ** 10",
    9580             :     "(~O.p) ** 10",
    9581             :     "(~x) ** 10",
    9582             :     "(!O.p) ** 10",
    9583             :     "(!x) ** 10",
    9584             :     "(+O.p) ** 10",
    9585             :     "(+x) ** 10",
    9586             :     "(-O.p) ** 10",
    9587             :     "(-x) ** 10",
    9588             :     "(typeof O.p) ** 10",
    9589             :     "(typeof x) ** 10",
    9590             :     "(void 0) ** 10",
    9591             :     "(void O.p) ** 10",
    9592             :     "(void x) ** 10",
    9593             :     "++O.p ** 10",
    9594             :     "++x ** 10",
    9595             :     "--O.p ** 10",
    9596             :     "--x ** 10",
    9597             :     "O.p++ ** 10",
    9598             :     "x++ ** 10",
    9599             :     "O.p-- ** 10",
    9600             :     "x-- ** 10",
    9601             :     nullptr
    9602           5 :   };
    9603             :   // clang-format on
    9604             : 
    9605           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9606           5 : }
    9607             : 
    9608       26644 : TEST(ExponentiationOperatorErrors) {
    9609             :   // clang-format off
    9610             :   const char* context_data[][2] = {
    9611             :     { "var O = { p: 1 }, x = 10; ; if (", ") { foo(); }" },
    9612             :     { "var O = { p: 1 }, x = 10; ; (", ")" },
    9613             :     { "var O = { p: 1 }, x = 10; foo(", ")" },
    9614             :     { nullptr, nullptr }
    9615           5 :   };
    9616             :   const char* error_data[] = {
    9617             :     "delete O.p ** 10",
    9618             :     "delete x ** 10",
    9619             :     "~O.p ** 10",
    9620             :     "~x ** 10",
    9621             :     "!O.p ** 10",
    9622             :     "!x ** 10",
    9623             :     "+O.p ** 10",
    9624             :     "+x ** 10",
    9625             :     "-O.p ** 10",
    9626             :     "-x ** 10",
    9627             :     "typeof O.p ** 10",
    9628             :     "typeof x ** 10",
    9629             :     "void ** 10",
    9630             :     "void O.p ** 10",
    9631             :     "void x ** 10",
    9632             :     "++delete O.p ** 10",
    9633             :     "--delete O.p ** 10",
    9634             :     "++~O.p ** 10",
    9635             :     "++~x ** 10",
    9636             :     "--!O.p ** 10",
    9637             :     "--!x ** 10",
    9638             :     "++-O.p ** 10",
    9639             :     "++-x ** 10",
    9640             :     "--+O.p ** 10",
    9641             :     "--+x ** 10",
    9642             :     "[ x ] **= [ 2 ]",
    9643             :     "[ x **= 2 ] = [ 2 ]",
    9644             :     "{ x } **= { x: 2 }",
    9645             :     "{ x: x **= 2 ] = { x: 2 }",
    9646             :     // TODO(caitp): a Call expression as LHS should be an early ReferenceError!
    9647             :     // "Array() **= 10",
    9648             :     nullptr
    9649           5 :   };
    9650             :   // clang-format on
    9651             : 
    9652           5 :   RunParserSyncTest(context_data, error_data, kError);
    9653           5 : }
    9654             : 
    9655       26644 : TEST(AsyncAwait) {
    9656             :   // clang-format off
    9657             :   const char* context_data[][2] = {
    9658             :     { "'use strict';", "" },
    9659             :     { "", "" },
    9660             :     { nullptr, nullptr }
    9661           5 :   };
    9662             : 
    9663             :   const char* data[] = {
    9664             :     "var asyncFn = async function() { await 1; };",
    9665             :     "var asyncFn = async function withName() { await 1; };",
    9666             :     "var asyncFn = async () => await 'test';",
    9667             :     "var asyncFn = async x => await x + 'test';",
    9668             :     "async function asyncFn() { await 1; }",
    9669             :     "var O = { async method() { await 1; } }",
    9670             :     "var O = { async ['meth' + 'od']() { await 1; } }",
    9671             :     "var O = { async 'method'() { await 1; } }",
    9672             :     "var O = { async 0() { await 1; } }",
    9673             :     "async function await() {}",
    9674             : 
    9675             :     "var asyncFn = async({ foo = 1 }) => foo;",
    9676             :     "var asyncFn = async({ foo = 1 } = {}) => foo;",
    9677             : 
    9678             :     "function* g() { var f = async(yield); }",
    9679             :     "function* g() { var f = async(x = yield); }",
    9680             : 
    9681             :     // v8:7817 assert that `await` is still allowed in the body of an arrow fn
    9682             :     // within formal parameters
    9683             :     "async(a = a => { var await = 1; return 1; }) => a()",
    9684             :     "async(a = await => 1); async(a) => 1",
    9685             :     "(async(a = await => 1), async(a) => 1)",
    9686             :     "async(a = await => 1, b = async() => 1);",
    9687             : 
    9688             :     nullptr
    9689           5 :   };
    9690             :   // clang-format on
    9691             : 
    9692           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9693             : 
    9694             :   // clang-format off
    9695             :   const char* async_body_context_data[][2] = {
    9696             :     { "async function f() {", "}" },
    9697             :     { "var f = async function() {", "}" },
    9698             :     { "var f = async() => {", "}" },
    9699             :     { "var O = { async method() {", "} }" },
    9700             :     { "'use strict'; async function f() {", "}" },
    9701             :     { "'use strict'; var f = async function() {", "}" },
    9702             :     { "'use strict'; var f = async() => {", "}" },
    9703             :     { "'use strict'; var O = { async method() {", "} }" },
    9704             :     { nullptr, nullptr }
    9705           5 :   };
    9706             : 
    9707             :   const char* body_context_data[][2] = {
    9708             :     { "function f() {", "}" },
    9709             :     { "function* g() {", "}" },
    9710             :     { "var f = function() {", "}" },
    9711             :     { "var g = function*() {", "}" },
    9712             :     { "var O = { method() {", "} }" },
    9713             :     { "var O = { *method() {", "} }" },
    9714             :     { "var f = () => {", "}" },
    9715             :     { "'use strict'; function f() {", "}" },
    9716             :     { "'use strict'; function* g() {", "}" },
    9717             :     { "'use strict'; var f = function() {", "}" },
    9718             :     { "'use strict'; var g = function*() {", "}" },
    9719             :     { "'use strict'; var O = { method() {", "} }" },
    9720             :     { "'use strict'; var O = { *method() {", "} }" },
    9721             :     { "'use strict'; var f = () => {", "}" },
    9722             :     { nullptr, nullptr }
    9723           5 :   };
    9724             : 
    9725             :   const char* body_data[] = {
    9726             :     "var async = 1; return async;",
    9727             :     "let async = 1; return async;",
    9728             :     "const async = 1; return async;",
    9729             :     "function async() {} return async();",
    9730             :     "var async = async => async; return async();",
    9731             :     "function foo() { var await = 1; return await; }",
    9732             :     "function foo(await) { return await; }",
    9733             :     "function* foo() { var await = 1; return await; }",
    9734             :     "function* foo(await) { return await; }",
    9735             :     "var f = () => { var await = 1; return await; }",
    9736             :     "var O = { method() { var await = 1; return await; } };",
    9737             :     "var O = { method(await) { return await; } };",
    9738             :     "var O = { *method() { var await = 1; return await; } };",
    9739             :     "var O = { *method(await) { return await; } };",
    9740             :     "var asyncFn = async function*() {}",
    9741             :     "async function* f() {}",
    9742             :     "var O = { async *method() {} };",
    9743             : 
    9744             :     "(function await() {})",
    9745             :     nullptr
    9746           5 :   };
    9747             :   // clang-format on
    9748             : 
    9749           5 :   RunParserSyncTest(async_body_context_data, body_data, kSuccess);
    9750           5 :   RunParserSyncTest(body_context_data, body_data, kSuccess);
    9751           5 : }
    9752             : 
    9753       26644 : TEST(AsyncAwaitErrors) {
    9754             :   // clang-format off
    9755             :   const char* context_data[][2] = {
    9756             :     { "'use strict';", "" },
    9757             :     { "", "" },
    9758             :     { nullptr, nullptr }
    9759           5 :   };
    9760             : 
    9761             :   const char* strict_context_data[][2] = {
    9762             :     { "'use strict';", "" },
    9763             :     { nullptr, nullptr }
    9764           5 :   };
    9765             : 
    9766             :   const char* error_data[] = {
    9767             :     "var asyncFn = async function await() {};",
    9768             :     "var asyncFn = async () => var await = 'test';",
    9769             :     "var asyncFn = async await => await + 'test';",
    9770             :     "var asyncFn = async function(await) {};",
    9771             :     "var asyncFn = async (await) => 'test';",
    9772             :     "async function f(await) {}",
    9773             : 
    9774             :     "var O = { async method(a, a) {} }",
    9775             :     "var O = { async ['meth' + 'od'](a, a) {} }",
    9776             :     "var O = { async 'method'(a, a) {} }",
    9777             :     "var O = { async 0(a, a) {} }",
    9778             : 
    9779             :     "var f = async() => await;",
    9780             : 
    9781             :     "var O = { *async method() {} };",
    9782             :     "var O = { async method*() {} };",
    9783             : 
    9784             :     "var asyncFn = async function(x = await 1) { return x; }",
    9785             :     "async function f(x = await 1) { return x; }",
    9786             :     "var f = async(x = await 1) => x;",
    9787             :     "var O = { async method(x = await 1) { return x; } };",
    9788             : 
    9789             :     "function* g() { var f = async yield => 1; }",
    9790             :     "function* g() { var f = async(yield) => 1; }",
    9791             :     "function* g() { var f = async(x = yield) => 1; }",
    9792             :     "function* g() { var f = async({x = yield}) => 1; }",
    9793             : 
    9794             :     "class C { async constructor() {} }",
    9795             :     "class C {}; class C2 extends C { async constructor() {} }",
    9796             :     "class C { static async prototype() {} }",
    9797             :     "class C {}; class C2 extends C { static async prototype() {} }",
    9798             : 
    9799             :     "var f = async() => ((async(x = await 1) => x)();",
    9800             : 
    9801             :     // Henrique Ferreiro's bug (tm)
    9802             :     "(async function foo1() { } foo2 => 1)",
    9803             :     "(async function foo3() { } () => 1)",
    9804             :     "(async function foo4() { } => 1)",
    9805             :     "(async function() { } foo5 => 1)",
    9806             :     "(async function() { } () => 1)",
    9807             :     "(async function() { } => 1)",
    9808             :     "(async.foo6 => 1)",
    9809             :     "(async.foo7 foo8 => 1)",
    9810             :     "(async.foo9 () => 1)",
    9811             :     "(async().foo10 => 1)",
    9812             :     "(async().foo11 foo12 => 1)",
    9813             :     "(async().foo13 () => 1)",
    9814             :     "(async['foo14'] => 1)",
    9815             :     "(async['foo15'] foo16 => 1)",
    9816             :     "(async['foo17'] () => 1)",
    9817             :     "(async()['foo18'] => 1)",
    9818             :     "(async()['foo19'] foo20 => 1)",
    9819             :     "(async()['foo21'] () => 1)",
    9820             :     "(async`foo22` => 1)",
    9821             :     "(async`foo23` foo24 => 1)",
    9822             :     "(async`foo25` () => 1)",
    9823             :     "(async`foo26`.bar27 => 1)",
    9824             :     "(async`foo28`.bar29 foo30 => 1)",
    9825             :     "(async`foo31`.bar32 () => 1)",
    9826             : 
    9827             :     // v8:5148 assert that errors are still thrown for calls that may have been
    9828             :     // async functions
    9829             :     "async({ foo33 = 1 })",
    9830             : 
    9831             :     "async(...a = b) => b",
    9832             :     "async(...a,) => b",
    9833             :     "async(...a, b) => b",
    9834             : 
    9835             :     // v8:7817 assert that `await` is an invalid identifier in arrow formal
    9836             :     // parameters nested within an async arrow function
    9837             :     "async(a = await => 1) => a",
    9838             :     "async(a = (await) => 1) => a",
    9839             :     "async(a = (...await) => 1) => a",
    9840             :     nullptr
    9841           5 :   };
    9842             : 
    9843             :   const char* strict_error_data[] = {
    9844             :     "var O = { async method(eval) {} }",
    9845             :     "var O = { async ['meth' + 'od'](eval) {} }",
    9846             :     "var O = { async 'method'(eval) {} }",
    9847             :     "var O = { async 0(eval) {} }",
    9848             : 
    9849             :     "var O = { async method(arguments) {} }",
    9850             :     "var O = { async ['meth' + 'od'](arguments) {} }",
    9851             :     "var O = { async 'method'(arguments) {} }",
    9852             :     "var O = { async 0(arguments) {} }",
    9853             : 
    9854             :     "var O = { async method(dupe, dupe) {} }",
    9855             : 
    9856             :     // TODO(caitp): preparser needs to report duplicate parameter errors, too.
    9857             :     // "var f = async(dupe, dupe) => {}",
    9858             : 
    9859             :     nullptr
    9860           5 :   };
    9861             : 
    9862           5 :   RunParserSyncTest(context_data, error_data, kError);
    9863           5 :   RunParserSyncTest(strict_context_data, strict_error_data, kError);
    9864             : 
    9865             :   // clang-format off
    9866             :   const char* async_body_context_data[][2] = {
    9867             :     { "async function f() {", "}" },
    9868             :     { "var f = async function() {", "}" },
    9869             :     { "var f = async() => {", "}" },
    9870             :     { "var O = { async method() {", "} }" },
    9871             :     { "'use strict'; async function f() {", "}" },
    9872             :     { "'use strict'; var f = async function() {", "}" },
    9873             :     { "'use strict'; var f = async() => {", "}" },
    9874             :     { "'use strict'; var O = { async method() {", "} }" },
    9875             :     { nullptr, nullptr }
    9876           5 :   };
    9877             : 
    9878             :   const char* async_body_error_data[] = {
    9879             :     "var await = 1;",
    9880             :     "var { await } = 1;",
    9881             :     "var [ await ] = 1;",
    9882             :     "return async (await) => {};",
    9883             :     "var O = { async [await](a, a) {} }",
    9884             :     "await;",
    9885             : 
    9886             :     "function await() {}",
    9887             : 
    9888             :     "var f = await => 42;",
    9889             :     "var f = (await) => 42;",
    9890             :     "var f = (await, a) => 42;",
    9891             :     "var f = (...await) => 42;",
    9892             : 
    9893             :     "var e = (await);",
    9894             :     "var e = (await, f);",
    9895             :     "var e = (await = 42)",
    9896             : 
    9897             :     "var e = [await];",
    9898             :     "var e = {await};",
    9899             : 
    9900             :     nullptr
    9901           5 :   };
    9902             :   // clang-format on
    9903             : 
    9904           5 :   RunParserSyncTest(async_body_context_data, async_body_error_data, kError);
    9905           5 : }
    9906             : 
    9907       26644 : TEST(Regress7173) {
    9908             :   // Await expression is an invalid destructuring target, and should not crash
    9909             : 
    9910             :   // clang-format off
    9911             :   const char* error_context_data[][2] = {
    9912             :     { "'use strict'; async function f() {", "}" },
    9913             :     { "async function f() {", "}" },
    9914             :     { "'use strict'; function f() {", "}" },
    9915             :     { "function f() {", "}" },
    9916             :     { "let f = async() => {", "}" },
    9917             :     { "let f = () => {", "}" },
    9918             :     { "'use strict'; async function* f() {", "}" },
    9919             :     { "async function* f() {", "}" },
    9920             :     { "'use strict'; function* f() {", "}" },
    9921             :     { "function* f() {", "}" },
    9922             :     { nullptr, nullptr }
    9923           5 :   };
    9924             : 
    9925             :   const char* error_data[] = {
    9926             :     "var [await f] = [];",
    9927             :     "let [await f] = [];",
    9928             :     "const [await f] = [];",
    9929             : 
    9930             :     "var [...await f] = [];",
    9931             :     "let [...await f] = [];",
    9932             :     "const [...await f] = [];",
    9933             : 
    9934             :     "var { await f } = {};",
    9935             :     "let { await f } = {};",
    9936             :     "const { await f } = {};",
    9937             : 
    9938             :     "var { ...await f } = {};",
    9939             :     "let { ...await f } = {};",
    9940             :     "const { ...await f } = {};",
    9941             : 
    9942             :     "var { f: await f } = {};",
    9943             :     "let { f: await f } = {};",
    9944             :     "const { f: await f } = {};"
    9945             : 
    9946             :     "var { f: ...await f } = {};",
    9947             :     "let { f: ...await f } = {};",
    9948             :     "const { f: ...await f } = {};"
    9949             : 
    9950             :     "var { [f]: await f } = {};",
    9951             :     "let { [f]: await f } = {};",
    9952             :     "const { [f]: await f } = {};",
    9953             : 
    9954             :     "var { [f]: ...await f } = {};",
    9955             :     "let { [f]: ...await f } = {};",
    9956             :     "const { [f]: ...await f } = {};",
    9957             : 
    9958             :     nullptr
    9959           5 :   };
    9960             :   // clang-format on
    9961             : 
    9962           5 :   RunParserSyncTest(error_context_data, error_data, kError);
    9963           5 : }
    9964             : 
    9965       26644 : TEST(AsyncAwaitFormalParameters) {
    9966             :   // clang-format off
    9967             :   const char* context_for_formal_parameters[][2] = {
    9968             :     { "async function f(", ") {}" },
    9969             :     { "var f = async function f(", ") {}" },
    9970             :     { "var f = async(", ") => {}" },
    9971             :     { "'use strict'; async function f(", ") {}" },
    9972             :     { "'use strict'; var f = async function f(", ") {}" },
    9973             :     { "'use strict'; var f = async(", ") => {}" },
    9974             :     { nullptr, nullptr }
    9975           5 :   };
    9976             : 
    9977             :   const char* good_formal_parameters[] = {
    9978             :     "x = function await() {}",
    9979             :     "x = function *await() {}",
    9980             :     "x = function() { let await = 0; }",
    9981             :     "x = () => { let await = 0; }",
    9982             :     nullptr
    9983           5 :   };
    9984             : 
    9985             :   const char* bad_formal_parameters[] = {
    9986             :     "{ await }",
    9987             :     "{ await = 1 }",
    9988             :     "{ await } = {}",
    9989             :     "{ await = 1 } = {}",
    9990             :     "[await]",
    9991             :     "[await] = []",
    9992             :     "[await = 1]",
    9993             :     "[await = 1] = []",
    9994             :     "...await",
    9995             :     "await",
    9996             :     "await = 1",
    9997             :     "...[await]",
    9998             :     "x = await",
    9999             : 
   10000             :     // v8:5190
   10001             :     "1) => 1",
   10002             :     "'str') => 1",
   10003             :     "/foo/) => 1",
   10004             :     "{ foo = async(1) => 1 }) => 1",
   10005             :     "{ foo = async(a) => 1 })",
   10006             : 
   10007             :     "x = async(await)",
   10008             :     "x = { [await]: 1 }",
   10009             :     "x = class extends (await) { }",
   10010             :     "x = class { static [await]() {} }",
   10011             :     "{ x = await }",
   10012             : 
   10013             :     // v8:6714
   10014             :     "x = class await {}",
   10015             :     "x = 1 ? class await {} : 0",
   10016             :     "x = async function await() {}",
   10017             : 
   10018             :     "x = y[await]",
   10019             :     "x = `${await}`",
   10020             :     "x = y()[await]",
   10021             : 
   10022             :     nullptr
   10023           5 :   };
   10024             :   // clang-format on
   10025             : 
   10026             :   RunParserSyncTest(context_for_formal_parameters, good_formal_parameters,
   10027           5 :                     kSuccess);
   10028             : 
   10029             :   RunParserSyncTest(context_for_formal_parameters, bad_formal_parameters,
   10030           5 :                     kError);
   10031           5 : }
   10032             : 
   10033       26644 : TEST(AsyncAwaitModule) {
   10034             :   // clang-format off
   10035             :   const char* context_data[][2] = {
   10036             :     { "", "" },
   10037             :     { nullptr, nullptr }
   10038           5 :   };
   10039             : 
   10040             :   const char* data[] = {
   10041             :     "export default async function() { await 1; }",
   10042             :     "export default async function async() { await 1; }",
   10043             :     "export async function async() { await 1; }",
   10044             :     nullptr
   10045           5 :   };
   10046             :   // clang-format on
   10047             : 
   10048             :   RunModuleParserSyncTest(context_data, data, kSuccess, nullptr, 0, nullptr, 0,
   10049             :                           nullptr, 0, false);
   10050           5 : }
   10051             : 
   10052       26644 : TEST(AsyncAwaitModuleErrors) {
   10053             :   // clang-format off
   10054             :   const char* context_data[][2] = {
   10055             :     { "", "" },
   10056             :     { nullptr, nullptr }
   10057           5 :   };
   10058             : 
   10059             :   const char* error_data[] = {
   10060             :     "export default (async function await() {})",
   10061             :     "export default async function await() {}",
   10062             :     "export async function await() {}",
   10063             :     "export async function() {}",
   10064             :     "export async",
   10065             :     "export async\nfunction async() { await 1; }",
   10066             :     nullptr
   10067           5 :   };
   10068             :   // clang-format on
   10069             : 
   10070             :   RunModuleParserSyncTest(context_data, error_data, kError, nullptr, 0, nullptr,
   10071             :                           0, nullptr, 0, false);
   10072           5 : }
   10073             : 
   10074       26644 : TEST(RestrictiveForInErrors) {
   10075             :   // clang-format off
   10076             :   const char* strict_context_data[][2] = {
   10077             :     { "'use strict'", "" },
   10078             :     { nullptr, nullptr }
   10079           5 :   };
   10080             :   const char* sloppy_context_data[][2] = {
   10081             :     { "", "" },
   10082             :     { nullptr, nullptr }
   10083           5 :   };
   10084             :   const char* error_data[] = {
   10085             :     "for (const x = 0 in {});",
   10086             :     "for (let x = 0 in {});",
   10087             :     nullptr
   10088           5 :   };
   10089             :   const char* sloppy_data[] = {
   10090             :     "for (var x = 0 in {});",
   10091             :     nullptr
   10092           5 :   };
   10093             :   // clang-format on
   10094             : 
   10095           5 :   RunParserSyncTest(strict_context_data, error_data, kError);
   10096           5 :   RunParserSyncTest(strict_context_data, sloppy_data, kError);
   10097           5 :   RunParserSyncTest(sloppy_context_data, error_data, kError);
   10098           5 :   RunParserSyncTest(sloppy_context_data, sloppy_data, kSuccess);
   10099           5 : }
   10100             : 
   10101       26644 : TEST(NoDuplicateGeneratorsInBlock) {
   10102             :   const char* block_context_data[][2] = {
   10103             :       {"'use strict'; {", "}"},
   10104             :       {"{", "}"},
   10105             :       {"(function() { {", "} })()"},
   10106             :       {"(function() {'use strict'; {", "} })()"},
   10107           5 :       {nullptr, nullptr}};
   10108             :   const char* top_level_context_data[][2] = {
   10109             :       {"'use strict';", ""},
   10110             :       {"", ""},
   10111             :       {"(function() {", "})()"},
   10112             :       {"(function() {'use strict';", "})()"},
   10113           5 :       {nullptr, nullptr}};
   10114             :   const char* error_data[] = {"function* x() {} function* x() {}",
   10115             :                               "function x() {} function* x() {}",
   10116           5 :                               "function* x() {} function x() {}", nullptr};
   10117             :   // The preparser doesn't enforce the restriction, so turn it off.
   10118             :   bool test_preparser = false;
   10119             :   RunParserSyncTest(block_context_data, error_data, kError, nullptr, 0, nullptr,
   10120           5 :                     0, nullptr, 0, false, test_preparser);
   10121           5 :   RunParserSyncTest(top_level_context_data, error_data, kSuccess);
   10122           5 : }
   10123             : 
   10124       26644 : TEST(NoDuplicateAsyncFunctionInBlock) {
   10125             :   const char* block_context_data[][2] = {
   10126             :       {"'use strict'; {", "}"},
   10127             :       {"{", "}"},
   10128             :       {"(function() { {", "} })()"},
   10129             :       {"(function() {'use strict'; {", "} })()"},
   10130           5 :       {nullptr, nullptr}};
   10131             :   const char* top_level_context_data[][2] = {
   10132             :       {"'use strict';", ""},
   10133             :       {"", ""},
   10134             :       {"(function() {", "})()"},
   10135             :       {"(function() {'use strict';", "})()"},
   10136           5 :       {nullptr, nullptr}};
   10137             :   const char* error_data[] = {"async function x() {} async function x() {}",
   10138             :                               "function x() {} async function x() {}",
   10139             :                               "async function x() {} function x() {}",
   10140             :                               "function* x() {} async function x() {}",
   10141             :                               "function* x() {} async function x() {}",
   10142             :                               "async function x() {} function* x() {}",
   10143             :                               "function* x() {} async function x() {}",
   10144           5 :                               nullptr};
   10145             :   // The preparser doesn't enforce the restriction, so turn it off.
   10146             :   bool test_preparser = false;
   10147             :   RunParserSyncTest(block_context_data, error_data, kError, nullptr, 0, nullptr,
   10148           5 :                     0, nullptr, 0, false, test_preparser);
   10149           5 :   RunParserSyncTest(top_level_context_data, error_data, kSuccess);
   10150           5 : }
   10151             : 
   10152       26644 : TEST(TrailingCommasInParameters) {
   10153             :   // clang-format off
   10154             :   const char* context_data[][2] = {
   10155             :     { "", "" },
   10156             :     { "'use strict';", "" },
   10157             :     { "function foo() {", "}" },
   10158             :     { "function foo() {'use strict';", "}" },
   10159             :     { nullptr, nullptr }
   10160           5 :   };
   10161             : 
   10162             :   const char* data[] = {
   10163             :     " function  a(b,) {}",
   10164             :     " function* a(b,) {}",
   10165             :     "(function  a(b,) {});",
   10166             :     "(function* a(b,) {});",
   10167             :     "(function   (b,) {});",
   10168             :     "(function*  (b,) {});",
   10169             :     " function  a(b,c,d,) {}",
   10170             :     " function* a(b,c,d,) {}",
   10171             :     "(function  a(b,c,d,) {});",
   10172             :     "(function* a(b,c,d,) {});",
   10173             :     "(function   (b,c,d,) {});",
   10174             :     "(function*  (b,c,d,) {});",
   10175             :     "(b,) => {};",
   10176             :     "(b,c,d,) => {};",
   10177             :     "a(1,);",
   10178             :     "a(1,2,3,);",
   10179             :     "a(...[],);",
   10180             :     "a(1, 2, ...[],);",
   10181             :     "a(...[], 2, ...[],);",
   10182             :     nullptr
   10183           5 :   };
   10184             :   // clang-format on
   10185             : 
   10186           5 :   RunParserSyncTest(context_data, data, kSuccess);
   10187           5 : }
   10188             : 
   10189       26644 : TEST(TrailingCommasInParametersErrors) {
   10190             :   // clang-format off
   10191             :   const char* context_data[][2] = {
   10192             :     { "", "" },
   10193             :     { "'use strict';", "" },
   10194             :     { "function foo() {", "}" },
   10195             :     { "function foo() {'use strict';", "}" },
   10196             :     { nullptr, nullptr }
   10197           5 :   };
   10198             : 
   10199             :   const char* data[] = {
   10200             :     // too many trailing commas
   10201             :     " function  a(b,,) {}",
   10202             :     " function* a(b,,) {}",
   10203             :     "(function  a(b,,) {});",
   10204             :     "(function* a(b,,) {});",
   10205             :     "(function   (b,,) {});",
   10206             :     "(function*  (b,,) {});",
   10207             :     " function  a(b,c,d,,) {}",
   10208             :     " function* a(b,c,d,,) {}",
   10209             :     "(function  a(b,c,d,,) {});",
   10210             :     "(function* a(b,c,d,,) {});",
   10211             :     "(function   (b,c,d,,) {});",
   10212             :     "(function*  (b,c,d,,) {});",
   10213             :     "(b,,) => {};",
   10214             :     "(b,c,d,,) => {};",
   10215             :     "a(1,,);",
   10216             :     "a(1,2,3,,);",
   10217             :     // only a trailing comma and no parameters
   10218             :     " function  a1(,) {}",
   10219             :     " function* a2(,) {}",
   10220             :     "(function  a3(,) {});",
   10221             :     "(function* a4(,) {});",
   10222             :     "(function    (,) {});",
   10223             :     "(function*   (,) {});",
   10224             :     "(,) => {};",
   10225             :     "a1(,);",
   10226             :     // no trailing commas after rest parameter declaration
   10227             :     " function  a(...b,) {}",
   10228             :     " function* a(...b,) {}",
   10229             :     "(function  a(...b,) {});",
   10230             :     "(function* a(...b,) {});",
   10231             :     "(function   (...b,) {});",
   10232             :     "(function*  (...b,) {});",
   10233             :     " function  a(b, c, ...d,) {}",
   10234             :     " function* a(b, c, ...d,) {}",
   10235             :     "(function  a(b, c, ...d,) {});",
   10236             :     "(function* a(b, c, ...d,) {});",
   10237             :     "(function   (b, c, ...d,) {});",
   10238             :     "(function*  (b, c, ...d,) {});",
   10239             :     "(...b,) => {};",
   10240             :     "(b, c, ...d,) => {};",
   10241             :     // parenthesized trailing comma without arrow is still an error
   10242             :     "(,);",
   10243             :     "(a,);",
   10244             :     "(a,b,c,);",
   10245             :     nullptr
   10246           5 :   };
   10247             :   // clang-format on
   10248             : 
   10249           5 :   RunParserSyncTest(context_data, data, kError);
   10250           5 : }
   10251             : 
   10252       26644 : TEST(ArgumentsRedeclaration) {
   10253             :   {
   10254             :     // clang-format off
   10255             :     const char* context_data[][2] = {
   10256             :       { "function f(", ") {}" },
   10257             :       { nullptr, nullptr }
   10258           5 :     };
   10259             :     const char* success_data[] = {
   10260             :       "{arguments}",
   10261             :       "{arguments = false}",
   10262             :       "arg1, arguments",
   10263             :       "arg1, ...arguments",
   10264             :       nullptr
   10265           5 :     };
   10266             :     // clang-format on
   10267           5 :     RunParserSyncTest(context_data, success_data, kSuccess);
   10268             :   }
   10269             : 
   10270             :   {
   10271             :     // clang-format off
   10272             :     const char* context_data[][2] = {
   10273             :       { "function f() {", "}" },
   10274             :       { nullptr, nullptr }
   10275           5 :     };
   10276             :     const char* data[] = {
   10277             :       "const arguments = 1",
   10278             :       "let arguments",
   10279             :       "var arguments",
   10280             :       nullptr
   10281           5 :     };
   10282             :     // clang-format on
   10283           5 :     RunParserSyncTest(context_data, data, kSuccess);
   10284             :   }
   10285           5 : }
   10286             : 
   10287             : 
   10288             : // Test that lazily parsed inner functions don't result in overly pessimistic
   10289             : // context allocations.
   10290       26644 : TEST(NoPessimisticContextAllocation) {
   10291             :   i::Isolate* isolate = CcTest::i_isolate();
   10292             :   i::Factory* factory = isolate->factory();
   10293             :   i::HandleScope scope(isolate);
   10294           5 :   LocalContext env;
   10295             : 
   10296             :   const char* prefix = "(function outer() { var my_var; ";
   10297             :   const char* suffix = " })();";
   10298           5 :   int prefix_len = Utf8LengthHelper(prefix);
   10299           5 :   int suffix_len = Utf8LengthHelper(suffix);
   10300             : 
   10301             :   // Test both normal inner functions and inner arrow functions.
   10302             :   const char* inner_functions[] = {"function inner(%s) { %s }",
   10303           5 :                                    "(%s) => { %s }"};
   10304             : 
   10305             :   struct {
   10306             :     const char* params;
   10307             :     const char* source;
   10308             :     bool ctxt_allocate;
   10309             :   } inners[] = {
   10310             :       // Context allocating because we need to:
   10311             :       {"", "my_var;", true},
   10312             :       {"", "if (true) { let my_var; } my_var;", true},
   10313             :       {"", "eval('foo');", true},
   10314             :       {"", "function inner2() { my_var; }", true},
   10315             :       {"", "function inner2() { eval('foo'); }", true},
   10316             :       {"", "var {my_var : a} = {my_var};", true},
   10317             :       {"", "let {my_var : a} = {my_var};", true},
   10318             :       {"", "const {my_var : a} = {my_var};", true},
   10319             :       {"", "var [a, b = my_var] = [1, 2];", true},
   10320             :       {"", "var [a, b = my_var] = [1, 2]; my_var;", true},
   10321             :       {"", "let [a, b = my_var] = [1, 2];", true},
   10322             :       {"", "let [a, b = my_var] = [1, 2]; my_var;", true},
   10323             :       {"", "const [a, b = my_var] = [1, 2];", true},
   10324             :       {"", "const [a, b = my_var] = [1, 2]; my_var;", true},
   10325             :       {"", "var {a = my_var} = {}", true},
   10326             :       {"", "var {a: b = my_var} = {}", true},
   10327             :       {"", "let {a = my_var} = {}", true},
   10328             :       {"", "let {a: b = my_var} = {}", true},
   10329             :       {"", "const {a = my_var} = {}", true},
   10330             :       {"", "const {a: b = my_var} = {}", true},
   10331             :       {"a = my_var", "", true},
   10332             :       {"a = my_var", "let my_var;", true},
   10333             :       {"", "function inner2(a = my_var) { }", true},
   10334             :       {"", "(a = my_var) => { }", true},
   10335             :       {"{a} = {a: my_var}", "", true},
   10336             :       {"", "function inner2({a} = {a: my_var}) { }", true},
   10337             :       {"", "({a} = {a: my_var}) => { }", true},
   10338             :       {"[a] = [my_var]", "", true},
   10339             :       {"", "function inner2([a] = [my_var]) { }", true},
   10340             :       {"", "([a] = [my_var]) => { }", true},
   10341             :       {"", "function inner2(a = eval('')) { }", true},
   10342             :       {"", "(a = eval('')) => { }", true},
   10343             :       {"", "try { } catch (my_var) { } my_var;", true},
   10344             :       {"", "for (my_var in {}) { my_var; }", true},
   10345             :       {"", "for (my_var in {}) { }", true},
   10346             :       {"", "for (my_var of []) { my_var; }", true},
   10347             :       {"", "for (my_var of []) { }", true},
   10348             :       {"", "for ([a, my_var, b] in {}) { my_var; }", true},
   10349             :       {"", "for ([a, my_var, b] of []) { my_var; }", true},
   10350             :       {"", "for ({x: my_var} in {}) { my_var; }", true},
   10351             :       {"", "for ({x: my_var} of []) { my_var; }", true},
   10352             :       {"", "for ({my_var} in {}) { my_var; }", true},
   10353             :       {"", "for ({my_var} of []) { my_var; }", true},
   10354             :       {"", "for ({y, x: my_var} in {}) { my_var; }", true},
   10355             :       {"", "for ({y, x: my_var} of []) { my_var; }", true},
   10356             :       {"", "for ({a, my_var} in {}) { my_var; }", true},
   10357             :       {"", "for ({a, my_var} of []) { my_var; }", true},
   10358             :       {"", "for (let my_var in {}) { } my_var;", true},
   10359             :       {"", "for (let my_var of []) { } my_var;", true},
   10360             :       {"", "for (let [a, my_var, b] in {}) { } my_var;", true},
   10361             :       {"", "for (let [a, my_var, b] of []) { } my_var;", true},
   10362             :       {"", "for (let {x: my_var} in {}) { } my_var;", true},
   10363             :       {"", "for (let {x: my_var} of []) { } my_var;", true},
   10364             :       {"", "for (let {my_var} in {}) { } my_var;", true},
   10365             :       {"", "for (let {my_var} of []) { } my_var;", true},
   10366             :       {"", "for (let {y, x: my_var} in {}) { } my_var;", true},
   10367             :       {"", "for (let {y, x: my_var} of []) { } my_var;", true},
   10368             :       {"", "for (let {a, my_var} in {}) { } my_var;", true},
   10369             :       {"", "for (let {a, my_var} of []) { } my_var;", true},
   10370             :       {"", "for (let my_var = 0; my_var < 1; ++my_var) { } my_var;", true},
   10371             :       {"", "'use strict'; if (true) { function my_var() {} } my_var;", true},
   10372             :       {"",
   10373             :        "'use strict'; function inner2() { if (true) { function my_var() {} }  "
   10374             :        "my_var; }",
   10375             :        true},
   10376             :       {"",
   10377             :        "function inner2() { 'use strict'; if (true) { function my_var() {} }  "
   10378             :        "my_var; }",
   10379             :        true},
   10380             :       {"",
   10381             :        "() => { 'use strict'; if (true) { function my_var() {} }  my_var; }",
   10382             :        true},
   10383             :       {"",
   10384             :        "if (true) { let my_var; if (true) { function my_var() {} } } my_var;",
   10385             :        true},
   10386             :       {"", "function inner2(a = my_var) {}", true},
   10387             :       {"", "function inner2(a = my_var) { let my_var; }", true},
   10388             :       {"", "(a = my_var) => {}", true},
   10389             :       {"", "(a = my_var) => { let my_var; }", true},
   10390             :       // No pessimistic context allocation:
   10391             :       {"", "var my_var; my_var;", false},
   10392             :       {"", "var my_var;", false},
   10393             :       {"", "var my_var = 0;", false},
   10394             :       {"", "if (true) { var my_var; } my_var;", false},
   10395             :       {"", "let my_var; my_var;", false},
   10396             :       {"", "let my_var;", false},
   10397             :       {"", "let my_var = 0;", false},
   10398             :       {"", "const my_var = 0; my_var;", false},
   10399             :       {"", "const my_var = 0;", false},
   10400             :       {"", "var [a, my_var] = [1, 2]; my_var;", false},
   10401             :       {"", "let [a, my_var] = [1, 2]; my_var;", false},
   10402             :       {"", "const [a, my_var] = [1, 2]; my_var;", false},
   10403             :       {"", "var {a: my_var} = {a: 3}; my_var;", false},
   10404             :       {"", "let {a: my_var} = {a: 3}; my_var;", false},
   10405             :       {"", "const {a: my_var} = {a: 3}; my_var;", false},
   10406             :       {"", "var {my_var} = {my_var: 3}; my_var;", false},
   10407             :       {"", "let {my_var} = {my_var: 3}; my_var;", false},
   10408             :       {"", "const {my_var} = {my_var: 3}; my_var;", false},
   10409             :       {"my_var", "my_var;", false},
   10410             :       {"my_var", "", false},
   10411             :       {"my_var = 5", "my_var;", false},
   10412             :       {"my_var = 5", "", false},
   10413             :       {"...my_var", "my_var;", false},
   10414             :       {"...my_var", "", false},
   10415             :       {"[a, my_var, b]", "my_var;", false},
   10416             :       {"[a, my_var, b]", "", false},
   10417             :       {"[a, my_var, b] = [1, 2, 3]", "my_var;", false},
   10418             :       {"[a, my_var, b] = [1, 2, 3]", "", false},
   10419             :       {"{x: my_var}", "my_var;", false},
   10420             :       {"{x: my_var}", "", false},
   10421             :       {"{x: my_var} = {x: 0}", "my_var;", false},
   10422             :       {"{x: my_var} = {x: 0}", "", false},
   10423             :       {"{my_var}", "my_var;", false},
   10424             :       {"{my_var}", "", false},
   10425             :       {"{my_var} = {my_var: 0}", "my_var;", false},
   10426             :       {"{my_var} = {my_var: 0}", "", false},
   10427             :       {"", "function inner2(my_var) { my_var; }", false},
   10428             :       {"", "function inner2(my_var) { }", false},
   10429             :       {"", "function inner2(my_var = 5) { my_var; }", false},
   10430             :       {"", "function inner2(my_var = 5) { }", false},
   10431             :       {"", "function inner2(...my_var) { my_var; }", false},
   10432             :       {"", "function inner2(...my_var) { }", false},
   10433             :       {"", "function inner2([a, my_var, b]) { my_var; }", false},
   10434             :       {"", "function inner2([a, my_var, b]) { }", false},
   10435             :       {"", "function inner2([a, my_var, b] = [1, 2, 3]) { my_var; }", false},
   10436             :       {"", "function inner2([a, my_var, b] = [1, 2, 3]) { }", false},
   10437             :       {"", "function inner2({x: my_var}) { my_var; }", false},
   10438             :       {"", "function inner2({x: my_var}) { }", false},
   10439             :       {"", "function inner2({x: my_var} = {x: 0}) { my_var; }", false},
   10440             :       {"", "function inner2({x: my_var} = {x: 0}) { }", false},
   10441             :       {"", "function inner2({my_var}) { my_var; }", false},
   10442             :       {"", "function inner2({my_var}) { }", false},
   10443             :       {"", "function inner2({my_var} = {my_var: 8}) { my_var; } ", false},
   10444             :       {"", "function inner2({my_var} = {my_var: 8}) { }", false},
   10445             :       {"", "my_var => my_var;", false},
   10446             :       {"", "my_var => { }", false},
   10447             :       {"", "(my_var = 5) => my_var;", false},
   10448             :       {"", "(my_var = 5) => { }", false},
   10449             :       {"", "(...my_var) => my_var;", false},
   10450             :       {"", "(...my_var) => { }", false},
   10451             :       {"", "([a, my_var, b]) => my_var;", false},
   10452             :       {"", "([a, my_var, b]) => { }", false},
   10453             :       {"", "([a, my_var, b] = [1, 2, 3]) => my_var;", false},
   10454             :       {"", "([a, my_var, b] = [1, 2, 3]) => { }", false},
   10455             :       {"", "({x: my_var}) => my_var;", false},
   10456             :       {"", "({x: my_var}) => { }", false},
   10457             :       {"", "({x: my_var} = {x: 0}) => my_var;", false},
   10458             :       {"", "({x: my_var} = {x: 0}) => { }", false},
   10459             :       {"", "({my_var}) => my_var;", false},
   10460             :       {"", "({my_var}) => { }", false},
   10461             :       {"", "({my_var} = {my_var: 5}) => my_var;", false},
   10462             :       {"", "({my_var} = {my_var: 5}) => { }", false},
   10463             :       {"", "({a, my_var}) => my_var;", false},
   10464             :       {"", "({a, my_var}) => { }", false},
   10465             :       {"", "({a, my_var} = {a: 0, my_var: 5}) => my_var;", false},
   10466             :       {"", "({a, my_var} = {a: 0, my_var: 5}) => { }", false},
   10467             :       {"", "({y, x: my_var}) => my_var;", false},
   10468             :       {"", "({y, x: my_var}) => { }", false},
   10469             :       {"", "({y, x: my_var} = {y: 0, x: 0}) => my_var;", false},
   10470             :       {"", "({y, x: my_var} = {y: 0, x: 0}) => { }", false},
   10471             :       {"", "try { } catch (my_var) { my_var; }", false},
   10472             :       {"", "try { } catch ([a, my_var, b]) { my_var; }", false},
   10473             :       {"", "try { } catch ({x: my_var}) { my_var; }", false},
   10474             :       {"", "try { } catch ({y, x: my_var}) { my_var; }", false},
   10475             :       {"", "try { } catch ({my_var}) { my_var; }", false},
   10476             :       {"", "for (let my_var in {}) { my_var; }", false},
   10477             :       {"", "for (let my_var in {}) { }", false},
   10478             :       {"", "for (let my_var of []) { my_var; }", false},
   10479             :       {"", "for (let my_var of []) { }", false},
   10480             :       {"", "for (let [a, my_var, b] in {}) { my_var; }", false},
   10481             :       {"", "for (let [a, my_var, b] of []) { my_var; }", false},
   10482             :       {"", "for (let {x: my_var} in {}) { my_var; }", false},
   10483             :       {"", "for (let {x: my_var} of []) { my_var; }", false},
   10484             :       {"", "for (let {my_var} in {}) { my_var; }", false},
   10485             :       {"", "for (let {my_var} of []) { my_var; }", false},
   10486             :       {"", "for (let {y, x: my_var} in {}) { my_var; }", false},
   10487             :       {"", "for (let {y, x: my_var} of []) { my_var; }", false},
   10488             :       {"", "for (let {a, my_var} in {}) { my_var; }", false},
   10489             :       {"", "for (let {a, my_var} of []) { my_var; }", false},
   10490             :       {"", "for (var my_var in {}) { my_var; }", false},
   10491             :       {"", "for (var my_var in {}) { }", false},
   10492             :       {"", "for (var my_var of []) { my_var; }", false},
   10493             :       {"", "for (var my_var of []) { }", false},
   10494             :       {"", "for (var [a, my_var, b] in {}) { my_var; }", false},
   10495             :       {"", "for (var [a, my_var, b] of []) { my_var; }", false},
   10496             :       {"", "for (var {x: my_var} in {}) { my_var; }", false},
   10497             :       {"", "for (var {x: my_var} of []) { my_var; }", false},
   10498             :       {"", "for (var {my_var} in {}) { my_var; }", false},
   10499             :       {"", "for (var {my_var} of []) { my_var; }", false},
   10500             :       {"", "for (var {y, x: my_var} in {}) { my_var; }", false},
   10501             :       {"", "for (var {y, x: my_var} of []) { my_var; }", false},
   10502             :       {"", "for (var {a, my_var} in {}) { my_var; }", false},
   10503             :       {"", "for (var {a, my_var} of []) { my_var; }", false},
   10504             :       {"", "for (var my_var in {}) { } my_var;", false},
   10505             :       {"", "for (var my_var of []) { } my_var;", false},
   10506             :       {"", "for (var [a, my_var, b] in {}) { } my_var;", false},
   10507             :       {"", "for (var [a, my_var, b] of []) { } my_var;", false},
   10508             :       {"", "for (var {x: my_var} in {}) { } my_var;", false},
   10509             :       {"", "for (var {x: my_var} of []) { } my_var;", false},
   10510             :       {"", "for (var {my_var} in {}) { } my_var;", false},
   10511             :       {"", "for (var {my_var} of []) { } my_var;", false},
   10512             :       {"", "for (var {y, x: my_var} in {}) { } my_var;", false},
   10513             :       {"", "for (var {y, x: my_var} of []) { } my_var;", false},
   10514             :       {"", "for (var {a, my_var} in {}) { } my_var;", false},
   10515             :       {"", "for (var {a, my_var} of []) { } my_var;", false},
   10516             :       {"", "for (let my_var = 0; my_var < 1; ++my_var) { my_var; }", false},
   10517             :       {"", "for (var my_var = 0; my_var < 1; ++my_var) { my_var; }", false},
   10518             :       {"", "for (var my_var = 0; my_var < 1; ++my_var) { } my_var; ", false},
   10519             :       {"", "for (let a = 0, my_var = 0; my_var < 1; ++my_var) { my_var }",
   10520             :        false},
   10521             :       {"", "for (var a = 0, my_var = 0; my_var < 1; ++my_var) { my_var }",
   10522             :        false},
   10523             :       {"", "class my_var {}; my_var; ", false},
   10524             :       {"", "function my_var() {} my_var;", false},
   10525             :       {"", "if (true) { function my_var() {} }  my_var;", false},
   10526             :       {"", "function inner2() { if (true) { function my_var() {} }  my_var; }",
   10527             :        false},
   10528             :       {"", "() => { if (true) { function my_var() {} }  my_var; }", false},
   10529             :       {"",
   10530             :        "if (true) { var my_var; if (true) { function my_var() {} } }  my_var;",
   10531             :        false},
   10532           5 :   };
   10533             : 
   10534          25 :   for (unsigned inner_ix = 0; inner_ix < arraysize(inner_functions);
   10535             :        ++inner_ix) {
   10536          10 :     const char* inner_function = inner_functions[inner_ix];
   10537          10 :     int inner_function_len = Utf8LengthHelper(inner_function) - 4;
   10538             : 
   10539        4110 :     for (unsigned i = 0; i < arraysize(inners); ++i) {
   10540        2050 :       int params_len = Utf8LengthHelper(inners[i].params);
   10541        2050 :       int source_len = Utf8LengthHelper(inners[i].source);
   10542        2050 :       int len = prefix_len + inner_function_len + params_len + source_len +
   10543        2050 :                 suffix_len;
   10544             : 
   10545        2050 :       i::ScopedVector<char> program(len + 1);
   10546        2050 :       i::SNPrintF(program, "%s", prefix);
   10547        2050 :       i::SNPrintF(program + prefix_len, inner_function, inners[i].params,
   10548        2050 :                   inners[i].source);
   10549        2050 :       i::SNPrintF(
   10550        2050 :           program + prefix_len + inner_function_len + params_len + source_len,
   10551        2050 :           "%s", suffix);
   10552             : 
   10553             :       i::Handle<i::String> source =
   10554        2050 :           factory->InternalizeUtf8String(program.start());
   10555        4100 :       source->PrintOn(stdout);
   10556             :       printf("\n");
   10557             : 
   10558        2050 :       i::Handle<i::Script> script = factory->NewScript(source);
   10559        4100 :       i::ParseInfo info(isolate, script);
   10560             : 
   10561        2050 :       CHECK(i::parsing::ParseProgram(&info, isolate));
   10562        2050 :       CHECK(i::Compiler::Analyze(&info));
   10563        2050 :       CHECK_NOT_NULL(info.literal());
   10564             : 
   10565             :       i::Scope* scope = info.literal()->scope()->inner_scope();
   10566             :       DCHECK_NOT_NULL(scope);
   10567             :       DCHECK_NULL(scope->sibling());
   10568             :       DCHECK(scope->is_function_scope());
   10569             :       const i::AstRawString* var_name =
   10570        2050 :           info.ast_value_factory()->GetOneByteString("my_var");
   10571             :       i::Variable* var = scope->LookupForTesting(var_name);
   10572        2050 :       CHECK_EQ(inners[i].ctxt_allocate,
   10573             :                i::ScopeTestHelper::MustAllocateInContext(var));
   10574             :     }
   10575             :   }
   10576           5 : }
   10577             : 
   10578       26644 : TEST(EscapedStrictReservedWord) {
   10579             :   // Test that identifiers which are both escaped and only reserved in the
   10580             :   // strict mode are accepted in non-strict mode.
   10581           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
   10582             : 
   10583             :   const char* statement_data[] = {"if (true) l\\u0065t: ;",
   10584             :                                   "function l\\u0065t() { }",
   10585             :                                   "(function l\\u0065t() { })",
   10586             :                                   "async function l\\u0065t() { }",
   10587             :                                   "(async function l\\u0065t() { })",
   10588             :                                   "l\\u0065t => 42",
   10589             :                                   "async l\\u0065t => 42",
   10590             :                                   "function packag\\u0065() {}",
   10591             :                                   "function impl\\u0065ments() {}",
   10592             :                                   "function privat\\u0065() {}",
   10593           5 :                                   nullptr};
   10594             : 
   10595           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
   10596           5 : }
   10597             : 
   10598       26644 : TEST(ForAwaitOf) {
   10599             :   // clang-format off
   10600             :   const char* context_data[][2] = {
   10601             :     { "async function f() { for await ", " ; }" },
   10602             :     { "async function f() { for await ", " { } }" },
   10603             :     { "async function * f() { for await ", " { } }" },
   10604             :     { "async function f() { 'use strict'; for await ", " ; }" },
   10605             :     { "async function f() { 'use strict'; for await ", "  { } }" },
   10606             :     { "async function * f() { 'use strict'; for await ", "  { } }" },
   10607             :     { "async function f() { for\nawait ", " ; }" },
   10608             :     { "async function f() { for\nawait ", " { } }" },
   10609             :     { "async function * f() { for\nawait ", " { } }" },
   10610             :     { "async function f() { 'use strict'; for\nawait ", " ; }" },
   10611             :     { "async function f() { 'use strict'; for\nawait ", " { } }" },
   10612             :     { "async function * f() { 'use strict'; for\nawait ", " { } }" },
   10613             :     { "async function f() { for await\n", " ; }" },
   10614             :     { "async function f() { for await\n", " { } }" },
   10615             :     { "async function * f() { for await\n", " { } }" },
   10616             :     { "async function f() { 'use strict'; for await\n", " ; }" },
   10617             :     { "async function f() { 'use strict'; for await\n", " { } }" },
   10618             :     { "async function * f() { 'use strict'; for await\n", " { } }" },
   10619             :     { nullptr, nullptr }
   10620           5 :   };
   10621             : 
   10622             :   const char* context_data2[][2] = {
   10623             :     { "async function f() { let a; for await ", " ; }" },
   10624             :     { "async function f() { let a; for await ", " { } }" },
   10625             :     { "async function * f() { let a; for await ", " { } }" },
   10626             :     { "async function f() { 'use strict'; let a; for await ", " ; }" },
   10627             :     { "async function f() { 'use strict'; let a; for await ", "  { } }" },
   10628             :     { "async function * f() { 'use strict'; let a; for await ", "  { } }" },
   10629             :     { "async function f() { let a; for\nawait ", " ; }" },
   10630             :     { "async function f() { let a; for\nawait ", " { } }" },
   10631             :     { "async function * f() { let a; for\nawait ", " { } }" },
   10632             :     { "async function f() { 'use strict'; let a; for\nawait ", " ; }" },
   10633             :     { "async function f() { 'use strict'; let a; for\nawait ", " { } }" },
   10634             :     { "async function * f() { 'use strict'; let a; for\nawait ", " { } }" },
   10635             :     { "async function f() { let a; for await\n", " ; }" },
   10636             :     { "async function f() { let a; for await\n", " { } }" },
   10637             :     { "async function * f() { let a; for await\n", " { } }" },
   10638             :     { "async function f() { 'use strict'; let a; for await\n", " ; }" },
   10639             :     { "async function f() { 'use strict'; let a; for await\n", " { } }" },
   10640             :     { "async function * f() { 'use strict'; let a; for await\n", " { } }" },
   10641             :     { nullptr, nullptr }
   10642           5 :   };
   10643             : 
   10644             :   const char* expr_data[] = {
   10645             :     // Primary Expressions
   10646             :     "(a of [])",
   10647             :     "(a.b of [])",
   10648             :     "([a] of [])",
   10649             :     "([a = 1] of [])",
   10650             :     "([a = 1, ...b] of [])",
   10651             :     "({a} of [])",
   10652             :     "({a: a} of [])",
   10653             :     "({'a': a} of [])",
   10654             :     "({\"a\": a} of [])",
   10655             :     "({[Symbol.iterator]: a} of [])",
   10656             :     "({0: a} of [])",
   10657             :     "({a = 1} of [])",
   10658             :     "({a: a = 1} of [])",
   10659             :     "({'a': a = 1} of [])",
   10660             :     "({\"a\": a = 1} of [])",
   10661             :     "({[Symbol.iterator]: a = 1} of [])",
   10662             :     "({0: a = 1} of [])",
   10663             :     nullptr
   10664           5 :   };
   10665             : 
   10666             :   const char* var_data[] = {
   10667             :     // VarDeclarations
   10668             :     "(var a of [])",
   10669             :     "(var [a] of [])",
   10670             :     "(var [a = 1] of [])",
   10671             :     "(var [a = 1, ...b] of [])",
   10672             :     "(var {a} of [])",
   10673             :     "(var {a: a} of [])",
   10674             :     "(var {'a': a} of [])",
   10675             :     "(var {\"a\": a} of [])",
   10676             :     "(var {[Symbol.iterator]: a} of [])",
   10677             :     "(var {0: a} of [])",
   10678             :     "(var {a = 1} of [])",
   10679             :     "(var {a: a = 1} of [])",
   10680             :     "(var {'a': a = 1} of [])",
   10681             :     "(var {\"a\": a = 1} of [])",
   10682             :     "(var {[Symbol.iterator]: a = 1} of [])",
   10683             :     "(var {0: a = 1} of [])",
   10684             :     nullptr
   10685           5 :   };
   10686             : 
   10687             :   const char* lexical_data[] = {
   10688             :     // LexicalDeclartions
   10689             :     "(let a of [])",
   10690             :     "(let [a] of [])",
   10691             :     "(let [a = 1] of [])",
   10692             :     "(let [a = 1, ...b] of [])",
   10693             :     "(let {a} of [])",
   10694             :     "(let {a: a} of [])",
   10695             :     "(let {'a': a} of [])",
   10696             :     "(let {\"a\": a} of [])",
   10697             :     "(let {[Symbol.iterator]: a} of [])",
   10698             :     "(let {0: a} of [])",
   10699             :     "(let {a = 1} of [])",
   10700             :     "(let {a: a = 1} of [])",
   10701             :     "(let {'a': a = 1} of [])",
   10702             :     "(let {\"a\": a = 1} of [])",
   10703             :     "(let {[Symbol.iterator]: a = 1} of [])",
   10704             :     "(let {0: a = 1} of [])",
   10705             : 
   10706             :     "(const a of [])",
   10707             :     "(const [a] of [])",
   10708             :     "(const [a = 1] of [])",
   10709             :     "(const [a = 1, ...b] of [])",
   10710             :     "(const {a} of [])",
   10711             :     "(const {a: a} of [])",
   10712             :     "(const {'a': a} of [])",
   10713             :     "(const {\"a\": a} of [])",
   10714             :     "(const {[Symbol.iterator]: a} of [])",
   10715             :     "(const {0: a} of [])",
   10716             :     "(const {a = 1} of [])",
   10717             :     "(const {a: a = 1} of [])",
   10718             :     "(const {'a': a = 1} of [])",
   10719             :     "(const {\"a\": a = 1} of [])",
   10720             :     "(const {[Symbol.iterator]: a = 1} of [])",
   10721             :     "(const {0: a = 1} of [])",
   10722             :     nullptr
   10723           5 :   };
   10724             :   // clang-format on
   10725           5 :   RunParserSyncTest(context_data, expr_data, kSuccess);
   10726           5 :   RunParserSyncTest(context_data2, expr_data, kSuccess);
   10727             : 
   10728           5 :   RunParserSyncTest(context_data, var_data, kSuccess);
   10729             :   // TODO(marja): PreParser doesn't report early errors.
   10730             :   //              (https://bugs.chromium.org/p/v8/issues/detail?id=2728)
   10731             :   // RunParserSyncTest(context_data2, var_data, kError, nullptr, 0,
   10732             :   // always_flags,
   10733             :   //                   arraysize(always_flags));
   10734             : 
   10735           5 :   RunParserSyncTest(context_data, lexical_data, kSuccess);
   10736           5 :   RunParserSyncTest(context_data2, lexical_data, kSuccess);
   10737           5 : }
   10738             : 
   10739       26644 : TEST(ForAwaitOfErrors) {
   10740             :   // clang-format off
   10741             :   const char* context_data[][2] = {
   10742             :     { "async function f() { for await ", " ; }" },
   10743             :     { "async function f() { for await ", " { } }" },
   10744             :     { "async function f() { 'use strict'; for await ", " ; }" },
   10745             :     { "async function f() { 'use strict'; for await ", "  { } }" },
   10746             :     { "async function * f() { for await ", " ; }" },
   10747             :     { "async function * f() { for await ", " { } }" },
   10748             :     { "async function * f() { 'use strict'; for await ", " ; }" },
   10749             :     { "async function * f() { 'use strict'; for await ", "  { } }" },
   10750             :     { nullptr, nullptr }
   10751           5 :   };
   10752             : 
   10753             :   const char* data[] = {
   10754             :     // Primary Expressions
   10755             :     "(a = 1 of [])",
   10756             :     "(a = 1) of [])",
   10757             :     "(a.b = 1 of [])",
   10758             :     "((a.b = 1) of [])",
   10759             :     "([a] = 1 of [])",
   10760             :     "(([a] = 1) of [])",
   10761             :     "([a = 1] = 1 of [])",
   10762             :     "(([a = 1] = 1) of [])",
   10763             :     "([a = 1 = 1, ...b] = 1 of [])",
   10764             :     "(([a = 1 = 1, ...b] = 1) of [])",
   10765             :     "({a} = 1 of [])",
   10766             :     "(({a} = 1) of [])",
   10767             :     "({a: a} = 1 of [])",
   10768             :     "(({a: a} = 1) of [])",
   10769             :     "({'a': a} = 1 of [])",
   10770             :     "(({'a': a} = 1) of [])",
   10771             :     "({\"a\": a} = 1 of [])",
   10772             :     "(({\"a\": a} = 1) of [])",
   10773             :     "({[Symbol.iterator]: a} = 1 of [])",
   10774             :     "(({[Symbol.iterator]: a} = 1) of [])",
   10775             :     "({0: a} = 1 of [])",
   10776             :     "(({0: a} = 1) of [])",
   10777             :     "({a = 1} = 1 of [])",
   10778             :     "(({a = 1} = 1) of [])",
   10779             :     "({a: a = 1} = 1 of [])",
   10780             :     "(({a: a = 1} = 1) of [])",
   10781             :     "({'a': a = 1} = 1 of [])",
   10782             :     "(({'a': a = 1} = 1) of [])",
   10783             :     "({\"a\": a = 1} = 1 of [])",
   10784             :     "(({\"a\": a = 1} = 1) of [])",
   10785             :     "({[Symbol.iterator]: a = 1} = 1 of [])",
   10786             :     "(({[Symbol.iterator]: a = 1} = 1) of [])",
   10787             :     "({0: a = 1} = 1 of [])",
   10788             :     "(({0: a = 1} = 1) of [])",
   10789             :     "(function a() {} of [])",
   10790             :     "([1] of [])",
   10791             :     "({a: 1} of [])"
   10792             : 
   10793             :     // VarDeclarations
   10794             :     "(var a = 1 of [])",
   10795             :     "(var a, b of [])",
   10796             :     "(var [a] = 1 of [])",
   10797             :     "(var [a], b of [])",
   10798             :     "(var [a = 1] = 1 of [])",
   10799             :     "(var [a = 1], b of [])",
   10800             :     "(var [a = 1 = 1, ...b] of [])",
   10801             :     "(var [a = 1, ...b], c of [])",
   10802             :     "(var {a} = 1 of [])",
   10803             :     "(var {a}, b of [])",
   10804             :     "(var {a: a} = 1 of [])",
   10805             :     "(var {a: a}, b of [])",
   10806             :     "(var {'a': a} = 1 of [])",
   10807             :     "(var {'a': a}, b of [])",
   10808             :     "(var {\"a\": a} = 1 of [])",
   10809             :     "(var {\"a\": a}, b of [])",
   10810             :     "(var {[Symbol.iterator]: a} = 1 of [])",
   10811             :     "(var {[Symbol.iterator]: a}, b of [])",
   10812             :     "(var {0: a} = 1 of [])",
   10813             :     "(var {0: a}, b of [])",
   10814             :     "(var {a = 1} = 1 of [])",
   10815             :     "(var {a = 1}, b of [])",
   10816             :     "(var {a: a = 1} = 1 of [])",
   10817             :     "(var {a: a = 1}, b of [])",
   10818             :     "(var {'a': a = 1} = 1 of [])",
   10819             :     "(var {'a': a = 1}, b of [])",
   10820             :     "(var {\"a\": a = 1} = 1 of [])",
   10821             :     "(var {\"a\": a = 1}, b of [])",
   10822             :     "(var {[Symbol.iterator]: a = 1} = 1 of [])",
   10823             :     "(var {[Symbol.iterator]: a = 1}, b of [])",
   10824             :     "(var {0: a = 1} = 1 of [])",
   10825             :     "(var {0: a = 1}, b of [])",
   10826             : 
   10827             :     // LexicalDeclartions
   10828             :     "(let a = 1 of [])",
   10829             :     "(let a, b of [])",
   10830             :     "(let [a] = 1 of [])",
   10831             :     "(let [a], b of [])",
   10832             :     "(let [a = 1] = 1 of [])",
   10833             :     "(let [a = 1], b of [])",
   10834             :     "(let [a = 1, ...b] = 1 of [])",
   10835             :     "(let [a = 1, ...b], c of [])",
   10836             :     "(let {a} = 1 of [])",
   10837             :     "(let {a}, b of [])",
   10838             :     "(let {a: a} = 1 of [])",
   10839             :     "(let {a: a}, b of [])",
   10840             :     "(let {'a': a} = 1 of [])",
   10841             :     "(let {'a': a}, b of [])",
   10842             :     "(let {\"a\": a} = 1 of [])",
   10843             :     "(let {\"a\": a}, b of [])",
   10844             :     "(let {[Symbol.iterator]: a} = 1 of [])",
   10845             :     "(let {[Symbol.iterator]: a}, b of [])",
   10846             :     "(let {0: a} = 1 of [])",
   10847             :     "(let {0: a}, b of [])",
   10848             :     "(let {a = 1} = 1 of [])",
   10849             :     "(let {a = 1}, b of [])",
   10850             :     "(let {a: a = 1} = 1 of [])",
   10851             :     "(let {a: a = 1}, b of [])",
   10852             :     "(let {'a': a = 1} = 1 of [])",
   10853             :     "(let {'a': a = 1}, b of [])",
   10854             :     "(let {\"a\": a = 1} = 1 of [])",
   10855             :     "(let {\"a\": a = 1}, b of [])",
   10856             :     "(let {[Symbol.iterator]: a = 1} = 1 of [])",
   10857             :     "(let {[Symbol.iterator]: a = 1}, b of [])",
   10858             :     "(let {0: a = 1} = 1 of [])",
   10859             :     "(let {0: a = 1}, b of [])",
   10860             : 
   10861             :     "(const a = 1 of [])",
   10862             :     "(const a, b of [])",
   10863             :     "(const [a] = 1 of [])",
   10864             :     "(const [a], b of [])",
   10865             :     "(const [a = 1] = 1 of [])",
   10866             :     "(const [a = 1], b of [])",
   10867             :     "(const [a = 1, ...b] = 1 of [])",
   10868             :     "(const [a = 1, ...b], b of [])",
   10869             :     "(const {a} = 1 of [])",
   10870             :     "(const {a}, b of [])",
   10871             :     "(const {a: a} = 1 of [])",
   10872             :     "(const {a: a}, b of [])",
   10873             :     "(const {'a': a} = 1 of [])",
   10874             :     "(const {'a': a}, b of [])",
   10875             :     "(const {\"a\": a} = 1 of [])",
   10876             :     "(const {\"a\": a}, b of [])",
   10877             :     "(const {[Symbol.iterator]: a} = 1 of [])",
   10878             :     "(const {[Symbol.iterator]: a}, b of [])",
   10879             :     "(const {0: a} = 1 of [])",
   10880             :     "(const {0: a}, b of [])",
   10881             :     "(const {a = 1} = 1 of [])",
   10882             :     "(const {a = 1}, b of [])",
   10883             :     "(const {a: a = 1} = 1 of [])",
   10884             :     "(const {a: a = 1}, b of [])",
   10885             :     "(const {'a': a = 1} = 1 of [])",
   10886             :     "(const {'a': a = 1}, b of [])",
   10887             :     "(const {\"a\": a = 1} = 1 of [])",
   10888             :     "(const {\"a\": a = 1}, b of [])",
   10889             :     "(const {[Symbol.iterator]: a = 1} = 1 of [])",
   10890             :     "(const {[Symbol.iterator]: a = 1}, b of [])",
   10891             :     "(const {0: a = 1} = 1 of [])",
   10892             :     "(const {0: a = 1}, b of [])",
   10893             : 
   10894             :     nullptr
   10895           5 :   };
   10896             :   // clang-format on
   10897           5 :   RunParserSyncTest(context_data, data, kError);
   10898           5 : }
   10899             : 
   10900       26644 : TEST(ForAwaitOfFunctionDeclaration) {
   10901             :   // clang-format off
   10902             :   const char* context_data[][2] = {
   10903             :     { "async function f() {", "}" },
   10904             :     { "async function f() { 'use strict'; ", "}" },
   10905             :     { nullptr, nullptr }
   10906           5 :   };
   10907             : 
   10908             :   const char* data[] = {
   10909             :     "for await (x of []) function d() {};",
   10910             :     "for await (x of []) function d() {}; return d;",
   10911             :     "for await (x of []) function* g() {};",
   10912             :     "for await (x of []) function* g() {}; return g;",
   10913             :     // TODO(caitp): handle async function declarations in ParseScopedStatement.
   10914             :     // "for await (x of []) async function a() {};",
   10915             :     // "for await (x of []) async function a() {}; return a;",
   10916             :     nullptr
   10917           5 :   };
   10918             : 
   10919             :   // clang-format on
   10920           5 :   RunParserSyncTest(context_data, data, kError);
   10921           5 : }
   10922             : 
   10923       26644 : TEST(AsyncGenerator) {
   10924             :   // clang-format off
   10925             :   const char* context_data[][2] = {
   10926             :     { "async function * gen() {", "}" },
   10927             :     { "(async function * gen() {", "})" },
   10928             :     { "(async function * () {", "})" },
   10929             :     { "({ async * gen () {", "} })" },
   10930             :     { nullptr, nullptr }
   10931           5 :   };
   10932             : 
   10933             :   const char* statement_data[] = {
   10934             :     // An async generator without a body is valid.
   10935             :     ""
   10936             :     // Valid yield expressions inside generators.
   10937             :     "yield 2;",
   10938             :     "yield * 2;",
   10939             :     "yield * \n 2;",
   10940             :     "yield yield 1;",
   10941             :     "yield * yield * 1;",
   10942             :     "yield 3 + (yield 4);",
   10943             :     "yield * 3 + (yield * 4);",
   10944             :     "(yield * 3) + (yield * 4);",
   10945             :     "yield 3; yield 4;",
   10946             :     "yield * 3; yield * 4;",
   10947             :     "(function (yield) { })",
   10948             :     "(function yield() { })",
   10949             :     "(function (await) { })",
   10950             :     "(function await() { })",
   10951             :     "yield { yield: 12 }",
   10952             :     "yield /* comment */ { yield: 12 }",
   10953             :     "yield * \n { yield: 12 }",
   10954             :     "yield /* comment */ * \n { yield: 12 }",
   10955             :     // You can return in an async generator.
   10956             :     "yield 1; return",
   10957             :     "yield * 1; return",
   10958             :     "yield 1; return 37",
   10959             :     "yield * 1; return 37",
   10960             :     "yield 1; return 37; yield 'dead';",
   10961             :     "yield * 1; return 37; yield * 'dead';",
   10962             :     // Yield/Await are still a valid key in object literals.
   10963             :     "({ yield: 1 })",
   10964             :     "({ get yield() { } })",
   10965             :     "({ await: 1 })",
   10966             :     "({ get await() { } })",
   10967             :     // And in assignment pattern computed properties
   10968             :     "({ [yield]: x } = { })",
   10969             :     "({ [await 1]: x } = { })",
   10970             :     // Yield without RHS.
   10971             :     "yield;",
   10972             :     "yield",
   10973             :     "yield\n",
   10974             :     "yield /* comment */"
   10975             :     "yield // comment\n"
   10976             :     "(yield)",
   10977             :     "[yield]",
   10978             :     "{yield}",
   10979             :     "yield, yield",
   10980             :     "yield; yield",
   10981             :     "(yield) ? yield : yield",
   10982             :     "(yield) \n ? yield : yield",
   10983             :     // If there is a newline before the next token, we don't look for RHS.
   10984             :     "yield\nfor (;;) {}",
   10985             :     "x = class extends (yield) {}",
   10986             :     "x = class extends f(yield) {}",
   10987             :     "x = class extends (null, yield) { }",
   10988             :     "x = class extends (a ? null : yield) { }",
   10989             :     "x = class extends (await 10) {}",
   10990             :     "x = class extends f(await 10) {}",
   10991             :     "x = class extends (null, await 10) { }",
   10992             :     "x = class extends (a ? null : await 10) { }",
   10993             : 
   10994             :     // More tests featuring AwaitExpressions
   10995             :     "await 10",
   10996             :     "await 10; return",
   10997             :     "await 10; return 20",
   10998             :     "await 10; return 20; yield 'dead'",
   10999             :     "await (yield 10)",
   11000             :     "await (yield 10); return",
   11001             :     "await (yield 10); return 20",
   11002             :     "await (yield 10); return 20; yield 'dead'",
   11003             :     "yield await 10",
   11004             :     "yield await 10; return",
   11005             :     "yield await 10; return 20",
   11006             :     "yield await 10; return 20; yield 'dead'",
   11007             :     "await /* comment */ 10",
   11008             :     "await // comment\n 10",
   11009             :     "yield await /* comment\n */ 10",
   11010             :     "yield await // comment\n 10",
   11011             :     "await (yield /* comment */)",
   11012             :     "await (yield // comment\n)",
   11013             :     nullptr
   11014           5 :   };
   11015             :   // clang-format on
   11016             : 
   11017           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
   11018           5 : }
   11019             : 
   11020       26644 : TEST(AsyncGeneratorErrors) {
   11021             :   // clang-format off
   11022             :   const char* context_data[][2] = {
   11023             :     { "async function * gen() {", "}" },
   11024             :     { "\"use strict\"; async function * gen() {", "}" },
   11025             :     { nullptr, nullptr }
   11026           5 :   };
   11027             : 
   11028             :   const char* statement_data[] = {
   11029             :     // Invalid yield expressions inside generators.
   11030             :     "var yield;",
   11031             :     "var await;",
   11032             :     "var foo, yield;",
   11033             :     "var foo, await;",
   11034             :     "try { } catch (yield) { }",
   11035             :     "try { } catch (await) { }",
   11036             :     "function yield() { }",
   11037             :     "function await() { }",
   11038             :     // The name of the NFE is bound in the generator, which does not permit
   11039             :     // yield or await to be identifiers.
   11040             :     "(async function * yield() { })",
   11041             :     "(async function * await() { })",
   11042             :     // Yield and Await aren't valid as a formal parameter for generators.
   11043             :     "async function * foo(yield) { }",
   11044             :     "(async function * foo(yield) { })",
   11045             :     "async function * foo(await) { }",
   11046             :     "(async function * foo(await) { })",
   11047             :     "yield = 1;",
   11048             :     "await = 1;",
   11049             :     "var foo = yield = 1;",
   11050             :     "var foo = await = 1;",
   11051             :     "++yield;",
   11052             :     "++await;",
   11053             :     "yield++;",
   11054             :     "await++;",
   11055             :     "yield *",
   11056             :     "(yield *)",
   11057             :     // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which
   11058             :     // is invalid.
   11059             :     "yield 3 + yield 4;",
   11060             :     "yield: 34",
   11061             :     "yield ? 1 : 2",
   11062             :     // Parses as yield (/ yield): invalid.
   11063             :     "yield / yield",
   11064             :     "+ yield",
   11065             :     "+ yield 3",
   11066             :     // Invalid (no newline allowed between yield and *).
   11067             :     "yield\n*3",
   11068             :     // Invalid (we see a newline, so we parse {yield:42} as a statement, not an
   11069             :     // object literal, and yield is not a valid label).
   11070             :     "yield\n{yield: 42}",
   11071             :     "yield /* comment */\n {yield: 42}",
   11072             :     "yield //comment\n {yield: 42}",
   11073             :     // Destructuring binding and assignment are both disallowed
   11074             :     "var [yield] = [42];",
   11075             :     "var [await] = [42];",
   11076             :     "var {foo: yield} = {a: 42};",
   11077             :     "var {foo: await} = {a: 42};",
   11078             :     "[yield] = [42];",
   11079             :     "[await] = [42];",
   11080             :     "({a: yield} = {a: 42});",
   11081             :     "({a: await} = {a: 42});",
   11082             :     // Also disallow full yield/await expressions on LHS
   11083             :     "var [yield 24] = [42];",
   11084             :     "var [await 24] = [42];",
   11085             :     "var {foo: yield 24} = {a: 42};",
   11086             :     "var {foo: await 24} = {a: 42};",
   11087             :     "[yield 24] = [42];",
   11088             :     "[await 24] = [42];",
   11089             :     "({a: yield 24} = {a: 42});",
   11090             :     "({a: await 24} = {a: 42});",
   11091             :     "for (yield 'x' in {});",
   11092             :     "for (await 'x' in {});",
   11093             :     "for (yield 'x' of {});",
   11094             :     "for (await 'x' of {});",
   11095             :     "for (yield 'x' in {} in {});",
   11096             :     "for (await 'x' in {} in {});",
   11097             :     "for (yield 'x' in {} of {});",
   11098             :     "for (await 'x' in {} of {});",
   11099             :     "class C extends yield { }",
   11100             :     "class C extends await { }",
   11101             :     nullptr
   11102           5 :   };
   11103             :   // clang-format on
   11104             : 
   11105           5 :   RunParserSyncTest(context_data, statement_data, kError);
   11106           5 : }
   11107             : 
   11108       26644 : TEST(LexicalLoopVariable) {
   11109             :   i::Isolate* isolate = CcTest::i_isolate();
   11110             :   i::HandleScope scope(isolate);
   11111           5 :   LocalContext env;
   11112             :   typedef std::function<void(const i::ParseInfo& info, i::DeclarationScope*)>
   11113             :       TestCB;
   11114         200 :   auto TestProgram = [isolate](const char* program, TestCB test) {
   11115             :     i::Factory* const factory = isolate->factory();
   11116             :     i::Handle<i::String> source =
   11117         100 :         factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
   11118          50 :     i::Handle<i::Script> script = factory->NewScript(source);
   11119         100 :     i::ParseInfo info(isolate, script);
   11120             : 
   11121             :     info.set_allow_lazy_parsing(false);
   11122          50 :     CHECK(i::parsing::ParseProgram(&info, isolate));
   11123          50 :     CHECK(i::Rewriter::Rewrite(&info));
   11124          50 :     CHECK(i::DeclarationScope::Analyze(&info));
   11125          50 :     i::DeclarationScope::AllocateScopeInfos(&info, isolate);
   11126          50 :     CHECK_NOT_NULL(info.literal());
   11127             : 
   11128             :     i::DeclarationScope* script_scope = info.literal()->scope();
   11129          50 :     CHECK(script_scope->is_script_scope());
   11130             : 
   11131             :     test(info, script_scope);
   11132          55 :   };
   11133             : 
   11134             :   // Check `let` loop variables is a stack local when not captured by
   11135             :   // an eval or closure within the area of the loop body.
   11136             :   const char* local_bindings[] = {
   11137             :       "function loop() {"
   11138             :       "  for (let loop_var = 0; loop_var < 10; ++loop_var) {"
   11139             :       "  }"
   11140             :       "  eval('0');"
   11141             :       "}",
   11142             : 
   11143             :       "function loop() {"
   11144             :       "  for (let loop_var = 0; loop_var < 10; ++loop_var) {"
   11145             :       "  }"
   11146             :       "  function foo() {}"
   11147             :       "  foo();"
   11148             :       "}",
   11149           5 :   };
   11150          25 :   for (const char* source : local_bindings) {
   11151          20 :     TestProgram(source, [=](const i::ParseInfo& info, i::DeclarationScope* s) {
   11152             :       i::Scope* fn = s->inner_scope();
   11153          10 :       CHECK(fn->is_function_scope());
   11154             : 
   11155             :       i::Scope* loop_block = fn->inner_scope();
   11156          10 :       if (loop_block->is_function_scope()) loop_block = loop_block->sibling();
   11157          10 :       CHECK(loop_block->is_block_scope());
   11158             : 
   11159             :       const i::AstRawString* var_name =
   11160          10 :           info.ast_value_factory()->GetOneByteString("loop_var");
   11161             :       i::Variable* loop_var = loop_block->LookupLocal(var_name);
   11162          10 :       CHECK_NOT_NULL(loop_var);
   11163          10 :       CHECK(loop_var->IsStackLocal());
   11164          10 :       CHECK_EQ(loop_block->ContextLocalCount(), 0);
   11165          10 :       CHECK_NULL(loop_block->inner_scope());
   11166          20 :     });
   11167             :   }
   11168             : 
   11169             :   // Check `let` loop variable is not a stack local, and is duplicated in the
   11170             :   // loop body to ensure capturing can work correctly.
   11171             :   // In this version of the test, the inner loop block's duplicate `loop_var`
   11172             :   // binding is not captured, and is a local.
   11173             :   const char* context_bindings1[] = {
   11174             :       "function loop() {"
   11175             :       "  for (let loop_var = eval('0'); loop_var < 10; ++loop_var) {"
   11176             :       "  }"
   11177             :       "}",
   11178             : 
   11179             :       "function loop() {"
   11180             :       "  for (let loop_var = (() => (loop_var, 0))(); loop_var < 10;"
   11181             :       "       ++loop_var) {"
   11182             :       "  }"
   11183           5 :       "}"};
   11184          25 :   for (const char* source : context_bindings1) {
   11185          20 :     TestProgram(source, [=](const i::ParseInfo& info, i::DeclarationScope* s) {
   11186             :       i::Scope* fn = s->inner_scope();
   11187          10 :       CHECK(fn->is_function_scope());
   11188             : 
   11189             :       i::Scope* loop_block = fn->inner_scope();
   11190          10 :       CHECK(loop_block->is_block_scope());
   11191             : 
   11192             :       const i::AstRawString* var_name =
   11193          10 :           info.ast_value_factory()->GetOneByteString("loop_var");
   11194             :       i::Variable* loop_var = loop_block->LookupLocal(var_name);
   11195          10 :       CHECK_NOT_NULL(loop_var);
   11196          10 :       CHECK(loop_var->IsContextSlot());
   11197          10 :       CHECK_EQ(loop_block->ContextLocalCount(), 1);
   11198             : 
   11199             :       i::Variable* loop_var2 = loop_block->inner_scope()->LookupLocal(var_name);
   11200          10 :       CHECK_NE(loop_var, loop_var2);
   11201          10 :       CHECK(loop_var2->IsStackLocal());
   11202          10 :       CHECK_EQ(loop_block->inner_scope()->ContextLocalCount(), 0);
   11203          20 :     });
   11204             :   }
   11205             : 
   11206             :   // Check `let` loop variable is not a stack local, and is duplicated in the
   11207             :   // loop body to ensure capturing can work correctly.
   11208             :   // In this version of the test, the inner loop block's duplicate `loop_var`
   11209             :   // binding is captured, and must be context allocated.
   11210             :   const char* context_bindings2[] = {
   11211             :       "function loop() {"
   11212             :       "  for (let loop_var = 0; loop_var < 10; ++loop_var) {"
   11213             :       "    eval('0');"
   11214             :       "  }"
   11215             :       "}",
   11216             : 
   11217             :       "function loop() {"
   11218             :       "  for (let loop_var = 0; loop_var < eval('10'); ++loop_var) {"
   11219             :       "  }"
   11220             :       "}",
   11221             : 
   11222             :       "function loop() {"
   11223             :       "  for (let loop_var = 0; loop_var < 10; eval('++loop_var')) {"
   11224             :       "  }"
   11225             :       "}",
   11226           5 :   };
   11227             : 
   11228          35 :   for (const char* source : context_bindings2) {
   11229          30 :     TestProgram(source, [=](const i::ParseInfo& info, i::DeclarationScope* s) {
   11230             :       i::Scope* fn = s->inner_scope();
   11231          15 :       CHECK(fn->is_function_scope());
   11232             : 
   11233             :       i::Scope* loop_block = fn->inner_scope();
   11234          15 :       CHECK(loop_block->is_block_scope());
   11235             : 
   11236             :       const i::AstRawString* var_name =
   11237          15 :           info.ast_value_factory()->GetOneByteString("loop_var");
   11238             :       i::Variable* loop_var = loop_block->LookupLocal(var_name);
   11239          15 :       CHECK_NOT_NULL(loop_var);
   11240          15 :       CHECK(loop_var->IsContextSlot());
   11241          15 :       CHECK_EQ(loop_block->ContextLocalCount(), 1);
   11242             : 
   11243             :       i::Variable* loop_var2 = loop_block->inner_scope()->LookupLocal(var_name);
   11244          15 :       CHECK_NE(loop_var, loop_var2);
   11245          15 :       CHECK(loop_var2->IsContextSlot());
   11246          15 :       CHECK_EQ(loop_block->inner_scope()->ContextLocalCount(), 1);
   11247          30 :     });
   11248             :   }
   11249             : 
   11250             :   // Similar to the above, but the first block scope's variables are not
   11251             :   // captured due to the closure occurring in a nested scope.
   11252             :   const char* context_bindings3[] = {
   11253             :       "function loop() {"
   11254             :       "  for (let loop_var = 0; loop_var < 10; ++loop_var) {"
   11255             :       "    (() => loop_var)();"
   11256             :       "  }"
   11257             :       "}",
   11258             : 
   11259             :       "function loop() {"
   11260             :       "  for (let loop_var = 0; loop_var < (() => (loop_var, 10))();"
   11261             :       "       ++loop_var) {"
   11262             :       "  }"
   11263             :       "}",
   11264             : 
   11265             :       "function loop() {"
   11266             :       "  for (let loop_var = 0; loop_var < 10; (() => ++loop_var)()) {"
   11267             :       "  }"
   11268             :       "}",
   11269           5 :   };
   11270             : 
   11271          35 :   for (const char* source : context_bindings3) {
   11272          30 :     TestProgram(source, [=](const i::ParseInfo& info, i::DeclarationScope* s) {
   11273             :       i::Scope* fn = s->inner_scope();
   11274          15 :       CHECK(fn->is_function_scope());
   11275             : 
   11276             :       i::Scope* loop_block = fn->inner_scope();
   11277          15 :       CHECK(loop_block->is_block_scope());
   11278             : 
   11279             :       const i::AstRawString* var_name =
   11280          15 :           info.ast_value_factory()->GetOneByteString("loop_var");
   11281             :       i::Variable* loop_var = loop_block->LookupLocal(var_name);
   11282          15 :       CHECK_NOT_NULL(loop_var);
   11283          15 :       CHECK(loop_var->IsStackLocal());
   11284          15 :       CHECK_EQ(loop_block->ContextLocalCount(), 0);
   11285             : 
   11286             :       i::Variable* loop_var2 = loop_block->inner_scope()->LookupLocal(var_name);
   11287          15 :       CHECK_NE(loop_var, loop_var2);
   11288          15 :       CHECK(loop_var2->IsContextSlot());
   11289          15 :       CHECK_EQ(loop_block->inner_scope()->ContextLocalCount(), 1);
   11290          30 :     });
   11291             :   }
   11292           5 : }
   11293             : 
   11294       26644 : TEST(PrivateNamesSyntaxErrorEarly) {
   11295             :   i::Isolate* isolate = CcTest::i_isolate();
   11296             :   i::HandleScope scope(isolate);
   11297           5 :   LocalContext env;
   11298             : 
   11299             :   const char* context_data[][2] = {
   11300           5 :       {"", ""}, {"\"use strict\";", ""}, {nullptr, nullptr}};
   11301             : 
   11302             :   const char* statement_data[] = {
   11303             :       "class A {"
   11304             :       "  foo() { return this.#bar; }"
   11305             :       "}",
   11306             : 
   11307             :       "let A = class {"
   11308             :       "  foo() { return this.#bar; }"
   11309             :       "}",
   11310             : 
   11311             :       "class A {"
   11312             :       "  #foo;  "
   11313             :       "  bar() { return this.#baz; }"
   11314             :       "}",
   11315             : 
   11316             :       "let A = class {"
   11317             :       "  #foo;  "
   11318             :       "  bar() { return this.#baz; }"
   11319             :       "}",
   11320             : 
   11321             :       "class A {"
   11322             :       "  bar() {"
   11323             :       "    class D { #baz = 1; };"
   11324             :       "    return this.#baz;"
   11325             :       "  }"
   11326             :       "}",
   11327             : 
   11328             :       "let A = class {"
   11329             :       "  bar() {"
   11330             :       "    class D { #baz = 1; };"
   11331             :       "    return this.#baz;"
   11332             :       "  }"
   11333             :       "}",
   11334             : 
   11335             :       "a.#bar",
   11336             : 
   11337             :       "class Foo {};"
   11338             :       "Foo.#bar;",
   11339             : 
   11340             :       "let Foo = class {};"
   11341             :       "Foo.#bar;",
   11342             : 
   11343             :       "class Foo {};"
   11344             :       "(new Foo).#bar;",
   11345             : 
   11346             :       "let Foo = class {};"
   11347             :       "(new Foo).#bar;",
   11348             : 
   11349             :       "class Foo { #bar; };"
   11350             :       "(new Foo).#bar;",
   11351             : 
   11352             :       "let Foo = class { #bar; };"
   11353             :       "(new Foo).#bar;",
   11354             : 
   11355             :       "function t(){"
   11356             :       "  class Foo { getA() { return this.#foo; } }"
   11357             :       "}",
   11358             : 
   11359             :       "function t(){"
   11360             :       "  return class { getA() { return this.#foo; } }"
   11361             :       "}",
   11362             : 
   11363           5 :       nullptr};
   11364             : 
   11365             :   static const ParserFlag flags[] = {kAllowHarmonyPrivateFields};
   11366           5 :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0, flags, 1);
   11367           5 :   RunParserSyncTest(context_data, statement_data, kError);
   11368           5 : }
   11369             : 
   11370       26644 : TEST(HashbangSyntax) {
   11371             :   const char* context_data[][2] = {
   11372             :       {"#!\n", ""},
   11373             :       {"#!---IGNORED---\n", ""},
   11374             :       {"#!---IGNORED---\r", ""},
   11375             :       {"#!---IGNORED---\xE2\x80\xA8", ""},  // <U+2028>
   11376             :       {"#!---IGNORED---\xE2\x80\xA9", ""},  // <U+2029>
   11377           5 :       {nullptr, nullptr}};
   11378             : 
   11379           5 :   const char* data[] = {"function\nFN\n(\n)\n {\n}\nFN();", nullptr};
   11380             : 
   11381           5 :   i::FLAG_harmony_hashbang = true;
   11382           5 :   RunParserSyncTest(context_data, data, kSuccess);
   11383             :   RunParserSyncTest(context_data, data, kSuccess, nullptr, 0, nullptr, 0,
   11384           5 :                     nullptr, 0, true);
   11385             : 
   11386           5 :   i::FLAG_harmony_hashbang = false;
   11387           5 :   RunParserSyncTest(context_data, data, kError);
   11388             :   RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0, nullptr,
   11389           5 :                     0, true);
   11390           5 : }
   11391             : 
   11392       26644 : TEST(HashbangSyntaxErrors) {
   11393           5 :   const char* file_context_data[][2] = {{"", ""}, {nullptr, nullptr}};
   11394             :   const char* other_context_data[][2] = {{"/**/", ""},
   11395             :                                          {"//---\n", ""},
   11396             :                                          {";", ""},
   11397             :                                          {"function fn() {", "}"},
   11398             :                                          {"function* fn() {", "}"},
   11399             :                                          {"async function fn() {", "}"},
   11400             :                                          {"async function* fn() {", "}"},
   11401             :                                          {"() => {", "}"},
   11402             :                                          {"() => ", ""},
   11403             :                                          {"function fn(a = ", ") {}"},
   11404             :                                          {"function* fn(a = ", ") {}"},
   11405             :                                          {"async function fn(a = ", ") {}"},
   11406             :                                          {"async function* fn(a = ", ") {}"},
   11407             :                                          {"(a = ", ") => {}"},
   11408             :                                          {"(a = ", ") => a"},
   11409             :                                          {"class k {", "}"},
   11410             :                                          {"[", "]"},
   11411             :                                          {"{", "}"},
   11412             :                                          {"({", "})"},
   11413           5 :                                          {nullptr, nullptr}};
   11414             : 
   11415             :   const char* invalid_hashbang_data[] = {// Encoded characters are not allowed
   11416             :                                          "#\\u0021\n"
   11417             :                                          "#\\u{21}\n",
   11418             :                                          "#\\x21\n",
   11419             :                                          "#\\041\n",
   11420             :                                          "\\u0023!\n",
   11421             :                                          "\\u{23}!\n",
   11422             :                                          "\\x23!\n",
   11423             :                                          "\\043!\n",
   11424             :                                          "\\u0023\\u0021\n",
   11425             : 
   11426             :                                          "\n#!---IGNORED---\n",
   11427             :                                          " #!---IGNORED---\n",
   11428           5 :                                          nullptr};
   11429           5 :   const char* hashbang_data[] = {"#!\n", "#!---IGNORED---\n", nullptr};
   11430             : 
   11431          15 :   auto SyntaxErrorTest = [](const char* context_data[][2], const char* data[]) {
   11432          15 :     i::FLAG_harmony_hashbang = true;
   11433          15 :     RunParserSyncTest(context_data, data, kError);
   11434             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
   11435          15 :                       nullptr, 0, true);
   11436             : 
   11437          15 :     i::FLAG_harmony_hashbang = false;
   11438          15 :     RunParserSyncTest(context_data, data, kError);
   11439             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
   11440          15 :                       nullptr, 0, true);
   11441          15 :   };
   11442             : 
   11443           5 :   SyntaxErrorTest(file_context_data, invalid_hashbang_data);
   11444           5 :   SyntaxErrorTest(other_context_data, invalid_hashbang_data);
   11445           5 :   SyntaxErrorTest(other_context_data, hashbang_data);
   11446           5 : }
   11447             : 
   11448             : }  // namespace test_parsing
   11449             : }  // namespace internal
   11450       79917 : }  // namespace v8

Generated by: LCOV version 1.10