LCOV - code coverage report
Current view: top level - test/cctest - test-parsing.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 2335 2412 96.8 %
Date: 2019-02-19 Functions: 273 299 91.3 %

          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       25880 : TEST(AutoSemicolonToken) {
      86         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
      87             :     Token::Value token = static_cast<Token::Value>(i);
      88        1120 :     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       25880 : TEST(AnyIdentifierToken) {
     111         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     112             :     Token::Value token = static_cast<Token::Value>(i);
     113        1120 :     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       25880 : TEST(CallableToken) {
     137         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     138             :     Token::Value token = static_cast<Token::Value>(i);
     139        1120 :     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       25880 : TEST(IsValidIdentifierToken) {
     167         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     168             :     Token::Value token = static_cast<Token::Value>(i);
     169        1120 :     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        3360 :       for (int is_generator = 0; is_generator < 2; is_generator++) {
     173        4480 :         for (int disallow_await = 0; disallow_await < 2; disallow_await++) {
     174        8960 :           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       25880 : TEST(IsStrictReservedWord) {
     199         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     200             :     Token::Value token = static_cast<Token::Value>(i);
     201        1120 :     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       25880 : TEST(IsLiteralToken) {
     223         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     224             :     Token::Value token = static_cast<Token::Value>(i);
     225        1120 :     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       25880 : TEST(AssignmentOp) {
     243         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     244             :     Token::Value token = static_cast<Token::Value>(i);
     245        1120 :     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       25880 : TEST(ArrowOrAssignmentOp) {
     254         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     255             :     Token::Value token = static_cast<Token::Value>(i);
     256        1120 :     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       25880 : TEST(BinaryOp) {
     276         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     277             :     Token::Value token = static_cast<Token::Value>(i);
     278        1120 :     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       25880 : TEST(CompareOp) {
     301         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     302             :     Token::Value token = static_cast<Token::Value>(i);
     303        1120 :     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       25880 : TEST(IsOrderedRelationalCompareOp) {
     320         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     321             :     Token::Value token = static_cast<Token::Value>(i);
     322        1120 :     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       25880 : TEST(IsEqualityOp) {
     338         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     339             :     Token::Value token = static_cast<Token::Value>(i);
     340        1120 :     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       25880 : TEST(IsBitOp) {
     360         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     361             :     Token::Value token = static_cast<Token::Value>(i);
     362        1120 :     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       25880 : TEST(IsUnaryOp) {
     382         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     383             :     Token::Value token = static_cast<Token::Value>(i);
     384        1120 :     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       25880 : TEST(IsPropertyOrCall) {
     402         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     403             :     Token::Value token = static_cast<Token::Value>(i);
     404        1120 :     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       25880 : TEST(IsMember) {
     441         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     442             :     Token::Value token = static_cast<Token::Value>(i);
     443        1120 :     CHECK_EQ(TokenIsMember(token), Token::IsMember(token));
     444             :   }
     445           5 : }
     446             : 
     447       25880 : TEST(IsTemplate) {
     448         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     449             :     Token::Value token = static_cast<Token::Value>(i);
     450        1120 :     CHECK_EQ(TokenIsTemplate(token), Token::IsTemplate(token));
     451             :   }
     452           5 : }
     453             : 
     454       25880 : TEST(IsProperty) {
     455         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     456             :     Token::Value token = static_cast<Token::Value>(i);
     457        1120 :     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       25880 : TEST(IsCountOp) {
     472         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     473             :     Token::Value token = static_cast<Token::Value>(i);
     474        1120 :     CHECK_EQ(TokenIsCountOp(token), Token::IsCountOp(token));
     475             :   }
     476           5 : }
     477             : 
     478       25880 : TEST(IsUnaryOrCountOp) {
     479         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     480             :     Token::Value token = static_cast<Token::Value>(i);
     481        1645 :     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       25880 : TEST(IsShiftOp) {
     498         565 :   for (int i = 0; i < Token::NUM_TOKENS; i++) {
     499             :     Token::Value token = static_cast<Token::Value>(i);
     500        1120 :     CHECK_EQ(TokenIsShiftOp(token), Token::IsShiftOp(token));
     501             :   }
     502           5 : }
     503             : 
     504       25880 : 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         220 :   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         860 :     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       25880 : TEST(ScanHTMLEndComments) {
     563           5 :   v8::V8::Initialize();
     564           5 :   v8::Isolate* isolate = CcTest::isolate();
     565         360 :   i::Isolate* i_isolate = CcTest::i_isolate();
     566           5 :   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           5 :   uintptr_t stack_limit = i_isolate->stack_guard()->real_climit();
     617         105 :   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         200 :         &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          20 :   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          40 :         &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           5 :   }
     654           5 : }
     655             : 
     656       25880 : 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           0 : class ScriptResource : public v8::String::ExternalOneByteStringResource {
     678             :  public:
     679             :   ScriptResource(const char* data, size_t length)
     680             :       : data_(data), length_(length) { }
     681             : 
     682           0 :   const char* data() const override { return data_; }
     683           0 :   size_t length() const override { return length_; }
     684             : 
     685             :  private:
     686             :   const char* data_;
     687             :   size_t length_;
     688             : };
     689             : 
     690             : 
     691       25880 : TEST(StandAlonePreParser) {
     692           5 :   v8::V8::Initialize();
     693          90 :   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           5 :   uintptr_t stack_limit = i_isolate->stack_guard()->real_climit();
     707          35 :   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          60 :         &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       25880 : TEST(StandAlonePreParserNoNatives) {
     729           5 :   v8::V8::Initialize();
     730             : 
     731          30 :   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           5 :   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
     739          15 :   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          20 :                                          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       25880 : TEST(RegressChromium62639) {
     762           5 :   v8::V8::Initialize();
     763          15 :   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          10 :                                        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       25880 : TEST(PreParseOverflow) {
     795           5 :   v8::V8::Initialize();
     796          15 :   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           5 :   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          10 :                                        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          35 :   i::Scanner scanner(stream, false);
     828          35 :   scanner.Initialize();
     829             : 
     830             :   int i = 0;
     831         190 :   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         225 :   } while (expected_tokens[i] != i::Token::ILLEGAL);
     840          35 : }
     841             : 
     842             : 
     843       25880 : 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          35 :   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         220 :       HashSeed(CcTest::i_isolate()));
     906         110 :   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         110 :   i::Vector<const uint8_t> actual = content.ToOneByteVector();
     914         510 :   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       25880 : 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       25880 : 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           5 :   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          20 :   for (unsigned j = 0; j < arraysize(surroundings); ++j) {
    1041         570 :     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             :           factory->NewStringFromUtf8(i::CStrVector(program.start()))
    1055         780 :               .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         390 :       i::DeclarationScope* script_scope = info.literal()->scope();
    1068         390 :       CHECK(script_scope->is_script_scope());
    1069             : 
    1070         190 :       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           5 :   }
    1103           5 : }
    1104             : 
    1105          75 : static void CheckParsesToNumber(const char* source) {
    1106          75 :   v8::V8::Initialize();
    1107          75 :   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             :       factory->NewStringFromUtf8(i::CStrVector(full_source.c_str()))
    1118         150 :           .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         150 :   i::FunctionLiteral* fun = decl->AsFunctionDeclaration()->fun();
    1131          75 :   CHECK_EQ(fun->body()->length(), 1);
    1132         150 :   CHECK(fun->body()->at(0)->IsReturnStatement());
    1133         150 :   i::ReturnStatement* ret = fun->body()->at(0)->AsReturnStatement();
    1134          75 :   i::Literal* lit = ret->expression()->AsLiteral();
    1135         150 :   CHECK(lit->IsNumberLiteral());
    1136          75 : }
    1137             : 
    1138             : 
    1139       25880 : 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       25880 : 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           5 :   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         260 :   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             :     i::Handle<i::String> source = factory->NewStringFromUtf8(
    1428         510 :         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        1020 :     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         765 :     i::Scope* inner_scope = scope->inner_scope();
    1443             :     DCHECK_NOT_NULL(inner_scope);
    1444             :     DCHECK_NULL(inner_scope->sibling());
    1445         510 :     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           5 :   }
    1451           5 : }
    1452             : 
    1453             : 
    1454       25880 : 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           5 :   v8::HandleScope handles(CcTest::isolate());
    1470             :   i::FunctionLiteral* function;
    1471             : 
    1472          15 :   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          10 :     i::ParseInfo info(isolate, script);
    1478          10 :     i::parsing::ParseProgram(&info, isolate);
    1479          10 :     function = info.literal();
    1480          10 :     CHECK_NOT_NULL(function);
    1481          10 :     CHECK_EQ(1, function->body()->length());
    1482          10 :     i::FunctionLiteral* inner =
    1483          20 :         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          20 :                 ->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          15 :   }
    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      521129 : void SetGlobalFlags(base::EnumSet<ParserFlag> flags) {
    1544      521129 :   i::FLAG_allow_natives_syntax = flags.contains(kAllowNatives);
    1545      521129 :   i::FLAG_harmony_public_fields = flags.contains(kAllowHarmonyPublicFields);
    1546      521129 :   i::FLAG_harmony_private_fields = flags.contains(kAllowHarmonyPrivateFields);
    1547      521129 :   i::FLAG_harmony_private_methods = flags.contains(kAllowHarmonyPrivateMethods);
    1548      521129 :   i::FLAG_harmony_static_fields = flags.contains(kAllowHarmonyStaticFields);
    1549      521129 :   i::FLAG_harmony_dynamic_import = flags.contains(kAllowHarmonyDynamicImport);
    1550      521129 :   i::FLAG_harmony_import_meta = flags.contains(kAllowHarmonyImportMeta);
    1551             :   i::FLAG_harmony_numeric_separator =
    1552      521129 :       flags.contains(kAllowHarmonyNumericSeparator);
    1553      521129 : }
    1554             : 
    1555      520149 : 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      520149 : }
    1572             : 
    1573      521129 : 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     1560447 :   i::Isolate* isolate = CcTest::i_isolate();
    1579             :   i::Factory* factory = isolate->factory();
    1580             : 
    1581      521129 :   uintptr_t stack_limit = isolate->stack_guard()->real_climit();
    1582             : 
    1583             :   // Preparse the data.
    1584             :   i::PendingCompilationErrorHandler pending_error_handler;
    1585      521129 :   if (test_preparser) {
    1586             :     std::unique_ptr<i::Utf16CharacterStream> stream(
    1587      520149 :         i::ScannerStream::For(isolate, source));
    1588     1040298 :     i::Scanner scanner(stream.get(), is_module);
    1589     1040298 :     i::Zone zone(isolate->allocator(), ZONE_NAME);
    1590             :     i::AstValueFactory ast_value_factory(&zone, isolate->ast_string_constants(),
    1591     1040298 :                                          HashSeed(isolate));
    1592             :     i::PreParser preparser(&zone, &scanner, stack_limit, &ast_value_factory,
    1593             :                            &pending_error_handler,
    1594             :                            isolate->counters()->runtime_call_stats(),
    1595     1040298 :                            isolate->logger(), -1, is_module);
    1596      520149 :     SetParserFlags(&preparser, flags);
    1597      520149 :     scanner.Initialize();
    1598      520149 :     i::PreParser::PreParseResult result = preparser.PreParseProgram();
    1599      520149 :     CHECK_EQ(i::PreParser::kPreParseSuccess, result);
    1600             :   }
    1601             : 
    1602             :   // Parse the data
    1603             :   i::FunctionLiteral* function;
    1604             :   {
    1605      521129 :     SetGlobalFlags(flags);
    1606      521129 :     i::Handle<i::Script> script = factory->NewScript(source);
    1607      521129 :     i::ParseInfo info(isolate, script);
    1608             :     info.set_allow_lazy_parsing(flags.contains(kAllowLazy));
    1609      521129 :     if (is_module) info.set_module();
    1610      521129 :     i::parsing::ParseProgram(&info, isolate);
    1611      521129 :     function = info.literal();
    1612             :   }
    1613             : 
    1614             :   // Check that preparsing fails iff parsing fails.
    1615      521129 :   if (function == nullptr) {
    1616             :     // Extract exception from the parser.
    1617      272590 :     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      272590 :         i::JSReceiver::GetProperty(isolate, exception_handle, "message")
    1622      545180 :             .ToHandleChecked());
    1623      272590 :     isolate->clear_pending_exception();
    1624             : 
    1625      272590 :     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      272590 :     if (test_preparser && !pending_error_handler.has_pending_error() &&
    1636           0 :         !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      532940 :     if (test_preparser && !ignore_error_msg &&
    1648      260350 :         !pending_error_handler.has_error_unidentifiable_by_preparser()) {
    1649             :       i::Handle<i::String> preparser_message =
    1650        2502 :           pending_error_handler.FormatErrorMessageForTest(CcTest::i_isolate());
    1651        2502 :       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      248539 :   } 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      248539 :   } 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      521129 : }
    1681             : 
    1682      133173 : 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      266346 :           ->NewStringFromUtf8(Vector<const char>(source, strlen(source)))
    1695      266346 :           .ToHandleChecked();
    1696      654302 :   for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
    1697             :     base::EnumSet<ParserFlag> flags;
    1698     1032972 :     for (size_t flag_index = 0; flag_index < varying_flags_length;
    1699             :          ++flag_index) {
    1700     1032972 :       if ((bits & (1 << flag_index)) != 0) flags.Add(varying_flags[flag_index]);
    1701             :     }
    1702      147250 :     for (size_t flag_index = 0; flag_index < always_true_flags_length;
    1703             :          ++flag_index) {
    1704      147250 :       flags.Add(always_true_flags[flag_index]);
    1705             :     }
    1706           0 :     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             :     TestParserSyncWithFlags(str, flags, result, is_module, test_preparser,
    1711      521129 :                             ignore_error_msg);
    1712             :   }
    1713      133173 : }
    1714             : 
    1715             : 
    1716       25876 : 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           1 :   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             :   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    1754           2 :       i::GetCurrentStackPosition() - 128 * 1024);
    1755             : 
    1756          14 :   for (int i = 0; context_data[i][0] != nullptr; ++i) {
    1757         455 :     for (int j = 0; statement_data[j] != nullptr; ++j) {
    1758        2275 :       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           2 :   TestParserSync("%DebugPrint(123)", flags3, arraysize(flags3));
    1788           1 : }
    1789             : 
    1790             : 
    1791       25880 : 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           5 :   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           5 :                   *exception));
    1813           5 : }
    1814             : 
    1815        1570 : 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        1570 :   v8::HandleScope handles(CcTest::isolate());
    1823        1570 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    1824             :   v8::Context::Scope context_scope(context);
    1825             : 
    1826             :   CcTest::i_isolate()->stack_guard()->SetStackLimit(
    1827        3140 :       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        1570 :   if (flags == nullptr) {
    1837             :     flags = default_flags;
    1838             :     flags_len = arraysize(default_flags);
    1839        1550 :     if (always_true_flags != nullptr || always_false_flags != nullptr) {
    1840             :       // Remove always_true/false_flags from default_flags (if present).
    1841         185 :       CHECK((always_true_flags != nullptr) == (always_true_len > 0));
    1842         185 :       CHECK((always_false_flags != nullptr) == (always_false_len > 0));
    1843         185 :       generated_flags = new ParserFlag[flags_len + always_true_len];
    1844             :       int flag_index = 0;
    1845         555 :       for (int i = 0; i < flags_len; ++i) {
    1846             :         bool use_flag = true;
    1847         560 :         for (int j = 0; use_flag && j < always_true_len; ++j) {
    1848         560 :           if (flags[i] == always_true_flags[j]) use_flag = false;
    1849             :         }
    1850           0 :         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         370 :         if (use_flag) generated_flags[flag_index++] = flags[i];
    1854             :       }
    1855             :       flags_len = flag_index;
    1856             :       flags = generated_flags;
    1857             :     }
    1858             :   }
    1859        8365 :   for (int i = 0; context_data[i][0] != nullptr; ++i) {
    1860      130895 :     for (int j = 0; statement_data[j] != nullptr; ++j) {
    1861      130895 :       int kPrefixLen = i::StrLength(context_data[i][0]);
    1862             :       int kStatementLen = i::StrLength(statement_data[j]);
    1863      130895 :       int kSuffixLen = i::StrLength(context_data[i][1]);
    1864      130895 :       int kProgramSize = kPrefixLen + kStatementLen + kSuffixLen;
    1865             : 
    1866             :       // Plug the source code pieces together.
    1867      130895 :       i::ScopedVector<char> program(kProgramSize + 1);
    1868             :       int length = i::SNPrintF(program,
    1869             :                                "%s%s%s",
    1870             :                                context_data[i][0],
    1871             :                                statement_data[j],
    1872      130895 :                                context_data[i][1]);
    1873      130895 :       PrintF("%s\n", program.start());
    1874      130895 :       CHECK_EQ(length, kProgramSize);
    1875             :       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      130895 :                      ignore_error_msg);
    1879             :     }
    1880             :   }
    1881        3140 :   delete[] generated_flags;
    1882        1570 : }
    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             :   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       25880 : TEST(NumericSeparator) {
    1897           5 :   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          10 :   RunParserSyncTest(context_data, statement_data, kError);
    1912           5 : }
    1913             : 
    1914       25880 : TEST(NumericSeparatorErrors) {
    1915           5 :   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          10 :   RunParserSyncTest(context_data, statement_data, kError);
    1932           5 : }
    1933             : 
    1934       25880 : TEST(NumericSeparatorImplicitOctalsErrors) {
    1935           5 :   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          10 :   RunParserSyncTest(context_data, statement_data, kError);
    1950           5 : }
    1951             : 
    1952       25880 : TEST(NumericSeparatorUnicodeEscapeSequencesErrors) {
    1953           5 :   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          10 :   RunParserSyncTest(context_data, statement_data, kError);
    1966           5 : }
    1967             : 
    1968       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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       25880 : 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      327675 :   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       25880 : 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       25880 : 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       25880 : 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       25880 : 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           5 :   v8::HandleScope scope(isolate);
    3083          10 :   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             :   ExpectString("%FunctionGetInferredName(obj3[1])",
    3111           5 :                "obj3.(anonymous function)");
    3112           5 :   ExpectString("%FunctionGetInferredName(obj4[1])", "");
    3113           5 :   ExpectString("%FunctionGetInferredName(obj5['foo9'])", "obj5.foo9");
    3114          10 :   ExpectString("%FunctionGetInferredName(obj6.obj7.foo10)", "obj6.obj7.foo10");
    3115           5 : }
    3116             : 
    3117             : 
    3118       25880 : TEST(FuncNameInferrerTwoByte) {
    3119             :   // Tests function name inferring in cases where some parts of the inferred
    3120             :   // function name are two-byte strings.
    3121           5 :   i::FLAG_allow_natives_syntax = true;
    3122           5 :   v8::Isolate* isolate = CcTest::isolate();
    3123           5 :   v8::HandleScope scope(isolate);
    3124          10 :   LocalContext env;
    3125             :   uint16_t* two_byte_source = AsciiToTwoByteString(
    3126             :       "var obj1 = { oXj2 : { foo1: function() {} } }; "
    3127           5 :       "%FunctionGetInferredName(obj1.oXj2.foo1)");
    3128           5 :   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
    3129             :   // Make it really non-Latin1 (replace the Xs with a non-Latin1 character).
    3130           5 :   two_byte_source[14] = two_byte_source[78] = two_byte_name[6] = 0x010D;
    3131             :   v8::Local<v8::String> source =
    3132             :       v8::String::NewFromTwoByte(isolate, two_byte_source,
    3133             :                                  v8::NewStringType::kNormal)
    3134          10 :           .ToLocalChecked();
    3135           5 :   v8::Local<v8::Value> result = CompileRun(source);
    3136           5 :   CHECK(result->IsString());
    3137             :   v8::Local<v8::String> expected_name =
    3138             :       v8::String::NewFromTwoByte(isolate, two_byte_name,
    3139             :                                  v8::NewStringType::kNormal)
    3140           5 :           .ToLocalChecked();
    3141          10 :   CHECK(result->Equals(isolate->GetCurrentContext(), expected_name).FromJust());
    3142             :   i::DeleteArray(two_byte_source);
    3143           5 :   i::DeleteArray(two_byte_name);
    3144           5 : }
    3145             : 
    3146             : 
    3147       25880 : TEST(FuncNameInferrerEscaped) {
    3148             :   // The same as FuncNameInferrerTwoByte, except that we express the two-byte
    3149             :   // character as a Unicode escape.
    3150           5 :   i::FLAG_allow_natives_syntax = true;
    3151           5 :   v8::Isolate* isolate = CcTest::isolate();
    3152           5 :   v8::HandleScope scope(isolate);
    3153          10 :   LocalContext env;
    3154             :   uint16_t* two_byte_source = AsciiToTwoByteString(
    3155             :       "var obj1 = { o\\u010dj2 : { foo1: function() {} } }; "
    3156           5 :       "%FunctionGetInferredName(obj1.o\\u010dj2.foo1)");
    3157           5 :   uint16_t* two_byte_name = AsciiToTwoByteString("obj1.oXj2.foo1");
    3158             :   // Fix to correspond to the non-ASCII name in two_byte_source.
    3159           5 :   two_byte_name[6] = 0x010D;
    3160             :   v8::Local<v8::String> source =
    3161             :       v8::String::NewFromTwoByte(isolate, two_byte_source,
    3162             :                                  v8::NewStringType::kNormal)
    3163          10 :           .ToLocalChecked();
    3164           5 :   v8::Local<v8::Value> result = CompileRun(source);
    3165           5 :   CHECK(result->IsString());
    3166             :   v8::Local<v8::String> expected_name =
    3167             :       v8::String::NewFromTwoByte(isolate, two_byte_name,
    3168             :                                  v8::NewStringType::kNormal)
    3169           5 :           .ToLocalChecked();
    3170          10 :   CHECK(result->Equals(isolate->GetCurrentContext(), expected_name).FromJust());
    3171             :   i::DeleteArray(two_byte_source);
    3172           5 :   i::DeleteArray(two_byte_name);
    3173           5 : }
    3174             : 
    3175             : 
    3176       25880 : TEST(RegressionLazyFunctionWithErrorWithArg) {
    3177             :   // Test only applies when lazy parsing.
    3178           5 :   if (!i::FLAG_lazy) return;
    3179             : 
    3180             :   // The bug occurred when a lazy function had an error which requires a
    3181             :   // parameter (such as "unknown label" here). The error message was processed
    3182             :   // before the AstValueFactory containing the error message string was
    3183             :   // internalized.
    3184           5 :   v8::Isolate* isolate = CcTest::isolate();
    3185           5 :   v8::HandleScope scope(isolate);
    3186          10 :   LocalContext env;
    3187           5 :   i::FLAG_lazy = true;
    3188             :   CompileRun("function this_is_lazy() {\n"
    3189             :              "  break p;\n"
    3190             :              "}\n"
    3191           5 :              "this_is_lazy();\n");
    3192             : }
    3193             : 
    3194             : 
    3195       25880 : TEST(SerializationOfMaybeAssignmentFlag) {
    3196           5 :   i::Isolate* isolate = CcTest::i_isolate();
    3197             :   i::Factory* factory = isolate->factory();
    3198             :   i::HandleScope scope(isolate);
    3199          10 :   LocalContext env;
    3200             : 
    3201             :   const char* src =
    3202             :       "function h() {"
    3203             :       "  var result = [];"
    3204             :       "  function f() {"
    3205             :       "    result.push(2);"
    3206             :       "  }"
    3207             :       "  function assertResult(r) {"
    3208             :       "    f();"
    3209             :       "    result = [];"
    3210             :       "  }"
    3211             :       "  assertResult([2]);"
    3212             :       "  assertResult([2]);"
    3213             :       "  return f;"
    3214             :       "};"
    3215             :       "h();";
    3216             : 
    3217           5 :   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
    3218           5 :   i::SNPrintF(program, "%s", src);
    3219           5 :   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
    3220          10 :   source->PrintOn(stdout);
    3221             :   printf("\n");
    3222          10 :   i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME);
    3223             :   v8::Local<v8::Value> v = CompileRun(src);
    3224           5 :   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    3225           5 :   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
    3226           5 :   i::Context context = f->context();
    3227             :   i::AstValueFactory avf(&zone, isolate->ast_string_constants(),
    3228          10 :                          HashSeed(isolate));
    3229          10 :   const i::AstRawString* name = avf.GetOneByteString("result");
    3230           5 :   avf.Internalize(isolate);
    3231             :   i::Handle<i::String> str = name->string();
    3232          10 :   CHECK(str->IsInternalizedString());
    3233             :   i::DeclarationScope* script_scope =
    3234           5 :       new (&zone) i::DeclarationScope(&zone, &avf);
    3235             :   i::Scope* s = i::Scope::DeserializeScopeChain(
    3236             :       isolate, &zone, context->scope_info(), script_scope, &avf,
    3237           5 :       i::Scope::DeserializationMode::kIncludingVariables);
    3238           5 :   CHECK(s != script_scope);
    3239           5 :   CHECK_NOT_NULL(name);
    3240             : 
    3241             :   // Get result from h's function context (that is f's context)
    3242           5 :   i::Variable* var = s->LookupForTesting(name);
    3243             : 
    3244           5 :   CHECK_NOT_NULL(var);
    3245             :   // Maybe assigned should survive deserialization
    3246           5 :   CHECK_EQ(var->maybe_assigned(), i::kMaybeAssigned);
    3247             :   // TODO(sigurds) Figure out if is_used should survive context serialization.
    3248           5 : }
    3249             : 
    3250             : 
    3251       25880 : TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) {
    3252          10 :   i::Isolate* isolate = CcTest::i_isolate();
    3253             :   i::Factory* factory = isolate->factory();
    3254             :   i::HandleScope scope(isolate);
    3255          10 :   LocalContext env;
    3256             : 
    3257             :   const char* src =
    3258             :       "function f(x) {"
    3259             :       "    var a = arguments;"
    3260             :       "    function g(i) {"
    3261             :       "      ++a[0];"
    3262             :       "    };"
    3263             :       "    return g;"
    3264             :       "  }"
    3265             :       "f(0);";
    3266             : 
    3267           5 :   i::ScopedVector<char> program(Utf8LengthHelper(src) + 1);
    3268           5 :   i::SNPrintF(program, "%s", src);
    3269           5 :   i::Handle<i::String> source = factory->InternalizeUtf8String(program.start());
    3270          10 :   source->PrintOn(stdout);
    3271             :   printf("\n");
    3272          10 :   i::Zone zone(isolate->allocator(), ZONE_NAME);
    3273             :   v8::Local<v8::Value> v = CompileRun(src);
    3274           5 :   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    3275           5 :   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
    3276           5 :   i::Context context = f->context();
    3277             :   i::AstValueFactory avf(&zone, isolate->ast_string_constants(),
    3278          10 :                          HashSeed(isolate));
    3279           5 :   const i::AstRawString* name_x = avf.GetOneByteString("x");
    3280           5 :   avf.Internalize(isolate);
    3281             : 
    3282             :   i::DeclarationScope* script_scope =
    3283           5 :       new (&zone) i::DeclarationScope(&zone, &avf);
    3284             :   i::Scope* s = i::Scope::DeserializeScopeChain(
    3285             :       isolate, &zone, context->scope_info(), script_scope, &avf,
    3286           5 :       i::Scope::DeserializationMode::kIncludingVariables);
    3287           5 :   CHECK(s != script_scope);
    3288             : 
    3289             :   // Get result from f's function context (that is g's outer context)
    3290           5 :   i::Variable* var_x = s->LookupForTesting(name_x);
    3291           5 :   CHECK_NOT_NULL(var_x);
    3292           5 :   CHECK_EQ(var_x->maybe_assigned(), i::kMaybeAssigned);
    3293           5 : }
    3294             : 
    3295             : 
    3296       25880 : TEST(InnerAssignment) {
    3297             :   i::Isolate* isolate = CcTest::i_isolate();
    3298             :   i::Factory* factory = isolate->factory();
    3299             :   i::HandleScope scope(isolate);
    3300          10 :   LocalContext env;
    3301             : 
    3302             :   const char* prefix = "function f() {";
    3303             :   const char* midfix = " function g() {";
    3304             :   const char* suffix = "}}; f";
    3305             :   struct {
    3306             :     const char* source;
    3307             :     bool assigned;
    3308             :     bool strict;
    3309             :   } outers[] = {
    3310             :       // Actual assignments.
    3311             :       {"var x; var x = 5;", true, false},
    3312             :       {"var x; { var x = 5; }", true, false},
    3313             :       {"'use strict'; let x; x = 6;", true, true},
    3314             :       {"var x = 5; function x() {}", true, false},
    3315             :       {"var x = 4; var x = 5;", true, false},
    3316             :       {"var [x, x] = [4, 5];", true, false},
    3317             :       {"var x; [x, x] = [4, 5];", true, false},
    3318             :       {"var {a: x, b: x} = {a: 4, b: 5};", true, false},
    3319             :       {"var x = {a: 4, b: (x = 5)};", true, false},
    3320             :       {"var {x=1} = {a: 4, b: (x = 5)};", true, false},
    3321             :       {"var {x} = {x: 4, b: (x = 5)};", true, false},
    3322             :       // Actual non-assignments.
    3323             :       {"var x;", false, false},
    3324             :       {"var x = 5;", false, false},
    3325             :       {"'use strict'; let x;", false, true},
    3326             :       {"'use strict'; let x = 6;", false, true},
    3327             :       {"'use strict'; var x = 0; { let x = 6; }", false, true},
    3328             :       {"'use strict'; var x = 0; { let x; x = 6; }", false, true},
    3329             :       {"'use strict'; let x = 0; { let x = 6; }", false, true},
    3330             :       {"'use strict'; let x = 0; { let x; x = 6; }", false, true},
    3331             :       {"var x; try {} catch (x) { x = 5; }", false, false},
    3332             :       {"function x() {}", false, false},
    3333             :       // Eval approximation.
    3334             :       {"var x; eval('');", true, false},
    3335             :       {"eval(''); var x;", true, false},
    3336             :       {"'use strict'; let x; eval('');", true, true},
    3337             :       {"'use strict'; eval(''); let x;", true, true},
    3338             :       // Non-assignments not recognized, because the analysis is approximative.
    3339             :       {"var x; var x;", true, false},
    3340             :       {"var x = 5; var x;", true, false},
    3341             :       {"var x; { var x; }", true, false},
    3342             :       {"var x; function x() {}", true, false},
    3343             :       {"function x() {}; var x;", true, false},
    3344             :       {"var x; try {} catch (x) { var x = 5; }", true, false},
    3345           5 :   };
    3346             : 
    3347             :   // We set allow_error_in_inner_function to true in cases where our handling of
    3348             :   // assigned variables in lazy inner functions is currently overly pessimistic.
    3349             :   // FIXME(marja): remove it when no longer needed.
    3350             :   struct {
    3351             :     const char* source;
    3352             :     bool assigned;
    3353             :     bool with;
    3354             :     bool allow_error_in_inner_function;
    3355             :   } inners[] = {
    3356             :       // Actual assignments.
    3357             :       {"x = 1;", true, false, false},
    3358             :       {"x++;", true, false, false},
    3359             :       {"++x;", true, false, false},
    3360             :       {"x--;", true, false, false},
    3361             :       {"--x;", true, false, false},
    3362             :       {"{ x = 1; }", true, false, false},
    3363             :       {"'use strict'; { let x; }; x = 0;", true, false, false},
    3364             :       {"'use strict'; { const x = 1; }; x = 0;", true, false, false},
    3365             :       {"'use strict'; { function x() {} }; x = 0;", true, false, false},
    3366             :       {"with ({}) { x = 1; }", true, true, false},
    3367             :       {"eval('');", true, false, false},
    3368             :       {"'use strict'; { let y; eval('') }", true, false, false},
    3369             :       {"function h() { x = 0; }", true, false, false},
    3370             :       {"(function() { x = 0; })", true, false, false},
    3371             :       {"(function() { x = 0; })", true, false, false},
    3372             :       {"with ({}) (function() { x = 0; })", true, true, false},
    3373             :       {"for (x of [1,2,3]) {}", true, false, false},
    3374             :       {"for (x in {a: 1}) {}", true, false, false},
    3375             :       {"for ([x] of [[1],[2],[3]]) {}", true, false, false},
    3376             :       {"for ([x] in {ab: 1}) {}", true, false, false},
    3377             :       {"for ([...x] in {ab: 1}) {}", true, false, false},
    3378             :       {"[x] = [1]", true, false, false},
    3379             :       // Actual non-assignments.
    3380             :       {"", false, false, false},
    3381             :       {"x;", false, false, false},
    3382             :       {"var x;", false, false, false},
    3383             :       {"var x = 8;", false, false, false},
    3384             :       {"var x; x = 8;", false, false, false},
    3385             :       {"'use strict'; let x;", false, false, false},
    3386             :       {"'use strict'; let x = 8;", false, false, false},
    3387             :       {"'use strict'; let x; x = 8;", false, false, false},
    3388             :       {"'use strict'; const x = 8;", false, false, false},
    3389             :       {"function x() {}", false, false, false},
    3390             :       {"function x() { x = 0; }", false, false, true},
    3391             :       {"function h(x) { x = 0; }", false, false, false},
    3392             :       {"'use strict'; { let x; x = 0; }", false, false, false},
    3393             :       {"{ var x; }; x = 0;", false, false, false},
    3394             :       {"with ({}) {}", false, true, false},
    3395             :       {"var x; { with ({}) { x = 1; } }", false, true, false},
    3396             :       {"try {} catch(x) { x = 0; }", false, false, true},
    3397             :       {"try {} catch(x) { with ({}) { x = 1; } }", false, true, true},
    3398             :       // Eval approximation.
    3399             :       {"eval('');", true, false, false},
    3400             :       {"function h() { eval(''); }", true, false, false},
    3401             :       {"(function() { eval(''); })", true, false, false},
    3402             :       // Shadowing not recognized because of eval approximation.
    3403             :       {"var x; eval('');", true, false, false},
    3404             :       {"'use strict'; let x; eval('');", true, false, false},
    3405             :       {"try {} catch(x) { eval(''); }", true, false, false},
    3406             :       {"function x() { eval(''); }", true, false, false},
    3407             :       {"(function(x) { eval(''); })", true, false, false},
    3408           5 :   };
    3409             : 
    3410           5 :   int prefix_len = Utf8LengthHelper(prefix);
    3411           5 :   int midfix_len = Utf8LengthHelper(midfix);
    3412           5 :   int suffix_len = Utf8LengthHelper(suffix);
    3413         160 :   for (unsigned i = 0; i < arraysize(outers); ++i) {
    3414         155 :     const char* outer = outers[i].source;
    3415         155 :     int outer_len = Utf8LengthHelper(outer);
    3416        7595 :     for (unsigned j = 0; j < arraysize(inners); ++j) {
    3417       14880 :       for (unsigned lazy = 0; lazy < 2; ++lazy) {
    3418       15330 :         if (outers[i].strict && inners[j].with) continue;
    3419       14430 :         const char* inner = inners[j].source;
    3420       14430 :         int inner_len = Utf8LengthHelper(inner);
    3421             : 
    3422       14430 :         int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len;
    3423       14430 :         i::ScopedVector<char> program(len + 1);
    3424             : 
    3425             :         i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner,
    3426       14430 :                     suffix);
    3427             : 
    3428             :         std::unique_ptr<i::ParseInfo> info;
    3429       14430 :         if (lazy) {
    3430             :           printf("%s\n", program.start());
    3431             :           v8::Local<v8::Value> v = CompileRun(program.start());
    3432        7215 :           i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    3433        7215 :           i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
    3434             :           i::Handle<i::SharedFunctionInfo> shared =
    3435       14430 :               i::handle(f->shared(), isolate);
    3436       14430 :           info =
    3437        7215 :               std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, shared));
    3438        7215 :           CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
    3439             :         } else {
    3440             :           i::Handle<i::String> source =
    3441        7215 :               factory->InternalizeUtf8String(program.start());
    3442       14430 :           source->PrintOn(stdout);
    3443             :           printf("\n");
    3444        7215 :           i::Handle<i::Script> script = factory->NewScript(source);
    3445       14430 :           info =
    3446        7215 :               std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, script));
    3447             :           info->set_allow_lazy_parsing(false);
    3448        7215 :           CHECK(i::parsing::ParseProgram(info.get(), isolate));
    3449             :         }
    3450       14430 :         CHECK(i::Compiler::Analyze(info.get()));
    3451       14430 :         CHECK_NOT_NULL(info->literal());
    3452             : 
    3453       21645 :         i::Scope* scope = info->literal()->scope();
    3454       14430 :         if (!lazy) {
    3455             :           scope = scope->inner_scope();
    3456             :         }
    3457             :         DCHECK_NOT_NULL(scope);
    3458             :         DCHECK_NULL(scope->sibling());
    3459             :         DCHECK(scope->is_function_scope());
    3460             :         const i::AstRawString* var_name =
    3461       14430 :             info->ast_value_factory()->GetOneByteString("x");
    3462       14430 :         i::Variable* var = scope->LookupForTesting(var_name);
    3463       14430 :         bool expected = outers[i].assigned || inners[j].assigned;
    3464       14430 :         CHECK_NOT_NULL(var);
    3465       14430 :         bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned;
    3466       14430 :         CHECK(is_maybe_assigned == expected ||
    3467             :               (is_maybe_assigned && inners[j].allow_error_in_inner_function));
    3468             :       }
    3469             :     }
    3470             :   }
    3471           5 : }
    3472             : 
    3473       25880 : TEST(MaybeAssignedParameters) {
    3474             :   i::Isolate* isolate = CcTest::i_isolate();
    3475             :   i::HandleScope scope(isolate);
    3476          10 :   LocalContext env;
    3477             : 
    3478             :   struct {
    3479             :     bool arg_assigned;
    3480             :     const char* source;
    3481             :   } tests[] = {
    3482             :       {false, "function f(arg) {}"},
    3483             :       {false, "function f(arg) {g(arg)}"},
    3484             :       {false, "function f(arg) {function h() { g(arg) }; h()}"},
    3485             :       {false, "function f(arg) {function h() { g(arg) }; return h}"},
    3486             :       {false, "function f(arg=1) {}"},
    3487             :       {false, "function f(arg=1) {g(arg)}"},
    3488             :       {false, "function f(arg, arguments) {g(arg); arguments[0] = 42; g(arg)}"},
    3489             :       {false,
    3490             :        "function f(arg, ...arguments) {g(arg); arguments[0] = 42; g(arg)}"},
    3491             :       {false,
    3492             :        "function f(arg, arguments=[]) {g(arg); arguments[0] = 42; g(arg)}"},
    3493             :       {false, "function f(...arg) {g(arg); arguments[0] = 42; g(arg)}"},
    3494             :       {false,
    3495             :        "function f(arg) {g(arg); g(function() {arguments[0] = 42}); g(arg)}"},
    3496             : 
    3497             :       // strict arguments object
    3498             :       {false, "function f(arg, x=1) {g(arg); arguments[0] = 42; g(arg)}"},
    3499             :       {false, "function f(arg, ...x) {g(arg); arguments[0] = 42; g(arg)}"},
    3500             :       {false, "function f(arg=1) {g(arg); arguments[0] = 42; g(arg)}"},
    3501             :       {false,
    3502             :        "function f(arg) {'use strict'; g(arg); arguments[0] = 42; g(arg)}"},
    3503             :       {false, "function f(arg) {g(arg); f.arguments[0] = 42; g(arg)}"},
    3504             :       {false, "function f(arg, args=arguments) {g(arg); args[0] = 42; g(arg)}"},
    3505             : 
    3506             :       {true, "function f(arg) {g(arg); arg = 42; g(arg)}"},
    3507             :       {true, "function f(arg) {g(arg); eval('arg = 42'); g(arg)}"},
    3508             :       {true, "function f(arg) {g(arg); var arg = 42; g(arg)}"},
    3509             :       {true, "function f(arg, x=1) {g(arg); arg = 42; g(arg)}"},
    3510             :       {true, "function f(arg, ...x) {g(arg); arg = 42; g(arg)}"},
    3511             :       {true, "function f(arg=1) {g(arg); arg = 42; g(arg)}"},
    3512             :       {true, "function f(arg) {'use strict'; g(arg); arg = 42; g(arg)}"},
    3513             :       {true, "function f(arg, {a=(g(arg), arg=42)}) {g(arg)}"},
    3514             :       {true, "function f(arg) {g(arg); g(function() {arg = 42}); g(arg)}"},
    3515             :       {true,
    3516             :        "function f(arg) {g(arg); g(function() {eval('arg = 42')}); g(arg)}"},
    3517             :       {true, "function f(arg) {g(arg); g(() => arg = 42); g(arg)}"},
    3518             :       {true, "function f(arg) {g(arg); g(() => eval('arg = 42')); g(arg)}"},
    3519             :       {true, "function f(...arg) {g(arg); eval('arg = 42'); g(arg)}"},
    3520             : 
    3521             :       // sloppy arguments object
    3522             :       {true, "function f(arg) {g(arg); arguments[0] = 42; g(arg)}"},
    3523             :       {true, "function f(arg) {g(arg); h(arguments); g(arg)}"},
    3524             :       {true,
    3525             :        "function f(arg) {((args) => {arguments[0] = 42})(arguments); "
    3526             :        "g(arg)}"},
    3527             :       {true, "function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)}"},
    3528             :       {true, "function f(arg) {g(arg); g(() => arguments[0] = 42); g(arg)}"},
    3529           5 :   };
    3530             : 
    3531             :   const char* suffix = "; f";
    3532             : 
    3533         180 :   for (unsigned i = 0; i < arraysize(tests); ++i) {
    3534         175 :     bool assigned = tests[i].arg_assigned;
    3535         175 :     const char* source = tests[i].source;
    3536         525 :     for (unsigned allow_lazy = 0; allow_lazy < 2; ++allow_lazy) {
    3537         700 :       i::ScopedVector<char> program(Utf8LengthHelper(source) +
    3538         700 :                                     Utf8LengthHelper(suffix) + 1);
    3539         350 :       i::SNPrintF(program, "%s%s", source, suffix);
    3540             :       std::unique_ptr<i::ParseInfo> info;
    3541             :       printf("%s\n", program.start());
    3542             :       v8::Local<v8::Value> v = CompileRun(program.start());
    3543         350 :       i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    3544         350 :       i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o);
    3545         700 :       i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared(), isolate);
    3546         350 :       info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, shared));
    3547             :       info->set_allow_lazy_parsing(allow_lazy);
    3548         350 :       CHECK(i::parsing::ParseFunction(info.get(), shared, isolate));
    3549         350 :       CHECK(i::Compiler::Analyze(info.get()));
    3550         350 :       CHECK_NOT_NULL(info->literal());
    3551             : 
    3552        1050 :       i::Scope* scope = info->literal()->scope();
    3553         700 :       CHECK(!scope->AsDeclarationScope()->was_lazily_parsed());
    3554         350 :       CHECK_NULL(scope->sibling());
    3555         350 :       CHECK(scope->is_function_scope());
    3556             :       const i::AstRawString* var_name =
    3557         350 :           info->ast_value_factory()->GetOneByteString("arg");
    3558         350 :       i::Variable* var = scope->LookupForTesting(var_name);
    3559         350 :       CHECK(var->is_used() || !assigned);
    3560         350 :       bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned;
    3561         350 :       CHECK_EQ(is_maybe_assigned, assigned);
    3562             :     }
    3563             :   }
    3564           5 : }
    3565             : 
    3566       65800 : struct Input {
    3567             :   bool assigned;
    3568             :   std::string source;
    3569             :   std::vector<unsigned> location;  // "Directions" to the relevant scope.
    3570             : };
    3571             : 
    3572       15000 : static void TestMaybeAssigned(Input input, const char* variable, bool module,
    3573             :                               bool allow_lazy_parsing) {
    3574             :   i::Isolate* isolate = CcTest::i_isolate();
    3575             :   i::Factory* factory = isolate->factory();
    3576             :   i::Handle<i::String> string =
    3577       15000 :       factory->InternalizeUtf8String(input.source.c_str());
    3578       30000 :   string->PrintOn(stdout);
    3579             :   printf("\n");
    3580       15000 :   i::Handle<i::Script> script = factory->NewScript(string);
    3581             : 
    3582             :   std::unique_ptr<i::ParseInfo> info;
    3583       15000 :   info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(isolate, script));
    3584             :   info->set_module(module);
    3585             :   info->set_allow_lazy_parsing(allow_lazy_parsing);
    3586             : 
    3587       15000 :   CHECK(i::parsing::ParseProgram(info.get(), isolate));
    3588       15000 :   CHECK(i::Compiler::Analyze(info.get()));
    3589             : 
    3590       15000 :   CHECK_NOT_NULL(info->literal());
    3591       45000 :   i::Scope* scope = info->literal()->scope();
    3592       30000 :   CHECK(!scope->AsDeclarationScope()->was_lazily_parsed());
    3593       15000 :   CHECK_NULL(scope->sibling());
    3594       30000 :   CHECK(module ? scope->is_module_scope() : scope->is_script_scope());
    3595             : 
    3596       26400 :   i::Variable* var;
    3597             :   {
    3598             :     // Find the variable.
    3599       15000 :     scope = i::ScopeTestHelper::FindScope(scope, input.location);
    3600             :     const i::AstRawString* var_name =
    3601       15000 :         info->ast_value_factory()->GetOneByteString(variable);
    3602             :     var = scope->LookupForTesting(var_name);
    3603             :   }
    3604             : 
    3605       15000 :   CHECK_NOT_NULL(var);
    3606       26400 :   CHECK_IMPLIES(input.assigned, var->is_used());
    3607             :   STATIC_ASSERT(true == i::kMaybeAssigned);
    3608       15000 :   CHECK_EQ(input.assigned, var->maybe_assigned() == i::kMaybeAssigned);
    3609       15000 : }
    3610             : 
    3611        4200 : static Input wrap(Input input) {
    3612             :   Input result;
    3613        4200 :   result.assigned = input.assigned;
    3614       16800 :   result.source = "function WRAPPED() { " + input.source + " }";
    3615        8400 :   result.location.push_back(0);
    3616       11780 :   for (auto n : input.location) {
    3617        3380 :     result.location.push_back(n);
    3618             :   }
    3619        4200 :   return result;
    3620             : }
    3621             : 
    3622       25880 : TEST(MaybeAssignedInsideLoop) {
    3623             :   i::Isolate* isolate = CcTest::i_isolate();
    3624             :   i::HandleScope scope(isolate);
    3625          10 :   LocalContext env;
    3626             : 
    3627             :   std::vector<unsigned> top;  // Can't use {} in initializers below.
    3628             : 
    3629             :   Input module_and_script_tests[] = {
    3630             :       {true, "for (j=x; j<10; ++j) { foo = j }", top},
    3631             :       {true, "for (j=x; j<10; ++j) { [foo] = [j] }", top},
    3632             :       {true, "for (j=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
    3633             :       {true, "for (j=x; j<10; ++j) { var foo = j }", top},
    3634             :       {true, "for (j=x; j<10; ++j) { var [foo] = [j] }", top},
    3635             :       {true, "for (j=x; j<10; ++j) { var [[foo]=[42]] = [] }", 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] = [j] }", top},
    3638             :       {true, "for (j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3639             :       {true, "for (j=x; j<10; ++j) { let foo; foo = j }", {0}},
    3640             :       {true, "for (j=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
    3641             :       {true, "for (j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
    3642             :       {false, "for (j=x; j<10; ++j) { let foo = j }", {0}},
    3643             :       {false, "for (j=x; j<10; ++j) { let [foo] = [j] }", {0}},
    3644             :       {false, "for (j=x; j<10; ++j) { const foo = j }", {0}},
    3645             :       {false, "for (j=x; j<10; ++j) { const [foo] = [j] }", {0}},
    3646             :       {false, "for (j=x; j<10; ++j) { function foo() {return j} }", {0}},
    3647             : 
    3648             :       {true, "for ({j}=x; j<10; ++j) { foo = j }", top},
    3649             :       {true, "for ({j}=x; j<10; ++j) { [foo] = [j] }", top},
    3650             :       {true, "for ({j}=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
    3651             :       {true, "for ({j}=x; j<10; ++j) { var foo = j }", top},
    3652             :       {true, "for ({j}=x; j<10; ++j) { var [foo] = [j] }", top},
    3653             :       {true, "for ({j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", 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] = [j] }", top},
    3656             :       {true, "for ({j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3657             :       {true, "for ({j}=x; j<10; ++j) { let foo; foo = j }", {0}},
    3658             :       {true, "for ({j}=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
    3659             :       {true, "for ({j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
    3660             :       {false, "for ({j}=x; j<10; ++j) { let foo = j }", {0}},
    3661             :       {false, "for ({j}=x; j<10; ++j) { let [foo] = [j] }", {0}},
    3662             :       {false, "for ({j}=x; j<10; ++j) { const foo = j }", {0}},
    3663             :       {false, "for ({j}=x; j<10; ++j) { const [foo] = [j] }", {0}},
    3664             :       {false, "for ({j}=x; j<10; ++j) { function foo() {return j} }", {0}},
    3665             : 
    3666             :       {true, "for (var j=x; j<10; ++j) { foo = j }", top},
    3667             :       {true, "for (var j=x; j<10; ++j) { [foo] = [j] }", top},
    3668             :       {true, "for (var j=x; j<10; ++j) { [[foo]=[42]] = [] }", 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] = [j] }", top},
    3671             :       {true, "for (var j=x; j<10; ++j) { var [[foo]=[42]] = [] }", 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] = [j] }", top},
    3674             :       {true, "for (var j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    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] = [j] }", {0}},
    3677             :       {true, "for (var j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
    3678             :       {false, "for (var j=x; j<10; ++j) { let foo = j }", {0}},
    3679             :       {false, "for (var j=x; j<10; ++j) { let [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) { const [foo] = [j] }", {0}},
    3682             :       {false, "for (var j=x; j<10; ++j) { function foo() {return j} }", {0}},
    3683             : 
    3684             :       {true, "for (var {j}=x; j<10; ++j) { foo = j }", top},
    3685             :       {true, "for (var {j}=x; j<10; ++j) { [foo] = [j] }", top},
    3686             :       {true, "for (var {j}=x; j<10; ++j) { [[foo]=[42]] = [] }", 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] = [j] }", top},
    3689             :       {true, "for (var {j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", 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] = [j] }", top},
    3692             :       {true, "for (var {j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    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] = [j] }", {0}},
    3695             :       {true, "for (var {j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
    3696             :       {false, "for (var {j}=x; j<10; ++j) { let foo = j }", {0}},
    3697             :       {false, "for (var {j}=x; j<10; ++j) { let [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) { const [foo] = [j] }", {0}},
    3700             :       {false, "for (var {j}=x; j<10; ++j) { function foo() {return j} }", {0}},
    3701             : 
    3702             :       {true, "for (let j=x; j<10; ++j) { foo = j }", top},
    3703             :       {true, "for (let j=x; j<10; ++j) { [foo] = [j] }", top},
    3704             :       {true, "for (let j=x; j<10; ++j) { [[foo]=[42]] = [] }", 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] = [j] }", top},
    3707             :       {true, "for (let j=x; j<10; ++j) { var [[foo]=[42]] = [] }", 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] = [j] }", top},
    3710             :       {true, "for (let j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    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] = [j] }", {0, 0}},
    3713             :       {true, "for (let j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {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) { let [foo] = [j] }", {0, 0}},
    3716             :       {false, "for (let j=x; j<10; ++j) { const foo = j }", {0, 0}},
    3717             :       {false, "for (let j=x; j<10; ++j) { const [foo] = [j] }", {0, 0}},
    3718             :       {false,
    3719             :        "for (let j=x; j<10; ++j) { function foo() {return j} }",
    3720             :        {0, 0, 0}},
    3721             : 
    3722             :       {true, "for (let {j}=x; j<10; ++j) { foo = j }", top},
    3723             :       {true, "for (let {j}=x; j<10; ++j) { [foo] = [j] }", top},
    3724             :       {true, "for (let {j}=x; j<10; ++j) { [[foo]=[42]] = [] }", 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] = [j] }", top},
    3727             :       {true, "for (let {j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", 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] = [j] }", top},
    3730             :       {true, "for (let {j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
    3731             :       {true, "for (let {j}=x; j<10; ++j) { let foo; foo = j }", {0, 0}},
    3732             :       {true, "for (let {j}=x; j<10; ++j) { let foo; [foo] = [j] }", {0, 0}},
    3733             :       {true,
    3734             :        "for (let {j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }",
    3735             :        {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) { let [foo] = [j] }", {0, 0}},
    3738             :       {false, "for (let {j}=x; j<10; ++j) { const foo = j }", {0, 0}},
    3739             :       {false, "for (let {j}=x; j<10; ++j) { const [foo] = [j] }", {0, 0}},
    3740             :       {false,
    3741             :        "for (let {j}=x; j<10; ++j) { function foo(){return j} }",
    3742             :        {0, 0, 0}},
    3743             : 
    3744             :       {true, "for (j of x) { foo = j }", top},
    3745             :       {true, "for (j of x) { [foo] = [j] }", top},
    3746             :       {true, "for (j of x) { [[foo]=[42]] = [] }", top},
    3747             :       {true, "for (j of x) { var foo = j }", top},
    3748             :       {true, "for (j of x) { var [foo] = [j] }", top},
    3749             :       {true, "for (j of x) { var [[foo]=[42]] = [] }", top},
    3750             :       {true, "for (j of x) { var foo; foo = j }", top},
    3751             :       {true, "for (j of x) { var foo; [foo] = [j] }", top},
    3752             :       {true, "for (j of x) { var foo; [[foo]=[42]] = [] }", top},
    3753             :       {true, "for (j of x) { let foo; foo = j }", {0}},
    3754             :       {true, "for (j of x) { let foo; [foo] = [j] }", {0}},
    3755             :       {true, "for (j of x) { let foo; [[foo]=[42]] = [] }", {0}},
    3756             :       {false, "for (j of x) { let foo = j }", {0}},
    3757             :       {false, "for (j of x) { let [foo] = [j] }", {0}},
    3758             :       {false, "for (j of x) { const foo = j }", {0}},
    3759             :       {false, "for (j of x) { const [foo] = [j] }", {0}},
    3760             :       {false, "for (j of x) { function foo() {return j} }", {0}},
    3761             : 
    3762             :       {true, "for ({j} of x) { foo = j }", top},
    3763             :       {true, "for ({j} of x) { [foo] = [j] }", top},
    3764             :       {true, "for ({j} of x) { [[foo]=[42]] = [] }", top},
    3765             :       {true, "for ({j} of x) { var foo = j }", top},
    3766             :       {true, "for ({j} of x) { var [foo] = [j] }", top},
    3767             :       {true, "for ({j} of x) { var [[foo]=[42]] = [] }", top},
    3768             :       {true, "for ({j} of x) { var foo; foo = j }", top},
    3769             :       {true, "for ({j} of x) { var foo; [foo] = [j] }", top},
    3770             :       {true, "for ({j} of x) { var foo; [[foo]=[42]] = [] }", top},
    3771             :       {true, "for ({j} of x) { let foo; foo = j }", {0}},
    3772             :       {true, "for ({j} of x) { let foo; [foo] = [j] }", {0}},
    3773             :       {true, "for ({j} of x) { let foo; [[foo]=[42]] = [] }", {0}},
    3774             :       {false, "for ({j} of x) { let foo = j }", {0}},
    3775             :       {false, "for ({j} of x) { let [foo] = [j] }", {0}},
    3776             :       {false, "for ({j} of x) { const foo = j }", {0}},
    3777             :       {false, "for ({j} of x) { const [foo] = [j] }", {0}},
    3778             :       {false, "for ({j} of x) { function foo() {return j} }", {0}},
    3779             : 
    3780             :       {true, "for (var j of x) { foo = j }", top},
    3781             :       {true, "for (var j of x) { [foo] = [j] }", top},
    3782             :       {true, "for (var j of x) { [[foo]=[42]] = [] }", top},
    3783             :       {true, "for (var j of x) { var foo = j }", top},
    3784             :       {true, "for (var j of x) { var [foo] = [j] }", top},
    3785             :       {true, "for (var j of x) { var [[foo]=[42]] = [] }", top},
    3786             :       {true, "for (var j of x) { var foo; foo = j }", top},
    3787             :       {true, "for (var j of x) { var foo; [foo] = [j] }", top},
    3788             :       {true, "for (var j of x) { var foo; [[foo]=[42]] = [] }", top},
    3789             :       {true, "for (var j of x) { let foo; foo = j }", {0}},
    3790             :       {true, "for (var j of x) { let foo; [foo] = [j] }", {0}},
    3791             :       {true, "for (var j of x) { let foo; [[foo]=[42]] = [] }", {0}},
    3792             :       {false, "for (var j of x) { let foo = j }", {0}},
    3793             :       {false, "for (var j of x) { let [foo] = [j] }", {0}},
    3794             :       {false, "for (var j of x) { const foo = j }", {0}},
    3795             :       {false, "for (var j of x) { const [foo] = [j] }", {0}},
    3796             :       {false, "for (var j of x) { function foo() {return j} }", {0}},
    3797             : 
    3798             :       {true, "for (var {j} of x) { foo = j }", top},
    3799             :       {true, "for (var {j} of x) { [foo] = [j] }", top},
    3800             :       {true, "for (var {j} of x) { [[foo]=[42]] = [] }", top},
    3801             :       {true, "for (var {j} of x) { var foo = j }", top},
    3802             :       {true, "for (var {j} of x) { var [foo] = [j] }", top},
    3803             :       {true, "for (var {j} of x) { var [[foo]=[42]] = [] }", top},
    3804             :       {true, "for (var {j} of x) { var foo; foo = j }", top},
    3805             :       {true, "for (var {j} of x) { var foo; [foo] = [j] }", top},
    3806             :       {true, "for (var {j} of x) { var foo; [[foo]=[42]] = [] }", top},
    3807             :       {true, "for (var {j} of x) { let foo; foo = j }", {0}},
    3808             :       {true, "for (var {j} of x) { let foo; [foo] = [j] }", {0}},
    3809             :       {true, "for (var {j} of x) { let foo; [[foo]=[42]] = [] }", {0}},
    3810             :       {false, "for (var {j} of x) { let foo = j }", {0}},
    3811             :       {false, "for (var {j} of x) { let [foo] = [j] }", {0}},
    3812             :       {false, "for (var {j} of x) { const foo = j }", {0}},
    3813             :       {false, "for (var {j} of x) { const [foo] = [j] }", {0}},
    3814             :       {false, "for (var {j} of x) { function foo() {return j} }", {0}},
    3815             : 
    3816             :       {true, "for (let j of x) { foo = j }", top},
    3817             :       {true, "for (let j of x) { [foo] = [j] }", top},
    3818             :       {true, "for (let j of x) { [[foo]=[42]] = [] }", top},
    3819             :       {true, "for (let j of x) { var foo = j }", top},
    3820             :       {true, "for (let j of x) { var [foo] = [j] }", top},
    3821             :       {true, "for (let j of x) { var [[foo]=[42]] = [] }", top},
    3822             :       {true, "for (let j of x) { var foo; foo = j }", top},
    3823             :       {true, "for (let j of x) { var foo; [foo] = [j] }", top},
    3824             :       {true, "for (let j of x) { var foo; [[foo]=[42]] = [] }", top},
    3825             :       {true, "for (let j of x) { let foo; foo = j }", {0, 0, 0}},
    3826             :       {true, "for (let j of x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3827             :       {true, "for (let j of x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3828             :       {false, "for (let j of x) { let foo = j }", {0, 0, 0}},
    3829             :       {false, "for (let j of x) { let [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) { const [foo] = [j] }", {0, 0, 0}},
    3832             :       {false, "for (let j of x) { function foo() {return j} }", {0, 0, 0}},
    3833             : 
    3834             :       {true, "for (let {j} of x) { foo = j }", top},
    3835             :       {true, "for (let {j} of x) { [foo] = [j] }", top},
    3836             :       {true, "for (let {j} of x) { [[foo]=[42]] = [] }", top},
    3837             :       {true, "for (let {j} of x) { var foo = j }", top},
    3838             :       {true, "for (let {j} of x) { var [foo] = [j] }", top},
    3839             :       {true, "for (let {j} of x) { var [[foo]=[42]] = [] }", top},
    3840             :       {true, "for (let {j} of x) { var foo; foo = j }", top},
    3841             :       {true, "for (let {j} of x) { var foo; [foo] = [j] }", top},
    3842             :       {true, "for (let {j} of x) { var foo; [[foo]=[42]] = [] }", top},
    3843             :       {true, "for (let {j} of x) { let foo; foo = j }", {0, 0, 0}},
    3844             :       {true, "for (let {j} of x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3845             :       {true, "for (let {j} of x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3846             :       {false, "for (let {j} of x) { let foo = j }", {0, 0, 0}},
    3847             :       {false, "for (let {j} of x) { let [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) { const [foo] = [j] }", {0, 0, 0}},
    3850             :       {false, "for (let {j} of x) { function foo() {return j} }", {0, 0, 0}},
    3851             : 
    3852             :       {true, "for (const j of x) { foo = j }", top},
    3853             :       {true, "for (const j of x) { [foo] = [j] }", top},
    3854             :       {true, "for (const j of x) { [[foo]=[42]] = [] }", top},
    3855             :       {true, "for (const j of x) { var foo = j }", top},
    3856             :       {true, "for (const j of x) { var [foo] = [j] }", top},
    3857             :       {true, "for (const j of x) { var [[foo]=[42]] = [] }", top},
    3858             :       {true, "for (const j of x) { var foo; foo = j }", top},
    3859             :       {true, "for (const j of x) { var foo; [foo] = [j] }", top},
    3860             :       {true, "for (const j of x) { var foo; [[foo]=[42]] = [] }", top},
    3861             :       {true, "for (const j of x) { let foo; foo = j }", {0, 0, 0}},
    3862             :       {true, "for (const j of x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3863             :       {true, "for (const j of x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3864             :       {false, "for (const j of x) { let foo = j }", {0, 0, 0}},
    3865             :       {false, "for (const j of x) { let [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) { const [foo] = [j] }", {0, 0, 0}},
    3868             :       {false, "for (const j of x) { function foo() {return j} }", {0, 0, 0}},
    3869             : 
    3870             :       {true, "for (const {j} of x) { foo = j }", top},
    3871             :       {true, "for (const {j} of x) { [foo] = [j] }", top},
    3872             :       {true, "for (const {j} of x) { [[foo]=[42]] = [] }", top},
    3873             :       {true, "for (const {j} of x) { var foo = j }", top},
    3874             :       {true, "for (const {j} of x) { var [foo] = [j] }", top},
    3875             :       {true, "for (const {j} of x) { var [[foo]=[42]] = [] }", top},
    3876             :       {true, "for (const {j} of x) { var foo; foo = j }", top},
    3877             :       {true, "for (const {j} of x) { var foo; [foo] = [j] }", top},
    3878             :       {true, "for (const {j} of x) { var foo; [[foo]=[42]] = [] }", top},
    3879             :       {true, "for (const {j} of x) { let foo; foo = j }", {0, 0, 0}},
    3880             :       {true, "for (const {j} of x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3881             :       {true, "for (const {j} of x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3882             :       {false, "for (const {j} of x) { let foo = j }", {0, 0, 0}},
    3883             :       {false, "for (const {j} of x) { let [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) { const [foo] = [j] }", {0, 0, 0}},
    3886             :       {false, "for (const {j} of x) { function foo() {return j} }", {0, 0, 0}},
    3887             : 
    3888             :       {true, "for (j in x) { foo = j }", top},
    3889             :       {true, "for (j in x) { [foo] = [j] }", top},
    3890             :       {true, "for (j in x) { [[foo]=[42]] = [] }", top},
    3891             :       {true, "for (j in x) { var foo = j }", top},
    3892             :       {true, "for (j in x) { var [foo] = [j] }", top},
    3893             :       {true, "for (j in x) { var [[foo]=[42]] = [] }", top},
    3894             :       {true, "for (j in x) { var foo; foo = j }", top},
    3895             :       {true, "for (j in x) { var foo; [foo] = [j] }", top},
    3896             :       {true, "for (j in x) { var foo; [[foo]=[42]] = [] }", top},
    3897             :       {true, "for (j in x) { let foo; foo = j }", {0}},
    3898             :       {true, "for (j in x) { let foo; [foo] = [j] }", {0}},
    3899             :       {true, "for (j in x) { let foo; [[foo]=[42]] = [] }", {0}},
    3900             :       {false, "for (j in x) { let foo = j }", {0}},
    3901             :       {false, "for (j in x) { let [foo] = [j] }", {0}},
    3902             :       {false, "for (j in x) { const foo = j }", {0}},
    3903             :       {false, "for (j in x) { const [foo] = [j] }", {0}},
    3904             :       {false, "for (j in x) { function foo() {return j} }", {0}},
    3905             : 
    3906             :       {true, "for ({j} in x) { foo = j }", top},
    3907             :       {true, "for ({j} in x) { [foo] = [j] }", top},
    3908             :       {true, "for ({j} in x) { [[foo]=[42]] = [] }", top},
    3909             :       {true, "for ({j} in x) { var foo = j }", top},
    3910             :       {true, "for ({j} in x) { var [foo] = [j] }", top},
    3911             :       {true, "for ({j} in x) { var [[foo]=[42]] = [] }", top},
    3912             :       {true, "for ({j} in x) { var foo; foo = j }", top},
    3913             :       {true, "for ({j} in x) { var foo; [foo] = [j] }", top},
    3914             :       {true, "for ({j} in x) { var foo; [[foo]=[42]] = [] }", top},
    3915             :       {true, "for ({j} in x) { let foo; foo = j }", {0}},
    3916             :       {true, "for ({j} in x) { let foo; [foo] = [j] }", {0}},
    3917             :       {true, "for ({j} in x) { let foo; [[foo]=[42]] = [] }", {0}},
    3918             :       {false, "for ({j} in x) { let foo = j }", {0}},
    3919             :       {false, "for ({j} in x) { let [foo] = [j] }", {0}},
    3920             :       {false, "for ({j} in x) { const foo = j }", {0}},
    3921             :       {false, "for ({j} in x) { const [foo] = [j] }", {0}},
    3922             :       {false, "for ({j} in x) { function foo() {return j} }", {0}},
    3923             : 
    3924             :       {true, "for (var j in x) { foo = j }", top},
    3925             :       {true, "for (var j in x) { [foo] = [j] }", top},
    3926             :       {true, "for (var j in x) { [[foo]=[42]] = [] }", top},
    3927             :       {true, "for (var j in x) { var foo = j }", top},
    3928             :       {true, "for (var j in x) { var [foo] = [j] }", top},
    3929             :       {true, "for (var j in x) { var [[foo]=[42]] = [] }", top},
    3930             :       {true, "for (var j in x) { var foo; foo = j }", top},
    3931             :       {true, "for (var j in x) { var foo; [foo] = [j] }", top},
    3932             :       {true, "for (var j in x) { var foo; [[foo]=[42]] = [] }", top},
    3933             :       {true, "for (var j in x) { let foo; foo = j }", {0}},
    3934             :       {true, "for (var j in x) { let foo; [foo] = [j] }", {0}},
    3935             :       {true, "for (var j in x) { let foo; [[foo]=[42]] = [] }", {0}},
    3936             :       {false, "for (var j in x) { let foo = j }", {0}},
    3937             :       {false, "for (var j in x) { let [foo] = [j] }", {0}},
    3938             :       {false, "for (var j in x) { const foo = j }", {0}},
    3939             :       {false, "for (var j in x) { const [foo] = [j] }", {0}},
    3940             :       {false, "for (var j in x) { function foo() {return j} }", {0}},
    3941             : 
    3942             :       {true, "for (var {j} in x) { foo = j }", top},
    3943             :       {true, "for (var {j} in x) { [foo] = [j] }", top},
    3944             :       {true, "for (var {j} in x) { [[foo]=[42]] = [] }", top},
    3945             :       {true, "for (var {j} in x) { var foo = j }", top},
    3946             :       {true, "for (var {j} in x) { var [foo] = [j] }", top},
    3947             :       {true, "for (var {j} in x) { var [[foo]=[42]] = [] }", top},
    3948             :       {true, "for (var {j} in x) { var foo; foo = j }", top},
    3949             :       {true, "for (var {j} in x) { var foo; [foo] = [j] }", top},
    3950             :       {true, "for (var {j} in x) { var foo; [[foo]=[42]] = [] }", top},
    3951             :       {true, "for (var {j} in x) { let foo; foo = j }", {0}},
    3952             :       {true, "for (var {j} in x) { let foo; [foo] = [j] }", {0}},
    3953             :       {true, "for (var {j} in x) { let foo; [[foo]=[42]] = [] }", {0}},
    3954             :       {false, "for (var {j} in x) { let foo = j }", {0}},
    3955             :       {false, "for (var {j} in x) { let [foo] = [j] }", {0}},
    3956             :       {false, "for (var {j} in x) { const foo = j }", {0}},
    3957             :       {false, "for (var {j} in x) { const [foo] = [j] }", {0}},
    3958             :       {false, "for (var {j} in x) { function foo() {return j} }", {0}},
    3959             : 
    3960             :       {true, "for (let j in x) { foo = j }", top},
    3961             :       {true, "for (let j in x) { [foo] = [j] }", top},
    3962             :       {true, "for (let j in x) { [[foo]=[42]] = [] }", top},
    3963             :       {true, "for (let j in x) { var foo = j }", top},
    3964             :       {true, "for (let j in x) { var [foo] = [j] }", top},
    3965             :       {true, "for (let j in x) { var [[foo]=[42]] = [] }", top},
    3966             :       {true, "for (let j in x) { var foo; foo = j }", top},
    3967             :       {true, "for (let j in x) { var foo; [foo] = [j] }", top},
    3968             :       {true, "for (let j in x) { var foo; [[foo]=[42]] = [] }", top},
    3969             :       {true, "for (let j in x) { let foo; foo = j }", {0, 0, 0}},
    3970             :       {true, "for (let j in x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3971             :       {true, "for (let j in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3972             :       {false, "for (let j in x) { let foo = j }", {0, 0, 0}},
    3973             :       {false, "for (let j in x) { let [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) { const [foo] = [j] }", {0, 0, 0}},
    3976             :       {false, "for (let j in x) { function foo() {return j} }", {0, 0, 0}},
    3977             : 
    3978             :       {true, "for (let {j} in x) { foo = j }", top},
    3979             :       {true, "for (let {j} in x) { [foo] = [j] }", top},
    3980             :       {true, "for (let {j} in x) { [[foo]=[42]] = [] }", top},
    3981             :       {true, "for (let {j} in x) { var foo = j }", top},
    3982             :       {true, "for (let {j} in x) { var [foo] = [j] }", top},
    3983             :       {true, "for (let {j} in x) { var [[foo]=[42]] = [] }", top},
    3984             :       {true, "for (let {j} in x) { var foo; foo = j }", top},
    3985             :       {true, "for (let {j} in x) { var foo; [foo] = [j] }", top},
    3986             :       {true, "for (let {j} in x) { var foo; [[foo]=[42]] = [] }", top},
    3987             :       {true, "for (let {j} in x) { let foo; foo = j }", {0, 0, 0}},
    3988             :       {true, "for (let {j} in x) { let foo; [foo] = [j] }", {0, 0, 0}},
    3989             :       {true, "for (let {j} in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    3990             :       {false, "for (let {j} in x) { let foo = j }", {0, 0, 0}},
    3991             :       {false, "for (let {j} in x) { let [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) { const [foo] = [j] }", {0, 0, 0}},
    3994             :       {false, "for (let {j} in x) { function foo() {return j} }", {0, 0, 0}},
    3995             : 
    3996             :       {true, "for (const j in x) { foo = j }", top},
    3997             :       {true, "for (const j in x) { [foo] = [j] }", top},
    3998             :       {true, "for (const j in x) { [[foo]=[42]] = [] }", top},
    3999             :       {true, "for (const j in x) { var foo = j }", top},
    4000             :       {true, "for (const j in x) { var [foo] = [j] }", top},
    4001             :       {true, "for (const j in x) { var [[foo]=[42]] = [] }", top},
    4002             :       {true, "for (const j in x) { var foo; foo = j }", top},
    4003             :       {true, "for (const j in x) { var foo; [foo] = [j] }", top},
    4004             :       {true, "for (const j in x) { var foo; [[foo]=[42]] = [] }", top},
    4005             :       {true, "for (const j in x) { let foo; foo = j }", {0, 0, 0}},
    4006             :       {true, "for (const j in x) { let foo; [foo] = [j] }", {0, 0, 0}},
    4007             :       {true, "for (const j in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    4008             :       {false, "for (const j in x) { let foo = j }", {0, 0, 0}},
    4009             :       {false, "for (const j in x) { let [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) { const [foo] = [j] }", {0, 0, 0}},
    4012             :       {false, "for (const j in x) { function foo() {return j} }", {0, 0, 0}},
    4013             : 
    4014             :       {true, "for (const {j} in x) { foo = j }", top},
    4015             :       {true, "for (const {j} in x) { [foo] = [j] }", top},
    4016             :       {true, "for (const {j} in x) { [[foo]=[42]] = [] }", top},
    4017             :       {true, "for (const {j} in x) { var foo = j }", top},
    4018             :       {true, "for (const {j} in x) { var [foo] = [j] }", top},
    4019             :       {true, "for (const {j} in x) { var [[foo]=[42]] = [] }", top},
    4020             :       {true, "for (const {j} in x) { var foo; foo = j }", top},
    4021             :       {true, "for (const {j} in x) { var foo; [foo] = [j] }", top},
    4022             :       {true, "for (const {j} in x) { var foo; [[foo]=[42]] = [] }", top},
    4023             :       {true, "for (const {j} in x) { let foo; foo = j }", {0, 0, 0}},
    4024             :       {true, "for (const {j} in x) { let foo; [foo] = [j] }", {0, 0, 0}},
    4025             :       {true, "for (const {j} in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
    4026             :       {false, "for (const {j} in x) { let foo = j }", {0, 0, 0}},
    4027             :       {false, "for (const {j} in x) { let [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) { const [foo] = [j] }", {0, 0, 0}},
    4030             :       {false, "for (const {j} in x) { function foo() {return j} }", {0, 0, 0}},
    4031             : 
    4032             :       {true, "while (j) { foo = j }", top},
    4033             :       {true, "while (j) { [foo] = [j] }", top},
    4034             :       {true, "while (j) { [[foo]=[42]] = [] }", top},
    4035             :       {true, "while (j) { var foo = j }", top},
    4036             :       {true, "while (j) { var [foo] = [j] }", top},
    4037             :       {true, "while (j) { var [[foo]=[42]] = [] }", top},
    4038             :       {true, "while (j) { var foo; foo = j }", top},
    4039             :       {true, "while (j) { var foo; [foo] = [j] }", top},
    4040             :       {true, "while (j) { var foo; [[foo]=[42]] = [] }", top},
    4041             :       {true, "while (j) { let foo; foo = j }", {0}},
    4042             :       {true, "while (j) { let foo; [foo] = [j] }", {0}},
    4043             :       {true, "while (j) { let foo; [[foo]=[42]] = [] }", {0}},
    4044             :       {false, "while (j) { let foo = j }", {0}},
    4045             :       {false, "while (j) { let [foo] = [j] }", {0}},
    4046             :       {false, "while (j) { const foo = j }", {0}},
    4047             :       {false, "while (j) { const [foo] = [j] }", {0}},
    4048             :       {false, "while (j) { function foo() {return j} }", {0}},
    4049             : 
    4050             :       {true, "do { foo = j } while (j)", top},
    4051             :       {true, "do { [foo] = [j] } while (j)", top},
    4052             :       {true, "do { [[foo]=[42]] = [] } while (j)", top},
    4053             :       {true, "do { var foo = j } while (j)", top},
    4054             :       {true, "do { var [foo] = [j] } while (j)", top},
    4055             :       {true, "do { var [[foo]=[42]] = [] } while (j)", top},
    4056             :       {true, "do { var foo; foo = j } while (j)", top},
    4057             :       {true, "do { var foo; [foo] = [j] } while (j)", top},
    4058             :       {true, "do { var foo; [[foo]=[42]] = [] } while (j)", top},
    4059             :       {true, "do { let foo; foo = j } while (j)", {0}},
    4060             :       {true, "do { let foo; [foo] = [j] } while (j)", {0}},
    4061             :       {true, "do { let foo; [[foo]=[42]] = [] } while (j)", {0}},
    4062             :       {false, "do { let foo = j } while (j)", {0}},
    4063             :       {false, "do { let [foo] = [j] } while (j)", {0}},
    4064             :       {false, "do { const foo = j } while (j)", {0}},
    4065             :       {false, "do { const [foo] = [j] } while (j)", {0}},
    4066             :       {false, "do { function foo() {return j} } while (j)", {0}},
    4067        3010 :   };
    4068             : 
    4069             :   Input script_only_tests[] = {
    4070             :       {true, "for (j=x; j<10; ++j) { function foo() {return j} }", top},
    4071             :       {true, "for ({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 (var {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 (let {j}=x; j<10; ++j) { function foo() {return j} }", top},
    4076             :       {true, "for (j of x) { function foo() {return j} }", top},
    4077             :       {true, "for ({j} of x) { function foo() {return j} }", top},
    4078             :       {true, "for (var j of x) { function foo() {return j} }", top},
    4079             :       {true, "for (var {j} of x) { function foo() {return j} }", top},
    4080             :       {true, "for (let j of x) { function foo() {return j} }", top},
    4081             :       {true, "for (let {j} of x) { function foo() {return j} }", top},
    4082             :       {true, "for (const j of x) { function foo() {return j} }", top},
    4083             :       {true, "for (const {j} of x) { function foo() {return j} }", top},
    4084             :       {true, "for (j in x) { function foo() {return j} }", top},
    4085             :       {true, "for ({j} in x) { function foo() {return j} }", top},
    4086             :       {true, "for (var j in x) { function foo() {return j} }", top},
    4087             :       {true, "for (var {j} in x) { function foo() {return j} }", top},
    4088             :       {true, "for (let j in x) { function foo() {return j} }", top},
    4089             :       {true, "for (let {j} in x) { function foo() {return j} }", top},
    4090             :       {true, "for (const j in x) { function foo() {return j} }", top},
    4091             :       {true, "for (const {j} in x) { function foo() {return j} }", top},
    4092             :       {true, "while (j) { function foo() {return j} }", top},
    4093             :       {true, "do { function foo() {return j} } while (j)", top},
    4094         130 :   };
    4095             : 
    4096        2045 :   for (unsigned i = 0; i < arraysize(module_and_script_tests); ++i) {
    4097        2040 :     Input input = module_and_script_tests[i];
    4098        6120 :     for (unsigned module = 0; module <= 1; ++module) {
    4099        8160 :       for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
    4100             :            ++allow_lazy_parsing) {
    4101        8160 :         TestMaybeAssigned(input, "foo", module, allow_lazy_parsing);
    4102             :       }
    4103        4080 :       TestMaybeAssigned(wrap(input), "foo", module, false);
    4104             :     }
    4105        2040 :   }
    4106             : 
    4107         120 :   for (unsigned i = 0; i < arraysize(script_only_tests); ++i) {
    4108         120 :     Input input = script_only_tests[i];
    4109         360 :     for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
    4110             :          ++allow_lazy_parsing) {
    4111         240 :       TestMaybeAssigned(input, "foo", false, allow_lazy_parsing);
    4112             :     }
    4113         120 :     TestMaybeAssigned(wrap(input), "foo", false, false);
    4114         120 :   }
    4115           5 : }
    4116             : 
    4117       25880 : TEST(MaybeAssignedTopLevel) {
    4118             :   i::Isolate* isolate = CcTest::i_isolate();
    4119             :   i::HandleScope scope(isolate);
    4120          10 :   LocalContext env;
    4121             : 
    4122             :   const char* prefixes[] = {
    4123             :       "let foo; ",
    4124             :       "let foo = 0; ",
    4125             :       "let [foo] = [1]; ",
    4126             :       "let {foo} = {foo: 2}; ",
    4127             :       "let {foo=3} = {}; ",
    4128             :       "var foo; ",
    4129             :       "var foo = 0; ",
    4130             :       "var [foo] = [1]; ",
    4131             :       "var {foo} = {foo: 2}; ",
    4132             :       "var {foo=3} = {}; ",
    4133             :       "{ var foo; }; ",
    4134             :       "{ var foo = 0; }; ",
    4135             :       "{ var [foo] = [1]; }; ",
    4136             :       "{ var {foo} = {foo: 2}; }; ",
    4137             :       "{ var {foo=3} = {}; }; ",
    4138             :       "function foo() {}; ",
    4139             :       "function* foo() {}; ",
    4140             :       "async function foo() {}; ",
    4141             :       "class foo {}; ",
    4142             :       "class foo extends null {}; ",
    4143           5 :   };
    4144             : 
    4145             :   const char* module_and_script_tests[] = {
    4146             :       "function bar() {foo = 42}; ext(bar); ext(foo)",
    4147             :       "ext(function() {foo++}); ext(foo)",
    4148             :       "bar = () => --foo; ext(bar); ext(foo)",
    4149             :       "function* bar() {eval(ext)}; ext(bar); ext(foo)",
    4150           5 :   };
    4151             : 
    4152             :   const char* script_only_tests[] = {
    4153             :       "",
    4154             :       "{ function foo() {}; }; ",
    4155             :       "{ function* foo() {}; }; ",
    4156             :       "{ async function foo() {}; }; ",
    4157           5 :   };
    4158             : 
    4159         105 :   for (unsigned i = 0; i < arraysize(prefixes); ++i) {
    4160         400 :     for (unsigned j = 0; j < arraysize(module_and_script_tests); ++j) {
    4161         400 :       std::string source(prefixes[i]);
    4162         400 :       source += module_and_script_tests[j];
    4163             :       std::vector<unsigned> top;
    4164         800 :       Input input({true, source, top});
    4165        1200 :       for (unsigned module = 0; module <= 1; ++module) {
    4166        1600 :         for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
    4167             :              ++allow_lazy_parsing) {
    4168        1600 :           TestMaybeAssigned(input, "foo", module, allow_lazy_parsing);
    4169             :         }
    4170             :       }
    4171             :     }
    4172             :   }
    4173             : 
    4174         100 :   for (unsigned i = 0; i < arraysize(prefixes); ++i) {
    4175         400 :     for (unsigned j = 0; j < arraysize(script_only_tests); ++j) {
    4176         400 :       std::string source(prefixes[i]);
    4177         400 :       source += script_only_tests[j];
    4178             :       std::vector<unsigned> top;
    4179         800 :       Input input({true, source, top});
    4180        1200 :       for (unsigned allow_lazy_parsing = 0; allow_lazy_parsing <= 1;
    4181             :            ++allow_lazy_parsing) {
    4182         800 :         TestMaybeAssigned(input, "foo", false, allow_lazy_parsing);
    4183             :       }
    4184             :     }
    4185             :   }
    4186           5 : }
    4187             : 
    4188             : namespace {
    4189             : 
    4190          10 : i::Scope* DeserializeFunctionScope(i::Isolate* isolate, i::Zone* zone,
    4191             :                                    i::Handle<i::JSObject> m, const char* name) {
    4192             :   i::AstValueFactory avf(zone, isolate->ast_string_constants(),
    4193          10 :                          HashSeed(isolate));
    4194             :   i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(
    4195          10 :       i::JSReceiver::GetProperty(isolate, m, name).ToHandleChecked());
    4196             :   i::DeclarationScope* script_scope =
    4197           5 :       new (zone) i::DeclarationScope(zone, &avf);
    4198             :   i::Scope* s = i::Scope::DeserializeScopeChain(
    4199          10 :       isolate, zone, f->context()->scope_info(), script_scope, &avf,
    4200           5 :       i::Scope::DeserializationMode::kIncludingVariables);
    4201           5 :   return s;
    4202             : }
    4203             : 
    4204             : }  // namespace
    4205             : 
    4206       25880 : TEST(AsmModuleFlag) {
    4207           5 :   i::FLAG_validate_asm = false;
    4208           5 :   i::Isolate* isolate = CcTest::i_isolate();
    4209             :   i::HandleScope scope(isolate);
    4210          10 :   LocalContext env;
    4211             : 
    4212             :   const char* src =
    4213             :       "function m() {"
    4214             :       "  'use asm';"
    4215             :       "  function f() { return 0 };"
    4216             :       "  return { f:f };"
    4217             :       "}"
    4218             :       "m();";
    4219             : 
    4220          10 :   i::Zone zone(isolate->allocator(), ZONE_NAME);
    4221             :   v8::Local<v8::Value> v = CompileRun(src);
    4222           5 :   i::Handle<i::Object> o = v8::Utils::OpenHandle(*v);
    4223           5 :   i::Handle<i::JSObject> m = i::Handle<i::JSObject>::cast(o);
    4224             : 
    4225             :   // The asm.js module should be marked as such.
    4226           5 :   i::Scope* s = DeserializeFunctionScope(isolate, &zone, m, "f");
    4227          10 :   CHECK(s->IsAsmModule() && s->AsDeclarationScope()->is_asm_module());
    4228           5 : }
    4229             : 
    4230             : 
    4231       25880 : TEST(UseAsmUseCount) {
    4232             :   i::Isolate* isolate = CcTest::i_isolate();
    4233             :   i::HandleScope scope(isolate);
    4234          10 :   LocalContext env;
    4235           5 :   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
    4236           5 :   global_use_counts = use_counts;
    4237           5 :   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
    4238             :   CompileRun("\"use asm\";\n"
    4239             :              "var foo = 1;\n"
    4240             :              "function bar() { \"use asm\"; var baz = 1; }");
    4241           5 :   CHECK_LT(0, use_counts[v8::Isolate::kUseAsm]);
    4242           5 : }
    4243             : 
    4244             : 
    4245       25880 : TEST(StrictModeUseCount) {
    4246             :   i::Isolate* isolate = CcTest::i_isolate();
    4247             :   i::HandleScope scope(isolate);
    4248          10 :   LocalContext env;
    4249           5 :   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
    4250           5 :   global_use_counts = use_counts;
    4251           5 :   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
    4252             :   CompileRun(
    4253             :       "\"use strict\";\n"
    4254             :       "function bar() { var baz = 1; }");  // strict mode inherits
    4255           5 :   CHECK_LT(0, use_counts[v8::Isolate::kStrictMode]);
    4256           5 :   CHECK_EQ(0, use_counts[v8::Isolate::kSloppyMode]);
    4257           5 : }
    4258             : 
    4259             : 
    4260       25880 : TEST(SloppyModeUseCount) {
    4261             :   i::Isolate* isolate = CcTest::i_isolate();
    4262             :   i::HandleScope scope(isolate);
    4263          10 :   LocalContext env;
    4264           5 :   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
    4265           5 :   global_use_counts = use_counts;
    4266             :   // Force eager parsing (preparser doesn't update use counts).
    4267           5 :   i::FLAG_lazy = false;
    4268           5 :   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
    4269             :   CompileRun("function bar() { var baz = 1; }");
    4270           5 :   CHECK_LT(0, use_counts[v8::Isolate::kSloppyMode]);
    4271           5 :   CHECK_EQ(0, use_counts[v8::Isolate::kStrictMode]);
    4272           5 : }
    4273             : 
    4274             : 
    4275       25880 : TEST(BothModesUseCount) {
    4276             :   i::Isolate* isolate = CcTest::i_isolate();
    4277             :   i::HandleScope scope(isolate);
    4278          10 :   LocalContext env;
    4279           5 :   int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
    4280           5 :   global_use_counts = use_counts;
    4281             :   // Force eager parsing (preparser doesn't update use counts).
    4282           5 :   i::FLAG_lazy = false;
    4283           5 :   CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
    4284             :   CompileRun("function bar() { 'use strict'; var baz = 1; }");
    4285           5 :   CHECK_LT(0, use_counts[v8::Isolate::kSloppyMode]);
    4286           5 :   CHECK_LT(0, use_counts[v8::Isolate::kStrictMode]);
    4287           5 : }
    4288             : 
    4289       25880 : TEST(LineOrParagraphSeparatorAsLineTerminator) {
    4290             :   // Tests that both preparsing and parsing accept U+2028 LINE SEPARATOR and
    4291             :   // U+2029 PARAGRAPH SEPARATOR as LineTerminator symbols outside of string
    4292             :   // literals.
    4293           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    4294             :   const char* statement_data[] = {"\x31\xE2\x80\xA8\x32",  // 1<U+2028>2
    4295             :                                   "\x31\xE2\x80\xA9\x32",  // 1<U+2029>2
    4296           5 :                                   nullptr};
    4297             : 
    4298           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    4299           5 : }
    4300             : 
    4301       25880 : TEST(LineOrParagraphSeparatorInStringLiteral) {
    4302             :   // Tests that both preparsing and parsing don't treat U+2028 LINE SEPARATOR
    4303             :   // and U+2029 PARAGRAPH SEPARATOR as line terminators within string literals.
    4304             :   // https://github.com/tc39/proposal-json-superset
    4305             :   const char* context_data[][2] = {
    4306           5 :       {"\"", "\""}, {"'", "'"}, {nullptr, nullptr}};
    4307             :   const char* statement_data[] = {"\x31\xE2\x80\xA8\x32",  // 1<U+2028>2
    4308             :                                   "\x31\xE2\x80\xA9\x32",  // 1<U+2029>2
    4309           5 :                                   nullptr};
    4310             : 
    4311           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    4312           5 : }
    4313             : 
    4314       25880 : TEST(ErrorsArrowFormalParameters) {
    4315             :   const char* context_data[][2] = {
    4316             :     { "()", "=>{}" },
    4317             :     { "()", "=>{};" },
    4318             :     { "var x = ()", "=>{}" },
    4319             :     { "var x = ()", "=>{};" },
    4320             : 
    4321             :     { "a", "=>{}" },
    4322             :     { "a", "=>{};" },
    4323             :     { "var x = a", "=>{}" },
    4324             :     { "var x = a", "=>{};" },
    4325             : 
    4326             :     { "(a)", "=>{}" },
    4327             :     { "(a)", "=>{};" },
    4328             :     { "var x = (a)", "=>{}" },
    4329             :     { "var x = (a)", "=>{};" },
    4330             : 
    4331             :     { "(...a)", "=>{}" },
    4332             :     { "(...a)", "=>{};" },
    4333             :     { "var x = (...a)", "=>{}" },
    4334             :     { "var x = (...a)", "=>{};" },
    4335             : 
    4336             :     { "(a,b)", "=>{}" },
    4337             :     { "(a,b)", "=>{};" },
    4338             :     { "var x = (a,b)", "=>{}" },
    4339             :     { "var x = (a,b)", "=>{};" },
    4340             : 
    4341             :     { "(a,...b)", "=>{}" },
    4342             :     { "(a,...b)", "=>{};" },
    4343             :     { "var x = (a,...b)", "=>{}" },
    4344             :     { "var x = (a,...b)", "=>{};" },
    4345             : 
    4346             :     { nullptr, nullptr }
    4347           5 :   };
    4348             :   const char* assignment_expression_suffix_data[] = {
    4349             :     "?c:d=>{}",
    4350             :     "=c=>{}",
    4351             :     "()",
    4352             :     "(c)",
    4353             :     "[1]",
    4354             :     "[c]",
    4355             :     ".c",
    4356             :     "-c",
    4357             :     "+c",
    4358             :     "c++",
    4359             :     "`c`",
    4360             :     "`${c}`",
    4361             :     "`template-head${c}`",
    4362             :     "`${c}template-tail`",
    4363             :     "`template-head${c}template-tail`",
    4364             :     "`${c}template-tail`",
    4365             :     nullptr
    4366           5 :   };
    4367             : 
    4368           5 :   RunParserSyncTest(context_data, assignment_expression_suffix_data, kError);
    4369           5 : }
    4370             : 
    4371             : 
    4372       25880 : TEST(ErrorsArrowFunctions) {
    4373             :   // Tests that parser and preparser generate the same kind of errors
    4374             :   // on invalid arrow function syntax.
    4375             : 
    4376             :   // clang-format off
    4377             :   const char* context_data[][2] = {
    4378             :     {"", ";"},
    4379             :     {"v = ", ";"},
    4380             :     {"bar ? (", ") : baz;"},
    4381             :     {"bar ? baz : (", ");"},
    4382             :     {"bar[", "];"},
    4383             :     {"bar, ", ";"},
    4384             :     {"", ", bar;"},
    4385             :     {nullptr, nullptr}
    4386           5 :   };
    4387             : 
    4388             :   const char* statement_data[] = {
    4389             :     "=> 0",
    4390             :     "=>",
    4391             :     "() =>",
    4392             :     "=> {}",
    4393             :     ") => {}",
    4394             :     ", => {}",
    4395             :     "(,) => {}",
    4396             :     "return => {}",
    4397             :     "() => {'value': 42}",
    4398             : 
    4399             :     // Check that the early return introduced in ParsePrimaryExpression
    4400             :     // does not accept stray closing parentheses.
    4401             :     ")",
    4402             :     ") => 0",
    4403             :     "foo[()]",
    4404             :     "()",
    4405             : 
    4406             :     // Parameter lists with extra parens should be recognized as errors.
    4407             :     "(()) => 0",
    4408             :     "((x)) => 0",
    4409             :     "((x, y)) => 0",
    4410             :     "(x, (y)) => 0",
    4411             :     "((x, y, z)) => 0",
    4412             :     "(x, (y, z)) => 0",
    4413             :     "((x, y), z) => 0",
    4414             : 
    4415             :     // Arrow function formal parameters are parsed as StrictFormalParameters,
    4416             :     // which confusingly only implies that there are no duplicates.  Words
    4417             :     // reserved in strict mode, and eval or arguments, are indeed valid in
    4418             :     // sloppy mode.
    4419             :     "eval => { 'use strict'; 0 }",
    4420             :     "arguments => { 'use strict'; 0 }",
    4421             :     "yield => { 'use strict'; 0 }",
    4422             :     "interface => { 'use strict'; 0 }",
    4423             :     "(eval) => { 'use strict'; 0 }",
    4424             :     "(arguments) => { 'use strict'; 0 }",
    4425             :     "(yield) => { 'use strict'; 0 }",
    4426             :     "(interface) => { 'use strict'; 0 }",
    4427             :     "(eval, bar) => { 'use strict'; 0 }",
    4428             :     "(bar, eval) => { 'use strict'; 0 }",
    4429             :     "(bar, arguments) => { 'use strict'; 0 }",
    4430             :     "(bar, yield) => { 'use strict'; 0 }",
    4431             :     "(bar, interface) => { 'use strict'; 0 }",
    4432             :     // TODO(aperez): Detecting duplicates does not work in PreParser.
    4433             :     // "(bar, bar) => {}",
    4434             : 
    4435             :     // The parameter list is parsed as an expression, but only
    4436             :     // a comma-separated list of identifier is valid.
    4437             :     "32 => {}",
    4438             :     "(32) => {}",
    4439             :     "(a, 32) => {}",
    4440             :     "if => {}",
    4441             :     "(if) => {}",
    4442             :     "(a, if) => {}",
    4443             :     "a + b => {}",
    4444             :     "(a + b) => {}",
    4445             :     "(a + b, c) => {}",
    4446             :     "(a, b - c) => {}",
    4447             :     "\"a\" => {}",
    4448             :     "(\"a\") => {}",
    4449             :     "(\"a\", b) => {}",
    4450             :     "(a, \"b\") => {}",
    4451             :     "-a => {}",
    4452             :     "(-a) => {}",
    4453             :     "(-a, b) => {}",
    4454             :     "(a, -b) => {}",
    4455             :     "{} => {}",
    4456             :     "a++ => {}",
    4457             :     "(a++) => {}",
    4458             :     "(a++, b) => {}",
    4459             :     "(a, b++) => {}",
    4460             :     "[] => {}",
    4461             :     "(foo ? bar : baz) => {}",
    4462             :     "(a, foo ? bar : baz) => {}",
    4463             :     "(foo ? bar : baz, a) => {}",
    4464             :     "(a.b, c) => {}",
    4465             :     "(c, a.b) => {}",
    4466             :     "(a['b'], c) => {}",
    4467             :     "(c, a['b']) => {}",
    4468             :     "(...a = b) => b",
    4469             : 
    4470             :     // crbug.com/582626
    4471             :     "(...rest - a) => b",
    4472             :     "(a, ...b - 10) => b",
    4473             : 
    4474             :     nullptr
    4475           5 :   };
    4476             :   // clang-format on
    4477             : 
    4478             :   // The test is quite slow, so run it with a reduced set of flags.
    4479             :   static const ParserFlag flags[] = {kAllowLazy};
    4480             :   RunParserSyncTest(context_data, statement_data, kError, flags,
    4481           5 :                     arraysize(flags));
    4482             : 
    4483             :   // In a context where a concise arrow body is parsed with [~In] variant,
    4484             :   // ensure that an error is reported in both full parser and preparser.
    4485             :   const char* loop_context_data[][2] = {{"for (", "; 0;);"},
    4486           5 :                                         {nullptr, nullptr}};
    4487           5 :   const char* loop_expr_data[] = {"f => 'key' in {}", nullptr};
    4488             :   RunParserSyncTest(loop_context_data, loop_expr_data, kError, flags,
    4489           5 :                     arraysize(flags));
    4490           5 : }
    4491             : 
    4492             : 
    4493       25880 : TEST(NoErrorsArrowFunctions) {
    4494             :   // Tests that parser and preparser accept valid arrow functions syntax.
    4495             :   // clang-format off
    4496             :   const char* context_data[][2] = {
    4497             :     {"", ";"},
    4498             :     {"bar ? (", ") : baz;"},
    4499             :     {"bar ? baz : (", ");"},
    4500             :     {"bar, ", ";"},
    4501             :     {"", ", bar;"},
    4502             :     {nullptr, nullptr}
    4503           5 :   };
    4504             : 
    4505             :   const char* statement_data[] = {
    4506             :     "() => {}",
    4507             :     "() => { return 42 }",
    4508             :     "x => { return x; }",
    4509             :     "(x) => { return x; }",
    4510             :     "(x, y) => { return x + y; }",
    4511             :     "(x, y, z) => { return x + y + z; }",
    4512             :     "(x, y) => { x.a = y; }",
    4513             :     "() => 42",
    4514             :     "x => x",
    4515             :     "x => x * x",
    4516             :     "(x) => x",
    4517             :     "(x) => x * x",
    4518             :     "(x, y) => x + y",
    4519             :     "(x, y, z) => x, y, z",
    4520             :     "(x, y) => x.a = y",
    4521             :     "() => ({'value': 42})",
    4522             :     "x => y => x + y",
    4523             :     "(x, y) => (u, v) => x*u + y*v",
    4524             :     "(x, y) => z => z * (x + y)",
    4525             :     "x => (y, z) => z * (x + y)",
    4526             : 
    4527             :     // Those are comma-separated expressions, with arrow functions as items.
    4528             :     // They stress the code for validating arrow function parameter lists.
    4529             :     "a, b => 0",
    4530             :     "a, b, (c, d) => 0",
    4531             :     "(a, b, (c, d) => 0)",
    4532             :     "(a, b) => 0, (c, d) => 1",
    4533             :     "(a, b => {}, a => a + 1)",
    4534             :     "((a, b) => {}, (a => a + 1))",
    4535             :     "(a, (a, (b, c) => 0))",
    4536             : 
    4537             :     // Arrow has more precedence, this is the same as: foo ? bar : (baz = {})
    4538             :     "foo ? bar : baz => {}",
    4539             : 
    4540             :     // Arrows with non-simple parameters.
    4541             :     "({}) => {}",
    4542             :     "(a, {}) => {}",
    4543             :     "({}, a) => {}",
    4544             :     "([]) => {}",
    4545             :     "(a, []) => {}",
    4546             :     "([], a) => {}",
    4547             :     "(a = b) => {}",
    4548             :     "(a = b, c) => {}",
    4549             :     "(a, b = c) => {}",
    4550             :     "({a}) => {}",
    4551             :     "(x = 9) => {}",
    4552             :     "(x, y = 9) => {}",
    4553             :     "(x = 9, y) => {}",
    4554             :     "(x, y = 9, z) => {}",
    4555             :     "(x, y = 9, z = 8) => {}",
    4556             :     "(...a) => {}",
    4557             :     "(x, ...a) => {}",
    4558             :     "(x = 9, ...a) => {}",
    4559             :     "(x, y = 9, ...a) => {}",
    4560             :     "(x, y = 9, {b}, z = 8, ...a) => {}",
    4561             :     "({a} = {}) => {}",
    4562             :     "([x] = []) => {}",
    4563             :     "({a = 42}) => {}",
    4564             :     "([x = 0]) => {}",
    4565             :     nullptr
    4566           5 :   };
    4567             :   // clang-format on
    4568             : 
    4569           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    4570             : 
    4571             :   static const ParserFlag flags[] = {kAllowLazy};
    4572             :   // In a context where a concise arrow body is parsed with [~In] variant,
    4573             :   // ensure that nested expressions can still use the 'in' operator,
    4574             :   const char* loop_context_data[][2] = {{"for (", "; 0;);"},
    4575           5 :                                         {nullptr, nullptr}};
    4576           5 :   const char* loop_expr_data[] = {"f => ('key' in {})", nullptr};
    4577             :   RunParserSyncTest(loop_context_data, loop_expr_data, kSuccess, flags,
    4578           5 :                     arraysize(flags));
    4579           5 : }
    4580             : 
    4581             : 
    4582       25880 : TEST(ArrowFunctionsSloppyParameterNames) {
    4583             :   const char* strict_context_data[][2] = {{"'use strict'; ", ";"},
    4584             :                                           {"'use strict'; bar ? (", ") : baz;"},
    4585             :                                           {"'use strict'; bar ? baz : (", ");"},
    4586             :                                           {"'use strict'; bar, ", ";"},
    4587             :                                           {"'use strict'; ", ", bar;"},
    4588           5 :                                           {nullptr, nullptr}};
    4589             : 
    4590             :   const char* sloppy_context_data[][2] = {
    4591             :       {"", ";"},      {"bar ? (", ") : baz;"}, {"bar ? baz : (", ");"},
    4592           5 :       {"bar, ", ";"}, {"", ", bar;"},          {nullptr, nullptr}};
    4593             : 
    4594             :   const char* statement_data[] = {"eval => {}",
    4595             :                                   "arguments => {}",
    4596             :                                   "yield => {}",
    4597             :                                   "interface => {}",
    4598             :                                   "(eval) => {}",
    4599             :                                   "(arguments) => {}",
    4600             :                                   "(yield) => {}",
    4601             :                                   "(interface) => {}",
    4602             :                                   "(eval, bar) => {}",
    4603             :                                   "(bar, eval) => {}",
    4604             :                                   "(bar, arguments) => {}",
    4605             :                                   "(bar, yield) => {}",
    4606             :                                   "(bar, interface) => {}",
    4607             :                                   "(interface, eval) => {}",
    4608             :                                   "(interface, arguments) => {}",
    4609             :                                   "(eval, interface) => {}",
    4610             :                                   "(arguments, interface) => {}",
    4611           5 :                                   nullptr};
    4612             : 
    4613           5 :   RunParserSyncTest(strict_context_data, statement_data, kError);
    4614           5 :   RunParserSyncTest(sloppy_context_data, statement_data, kSuccess);
    4615           5 : }
    4616             : 
    4617             : 
    4618       25880 : TEST(ArrowFunctionsYieldParameterNameInGenerator) {
    4619             :   const char* sloppy_function_context_data[][2] = {
    4620           5 :       {"(function f() { (", "); });"}, {nullptr, nullptr}};
    4621             : 
    4622             :   const char* strict_function_context_data[][2] = {
    4623           5 :       {"(function f() {'use strict'; (", "); });"}, {nullptr, nullptr}};
    4624             : 
    4625             :   const char* generator_context_data[][2] = {
    4626             :       {"(function *g() {'use strict'; (", "); });"},
    4627             :       {"(function *g() { (", "); });"},
    4628           5 :       {nullptr, nullptr}};
    4629             : 
    4630             :   const char* arrow_data[] = {
    4631             :       "yield => {}",      "(yield) => {}",       "(a, yield) => {}",
    4632             :       "(yield, a) => {}", "(yield, ...a) => {}", "(a, ...yield) => {}",
    4633           5 :       "({yield}) => {}",  "([yield]) => {}",     nullptr};
    4634             : 
    4635           5 :   RunParserSyncTest(sloppy_function_context_data, arrow_data, kSuccess);
    4636           5 :   RunParserSyncTest(strict_function_context_data, arrow_data, kError);
    4637           5 :   RunParserSyncTest(generator_context_data, arrow_data, kError);
    4638           5 : }
    4639             : 
    4640             : 
    4641       25880 : TEST(SuperNoErrors) {
    4642             :   // Tests that parser and preparser accept 'super' keyword in right places.
    4643             :   const char* context_data[][2] = {{"class C { m() { ", "; } }"},
    4644             :                                    {"class C { m() { k = ", "; } }"},
    4645             :                                    {"class C { m() { foo(", "); } }"},
    4646             :                                    {"class C { m() { () => ", "; } }"},
    4647           5 :                                    {nullptr, nullptr}};
    4648             : 
    4649             :   const char* statement_data[] = {"super.x",       "super[27]",
    4650             :                                   "new super.x",   "new super.x()",
    4651             :                                   "new super[27]", "new super[27]()",
    4652             :                                   "z.super",  // Ok, property lookup.
    4653           5 :                                   nullptr};
    4654             : 
    4655           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    4656           5 : }
    4657             : 
    4658             : 
    4659       25880 : TEST(SuperErrors) {
    4660             :   const char* context_data[][2] = {{"class C { m() { ", "; } }"},
    4661             :                                    {"class C { m() { k = ", "; } }"},
    4662             :                                    {"class C { m() { foo(", "); } }"},
    4663             :                                    {"class C { m() { () => ", "; } }"},
    4664           5 :                                    {nullptr, nullptr}};
    4665             : 
    4666             :   const char* expression_data[] = {"super",
    4667             :                                    "super = x",
    4668             :                                    "y = super",
    4669             :                                    "f(super)",
    4670             :                                    "new super",
    4671             :                                    "new super()",
    4672             :                                    "new super(12, 45)",
    4673             :                                    "new new super",
    4674             :                                    "new new super()",
    4675             :                                    "new new super()()",
    4676           5 :                                    nullptr};
    4677             : 
    4678           5 :   RunParserSyncTest(context_data, expression_data, kError);
    4679           5 : }
    4680             : 
    4681       25880 : TEST(ImportExpressionSuccess) {
    4682             :   // clang-format off
    4683             :   const char* context_data[][2] = {
    4684             :     {"", ""},
    4685             :     {nullptr, nullptr}
    4686           5 :   };
    4687             : 
    4688             :   const char* data[] = {
    4689             :     "import(1)",
    4690             :     "import(y=x)",
    4691             :     "f(...[import(y=x)])",
    4692             :     "x = {[import(y=x)]: 1}",
    4693             :     "var {[import(y=x)]: x} = {}",
    4694             :     "({[import(y=x)]: x} = {})",
    4695             :     "async () => { await import(x) }",
    4696             :     "() => { import(x) }",
    4697             :     "(import(y=x))",
    4698             :     "{import(y=x)}",
    4699             :     "import(import(x))",
    4700             :     "x = import(x)",
    4701             :     "var x = import(x)",
    4702             :     "let x = import(x)",
    4703             :     "for(x of import(x)) {}",
    4704             :     "import(x).then()",
    4705             :     nullptr
    4706           5 :   };
    4707             : 
    4708             :   // clang-format on
    4709             : 
    4710             :   // We ignore test error messages because the error message from the
    4711             :   // parser/preparser is different for the same data depending on the
    4712             :   // context.
    4713             :   // For example, a top level "import(" is parsed as an
    4714             :   // import declaration. The parser parses the import token correctly
    4715             :   // and then shows an "Unexpected token (" error message. The
    4716             :   // preparser does not understand the import keyword (this test is
    4717             :   // run without kAllowHarmonyDynamicImport flag), so this results in
    4718             :   // an "Unexpected token import" error.
    4719           5 :   RunParserSyncTest(context_data, data, kError);
    4720             :   RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
    4721             :                           nullptr, 0, true, true);
    4722             :   static const ParserFlag flags[] = {kAllowHarmonyDynamicImport};
    4723             :   RunParserSyncTest(context_data, data, kSuccess, nullptr, 0, flags,
    4724           5 :                     arraysize(flags));
    4725             :   RunModuleParserSyncTest(context_data, data, kSuccess, nullptr, 0, flags,
    4726             :                           arraysize(flags));
    4727           5 : }
    4728             : 
    4729       25880 : TEST(ImportExpressionErrors) {
    4730             :   {
    4731             :     // clang-format off
    4732             :     const char* context_data[][2] = {
    4733             :       {"", ""},
    4734             :       {"var ", ""},
    4735             :       {"let ", ""},
    4736             :       {"new ", ""},
    4737             :       {nullptr, nullptr}
    4738           5 :     };
    4739             : 
    4740             :     const char* data[] = {
    4741             :       "import(",
    4742             :       "import)",
    4743             :       "import()",
    4744             :       "import('x",
    4745             :       "import('x']",
    4746             :       "import['x')",
    4747             :       "import = x",
    4748             :       "import[",
    4749             :       "import[]",
    4750             :       "import]",
    4751             :       "import[x]",
    4752             :       "import{",
    4753             :       "import{x",
    4754             :       "import{x}",
    4755             :       "import(x, y)",
    4756             :       "import(...y)",
    4757             :       "import(x,)",
    4758             :       "import(,)",
    4759             :       "import(,y)",
    4760             :       "import(;)",
    4761             :       "[import]",
    4762             :       "{import}",
    4763             :       "import+",
    4764             :       "import = 1",
    4765             :       "import.wat",
    4766             :       "new import(x)",
    4767             :       nullptr
    4768           5 :     };
    4769             : 
    4770             :     // clang-format on
    4771           5 :     RunParserSyncTest(context_data, data, kError);
    4772             :     // We ignore the error messages for the reason explained in the
    4773             :     // ImportExpressionSuccess test.
    4774             :     RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
    4775             :                             nullptr, 0, true, true);
    4776             :     static const ParserFlag flags[] = {kAllowHarmonyDynamicImport};
    4777             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4778           5 :                       arraysize(flags));
    4779             : 
    4780             :     // We ignore test error messages because the error message from
    4781             :     // the parser/preparser is different for the same data depending
    4782             :     // on the context.  For example, a top level "import{" is parsed
    4783             :     // as an import declaration. The parser parses the import token
    4784             :     // correctly and then shows an "Unexpected end of input" error
    4785             :     // message because of the '{'. The preparser shows an "Unexpected
    4786             :     // token {" because it's not a valid token in a CallExpression.
    4787             :     RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4788             :                             arraysize(flags), nullptr, 0, true, true);
    4789             :   }
    4790             : 
    4791             :   {
    4792             :     // clang-format off
    4793             :     const char* context_data[][2] = {
    4794             :       {"var ", ""},
    4795             :       {"let ", ""},
    4796             :       {nullptr, nullptr}
    4797           5 :     };
    4798             : 
    4799             :     const char* data[] = {
    4800             :       "import('x')",
    4801             :       nullptr
    4802           5 :     };
    4803             : 
    4804             :     // clang-format on
    4805           5 :     RunParserSyncTest(context_data, data, kError);
    4806             :     RunModuleParserSyncTest(context_data, data, kError);
    4807             : 
    4808             :     static const ParserFlag flags[] = {kAllowHarmonyDynamicImport};
    4809             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4810           5 :                       arraysize(flags));
    4811             :     RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4812             :                             arraysize(flags));
    4813             :   }
    4814             : 
    4815             :   // Import statements as arrow function params and destructuring targets.
    4816             :   {
    4817             :     // clang-format off
    4818             :     const char* context_data[][2] = {
    4819             :       {"(", ") => {}"},
    4820             :       {"(a, ", ") => {}"},
    4821             :       {"(1, ", ") => {}"},
    4822             :       {"let f = ", " => {}"},
    4823             :       {"[", "] = [1];"},
    4824             :       {"{", "} = {'a': 1};"},
    4825             :       {nullptr, nullptr}
    4826           5 :     };
    4827             : 
    4828             :     const char* data[] = {
    4829             :       "import(foo)",
    4830             :       "import(1)",
    4831             :       "import(y=x)",
    4832             :       "import(import(x))",
    4833             :       "import(x).then()",
    4834             :       nullptr
    4835           5 :     };
    4836             : 
    4837             :     // clang-format on
    4838           5 :     RunParserSyncTest(context_data, data, kError);
    4839             :     RunModuleParserSyncTest(context_data, data, kError);
    4840             : 
    4841             :     static const ParserFlag flags[] = {kAllowHarmonyDynamicImport};
    4842             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4843           5 :                       arraysize(flags));
    4844             :     RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    4845             :                             arraysize(flags));
    4846             :   }
    4847           5 : }
    4848             : 
    4849       25880 : TEST(SuperCall) {
    4850           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    4851             : 
    4852             :   const char* success_data[] = {
    4853             :       "class C extends B { constructor() { super(); } }",
    4854           5 :       "class C extends B { constructor() { () => super(); } }", nullptr};
    4855             : 
    4856           5 :   RunParserSyncTest(context_data, success_data, kSuccess);
    4857             : 
    4858             :   const char* error_data[] = {"class C { constructor() { super(); } }",
    4859             :                               "class C { method() { super(); } }",
    4860             :                               "class C { method() { () => super(); } }",
    4861             :                               "class C { *method() { super(); } }",
    4862             :                               "class C { get x() { super(); } }",
    4863             :                               "class C { set x(_) { super(); } }",
    4864             :                               "({ method() { super(); } })",
    4865             :                               "({ *method() { super(); } })",
    4866             :                               "({ get x() { super(); } })",
    4867             :                               "({ set x(_) { super(); } })",
    4868             :                               "({ f: function() { super(); } })",
    4869             :                               "(function() { super(); })",
    4870             :                               "var f = function() { super(); }",
    4871             :                               "({ f: function*() { super(); } })",
    4872             :                               "(function*() { super(); })",
    4873             :                               "var f = function*() { super(); }",
    4874           5 :                               nullptr};
    4875             : 
    4876           5 :   RunParserSyncTest(context_data, error_data, kError);
    4877           5 : }
    4878             : 
    4879             : 
    4880       25880 : TEST(SuperNewNoErrors) {
    4881             :   const char* context_data[][2] = {{"class C { constructor() { ", " } }"},
    4882             :                                    {"class C { *method() { ", " } }"},
    4883             :                                    {"class C { get x() { ", " } }"},
    4884             :                                    {"class C { set x(_) { ", " } }"},
    4885             :                                    {"({ method() { ", " } })"},
    4886             :                                    {"({ *method() { ", " } })"},
    4887             :                                    {"({ get x() { ", " } })"},
    4888             :                                    {"({ set x(_) { ", " } })"},
    4889           5 :                                    {nullptr, nullptr}};
    4890             : 
    4891             :   const char* expression_data[] = {"new super.x;", "new super.x();",
    4892             :                                    "() => new super.x;", "() => new super.x();",
    4893           5 :                                    nullptr};
    4894             : 
    4895           5 :   RunParserSyncTest(context_data, expression_data, kSuccess);
    4896           5 : }
    4897             : 
    4898             : 
    4899       25880 : TEST(SuperNewErrors) {
    4900             :   const char* context_data[][2] = {{"class C { method() { ", " } }"},
    4901             :                                    {"class C { *method() { ", " } }"},
    4902             :                                    {"class C { get x() { ", " } }"},
    4903             :                                    {"class C { set x(_) { ", " } }"},
    4904             :                                    {"({ method() { ", " } })"},
    4905             :                                    {"({ *method() { ", " } })"},
    4906             :                                    {"({ get x() { ", " } })"},
    4907             :                                    {"({ set x(_) { ", " } })"},
    4908             :                                    {"({ f: function() { ", " } })"},
    4909             :                                    {"(function() { ", " })"},
    4910             :                                    {"var f = function() { ", " }"},
    4911             :                                    {"({ f: function*() { ", " } })"},
    4912             :                                    {"(function*() { ", " })"},
    4913             :                                    {"var f = function*() { ", " }"},
    4914           5 :                                    {nullptr, nullptr}};
    4915             : 
    4916             :   const char* statement_data[] = {"new super;", "new super();",
    4917             :                                   "() => new super;", "() => new super();",
    4918           5 :                                   nullptr};
    4919             : 
    4920           5 :   RunParserSyncTest(context_data, statement_data, kError);
    4921           5 : }
    4922             : 
    4923             : 
    4924       25880 : TEST(SuperErrorsNonMethods) {
    4925             :   // super is only allowed in methods, accessors and constructors.
    4926             :   const char* context_data[][2] = {{"", ";"},
    4927             :                                    {"k = ", ";"},
    4928             :                                    {"foo(", ");"},
    4929             :                                    {"if (", ") {}"},
    4930             :                                    {"if (true) {", "}"},
    4931             :                                    {"if (false) {} else {", "}"},
    4932             :                                    {"while (true) {", "}"},
    4933             :                                    {"function f() {", "}"},
    4934             :                                    {"class C extends (", ") {}"},
    4935             :                                    {"class C { m() { function f() {", "} } }"},
    4936             :                                    {"({ m() { function f() {", "} } })"},
    4937           5 :                                    {nullptr, nullptr}};
    4938             : 
    4939             :   const char* statement_data[] = {
    4940             :       "super",           "super = x",   "y = super",     "f(super)",
    4941             :       "super.x",         "super[27]",   "super.x()",     "super[27]()",
    4942             :       "super()",         "new super.x", "new super.x()", "new super[27]",
    4943           5 :       "new super[27]()", nullptr};
    4944             : 
    4945           5 :   RunParserSyncTest(context_data, statement_data, kError);
    4946           5 : }
    4947             : 
    4948             : 
    4949       25880 : TEST(NoErrorsMethodDefinition) {
    4950             :   const char* context_data[][2] = {{"({", "});"},
    4951             :                                    {"'use strict'; ({", "});"},
    4952             :                                    {"({*", "});"},
    4953             :                                    {"'use strict'; ({*", "});"},
    4954           5 :                                    {nullptr, nullptr}};
    4955             : 
    4956             :   const char* object_literal_body_data[] = {
    4957             :       "m() {}",       "m(x) { return x; }", "m(x, y) {}, n() {}",
    4958           5 :       "set(x, y) {}", "get(x, y) {}",       nullptr};
    4959             : 
    4960           5 :   RunParserSyncTest(context_data, object_literal_body_data, kSuccess);
    4961           5 : }
    4962             : 
    4963             : 
    4964       25880 : TEST(MethodDefinitionNames) {
    4965             :   const char* context_data[][2] = {{"({", "(x, y) {}});"},
    4966             :                                    {"'use strict'; ({", "(x, y) {}});"},
    4967             :                                    {"({*", "(x, y) {}});"},
    4968             :                                    {"'use strict'; ({*", "(x, y) {}});"},
    4969           5 :                                    {nullptr, nullptr}};
    4970             : 
    4971             :   const char* name_data[] = {
    4972             :       "m", "'m'", "\"m\"", "\"m n\"", "true", "false", "null", "0", "1.2",
    4973             :       "1e1", "1E1", "1e+1", "1e-1",
    4974             : 
    4975             :       // Keywords
    4976             :       "async", "await", "break", "case", "catch", "class", "const", "continue",
    4977             :       "debugger", "default", "delete", "do", "else", "enum", "export",
    4978             :       "extends", "finally", "for", "function", "if", "implements", "import",
    4979             :       "in", "instanceof", "interface", "let", "new", "package", "private",
    4980             :       "protected", "public", "return", "static", "super", "switch", "this",
    4981             :       "throw", "try", "typeof", "var", "void", "while", "with", "yield",
    4982           5 :       nullptr};
    4983             : 
    4984           5 :   RunParserSyncTest(context_data, name_data, kSuccess);
    4985           5 : }
    4986             : 
    4987             : 
    4988       25880 : TEST(MethodDefinitionStrictFormalParamereters) {
    4989             :   const char* context_data[][2] = {{"({method(", "){}});"},
    4990             :                                    {"'use strict'; ({method(", "){}});"},
    4991             :                                    {"({*method(", "){}});"},
    4992             :                                    {"'use strict'; ({*method(", "){}});"},
    4993           5 :                                    {nullptr, nullptr}};
    4994             : 
    4995           5 :   const char* params_data[] = {"x, x", "x, y, x", "var", "const", nullptr};
    4996             : 
    4997           5 :   RunParserSyncTest(context_data, params_data, kError);
    4998           5 : }
    4999             : 
    5000             : 
    5001       25880 : TEST(MethodDefinitionEvalArguments) {
    5002             :   const char* strict_context_data[][2] = {
    5003             :       {"'use strict'; ({method(", "){}});"},
    5004             :       {"'use strict'; ({*method(", "){}});"},
    5005           5 :       {nullptr, nullptr}};
    5006             :   const char* sloppy_context_data[][2] = {
    5007           5 :       {"({method(", "){}});"}, {"({*method(", "){}});"}, {nullptr, nullptr}};
    5008             : 
    5009           5 :   const char* data[] = {"eval", "arguments", nullptr};
    5010             : 
    5011             :   // Fail in strict mode
    5012           5 :   RunParserSyncTest(strict_context_data, data, kError);
    5013             : 
    5014             :   // OK in sloppy mode
    5015           5 :   RunParserSyncTest(sloppy_context_data, data, kSuccess);
    5016           5 : }
    5017             : 
    5018             : 
    5019       25880 : TEST(MethodDefinitionDuplicateEvalArguments) {
    5020             :   const char* context_data[][2] = {{"'use strict'; ({method(", "){}});"},
    5021             :                                    {"'use strict'; ({*method(", "){}});"},
    5022             :                                    {"({method(", "){}});"},
    5023             :                                    {"({*method(", "){}});"},
    5024           5 :                                    {nullptr, nullptr}};
    5025             : 
    5026             :   const char* data[] = {"eval, eval", "eval, a, eval", "arguments, arguments",
    5027           5 :                         "arguments, a, arguments", nullptr};
    5028             : 
    5029             :   // In strict mode, the error is using "eval" or "arguments" as parameter names
    5030             :   // In sloppy mode, the error is that eval / arguments are duplicated
    5031           5 :   RunParserSyncTest(context_data, data, kError);
    5032           5 : }
    5033             : 
    5034             : 
    5035       25880 : TEST(MethodDefinitionDuplicateProperty) {
    5036             :   const char* context_data[][2] = {{"'use strict'; ({", "});"},
    5037           5 :                                    {nullptr, nullptr}};
    5038             : 
    5039             :   const char* params_data[] = {"x: 1, x() {}",
    5040             :                                "x() {}, x: 1",
    5041             :                                "x() {}, get x() {}",
    5042             :                                "x() {}, set x(_) {}",
    5043             :                                "x() {}, x() {}",
    5044             :                                "x() {}, y() {}, x() {}",
    5045             :                                "x() {}, \"x\"() {}",
    5046             :                                "x() {}, 'x'() {}",
    5047             :                                "0() {}, '0'() {}",
    5048             :                                "1.0() {}, 1: 1",
    5049             : 
    5050             :                                "x: 1, *x() {}",
    5051             :                                "*x() {}, x: 1",
    5052             :                                "*x() {}, get x() {}",
    5053             :                                "*x() {}, set x(_) {}",
    5054             :                                "*x() {}, *x() {}",
    5055             :                                "*x() {}, y() {}, *x() {}",
    5056             :                                "*x() {}, *\"x\"() {}",
    5057             :                                "*x() {}, *'x'() {}",
    5058             :                                "*0() {}, *'0'() {}",
    5059             :                                "*1.0() {}, 1: 1",
    5060             : 
    5061           5 :                                nullptr};
    5062             : 
    5063           5 :   RunParserSyncTest(context_data, params_data, kSuccess);
    5064           5 : }
    5065             : 
    5066             : 
    5067       25880 : TEST(ClassExpressionNoErrors) {
    5068             :   const char* context_data[][2] = {
    5069           5 :       {"(", ");"}, {"var C = ", ";"}, {"bar, ", ";"}, {nullptr, nullptr}};
    5070             :   const char* class_data[] = {"class {}",
    5071             :                               "class name {}",
    5072             :                               "class extends F {}",
    5073             :                               "class name extends F {}",
    5074             :                               "class extends (F, G) {}",
    5075             :                               "class name extends (F, G) {}",
    5076             :                               "class extends class {} {}",
    5077             :                               "class name extends class {} {}",
    5078             :                               "class extends class base {} {}",
    5079             :                               "class name extends class base {} {}",
    5080           5 :                               nullptr};
    5081             : 
    5082           5 :   RunParserSyncTest(context_data, class_data, kSuccess);
    5083           5 : }
    5084             : 
    5085             : 
    5086       25880 : TEST(ClassDeclarationNoErrors) {
    5087             :   const char* context_data[][2] = {{"'use strict'; ", ""},
    5088             :                                    {"'use strict'; {", "}"},
    5089             :                                    {"'use strict'; if (true) {", "}"},
    5090           5 :                                    {nullptr, nullptr}};
    5091             :   const char* statement_data[] = {"class name {}",
    5092             :                                   "class name extends F {}",
    5093             :                                   "class name extends (F, G) {}",
    5094             :                                   "class name extends class {} {}",
    5095             :                                   "class name extends class base {} {}",
    5096           5 :                                   nullptr};
    5097             : 
    5098           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    5099           5 : }
    5100             : 
    5101             : 
    5102       25880 : TEST(ClassBodyNoErrors) {
    5103             :   // clang-format off
    5104             :   // Tests that parser and preparser accept valid class syntax.
    5105             :   const char* context_data[][2] = {{"(class {", "});"},
    5106             :                                    {"(class extends Base {", "});"},
    5107             :                                    {"class C {", "}"},
    5108             :                                    {"class C extends Base {", "}"},
    5109           5 :                                    {nullptr, nullptr}};
    5110             :   const char* class_body_data[] = {
    5111             :     ";",
    5112             :     ";;",
    5113             :     "m() {}",
    5114             :     "m() {};",
    5115             :     "; m() {}",
    5116             :     "m() {}; n(x) {}",
    5117             :     "get x() {}",
    5118             :     "set x(v) {}",
    5119             :     "get() {}",
    5120             :     "set() {}",
    5121             :     "*g() {}",
    5122             :     "*g() {};",
    5123             :     "; *g() {}",
    5124             :     "*g() {}; *h(x) {}",
    5125             :     "async *x(){}",
    5126             :     "static() {}",
    5127             :     "get static() {}",
    5128             :     "set static(v) {}",
    5129             :     "static m() {}",
    5130             :     "static get x() {}",
    5131             :     "static set x(v) {}",
    5132             :     "static get() {}",
    5133             :     "static set() {}",
    5134             :     "static static() {}",
    5135             :     "static get static() {}",
    5136             :     "static set static(v) {}",
    5137             :     "*static() {}",
    5138             :     "static *static() {}",
    5139             :     "*get() {}",
    5140             :     "*set() {}",
    5141             :     "static *g() {}",
    5142             :     "async(){}",
    5143             :     "*async(){}",
    5144             :     "static async(){}",
    5145             :     "static *async(){}",
    5146             :     "static async *x(){}",
    5147             : 
    5148             :     // Escaped 'static' should be allowed anywhere
    5149             :     // static-as-PropertyName is.
    5150             :     "st\\u0061tic() {}",
    5151             :     "get st\\u0061tic() {}",
    5152             :     "set st\\u0061tic(v) {}",
    5153             :     "static st\\u0061tic() {}",
    5154             :     "static get st\\u0061tic() {}",
    5155             :     "static set st\\u0061tic(v) {}",
    5156             :     "*st\\u0061tic() {}",
    5157             :     "static *st\\u0061tic() {}",
    5158             : 
    5159             :     "static async x(){}",
    5160             :     "static async(){}",
    5161             :     "static *async(){}",
    5162             :     "async x(){}",
    5163             :     "async 0(){}",
    5164             :     "async get(){}",
    5165             :     "async set(){}",
    5166             :     "async static(){}",
    5167             :     "async async(){}",
    5168             :     "async(){}",
    5169             :     "*async(){}",
    5170           5 :     nullptr};
    5171             :   // clang-format on
    5172             : 
    5173           5 :   RunParserSyncTest(context_data, class_body_data, kSuccess);
    5174           5 : }
    5175             : 
    5176             : 
    5177       25880 : TEST(ClassPropertyNameNoErrors) {
    5178             :   const char* context_data[][2] = {{"(class {", "() {}});"},
    5179             :                                    {"(class { get ", "() {}});"},
    5180             :                                    {"(class { set ", "(v) {}});"},
    5181             :                                    {"(class { static ", "() {}});"},
    5182             :                                    {"(class { static get ", "() {}});"},
    5183             :                                    {"(class { static set ", "(v) {}});"},
    5184             :                                    {"(class { *", "() {}});"},
    5185             :                                    {"(class { static *", "() {}});"},
    5186             :                                    {"class C {", "() {}}"},
    5187             :                                    {"class C { get ", "() {}}"},
    5188             :                                    {"class C { set ", "(v) {}}"},
    5189             :                                    {"class C { static ", "() {}}"},
    5190             :                                    {"class C { static get ", "() {}}"},
    5191             :                                    {"class C { static set ", "(v) {}}"},
    5192             :                                    {"class C { *", "() {}}"},
    5193             :                                    {"class C { static *", "() {}}"},
    5194           5 :                                    {nullptr, nullptr}};
    5195             :   const char* name_data[] = {
    5196             :       "42",       "42.5",  "42e2",  "42e+2",   "42e-2",  "null",
    5197             :       "false",    "true",  "'str'", "\"str\"", "static", "get",
    5198             :       "set",      "var",   "const", "let",     "this",   "class",
    5199             :       "function", "yield", "if",    "else",    "for",    "while",
    5200           5 :       "do",       "try",   "catch", "finally", nullptr};
    5201             : 
    5202           5 :   RunParserSyncTest(context_data, name_data, kSuccess);
    5203           5 : }
    5204             : 
    5205       25880 : TEST(StaticClassFieldsNoErrors) {
    5206             :   // clang-format off
    5207             :   // Tests proposed class fields syntax.
    5208             :   const char* context_data[][2] = {{"(class {", "});"},
    5209             :                                    {"(class extends Base {", "});"},
    5210             :                                    {"class C {", "}"},
    5211             :                                    {"class C extends Base {", "}"},
    5212           5 :                                    {nullptr, nullptr}};
    5213             :   const char* class_body_data[] = {
    5214             :     // Basic syntax
    5215             :     "static a = 0;",
    5216             :     "static a = 0; b",
    5217             :     "static a = 0; b(){}",
    5218             :     "static a = 0; *b(){}",
    5219             :     "static a = 0; ['b'](){}",
    5220             :     "static a;",
    5221             :     "static a; b;",
    5222             :     "static a; b(){}",
    5223             :     "static a; *b(){}",
    5224             :     "static a; ['b'](){}",
    5225             :     "static ['a'] = 0;",
    5226             :     "static ['a'] = 0; b",
    5227             :     "static ['a'] = 0; b(){}",
    5228             :     "static ['a'] = 0; *b(){}",
    5229             :     "static ['a'] = 0; ['b'](){}",
    5230             :     "static ['a'];",
    5231             :     "static ['a']; b;",
    5232             :     "static ['a']; b(){}",
    5233             :     "static ['a']; *b(){}",
    5234             :     "static ['a']; ['b'](){}",
    5235             : 
    5236             :     "static 0 = 0;",
    5237             :     "static 0;",
    5238             :     "static 'a' = 0;",
    5239             :     "static 'a';",
    5240             : 
    5241             :     "static c = [c] = c",
    5242             : 
    5243             :     // ASI
    5244             :     "static a = 0\n",
    5245             :     "static a = 0\n b",
    5246             :     "static a = 0\n b(){}",
    5247             :     "static a\n",
    5248             :     "static a\n b\n",
    5249             :     "static a\n b(){}",
    5250             :     "static a\n *b(){}",
    5251             :     "static a\n ['b'](){}",
    5252             :     "static ['a'] = 0\n",
    5253             :     "static ['a'] = 0\n b",
    5254             :     "static ['a'] = 0\n b(){}",
    5255             :     "static ['a']\n",
    5256             :     "static ['a']\n b\n",
    5257             :     "static ['a']\n b(){}",
    5258             :     "static ['a']\n *b(){}",
    5259             :     "static ['a']\n ['b'](){}",
    5260             : 
    5261             :     "static a = function t() { arguments; }",
    5262             :     "static a = () => function t() { arguments; }",
    5263             : 
    5264             :     // ASI edge cases
    5265             :     "static a\n get",
    5266             :     "static get\n *a(){}",
    5267             :     "static a\n static",
    5268             : 
    5269             :     // Misc edge cases
    5270             :     "static yield",
    5271             :     "static yield = 0",
    5272             :     "static yield\n a",
    5273             :     "static async;",
    5274             :     "static async = 0;",
    5275             :     "static async",
    5276             :     "static async = 0",
    5277             :     "static async\n a(){}",  // a field named async, and a method named a.
    5278             :     "static async\n a",
    5279             :     "static await;",
    5280             :     "static await = 0;",
    5281             :     "static await\n a",
    5282             :     nullptr
    5283           5 :   };
    5284             :   // clang-format on
    5285             : 
    5286             :   static const ParserFlag always_flags[] = {kAllowHarmonyPublicFields,
    5287             :                                             kAllowHarmonyStaticFields};
    5288             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5289           5 :                     always_flags, arraysize(always_flags));
    5290             : 
    5291             :   // Without the static flag, all of these are errors
    5292             :   static const ParserFlag no_static_flags[] = {kAllowHarmonyPublicFields};
    5293             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5294           5 :                     no_static_flags, arraysize(no_static_flags));
    5295           5 : }
    5296             : 
    5297       25880 : TEST(ClassFieldsNoErrors) {
    5298             :   // clang-format off
    5299             :   // Tests proposed class fields syntax.
    5300             :   const char* context_data[][2] = {{"(class {", "});"},
    5301             :                                    {"(class extends Base {", "});"},
    5302             :                                    {"class C {", "}"},
    5303             :                                    {"class C extends Base {", "}"},
    5304           5 :                                    {nullptr, nullptr}};
    5305             :   const char* class_body_data[] = {
    5306             :     // Basic syntax
    5307             :     "a = 0;",
    5308             :     "a = 0; b",
    5309             :     "a = 0; b(){}",
    5310             :     "a = 0; *b(){}",
    5311             :     "a = 0; ['b'](){}",
    5312             :     "a;",
    5313             :     "a; b;",
    5314             :     "a; b(){}",
    5315             :     "a; *b(){}",
    5316             :     "a; ['b'](){}",
    5317             :     "['a'] = 0;",
    5318             :     "['a'] = 0; b",
    5319             :     "['a'] = 0; b(){}",
    5320             :     "['a'] = 0; *b(){}",
    5321             :     "['a'] = 0; ['b'](){}",
    5322             :     "['a'];",
    5323             :     "['a']; b;",
    5324             :     "['a']; b(){}",
    5325             :     "['a']; *b(){}",
    5326             :     "['a']; ['b'](){}",
    5327             : 
    5328             :     "0 = 0;",
    5329             :     "0;",
    5330             :     "'a' = 0;",
    5331             :     "'a';",
    5332             : 
    5333             :     "c = [c] = c",
    5334             : 
    5335             :     // ASI
    5336             :     "a = 0\n",
    5337             :     "a = 0\n b",
    5338             :     "a = 0\n b(){}",
    5339             :     "a\n",
    5340             :     "a\n b\n",
    5341             :     "a\n b(){}",
    5342             :     "a\n *b(){}",
    5343             :     "a\n ['b'](){}",
    5344             :     "['a'] = 0\n",
    5345             :     "['a'] = 0\n b",
    5346             :     "['a'] = 0\n b(){}",
    5347             :     "['a']\n",
    5348             :     "['a']\n b\n",
    5349             :     "['a']\n b(){}",
    5350             :     "['a']\n *b(){}",
    5351             :     "['a']\n ['b'](){}",
    5352             : 
    5353             :     // ASI edge cases
    5354             :     "a\n get",
    5355             :     "get\n *a(){}",
    5356             :     "a\n static",
    5357             : 
    5358             :     "a = function t() { arguments; }",
    5359             :     "a = () => function() { arguments; }",
    5360             : 
    5361             :     // Misc edge cases
    5362             :     "yield",
    5363             :     "yield = 0",
    5364             :     "yield\n a",
    5365             :     "async;",
    5366             :     "async = 0;",
    5367             :     "async",
    5368             :     "async = 0",
    5369             :     "async\n a(){}",  // a field named async, and a method named a.
    5370             :     "async\n a",
    5371             :     "await;",
    5372             :     "await = 0;",
    5373             :     "await\n a",
    5374             :     nullptr
    5375           5 :   };
    5376             :   // clang-format on
    5377             : 
    5378             :   static const ParserFlag always_flags[] = {kAllowHarmonyPublicFields};
    5379             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5380           5 :                     always_flags, arraysize(always_flags));
    5381             : 
    5382             :   static const ParserFlag static_flags[] = {kAllowHarmonyPublicFields,
    5383             :                                             kAllowHarmonyStaticFields};
    5384             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5385           5 :                     static_flags, arraysize(static_flags));
    5386           5 : }
    5387             : 
    5388       25880 : TEST(PrivateMethodsNoErrors) {
    5389             :   // clang-format off
    5390             :   // Tests proposed class methods syntax.
    5391             :   const char* context_data[][2] = {{"(class {", "});"},
    5392             :                                    {"(class extends Base {", "});"},
    5393             :                                    {"class C {", "}"},
    5394             :                                    {"class C extends Base {", "}"},
    5395           5 :                                    {nullptr, nullptr}};
    5396             :   const char* class_body_data[] = {
    5397             :     // Basic syntax
    5398             :     "#a() { }",
    5399             :     "get #a() { }",
    5400             :     "set #a(foo) { }",
    5401             :     "*#a() { }",
    5402             :     "async #a() { }",
    5403             :     "async *#a() { }",
    5404             : 
    5405             :     "#a() { } #b() {}",
    5406             :     "get #a() { } set #a(foo) {}",
    5407             :     "get #a() { } get #b() {} set #a(foo) {}",
    5408             :     "get #a() { } get #b() {} set #a(foo) {} set #b(foo) {}",
    5409             :     "set #a(foo) { } set #b(foo) {}",
    5410             :     "get #a() { } get #b() {}",
    5411             : 
    5412             :     "#a() { } static a() {}",
    5413             :     "#a() { } a() {}",
    5414             :     "#a() { } a() {} static a() {}",
    5415             :     "get #a() { } get a() {} static get a() {}",
    5416             :     "set #a(foo) { } set a(foo) {} static set a(foo) {}",
    5417             : 
    5418             :     "#a() { } get #b() {}",
    5419             :     "#a() { } async #b() {}",
    5420             :     "#a() { } async *#b() {}",
    5421             : 
    5422             :     // With arguments
    5423             :     "#a(...args) { }",
    5424             :     "#a(a = 1) { }",
    5425             :     "get #a() { }",
    5426             :     "set #a(a = (...args) => {}) { }",
    5427             : 
    5428             :     // Misc edge cases
    5429             :     "#get() {}",
    5430             :     "#set() {}",
    5431             :     "#yield() {}",
    5432             :     "#await() {}",
    5433             :     "#async() {}",
    5434             :     "#static() {}",
    5435             :     "#arguments() {}",
    5436             :     "get #yield() {}",
    5437             :     "get #await() {}",
    5438             :     "get #async() {}",
    5439             :     "get #get() {}",
    5440             :     "get #static() {}",
    5441             :     "get #arguments() {}",
    5442             :     "set #yield(test) {}",
    5443             :     "set #async(test) {}",
    5444             :     "set #await(test) {}",
    5445             :     "set #set(test) {}",
    5446             :     "set #static(test) {}",
    5447             :     "set #arguments(test) {}",
    5448             :     "async #yield() {}",
    5449             :     "async #async() {}",
    5450             :     "async #await() {}",
    5451             :     "async #get() {}",
    5452             :     "async #set() {}",
    5453             :     "async #static() {}",
    5454             :     "async #arguments() {}",
    5455             :     "*#async() {}",
    5456             :     "*#await() {}",
    5457             :     "*#yield() {}",
    5458             :     "*#get() {}",
    5459             :     "*#set() {}",
    5460             :     "*#static() {}",
    5461             :     "*#arguments() {}",
    5462             :     "async *#yield() {}",
    5463             :     "async *#async() {}",
    5464             :     "async *#await() {}",
    5465             :     "async *#get() {}",
    5466             :     "async *#set() {}",
    5467             :     "async *#static() {}",
    5468             :     "async *#arguments() {}",
    5469             :     nullptr
    5470           5 :   };
    5471             :   // clang-format on
    5472             : 
    5473           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5474             : 
    5475             :   static const ParserFlag private_methods[] = {kAllowHarmonyPrivateFields,
    5476             :                                                kAllowHarmonyPrivateMethods};
    5477             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5478           5 :                     private_methods, arraysize(private_methods));
    5479           5 : }
    5480             : 
    5481       25880 : TEST(PrivateMethodsAndFieldsNoErrors) {
    5482             :   // clang-format off
    5483             :   // Tests proposed class methods syntax in combination with fields
    5484             :   const char* context_data[][2] = {{"(class {", "});"},
    5485             :                                    {"(class extends Base {", "});"},
    5486             :                                    {"class C {", "}"},
    5487             :                                    {"class C extends Base {", "}"},
    5488           5 :                                    {nullptr, nullptr}};
    5489             :   const char* class_body_data[] = {
    5490             :     // Basic syntax
    5491             :     "#b;#a() { }",
    5492             :     "#b;get #a() { }",
    5493             :     "#b;set #a(foo) { }",
    5494             :     "#b;*#a() { }",
    5495             :     "#b;async #a() { }",
    5496             :     "#b;async *#a() { }",
    5497             :     "#b = 1;#a() { }",
    5498             :     "#b = 1;get #a() { }",
    5499             :     "#b = 1;set #a(foo) { }",
    5500             :     "#b = 1;*#a() { }",
    5501             :     "#b = 1;async #a() { }",
    5502             :     "#b = 1;async *#a() { }",
    5503             : 
    5504             :     // With public fields
    5505             :     "a;#a() { }",
    5506             :     "a;get #a() { }",
    5507             :     "a;set #a(foo) { }",
    5508             :     "a;*#a() { }",
    5509             :     "a;async #a() { }",
    5510             :     "a;async *#a() { }",
    5511             :     "a = 1;#a() { }",
    5512             :     "a = 1;get #a() { }",
    5513             :     "a = 1;set #a(foo) { }",
    5514             :     "a = 1;*#a() { }",
    5515             :     "a = 1;async #a() { }",
    5516             :     "a = 1;async *#a() { }",
    5517             : 
    5518             :     // ASI
    5519             :     "#a = 0\n #b(){}",
    5520             :     "#a\n *#b(){}",
    5521             :     "#a = 0\n get #b(){}",
    5522             :     "#a\n *#b(){}",
    5523             : 
    5524             :     "b = 0\n #b(){}",
    5525             :     "b\n *#b(){}",
    5526             :     "b = 0\n get #b(){}",
    5527             :     "b\n *#b(){}",
    5528             :     nullptr
    5529           5 :   };
    5530             :   // clang-format on
    5531             : 
    5532           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5533             : 
    5534             :   static const ParserFlag private_methods_and_fields[] = {
    5535             :       kAllowHarmonyPrivateFields, kAllowHarmonyPublicFields,
    5536             :       kAllowHarmonyPrivateMethods};
    5537             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5538             :                     private_methods_and_fields,
    5539           5 :                     arraysize(private_methods_and_fields));
    5540           5 : }
    5541             : 
    5542       25880 : TEST(PrivateMethodsErrors) {
    5543             :   // clang-format off
    5544             :   // Tests proposed class methods syntax in combination with fields
    5545             :   const char* context_data[][2] = {{"(class {", "});"},
    5546             :                                    {"(class extends Base {", "});"},
    5547             :                                    {"class C {", "}"},
    5548             :                                    {"class C extends Base {", "}"},
    5549           5 :                                    {nullptr, nullptr}};
    5550             :   const char* class_body_data[] = {
    5551             :     "#a() : 0",
    5552             :     "#a() =",
    5553             :     "#a() => {}",
    5554             :     "#a => {}",
    5555             :     "*#a() = 0",
    5556             :     "*#a() => 0",
    5557             :     "*#a() => {}",
    5558             :     "get #a()[]",
    5559             :     "yield #a()[]",
    5560             :     "yield #a => {}",
    5561             :     "async #a() = 0",
    5562             :     "async #a => {}",
    5563             :     "#a(arguments) {}",
    5564             :     "set #a(arguments) {}",
    5565             : 
    5566             :     "#['a']() { }",
    5567             :     "get #['a']() { }",
    5568             :     "set #['a'](foo) { }",
    5569             :     "*#['a']() { }",
    5570             :     "async #['a']() { }",
    5571             :     "async *#['a]() { }",
    5572             : 
    5573             :     // TODO(joyee): check duplicate accessors
    5574             : 
    5575             :     "#a\n#",
    5576             :     "#a() c",
    5577             :     "#a() #",
    5578             :     "#a(arg) c",
    5579             :     "#a(arg) #",
    5580             :     "#a(arg) #c",
    5581             :     "#a#",
    5582             :     "#a#b",
    5583             :     "#a#b(){}",
    5584             :     "#[test](){}",
    5585             : 
    5586             :     "async *#constructor() {}",
    5587             :     "*#constructor() {}",
    5588             :     "async #constructor() {}",
    5589             :     "set #constructor(test) {}",
    5590             :     "#constructor() {}",
    5591             :     "get #constructor() {}",
    5592             :     nullptr
    5593           5 :   };
    5594             :   // clang-format on
    5595             : 
    5596           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5597             : 
    5598             :   static const ParserFlag private_methods[] = {kAllowHarmonyPrivateFields,
    5599             :                                                kAllowHarmonyPrivateMethods};
    5600             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5601           5 :                     private_methods, arraysize(private_methods));
    5602           5 : }
    5603             : 
    5604             : // Test that private members do not parse outside class bodies
    5605       25880 : TEST(PrivateMembersInNonClassNoErrors) {
    5606             :   // clang-format off
    5607             :   const char* context_data[][2] = {{"", ""},
    5608             :                                    {"({", "})"},
    5609             :                                    {"'use strict'; ({", "});"},
    5610             :                                    {"function() {", "}"},
    5611             :                                    {"() => {", "}"},
    5612             :                                    {"class C { test() {", "} }"},
    5613             :                                    {"const {", "} = {}"},
    5614             :                                    {"({", "} = {})"},
    5615           5 :                                    {nullptr, nullptr}};
    5616             :   const char* class_body_data[] = {
    5617             :     "#a = 1",
    5618             :     "#a = () => {}",
    5619             :     "#a",
    5620             :     "#a() { }",
    5621             :     "get #a() { }",
    5622             :     "set #a(foo) { }",
    5623             :     "*#a() { }",
    5624             :     "async #a() { }",
    5625             :     "async *#a() { }",
    5626             :     nullptr
    5627           5 :   };
    5628             :   // clang-format on
    5629             : 
    5630           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5631             : 
    5632             :   static const ParserFlag private_methods[] = {kAllowHarmonyPrivateFields,
    5633             :                                                kAllowHarmonyPrivateMethods};
    5634             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5635           5 :                     private_methods, arraysize(private_methods));
    5636           5 : }
    5637             : 
    5638       25880 : TEST(PrivateClassFieldsNoErrors) {
    5639             :   // clang-format off
    5640             :   // Tests proposed class fields syntax.
    5641             :   const char* context_data[][2] = {{"(class {", "});"},
    5642             :                                    {"(class extends Base {", "});"},
    5643             :                                    {"class C {", "}"},
    5644             :                                    {"class C extends Base {", "}"},
    5645           5 :                                    {nullptr, nullptr}};
    5646             :   const char* class_body_data[] = {
    5647             :     // Basic syntax
    5648             :     "#a = 0;",
    5649             :     "#a = 0; #b",
    5650             :     "#a = 0; b",
    5651             :     "#a = 0; b(){}",
    5652             :     "#a = 0; *b(){}",
    5653             :     "#a = 0; ['b'](){}",
    5654             :     "#a;",
    5655             :     "#a; #b;",
    5656             :     "#a; b;",
    5657             :     "#a; b(){}",
    5658             :     "#a; *b(){}",
    5659             :     "#a; ['b'](){}",
    5660             : 
    5661             :     // ASI
    5662             :     "#a = 0\n",
    5663             :     "#a = 0\n #b",
    5664             :     "#a = 0\n b",
    5665             :     "#a = 0\n b(){}",
    5666             :     "#a\n",
    5667             :     "#a\n #b\n",
    5668             :     "#a\n b\n",
    5669             :     "#a\n b(){}",
    5670             :     "#a\n *b(){}",
    5671             :     "#a\n ['b'](){}",
    5672             : 
    5673             :     // ASI edge cases
    5674             :     "#a\n get",
    5675             :     "#get\n *a(){}",
    5676             :     "#a\n static",
    5677             : 
    5678             :     "#a = function t() { arguments; }",
    5679             :     "#a = () => function() { arguments; }",
    5680             : 
    5681             :     // Misc edge cases
    5682             :     "#yield",
    5683             :     "#yield = 0",
    5684             :     "#yield\n a",
    5685             :     "#async;",
    5686             :     "#async = 0;",
    5687             :     "#async",
    5688             :     "#async = 0",
    5689             :     "#async\n a(){}",  // a field named async, and a method named a.
    5690             :     "#async\n a",
    5691             :     "#await;",
    5692             :     "#await = 0;",
    5693             :     "#await\n a",
    5694             :     nullptr
    5695           5 :   };
    5696             :   // clang-format on
    5697             : 
    5698           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5699             : 
    5700             :   static const ParserFlag private_fields[] = {kAllowHarmonyPrivateFields};
    5701             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5702           5 :                     private_fields, arraysize(private_fields));
    5703           5 : }
    5704             : 
    5705       25880 : TEST(StaticClassFieldsErrors) {
    5706             :   // clang-format off
    5707             :   // Tests proposed class fields syntax.
    5708             :   const char* context_data[][2] = {{"(class {", "});"},
    5709             :                                    {"(class extends Base {", "});"},
    5710             :                                    {"class C {", "}"},
    5711             :                                    {"class C extends Base {", "}"},
    5712           5 :                                    {nullptr, nullptr}};
    5713             :   const char* class_body_data[] = {
    5714             :     "static a : 0",
    5715             :     "static a =",
    5716             :     "static constructor",
    5717             :     "static prototype",
    5718             :     "static *a = 0",
    5719             :     "static *a",
    5720             :     "static get a",
    5721             :     "static get\n a",
    5722             :     "static yield a",
    5723             :     "static async a = 0",
    5724             :     "static async a",
    5725             : 
    5726             :     "static a = arguments",
    5727             :     "static a = () => arguments",
    5728             :     "static a = () => { arguments }",
    5729             :     "static a = arguments[0]",
    5730             :     "static a = delete arguments[0]",
    5731             :     "static a = f(arguments)",
    5732             :     "static a = () => () => arguments",
    5733             : 
    5734             :     // ASI requires a linebreak
    5735             :     "static a b",
    5736             :     "static a = 0 b",
    5737             : 
    5738             :     "static c = [1] = [c]",
    5739             : 
    5740             :     // ASI requires that the next token is not part of any legal production
    5741             :     "static a = 0\n *b(){}",
    5742             :     "static a = 0\n ['b'](){}",
    5743             :     nullptr
    5744           5 :   };
    5745             :   // clang-format on
    5746             : 
    5747             :   static const ParserFlag no_static_flags[] = {kAllowHarmonyPublicFields};
    5748             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5749           5 :                     no_static_flags, arraysize(no_static_flags));
    5750             : 
    5751             :   static const ParserFlag always_flags[] = {kAllowHarmonyPublicFields,
    5752             :                                             kAllowHarmonyStaticFields};
    5753             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5754           5 :                     always_flags, arraysize(always_flags));
    5755           5 : }
    5756             : 
    5757       25880 : TEST(ClassFieldsErrors) {
    5758             :   // clang-format off
    5759             :   // Tests proposed class fields syntax.
    5760             :   const char* context_data[][2] = {{"(class {", "});"},
    5761             :                                    {"(class extends Base {", "});"},
    5762             :                                    {"class C {", "}"},
    5763             :                                    {"class C extends Base {", "}"},
    5764           5 :                                    {nullptr, nullptr}};
    5765             :   const char* class_body_data[] = {
    5766             :     "a : 0",
    5767             :     "a =",
    5768             :     "constructor",
    5769             :     "*a = 0",
    5770             :     "*a",
    5771             :     "get a",
    5772             :     "yield a",
    5773             :     "async a = 0",
    5774             :     "async a",
    5775             : 
    5776             :     "a = arguments",
    5777             :     "a = () => arguments",
    5778             :     "a = () => { arguments }",
    5779             :     "a = arguments[0]",
    5780             :     "a = delete arguments[0]",
    5781             :     "a = f(arguments)",
    5782             :     "a = () => () => arguments",
    5783             : 
    5784             :     // ASI requires a linebreak
    5785             :     "a b",
    5786             :     "a = 0 b",
    5787             : 
    5788             :     "c = [1] = [c]",
    5789             : 
    5790             :     // ASI requires that the next token is not part of any legal production
    5791             :     "a = 0\n *b(){}",
    5792             :     "a = 0\n ['b'](){}",
    5793             :     "get\n a",
    5794             :     nullptr
    5795           5 :   };
    5796             :   // clang-format on
    5797             : 
    5798             :   static const ParserFlag always_flags[] = {kAllowHarmonyPublicFields};
    5799             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5800           5 :                     always_flags, arraysize(always_flags));
    5801             : 
    5802             :   static const ParserFlag static_flags[] = {kAllowHarmonyPublicFields,
    5803             :                                             kAllowHarmonyStaticFields};
    5804             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5805           5 :                     static_flags, arraysize(static_flags));
    5806           5 : }
    5807             : 
    5808       25880 : TEST(PrivateClassFieldsErrors) {
    5809             :   // clang-format off
    5810             :   // Tests proposed class fields syntax.
    5811             :   const char* context_data[][2] = {{"(class {", "});"},
    5812             :                                    {"(class extends Base {", "});"},
    5813             :                                    {"class C {", "}"},
    5814             :                                    {"class C extends Base {", "}"},
    5815           5 :                                    {nullptr, nullptr}};
    5816             :   const char* class_body_data[] = {
    5817             :     "#a : 0",
    5818             :     "#a =",
    5819             :     "#*a = 0",
    5820             :     "#*a",
    5821             :     "#get a",
    5822             :     "#yield a",
    5823             :     "#async a = 0",
    5824             :     "#async a",
    5825             : 
    5826             :     "#a; #a",
    5827             :     "#a = 1; #a",
    5828             :     "#a; #a = 1;",
    5829             : 
    5830             :     "#constructor",
    5831             :     "#constructor = function() {}",
    5832             : 
    5833             :     "# a = 0",
    5834             :     "#a() { }",
    5835             :     "get #a() { }",
    5836             :     "#get a() { }",
    5837             :     "set #a() { }",
    5838             :     "#set a() { }",
    5839             :     "*#a() { }",
    5840             :     "#*a() { }",
    5841             :     "async #a() { }",
    5842             :     "async *#a() { }",
    5843             :     "async #*a() { }",
    5844             : 
    5845             :     "#0 = 0;",
    5846             :     "#0;",
    5847             :     "#'a' = 0;",
    5848             :     "#'a';",
    5849             : 
    5850             :     "#['a']",
    5851             :     "#['a'] = 1",
    5852             :     "#[a]",
    5853             :     "#[a] = 1",
    5854             : 
    5855             :     "#a = arguments",
    5856             :     "#a = () => arguments",
    5857             :     "#a = () => { arguments }",
    5858             :     "#a = arguments[0]",
    5859             :     "#a = delete arguments[0]",
    5860             :     "#a = f(arguments)",
    5861             :     "#a = () => () => arguments",
    5862             : 
    5863             :     "foo() { delete this.#a }",
    5864             :     "foo() { delete this.x.#a }",
    5865             :     "foo() { delete this.x().#a }",
    5866             : 
    5867             :     "foo() { delete f.#a }",
    5868             :     "foo() { delete f.x.#a }",
    5869             :     "foo() { delete f.x().#a }",
    5870             : 
    5871             :     // ASI requires a linebreak
    5872             :     "#a b",
    5873             :     "#a = 0 b",
    5874             : 
    5875             :     // ASI requires that the next token is not part of any legal production
    5876             :     "#a = 0\n *b(){}",
    5877             :     "#a = 0\n ['b'](){}",
    5878             :     nullptr
    5879           5 :   };
    5880             :   // clang-format on
    5881             : 
    5882           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5883             : 
    5884             :   static const ParserFlag private_fields[] = {kAllowHarmonyPrivateFields};
    5885             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5886           5 :                     private_fields, arraysize(private_fields));
    5887           5 : }
    5888             : 
    5889       25880 : TEST(PrivateStaticClassFieldsNoErrors) {
    5890             :   // clang-format off
    5891             :   // Tests proposed class fields syntax.
    5892             :   const char* context_data[][2] = {{"(class {", "});"},
    5893             :                                    {"(class extends Base {", "});"},
    5894             :                                    {"class C {", "}"},
    5895             :                                    {"class C extends Base {", "}"},
    5896           5 :                                    {nullptr, nullptr}};
    5897             :   const char* class_body_data[] = {
    5898             :     // Basic syntax
    5899             :     "static #a = 0;",
    5900             :     "static #a = 0; b",
    5901             :     "static #a = 0; #b",
    5902             :     "static #a = 0; b(){}",
    5903             :     "static #a = 0; *b(){}",
    5904             :     "static #a = 0; ['b'](){}",
    5905             :     "static #a;",
    5906             :     "static #a; b;",
    5907             :     "static #a; b(){}",
    5908             :     "static #a; *b(){}",
    5909             :     "static #a; ['b'](){}",
    5910             : 
    5911             :     "#prototype",
    5912             :     "#prototype = function() {}",
    5913             : 
    5914             :     // ASI
    5915             :     "static #a = 0\n",
    5916             :     "static #a = 0\n b",
    5917             :     "static #a = 0\n #b",
    5918             :     "static #a = 0\n b(){}",
    5919             :     "static #a\n",
    5920             :     "static #a\n b\n",
    5921             :     "static #a\n #b\n",
    5922             :     "static #a\n b(){}",
    5923             :     "static #a\n *b(){}",
    5924             :     "static #a\n ['b'](){}",
    5925             : 
    5926             :     "static #a = function t() { arguments; }",
    5927             :     "static #a = () => function t() { arguments; }",
    5928             : 
    5929             :     // ASI edge cases
    5930             :     "static #a\n get",
    5931             :     "static #get\n *a(){}",
    5932             :     "static #a\n static",
    5933             : 
    5934             :     // Misc edge cases
    5935             :     "static #yield",
    5936             :     "static #yield = 0",
    5937             :     "static #yield\n a",
    5938             :     "static #async;",
    5939             :     "static #async = 0;",
    5940             :     "static #async",
    5941             :     "static #async = 0",
    5942             :     "static #async\n a(){}",  // a field named async, and a method named a.
    5943             :     "static #async\n a",
    5944             :     "static #await;",
    5945             :     "static #await = 0;",
    5946             :     "static #await\n a",
    5947             :     nullptr
    5948           5 :   };
    5949             :   // clang-format on
    5950             : 
    5951           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    5952             : 
    5953             :   static const ParserFlag public_static_fields[] = {kAllowHarmonyPublicFields,
    5954             :                                                     kAllowHarmonyStaticFields};
    5955             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    5956           5 :                     public_static_fields, arraysize(public_static_fields));
    5957             : 
    5958             :   static const ParserFlag private_static_fields[] = {
    5959             :       kAllowHarmonyPublicFields, kAllowHarmonyStaticFields,
    5960             :       kAllowHarmonyPrivateFields};
    5961             :   RunParserSyncTest(context_data, class_body_data, kSuccess, nullptr, 0,
    5962           5 :                     private_static_fields, arraysize(private_static_fields));
    5963           5 : }
    5964             : 
    5965       25880 : TEST(PrivateStaticClassFieldsErrors) {
    5966             :   // clang-format off
    5967             :   // Tests proposed class fields syntax.
    5968             :   const char* context_data[][2] = {{"(class {", "});"},
    5969             :                                    {"(class extends Base {", "});"},
    5970             :                                    {"class C {", "}"},
    5971             :                                    {"class C extends Base {", "}"},
    5972           5 :                                    {nullptr, nullptr}};
    5973             :   const char* class_body_data[] = {
    5974             :     // Basic syntax
    5975             :     "static #['a'] = 0;",
    5976             :     "static #['a'] = 0; b",
    5977             :     "static #['a'] = 0; #b",
    5978             :     "static #['a'] = 0; b(){}",
    5979             :     "static #['a'] = 0; *b(){}",
    5980             :     "static #['a'] = 0; ['b'](){}",
    5981             :     "static #['a'];",
    5982             :     "static #['a']; b;",
    5983             :     "static #['a']; #b;",
    5984             :     "static #['a']; b(){}",
    5985             :     "static #['a']; *b(){}",
    5986             :     "static #['a']; ['b'](){}",
    5987             : 
    5988             :     "static #0 = 0;",
    5989             :     "static #0;",
    5990             :     "static #'a' = 0;",
    5991             :     "static #'a';",
    5992             : 
    5993             :     "static # a = 0",
    5994             :     "static #get a() { }",
    5995             :     "static #set a() { }",
    5996             :     "static #*a() { }",
    5997             :     "static async #*a() { }",
    5998             : 
    5999             :     "#a = arguments",
    6000             :     "#a = () => arguments",
    6001             :     "#a = () => { arguments }",
    6002             :     "#a = arguments[0]",
    6003             :     "#a = delete arguments[0]",
    6004             :     "#a = f(arguments)",
    6005             :     "#a = () => () => arguments",
    6006             : 
    6007             :     "#a; static #a",
    6008             :     "static #a; #a",
    6009             : 
    6010             :     // TODO(joyee): support static private methods
    6011             :     "static #a() { }",
    6012             :     "static get #a() { }",
    6013             :     "static set #a() { }",
    6014             :     "static *#a() { }",
    6015             :     "static async #a() { }",
    6016             :     "static async *#a() { }",
    6017             : 
    6018             :     // ASI
    6019             :     "static #['a'] = 0\n",
    6020             :     "static #['a'] = 0\n b",
    6021             :     "static #['a'] = 0\n #b",
    6022             :     "static #['a'] = 0\n b(){}",
    6023             :     "static #['a']\n",
    6024             :     "static #['a']\n b\n",
    6025             :     "static #['a']\n #b\n",
    6026             :     "static #['a']\n b(){}",
    6027             :     "static #['a']\n *b(){}",
    6028             :     "static #['a']\n ['b'](){}",
    6029             : 
    6030             :     // ASI requires a linebreak
    6031             :     "static #a b",
    6032             :     "static #a = 0 b",
    6033             : 
    6034             :     // ASI requires that the next token is not part of any legal production
    6035             :     "static #a = 0\n *b(){}",
    6036             :     "static #a = 0\n ['b'](){}",
    6037             : 
    6038             :     "static #a : 0",
    6039             :     "static #a =",
    6040             :     "static #*a = 0",
    6041             :     "static #*a",
    6042             :     "static #get a",
    6043             :     "static #yield a",
    6044             :     "static #async a = 0",
    6045             :     "static #async a",
    6046             :     "static # a = 0",
    6047             : 
    6048             :     "#constructor",
    6049             :     "#constructor = function() {}",
    6050             : 
    6051             :     "foo() { delete this.#a }",
    6052             :     "foo() { delete this.x.#a }",
    6053             :     "foo() { delete this.x().#a }",
    6054             : 
    6055             :     "foo() { delete f.#a }",
    6056             :     "foo() { delete f.x.#a }",
    6057             :     "foo() { delete f.x().#a }",
    6058             :     nullptr
    6059           5 :   };
    6060             :   // clang-format on
    6061             : 
    6062           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6063             : 
    6064             :   static const ParserFlag public_static_fields[] = {kAllowHarmonyPublicFields,
    6065             :                                                     kAllowHarmonyStaticFields};
    6066             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    6067           5 :                     public_static_fields, arraysize(public_static_fields));
    6068             : 
    6069             :   static const ParserFlag private_static_fields[] = {
    6070             :       kAllowHarmonyPublicFields, kAllowHarmonyStaticFields,
    6071             :       kAllowHarmonyPrivateFields};
    6072             :   RunParserSyncTest(context_data, class_body_data, kError, nullptr, 0,
    6073           5 :                     private_static_fields, arraysize(private_static_fields));
    6074           5 : }
    6075             : 
    6076       25880 : TEST(PrivateNameNoErrors) {
    6077             :   // clang-format off
    6078             :   const char* context_data[][2] = {
    6079             :       {"", ""},
    6080             :       {"\"use strict\";", ""},
    6081             :       {nullptr, nullptr}
    6082           5 :   };
    6083             : 
    6084             :   const char* statement_data[] = {
    6085             :     "this.#a",
    6086             :     "this.#a()",
    6087             :     "this.#b.#a",
    6088             :     "this.#b.#a()",
    6089             : 
    6090             :     "foo.#a",
    6091             :     "foo.#a()",
    6092             :     "foo.#b.#a",
    6093             :     "foo.#b.#a()",
    6094             : 
    6095             :     "foo().#a",
    6096             :     "foo().b.#a",
    6097             :     "foo().b().#a",
    6098             :     "foo().b().#a()",
    6099             :     "foo().b().#a.bar",
    6100             :     "foo().b().#a.bar()",
    6101             : 
    6102             :     "foo(this.#a)",
    6103             :     "foo(bar().#a)",
    6104             : 
    6105             :     "new foo.#a",
    6106             :     "new foo.#b.#a",
    6107             :     "new foo.#b.#a()",
    6108             : 
    6109             :     "foo.#if;",
    6110             :     "foo.#yield;",
    6111             :     "foo.#super;",
    6112             :     "foo.#interface;",
    6113             :     "foo.#eval;",
    6114             :     "foo.#arguments;",
    6115             : 
    6116             :     nullptr
    6117           5 :   };
    6118             : 
    6119             :   // clang-format on
    6120           5 :   RunParserSyncTest(context_data, statement_data, kError);
    6121             : 
    6122             :   static const ParserFlag private_fields[] = {kAllowHarmonyPrivateFields};
    6123             :   RunParserSyncTest(context_data, statement_data, kSuccess, nullptr, 0,
    6124           5 :                     private_fields, arraysize(private_fields));
    6125           5 : }
    6126             : 
    6127       25880 : TEST(PrivateNameErrors) {
    6128             :   // clang-format off
    6129             :   const char* context_data[][2] = {
    6130             :       {"", ""},
    6131             :       {"\"use strict\";", ""},
    6132             :       {nullptr, nullptr}
    6133           5 :   };
    6134             : 
    6135             :   const char* statement_data[] = {
    6136             :     "#foo",
    6137             :     "#foo = 1",
    6138             : 
    6139             :     "# a;",
    6140             :     "#\n a;",
    6141             :     "a, # b",
    6142             :     "a, #, b;",
    6143             : 
    6144             :     "foo.#[a];",
    6145             :     "foo.#['a'];",
    6146             : 
    6147             :     "foo()#a",
    6148             :     "foo()#[a]",
    6149             :     "foo()#['a']",
    6150             : 
    6151             :     "super.#a;",
    6152             :     "super.#a = 1;",
    6153             :     "super.#['a']",
    6154             :     "super.#[a]",
    6155             : 
    6156             :     "new.#a",
    6157             :     "new.#[a]",
    6158             : 
    6159             :     "foo.#{;",
    6160             :     "foo.#};",
    6161             :     "foo.#=;",
    6162             :     "foo.#888;",
    6163             :     "foo.#-;",
    6164             :     "foo.#--;",
    6165             :     nullptr
    6166           5 :   };
    6167             : 
    6168             :   // clang-format on
    6169           5 :   RunParserSyncTest(context_data, statement_data, kError);
    6170             : 
    6171             :   static const ParserFlag private_fields[] = {kAllowHarmonyPrivateFields};
    6172             :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0,
    6173           5 :                     private_fields, arraysize(private_fields));
    6174           5 : }
    6175             : 
    6176       25880 : TEST(ClassExpressionErrors) {
    6177             :   const char* context_data[][2] = {
    6178           5 :       {"(", ");"}, {"var C = ", ";"}, {"bar, ", ";"}, {nullptr, nullptr}};
    6179             :   const char* class_data[] = {
    6180             :       "class",
    6181             :       "class name",
    6182             :       "class name extends",
    6183             :       "class extends",
    6184             :       "class {",
    6185             :       "class { m }",
    6186             :       "class { m; n }",
    6187             :       "class { m: 1 }",
    6188             :       "class { m(); n() }",
    6189             :       "class { get m }",
    6190             :       "class { get m() }",
    6191             :       "class { get m() { }",
    6192             :       "class { set m() {} }",      // Missing required parameter.
    6193             :       "class { m() {}, n() {} }",  // No commas allowed.
    6194           5 :       nullptr};
    6195             : 
    6196           5 :   RunParserSyncTest(context_data, class_data, kError);
    6197           5 : }
    6198             : 
    6199             : 
    6200       25880 : TEST(ClassDeclarationErrors) {
    6201             :   const char* context_data[][2] = {
    6202           5 :       {"", ""}, {"{", "}"}, {"if (true) {", "}"}, {nullptr, nullptr}};
    6203             :   const char* class_data[] = {
    6204             :       "class",
    6205             :       "class name",
    6206             :       "class name extends",
    6207             :       "class extends",
    6208             :       "class name {",
    6209             :       "class name { m }",
    6210             :       "class name { m; n }",
    6211             :       "class name { m: 1 }",
    6212             :       "class name { m(); n() }",
    6213             :       "class name { get x }",
    6214             :       "class name { get x() }",
    6215             :       "class name { set x() {) }",  // missing required param
    6216             :       "class {}",                   // Name is required for declaration
    6217             :       "class extends base {}",
    6218             :       "class name { *",
    6219             :       "class name { * }",
    6220             :       "class name { *; }",
    6221             :       "class name { *get x() {} }",
    6222             :       "class name { *set x(_) {} }",
    6223             :       "class name { *static m() {} }",
    6224           5 :       nullptr};
    6225             : 
    6226           5 :   RunParserSyncTest(context_data, class_data, kError);
    6227           5 : }
    6228             : 
    6229       25880 : TEST(ClassAsyncErrors) {
    6230             :   // clang-format off
    6231             :   const char* context_data[][2] = {{"(class {", "});"},
    6232             :                                    {"(class extends Base {", "});"},
    6233             :                                    {"class C {", "}"},
    6234             :                                    {"class C extends Base {", "}"},
    6235           5 :                                    {nullptr, nullptr}};
    6236             :   const char* async_data[] = {
    6237             :     "*async x(){}",
    6238             :     "async *(){}",
    6239             :     "async get x(){}",
    6240             :     "async set x(y){}",
    6241             :     "async x : 0",
    6242             :     "async : 0",
    6243             : 
    6244             :     "async static x(){}",
    6245             : 
    6246             :     "static *async x(){}",
    6247             :     "static async *(){}",
    6248             :     "static async get x(){}",
    6249             :     "static async set x(y){}",
    6250             :     "static async x : 0",
    6251             :     "static async : 0",
    6252             :     nullptr
    6253           5 :   };
    6254             :   // clang-format on
    6255             : 
    6256           5 :   RunParserSyncTest(context_data, async_data, kError);
    6257           5 : }
    6258             : 
    6259       25880 : TEST(ClassNameErrors) {
    6260             :   const char* context_data[][2] = {{"class ", "{}"},
    6261             :                                    {"(class ", "{});"},
    6262             :                                    {"'use strict'; class ", "{}"},
    6263             :                                    {"'use strict'; (class ", "{});"},
    6264           5 :                                    {nullptr, nullptr}};
    6265             :   const char* class_name[] = {"arguments", "eval",    "implements", "interface",
    6266             :                               "let",       "package", "private",    "protected",
    6267             :                               "public",    "static",  "var",        "yield",
    6268           5 :                               nullptr};
    6269             : 
    6270           5 :   RunParserSyncTest(context_data, class_name, kError);
    6271           5 : }
    6272             : 
    6273             : 
    6274       25880 : TEST(ClassGetterParamNameErrors) {
    6275             :   const char* context_data[][2] = {
    6276             :       {"class C { get name(", ") {} }"},
    6277             :       {"(class { get name(", ") {} });"},
    6278             :       {"'use strict'; class C { get name(", ") {} }"},
    6279             :       {"'use strict'; (class { get name(", ") {} })"},
    6280           5 :       {nullptr, nullptr}};
    6281             : 
    6282             :   const char* class_name[] = {"arguments", "eval",    "implements", "interface",
    6283             :                               "let",       "package", "private",    "protected",
    6284             :                               "public",    "static",  "var",        "yield",
    6285           5 :                               nullptr};
    6286             : 
    6287           5 :   RunParserSyncTest(context_data, class_name, kError);
    6288           5 : }
    6289             : 
    6290             : 
    6291       25880 : TEST(ClassStaticPrototypeErrors) {
    6292             :   const char* context_data[][2] = {
    6293           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6294             : 
    6295             :   const char* class_body_data[] = {"static prototype() {}",
    6296             :                                    "static get prototype() {}",
    6297             :                                    "static set prototype(_) {}",
    6298             :                                    "static *prototype() {}",
    6299             :                                    "static 'prototype'() {}",
    6300             :                                    "static *'prototype'() {}",
    6301             :                                    "static prot\\u006ftype() {}",
    6302             :                                    "static 'prot\\u006ftype'() {}",
    6303             :                                    "static get 'prot\\u006ftype'() {}",
    6304             :                                    "static set 'prot\\u006ftype'(_) {}",
    6305             :                                    "static *'prot\\u006ftype'() {}",
    6306           5 :                                    nullptr};
    6307             : 
    6308           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6309           5 : }
    6310             : 
    6311             : 
    6312       25880 : TEST(ClassSpecialConstructorErrors) {
    6313             :   const char* context_data[][2] = {
    6314           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6315             : 
    6316             :   const char* class_body_data[] = {"get constructor() {}",
    6317             :                                    "get constructor(_) {}",
    6318             :                                    "*constructor() {}",
    6319             :                                    "get 'constructor'() {}",
    6320             :                                    "*'constructor'() {}",
    6321             :                                    "get c\\u006fnstructor() {}",
    6322             :                                    "*c\\u006fnstructor() {}",
    6323             :                                    "get 'c\\u006fnstructor'() {}",
    6324             :                                    "get 'c\\u006fnstructor'(_) {}",
    6325             :                                    "*'c\\u006fnstructor'() {}",
    6326           5 :                                    nullptr};
    6327             : 
    6328           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6329           5 : }
    6330             : 
    6331             : 
    6332       25880 : TEST(ClassConstructorNoErrors) {
    6333             :   const char* context_data[][2] = {
    6334           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6335             : 
    6336             :   const char* class_body_data[] = {"constructor() {}",
    6337             :                                    "static constructor() {}",
    6338             :                                    "static get constructor() {}",
    6339             :                                    "static set constructor(_) {}",
    6340             :                                    "static *constructor() {}",
    6341           5 :                                    nullptr};
    6342             : 
    6343           5 :   RunParserSyncTest(context_data, class_body_data, kSuccess);
    6344           5 : }
    6345             : 
    6346             : 
    6347       25880 : TEST(ClassMultipleConstructorErrors) {
    6348             :   const char* context_data[][2] = {
    6349           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6350             : 
    6351             :   const char* class_body_data[] = {"constructor() {}; constructor() {}",
    6352           5 :                                    nullptr};
    6353             : 
    6354           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6355           5 : }
    6356             : 
    6357             : 
    6358       25880 : TEST(ClassMultiplePropertyNamesNoErrors) {
    6359             :   const char* context_data[][2] = {
    6360           5 :       {"class C {", "}"}, {"(class {", "});"}, {nullptr, nullptr}};
    6361             : 
    6362             :   const char* class_body_data[] = {
    6363             :       "constructor() {}; static constructor() {}",
    6364             :       "m() {}; static m() {}",
    6365             :       "m() {}; m() {}",
    6366             :       "static m() {}; static m() {}",
    6367             :       "get m() {}; set m(_) {}; get m() {}; set m(_) {};",
    6368           5 :       nullptr};
    6369             : 
    6370           5 :   RunParserSyncTest(context_data, class_body_data, kSuccess);
    6371           5 : }
    6372             : 
    6373             : 
    6374       25880 : TEST(ClassesAreStrictErrors) {
    6375           5 :   const char* context_data[][2] = {{"", ""}, {"(", ");"}, {nullptr, nullptr}};
    6376             : 
    6377             :   const char* class_body_data[] = {
    6378             :       "class C { method() { with ({}) {} } }",
    6379             :       "class C extends function() { with ({}) {} } {}",
    6380           5 :       "class C { *method() { with ({}) {} } }", nullptr};
    6381             : 
    6382           5 :   RunParserSyncTest(context_data, class_body_data, kError);
    6383           5 : }
    6384             : 
    6385             : 
    6386       25880 : TEST(ObjectLiteralPropertyShorthandKeywordsError) {
    6387             :   const char* context_data[][2] = {
    6388           5 :       {"({", "});"}, {"'use strict'; ({", "});"}, {nullptr, nullptr}};
    6389             : 
    6390             :   const char* name_data[] = {
    6391             :       "break",    "case",    "catch",  "class",      "const", "continue",
    6392             :       "debugger", "default", "delete", "do",         "else",  "enum",
    6393             :       "export",   "extends", "false",  "finally",    "for",   "function",
    6394             :       "if",       "import",  "in",     "instanceof", "new",   "null",
    6395             :       "return",   "super",   "switch", "this",       "throw", "true",
    6396             :       "try",      "typeof",  "var",    "void",       "while", "with",
    6397           5 :       nullptr};
    6398             : 
    6399           5 :   RunParserSyncTest(context_data, name_data, kError);
    6400           5 : }
    6401             : 
    6402             : 
    6403       25880 : TEST(ObjectLiteralPropertyShorthandStrictKeywords) {
    6404           5 :   const char* context_data[][2] = {{"({", "});"}, {nullptr, nullptr}};
    6405             : 
    6406             :   const char* name_data[] = {"implements", "interface", "let",    "package",
    6407             :                              "private",    "protected", "public", "static",
    6408           5 :                              "yield",      nullptr};
    6409             : 
    6410           5 :   RunParserSyncTest(context_data, name_data, kSuccess);
    6411             : 
    6412             :   const char* context_strict_data[][2] = {{"'use strict'; ({", "});"},
    6413           5 :                                           {nullptr, nullptr}};
    6414           5 :   RunParserSyncTest(context_strict_data, name_data, kError);
    6415           5 : }
    6416             : 
    6417             : 
    6418       25880 : TEST(ObjectLiteralPropertyShorthandError) {
    6419             :   const char* context_data[][2] = {
    6420           5 :       {"({", "});"}, {"'use strict'; ({", "});"}, {nullptr, nullptr}};
    6421             : 
    6422             :   const char* name_data[] = {"1",   "1.2", "0",     "0.1", "1.0",
    6423           5 :                              "1e1", "0x1", "\"s\"", "'s'", nullptr};
    6424             : 
    6425           5 :   RunParserSyncTest(context_data, name_data, kError);
    6426           5 : }
    6427             : 
    6428             : 
    6429       25880 : TEST(ObjectLiteralPropertyShorthandYieldInGeneratorError) {
    6430           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    6431             : 
    6432           5 :   const char* name_data[] = {"function* g() { ({yield}); }", nullptr};
    6433             : 
    6434           5 :   RunParserSyncTest(context_data, name_data, kError);
    6435           5 : }
    6436             : 
    6437             : 
    6438       25880 : TEST(ConstParsingInForIn) {
    6439             :   const char* context_data[][2] = {{"'use strict';", ""},
    6440             :                                    {"function foo(){ 'use strict';", "}"},
    6441           5 :                                    {nullptr, nullptr}};
    6442             : 
    6443             :   const char* data[] = {
    6444             :       "for(const x = 1; ; ) {}", "for(const x = 1, y = 2;;){}",
    6445           5 :       "for(const x in [1,2,3]) {}", "for(const x of [1,2,3]) {}", nullptr};
    6446           5 :   RunParserSyncTest(context_data, data, kSuccess, nullptr, 0, nullptr, 0);
    6447           5 : }
    6448             : 
    6449             : 
    6450       25880 : TEST(StatementParsingInForIn) {
    6451             :   const char* context_data[][2] = {{"", ""},
    6452             :                                    {"'use strict';", ""},
    6453             :                                    {"function foo(){ 'use strict';", "}"},
    6454           5 :                                    {nullptr, nullptr}};
    6455             : 
    6456             :   const char* data[] = {"for(x in {}, {}) {}", "for(var x in {}, {}) {}",
    6457             :                         "for(let x in {}, {}) {}", "for(const x in {}, {}) {}",
    6458           5 :                         nullptr};
    6459             : 
    6460           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6461           5 : }
    6462             : 
    6463             : 
    6464       25880 : TEST(ConstParsingInForInError) {
    6465             :   const char* context_data[][2] = {{"'use strict';", ""},
    6466             :                                    {"function foo(){ 'use strict';", "}"},
    6467           5 :                                    {nullptr, nullptr}};
    6468             : 
    6469             :   const char* data[] = {
    6470             :       "for(const x,y = 1; ; ) {}",         "for(const x = 4 in [1,2,3]) {}",
    6471             :       "for(const x = 4, y in [1,2,3]) {}", "for(const x = 4 of [1,2,3]) {}",
    6472             :       "for(const x = 4, y of [1,2,3]) {}", "for(const x = 1, y = 2 in []) {}",
    6473             :       "for(const x,y in []) {}",           "for(const x = 1, y = 2 of []) {}",
    6474           5 :       "for(const x,y of []) {}",           nullptr};
    6475           5 :   RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0);
    6476           5 : }
    6477             : 
    6478       25880 : TEST(InitializedDeclarationsInForInOf) {
    6479             :   // https://tc39.github.io/ecma262/#sec-initializers-in-forin-statement-heads
    6480             : 
    6481             :   // Initialized declarations only allowed for
    6482             :   // - sloppy mode (not strict mode)
    6483             :   // - for-in (not for-of)
    6484             :   // - var (not let / const)
    6485             : 
    6486             :   // clang-format off
    6487             :   const char* strict_context[][2] = {{"'use strict';", ""},
    6488             :                                      {"function foo(){ 'use strict';", "}"},
    6489             :                                      {"function* foo(){ 'use strict';", "}"},
    6490           5 :                                      {nullptr, nullptr}};
    6491             : 
    6492             :   const char* sloppy_context[][2] = {{"", ""},
    6493             :                                      {"function foo(){ ", "}"},
    6494             :                                      {"function* foo(){ ", "}"},
    6495             :                                      {"function foo(){ var yield = 0; ", "}"},
    6496           5 :                                      {nullptr, nullptr}};
    6497             : 
    6498             :   const char* let_const_var_for_of[] = {
    6499             :       "for (let i = 1 of {}) {}",
    6500             :       "for (let i = void 0 of [1, 2, 3]) {}",
    6501             :       "for (const i = 1 of {}) {}",
    6502             :       "for (const i = void 0 of [1, 2, 3]) {}",
    6503             :       "for (var i = 1 of {}) {}",
    6504             :       "for (var i = void 0 of [1, 2, 3]) {}",
    6505           5 :       nullptr};
    6506             : 
    6507             :   const char* let_const_for_in[] = {
    6508             :       "for (let i = 1 in {}) {}",
    6509             :       "for (let i = void 0 in [1, 2, 3]) {}",
    6510             :       "for (const i = 1 in {}) {}",
    6511             :       "for (const i = void 0 in [1, 2, 3]) {}",
    6512           5 :       nullptr};
    6513             : 
    6514             :   const char* var_for_in[] = {
    6515             :       "for (var i = 1 in {}) {}",
    6516             :       "for (var i = void 0 in [1, 2, 3]) {}",
    6517             :       "for (var i = yield in [1, 2, 3]) {}",
    6518           5 :       nullptr};
    6519             :   // clang-format on
    6520             : 
    6521             :   // The only allowed case is sloppy + var + for-in.
    6522           5 :   RunParserSyncTest(sloppy_context, var_for_in, kSuccess);
    6523             : 
    6524             :   // Everything else is disallowed.
    6525           5 :   RunParserSyncTest(sloppy_context, let_const_var_for_of, kError);
    6526           5 :   RunParserSyncTest(sloppy_context, let_const_for_in, kError);
    6527             : 
    6528           5 :   RunParserSyncTest(strict_context, let_const_var_for_of, kError);
    6529           5 :   RunParserSyncTest(strict_context, let_const_for_in, kError);
    6530           5 :   RunParserSyncTest(strict_context, var_for_in, kError);
    6531           5 : }
    6532             : 
    6533       25880 : TEST(ForInMultipleDeclarationsError) {
    6534             :   const char* context_data[][2] = {{"", ""},
    6535             :                                    {"function foo(){", "}"},
    6536             :                                    {"'use strict';", ""},
    6537             :                                    {"function foo(){ 'use strict';", "}"},
    6538           5 :                                    {nullptr, nullptr}};
    6539             : 
    6540             :   const char* data[] = {"for (var i, j in {}) {}",
    6541             :                         "for (var i, j in [1, 2, 3]) {}",
    6542             :                         "for (var i, j = 1 in {}) {}",
    6543             :                         "for (var i, j = void 0 in [1, 2, 3]) {}",
    6544             : 
    6545             :                         "for (let i, j in {}) {}",
    6546             :                         "for (let i, j in [1, 2, 3]) {}",
    6547             :                         "for (let i, j = 1 in {}) {}",
    6548             :                         "for (let i, j = void 0 in [1, 2, 3]) {}",
    6549             : 
    6550             :                         "for (const i, j in {}) {}",
    6551             :                         "for (const i, j in [1, 2, 3]) {}",
    6552             :                         "for (const i, j = 1 in {}) {}",
    6553             :                         "for (const i, j = void 0 in [1, 2, 3]) {}",
    6554           5 :                         nullptr};
    6555           5 :   RunParserSyncTest(context_data, data, kError);
    6556           5 : }
    6557             : 
    6558             : 
    6559       25880 : TEST(ForOfMultipleDeclarationsError) {
    6560             :   const char* context_data[][2] = {{"", ""},
    6561             :                                    {"function foo(){", "}"},
    6562             :                                    {"'use strict';", ""},
    6563             :                                    {"function foo(){ 'use strict';", "}"},
    6564           5 :                                    {nullptr, nullptr}};
    6565             : 
    6566             :   const char* data[] = {"for (var i, j of {}) {}",
    6567             :                         "for (var i, j of [1, 2, 3]) {}",
    6568             :                         "for (var i, j = 1 of {}) {}",
    6569             :                         "for (var i, j = void 0 of [1, 2, 3]) {}",
    6570             : 
    6571             :                         "for (let i, j of {}) {}",
    6572             :                         "for (let i, j of [1, 2, 3]) {}",
    6573             :                         "for (let i, j = 1 of {}) {}",
    6574             :                         "for (let i, j = void 0 of [1, 2, 3]) {}",
    6575             : 
    6576             :                         "for (const i, j of {}) {}",
    6577             :                         "for (const i, j of [1, 2, 3]) {}",
    6578             :                         "for (const i, j = 1 of {}) {}",
    6579             :                         "for (const i, j = void 0 of [1, 2, 3]) {}",
    6580           5 :                         nullptr};
    6581           5 :   RunParserSyncTest(context_data, data, kError);
    6582           5 : }
    6583             : 
    6584             : 
    6585       25880 : TEST(ForInNoDeclarationsError) {
    6586             :   const char* context_data[][2] = {{"", ""},
    6587             :                                    {"function foo(){", "}"},
    6588             :                                    {"'use strict';", ""},
    6589             :                                    {"function foo(){ 'use strict';", "}"},
    6590           5 :                                    {nullptr, nullptr}};
    6591             : 
    6592           5 :   const char* data[] = {"for (var in {}) {}", "for (const in {}) {}", nullptr};
    6593           5 :   RunParserSyncTest(context_data, data, kError);
    6594           5 : }
    6595             : 
    6596             : 
    6597       25880 : TEST(ForOfNoDeclarationsError) {
    6598             :   const char* context_data[][2] = {{"", ""},
    6599             :                                    {"function foo(){", "}"},
    6600             :                                    {"'use strict';", ""},
    6601             :                                    {"function foo(){ 'use strict';", "}"},
    6602           5 :                                    {nullptr, nullptr}};
    6603             : 
    6604             :   const char* data[] = {"for (var of [1, 2, 3]) {}",
    6605           5 :                         "for (const of [1, 2, 3]) {}", nullptr};
    6606           5 :   RunParserSyncTest(context_data, data, kError);
    6607           5 : }
    6608             : 
    6609             : 
    6610       25880 : TEST(ForOfInOperator) {
    6611             :   const char* context_data[][2] = {{"", ""},
    6612             :                                    {"'use strict';", ""},
    6613             :                                    {"function foo(){ 'use strict';", "}"},
    6614           5 :                                    {nullptr, nullptr}};
    6615             : 
    6616             :   const char* data[] = {"for(x of 'foo' in {}) {}",
    6617             :                         "for(var x of 'foo' in {}) {}",
    6618             :                         "for(let x of 'foo' in {}) {}",
    6619           5 :                         "for(const x of 'foo' in {}) {}", nullptr};
    6620             : 
    6621           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6622           5 : }
    6623             : 
    6624             : 
    6625       25880 : TEST(ForOfYieldIdentifier) {
    6626           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    6627             : 
    6628             :   const char* data[] = {"for(x of yield) {}", "for(var x of yield) {}",
    6629             :                         "for(let x of yield) {}", "for(const x of yield) {}",
    6630           5 :                         nullptr};
    6631             : 
    6632           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6633           5 : }
    6634             : 
    6635             : 
    6636       25880 : TEST(ForOfYieldExpression) {
    6637             :   const char* context_data[][2] = {{"", ""},
    6638             :                                    {"'use strict';", ""},
    6639             :                                    {"function foo(){ 'use strict';", "}"},
    6640           5 :                                    {nullptr, nullptr}};
    6641             : 
    6642             :   const char* data[] = {"function* g() { for(x of yield) {} }",
    6643             :                         "function* g() { for(var x of yield) {} }",
    6644             :                         "function* g() { for(let x of yield) {} }",
    6645           5 :                         "function* g() { for(const x of yield) {} }", nullptr};
    6646             : 
    6647           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6648           5 : }
    6649             : 
    6650             : 
    6651       25880 : TEST(ForOfExpressionError) {
    6652             :   const char* context_data[][2] = {{"", ""},
    6653             :                                    {"'use strict';", ""},
    6654             :                                    {"function foo(){ 'use strict';", "}"},
    6655           5 :                                    {nullptr, nullptr}};
    6656             : 
    6657             :   const char* data[] = {
    6658             :       "for(x of [], []) {}", "for(var x of [], []) {}",
    6659             :       "for(let x of [], []) {}", "for(const x of [], []) {}",
    6660             : 
    6661             :       // AssignmentExpression should be validated statically:
    6662             :       "for(x of { y = 23 }) {}", "for(var x of { y = 23 }) {}",
    6663           5 :       "for(let x of { y = 23 }) {}", "for(const x of { y = 23 }) {}", nullptr};
    6664             : 
    6665           5 :   RunParserSyncTest(context_data, data, kError);
    6666           5 : }
    6667             : 
    6668             : 
    6669       25880 : TEST(InvalidUnicodeEscapes) {
    6670             :   const char* context_data[][2] = {
    6671           5 :       {"", ""}, {"'use strict';", ""}, {nullptr, nullptr}};
    6672             :   const char* data[] = {
    6673             :       "var foob\\u123r = 0;", "var \\u123roo = 0;", "\"foob\\u123rr\"",
    6674             :       // No escapes allowed in regexp flags
    6675             :       "/regex/\\u0069g", "/regex/\\u006g",
    6676             :       // Braces gone wrong
    6677             :       "var foob\\u{c481r = 0;", "var foob\\uc481}r = 0;", "var \\u{0052oo = 0;",
    6678             :       "var \\u0052}oo = 0;", "\"foob\\u{c481r\"", "var foob\\u{}ar = 0;",
    6679             :       // Too high value for the Unicode code point escape
    6680             :       "\"\\u{110000}\"",
    6681             :       // Not a Unicode code point escape
    6682             :       "var foob\\v1234r = 0;", "var foob\\U1234r = 0;",
    6683           5 :       "var foob\\v{1234}r = 0;", "var foob\\U{1234}r = 0;", nullptr};
    6684           5 :   RunParserSyncTest(context_data, data, kError);
    6685           5 : }
    6686             : 
    6687             : 
    6688       25880 : TEST(UnicodeEscapes) {
    6689             :   const char* context_data[][2] = {
    6690           5 :       {"", ""}, {"'use strict';", ""}, {nullptr, nullptr}};
    6691             :   const char* data[] = {
    6692             :       // Identifier starting with escape
    6693             :       "var \\u0052oo = 0;", "var \\u{0052}oo = 0;", "var \\u{52}oo = 0;",
    6694             :       "var \\u{00000000052}oo = 0;",
    6695             :       // Identifier with an escape but not starting with an escape
    6696             :       "var foob\\uc481r = 0;", "var foob\\u{c481}r = 0;",
    6697             :       // String with an escape
    6698             :       "\"foob\\uc481r\"", "\"foob\\{uc481}r\"",
    6699             :       // This character is a valid Unicode character, representable as a
    6700             :       // surrogate pair, not representable as 4 hex digits.
    6701             :       "\"foo\\u{10e6d}\"",
    6702             :       // Max value for the Unicode code point escape
    6703           5 :       "\"\\u{10ffff}\"", nullptr};
    6704           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6705           5 : }
    6706             : 
    6707       25880 : TEST(OctalEscapes) {
    6708             :   const char* sloppy_context_data[][2] = {{"", ""},    // as a directive
    6709             :                                           {"0;", ""},  // as a string literal
    6710           5 :                                           {nullptr, nullptr}};
    6711             : 
    6712             :   const char* strict_context_data[][2] = {
    6713             :       {"'use strict';", ""},     // as a directive before 'use strict'
    6714             :       {"", ";'use strict';"},    // as a directive after 'use strict'
    6715             :       {"'use strict'; 0;", ""},  // as a string literal
    6716           5 :       {nullptr, nullptr}};
    6717             : 
    6718             :   // clang-format off
    6719             :   const char* data[] = {
    6720             :     "'\\1'",
    6721             :     "'\\01'",
    6722             :     "'\\001'",
    6723             :     "'\\08'",
    6724             :     "'\\09'",
    6725           5 :     nullptr};
    6726             :   // clang-format on
    6727             : 
    6728             :   // Permitted in sloppy mode
    6729           5 :   RunParserSyncTest(sloppy_context_data, data, kSuccess);
    6730             : 
    6731             :   // Error in strict mode
    6732           5 :   RunParserSyncTest(strict_context_data, data, kError);
    6733           5 : }
    6734             : 
    6735       25880 : TEST(ScanTemplateLiterals) {
    6736             :   const char* context_data[][2] = {{"'use strict';", ""},
    6737             :                                    {"function foo(){ 'use strict';"
    6738             :                                     "  var a, b, c; return ",
    6739             :                                     "}"},
    6740           5 :                                    {nullptr, nullptr}};
    6741             : 
    6742             :   const char* data[] = {"``",
    6743             :                         "`no-subst-template`",
    6744             :                         "`template-head${a}`",
    6745             :                         "`${a}`",
    6746             :                         "`${a}template-tail`",
    6747             :                         "`template-head${a}template-tail`",
    6748             :                         "`${a}${b}${c}`",
    6749             :                         "`a${a}b${b}c${c}`",
    6750             :                         "`${a}a${b}b${c}c`",
    6751             :                         "`foo\n\nbar\r\nbaz`",
    6752             :                         "`foo\n\n${  bar  }\r\nbaz`",
    6753             :                         "`foo${a /* comment */}`",
    6754             :                         "`foo${a // comment\n}`",
    6755             :                         "`foo${a \n}`",
    6756             :                         "`foo${a \r\n}`",
    6757             :                         "`foo${a \r}`",
    6758             :                         "`foo${/* comment */ a}`",
    6759             :                         "`foo${// comment\na}`",
    6760             :                         "`foo${\n a}`",
    6761             :                         "`foo${\r\n a}`",
    6762             :                         "`foo${\r a}`",
    6763             :                         "`foo${'a' in a}`",
    6764           5 :                         nullptr};
    6765           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6766           5 : }
    6767             : 
    6768             : 
    6769       25880 : TEST(ScanTaggedTemplateLiterals) {
    6770             :   const char* context_data[][2] = {{"'use strict';", ""},
    6771             :                                    {"function foo(){ 'use strict';"
    6772             :                                     "  function tag() {}"
    6773             :                                     "  var a, b, c; return ",
    6774             :                                     "}"},
    6775           5 :                                    {nullptr, nullptr}};
    6776             : 
    6777             :   const char* data[] = {"tag ``",
    6778             :                         "tag `no-subst-template`",
    6779             :                         "tag`template-head${a}`",
    6780             :                         "tag `${a}`",
    6781             :                         "tag `${a}template-tail`",
    6782             :                         "tag   `template-head${a}template-tail`",
    6783             :                         "tag\n`${a}${b}${c}`",
    6784             :                         "tag\r\n`a${a}b${b}c${c}`",
    6785             :                         "tag    `${a}a${b}b${c}c`",
    6786             :                         "tag\t`foo\n\nbar\r\nbaz`",
    6787             :                         "tag\r`foo\n\n${  bar  }\r\nbaz`",
    6788             :                         "tag`foo${a /* comment */}`",
    6789             :                         "tag`foo${a // comment\n}`",
    6790             :                         "tag`foo${a \n}`",
    6791             :                         "tag`foo${a \r\n}`",
    6792             :                         "tag`foo${a \r}`",
    6793             :                         "tag`foo${/* comment */ a}`",
    6794             :                         "tag`foo${// comment\na}`",
    6795             :                         "tag`foo${\n a}`",
    6796             :                         "tag`foo${\r\n a}`",
    6797             :                         "tag`foo${\r a}`",
    6798             :                         "tag`foo${'a' in a}`",
    6799           5 :                         nullptr};
    6800           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6801           5 : }
    6802             : 
    6803             : 
    6804       25880 : TEST(TemplateMaterializedLiterals) {
    6805             :   const char* context_data[][2] = {{"'use strict';\n"
    6806             :                                     "function tag() {}\n"
    6807             :                                     "var a, b, c;\n"
    6808             :                                     "(",
    6809             :                                     ")"},
    6810           5 :                                    {nullptr, nullptr}};
    6811             : 
    6812             :   const char* data[] = {"tag``", "tag`a`", "tag`a${1}b`", "tag`a${1}b${2}c`",
    6813             :                         "``",    "`a`",    "`a${1}b`",    "`a${1}b${2}c`",
    6814           5 :                         nullptr};
    6815             : 
    6816           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6817           5 : }
    6818             : 
    6819             : 
    6820       25880 : TEST(ScanUnterminatedTemplateLiterals) {
    6821             :   const char* context_data[][2] = {{"'use strict';", ""},
    6822             :                                    {"function foo(){ 'use strict';"
    6823             :                                     "  var a, b, c; return ",
    6824             :                                     "}"},
    6825           5 :                                    {nullptr, nullptr}};
    6826             : 
    6827             :   const char* data[] = {"`no-subst-template",
    6828             :                         "`template-head${a}",
    6829             :                         "`${a}template-tail",
    6830             :                         "`template-head${a}template-tail",
    6831             :                         "`${a}${b}${c}",
    6832             :                         "`a${a}b${b}c${c}",
    6833             :                         "`${a}a${b}b${c}c",
    6834             :                         "`foo\n\nbar\r\nbaz",
    6835             :                         "`foo\n\n${  bar  }\r\nbaz",
    6836             :                         "`foo${a /* comment } */`",
    6837             :                         "`foo${a /* comment } `*/",
    6838             :                         "`foo${a // comment}`",
    6839             :                         "`foo${a \n`",
    6840             :                         "`foo${a \r\n`",
    6841             :                         "`foo${a \r`",
    6842             :                         "`foo${/* comment */ a`",
    6843             :                         "`foo${// commenta}`",
    6844             :                         "`foo${\n a`",
    6845             :                         "`foo${\r\n a`",
    6846             :                         "`foo${\r a`",
    6847             :                         "`foo${fn(}`",
    6848             :                         "`foo${1 if}`",
    6849           5 :                         nullptr};
    6850           5 :   RunParserSyncTest(context_data, data, kError);
    6851           5 : }
    6852             : 
    6853             : 
    6854       25880 : TEST(TemplateLiteralsIllegalTokens) {
    6855             :   const char* context_data[][2] = {{"'use strict';", ""},
    6856             :                                    {"function foo(){ 'use strict';"
    6857             :                                     "  var a, b, c; return ",
    6858             :                                     "}"},
    6859           5 :                                    {nullptr, nullptr}};
    6860             :   const char* data[] = {
    6861             :       "`hello\\x`",         "`hello\\x${1}`",       "`hello${1}\\x`",
    6862             :       "`hello${1}\\x${2}`", "`hello\\x\n`",         "`hello\\x\n${1}`",
    6863           5 :       "`hello${1}\\x\n`",   "`hello${1}\\x\n${2}`", nullptr};
    6864             : 
    6865           5 :   RunParserSyncTest(context_data, data, kError);
    6866           5 : }
    6867             : 
    6868             : 
    6869       25880 : TEST(ParseRestParameters) {
    6870             :   const char* context_data[][2] = {{"'use strict';(function(",
    6871             :                                     "){ return args;})(1, [], /regexp/, 'str',"
    6872             :                                     "function(){});"},
    6873             :                                    {"(function(",
    6874             :                                     "){ return args;})(1, [],"
    6875             :                                     "/regexp/, 'str', function(){});"},
    6876           5 :                                    {nullptr, nullptr}};
    6877             : 
    6878             :   const char* data[] = {"...args",
    6879             :                         "a, ...args",
    6880             :                         "...   args",
    6881             :                         "a, ...   args",
    6882             :                         "...\targs",
    6883             :                         "a, ...\targs",
    6884             :                         "...\r\nargs",
    6885             :                         "a, ...\r\nargs",
    6886             :                         "...\rargs",
    6887             :                         "a, ...\rargs",
    6888             :                         "...\t\n\t\t\n  args",
    6889             :                         "a, ...  \n  \n  args",
    6890             :                         "...{ length, 0: a, 1: b}",
    6891             :                         "...{}",
    6892             :                         "...[a, b]",
    6893             :                         "...[]",
    6894             :                         "...[...[a, b, ...c]]",
    6895           5 :                         nullptr};
    6896           5 :   RunParserSyncTest(context_data, data, kSuccess);
    6897           5 : }
    6898             : 
    6899             : 
    6900       25880 : TEST(ParseRestParametersErrors) {
    6901             :   const char* context_data[][2] = {{"'use strict';(function(",
    6902             :                                     "){ return args;}(1, [], /regexp/, 'str',"
    6903             :                                     "function(){});"},
    6904             :                                    {"(function(",
    6905             :                                     "){ return args;}(1, [],"
    6906             :                                     "/regexp/, 'str', function(){});"},
    6907           5 :                                    {nullptr, nullptr}};
    6908             : 
    6909             :   const char* data[] = {"...args, b",
    6910             :                         "a, ...args, b",
    6911             :                         "...args,   b",
    6912             :                         "a, ...args,   b",
    6913             :                         "...args,\tb",
    6914             :                         "a,...args\t,b",
    6915             :                         "...args\r\n, b",
    6916             :                         "a, ... args,\r\nb",
    6917             :                         "...args\r,b",
    6918             :                         "a, ... args,\rb",
    6919             :                         "...args\t\n\t\t\n,  b",
    6920             :                         "a, ... args,  \n  \n  b",
    6921             :                         "a, a, ...args",
    6922             :                         "a,\ta, ...args",
    6923             :                         "a,\ra, ...args",
    6924             :                         "a,\na, ...args",
    6925           5 :                         nullptr};
    6926           5 :   RunParserSyncTest(context_data, data, kError);
    6927           5 : }
    6928             : 
    6929             : 
    6930       25880 : TEST(RestParameterInSetterMethodError) {
    6931             :   const char* context_data[][2] = {
    6932             :       {"'use strict';({ set prop(", ") {} }).prop = 1;"},
    6933             :       {"'use strict';(class { static set prop(", ") {} }).prop = 1;"},
    6934             :       {"'use strict';(new (class { set prop(", ") {} })).prop = 1;"},
    6935             :       {"({ set prop(", ") {} }).prop = 1;"},
    6936             :       {"(class { static set prop(", ") {} }).prop = 1;"},
    6937             :       {"(new (class { set prop(", ") {} })).prop = 1;"},
    6938           5 :       {nullptr, nullptr}};
    6939           5 :   const char* data[] = {"...a", "...arguments", "...eval", nullptr};
    6940             : 
    6941           5 :   RunParserSyncTest(context_data, data, kError);
    6942           5 : }
    6943             : 
    6944             : 
    6945       25880 : TEST(RestParametersEvalArguments) {
    6946             :   // clang-format off
    6947             :   const char* strict_context_data[][2] =
    6948             :       {{"'use strict';(function(",
    6949             :         "){ return;})(1, [], /regexp/, 'str',function(){});"},
    6950           5 :        {nullptr, nullptr}};
    6951             :   const char* sloppy_context_data[][2] =
    6952             :       {{"(function(",
    6953             :         "){ return;})(1, [],/regexp/, 'str', function(){});"},
    6954           5 :        {nullptr, nullptr}};
    6955             : 
    6956             :   const char* data[] = {
    6957             :       "...eval",
    6958             :       "eval, ...args",
    6959             :       "...arguments",
    6960             :       // See https://bugs.chromium.org/p/v8/issues/detail?id=4577
    6961             :       // "arguments, ...args",
    6962           5 :       nullptr};
    6963             :   // clang-format on
    6964             : 
    6965             :   // Fail in strict mode
    6966           5 :   RunParserSyncTest(strict_context_data, data, kError);
    6967             : 
    6968             :   // OK in sloppy mode
    6969           5 :   RunParserSyncTest(sloppy_context_data, data, kSuccess);
    6970           5 : }
    6971             : 
    6972             : 
    6973       25880 : TEST(RestParametersDuplicateEvalArguments) {
    6974             :   const char* context_data[][2] = {
    6975             :       {"'use strict';(function(",
    6976             :        "){ return;})(1, [], /regexp/, 'str',function(){});"},
    6977             :       {"(function(", "){ return;})(1, [],/regexp/, 'str', function(){});"},
    6978           5 :       {nullptr, nullptr}};
    6979             : 
    6980             :   const char* data[] = {"eval, ...eval", "eval, eval, ...args",
    6981             :                         "arguments, ...arguments",
    6982           5 :                         "arguments, arguments, ...args", nullptr};
    6983             : 
    6984             :   // In strict mode, the error is using "eval" or "arguments" as parameter names
    6985             :   // In sloppy mode, the error is that eval / arguments are duplicated
    6986           5 :   RunParserSyncTest(context_data, data, kError);
    6987           5 : }
    6988             : 
    6989             : 
    6990       25880 : TEST(SpreadCall) {
    6991             :   const char* context_data[][2] = {{"function fn() { 'use strict';} fn(", ");"},
    6992             :                                    {"function fn() {} fn(", ");"},
    6993           5 :                                    {nullptr, nullptr}};
    6994             : 
    6995             :   const char* data[] = {"...([1, 2, 3])",
    6996             :                         "...'123', ...'456'",
    6997             :                         "...new Set([1, 2, 3]), 4",
    6998             :                         "1, ...[2, 3], 4",
    6999             :                         "...Array(...[1,2,3,4])",
    7000             :                         "...NaN",
    7001             :                         "0, 1, ...[2, 3, 4], 5, 6, 7, ...'89'",
    7002             :                         "0, 1, ...[2, 3, 4], 5, 6, 7, ...'89', 10",
    7003             :                         "...[0, 1, 2], 3, 4, 5, 6, ...'7', 8, 9",
    7004             :                         "...[0, 1, 2], 3, 4, 5, 6, ...'7', 8, 9, ...[10]",
    7005           5 :                         nullptr};
    7006             : 
    7007           5 :   RunParserSyncTest(context_data, data, kSuccess);
    7008           5 : }
    7009             : 
    7010             : 
    7011       25880 : TEST(SpreadCallErrors) {
    7012             :   const char* context_data[][2] = {{"function fn() { 'use strict';} fn(", ");"},
    7013             :                                    {"function fn() {} fn(", ");"},
    7014           5 :                                    {nullptr, nullptr}};
    7015             : 
    7016           5 :   const char* data[] = {"(...[1, 2, 3])", "......[1,2,3]", nullptr};
    7017             : 
    7018           5 :   RunParserSyncTest(context_data, data, kError);
    7019           5 : }
    7020             : 
    7021             : 
    7022       25880 : TEST(BadRestSpread) {
    7023             :   const char* context_data[][2] = {{"function fn() { 'use strict';", "} fn();"},
    7024             :                                    {"function fn() { ", "} fn();"},
    7025           5 :                                    {nullptr, nullptr}};
    7026             :   const char* data[] = {"return ...[1,2,3];",
    7027             :                         "var ...x = [1,2,3];",
    7028             :                         "var [...x,] = [1,2,3];",
    7029             :                         "var [...x, y] = [1,2,3];",
    7030             :                         "var { x } = {x: ...[1,2,3]}",
    7031           5 :                         nullptr};
    7032           5 :   RunParserSyncTest(context_data, data, kError);
    7033           5 : }
    7034             : 
    7035             : 
    7036       25880 : TEST(LexicalScopingSloppyMode) {
    7037             :   const char* context_data[][2] = {
    7038           5 :       {"", ""}, {"function f() {", "}"}, {"{", "}"}, {nullptr, nullptr}};
    7039             : 
    7040           5 :   const char* good_data[] = {"let = 1;", "for(let = 1;;){}", nullptr};
    7041           5 :   RunParserSyncTest(context_data, good_data, kSuccess);
    7042           5 : }
    7043             : 
    7044             : 
    7045       25880 : TEST(ComputedPropertyName) {
    7046             :   const char* context_data[][2] = {{"({[", "]: 1});"},
    7047             :                                    {"({get [", "]() {}});"},
    7048             :                                    {"({set [", "](_) {}});"},
    7049             :                                    {"({[", "]() {}});"},
    7050             :                                    {"({*[", "]() {}});"},
    7051             :                                    {"(class {get [", "]() {}});"},
    7052             :                                    {"(class {set [", "](_) {}});"},
    7053             :                                    {"(class {[", "]() {}});"},
    7054             :                                    {"(class {*[", "]() {}});"},
    7055           5 :                                    {nullptr, nullptr}};
    7056           5 :   const char* error_data[] = {"1, 2", "var name", nullptr};
    7057             : 
    7058           5 :   RunParserSyncTest(context_data, error_data, kError);
    7059             : 
    7060             :   const char* name_data[] = {"1",  "1 + 2", "'name'", "\"name\"",
    7061           5 :                              "[]", "{}",    nullptr};
    7062             : 
    7063           5 :   RunParserSyncTest(context_data, name_data, kSuccess);
    7064           5 : }
    7065             : 
    7066             : 
    7067       25880 : TEST(ComputedPropertyNameShorthandError) {
    7068           5 :   const char* context_data[][2] = {{"({", "});"}, {nullptr, nullptr}};
    7069           5 :   const char* error_data[] = {"a: 1, [2]", "[1], a: 1", nullptr};
    7070             : 
    7071           5 :   RunParserSyncTest(context_data, error_data, kError);
    7072           5 : }
    7073             : 
    7074             : 
    7075       25880 : TEST(BasicImportExportParsing) {
    7076             :   // clang-format off
    7077             :   const char* kSources[] = {
    7078             :       "export let x = 0;",
    7079             :       "export var y = 0;",
    7080             :       "export const z = 0;",
    7081             :       "export function func() { };",
    7082             :       "export class C { };",
    7083             :       "export { };",
    7084             :       "function f() {}; f(); export { f };",
    7085             :       "var a, b, c; export { a, b as baz, c };",
    7086             :       "var d, e; export { d as dreary, e, };",
    7087             :       "export default function f() {}",
    7088             :       "export default function() {}",
    7089             :       "export default function*() {}",
    7090             :       "export default class C {}",
    7091             :       "export default class {}",
    7092             :       "export default class extends C {}",
    7093             :       "export default 42",
    7094             :       "var x; export default x = 7",
    7095             :       "export { Q } from 'somemodule.js';",
    7096             :       "export * from 'somemodule.js';",
    7097             :       "var foo; export { foo as for };",
    7098             :       "export { arguments } from 'm.js';",
    7099             :       "export { for } from 'm.js';",
    7100             :       "export { yield } from 'm.js'",
    7101             :       "export { static } from 'm.js'",
    7102             :       "export { let } from 'm.js'",
    7103             :       "var a; export { a as b, a as c };",
    7104             :       "var a; export { a as await };",
    7105             :       "var a; export { a as enum };",
    7106             : 
    7107             :       "import 'somemodule.js';",
    7108             :       "import { } from 'm.js';",
    7109             :       "import { a } from 'm.js';",
    7110             :       "import { a, b as d, c, } from 'm.js';",
    7111             :       "import * as thing from 'm.js';",
    7112             :       "import thing from 'm.js';",
    7113             :       "import thing, * as rest from 'm.js';",
    7114             :       "import thing, { a, b, c } from 'm.js';",
    7115             :       "import { arguments as a } from 'm.js';",
    7116             :       "import { for as f } from 'm.js';",
    7117             :       "import { yield as y } from 'm.js';",
    7118             :       "import { static as s } from 'm.js';",
    7119             :       "import { let as l } from 'm.js';",
    7120             : 
    7121             :       "import thing from 'a.js'; export {thing};",
    7122             :       "export {thing}; import thing from 'a.js';",
    7123             :       "import {thing} from 'a.js'; export {thing};",
    7124             :       "export {thing}; import {thing} from 'a.js';",
    7125             :       "import * as thing from 'a.js'; export {thing};",
    7126             :       "export {thing}; import * as thing from 'a.js';",
    7127           5 :   };
    7128             :   // clang-format on
    7129             : 
    7130             :   i::Isolate* isolate = CcTest::i_isolate();
    7131             :   i::Factory* factory = isolate->factory();
    7132             : 
    7133           5 :   v8::HandleScope handles(CcTest::isolate());
    7134           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7135             :   v8::Context::Scope context_scope(context);
    7136             : 
    7137           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7138           5 :                                         128 * 1024);
    7139             : 
    7140         240 :   for (unsigned i = 0; i < arraysize(kSources); ++i) {
    7141             :     i::Handle<i::String> source =
    7142         235 :         factory->NewStringFromAsciiChecked(kSources[i]);
    7143             : 
    7144             :     // Show that parsing as a module works
    7145             :     {
    7146         235 :       i::Handle<i::Script> script = factory->NewScript(source);
    7147         235 :       i::ParseInfo info(isolate, script);
    7148             :       info.set_module();
    7149         235 :       if (!i::parsing::ParseProgram(&info, isolate)) {
    7150             :         i::Handle<i::JSObject> exception_handle(
    7151             :             i::JSObject::cast(isolate->pending_exception()), isolate);
    7152             :         i::Handle<i::String> message_string = i::Handle<i::String>::cast(
    7153           0 :             i::JSReceiver::GetProperty(isolate, exception_handle, "message")
    7154           0 :                 .ToHandleChecked());
    7155           0 :         isolate->clear_pending_exception();
    7156             : 
    7157           0 :         FATAL(
    7158             :             "Parser failed on:\n"
    7159             :             "\t%s\n"
    7160             :             "with error:\n"
    7161             :             "\t%s\n"
    7162             :             "However, we expected no error.",
    7163           0 :             source->ToCString().get(), message_string->ToCString().get());
    7164         235 :       }
    7165             :     }
    7166             : 
    7167             :     // And that parsing a script does not.
    7168             :     {
    7169         235 :       i::Handle<i::Script> script = factory->NewScript(source);
    7170         235 :       i::ParseInfo info(isolate, script);
    7171         235 :       CHECK(!i::parsing::ParseProgram(&info, isolate));
    7172         235 :       isolate->clear_pending_exception();
    7173             :     }
    7174           5 :   }
    7175           5 : }
    7176             : 
    7177       25880 : TEST(NamespaceExportParsing) {
    7178             :   // clang-format off
    7179             :   const char* kSources[] = {
    7180             :       "export * as arguments from 'bar'",
    7181             :       "export * as await from 'bar'",
    7182             :       "export * as default from 'bar'",
    7183             :       "export * as enum from 'bar'",
    7184             :       "export * as foo from 'bar'",
    7185             :       "export * as for from 'bar'",
    7186             :       "export * as let from 'bar'",
    7187             :       "export * as static from 'bar'",
    7188             :       "export * as yield from 'bar'",
    7189           5 :   };
    7190             :   // clang-format on
    7191             : 
    7192           5 :   i::FLAG_harmony_namespace_exports = true;
    7193             :   i::Isolate* isolate = CcTest::i_isolate();
    7194             :   i::Factory* factory = isolate->factory();
    7195             : 
    7196           5 :   v8::HandleScope handles(CcTest::isolate());
    7197           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7198             :   v8::Context::Scope context_scope(context);
    7199             : 
    7200           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7201           5 :                                         128 * 1024);
    7202             : 
    7203          50 :   for (unsigned i = 0; i < arraysize(kSources); ++i) {
    7204             :     i::Handle<i::String> source =
    7205          45 :         factory->NewStringFromAsciiChecked(kSources[i]);
    7206          45 :     i::Handle<i::Script> script = factory->NewScript(source);
    7207          45 :     i::ParseInfo info(isolate, script);
    7208             :     info.set_module();
    7209          45 :     CHECK(i::parsing::ParseProgram(&info, isolate));
    7210          50 :   }
    7211           5 : }
    7212             : 
    7213       25880 : TEST(ImportExportParsingErrors) {
    7214             :   // clang-format off
    7215             :   const char* kErrorSources[] = {
    7216             :       "export {",
    7217             :       "var a; export { a",
    7218             :       "var a; export { a,",
    7219             :       "var a; export { a, ;",
    7220             :       "var a; export { a as };",
    7221             :       "var a, b; export { a as , b};",
    7222             :       "export }",
    7223             :       "var foo, bar; export { foo bar };",
    7224             :       "export { foo };",
    7225             :       "export { , };",
    7226             :       "export default;",
    7227             :       "export default var x = 7;",
    7228             :       "export default let x = 7;",
    7229             :       "export default const x = 7;",
    7230             :       "export *;",
    7231             :       "export * from;",
    7232             :       "export { Q } from;",
    7233             :       "export default from 'module.js';",
    7234             :       "export { for }",
    7235             :       "export { for as foo }",
    7236             :       "export { arguments }",
    7237             :       "export { arguments as foo }",
    7238             :       "var a; export { a, a };",
    7239             :       "var a, b; export { a as b, b };",
    7240             :       "var a, b; export { a as c, b as c };",
    7241             :       "export default function f(){}; export default class C {};",
    7242             :       "export default function f(){}; var a; export { a as default };",
    7243             :       "export function() {}",
    7244             :       "export function*() {}",
    7245             :       "export class {}",
    7246             :       "export class extends C {}",
    7247             : 
    7248             :       "import from;",
    7249             :       "import from 'm.js';",
    7250             :       "import { };",
    7251             :       "import {;",
    7252             :       "import };",
    7253             :       "import { , };",
    7254             :       "import { , } from 'm.js';",
    7255             :       "import { a } from;",
    7256             :       "import { a } 'm.js';",
    7257             :       "import , from 'm.js';",
    7258             :       "import a , from 'm.js';",
    7259             :       "import a { b, c } from 'm.js';",
    7260             :       "import arguments from 'm.js';",
    7261             :       "import eval from 'm.js';",
    7262             :       "import { arguments } from 'm.js';",
    7263             :       "import { eval } from 'm.js';",
    7264             :       "import { a as arguments } from 'm.js';",
    7265             :       "import { for } from 'm.js';",
    7266             :       "import { y as yield } from 'm.js'",
    7267             :       "import { s as static } from 'm.js'",
    7268             :       "import { l as let } from 'm.js'",
    7269             :       "import { a as await } from 'm.js';",
    7270             :       "import { a as enum } from 'm.js';",
    7271             :       "import { x }, def from 'm.js';",
    7272             :       "import def, def2 from 'm.js';",
    7273             :       "import * as x, def from 'm.js';",
    7274             :       "import * as x, * as y from 'm.js';",
    7275             :       "import {x}, {y} from 'm.js';",
    7276             :       "import * as x, {y} from 'm.js';",
    7277             : 
    7278             :       "export *;",
    7279             :       "export * as;",
    7280             :       "export * as foo;",
    7281             :       "export * as foo from;",
    7282             :       "export * as foo from ';",
    7283             :       "export * as ,foo from 'bar'",
    7284           5 :   };
    7285             :   // clang-format on
    7286             : 
    7287             :   i::Isolate* isolate = CcTest::i_isolate();
    7288             :   i::Factory* factory = isolate->factory();
    7289             : 
    7290           5 :   v8::HandleScope handles(CcTest::isolate());
    7291           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7292             :   v8::Context::Scope context_scope(context);
    7293             : 
    7294           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7295           5 :                                         128 * 1024);
    7296             : 
    7297         335 :   for (unsigned i = 0; i < arraysize(kErrorSources); ++i) {
    7298             :     i::Handle<i::String> source =
    7299         330 :         factory->NewStringFromAsciiChecked(kErrorSources[i]);
    7300             : 
    7301         330 :     i::Handle<i::Script> script = factory->NewScript(source);
    7302         330 :     i::ParseInfo info(isolate, script);
    7303             :     info.set_module();
    7304         330 :     CHECK(!i::parsing::ParseProgram(&info, isolate));
    7305         330 :     isolate->clear_pending_exception();
    7306         335 :   }
    7307           5 : }
    7308             : 
    7309       25880 : TEST(ModuleTopLevelFunctionDecl) {
    7310             :   // clang-format off
    7311             :   const char* kErrorSources[] = {
    7312             :       "function f() {} function f() {}",
    7313             :       "var f; function f() {}",
    7314             :       "function f() {} var f;",
    7315             :       "function* f() {} function* f() {}",
    7316             :       "var f; function* f() {}",
    7317             :       "function* f() {} var f;",
    7318             :       "function f() {} function* f() {}",
    7319             :       "function* f() {} function f() {}",
    7320           5 :   };
    7321             :   // clang-format on
    7322             : 
    7323             :   i::Isolate* isolate = CcTest::i_isolate();
    7324             :   i::Factory* factory = isolate->factory();
    7325             : 
    7326           5 :   v8::HandleScope handles(CcTest::isolate());
    7327           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7328             :   v8::Context::Scope context_scope(context);
    7329             : 
    7330           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7331           5 :                                         128 * 1024);
    7332             : 
    7333          45 :   for (unsigned i = 0; i < arraysize(kErrorSources); ++i) {
    7334             :     i::Handle<i::String> source =
    7335          40 :         factory->NewStringFromAsciiChecked(kErrorSources[i]);
    7336             : 
    7337          40 :     i::Handle<i::Script> script = factory->NewScript(source);
    7338          40 :     i::ParseInfo info(isolate, script);
    7339             :     info.set_module();
    7340          40 :     CHECK(!i::parsing::ParseProgram(&info, isolate));
    7341          40 :     isolate->clear_pending_exception();
    7342          45 :   }
    7343           5 : }
    7344             : 
    7345       25880 : TEST(ModuleAwaitReserved) {
    7346             :   // clang-format off
    7347             :   const char* kErrorSources[] = {
    7348             :       "await;",
    7349             :       "await: ;",
    7350             :       "var await;",
    7351             :       "var [await] = [];",
    7352             :       "var { await } = {};",
    7353             :       "var { x: await } = {};",
    7354             :       "{ var await; }",
    7355             :       "let await;",
    7356             :       "let [await] = [];",
    7357             :       "let { await } = {};",
    7358             :       "let { x: await } = {};",
    7359             :       "{ let await; }",
    7360             :       "const await = null;",
    7361             :       "const [await] = [];",
    7362             :       "const { await } = {};",
    7363             :       "const { x: await } = {};",
    7364             :       "{ const await = null; }",
    7365             :       "function await() {}",
    7366             :       "function f(await) {}",
    7367             :       "function* await() {}",
    7368             :       "function* g(await) {}",
    7369             :       "(function await() {});",
    7370             :       "(function (await) {});",
    7371             :       "(function* await() {});",
    7372             :       "(function* (await) {});",
    7373             :       "(await) => {};",
    7374             :       "await => {};",
    7375             :       "class await {}",
    7376             :       "class C { constructor(await) {} }",
    7377             :       "class C { m(await) {} }",
    7378             :       "class C { static m(await) {} }",
    7379             :       "class C { *m(await) {} }",
    7380             :       "class C { static *m(await) {} }",
    7381             :       "(class await {})",
    7382             :       "(class { constructor(await) {} });",
    7383             :       "(class { m(await) {} });",
    7384             :       "(class { static m(await) {} });",
    7385             :       "(class { *m(await) {} });",
    7386             :       "(class { static *m(await) {} });",
    7387             :       "({ m(await) {} });",
    7388             :       "({ *m(await) {} });",
    7389             :       "({ set p(await) {} });",
    7390             :       "try {} catch (await) {}",
    7391             :       "try {} catch (await) {} finally {}",
    7392             :       nullptr
    7393           5 :   };
    7394             :   // clang-format on
    7395           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    7396             : 
    7397             :   RunModuleParserSyncTest(context_data, kErrorSources, kError);
    7398           5 : }
    7399             : 
    7400       25880 : TEST(ModuleAwaitReservedPreParse) {
    7401           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    7402           5 :   const char* error_data[] = {"function f() { var await = 0; }", nullptr};
    7403             : 
    7404             :   RunModuleParserSyncTest(context_data, error_data, kError);
    7405           5 : }
    7406             : 
    7407       25880 : TEST(ModuleAwaitPermitted) {
    7408             :   // clang-format off
    7409             :   const char* kValidSources[] = {
    7410             :     "({}).await;",
    7411             :     "({ await: null });",
    7412             :     "({ await() {} });",
    7413             :     "({ get await() {} });",
    7414             :     "({ set await(x) {} });",
    7415             :     "(class { await() {} });",
    7416             :     "(class { static await() {} });",
    7417             :     "(class { *await() {} });",
    7418             :     "(class { static *await() {} });",
    7419             :     nullptr
    7420           5 :   };
    7421             :   // clang-format on
    7422           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    7423             : 
    7424             :   RunModuleParserSyncTest(context_data, kValidSources, kSuccess);
    7425           5 : }
    7426             : 
    7427       25880 : TEST(EnumReserved) {
    7428             :   // clang-format off
    7429             :   const char* kErrorSources[] = {
    7430             :       "enum;",
    7431             :       "enum: ;",
    7432             :       "var enum;",
    7433             :       "var [enum] = [];",
    7434             :       "var { enum } = {};",
    7435             :       "var { x: enum } = {};",
    7436             :       "{ var enum; }",
    7437             :       "let enum;",
    7438             :       "let [enum] = [];",
    7439             :       "let { enum } = {};",
    7440             :       "let { x: enum } = {};",
    7441             :       "{ let enum; }",
    7442             :       "const enum = null;",
    7443             :       "const [enum] = [];",
    7444             :       "const { enum } = {};",
    7445             :       "const { x: enum } = {};",
    7446             :       "{ const enum = null; }",
    7447             :       "function enum() {}",
    7448             :       "function f(enum) {}",
    7449             :       "function* enum() {}",
    7450             :       "function* g(enum) {}",
    7451             :       "(function enum() {});",
    7452             :       "(function (enum) {});",
    7453             :       "(function* enum() {});",
    7454             :       "(function* (enum) {});",
    7455             :       "(enum) => {};",
    7456             :       "enum => {};",
    7457             :       "class enum {}",
    7458             :       "class C { constructor(enum) {} }",
    7459             :       "class C { m(enum) {} }",
    7460             :       "class C { static m(enum) {} }",
    7461             :       "class C { *m(enum) {} }",
    7462             :       "class C { static *m(enum) {} }",
    7463             :       "(class enum {})",
    7464             :       "(class { constructor(enum) {} });",
    7465             :       "(class { m(enum) {} });",
    7466             :       "(class { static m(enum) {} });",
    7467             :       "(class { *m(enum) {} });",
    7468             :       "(class { static *m(enum) {} });",
    7469             :       "({ m(enum) {} });",
    7470             :       "({ *m(enum) {} });",
    7471             :       "({ set p(enum) {} });",
    7472             :       "try {} catch (enum) {}",
    7473             :       "try {} catch (enum) {} finally {}",
    7474             :       nullptr
    7475           5 :   };
    7476             :   // clang-format on
    7477           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
    7478             : 
    7479             :   RunModuleParserSyncTest(context_data, kErrorSources, kError);
    7480           5 : }
    7481             : 
    7482          85 : static void CheckEntry(const i::ModuleDescriptor::Entry* entry,
    7483             :                        const char* export_name, const char* local_name,
    7484             :                        const char* import_name, int module_request) {
    7485          85 :   CHECK_NOT_NULL(entry);
    7486          85 :   if (export_name == nullptr) {
    7487          35 :     CHECK_NULL(entry->export_name);
    7488             :   } else {
    7489          50 :     CHECK(entry->export_name->IsOneByteEqualTo(export_name));
    7490             :   }
    7491          85 :   if (local_name == nullptr) {
    7492          15 :     CHECK_NULL(entry->local_name);
    7493             :   } else {
    7494          70 :     CHECK(entry->local_name->IsOneByteEqualTo(local_name));
    7495             :   }
    7496          85 :   if (import_name == nullptr) {
    7497          55 :     CHECK_NULL(entry->import_name);
    7498             :   } else {
    7499          30 :     CHECK(entry->import_name->IsOneByteEqualTo(import_name));
    7500             :   }
    7501          85 :   CHECK_EQ(entry->module_request, module_request);
    7502          85 : }
    7503             : 
    7504       25880 : TEST(ModuleParsingInternals) {
    7505             :   i::Isolate* isolate = CcTest::i_isolate();
    7506             :   i::Factory* factory = isolate->factory();
    7507           5 :   v8::HandleScope handles(CcTest::isolate());
    7508           5 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7509             :   v8::Context::Scope context_scope(context);
    7510           5 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7511           5 :                                         128 * 1024);
    7512             : 
    7513             :   static const char kSource[] =
    7514             :       "let x = 5;"
    7515             :       "export { x as y };"
    7516             :       "import { q as z } from 'm.js';"
    7517             :       "import n from 'n.js';"
    7518             :       "export { a as b } from 'm.js';"
    7519             :       "export * from 'p.js';"
    7520             :       "export var foo;"
    7521             :       "export function goo() {};"
    7522             :       "export let hoo;"
    7523             :       "export const joo = 42;"
    7524             :       "export default (function koo() {});"
    7525             :       "import 'q.js';"
    7526             :       "let nonexport = 42;"
    7527             :       "import {m as mm} from 'm.js';"
    7528             :       "import {aa} from 'm.js';"
    7529             :       "export {aa as bb, x};"
    7530             :       "import * as loo from 'bar.js';"
    7531             :       "import * as foob from 'bar.js';"
    7532             :       "export {foob};";
    7533           5 :   i::Handle<i::String> source = factory->NewStringFromAsciiChecked(kSource);
    7534           5 :   i::Handle<i::Script> script = factory->NewScript(source);
    7535          10 :   i::ParseInfo info(isolate, script);
    7536             :   info.set_module();
    7537           5 :   CHECK(i::parsing::ParseProgram(&info, isolate));
    7538           5 :   CHECK(i::Compiler::Analyze(&info));
    7539           5 :   i::FunctionLiteral* func = info.literal();
    7540          10 :   i::ModuleScope* module_scope = func->scope()->AsModuleScope();
    7541          15 :   i::Scope* outer_scope = module_scope->outer_scope();
    7542           5 :   CHECK(outer_scope->is_script_scope());
    7543           5 :   CHECK_NULL(outer_scope->outer_scope());
    7544           5 :   CHECK(module_scope->is_module_scope());
    7545             :   const i::ModuleDescriptor::Entry* entry;
    7546             :   i::Declaration::List* declarations = module_scope->declarations();
    7547           5 :   CHECK_EQ(13, declarations->LengthForTest());
    7548             : 
    7549           5 :   CHECK(declarations->AtForTest(0)->var()->raw_name()->IsOneByteEqualTo("x"));
    7550          10 :   CHECK(declarations->AtForTest(0)->var()->mode() == i::VariableMode::kLet);
    7551           5 :   CHECK(declarations->AtForTest(0)->var()->binding_needs_init());
    7552           5 :   CHECK(declarations->AtForTest(0)->var()->location() ==
    7553             :         i::VariableLocation::MODULE);
    7554             : 
    7555           5 :   CHECK(declarations->AtForTest(1)->var()->raw_name()->IsOneByteEqualTo("z"));
    7556          10 :   CHECK(declarations->AtForTest(1)->var()->mode() == i::VariableMode::kConst);
    7557           5 :   CHECK(declarations->AtForTest(1)->var()->binding_needs_init());
    7558          10 :   CHECK(declarations->AtForTest(1)->var()->location() ==
    7559             :         i::VariableLocation::MODULE);
    7560             : 
    7561           5 :   CHECK(declarations->AtForTest(2)->var()->raw_name()->IsOneByteEqualTo("n"));
    7562          10 :   CHECK(declarations->AtForTest(2)->var()->mode() == i::VariableMode::kConst);
    7563           5 :   CHECK(declarations->AtForTest(2)->var()->binding_needs_init());
    7564          10 :   CHECK(declarations->AtForTest(2)->var()->location() ==
    7565             :         i::VariableLocation::MODULE);
    7566             : 
    7567           5 :   CHECK(declarations->AtForTest(3)->var()->raw_name()->IsOneByteEqualTo("foo"));
    7568          10 :   CHECK(declarations->AtForTest(3)->var()->mode() == i::VariableMode::kVar);
    7569           5 :   CHECK(!declarations->AtForTest(3)->var()->binding_needs_init());
    7570          10 :   CHECK(declarations->AtForTest(3)->var()->location() ==
    7571             :         i::VariableLocation::MODULE);
    7572             : 
    7573           5 :   CHECK(declarations->AtForTest(4)->var()->raw_name()->IsOneByteEqualTo("goo"));
    7574          10 :   CHECK(declarations->AtForTest(4)->var()->mode() == i::VariableMode::kLet);
    7575           5 :   CHECK(!declarations->AtForTest(4)->var()->binding_needs_init());
    7576          10 :   CHECK(declarations->AtForTest(4)->var()->location() ==
    7577             :         i::VariableLocation::MODULE);
    7578             : 
    7579           5 :   CHECK(declarations->AtForTest(5)->var()->raw_name()->IsOneByteEqualTo("hoo"));
    7580          10 :   CHECK(declarations->AtForTest(5)->var()->mode() == i::VariableMode::kLet);
    7581           5 :   CHECK(declarations->AtForTest(5)->var()->binding_needs_init());
    7582          10 :   CHECK(declarations->AtForTest(5)->var()->location() ==
    7583             :         i::VariableLocation::MODULE);
    7584             : 
    7585           5 :   CHECK(declarations->AtForTest(6)->var()->raw_name()->IsOneByteEqualTo("joo"));
    7586          10 :   CHECK(declarations->AtForTest(6)->var()->mode() == i::VariableMode::kConst);
    7587           5 :   CHECK(declarations->AtForTest(6)->var()->binding_needs_init());
    7588          10 :   CHECK(declarations->AtForTest(6)->var()->location() ==
    7589             :         i::VariableLocation::MODULE);
    7590             : 
    7591           5 :   CHECK(declarations->AtForTest(7)->var()->raw_name()->IsOneByteEqualTo(
    7592             :       "*default*"));
    7593          10 :   CHECK(declarations->AtForTest(7)->var()->mode() == i::VariableMode::kConst);
    7594           5 :   CHECK(declarations->AtForTest(7)->var()->binding_needs_init());
    7595          10 :   CHECK(declarations->AtForTest(7)->var()->location() ==
    7596             :         i::VariableLocation::MODULE);
    7597             : 
    7598           5 :   CHECK(declarations->AtForTest(8)->var()->raw_name()->IsOneByteEqualTo(
    7599             :       "nonexport"));
    7600           5 :   CHECK(!declarations->AtForTest(8)->var()->binding_needs_init());
    7601          10 :   CHECK(declarations->AtForTest(8)->var()->location() ==
    7602             :         i::VariableLocation::LOCAL);
    7603             : 
    7604           5 :   CHECK(declarations->AtForTest(9)->var()->raw_name()->IsOneByteEqualTo("mm"));
    7605          10 :   CHECK(declarations->AtForTest(9)->var()->mode() == i::VariableMode::kConst);
    7606           5 :   CHECK(declarations->AtForTest(9)->var()->binding_needs_init());
    7607          10 :   CHECK(declarations->AtForTest(9)->var()->location() ==
    7608             :         i::VariableLocation::MODULE);
    7609             : 
    7610           5 :   CHECK(declarations->AtForTest(10)->var()->raw_name()->IsOneByteEqualTo("aa"));
    7611          10 :   CHECK(declarations->AtForTest(10)->var()->mode() == i::VariableMode::kConst);
    7612           5 :   CHECK(declarations->AtForTest(10)->var()->binding_needs_init());
    7613          10 :   CHECK(declarations->AtForTest(10)->var()->location() ==
    7614             :         i::VariableLocation::MODULE);
    7615             : 
    7616           5 :   CHECK(
    7617             :       declarations->AtForTest(11)->var()->raw_name()->IsOneByteEqualTo("loo"));
    7618          10 :   CHECK(declarations->AtForTest(11)->var()->mode() == i::VariableMode::kConst);
    7619           5 :   CHECK(!declarations->AtForTest(11)->var()->binding_needs_init());
    7620          10 :   CHECK(declarations->AtForTest(11)->var()->location() !=
    7621             :         i::VariableLocation::MODULE);
    7622             : 
    7623           5 :   CHECK(
    7624             :       declarations->AtForTest(12)->var()->raw_name()->IsOneByteEqualTo("foob"));
    7625          10 :   CHECK(declarations->AtForTest(12)->var()->mode() == i::VariableMode::kConst);
    7626           5 :   CHECK(!declarations->AtForTest(12)->var()->binding_needs_init());
    7627          10 :   CHECK(declarations->AtForTest(12)->var()->location() ==
    7628             :         i::VariableLocation::MODULE);
    7629             : 
    7630             :   i::ModuleDescriptor* descriptor = module_scope->module();
    7631           5 :   CHECK_NOT_NULL(descriptor);
    7632             : 
    7633           5 :   CHECK_EQ(5u, descriptor->module_requests().size());
    7634          35 :   for (const auto& elem : descriptor->module_requests()) {
    7635          25 :     if (elem.first->IsOneByteEqualTo("m.js")) {
    7636           5 :       CHECK_EQ(0, elem.second.index);
    7637           5 :       CHECK_EQ(51, elem.second.position);
    7638          20 :     } else if (elem.first->IsOneByteEqualTo("n.js")) {
    7639           5 :       CHECK_EQ(1, elem.second.index);
    7640           5 :       CHECK_EQ(72, elem.second.position);
    7641          15 :     } else if (elem.first->IsOneByteEqualTo("p.js")) {
    7642           5 :       CHECK_EQ(2, elem.second.index);
    7643           5 :       CHECK_EQ(123, elem.second.position);
    7644          10 :     } else if (elem.first->IsOneByteEqualTo("q.js")) {
    7645           5 :       CHECK_EQ(3, elem.second.index);
    7646           5 :       CHECK_EQ(249, elem.second.position);
    7647           5 :     } else if (elem.first->IsOneByteEqualTo("bar.js")) {
    7648           5 :       CHECK_EQ(4, elem.second.index);
    7649           5 :       CHECK_EQ(370, elem.second.position);
    7650             :     } else {
    7651           0 :       UNREACHABLE();
    7652             :     }
    7653             :   }
    7654             : 
    7655          10 :   CHECK_EQ(3, descriptor->special_exports().size());
    7656           5 :   CheckEntry(descriptor->special_exports().at(0), "b", nullptr, "a", 0);
    7657           5 :   CheckEntry(descriptor->special_exports().at(1), nullptr, nullptr, nullptr, 2);
    7658             :   CheckEntry(descriptor->special_exports().at(2), "bb", nullptr, "aa",
    7659           5 :              0);  // !!!
    7660             : 
    7661           5 :   CHECK_EQ(8u, descriptor->regular_exports().size());
    7662             :   entry = descriptor->regular_exports()
    7663          10 :               .find(declarations->AtForTest(3)->var()->raw_name())
    7664           5 :               ->second;
    7665           5 :   CheckEntry(entry, "foo", "foo", nullptr, -1);
    7666             :   entry = descriptor->regular_exports()
    7667          10 :               .find(declarations->AtForTest(4)->var()->raw_name())
    7668           5 :               ->second;
    7669           5 :   CheckEntry(entry, "goo", "goo", nullptr, -1);
    7670             :   entry = descriptor->regular_exports()
    7671          10 :               .find(declarations->AtForTest(5)->var()->raw_name())
    7672           5 :               ->second;
    7673           5 :   CheckEntry(entry, "hoo", "hoo", nullptr, -1);
    7674             :   entry = descriptor->regular_exports()
    7675          10 :               .find(declarations->AtForTest(6)->var()->raw_name())
    7676           5 :               ->second;
    7677           5 :   CheckEntry(entry, "joo", "joo", nullptr, -1);
    7678             :   entry = descriptor->regular_exports()
    7679          10 :               .find(declarations->AtForTest(7)->var()->raw_name())
    7680           5 :               ->second;
    7681           5 :   CheckEntry(entry, "default", "*default*", nullptr, -1);
    7682             :   entry = descriptor->regular_exports()
    7683          10 :               .find(declarations->AtForTest(12)->var()->raw_name())
    7684           5 :               ->second;
    7685           5 :   CheckEntry(entry, "foob", "foob", nullptr, -1);
    7686             :   // TODO(neis): The next lines are terrible. Find a better way.
    7687           5 :   auto name_x = declarations->AtForTest(0)->var()->raw_name();
    7688           5 :   CHECK_EQ(2u, descriptor->regular_exports().count(name_x));
    7689             :   auto it = descriptor->regular_exports().equal_range(name_x).first;
    7690           5 :   entry = it->second;
    7691           5 :   if (entry->export_name->IsOneByteEqualTo("y")) {
    7692           5 :     CheckEntry(entry, "y", "x", nullptr, -1);
    7693           5 :     entry = (++it)->second;
    7694           5 :     CheckEntry(entry, "x", "x", nullptr, -1);
    7695             :   } else {
    7696           0 :     CheckEntry(entry, "x", "x", nullptr, -1);
    7697           0 :     entry = (++it)->second;
    7698           0 :     CheckEntry(entry, "y", "x", nullptr, -1);
    7699             :   }
    7700             : 
    7701          10 :   CHECK_EQ(2, descriptor->namespace_imports().size());
    7702           5 :   CheckEntry(descriptor->namespace_imports().at(0), nullptr, "loo", nullptr, 4);
    7703             :   CheckEntry(descriptor->namespace_imports().at(1), nullptr, "foob", nullptr,
    7704           5 :              4);
    7705             : 
    7706           5 :   CHECK_EQ(4u, descriptor->regular_imports().size());
    7707             :   entry = descriptor->regular_imports()
    7708          10 :               .find(declarations->AtForTest(1)->var()->raw_name())
    7709           5 :               ->second;
    7710           5 :   CheckEntry(entry, nullptr, "z", "q", 0);
    7711             :   entry = descriptor->regular_imports()
    7712          10 :               .find(declarations->AtForTest(2)->var()->raw_name())
    7713           5 :               ->second;
    7714           5 :   CheckEntry(entry, nullptr, "n", "default", 1);
    7715             :   entry = descriptor->regular_imports()
    7716          10 :               .find(declarations->AtForTest(9)->var()->raw_name())
    7717           5 :               ->second;
    7718           5 :   CheckEntry(entry, nullptr, "mm", "m", 0);
    7719             :   entry = descriptor->regular_imports()
    7720          10 :               .find(declarations->AtForTest(10)->var()->raw_name())
    7721           5 :               ->second;
    7722          10 :   CheckEntry(entry, nullptr, "aa", "aa", 0);
    7723           5 : }
    7724             : 
    7725             : 
    7726       25880 : TEST(DuplicateProtoError) {
    7727             :   const char* context_data[][2] = {
    7728           5 :       {"({", "});"}, {"'use strict'; ({", "});"}, {nullptr, nullptr}};
    7729             :   const char* error_data[] = {"__proto__: {}, __proto__: {}",
    7730             :                               "__proto__: {}, \"__proto__\": {}",
    7731             :                               "__proto__: {}, \"__\x70roto__\": {}",
    7732           5 :                               "__proto__: {}, a: 1, __proto__: {}", nullptr};
    7733             : 
    7734           5 :   RunParserSyncTest(context_data, error_data, kError);
    7735           5 : }
    7736             : 
    7737             : 
    7738       25880 : TEST(DuplicateProtoNoError) {
    7739             :   const char* context_data[][2] = {
    7740           5 :       {"({", "});"}, {"'use strict'; ({", "});"}, {nullptr, nullptr}};
    7741             :   const char* error_data[] = {
    7742             :       "__proto__: {}, ['__proto__']: {}",  "__proto__: {}, __proto__() {}",
    7743             :       "__proto__: {}, get __proto__() {}", "__proto__: {}, set __proto__(v) {}",
    7744           5 :       "__proto__: {}, __proto__",          nullptr};
    7745             : 
    7746           5 :   RunParserSyncTest(context_data, error_data, kSuccess);
    7747           5 : }
    7748             : 
    7749             : 
    7750       25880 : TEST(DeclarationsError) {
    7751             :   const char* context_data[][2] = {{"'use strict'; if (true)", ""},
    7752             :                                    {"'use strict'; if (false) {} else", ""},
    7753             :                                    {"'use strict'; while (false)", ""},
    7754             :                                    {"'use strict'; for (;;)", ""},
    7755             :                                    {"'use strict'; for (x in y)", ""},
    7756             :                                    {"'use strict'; do ", " while (false)"},
    7757           5 :                                    {nullptr, nullptr}};
    7758             : 
    7759             :   const char* statement_data[] = {"let x = 1;", "const x = 1;", "class C {}",
    7760           5 :                                   nullptr};
    7761             : 
    7762           5 :   RunParserSyncTest(context_data, statement_data, kError);
    7763           5 : }
    7764             : 
    7765             : 
    7766          20 : void TestLanguageMode(const char* source,
    7767             :                       i::LanguageMode expected_language_mode) {
    7768             :   i::Isolate* isolate = CcTest::i_isolate();
    7769             :   i::Factory* factory = isolate->factory();
    7770          20 :   v8::HandleScope handles(CcTest::isolate());
    7771          20 :   v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
    7772             :   v8::Context::Scope context_scope(context);
    7773          20 :   isolate->stack_guard()->SetStackLimit(i::GetCurrentStackPosition() -
    7774          20 :                                         128 * 1024);
    7775             : 
    7776             :   i::Handle<i::Script> script =
    7777          20 :       factory->NewScript(factory->NewStringFromAsciiChecked(source));
    7778          40 :   i::ParseInfo info(isolate, script);
    7779          20 :   i::parsing::ParseProgram(&info, isolate);
    7780          20 :   CHECK_NOT_NULL(info.literal());
    7781          40 :   CHECK_EQ(expected_language_mode, info.literal()->language_mode());
    7782          20 : }
    7783             : 
    7784             : 
    7785       25880 : TEST(LanguageModeDirectives) {
    7786           5 :   TestLanguageMode("\"use nothing\"", i::LanguageMode::kSloppy);
    7787           5 :   TestLanguageMode("\"use strict\"", i::LanguageMode::kStrict);
    7788             : 
    7789           5 :   TestLanguageMode("var x = 1; \"use strict\"", i::LanguageMode::kSloppy);
    7790             : 
    7791             :   TestLanguageMode("\"use some future directive\"; \"use strict\";",
    7792           5 :                    i::LanguageMode::kStrict);
    7793           5 : }
    7794             : 
    7795             : 
    7796       25880 : TEST(PropertyNameEvalArguments) {
    7797           5 :   const char* context_data[][2] = {{"'use strict';", ""}, {nullptr, nullptr}};
    7798             : 
    7799             :   const char* statement_data[] = {"({eval: 1})",
    7800             :                                   "({arguments: 1})",
    7801             :                                   "({eval() {}})",
    7802             :                                   "({arguments() {}})",
    7803             :                                   "({*eval() {}})",
    7804             :                                   "({*arguments() {}})",
    7805             :                                   "({get eval() {}})",
    7806             :                                   "({get arguments() {}})",
    7807             :                                   "({set eval(_) {}})",
    7808             :                                   "({set arguments(_) {}})",
    7809             : 
    7810             :                                   "class C {eval() {}}",
    7811             :                                   "class C {arguments() {}}",
    7812             :                                   "class C {*eval() {}}",
    7813             :                                   "class C {*arguments() {}}",
    7814             :                                   "class C {get eval() {}}",
    7815             :                                   "class C {get arguments() {}}",
    7816             :                                   "class C {set eval(_) {}}",
    7817             :                                   "class C {set arguments(_) {}}",
    7818             : 
    7819             :                                   "class C {static eval() {}}",
    7820             :                                   "class C {static arguments() {}}",
    7821             :                                   "class C {static *eval() {}}",
    7822             :                                   "class C {static *arguments() {}}",
    7823             :                                   "class C {static get eval() {}}",
    7824             :                                   "class C {static get arguments() {}}",
    7825             :                                   "class C {static set eval(_) {}}",
    7826             :                                   "class C {static set arguments(_) {}}",
    7827             : 
    7828           5 :                                   nullptr};
    7829             : 
    7830           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
    7831           5 : }
    7832             : 
    7833             : 
    7834       25880 : TEST(FunctionLiteralDuplicateParameters) {
    7835             :   const char* strict_context_data[][2] = {
    7836             :       {"'use strict';(function(", "){})();"},
    7837             :       {"(function(", ") { 'use strict'; })();"},
    7838             :       {"'use strict'; function fn(", ") {}; fn();"},
    7839             :       {"function fn(", ") { 'use strict'; }; fn();"},
    7840           5 :       {nullptr, nullptr}};
    7841             : 
    7842             :   const char* sloppy_context_data[][2] = {{"(function(", "){})();"},
    7843             :                                           {"(function(", ") {})();"},
    7844             :                                           {"function fn(", ") {}; fn();"},
    7845             :                                           {"function fn(", ") {}; fn();"},
    7846           5 :                                           {nullptr, nullptr}};
    7847             : 
    7848             :   const char* data[] = {
    7849             :       "a, a",
    7850             :       "a, a, a",
    7851             :       "b, a, a",
    7852             :       "a, b, c, c",
    7853             :       "a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, w",
    7854           5 :       nullptr};
    7855             : 
    7856           5 :   RunParserSyncTest(strict_context_data, data, kError);
    7857           5 :   RunParserSyncTest(sloppy_context_data, data, kSuccess);
    7858           5 : }
    7859             : 
    7860             : 
    7861       25880 : TEST(ArrowFunctionASIErrors) {
    7862             :   const char* context_data[][2] = {
    7863           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    7864             : 
    7865             :   const char* data[] = {"(a\n=> a)(1)",
    7866             :                         "(a/*\n*/=> a)(1)",
    7867             :                         "((a)\n=> a)(1)",
    7868             :                         "((a)/*\n*/=> a)(1)",
    7869             :                         "((a, b)\n=> a + b)(1, 2)",
    7870             :                         "((a, b)/*\n*/=> a + b)(1, 2)",
    7871           5 :                         nullptr};
    7872           5 :   RunParserSyncTest(context_data, data, kError);
    7873           5 : }
    7874             : 
    7875       25880 : TEST(ObjectSpreadPositiveTests) {
    7876             :   // clang-format off
    7877             :   const char* context_data[][2] = {
    7878             :     {"x = ", ""},
    7879             :     {"'use strict'; x = ", ""},
    7880           5 :     {nullptr, nullptr}};
    7881             : 
    7882             :   // clang-format off
    7883             :   const char* data[] = {
    7884             :     "{ ...y }",
    7885             :     "{ a: 1, ...y }",
    7886             :     "{ b: 1, ...y }",
    7887             :     "{ y, ...y}",
    7888             :     "{ ...z = y}",
    7889             :     "{ ...y, y }",
    7890             :     "{ ...y, ...y}",
    7891             :     "{ a: 1, ...y, b: 1}",
    7892             :     "{ ...y, b: 1}",
    7893             :     "{ ...1}",
    7894             :     "{ ...null}",
    7895             :     "{ ...undefined}",
    7896             :     "{ ...1 in {}}",
    7897             :     "{ ...[]}",
    7898             :     "{ ...async function() { }}",
    7899             :     "{ ...async () => { }}",
    7900             :     "{ ...new Foo()}",
    7901           5 :     nullptr};
    7902             :   // clang-format on
    7903             : 
    7904           5 :   RunParserSyncTest(context_data, data, kSuccess);
    7905           5 : }
    7906             : 
    7907       25880 : TEST(ObjectSpreadNegativeTests) {
    7908             :   const char* context_data[][2] = {
    7909           5 :       {"x = ", ""}, {"'use strict'; x = ", ""}, {nullptr, nullptr}};
    7910             : 
    7911             :   // clang-format off
    7912             :   const char* data[] = {
    7913             :     "{ ...var z = y}",
    7914             :     "{ ...var}",
    7915             :     "{ ...foo bar}",
    7916             :     "{* ...foo}",
    7917             :     "{get ...foo}",
    7918             :     "{set ...foo}",
    7919             :     "{async ...foo}",
    7920           5 :     nullptr};
    7921             : 
    7922           5 :   RunParserSyncTest(context_data, data, kError);
    7923           5 : }
    7924             : 
    7925       25880 : TEST(TemplateEscapesPositiveTests) {
    7926             :   // clang-format off
    7927             :   const char* context_data[][2] = {
    7928             :     {"", ""},
    7929             :     {"'use strict';", ""},
    7930           5 :     {nullptr, nullptr}};
    7931             : 
    7932             :   // clang-format off
    7933             :   const char* data[] = {
    7934             :     "tag`\\08`",
    7935             :     "tag`\\01`",
    7936             :     "tag`\\01${0}right`",
    7937             :     "tag`left${0}\\01`",
    7938             :     "tag`left${0}\\01${1}right`",
    7939             :     "tag`\\1`",
    7940             :     "tag`\\1${0}right`",
    7941             :     "tag`left${0}\\1`",
    7942             :     "tag`left${0}\\1${1}right`",
    7943             :     "tag`\\xg`",
    7944             :     "tag`\\xg${0}right`",
    7945             :     "tag`left${0}\\xg`",
    7946             :     "tag`left${0}\\xg${1}right`",
    7947             :     "tag`\\xAg`",
    7948             :     "tag`\\xAg${0}right`",
    7949             :     "tag`left${0}\\xAg`",
    7950             :     "tag`left${0}\\xAg${1}right`",
    7951             :     "tag`\\u0`",
    7952             :     "tag`\\u0${0}right`",
    7953             :     "tag`left${0}\\u0`",
    7954             :     "tag`left${0}\\u0${1}right`",
    7955             :     "tag`\\u0g`",
    7956             :     "tag`\\u0g${0}right`",
    7957             :     "tag`left${0}\\u0g`",
    7958             :     "tag`left${0}\\u0g${1}right`",
    7959             :     "tag`\\u00g`",
    7960             :     "tag`\\u00g${0}right`",
    7961             :     "tag`left${0}\\u00g`",
    7962             :     "tag`left${0}\\u00g${1}right`",
    7963             :     "tag`\\u000g`",
    7964             :     "tag`\\u000g${0}right`",
    7965             :     "tag`left${0}\\u000g`",
    7966             :     "tag`left${0}\\u000g${1}right`",
    7967             :     "tag`\\u{}`",
    7968             :     "tag`\\u{}${0}right`",
    7969             :     "tag`left${0}\\u{}`",
    7970             :     "tag`left${0}\\u{}${1}right`",
    7971             :     "tag`\\u{-0}`",
    7972             :     "tag`\\u{-0}${0}right`",
    7973             :     "tag`left${0}\\u{-0}`",
    7974             :     "tag`left${0}\\u{-0}${1}right`",
    7975             :     "tag`\\u{g}`",
    7976             :     "tag`\\u{g}${0}right`",
    7977             :     "tag`left${0}\\u{g}`",
    7978             :     "tag`left${0}\\u{g}${1}right`",
    7979             :     "tag`\\u{0`",
    7980             :     "tag`\\u{0${0}right`",
    7981             :     "tag`left${0}\\u{0`",
    7982             :     "tag`left${0}\\u{0${1}right`",
    7983             :     "tag`\\u{\\u{0}`",
    7984             :     "tag`\\u{\\u{0}${0}right`",
    7985             :     "tag`left${0}\\u{\\u{0}`",
    7986             :     "tag`left${0}\\u{\\u{0}${1}right`",
    7987             :     "tag`\\u{110000}`",
    7988             :     "tag`\\u{110000}${0}right`",
    7989             :     "tag`left${0}\\u{110000}`",
    7990             :     "tag`left${0}\\u{110000}${1}right`",
    7991             :     "tag` ${tag`\\u`}`",
    7992             :     "tag` ``\\u`",
    7993             :     "tag`\\u`` `",
    7994             :     "tag`\\u``\\u`",
    7995             :     "` ${tag`\\u`}`",
    7996             :     "` ``\\u`",
    7997           5 :     nullptr};
    7998             :   // clang-format on
    7999             : 
    8000           5 :   RunParserSyncTest(context_data, data, kSuccess);
    8001           5 : }
    8002             : 
    8003       25880 : TEST(TemplateEscapesNegativeTests) {
    8004             :   // clang-format off
    8005             :   const char* context_data[][2] = {
    8006             :     {"", ""},
    8007             :     {"'use strict';", ""},
    8008           5 :     {nullptr, nullptr}};
    8009             : 
    8010             :   // clang-format off
    8011             :   const char* data[] = {
    8012             :     "`\\08`",
    8013             :     "`\\01`",
    8014             :     "`\\01${0}right`",
    8015             :     "`left${0}\\01`",
    8016             :     "`left${0}\\01${1}right`",
    8017             :     "`\\1`",
    8018             :     "`\\1${0}right`",
    8019             :     "`left${0}\\1`",
    8020             :     "`left${0}\\1${1}right`",
    8021             :     "`\\xg`",
    8022             :     "`\\xg${0}right`",
    8023             :     "`left${0}\\xg`",
    8024             :     "`left${0}\\xg${1}right`",
    8025             :     "`\\xAg`",
    8026             :     "`\\xAg${0}right`",
    8027             :     "`left${0}\\xAg`",
    8028             :     "`left${0}\\xAg${1}right`",
    8029             :     "`\\u0`",
    8030             :     "`\\u0${0}right`",
    8031             :     "`left${0}\\u0`",
    8032             :     "`left${0}\\u0${1}right`",
    8033             :     "`\\u0g`",
    8034             :     "`\\u0g${0}right`",
    8035             :     "`left${0}\\u0g`",
    8036             :     "`left${0}\\u0g${1}right`",
    8037             :     "`\\u00g`",
    8038             :     "`\\u00g${0}right`",
    8039             :     "`left${0}\\u00g`",
    8040             :     "`left${0}\\u00g${1}right`",
    8041             :     "`\\u000g`",
    8042             :     "`\\u000g${0}right`",
    8043             :     "`left${0}\\u000g`",
    8044             :     "`left${0}\\u000g${1}right`",
    8045             :     "`\\u{}`",
    8046             :     "`\\u{}${0}right`",
    8047             :     "`left${0}\\u{}`",
    8048             :     "`left${0}\\u{}${1}right`",
    8049             :     "`\\u{-0}`",
    8050             :     "`\\u{-0}${0}right`",
    8051             :     "`left${0}\\u{-0}`",
    8052             :     "`left${0}\\u{-0}${1}right`",
    8053             :     "`\\u{g}`",
    8054             :     "`\\u{g}${0}right`",
    8055             :     "`left${0}\\u{g}`",
    8056             :     "`left${0}\\u{g}${1}right`",
    8057             :     "`\\u{0`",
    8058             :     "`\\u{0${0}right`",
    8059             :     "`left${0}\\u{0`",
    8060             :     "`left${0}\\u{0${1}right`",
    8061             :     "`\\u{\\u{0}`",
    8062             :     "`\\u{\\u{0}${0}right`",
    8063             :     "`left${0}\\u{\\u{0}`",
    8064             :     "`left${0}\\u{\\u{0}${1}right`",
    8065             :     "`\\u{110000}`",
    8066             :     "`\\u{110000}${0}right`",
    8067             :     "`left${0}\\u{110000}`",
    8068             :     "`left${0}\\u{110000}${1}right`",
    8069             :     "`\\1``\\2`",
    8070             :     "tag` ${`\\u`}`",
    8071             :     "`\\u```",
    8072           5 :     nullptr};
    8073             :   // clang-format on
    8074             : 
    8075           5 :   RunParserSyncTest(context_data, data, kError);
    8076           5 : }
    8077             : 
    8078       25880 : TEST(DestructuringPositiveTests) {
    8079             :   const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
    8080             :                                    {"var ", " = {};"},
    8081             :                                    {"'use strict'; const ", " = {};"},
    8082             :                                    {"function f(", ") {}"},
    8083             :                                    {"function f(argument1, ", ") {}"},
    8084             :                                    {"var f = (", ") => {};"},
    8085             :                                    {"var f = (argument1,", ") => {};"},
    8086             :                                    {"try {} catch(", ") {}"},
    8087           5 :                                    {nullptr, nullptr}};
    8088             : 
    8089             :   // clang-format off
    8090             :   const char* data[] = {
    8091             :     "a",
    8092             :     "{ x : y }",
    8093             :     "{ x : y = 1 }",
    8094             :     "{ get, set }",
    8095             :     "{ get = 1, set = 2 }",
    8096             :     "[a]",
    8097             :     "[a = 1]",
    8098             :     "[a,b,c]",
    8099             :     "[a, b = 42, c]",
    8100             :     "{ x : x, y : y }",
    8101             :     "{ x : x = 1, y : y }",
    8102             :     "{ x : x, y : y = 42 }",
    8103             :     "[]",
    8104             :     "{}",
    8105             :     "[{x:x, y:y}, [a,b,c]]",
    8106             :     "[{x:x = 1, y:y = 2}, [a = 3, b = 4, c = 5]]",
    8107             :     "{x}",
    8108             :     "{x, y}",
    8109             :     "{x = 42, y = 15}",
    8110             :     "[a,,b]",
    8111             :     "{42 : x}",
    8112             :     "{42 : x = 42}",
    8113             :     "{42e-2 : x}",
    8114             :     "{42e-2 : x = 42}",
    8115             :     "{x : y, x : z}",
    8116             :     "{'hi' : x}",
    8117             :     "{'hi' : x = 42}",
    8118             :     "{var: x}",
    8119             :     "{var: x = 42}",
    8120             :     "{[x] : z}",
    8121             :     "{[1+1] : z}",
    8122             :     "{[foo()] : z}",
    8123             :     "{}",
    8124             :     "[...rest]",
    8125             :     "[a,b,...rest]",
    8126             :     "[a,,...rest]",
    8127             :     "{ __proto__: x, __proto__: y}",
    8128             :     "{arguments: x}",
    8129             :     "{eval: x}",
    8130             :     "{ x : y, ...z }",
    8131             :     "{ x : y = 1, ...z }",
    8132             :     "{ x : x, y : y, ...z }",
    8133             :     "{ x : x = 1, y : y, ...z }",
    8134             :     "{ x : x, y : y = 42, ...z }",
    8135             :     "[{x:x, y:y, ...z}, [a,b,c]]",
    8136             :     "[{x:x = 1, y:y = 2, ...z}, [a = 3, b = 4, c = 5]]",
    8137             :     "{...x}",
    8138             :     "{x, ...y}",
    8139             :     "{x = 42, y = 15, ...z}",
    8140             :     "{42 : x = 42, ...y}",
    8141             :     "{'hi' : x, ...z}",
    8142             :     "{'hi' : x = 42, ...z}",
    8143             :     "{var: x = 42, ...z}",
    8144             :     "{[x] : z, ...y}",
    8145             :     "{[1+1] : z, ...x}",
    8146             :     "{arguments: x, ...z}",
    8147             :     "{ __proto__: x, __proto__: y, ...z}",
    8148             :     nullptr
    8149           5 :   };
    8150             : 
    8151             :   // clang-format on
    8152           5 :   RunParserSyncTest(context_data, data, kSuccess);
    8153             : 
    8154             :   // v8:5201
    8155             :   {
    8156             :     // clang-format off
    8157             :     const char* sloppy_context_data[][2] = {
    8158             :       {"var ", " = {};"},
    8159             :       {"function f(", ") {}"},
    8160             :       {"function f(argument1, ", ") {}"},
    8161             :       {"var f = (", ") => {};"},
    8162             :       {"var f = (argument1,", ") => {};"},
    8163             :       {"try {} catch(", ") {}"},
    8164             :       {nullptr, nullptr}
    8165           5 :     };
    8166             : 
    8167             :     const char* data[] = {
    8168             :       "{arguments}",
    8169             :       "{eval}",
    8170             :       "{x: arguments}",
    8171             :       "{x: eval}",
    8172             :       "{arguments = false}",
    8173             :       "{eval = false}",
    8174             :       "{...arguments}",
    8175             :       "{...eval}",
    8176             :       nullptr
    8177           5 :     };
    8178             :     // clang-format on
    8179           5 :     RunParserSyncTest(sloppy_context_data, data, kSuccess);
    8180             :   }
    8181           5 : }
    8182             : 
    8183             : 
    8184       25880 : TEST(DestructuringNegativeTests) {
    8185             :   {  // All modes.
    8186             :     const char* context_data[][2] = {{"'use strict'; let ", " = {};"},
    8187             :                                      {"var ", " = {};"},
    8188             :                                      {"'use strict'; const ", " = {};"},
    8189             :                                      {"function f(", ") {}"},
    8190             :                                      {"function f(argument1, ", ") {}"},
    8191             :                                      {"var f = (", ") => {};"},
    8192             :                                      {"var f = ", " => {};"},
    8193             :                                      {"var f = (argument1,", ") => {};"},
    8194             :                                      {"try {} catch(", ") {}"},
    8195           5 :                                      {nullptr, nullptr}};
    8196             : 
    8197             :     // clang-format off
    8198             :     const char* data[] = {
    8199             :         "a++",
    8200             :         "++a",
    8201             :         "delete a",
    8202             :         "void a",
    8203             :         "typeof a",
    8204             :         "--a",
    8205             :         "+a",
    8206             :         "-a",
    8207             :         "~a",
    8208             :         "!a",
    8209             :         "{ x : y++ }",
    8210             :         "[a++]",
    8211             :         "(x => y)",
    8212             :         "(async x => y)",
    8213             :         "((x, z) => y)",
    8214             :         "(async (x, z) => y)",
    8215             :         "a[i]", "a()",
    8216             :         "a.b",
    8217             :         "new a",
    8218             :         "a + a",
    8219             :         "a - 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             :         "function a() {}",
    8229             :         "function* a() {}",
    8230             :         "async function a() {}",
    8231             :         "a`bcd`",
    8232             :         "this",
    8233             :         "null",
    8234             :         "true",
    8235             :         "false",
    8236             :         "1",
    8237             :         "'abc'",
    8238             :         "/abc/",
    8239             :         "`abc`",
    8240             :         "class {}",
    8241             :         "{+2 : x}",
    8242             :         "{-2 : x}",
    8243             :         "var",
    8244             :         "[var]",
    8245             :         "{x : {y : var}}",
    8246             :         "{x : x = a+}",
    8247             :         "{x : x = (a+)}",
    8248             :         "{x : x += a}",
    8249             :         "{m() {} = 0}",
    8250             :         "{[1+1]}",
    8251             :         "[...rest, x]",
    8252             :         "[a,b,...rest, x]",
    8253             :         "[a,,...rest, x]",
    8254             :         "[...rest,]",
    8255             :         "[a,b,...rest,]",
    8256             :         "[a,,...rest,]",
    8257             :         "[...rest,...rest1]",
    8258             :         "[a,b,...rest,...rest1]",
    8259             :         "[a,,..rest,...rest1]",
    8260             :         "[x, y, ...z = 1]",
    8261             :         "[...z = 1]",
    8262             :         "[x, y, ...[z] = [1]]",
    8263             :         "[...[z] = [1]]",
    8264             :         "{ x : 3 }",
    8265             :         "{ x : 'foo' }",
    8266             :         "{ x : /foo/ }",
    8267             :         "{ x : `foo` }",
    8268             :         "{ get a() {} }",
    8269             :         "{ set a() {} }",
    8270             :         "{ method() {} }",
    8271             :         "{ *method() {} }",
    8272             :         "...a++",
    8273             :         "...++a",
    8274             :         "...typeof a",
    8275             :         "...[a++]",
    8276             :         "...(x => y)",
    8277             :         "{ ...x, }",
    8278             :         "{ ...x, y }",
    8279             :         "{ y, ...x, y }",
    8280             :         "{ ...x, ...y }",
    8281             :         "{ ...x, ...x }",
    8282             :         "{ ...x, ...x = {} }",
    8283             :         "{ ...x, ...x = ...x }",
    8284             :         "{ ...x, ...x = ...{ x } }",
    8285             :         "{ ,, ...x }",
    8286             :         "{ ...get a() {} }",
    8287             :         "{ ...set a() {} }",
    8288             :         "{ ...method() {} }",
    8289             :         "{ ...function() {} }",
    8290             :         "{ ...*method() {} }",
    8291             :         "{...{x} }",
    8292             :         "{...[x] }",
    8293             :         "{...{ x = 5 } }",
    8294             :         "{...[ x = 5 ] }",
    8295             :         "{...x.f }",
    8296             :         "{...x[0] }",
    8297             :         "async function* a() {}",
    8298             :         nullptr
    8299           5 :     };
    8300             : 
    8301             :     // clang-format on
    8302           5 :     RunParserSyncTest(context_data, data, kError);
    8303             :   }
    8304             : 
    8305             :   {  // All modes.
    8306             :     const char* context_data[][2] = {
    8307             :         {"'use strict'; let ", " = {};"},    {"var ", " = {};"},
    8308             :         {"'use strict'; const ", " = {};"},  {"function f(", ") {}"},
    8309             :         {"function f(argument1, ", ") {}"},  {"var f = (", ") => {};"},
    8310           5 :         {"var f = (argument1,", ") => {};"}, {nullptr, nullptr}};
    8311             : 
    8312             :     // clang-format off
    8313             :     const char* data[] = {
    8314             :         "x => x",
    8315             :         "() => x",
    8316           5 :         nullptr};
    8317             :     // clang-format on
    8318           5 :     RunParserSyncTest(context_data, data, kError);
    8319             :   }
    8320             : 
    8321             :   {  // Strict mode.
    8322             :     const char* context_data[][2] = {
    8323             :         {"'use strict'; var ", " = {};"},
    8324             :         {"'use strict'; let ", " = {};"},
    8325             :         {"'use strict'; const ", " = {};"},
    8326             :         {"'use strict'; function f(", ") {}"},
    8327             :         {"'use strict'; function f(argument1, ", ") {}"},
    8328           5 :         {nullptr, nullptr}};
    8329             : 
    8330             :     // clang-format off
    8331             :     const char* data[] = {
    8332             :       "[arguments]",
    8333             :       "[eval]",
    8334             :       "{ a : arguments }",
    8335             :       "{ a : eval }",
    8336             :       "[public]",
    8337             :       "{ x : private }",
    8338             :       "{ x : arguments }",
    8339             :       "{ x : eval }",
    8340             :       "{ arguments }",
    8341             :       "{ eval }",
    8342             :       "{ arguments = false }"
    8343             :       "{ eval = false }",
    8344             :       "{ ...eval }",
    8345             :       "{ ...arguments }",
    8346           5 :       nullptr};
    8347             : 
    8348             :     // clang-format on
    8349           5 :     RunParserSyncTest(context_data, data, kError);
    8350             :   }
    8351             : 
    8352             :   {  // 'yield' in generators.
    8353             :     const char* context_data[][2] = {
    8354             :         {"function*() { var ", " = {};"},
    8355             :         {"function*() { 'use strict'; let ", " = {};"},
    8356             :         {"function*() { 'use strict'; const ", " = {};"},
    8357           5 :         {nullptr, nullptr}};
    8358             : 
    8359             :     // clang-format off
    8360             :     const char* data[] = {
    8361             :       "yield",
    8362             :       "[yield]",
    8363             :       "{ x : yield }",
    8364           5 :       nullptr};
    8365             :     // clang-format on
    8366           5 :     RunParserSyncTest(context_data, data, kError);
    8367             :   }
    8368             : 
    8369             :   { // Declaration-specific errors
    8370             :     const char* context_data[][2] = {{"'use strict'; var ", ""},
    8371             :                                      {"'use strict'; let ", ""},
    8372             :                                      {"'use strict'; const ", ""},
    8373             :                                      {"'use strict'; for (var ", ";;) {}"},
    8374             :                                      {"'use strict'; for (let ", ";;) {}"},
    8375             :                                      {"'use strict'; for (const ", ";;) {}"},
    8376             :                                      {"var ", ""},
    8377             :                                      {"let ", ""},
    8378             :                                      {"const ", ""},
    8379             :                                      {"for (var ", ";;) {}"},
    8380             :                                      {"for (let ", ";;) {}"},
    8381             :                                      {"for (const ", ";;) {}"},
    8382           5 :                                      {nullptr, nullptr}};
    8383             : 
    8384             :     // clang-format off
    8385             :     const char* data[] = {
    8386             :       "{ a }",
    8387             :       "[ a ]",
    8388             :       "{ ...a }",
    8389             :       nullptr
    8390           5 :     };
    8391             :     // clang-format on
    8392           5 :     RunParserSyncTest(context_data, data, kError);
    8393             :   }
    8394           5 : }
    8395             : 
    8396       25880 : TEST(ObjectRestNegativeTestSlow) {
    8397             :   // clang-format off
    8398             :   const char* context_data[][2] = {
    8399             :     {"var { ", " } = { a: 1};"},
    8400             :     { nullptr, nullptr }
    8401           5 :   };
    8402             : 
    8403             :   using v8::internal::Code;
    8404             :   std::string statement;
    8405      327675 :   for (int i = 0; i < Code::kMaxArguments; ++i) {
    8406      983010 :     statement += std::to_string(i) + " : " + "x, ";
    8407             :   }
    8408             :   statement += "...y";
    8409             : 
    8410             :   const char* statement_data[] = {
    8411             :     statement.c_str(),
    8412             :     nullptr
    8413          10 :   };
    8414             : 
    8415             :   // clang-format on
    8416             :   // The test is quite slow, so run it with a reduced set of flags.
    8417             :   static const ParserFlag flags[] = {kAllowLazy};
    8418             :   RunParserSyncTest(context_data, statement_data, kError, nullptr, 0, flags,
    8419           5 :                     arraysize(flags));
    8420           5 : }
    8421             : 
    8422       25880 : TEST(DestructuringAssignmentPositiveTests) {
    8423             :   const char* context_data[][2] = {
    8424             :       {"'use strict'; let x, y, z; (", " = {});"},
    8425             :       {"var x, y, z; (", " = {});"},
    8426             :       {"'use strict'; let x, y, z; for (x in ", " = {});"},
    8427             :       {"'use strict'; let x, y, z; for (x of ", " = {});"},
    8428             :       {"var x, y, z; for (x in ", " = {});"},
    8429             :       {"var x, y, z; for (x of ", " = {});"},
    8430             :       {"var x, y, z; for (", " in {});"},
    8431             :       {"var x, y, z; for (", " of {});"},
    8432             :       {"'use strict'; var x, y, z; for (", " in {});"},
    8433             :       {"'use strict'; var x, y, z; for (", " of {});"},
    8434             :       {"var x, y, z; m(['a']) ? ", " = {} : rhs"},
    8435             :       {"var x, y, z; m(['b']) ? lhs : ", " = {}"},
    8436             :       {"'use strict'; var x, y, z; m(['a']) ? ", " = {} : rhs"},
    8437             :       {"'use strict'; var x, y, z; m(['b']) ? lhs : ", " = {}"},
    8438           5 :       {nullptr, nullptr}};
    8439             : 
    8440             :   const char* mixed_assignments_context_data[][2] = {
    8441             :       {"'use strict'; let x, y, z; (", " = z = {});"},
    8442             :       {"var x, y, z; (", " = z = {});"},
    8443             :       {"'use strict'; let x, y, z; (x = ", " = z = {});"},
    8444             :       {"var x, y, z; (x = ", " = z = {});"},
    8445             :       {"'use strict'; let x, y, z; for (x in ", " = z = {});"},
    8446             :       {"'use strict'; let x, y, z; for (x in x = ", " = z = {});"},
    8447             :       {"'use strict'; let x, y, z; for (x of ", " = z = {});"},
    8448             :       {"'use strict'; let x, y, z; for (x of x = ", " = z = {});"},
    8449             :       {"var x, y, z; for (x in ", " = z = {});"},
    8450             :       {"var x, y, z; for (x in x = ", " = z = {});"},
    8451             :       {"var x, y, z; for (x of ", " = z = {});"},
    8452             :       {"var x, y, z; for (x of x = ", " = z = {});"},
    8453           5 :       {nullptr, nullptr}};
    8454             : 
    8455             :   // clang-format off
    8456             :   const char* data[] = {
    8457             :     "x",
    8458             : 
    8459             :     "{ x : y }",
    8460             :     "{ x : foo().y }",
    8461             :     "{ x : foo()[y] }",
    8462             :     "{ x : y.z }",
    8463             :     "{ x : y[z] }",
    8464             :     "{ x : { y } }",
    8465             :     "{ x : { foo: y } }",
    8466             :     "{ x : { foo: foo().y } }",
    8467             :     "{ x : { foo: foo()[y] } }",
    8468             :     "{ x : { foo: y.z } }",
    8469             :     "{ x : { foo: y[z] } }",
    8470             :     "{ x : [ y ] }",
    8471             :     "{ x : [ foo().y ] }",
    8472             :     "{ x : [ foo()[y] ] }",
    8473             :     "{ x : [ y.z ] }",
    8474             :     "{ x : [ y[z] ] }",
    8475             : 
    8476             :     "{ x : y = 10 }",
    8477             :     "{ x : foo().y = 10 }",
    8478             :     "{ x : foo()[y] = 10 }",
    8479             :     "{ x : y.z = 10 }",
    8480             :     "{ x : y[z] = 10 }",
    8481             :     "{ x : { y = 10 } = {} }",
    8482             :     "{ x : { foo: y = 10 } = {} }",
    8483             :     "{ x : { foo: foo().y = 10 } = {} }",
    8484             :     "{ x : { foo: foo()[y] = 10 } = {} }",
    8485             :     "{ x : { foo: y.z = 10 } = {} }",
    8486             :     "{ x : { foo: y[z] = 10 } = {} }",
    8487             :     "{ x : [ y = 10 ] = {} }",
    8488             :     "{ x : [ foo().y = 10 ] = {} }",
    8489             :     "{ x : [ foo()[y] = 10 ] = {} }",
    8490             :     "{ x : [ y.z = 10 ] = {} }",
    8491             :     "{ x : [ y[z] = 10 ] = {} }",
    8492             :     "{ z : { __proto__: x, __proto__: y } = z }"
    8493             : 
    8494             :     "[ x ]",
    8495             :     "[ foo().x ]",
    8496             :     "[ foo()[x] ]",
    8497             :     "[ x.y ]",
    8498             :     "[ x[y] ]",
    8499             :     "[ { x } ]",
    8500             :     "[ { x : y } ]",
    8501             :     "[ { x : foo().y } ]",
    8502             :     "[ { x : foo()[y] } ]",
    8503             :     "[ { x : x.y } ]",
    8504             :     "[ { x : x[y] } ]",
    8505             :     "[ [ x ] ]",
    8506             :     "[ [ foo().x ] ]",
    8507             :     "[ [ foo()[x] ] ]",
    8508             :     "[ [ x.y ] ]",
    8509             :     "[ [ x[y] ] ]",
    8510             : 
    8511             :     "[ x = 10 ]",
    8512             :     "[ foo().x = 10 ]",
    8513             :     "[ foo()[x] = 10 ]",
    8514             :     "[ x.y = 10 ]",
    8515             :     "[ x[y] = 10 ]",
    8516             :     "[ { x = 10 } = {} ]",
    8517             :     "[ { x : y = 10 } = {} ]",
    8518             :     "[ { x : foo().y = 10 } = {} ]",
    8519             :     "[ { x : foo()[y] = 10 } = {} ]",
    8520             :     "[ { x : x.y = 10 } = {} ]",
    8521             :     "[ { x : x[y] = 10 } = {} ]",
    8522             :     "[ [ x = 10 ] = {} ]",
    8523             :     "[ [ foo().x = 10 ] = {} ]",
    8524             :     "[ [ foo()[x] = 10 ] = {} ]",
    8525             :     "[ [ x.y = 10 ] = {} ]",
    8526             :     "[ [ x[y] = 10 ] = {} ]",
    8527             :     "{ x : y = 1 }",
    8528             :     "{ x }",
    8529             :     "{ x, y, z }",
    8530             :     "{ x = 1, y: z, z: y }",
    8531             :     "{x = 42, y = 15}",
    8532             :     "[x]",
    8533             :     "[x = 1]",
    8534             :     "[x,y,z]",
    8535             :     "[x, y = 42, z]",
    8536             :     "{ x : x, y : y }",
    8537             :     "{ x : x = 1, y : y }",
    8538             :     "{ x : x, y : y = 42 }",
    8539             :     "[]",
    8540             :     "{}",
    8541             :     "[{x:x, y:y}, [,x,z,]]",
    8542             :     "[{x:x = 1, y:y = 2}, [z = 3, z = 4, z = 5]]",
    8543             :     "[x,,y]",
    8544             :     "[(x),,(y)]",
    8545             :     "[(x)]",
    8546             :     "{42 : x}",
    8547             :     "{42 : x = 42}",
    8548             :     "{42e-2 : x}",
    8549             :     "{42e-2 : x = 42}",
    8550             :     "{'hi' : x}",
    8551             :     "{'hi' : x = 42}",
    8552             :     "{var: x}",
    8553             :     "{var: x = 42}",
    8554             :     "{var: (x) = 42}",
    8555             :     "{[x] : z}",
    8556             :     "{[1+1] : z}",
    8557             :     "{[1+1] : (z)}",
    8558             :     "{[foo()] : z}",
    8559             :     "{[foo()] : (z)}",
    8560             :     "{[foo()] : foo().bar}",
    8561             :     "{[foo()] : foo()['bar']}",
    8562             :     "{[foo()] : this.bar}",
    8563             :     "{[foo()] : this['bar']}",
    8564             :     "{[foo()] : 'foo'.bar}",
    8565             :     "{[foo()] : 'foo'['bar']}",
    8566             :     "[...x]",
    8567             :     "[x,y,...z]",
    8568             :     "[x,,...z]",
    8569             :     "{ x: y }",
    8570             :     "[x, y]",
    8571             :     "[((x, y) => z).x]",
    8572             :     "{x: ((y, z) => z).x}",
    8573             :     "[((x, y) => z)['x']]",
    8574             :     "{x: ((y, z) => z)['x']}",
    8575             : 
    8576             :     "{x: { y = 10 } }",
    8577             :     "[(({ x } = { x: 1 }) => x).a]",
    8578             : 
    8579             :     "{ ...d.x }",
    8580             :     "{ ...c[0]}",
    8581             : 
    8582             :     // v8:4662
    8583             :     "{ x: (y) }",
    8584             :     "{ x: (y) = [] }",
    8585             :     "{ x: (foo.bar) }",
    8586             :     "{ x: (foo['bar']) }",
    8587             :     "[ ...(a) ]",
    8588             :     "[ ...(foo['bar']) ]",
    8589             :     "[ ...(foo.bar) ]",
    8590             :     "[ (y) ]",
    8591             :     "[ (foo.bar) ]",
    8592             :     "[ (foo['bar']) ]",
    8593             : 
    8594           5 :     nullptr};
    8595             :   // clang-format on
    8596           5 :   RunParserSyncTest(context_data, data, kSuccess);
    8597             : 
    8598           5 :   RunParserSyncTest(mixed_assignments_context_data, data, kSuccess);
    8599             : 
    8600             :   const char* empty_context_data[][2] = {
    8601           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    8602             : 
    8603             :   // CoverInitializedName ambiguity handling in various contexts
    8604             :   const char* ambiguity_data[] = {
    8605             :       "var foo = { x = 10 } = {};",
    8606             :       "var foo = { q } = { x = 10 } = {};",
    8607             :       "var foo; foo = { x = 10 } = {};",
    8608             :       "var foo; foo = { q } = { x = 10 } = {};",
    8609             :       "var x; ({ x = 10 } = {});",
    8610             :       "var q, x; ({ q } = { x = 10 } = {});",
    8611             :       "var x; [{ x = 10 } = {}]",
    8612             :       "var x; (true ? { x = true } = {} : { x = false } = {})",
    8613             :       "var q, x; (q, { x = 10 } = {});",
    8614             :       "var { x = 10 } = { x = 20 } = {};",
    8615             :       "var { __proto__: x, __proto__: y } = {}",
    8616             :       "({ __proto__: x, __proto__: y } = {})",
    8617             :       "var { x = 10 } = (o = { x = 20 } = {});",
    8618             :       "var x; (({ x = 10 } = { x = 20 } = {}) => x)({})",
    8619             :       nullptr,
    8620           5 :   };
    8621           5 :   RunParserSyncTest(empty_context_data, ambiguity_data, kSuccess);
    8622           5 : }
    8623             : 
    8624             : 
    8625       25880 : TEST(DestructuringAssignmentNegativeTests) {
    8626             :   const char* context_data[][2] = {
    8627             :       {"'use strict'; let x, y, z; (", " = {});"},
    8628             :       {"var x, y, z; (", " = {});"},
    8629             :       {"'use strict'; let x, y, z; for (x in ", " = {});"},
    8630             :       {"'use strict'; let x, y, z; for (x of ", " = {});"},
    8631             :       {"var x, y, z; for (x in ", " = {});"},
    8632             :       {"var x, y, z; for (x of ", " = {});"},
    8633           5 :       {nullptr, nullptr}};
    8634             : 
    8635             :   // clang-format off
    8636             :   const char* data[] = {
    8637             :     "{ x : ++y }",
    8638             :     "{ x : y * 2 }",
    8639             :     "{ get x() {} }",
    8640             :     "{ set x() {} }",
    8641             :     "{ x: y() }",
    8642             :     "{ this }",
    8643             :     "{ x: this }",
    8644             :     "{ x: this = 1 }",
    8645             :     "{ super }",
    8646             :     "{ x: super }",
    8647             :     "{ x: super = 1 }",
    8648             :     "{ new.target }",
    8649             :     "{ x: new.target }",
    8650             :     "{ x: new.target = 1 }",
    8651             :     "{ import.meta }",
    8652             :     "{ x: import.meta }",
    8653             :     "{ x: import.meta = 1 }",
    8654             :     "[x--]",
    8655             :     "[--x = 1]",
    8656             :     "[x()]",
    8657             :     "[this]",
    8658             :     "[this = 1]",
    8659             :     "[new.target]",
    8660             :     "[new.target = 1]",
    8661             :     "[import.meta]",
    8662             :     "[import.meta = 1]",
    8663             :     "[super]",
    8664             :     "[super = 1]",
    8665             :     "[function f() {}]",
    8666             :     "[async function f() {}]",
    8667             :     "[function* f() {}]",
    8668             :     "[50]",
    8669             :     "[(50)]",
    8670             :     "[(function() {})]",
    8671             :     "[(async function() {})]",
    8672             :     "[(function*() {})]",
    8673             :     "[(foo())]",
    8674             :     "{ x: 50 }",
    8675             :     "{ x: (50) }",
    8676             :     "['str']",
    8677             :     "{ x: 'str' }",
    8678             :     "{ x: ('str') }",
    8679             :     "{ x: (foo()) }",
    8680             :     "{ x: function() {} }",
    8681             :     "{ x: async function() {} }",
    8682             :     "{ x: function*() {} }",
    8683             :     "{ x: (function() {}) }",
    8684             :     "{ x: (async function() {}) }",
    8685             :     "{ x: (function*() {}) }",
    8686             :     "{ x: y } = 'str'",
    8687             :     "[x, y] = 'str'",
    8688             :     "[(x,y) => z]",
    8689             :     "[async(x,y) => z]",
    8690             :     "[async x => z]",
    8691             :     "{x: (y) => z}",
    8692             :     "{x: (y,w) => z}",
    8693             :     "{x: async (y) => z}",
    8694             :     "{x: async (y,w) => z}",
    8695             :     "[x, ...y, z]",
    8696             :     "[...x,]",
    8697             :     "[x, y, ...z = 1]",
    8698             :     "[...z = 1]",
    8699             :     "[x, y, ...[z] = [1]]",
    8700             :     "[...[z] = [1]]",
    8701             : 
    8702             :     "[...++x]",
    8703             :     "[...x--]",
    8704             :     "[...!x]",
    8705             :     "[...x + y]",
    8706             : 
    8707             :     // v8:4657
    8708             :     "({ x: x4, x: (x+=1e4) })",
    8709             :     "(({ x: x4, x: (x+=1e4) }))",
    8710             :     "({ x: x4, x: (x+=1e4) } = {})",
    8711             :     "(({ x: x4, x: (x+=1e4) } = {}))",
    8712             :     "(({ x: x4, x: (x+=1e4) }) = {})",
    8713             :     "({ x: y } = {})",
    8714             :     "(({ x: y } = {}))",
    8715             :     "(({ x: y }) = {})",
    8716             :     "([a])",
    8717             :     "(([a]))",
    8718             :     "([a] = [])",
    8719             :     "(([a] = []))",
    8720             :     "(([a]) = [])",
    8721             : 
    8722             :     // v8:4662
    8723             :     "{ x: ([y]) }",
    8724             :     "{ x: ([y] = []) }",
    8725             :     "{ x: ({y}) }",
    8726             :     "{ x: ({y} = {}) }",
    8727             :     "{ x: (++y) }",
    8728             :     "[ (...[a]) ]",
    8729             :     "[ ...([a]) ]",
    8730             :     "[ ...([a] = [])",
    8731             :     "[ ...[ ( [ a ] ) ] ]",
    8732             :     "[ ([a]) ]",
    8733             :     "[ (...[a]) ]",
    8734             :     "[ ([a] = []) ]",
    8735             :     "[ (++y) ]",
    8736             :     "[ ...(++y) ]",
    8737             : 
    8738             :     "[ x += x ]",
    8739             :     "{ foo: x += x }",
    8740             : 
    8741           5 :     nullptr};
    8742             :   // clang-format on
    8743           5 :   RunParserSyncTest(context_data, data, kError);
    8744             : 
    8745             :   const char* empty_context_data[][2] = {
    8746           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    8747             : 
    8748             :   // CoverInitializedName ambiguity handling in various contexts
    8749             :   const char* ambiguity_data[] = {
    8750             :       "var foo = { x = 10 };", "var foo = { q } = { x = 10 };",
    8751             :       "var foo; foo = { x = 10 };", "var foo; foo = { q } = { x = 10 };",
    8752             :       "var x; ({ x = 10 });", "var q, x; ({ q } = { x = 10 });",
    8753             :       "var x; [{ x = 10 }]", "var x; (true ? { x = true } : { x = false })",
    8754             :       "var q, x; (q, { x = 10 });", "var { x = 10 } = { x = 20 };",
    8755             :       "var { x = 10 } = (o = { x = 20 });",
    8756             :       "var x; (({ x = 10 } = { x = 20 }) => x)({})",
    8757             : 
    8758             :       // Not ambiguous, but uses same context data
    8759             :       "switch([window %= []] = []) { default: }",
    8760             : 
    8761             :       nullptr,
    8762           5 :   };
    8763           5 :   RunParserSyncTest(empty_context_data, ambiguity_data, kError);
    8764             : 
    8765             :   // Strict mode errors
    8766             :   const char* strict_context_data[][2] = {{"'use strict'; (", " = {})"},
    8767             :                                           {"'use strict'; for (", " of {}) {}"},
    8768             :                                           {"'use strict'; for (", " in {}) {}"},
    8769           5 :                                           {nullptr, nullptr}};
    8770             :   const char* strict_data[] = {
    8771             :       "{ eval }", "{ arguments }", "{ foo: eval }", "{ foo: arguments }",
    8772             :       "{ eval = 0 }", "{ arguments = 0 }", "{ foo: eval = 0 }",
    8773             :       "{ foo: arguments = 0 }", "[ eval ]", "[ arguments ]", "[ eval = 0 ]",
    8774             :       "[ arguments = 0 ]",
    8775             : 
    8776             :       // v8:4662
    8777             :       "{ x: (eval) }", "{ x: (arguments) }", "{ x: (eval = 0) }",
    8778             :       "{ x: (arguments = 0) }", "{ x: (eval) = 0 }", "{ x: (arguments) = 0 }",
    8779             :       "[ (eval) ]", "[ (arguments) ]", "[ (eval = 0) ]", "[ (arguments = 0) ]",
    8780             :       "[ (eval) = 0 ]", "[ (arguments) = 0 ]", "[ ...(eval) ]",
    8781             :       "[ ...(arguments) ]", "[ ...(eval = 0) ]", "[ ...(arguments = 0) ]",
    8782             :       "[ ...(eval) = 0 ]", "[ ...(arguments) = 0 ]",
    8783             : 
    8784           5 :       nullptr};
    8785           5 :   RunParserSyncTest(strict_context_data, strict_data, kError);
    8786           5 : }
    8787             : 
    8788             : 
    8789       25880 : TEST(DestructuringDisallowPatternsInForVarIn) {
    8790             :   const char* context_data[][2] = {
    8791           5 :       {"", ""}, {"function f() {", "}"}, {nullptr, nullptr}};
    8792             :   // clang-format off
    8793             :   const char* error_data[] = {
    8794             :     "for (let x = {} in null);",
    8795             :     "for (let x = {} of null);",
    8796           5 :     nullptr};
    8797             :   // clang-format on
    8798           5 :   RunParserSyncTest(context_data, error_data, kError);
    8799             : 
    8800             :   // clang-format off
    8801             :   const char* success_data[] = {
    8802             :     "for (var x = {} in null);",
    8803           5 :     nullptr};
    8804             :   // clang-format on
    8805           5 :   RunParserSyncTest(context_data, success_data, kSuccess);
    8806           5 : }
    8807             : 
    8808             : 
    8809       25880 : TEST(DestructuringDuplicateParams) {
    8810             :   const char* context_data[][2] = {{"'use strict';", ""},
    8811             :                                    {"function outer() { 'use strict';", "}"},
    8812           5 :                                    {nullptr, nullptr}};
    8813             : 
    8814             : 
    8815             :   // clang-format off
    8816             :   const char* error_data[] = {
    8817             :     "function f(x,x){}",
    8818             :     "function f(x, {x : x}){}",
    8819             :     "function f(x, {x}){}",
    8820             :     "function f({x,x}) {}",
    8821             :     "function f([x,x]) {}",
    8822             :     "function f(x, [y,{z:x}]) {}",
    8823             :     "function f([x,{y:x}]) {}",
    8824             :     // non-simple parameter list causes duplicates to be errors in sloppy mode.
    8825             :     "function f(x, x, {a}) {}",
    8826           5 :     nullptr};
    8827             :   // clang-format on
    8828           5 :   RunParserSyncTest(context_data, error_data, kError);
    8829           5 : }
    8830             : 
    8831             : 
    8832       25880 : TEST(DestructuringDuplicateParamsSloppy) {
    8833             :   const char* context_data[][2] = {
    8834           5 :       {"", ""}, {"function outer() {", "}"}, {nullptr, nullptr}};
    8835             : 
    8836             : 
    8837             :   // clang-format off
    8838             :   const char* error_data[] = {
    8839             :     // non-simple parameter list causes duplicates to be errors in sloppy mode.
    8840             :     "function f(x, {x : x}){}",
    8841             :     "function f(x, {x}){}",
    8842             :     "function f({x,x}) {}",
    8843             :     "function f(x, x, {a}) {}",
    8844           5 :     nullptr};
    8845             :   // clang-format on
    8846           5 :   RunParserSyncTest(context_data, error_data, kError);
    8847           5 : }
    8848             : 
    8849             : 
    8850       25880 : TEST(DestructuringDisallowPatternsInSingleParamArrows) {
    8851             :   const char* context_data[][2] = {{"'use strict';", ""},
    8852             :                                    {"function outer() { 'use strict';", "}"},
    8853             :                                    {"", ""},
    8854             :                                    {"function outer() { ", "}"},
    8855           5 :                                    {nullptr, nullptr}};
    8856             : 
    8857             :   // clang-format off
    8858             :   const char* error_data[] = {
    8859             :     "var f = {x} => {};",
    8860             :     "var f = {x,y} => {};",
    8861           5 :     nullptr};
    8862             :   // clang-format on
    8863           5 :   RunParserSyncTest(context_data, error_data, kError);
    8864           5 : }
    8865             : 
    8866             : 
    8867       25880 : TEST(DefaultParametersYieldInInitializers) {
    8868             :   // clang-format off
    8869             :   const char* sloppy_function_context_data[][2] = {
    8870             :     {"(function f(", ") { });"},
    8871             :     {nullptr, nullptr}
    8872           5 :   };
    8873             : 
    8874             :   const char* strict_function_context_data[][2] = {
    8875             :     {"'use strict'; (function f(", ") { });"},
    8876             :     {nullptr, nullptr}
    8877           5 :   };
    8878             : 
    8879             :   const char* sloppy_arrow_context_data[][2] = {
    8880             :     {"((", ")=>{});"},
    8881             :     {nullptr, nullptr}
    8882           5 :   };
    8883             : 
    8884             :   const char* strict_arrow_context_data[][2] = {
    8885             :     {"'use strict'; ((", ")=>{});"},
    8886             :     {nullptr, nullptr}
    8887           5 :   };
    8888             : 
    8889             :   const char* generator_context_data[][2] = {
    8890             :     {"'use strict'; (function *g(", ") { });"},
    8891             :     {"(function *g(", ") { });"},
    8892             :     // Arrow function within generator has the same rules.
    8893             :     {"'use strict'; (function *g() { (", ") => {} });"},
    8894             :     {"(function *g() { (", ") => {} });"},
    8895             :     // And similarly for arrow functions in the parameter list.
    8896             :     {"'use strict'; (function *g(z = (", ") => {}) { });"},
    8897             :     {"(function *g(z = (", ") => {}) { });"},
    8898             :     {nullptr, nullptr}
    8899           5 :   };
    8900             : 
    8901             :   const char* parameter_data[] = {
    8902             :     "x=yield",
    8903             :     "x, y=yield",
    8904             :     "{x=yield}",
    8905             :     "[x=yield]",
    8906             : 
    8907             :     "x=(yield)",
    8908             :     "x, y=(yield)",
    8909             :     "{x=(yield)}",
    8910             :     "[x=(yield)]",
    8911             : 
    8912             :     "x=f(yield)",
    8913             :     "x, y=f(yield)",
    8914             :     "{x=f(yield)}",
    8915             :     "[x=f(yield)]",
    8916             : 
    8917             :     "{x}=yield",
    8918             :     "[x]=yield",
    8919             : 
    8920             :     "{x}=(yield)",
    8921             :     "[x]=(yield)",
    8922             : 
    8923             :     "{x}=f(yield)",
    8924             :     "[x]=f(yield)",
    8925             :     nullptr
    8926           5 :   };
    8927             : 
    8928             :   // Because classes are always in strict mode, these are always errors.
    8929             :   const char* always_error_param_data[] = {
    8930             :     "x = class extends (yield) { }",
    8931             :     "x = class extends f(yield) { }",
    8932             :     "x = class extends (null, yield) { }",
    8933             :     "x = class extends (a ? null : yield) { }",
    8934             :     "[x] = [class extends (a ? null : yield) { }]",
    8935             :     "[x = class extends (a ? null : yield) { }]",
    8936             :     "[x = class extends (a ? null : yield) { }] = [null]",
    8937             :     "x = class { [yield]() { } }",
    8938             :     "x = class { static [yield]() { } }",
    8939             :     "x = class { [(yield, 1)]() { } }",
    8940             :     "x = class { [y = (yield, 1)]() { } }",
    8941             :     nullptr
    8942           5 :   };
    8943             :   // clang-format on
    8944             : 
    8945           5 :   RunParserSyncTest(sloppy_function_context_data, parameter_data, kSuccess);
    8946           5 :   RunParserSyncTest(sloppy_arrow_context_data, parameter_data, kSuccess);
    8947             : 
    8948           5 :   RunParserSyncTest(strict_function_context_data, parameter_data, kError);
    8949           5 :   RunParserSyncTest(strict_arrow_context_data, parameter_data, kError);
    8950             : 
    8951           5 :   RunParserSyncTest(generator_context_data, parameter_data, kError);
    8952           5 :   RunParserSyncTest(generator_context_data, always_error_param_data, kError);
    8953           5 : }
    8954             : 
    8955       25880 : TEST(SpreadArray) {
    8956             :   const char* context_data[][2] = {
    8957           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    8958             : 
    8959             :   // clang-format off
    8960             :   const char* data[] = {
    8961             :     "[...a]",
    8962             :     "[a, ...b]",
    8963             :     "[...a,]",
    8964             :     "[...a, ,]",
    8965             :     "[, ...a]",
    8966             :     "[...a, ...b]",
    8967             :     "[...a, , ...b]",
    8968             :     "[...[...a]]",
    8969             :     "[, ...a]",
    8970             :     "[, , ...a]",
    8971           5 :     nullptr};
    8972             :   // clang-format on
    8973           5 :   RunParserSyncTest(context_data, data, kSuccess);
    8974           5 : }
    8975             : 
    8976             : 
    8977       25880 : TEST(SpreadArrayError) {
    8978             :   const char* context_data[][2] = {
    8979           5 :       {"'use strict';", ""}, {"", ""}, {nullptr, nullptr}};
    8980             : 
    8981             :   // clang-format off
    8982             :   const char* data[] = {
    8983             :     "[...]",
    8984             :     "[a, ...]",
    8985             :     "[..., ]",
    8986             :     "[..., ...]",
    8987             :     "[ (...a)]",
    8988           5 :     nullptr};
    8989             :   // clang-format on
    8990           5 :   RunParserSyncTest(context_data, data, kError);
    8991           5 : }
    8992             : 
    8993             : 
    8994       25880 : TEST(NewTarget) {
    8995             :   // clang-format off
    8996             :   const char* good_context_data[][2] = {
    8997             :     {"function f() {", "}"},
    8998             :     {"'use strict'; function f() {", "}"},
    8999             :     {"var f = function() {", "}"},
    9000             :     {"'use strict'; var f = function() {", "}"},
    9001             :     {"({m: function() {", "}})"},
    9002             :     {"'use strict'; ({m: function() {", "}})"},
    9003             :     {"({m() {", "}})"},
    9004             :     {"'use strict'; ({m() {", "}})"},
    9005             :     {"({get x() {", "}})"},
    9006             :     {"'use strict'; ({get x() {", "}})"},
    9007             :     {"({set x(_) {", "}})"},
    9008             :     {"'use strict'; ({set x(_) {", "}})"},
    9009             :     {"class C {m() {", "}}"},
    9010             :     {"class C {get x() {", "}}"},
    9011             :     {"class C {set x(_) {", "}}"},
    9012             :     {nullptr}
    9013           5 :   };
    9014             : 
    9015             :   const char* bad_context_data[][2] = {
    9016             :     {"", ""},
    9017             :     {"'use strict';", ""},
    9018             :     {nullptr}
    9019           5 :   };
    9020             : 
    9021             :   const char* data[] = {
    9022             :     "new.target",
    9023             :     "{ new.target }",
    9024             :     "() => { new.target }",
    9025             :     "() => new.target",
    9026             :     "if (1) { new.target }",
    9027             :     "if (1) {} else { new.target }",
    9028             :     "while (0) { new.target }",
    9029             :     "do { new.target } while (0)",
    9030             :     nullptr
    9031           5 :   };
    9032             : 
    9033             :   // clang-format on
    9034             : 
    9035           5 :   RunParserSyncTest(good_context_data, data, kSuccess);
    9036           5 :   RunParserSyncTest(bad_context_data, data, kError);
    9037           5 : }
    9038             : 
    9039       25880 : TEST(ImportMetaSuccess) {
    9040             :   // clang-format off
    9041             :   const char* context_data[][2] = {
    9042             :     {"", ""},
    9043             :     {"'use strict';", ""},
    9044             :     {"function f() {", "}"},
    9045             :     {"'use strict'; function f() {", "}"},
    9046             :     {"var f = function() {", "}"},
    9047             :     {"'use strict'; var f = function() {", "}"},
    9048             :     {"({m: function() {", "}})"},
    9049             :     {"'use strict'; ({m: function() {", "}})"},
    9050             :     {"({m() {", "}})"},
    9051             :     {"'use strict'; ({m() {", "}})"},
    9052             :     {"({get x() {", "}})"},
    9053             :     {"'use strict'; ({get x() {", "}})"},
    9054             :     {"({set x(_) {", "}})"},
    9055             :     {"'use strict'; ({set x(_) {", "}})"},
    9056             :     {"class C {m() {", "}}"},
    9057             :     {"class C {get x() {", "}}"},
    9058             :     {"class C {set x(_) {", "}}"},
    9059             :     {nullptr}
    9060           5 :   };
    9061             : 
    9062             :   const char* data[] = {
    9063             :     "import.meta",
    9064             :     "() => { import.meta }",
    9065             :     "() => import.meta",
    9066             :     "if (1) { import.meta }",
    9067             :     "if (1) {} else { import.meta }",
    9068             :     "while (0) { import.meta }",
    9069             :     "do { import.meta } while (0)",
    9070             :     "import.meta.url",
    9071             :     "import.meta[0]",
    9072             :     "import.meta.couldBeMutable = true",
    9073             :     "import.meta()",
    9074             :     "new import.meta.MagicClass",
    9075             :     "new import.meta",
    9076             :     "t = [...import.meta]",
    9077             :     "f = {...import.meta}",
    9078             :     "delete import.meta",
    9079             :     nullptr
    9080           5 :   };
    9081             : 
    9082             :   // clang-format on
    9083             : 
    9084             :   // Making sure the same *wouldn't* parse without the flags
    9085             :   RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
    9086             :                           nullptr, 0, true, true);
    9087             : 
    9088             :   static const ParserFlag flags[] = {
    9089             :       kAllowHarmonyImportMeta, kAllowHarmonyDynamicImport,
    9090             :   };
    9091             :   // 2.1.1 Static Semantics: Early Errors
    9092             :   // ImportMeta
    9093             :   // * It is an early Syntax Error if Module is not the syntactic goal symbol.
    9094             :   RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    9095           5 :                     arraysize(flags));
    9096             :   // Making sure the same wouldn't parse without the flags either
    9097           5 :   RunParserSyncTest(context_data, data, kError);
    9098             : 
    9099             :   RunModuleParserSyncTest(context_data, data, kSuccess, nullptr, 0, flags,
    9100             :                           arraysize(flags));
    9101           5 : }
    9102             : 
    9103       25880 : TEST(ImportMetaFailure) {
    9104             :   // clang-format off
    9105             :   const char* context_data[][2] = {
    9106             :     {"var ", ""},
    9107             :     {"let ", ""},
    9108             :     {"const ", ""},
    9109             :     {"var [", "] = [1]"},
    9110             :     {"([", "] = [1])"},
    9111             :     {"({", "} = {1})"},
    9112             :     {"var {", " = 1} = 1"},
    9113             :     {"for (var ", " of [1]) {}"},
    9114             :     {"(", ") => {}"},
    9115             :     {"let f = ", " => {}"},
    9116             :     {nullptr}
    9117           5 :   };
    9118             : 
    9119             :   const char* data[] = {
    9120             :     "import.meta",
    9121             :     nullptr
    9122           5 :   };
    9123             : 
    9124             :   // clang-format on
    9125             : 
    9126             :   static const ParserFlag flags[] = {
    9127             :       kAllowHarmonyImportMeta, kAllowHarmonyDynamicImport,
    9128             :   };
    9129             : 
    9130             :   RunParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    9131           5 :                     arraysize(flags));
    9132             :   RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, flags,
    9133             :                           arraysize(flags));
    9134             : 
    9135             :   RunModuleParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
    9136             :                           nullptr, 0, true, true);
    9137           5 :   RunParserSyncTest(context_data, data, kError);
    9138           5 : }
    9139             : 
    9140       25880 : TEST(ConstSloppy) {
    9141             :   // clang-format off
    9142             :   const char* context_data[][2] = {
    9143             :     {"", ""},
    9144             :     {"{", "}"},
    9145             :     {nullptr, nullptr}
    9146           5 :   };
    9147             : 
    9148             :   const char* data[] = {
    9149             :     "const x = 1",
    9150             :     "for (const x = 1; x < 1; x++) {}",
    9151             :     "for (const x in {}) {}",
    9152             :     "for (const x of []) {}",
    9153             :     nullptr
    9154           5 :   };
    9155             :   // clang-format on
    9156           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9157           5 : }
    9158             : 
    9159             : 
    9160       25880 : TEST(LetSloppy) {
    9161             :   // clang-format off
    9162             :   const char* context_data[][2] = {
    9163             :     {"", ""},
    9164             :     {"'use strict';", ""},
    9165             :     {"{", "}"},
    9166             :     {nullptr, nullptr}
    9167           5 :   };
    9168             : 
    9169             :   const char* data[] = {
    9170             :     "let x",
    9171             :     "let x = 1",
    9172             :     "for (let x = 1; x < 1; x++) {}",
    9173             :     "for (let x in {}) {}",
    9174             :     "for (let x of []) {}",
    9175             :     nullptr
    9176           5 :   };
    9177             :   // clang-format on
    9178             : 
    9179           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9180           5 : }
    9181             : 
    9182             : 
    9183       25880 : TEST(LanguageModeDirectivesNonSimpleParameterListErrors) {
    9184             :   // TC39 deemed "use strict" directives to be an error when occurring in the
    9185             :   // body of a function with non-simple parameter list, on 29/7/2015.
    9186             :   // https://goo.gl/ueA7Ln
    9187             :   const char* context_data[][2] = {
    9188             :       {"function f(", ") { 'use strict'; }"},
    9189             :       {"function* g(", ") { 'use strict'; }"},
    9190             :       {"class c { foo(", ") { 'use strict' }"},
    9191             :       {"var a = (", ") => { 'use strict'; }"},
    9192             :       {"var o = { m(", ") { 'use strict'; }"},
    9193             :       {"var o = { *gm(", ") { 'use strict'; }"},
    9194             :       {"var c = { m(", ") { 'use strict'; }"},
    9195             :       {"var c = { *gm(", ") { 'use strict'; }"},
    9196             : 
    9197             :       {"'use strict'; function f(", ") { 'use strict'; }"},
    9198             :       {"'use strict'; function* g(", ") { 'use strict'; }"},
    9199             :       {"'use strict'; class c { foo(", ") { 'use strict' }"},
    9200             :       {"'use strict'; var a = (", ") => { 'use strict'; }"},
    9201             :       {"'use strict'; var o = { m(", ") { 'use strict'; }"},
    9202             :       {"'use strict'; var o = { *gm(", ") { 'use strict'; }"},
    9203             :       {"'use strict'; var c = { m(", ") { 'use strict'; }"},
    9204             :       {"'use strict'; var c = { *gm(", ") { 'use strict'; }"},
    9205             : 
    9206           5 :       {nullptr, nullptr}};
    9207             : 
    9208             :   const char* data[] = {
    9209             :       // TODO(@caitp): support formal parameter initializers
    9210             :       "{}",
    9211             :       "[]",
    9212             :       "[{}]",
    9213             :       "{a}",
    9214             :       "a, {b}",
    9215             :       "a, b, {c, d, e}",
    9216             :       "initializer = true",
    9217             :       "a, b, c = 1",
    9218             :       "...args",
    9219             :       "a, b, ...rest",
    9220             :       "[a, b, ...rest]",
    9221             :       "{ bindingPattern = {} }",
    9222             :       "{ initializedBindingPattern } = { initializedBindingPattern: true }",
    9223           5 :       nullptr};
    9224             : 
    9225           5 :   RunParserSyncTest(context_data, data, kError);
    9226           5 : }
    9227             : 
    9228             : 
    9229       25880 : TEST(LetSloppyOnly) {
    9230             :   // clang-format off
    9231             :   const char* context_data[][2] = {
    9232             :     {"", ""},
    9233             :     {"{", "}"},
    9234             :     {"(function() {", "})()"},
    9235             :     {nullptr, nullptr}
    9236           5 :   };
    9237             : 
    9238             :   const char* data[] = {
    9239             :     "let",
    9240             :     "let = 1",
    9241             :     "for (let = 1; let < 1; let++) {}",
    9242             :     "for (let in {}) {}",
    9243             :     "for (var let = 1; let < 1; let++) {}",
    9244             :     "for (var let in {}) {}",
    9245             :     "for (var [let] = 1; let < 1; let++) {}",
    9246             :     "for (var [let] in {}) {}",
    9247             :     "var let",
    9248             :     "var [let] = []",
    9249             :     nullptr
    9250           5 :   };
    9251             :   // clang-format on
    9252             : 
    9253           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9254             : 
    9255             :   // Some things should be rejected even in sloppy mode
    9256             :   // This addresses BUG(v8:4403).
    9257             : 
    9258             :   // clang-format off
    9259             :   const char* fail_data[] = {
    9260             :     "let let = 1",
    9261             :     "for (let let = 1; let < 1; let++) {}",
    9262             :     "for (let let in {}) {}",
    9263             :     "for (let let of []) {}",
    9264             :     "const let = 1",
    9265             :     "for (const let = 1; let < 1; let++) {}",
    9266             :     "for (const let in {}) {}",
    9267             :     "for (const let of []) {}",
    9268             :     "let [let] = 1",
    9269             :     "for (let [let] = 1; let < 1; let++) {}",
    9270             :     "for (let [let] in {}) {}",
    9271             :     "for (let [let] of []) {}",
    9272             :     "const [let] = 1",
    9273             :     "for (const [let] = 1; let < 1; let++) {}",
    9274             :     "for (const [let] in {}) {}",
    9275             :     "for (const [let] of []) {}",
    9276             : 
    9277             :     // Sprinkle in the escaped version too.
    9278             :     "let l\\u0065t = 1",
    9279             :     "const l\\u0065t = 1",
    9280             :     "let [l\\u0065t] = 1",
    9281             :     "const [l\\u0065t] = 1",
    9282             :     "for (let l\\u0065t in {}) {}",
    9283             :     nullptr
    9284           5 :   };
    9285             :   // clang-format on
    9286             : 
    9287           5 :   RunParserSyncTest(context_data, fail_data, kError);
    9288           5 : }
    9289             : 
    9290             : 
    9291       25880 : TEST(EscapedKeywords) {
    9292             :   // clang-format off
    9293             :   const char* sloppy_context_data[][2] = {
    9294             :     {"", ""},
    9295             :     {nullptr, nullptr}
    9296           5 :   };
    9297             : 
    9298             :   const char* strict_context_data[][2] = {
    9299             :     {"'use strict';", ""},
    9300             :     {nullptr, nullptr}
    9301           5 :   };
    9302             : 
    9303             :   const char* fail_data[] = {
    9304             :     "for (var i = 0; i < 100; ++i) { br\\u0065ak; }",
    9305             :     "cl\\u0061ss Foo {}",
    9306             :     "var x = cl\\u0061ss {}",
    9307             :     "\\u0063onst foo = 1;",
    9308             :     "while (i < 10) { if (i++ & 1) c\\u006fntinue; this.x++; }",
    9309             :     "d\\u0065bugger;",
    9310             :     "d\\u0065lete this.a;",
    9311             :     "\\u0063o { } while(0)",
    9312             :     "if (d\\u006f { true }) {}",
    9313             :     "if (false) { this.a = 1; } \\u0065lse { this.b = 1; }",
    9314             :     "e\\u0078port var foo;",
    9315             :     "try { } catch (e) {} f\\u0069nally { }",
    9316             :     "f\\u006fr (var i = 0; i < 10; ++i);",
    9317             :     "f\\u0075nction fn() {}",
    9318             :     "var f = f\\u0075nction() {}",
    9319             :     "\\u0069f (true) { }",
    9320             :     "\\u0069mport blah from './foo.js';",
    9321             :     "n\\u0065w function f() {}",
    9322             :     "(function() { r\\u0065turn; })()",
    9323             :     "class C extends function() {} { constructor() { sup\\u0065r() } }",
    9324             :     "class C extends function() {} { constructor() { sup\\u0065r.a = 1 } }",
    9325             :     "sw\\u0069tch (this.a) {}",
    9326             :     "var x = th\\u0069s;",
    9327             :     "th\\u0069s.a = 1;",
    9328             :     "thr\\u006fw 'boo';",
    9329             :     "t\\u0072y { true } catch (e) {}",
    9330             :     "var x = typ\\u0065of 'blah'",
    9331             :     "v\\u0061r a = true",
    9332             :     "var v\\u0061r = true",
    9333             :     "(function() { return v\\u006fid 0; })()",
    9334             :     "wh\\u0069le (true) { }",
    9335             :     "w\\u0069th (this.scope) { }",
    9336             :     "(function*() { y\\u0069eld 1; })()",
    9337             :     "(function*() { var y\\u0069eld = 1; })()",
    9338             : 
    9339             :     "var \\u0065num = 1;",
    9340             :     "var { \\u0065num } = {}",
    9341             :     "(\\u0065num = 1);",
    9342             : 
    9343             :     // Null / Boolean literals
    9344             :     "(x === n\\u0075ll);",
    9345             :     "var x = n\\u0075ll;",
    9346             :     "var n\\u0075ll = 1;",
    9347             :     "var { n\\u0075ll } = { 1 };",
    9348             :     "n\\u0075ll = 1;",
    9349             :     "(x === tr\\u0075e);",
    9350             :     "var x = tr\\u0075e;",
    9351             :     "var tr\\u0075e = 1;",
    9352             :     "var { tr\\u0075e } = {};",
    9353             :     "tr\\u0075e = 1;",
    9354             :     "(x === f\\u0061lse);",
    9355             :     "var x = f\\u0061lse;",
    9356             :     "var f\\u0061lse = 1;",
    9357             :     "var { f\\u0061lse } = {};",
    9358             :     "f\\u0061lse = 1;",
    9359             : 
    9360             :     // TODO(caitp): consistent error messages for labeled statements and
    9361             :     // expressions
    9362             :     "switch (this.a) { c\\u0061se 6: break; }",
    9363             :     "try { } c\\u0061tch (e) {}",
    9364             :     "switch (this.a) { d\\u0065fault: break; }",
    9365             :     "class C \\u0065xtends function B() {} {}",
    9366             :     "for (var a i\\u006e this) {}",
    9367             :     "if ('foo' \\u0069n this) {}",
    9368             :     "if (this \\u0069nstanceof Array) {}",
    9369             :     "(n\\u0065w function f() {})",
    9370             :     "(typ\\u0065of 123)",
    9371             :     "(v\\u006fid 0)",
    9372             :     "do { ; } wh\\u0069le (true) { }",
    9373             :     "(function*() { return (n++, y\\u0069eld 1); })()",
    9374             :     "class C { st\\u0061tic bar() {} }",
    9375             :     "class C { st\\u0061tic *bar() {} }",
    9376             :     "class C { st\\u0061tic get bar() {} }",
    9377             :     "class C { st\\u0061tic set bar() {} }",
    9378             :     "(async ()=>{\\u0061wait 100})()",
    9379             :     "({\\u0067et get(){}})",
    9380             :     "({\\u0073et set(){}})",
    9381             :     "(async ()=>{var \\u0061wait = 100})()",
    9382             :     nullptr
    9383           5 :   };
    9384             :   // clang-format on
    9385             : 
    9386           5 :   RunParserSyncTest(sloppy_context_data, fail_data, kError);
    9387           5 :   RunParserSyncTest(strict_context_data, fail_data, kError);
    9388             :   RunModuleParserSyncTest(sloppy_context_data, fail_data, kError);
    9389             : 
    9390             :   // clang-format off
    9391             :   const char* let_data[] = {
    9392             :     "var l\\u0065t = 1;",
    9393             :     "l\\u0065t = 1;",
    9394             :     "(l\\u0065t === 1);",
    9395             :     "(y\\u0069eld);",
    9396             :     "var y\\u0069eld = 1;",
    9397             :     "var { y\\u0069eld } = {};",
    9398             :     nullptr
    9399           5 :   };
    9400             :   // clang-format on
    9401             : 
    9402           5 :   RunParserSyncTest(sloppy_context_data, let_data, kSuccess);
    9403           5 :   RunParserSyncTest(strict_context_data, let_data, kError);
    9404             : 
    9405             :   // Non-errors in sloppy mode
    9406             :   const char* valid_data[] = {"(\\u0069mplements = 1);",
    9407             :                               "var impl\\u0065ments = 1;",
    9408             :                               "var { impl\\u0065ments  } = {};",
    9409             :                               "(\\u0069nterface = 1);",
    9410             :                               "var int\\u0065rface = 1;",
    9411             :                               "var { int\\u0065rface  } = {};",
    9412             :                               "(p\\u0061ckage = 1);",
    9413             :                               "var packa\\u0067e = 1;",
    9414             :                               "var { packa\\u0067e  } = {};",
    9415             :                               "(p\\u0072ivate = 1);",
    9416             :                               "var p\\u0072ivate;",
    9417             :                               "var { p\\u0072ivate } = {};",
    9418             :                               "(prot\\u0065cted);",
    9419             :                               "var prot\\u0065cted = 1;",
    9420             :                               "var { prot\\u0065cted  } = {};",
    9421             :                               "(publ\\u0069c);",
    9422             :                               "var publ\\u0069c = 1;",
    9423             :                               "var { publ\\u0069c } = {};",
    9424             :                               "(st\\u0061tic);",
    9425             :                               "var st\\u0061tic = 1;",
    9426             :                               "var { st\\u0061tic } = {};",
    9427           5 :                               nullptr};
    9428           5 :   RunParserSyncTest(sloppy_context_data, valid_data, kSuccess);
    9429           5 :   RunParserSyncTest(strict_context_data, valid_data, kError);
    9430             :   RunModuleParserSyncTest(strict_context_data, valid_data, kError);
    9431           5 : }
    9432             : 
    9433             : 
    9434       25880 : TEST(MiscSyntaxErrors) {
    9435             :   // clang-format off
    9436             :   const char* context_data[][2] = {
    9437             :     { "'use strict'", "" },
    9438             :     { "", "" },
    9439             :     { nullptr, nullptr }
    9440           5 :   };
    9441             :   const char* error_data[] = {
    9442             :     "for (();;) {}",
    9443             : 
    9444             :     // crbug.com/582626
    9445             :     "{ NaN ,chA((evarA=new t ( l = !.0[((... co -a0([1]))=> greturnkf",
    9446             :     nullptr
    9447           5 :   };
    9448             :   // clang-format on
    9449             : 
    9450           5 :   RunParserSyncTest(context_data, error_data, kError);
    9451           5 : }
    9452             : 
    9453             : 
    9454       25880 : TEST(EscapeSequenceErrors) {
    9455             :   // clang-format off
    9456             :   const char* context_data[][2] = {
    9457             :     { "'", "'" },
    9458             :     { "\"", "\"" },
    9459             :     { "`", "`" },
    9460             :     { "`${'", "'}`" },
    9461             :     { "`${\"", "\"}`" },
    9462             :     { "`${`", "`}`" },
    9463             :     { nullptr, nullptr }
    9464           5 :   };
    9465             :   const char* error_data[] = {
    9466             :     "\\uABCG",
    9467             :     "\\u{ZZ}",
    9468             :     "\\u{FFZ}",
    9469             :     "\\u{FFFFFFFFFF }",
    9470             :     "\\u{110000}",
    9471             :     "\\u{110000",
    9472             :     "\\u{FFFD }",
    9473             :     "\\xZF",
    9474             :     nullptr
    9475           5 :   };
    9476             :   // clang-format on
    9477             : 
    9478           5 :   RunParserSyncTest(context_data, error_data, kError);
    9479           5 : }
    9480             : 
    9481       25880 : TEST(NewTargetErrors) {
    9482             :   // clang-format off
    9483             :   const char* context_data[][2] = {
    9484             :     { "'use strict'", "" },
    9485             :     { "", "" },
    9486             :     { nullptr, nullptr }
    9487           5 :   };
    9488             :   const char* error_data[] = {
    9489             :     "var x = new.target",
    9490             :     "function f() { return new.t\\u0061rget; }",
    9491             :     nullptr
    9492           5 :   };
    9493             :   // clang-format on
    9494           5 :   RunParserSyncTest(context_data, error_data, kError);
    9495           5 : }
    9496             : 
    9497       25880 : TEST(FunctionDeclarationError) {
    9498             :   // clang-format off
    9499             :   const char* strict_context[][2] = {
    9500             :     { "'use strict';", "" },
    9501             :     { "'use strict'; { ", "}" },
    9502             :     {"(function() { 'use strict';", "})()"},
    9503             :     {"(function() { 'use strict'; {", "} })()"},
    9504             :     { nullptr, nullptr }
    9505           5 :   };
    9506             :   const char* sloppy_context[][2] = {
    9507             :     { "", "" },
    9508             :     { "{", "}" },
    9509             :     {"(function() {", "})()"},
    9510             :     {"(function() { {", "} })()"},
    9511             :     { nullptr, nullptr }
    9512           5 :   };
    9513             :   // Invalid in all contexts
    9514             :   const char* error_data[] = {
    9515             :     "try function foo() {} catch (e) {}",
    9516             :     "do function foo() {} while (0);",
    9517             :     "for (;false;) function foo() {}",
    9518             :     "for (var i = 0; i < 1; i++) function f() { };",
    9519             :     "for (var x in {a: 1}) function f() { };",
    9520             :     "for (var x in {}) function f() { };",
    9521             :     "for (var x in {}) function foo() {}",
    9522             :     "for (x in {a: 1}) function f() { };",
    9523             :     "for (x in {}) function f() { };",
    9524             :     "var x; for (x in {}) function foo() {}",
    9525             :     "with ({}) function f() { };",
    9526             :     "do label: function foo() {} while (0);",
    9527             :     "for (;false;) label: function foo() {}",
    9528             :     "for (var i = 0; i < 1; i++) label: function f() { };",
    9529             :     "for (var x in {a: 1}) label: function f() { };",
    9530             :     "for (var x in {}) label: function f() { };",
    9531             :     "for (var x in {}) label: function foo() {}",
    9532             :     "for (x in {a: 1}) label: function f() { };",
    9533             :     "for (x in {}) label: function f() { };",
    9534             :     "var x; for (x in {}) label: function foo() {}",
    9535             :     "with ({}) label: function f() { };",
    9536             :     "if (true) label: function f() {}",
    9537             :     "if (true) {} else label: function f() {}",
    9538             :     "if (true) function* f() { }",
    9539             :     "label: function* f() { }",
    9540             :     "if (true) async function f() { }",
    9541             :     "label: async function f() { }",
    9542             :     "if (true) async function* f() { }",
    9543             :     "label: async function* f() { }",
    9544             :     nullptr
    9545           5 :   };
    9546             :   // Valid only in sloppy mode.
    9547             :   const char* sloppy_data[] = {
    9548             :     "if (true) function foo() {}",
    9549             :     "if (false) {} else function f() { };",
    9550             :     "label: function f() { }",
    9551             :     "label: if (true) function f() { }",
    9552             :     "label: if (true) {} else function f() { }",
    9553             :     "label: label2: function f() { }",
    9554             :     nullptr
    9555           5 :   };
    9556             :   // clang-format on
    9557             : 
    9558             :   // Nothing parses in strict mode without a SyntaxError
    9559           5 :   RunParserSyncTest(strict_context, error_data, kError);
    9560           5 :   RunParserSyncTest(strict_context, sloppy_data, kError);
    9561             : 
    9562             :   // In sloppy mode, sloppy_data is successful
    9563           5 :   RunParserSyncTest(sloppy_context, error_data, kError);
    9564           5 :   RunParserSyncTest(sloppy_context, sloppy_data, kSuccess);
    9565           5 : }
    9566             : 
    9567       25880 : TEST(ExponentiationOperator) {
    9568             :   // clang-format off
    9569             :   const char* context_data[][2] = {
    9570             :     { "var O = { p: 1 }, x = 10; ; if (", ") { foo(); }" },
    9571             :     { "var O = { p: 1 }, x = 10; ; (", ")" },
    9572             :     { "var O = { p: 1 }, x = 10; foo(", ")" },
    9573             :     { nullptr, nullptr }
    9574           5 :   };
    9575             :   const char* data[] = {
    9576             :     "(delete O.p) ** 10",
    9577             :     "(delete x) ** 10",
    9578             :     "(~O.p) ** 10",
    9579             :     "(~x) ** 10",
    9580             :     "(!O.p) ** 10",
    9581             :     "(!x) ** 10",
    9582             :     "(+O.p) ** 10",
    9583             :     "(+x) ** 10",
    9584             :     "(-O.p) ** 10",
    9585             :     "(-x) ** 10",
    9586             :     "(typeof O.p) ** 10",
    9587             :     "(typeof x) ** 10",
    9588             :     "(void 0) ** 10",
    9589             :     "(void O.p) ** 10",
    9590             :     "(void x) ** 10",
    9591             :     "++O.p ** 10",
    9592             :     "++x ** 10",
    9593             :     "--O.p ** 10",
    9594             :     "--x ** 10",
    9595             :     "O.p++ ** 10",
    9596             :     "x++ ** 10",
    9597             :     "O.p-- ** 10",
    9598             :     "x-- ** 10",
    9599             :     nullptr
    9600           5 :   };
    9601             :   // clang-format on
    9602             : 
    9603           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9604           5 : }
    9605             : 
    9606       25880 : TEST(ExponentiationOperatorErrors) {
    9607             :   // clang-format off
    9608             :   const char* context_data[][2] = {
    9609             :     { "var O = { p: 1 }, x = 10; ; if (", ") { foo(); }" },
    9610             :     { "var O = { p: 1 }, x = 10; ; (", ")" },
    9611             :     { "var O = { p: 1 }, x = 10; foo(", ")" },
    9612             :     { nullptr, nullptr }
    9613           5 :   };
    9614             :   const char* error_data[] = {
    9615             :     "delete O.p ** 10",
    9616             :     "delete x ** 10",
    9617             :     "~O.p ** 10",
    9618             :     "~x ** 10",
    9619             :     "!O.p ** 10",
    9620             :     "!x ** 10",
    9621             :     "+O.p ** 10",
    9622             :     "+x ** 10",
    9623             :     "-O.p ** 10",
    9624             :     "-x ** 10",
    9625             :     "typeof O.p ** 10",
    9626             :     "typeof x ** 10",
    9627             :     "void ** 10",
    9628             :     "void O.p ** 10",
    9629             :     "void x ** 10",
    9630             :     "++delete O.p ** 10",
    9631             :     "--delete O.p ** 10",
    9632             :     "++~O.p ** 10",
    9633             :     "++~x ** 10",
    9634             :     "--!O.p ** 10",
    9635             :     "--!x ** 10",
    9636             :     "++-O.p ** 10",
    9637             :     "++-x ** 10",
    9638             :     "--+O.p ** 10",
    9639             :     "--+x ** 10",
    9640             :     "[ x ] **= [ 2 ]",
    9641             :     "[ x **= 2 ] = [ 2 ]",
    9642             :     "{ x } **= { x: 2 }",
    9643             :     "{ x: x **= 2 ] = { x: 2 }",
    9644             :     // TODO(caitp): a Call expression as LHS should be an early ReferenceError!
    9645             :     // "Array() **= 10",
    9646             :     nullptr
    9647           5 :   };
    9648             :   // clang-format on
    9649             : 
    9650           5 :   RunParserSyncTest(context_data, error_data, kError);
    9651           5 : }
    9652             : 
    9653       25880 : TEST(AsyncAwait) {
    9654             :   // clang-format off
    9655             :   const char* context_data[][2] = {
    9656             :     { "'use strict';", "" },
    9657             :     { "", "" },
    9658             :     { nullptr, nullptr }
    9659           5 :   };
    9660             : 
    9661             :   const char* data[] = {
    9662             :     "var asyncFn = async function() { await 1; };",
    9663             :     "var asyncFn = async function withName() { await 1; };",
    9664             :     "var asyncFn = async () => await 'test';",
    9665             :     "var asyncFn = async x => await x + 'test';",
    9666             :     "async function asyncFn() { await 1; }",
    9667             :     "var O = { async method() { await 1; } }",
    9668             :     "var O = { async ['meth' + 'od']() { await 1; } }",
    9669             :     "var O = { async 'method'() { await 1; } }",
    9670             :     "var O = { async 0() { await 1; } }",
    9671             :     "async function await() {}",
    9672             : 
    9673             :     "var asyncFn = async({ foo = 1 }) => foo;",
    9674             :     "var asyncFn = async({ foo = 1 } = {}) => foo;",
    9675             : 
    9676             :     "function* g() { var f = async(yield); }",
    9677             :     "function* g() { var f = async(x = yield); }",
    9678             : 
    9679             :     // v8:7817 assert that `await` is still allowed in the body of an arrow fn
    9680             :     // within formal parameters
    9681             :     "async(a = a => { var await = 1; return 1; }) => a()",
    9682             :     "async(a = await => 1); async(a) => 1",
    9683             :     "(async(a = await => 1), async(a) => 1)",
    9684             :     "async(a = await => 1, b = async() => 1);",
    9685             : 
    9686             :     nullptr
    9687           5 :   };
    9688             :   // clang-format on
    9689             : 
    9690           5 :   RunParserSyncTest(context_data, data, kSuccess);
    9691             : 
    9692             :   // clang-format off
    9693             :   const char* async_body_context_data[][2] = {
    9694             :     { "async function f() {", "}" },
    9695             :     { "var f = async function() {", "}" },
    9696             :     { "var f = async() => {", "}" },
    9697             :     { "var O = { async method() {", "} }" },
    9698             :     { "'use strict'; async function f() {", "}" },
    9699             :     { "'use strict'; var f = async function() {", "}" },
    9700             :     { "'use strict'; var f = async() => {", "}" },
    9701             :     { "'use strict'; var O = { async method() {", "} }" },
    9702             :     { nullptr, nullptr }
    9703           5 :   };
    9704             : 
    9705             :   const char* body_context_data[][2] = {
    9706             :     { "function f() {", "}" },
    9707             :     { "function* g() {", "}" },
    9708             :     { "var f = function() {", "}" },
    9709             :     { "var g = function*() {", "}" },
    9710             :     { "var O = { method() {", "} }" },
    9711             :     { "var O = { *method() {", "} }" },
    9712             :     { "var f = () => {", "}" },
    9713             :     { "'use strict'; function f() {", "}" },
    9714             :     { "'use strict'; function* g() {", "}" },
    9715             :     { "'use strict'; var f = function() {", "}" },
    9716             :     { "'use strict'; var g = function*() {", "}" },
    9717             :     { "'use strict'; var O = { method() {", "} }" },
    9718             :     { "'use strict'; var O = { *method() {", "} }" },
    9719             :     { "'use strict'; var f = () => {", "}" },
    9720             :     { nullptr, nullptr }
    9721           5 :   };
    9722             : 
    9723             :   const char* body_data[] = {
    9724             :     "var async = 1; return async;",
    9725             :     "let async = 1; return async;",
    9726             :     "const async = 1; return async;",
    9727             :     "function async() {} return async();",
    9728             :     "var async = async => async; return async();",
    9729             :     "function foo() { var await = 1; return await; }",
    9730             :     "function foo(await) { return await; }",
    9731             :     "function* foo() { var await = 1; return await; }",
    9732             :     "function* foo(await) { return await; }",
    9733             :     "var f = () => { var await = 1; return await; }",
    9734             :     "var O = { method() { var await = 1; return await; } };",
    9735             :     "var O = { method(await) { return await; } };",
    9736             :     "var O = { *method() { var await = 1; return await; } };",
    9737             :     "var O = { *method(await) { return await; } };",
    9738             :     "var asyncFn = async function*() {}",
    9739             :     "async function* f() {}",
    9740             :     "var O = { async *method() {} };",
    9741             : 
    9742             :     "(function await() {})",
    9743             :     nullptr
    9744           5 :   };
    9745             :   // clang-format on
    9746             : 
    9747           5 :   RunParserSyncTest(async_body_context_data, body_data, kSuccess);
    9748           5 :   RunParserSyncTest(body_context_data, body_data, kSuccess);
    9749           5 : }
    9750             : 
    9751       25880 : TEST(AsyncAwaitErrors) {
    9752             :   // clang-format off
    9753             :   const char* context_data[][2] = {
    9754             :     { "'use strict';", "" },
    9755             :     { "", "" },
    9756             :     { nullptr, nullptr }
    9757           5 :   };
    9758             : 
    9759             :   const char* strict_context_data[][2] = {
    9760             :     { "'use strict';", "" },
    9761             :     { nullptr, nullptr }
    9762           5 :   };
    9763             : 
    9764             :   const char* error_data[] = {
    9765             :     "var asyncFn = async function await() {};",
    9766             :     "var asyncFn = async () => var await = 'test';",
    9767             :     "var asyncFn = async await => await + 'test';",
    9768             :     "var asyncFn = async function(await) {};",
    9769             :     "var asyncFn = async (await) => 'test';",
    9770             :     "async function f(await) {}",
    9771             : 
    9772             :     "var O = { async method(a, a) {} }",
    9773             :     "var O = { async ['meth' + 'od'](a, a) {} }",
    9774             :     "var O = { async 'method'(a, a) {} }",
    9775             :     "var O = { async 0(a, a) {} }",
    9776             : 
    9777             :     "var f = async() => await;",
    9778             : 
    9779             :     "var O = { *async method() {} };",
    9780             :     "var O = { async method*() {} };",
    9781             : 
    9782             :     "var asyncFn = async function(x = await 1) { return x; }",
    9783             :     "async function f(x = await 1) { return x; }",
    9784             :     "var f = async(x = await 1) => x;",
    9785             :     "var O = { async method(x = await 1) { return x; } };",
    9786             : 
    9787             :     "function* g() { var f = async yield => 1; }",
    9788             :     "function* g() { var f = async(yield) => 1; }",
    9789             :     "function* g() { var f = async(x = yield) => 1; }",
    9790             :     "function* g() { var f = async({x = yield}) => 1; }",
    9791             : 
    9792             :     "class C { async constructor() {} }",
    9793             :     "class C {}; class C2 extends C { async constructor() {} }",
    9794             :     "class C { static async prototype() {} }",
    9795             :     "class C {}; class C2 extends C { static async prototype() {} }",
    9796             : 
    9797             :     "var f = async() => ((async(x = await 1) => x)();",
    9798             : 
    9799             :     // Henrique Ferreiro's bug (tm)
    9800             :     "(async function foo1() { } foo2 => 1)",
    9801             :     "(async function foo3() { } () => 1)",
    9802             :     "(async function foo4() { } => 1)",
    9803             :     "(async function() { } foo5 => 1)",
    9804             :     "(async function() { } () => 1)",
    9805             :     "(async function() { } => 1)",
    9806             :     "(async.foo6 => 1)",
    9807             :     "(async.foo7 foo8 => 1)",
    9808             :     "(async.foo9 () => 1)",
    9809             :     "(async().foo10 => 1)",
    9810             :     "(async().foo11 foo12 => 1)",
    9811             :     "(async().foo13 () => 1)",
    9812             :     "(async['foo14'] => 1)",
    9813             :     "(async['foo15'] foo16 => 1)",
    9814             :     "(async['foo17'] () => 1)",
    9815             :     "(async()['foo18'] => 1)",
    9816             :     "(async()['foo19'] foo20 => 1)",
    9817             :     "(async()['foo21'] () => 1)",
    9818             :     "(async`foo22` => 1)",
    9819             :     "(async`foo23` foo24 => 1)",
    9820             :     "(async`foo25` () => 1)",
    9821             :     "(async`foo26`.bar27 => 1)",
    9822             :     "(async`foo28`.bar29 foo30 => 1)",
    9823             :     "(async`foo31`.bar32 () => 1)",
    9824             : 
    9825             :     // v8:5148 assert that errors are still thrown for calls that may have been
    9826             :     // async functions
    9827             :     "async({ foo33 = 1 })",
    9828             : 
    9829             :     "async(...a = b) => b",
    9830             :     "async(...a,) => b",
    9831             :     "async(...a, b) => b",
    9832             : 
    9833             :     // v8:7817 assert that `await` is an invalid identifier in arrow formal
    9834             :     // parameters nested within an async arrow function
    9835             :     "async(a = await => 1) => a",
    9836             :     "async(a = (await) => 1) => a",
    9837             :     "async(a = (...await) => 1) => a",
    9838             :     nullptr
    9839           5 :   };
    9840             : 
    9841             :   const char* strict_error_data[] = {
    9842             :     "var O = { async method(eval) {} }",
    9843             :     "var O = { async ['meth' + 'od'](eval) {} }",
    9844             :     "var O = { async 'method'(eval) {} }",
    9845             :     "var O = { async 0(eval) {} }",
    9846             : 
    9847             :     "var O = { async method(arguments) {} }",
    9848             :     "var O = { async ['meth' + 'od'](arguments) {} }",
    9849             :     "var O = { async 'method'(arguments) {} }",
    9850             :     "var O = { async 0(arguments) {} }",
    9851             : 
    9852             :     "var O = { async method(dupe, dupe) {} }",
    9853             : 
    9854             :     // TODO(caitp): preparser needs to report duplicate parameter errors, too.
    9855             :     // "var f = async(dupe, dupe) => {}",
    9856             : 
    9857             :     nullptr
    9858           5 :   };
    9859             : 
    9860           5 :   RunParserSyncTest(context_data, error_data, kError);
    9861           5 :   RunParserSyncTest(strict_context_data, strict_error_data, kError);
    9862             : 
    9863             :   // clang-format off
    9864             :   const char* async_body_context_data[][2] = {
    9865             :     { "async function f() {", "}" },
    9866             :     { "var f = async function() {", "}" },
    9867             :     { "var f = async() => {", "}" },
    9868             :     { "var O = { async method() {", "} }" },
    9869             :     { "'use strict'; async function f() {", "}" },
    9870             :     { "'use strict'; var f = async function() {", "}" },
    9871             :     { "'use strict'; var f = async() => {", "}" },
    9872             :     { "'use strict'; var O = { async method() {", "} }" },
    9873             :     { nullptr, nullptr }
    9874           5 :   };
    9875             : 
    9876             :   const char* async_body_error_data[] = {
    9877             :     "var await = 1;",
    9878             :     "var { await } = 1;",
    9879             :     "var [ await ] = 1;",
    9880             :     "return async (await) => {};",
    9881             :     "var O = { async [await](a, a) {} }",
    9882             :     "await;",
    9883             : 
    9884             :     "function await() {}",
    9885             : 
    9886             :     "var f = await => 42;",
    9887             :     "var f = (await) => 42;",
    9888             :     "var f = (await, a) => 42;",
    9889             :     "var f = (...await) => 42;",
    9890             : 
    9891             :     "var e = (await);",
    9892             :     "var e = (await, f);",
    9893             :     "var e = (await = 42)",
    9894             : 
    9895             :     "var e = [await];",
    9896             :     "var e = {await};",
    9897             : 
    9898             :     nullptr
    9899           5 :   };
    9900             :   // clang-format on
    9901             : 
    9902           5 :   RunParserSyncTest(async_body_context_data, async_body_error_data, kError);
    9903           5 : }
    9904             : 
    9905       25880 : TEST(Regress7173) {
    9906             :   // Await expression is an invalid destructuring target, and should not crash
    9907             : 
    9908             :   // clang-format off
    9909             :   const char* error_context_data[][2] = {
    9910             :     { "'use strict'; async function f() {", "}" },
    9911             :     { "async function f() {", "}" },
    9912             :     { "'use strict'; function f() {", "}" },
    9913             :     { "function f() {", "}" },
    9914             :     { "let f = async() => {", "}" },
    9915             :     { "let f = () => {", "}" },
    9916             :     { "'use strict'; async function* f() {", "}" },
    9917             :     { "async function* f() {", "}" },
    9918             :     { "'use strict'; function* f() {", "}" },
    9919             :     { "function* f() {", "}" },
    9920             :     { nullptr, nullptr }
    9921           5 :   };
    9922             : 
    9923             :   const char* error_data[] = {
    9924             :     "var [await f] = [];",
    9925             :     "let [await f] = [];",
    9926             :     "const [await f] = [];",
    9927             : 
    9928             :     "var [...await f] = [];",
    9929             :     "let [...await f] = [];",
    9930             :     "const [...await f] = [];",
    9931             : 
    9932             :     "var { await f } = {};",
    9933             :     "let { await f } = {};",
    9934             :     "const { await f } = {};",
    9935             : 
    9936             :     "var { ...await f } = {};",
    9937             :     "let { ...await f } = {};",
    9938             :     "const { ...await f } = {};",
    9939             : 
    9940             :     "var { f: await f } = {};",
    9941             :     "let { f: await f } = {};",
    9942             :     "const { f: await f } = {};"
    9943             : 
    9944             :     "var { f: ...await f } = {};",
    9945             :     "let { f: ...await f } = {};",
    9946             :     "const { f: ...await f } = {};"
    9947             : 
    9948             :     "var { [f]: await f } = {};",
    9949             :     "let { [f]: await f } = {};",
    9950             :     "const { [f]: await f } = {};",
    9951             : 
    9952             :     "var { [f]: ...await f } = {};",
    9953             :     "let { [f]: ...await f } = {};",
    9954             :     "const { [f]: ...await f } = {};",
    9955             : 
    9956             :     nullptr
    9957           5 :   };
    9958             :   // clang-format on
    9959             : 
    9960           5 :   RunParserSyncTest(error_context_data, error_data, kError);
    9961           5 : }
    9962             : 
    9963       25880 : TEST(AsyncAwaitFormalParameters) {
    9964             :   // clang-format off
    9965             :   const char* context_for_formal_parameters[][2] = {
    9966             :     { "async function f(", ") {}" },
    9967             :     { "var f = async function f(", ") {}" },
    9968             :     { "var f = async(", ") => {}" },
    9969             :     { "'use strict'; async function f(", ") {}" },
    9970             :     { "'use strict'; var f = async function f(", ") {}" },
    9971             :     { "'use strict'; var f = async(", ") => {}" },
    9972             :     { nullptr, nullptr }
    9973           5 :   };
    9974             : 
    9975             :   const char* good_formal_parameters[] = {
    9976             :     "x = function await() {}",
    9977             :     "x = function *await() {}",
    9978             :     "x = function() { let await = 0; }",
    9979             :     "x = () => { let await = 0; }",
    9980             :     nullptr
    9981           5 :   };
    9982             : 
    9983             :   const char* bad_formal_parameters[] = {
    9984             :     "{ await }",
    9985             :     "{ await = 1 }",
    9986             :     "{ await } = {}",
    9987             :     "{ await = 1 } = {}",
    9988             :     "[await]",
    9989             :     "[await] = []",
    9990             :     "[await = 1]",
    9991             :     "[await = 1] = []",
    9992             :     "...await",
    9993             :     "await",
    9994             :     "await = 1",
    9995             :     "...[await]",
    9996             :     "x = await",
    9997             : 
    9998             :     // v8:5190
    9999             :     "1) => 1",
   10000             :     "'str') => 1",
   10001             :     "/foo/) => 1",
   10002             :     "{ foo = async(1) => 1 }) => 1",
   10003             :     "{ foo = async(a) => 1 })",
   10004             : 
   10005             :     "x = async(await)",
   10006             :     "x = { [await]: 1 }",
   10007             :     "x = class extends (await) { }",
   10008             :     "x = class { static [await]() {} }",
   10009             :     "{ x = await }",
   10010             : 
   10011             :     // v8:6714
   10012             :     "x = class await {}",
   10013             :     "x = 1 ? class await {} : 0",
   10014             :     "x = async function await() {}",
   10015             : 
   10016             :     "x = y[await]",
   10017             :     "x = `${await}`",
   10018             :     "x = y()[await]",
   10019             : 
   10020             :     nullptr
   10021           5 :   };
   10022             :   // clang-format on
   10023             : 
   10024             :   RunParserSyncTest(context_for_formal_parameters, good_formal_parameters,
   10025           5 :                     kSuccess);
   10026             : 
   10027             :   RunParserSyncTest(context_for_formal_parameters, bad_formal_parameters,
   10028           5 :                     kError);
   10029           5 : }
   10030             : 
   10031       25880 : TEST(AsyncAwaitModule) {
   10032             :   // clang-format off
   10033             :   const char* context_data[][2] = {
   10034             :     { "", "" },
   10035             :     { nullptr, nullptr }
   10036           5 :   };
   10037             : 
   10038             :   const char* data[] = {
   10039             :     "export default async function() { await 1; }",
   10040             :     "export default async function async() { await 1; }",
   10041             :     "export async function async() { await 1; }",
   10042             :     nullptr
   10043           5 :   };
   10044             :   // clang-format on
   10045             : 
   10046             :   RunModuleParserSyncTest(context_data, data, kSuccess, nullptr, 0, nullptr, 0,
   10047             :                           nullptr, 0, false);
   10048           5 : }
   10049             : 
   10050       25880 : TEST(AsyncAwaitModuleErrors) {
   10051             :   // clang-format off
   10052             :   const char* context_data[][2] = {
   10053             :     { "", "" },
   10054             :     { nullptr, nullptr }
   10055           5 :   };
   10056             : 
   10057             :   const char* error_data[] = {
   10058             :     "export default (async function await() {})",
   10059             :     "export default async function await() {}",
   10060             :     "export async function await() {}",
   10061             :     "export async function() {}",
   10062             :     "export async",
   10063             :     "export async\nfunction async() { await 1; }",
   10064             :     nullptr
   10065           5 :   };
   10066             :   // clang-format on
   10067             : 
   10068             :   RunModuleParserSyncTest(context_data, error_data, kError, nullptr, 0, nullptr,
   10069             :                           0, nullptr, 0, false);
   10070           5 : }
   10071             : 
   10072       25880 : TEST(RestrictiveForInErrors) {
   10073             :   // clang-format off
   10074             :   const char* strict_context_data[][2] = {
   10075             :     { "'use strict'", "" },
   10076             :     { nullptr, nullptr }
   10077           5 :   };
   10078             :   const char* sloppy_context_data[][2] = {
   10079             :     { "", "" },
   10080             :     { nullptr, nullptr }
   10081           5 :   };
   10082             :   const char* error_data[] = {
   10083             :     "for (const x = 0 in {});",
   10084             :     "for (let x = 0 in {});",
   10085             :     nullptr
   10086           5 :   };
   10087             :   const char* sloppy_data[] = {
   10088             :     "for (var x = 0 in {});",
   10089             :     nullptr
   10090           5 :   };
   10091             :   // clang-format on
   10092             : 
   10093           5 :   RunParserSyncTest(strict_context_data, error_data, kError);
   10094           5 :   RunParserSyncTest(strict_context_data, sloppy_data, kError);
   10095           5 :   RunParserSyncTest(sloppy_context_data, error_data, kError);
   10096           5 :   RunParserSyncTest(sloppy_context_data, sloppy_data, kSuccess);
   10097           5 : }
   10098             : 
   10099       25880 : TEST(NoDuplicateGeneratorsInBlock) {
   10100             :   const char* block_context_data[][2] = {
   10101             :       {"'use strict'; {", "}"},
   10102             :       {"{", "}"},
   10103             :       {"(function() { {", "} })()"},
   10104             :       {"(function() {'use strict'; {", "} })()"},
   10105           5 :       {nullptr, nullptr}};
   10106             :   const char* top_level_context_data[][2] = {
   10107             :       {"'use strict';", ""},
   10108             :       {"", ""},
   10109             :       {"(function() {", "})()"},
   10110             :       {"(function() {'use strict';", "})()"},
   10111           5 :       {nullptr, nullptr}};
   10112             :   const char* error_data[] = {"function* x() {} function* x() {}",
   10113             :                               "function x() {} function* x() {}",
   10114           5 :                               "function* x() {} function x() {}", nullptr};
   10115             :   // The preparser doesn't enforce the restriction, so turn it off.
   10116             :   bool test_preparser = false;
   10117             :   RunParserSyncTest(block_context_data, error_data, kError, nullptr, 0, nullptr,
   10118           5 :                     0, nullptr, 0, false, test_preparser);
   10119           5 :   RunParserSyncTest(top_level_context_data, error_data, kSuccess);
   10120           5 : }
   10121             : 
   10122       25880 : TEST(NoDuplicateAsyncFunctionInBlock) {
   10123             :   const char* block_context_data[][2] = {
   10124             :       {"'use strict'; {", "}"},
   10125             :       {"{", "}"},
   10126             :       {"(function() { {", "} })()"},
   10127             :       {"(function() {'use strict'; {", "} })()"},
   10128           5 :       {nullptr, nullptr}};
   10129             :   const char* top_level_context_data[][2] = {
   10130             :       {"'use strict';", ""},
   10131             :       {"", ""},
   10132             :       {"(function() {", "})()"},
   10133             :       {"(function() {'use strict';", "})()"},
   10134           5 :       {nullptr, nullptr}};
   10135             :   const char* error_data[] = {"async function x() {} async function x() {}",
   10136             :                               "function x() {} async function x() {}",
   10137             :                               "async function x() {} function x() {}",
   10138             :                               "function* x() {} async function x() {}",
   10139             :                               "function* x() {} async function x() {}",
   10140             :                               "async function x() {} function* x() {}",
   10141             :                               "function* x() {} async function x() {}",
   10142           5 :                               nullptr};
   10143             :   // The preparser doesn't enforce the restriction, so turn it off.
   10144             :   bool test_preparser = false;
   10145             :   RunParserSyncTest(block_context_data, error_data, kError, nullptr, 0, nullptr,
   10146           5 :                     0, nullptr, 0, false, test_preparser);
   10147           5 :   RunParserSyncTest(top_level_context_data, error_data, kSuccess);
   10148           5 : }
   10149             : 
   10150       25880 : TEST(TrailingCommasInParameters) {
   10151             :   // clang-format off
   10152             :   const char* context_data[][2] = {
   10153             :     { "", "" },
   10154             :     { "'use strict';", "" },
   10155             :     { "function foo() {", "}" },
   10156             :     { "function foo() {'use strict';", "}" },
   10157             :     { nullptr, nullptr }
   10158           5 :   };
   10159             : 
   10160             :   const char* data[] = {
   10161             :     " function  a(b,) {}",
   10162             :     " function* a(b,) {}",
   10163             :     "(function  a(b,) {});",
   10164             :     "(function* a(b,) {});",
   10165             :     "(function   (b,) {});",
   10166             :     "(function*  (b,) {});",
   10167             :     " function  a(b,c,d,) {}",
   10168             :     " function* a(b,c,d,) {}",
   10169             :     "(function  a(b,c,d,) {});",
   10170             :     "(function* a(b,c,d,) {});",
   10171             :     "(function   (b,c,d,) {});",
   10172             :     "(function*  (b,c,d,) {});",
   10173             :     "(b,) => {};",
   10174             :     "(b,c,d,) => {};",
   10175             :     "a(1,);",
   10176             :     "a(1,2,3,);",
   10177             :     "a(...[],);",
   10178             :     "a(1, 2, ...[],);",
   10179             :     "a(...[], 2, ...[],);",
   10180             :     nullptr
   10181           5 :   };
   10182             :   // clang-format on
   10183             : 
   10184           5 :   RunParserSyncTest(context_data, data, kSuccess);
   10185           5 : }
   10186             : 
   10187       25880 : TEST(TrailingCommasInParametersErrors) {
   10188             :   // clang-format off
   10189             :   const char* context_data[][2] = {
   10190             :     { "", "" },
   10191             :     { "'use strict';", "" },
   10192             :     { "function foo() {", "}" },
   10193             :     { "function foo() {'use strict';", "}" },
   10194             :     { nullptr, nullptr }
   10195           5 :   };
   10196             : 
   10197             :   const char* data[] = {
   10198             :     // too many trailing commas
   10199             :     " function  a(b,,) {}",
   10200             :     " function* a(b,,) {}",
   10201             :     "(function  a(b,,) {});",
   10202             :     "(function* a(b,,) {});",
   10203             :     "(function   (b,,) {});",
   10204             :     "(function*  (b,,) {});",
   10205             :     " function  a(b,c,d,,) {}",
   10206             :     " function* a(b,c,d,,) {}",
   10207             :     "(function  a(b,c,d,,) {});",
   10208             :     "(function* a(b,c,d,,) {});",
   10209             :     "(function   (b,c,d,,) {});",
   10210             :     "(function*  (b,c,d,,) {});",
   10211             :     "(b,,) => {};",
   10212             :     "(b,c,d,,) => {};",
   10213             :     "a(1,,);",
   10214             :     "a(1,2,3,,);",
   10215             :     // only a trailing comma and no parameters
   10216             :     " function  a1(,) {}",
   10217             :     " function* a2(,) {}",
   10218             :     "(function  a3(,) {});",
   10219             :     "(function* a4(,) {});",
   10220             :     "(function    (,) {});",
   10221             :     "(function*   (,) {});",
   10222             :     "(,) => {};",
   10223             :     "a1(,);",
   10224             :     // no trailing commas after rest parameter declaration
   10225             :     " function  a(...b,) {}",
   10226             :     " function* a(...b,) {}",
   10227             :     "(function  a(...b,) {});",
   10228             :     "(function* a(...b,) {});",
   10229             :     "(function   (...b,) {});",
   10230             :     "(function*  (...b,) {});",
   10231             :     " function  a(b, c, ...d,) {}",
   10232             :     " function* a(b, c, ...d,) {}",
   10233             :     "(function  a(b, c, ...d,) {});",
   10234             :     "(function* a(b, c, ...d,) {});",
   10235             :     "(function   (b, c, ...d,) {});",
   10236             :     "(function*  (b, c, ...d,) {});",
   10237             :     "(...b,) => {};",
   10238             :     "(b, c, ...d,) => {};",
   10239             :     // parenthesized trailing comma without arrow is still an error
   10240             :     "(,);",
   10241             :     "(a,);",
   10242             :     "(a,b,c,);",
   10243             :     nullptr
   10244           5 :   };
   10245             :   // clang-format on
   10246             : 
   10247           5 :   RunParserSyncTest(context_data, data, kError);
   10248           5 : }
   10249             : 
   10250       25880 : TEST(ArgumentsRedeclaration) {
   10251             :   {
   10252             :     // clang-format off
   10253             :     const char* context_data[][2] = {
   10254             :       { "function f(", ") {}" },
   10255             :       { nullptr, nullptr }
   10256           5 :     };
   10257             :     const char* success_data[] = {
   10258             :       "{arguments}",
   10259             :       "{arguments = false}",
   10260             :       "arg1, arguments",
   10261             :       "arg1, ...arguments",
   10262             :       nullptr
   10263           5 :     };
   10264             :     // clang-format on
   10265           5 :     RunParserSyncTest(context_data, success_data, kSuccess);
   10266             :   }
   10267             : 
   10268             :   {
   10269             :     // clang-format off
   10270             :     const char* context_data[][2] = {
   10271             :       { "function f() {", "}" },
   10272             :       { nullptr, nullptr }
   10273           5 :     };
   10274             :     const char* data[] = {
   10275             :       "const arguments = 1",
   10276             :       "let arguments",
   10277             :       "var arguments",
   10278             :       nullptr
   10279           5 :     };
   10280             :     // clang-format on
   10281           5 :     RunParserSyncTest(context_data, data, kSuccess);
   10282             :   }
   10283           5 : }
   10284             : 
   10285             : 
   10286             : // Test that lazily parsed inner functions don't result in overly pessimistic
   10287             : // context allocations.
   10288       25880 : TEST(NoPessimisticContextAllocation) {
   10289             :   i::Isolate* isolate = CcTest::i_isolate();
   10290             :   i::Factory* factory = isolate->factory();
   10291             :   i::HandleScope scope(isolate);
   10292          10 :   LocalContext env;
   10293             : 
   10294             :   const char* prefix = "(function outer() { var my_var; ";
   10295             :   const char* suffix = " })();";
   10296           5 :   int prefix_len = Utf8LengthHelper(prefix);
   10297           5 :   int suffix_len = Utf8LengthHelper(suffix);
   10298             : 
   10299             :   // Test both normal inner functions and inner arrow functions.
   10300             :   const char* inner_functions[] = {"function inner(%s) { %s }",
   10301           5 :                                    "(%s) => { %s }"};
   10302             : 
   10303             :   struct {
   10304             :     const char* params;
   10305             :     const char* source;
   10306             :     bool ctxt_allocate;
   10307             :   } inners[] = {
   10308             :       // Context allocating because we need to:
   10309             :       {"", "my_var;", true},
   10310             :       {"", "if (true) { let my_var; } my_var;", true},
   10311             :       {"", "eval('foo');", true},
   10312             :       {"", "function inner2() { my_var; }", true},
   10313             :       {"", "function inner2() { eval('foo'); }", true},
   10314             :       {"", "var {my_var : a} = {my_var};", true},
   10315             :       {"", "let {my_var : a} = {my_var};", true},
   10316             :       {"", "const {my_var : a} = {my_var};", true},
   10317             :       {"", "var [a, b = my_var] = [1, 2];", true},
   10318             :       {"", "var [a, b = my_var] = [1, 2]; my_var;", true},
   10319             :       {"", "let [a, b = my_var] = [1, 2];", true},
   10320             :       {"", "let [a, b = my_var] = [1, 2]; my_var;", true},
   10321             :       {"", "const [a, b = my_var] = [1, 2];", true},
   10322             :       {"", "const [a, b = my_var] = [1, 2]; my_var;", true},
   10323             :       {"", "var {a = my_var} = {}", true},
   10324             :       {"", "var {a: b = my_var} = {}", true},
   10325             :       {"", "let {a = my_var} = {}", true},
   10326             :       {"", "let {a: b = my_var} = {}", true},
   10327             :       {"", "const {a = my_var} = {}", true},
   10328             :       {"", "const {a: b = my_var} = {}", true},
   10329             :       {"a = my_var", "", true},
   10330             :       {"a = my_var", "let my_var;", true},
   10331             :       {"", "function inner2(a = my_var) { }", true},
   10332             :       {"", "(a = my_var) => { }", true},
   10333             :       {"{a} = {a: my_var}", "", true},
   10334             :       {"", "function inner2({a} = {a: my_var}) { }", true},
   10335             :       {"", "({a} = {a: my_var}) => { }", true},
   10336             :       {"[a] = [my_var]", "", true},
   10337             :       {"", "function inner2([a] = [my_var]) { }", true},
   10338             :       {"", "([a] = [my_var]) => { }", true},
   10339             :       {"", "function inner2(a = eval('')) { }", true},
   10340             :       {"", "(a = eval('')) => { }", true},
   10341             :       {"", "try { } catch (my_var) { } my_var;", true},
   10342             :       {"", "for (my_var in {}) { my_var; }", true},
   10343             :       {"", "for (my_var in {}) { }", true},
   10344             :       {"", "for (my_var of []) { my_var; }", true},
   10345             :       {"", "for (my_var of []) { }", true},
   10346             :       {"", "for ([a, my_var, b] in {}) { my_var; }", true},
   10347             :       {"", "for ([a, my_var, b] of []) { my_var; }", true},
   10348             :       {"", "for ({x: my_var} in {}) { my_var; }", true},
   10349             :       {"", "for ({x: my_var} of []) { my_var; }", true},
   10350             :       {"", "for ({my_var} in {}) { my_var; }", true},
   10351             :       {"", "for ({my_var} of []) { my_var; }", true},
   10352             :       {"", "for ({y, x: my_var} in {}) { my_var; }", true},
   10353             :       {"", "for ({y, x: my_var} of []) { my_var; }", true},
   10354             :       {"", "for ({a, my_var} in {}) { my_var; }", true},
   10355             :       {"", "for ({a, my_var} of []) { my_var; }", true},
   10356             :       {"", "for (let my_var in {}) { } my_var;", true},
   10357             :       {"", "for (let my_var of []) { } my_var;", true},
   10358             :       {"", "for (let [a, my_var, b] in {}) { } my_var;", true},
   10359             :       {"", "for (let [a, my_var, b] of []) { } my_var;", true},
   10360             :       {"", "for (let {x: my_var} in {}) { } my_var;", true},
   10361             :       {"", "for (let {x: my_var} of []) { } my_var;", true},
   10362             :       {"", "for (let {my_var} in {}) { } my_var;", true},
   10363             :       {"", "for (let {my_var} of []) { } my_var;", true},
   10364             :       {"", "for (let {y, x: my_var} in {}) { } my_var;", true},
   10365             :       {"", "for (let {y, x: my_var} of []) { } my_var;", true},
   10366             :       {"", "for (let {a, my_var} in {}) { } my_var;", true},
   10367             :       {"", "for (let {a, my_var} of []) { } my_var;", true},
   10368             :       {"", "for (let my_var = 0; my_var < 1; ++my_var) { } my_var;", true},
   10369             :       {"", "'use strict'; if (true) { function my_var() {} } my_var;", true},
   10370             :       {"",
   10371             :        "'use strict'; function inner2() { if (true) { function my_var() {} }  "
   10372             :        "my_var; }",
   10373             :        true},
   10374             :       {"",
   10375             :        "function inner2() { 'use strict'; if (true) { function my_var() {} }  "
   10376             :        "my_var; }",
   10377             :        true},
   10378             :       {"",
   10379             :        "() => { 'use strict'; if (true) { function my_var() {} }  my_var; }",
   10380             :        true},
   10381             :       {"",
   10382             :        "if (true) { let my_var; if (true) { function my_var() {} } } my_var;",
   10383             :        true},
   10384             :       {"", "function inner2(a = my_var) {}", true},
   10385             :       {"", "function inner2(a = my_var) { let my_var; }", true},
   10386             :       {"", "(a = my_var) => {}", true},
   10387             :       {"", "(a = my_var) => { let my_var; }", true},
   10388             :       // No pessimistic context allocation:
   10389             :       {"", "var my_var; my_var;", false},
   10390             :       {"", "var my_var;", false},
   10391             :       {"", "var my_var = 0;", false},
   10392             :       {"", "if (true) { var my_var; } my_var;", false},
   10393             :       {"", "let my_var; my_var;", false},
   10394             :       {"", "let my_var;", false},
   10395             :       {"", "let my_var = 0;", false},
   10396             :       {"", "const my_var = 0; my_var;", false},
   10397             :       {"", "const my_var = 0;", false},
   10398             :       {"", "var [a, my_var] = [1, 2]; my_var;", false},
   10399             :       {"", "let [a, my_var] = [1, 2]; my_var;", false},
   10400             :       {"", "const [a, my_var] = [1, 2]; my_var;", false},
   10401             :       {"", "var {a: my_var} = {a: 3}; my_var;", false},
   10402             :       {"", "let {a: my_var} = {a: 3}; my_var;", false},
   10403             :       {"", "const {a: my_var} = {a: 3}; my_var;", false},
   10404             :       {"", "var {my_var} = {my_var: 3}; my_var;", false},
   10405             :       {"", "let {my_var} = {my_var: 3}; my_var;", false},
   10406             :       {"", "const {my_var} = {my_var: 3}; my_var;", false},
   10407             :       {"my_var", "my_var;", false},
   10408             :       {"my_var", "", false},
   10409             :       {"my_var = 5", "my_var;", false},
   10410             :       {"my_var = 5", "", false},
   10411             :       {"...my_var", "my_var;", false},
   10412             :       {"...my_var", "", false},
   10413             :       {"[a, my_var, b]", "my_var;", false},
   10414             :       {"[a, my_var, b]", "", false},
   10415             :       {"[a, my_var, b] = [1, 2, 3]", "my_var;", false},
   10416             :       {"[a, my_var, b] = [1, 2, 3]", "", false},
   10417             :       {"{x: my_var}", "my_var;", false},
   10418             :       {"{x: my_var}", "", false},
   10419             :       {"{x: my_var} = {x: 0}", "my_var;", false},
   10420             :       {"{x: my_var} = {x: 0}", "", false},
   10421             :       {"{my_var}", "my_var;", false},
   10422             :       {"{my_var}", "", false},
   10423             :       {"{my_var} = {my_var: 0}", "my_var;", false},
   10424             :       {"{my_var} = {my_var: 0}", "", false},
   10425             :       {"", "function inner2(my_var) { my_var; }", false},
   10426             :       {"", "function inner2(my_var) { }", false},
   10427             :       {"", "function inner2(my_var = 5) { my_var; }", false},
   10428             :       {"", "function inner2(my_var = 5) { }", false},
   10429             :       {"", "function inner2(...my_var) { my_var; }", false},
   10430             :       {"", "function inner2(...my_var) { }", false},
   10431             :       {"", "function inner2([a, my_var, b]) { my_var; }", false},
   10432             :       {"", "function inner2([a, my_var, b]) { }", false},
   10433             :       {"", "function inner2([a, my_var, b] = [1, 2, 3]) { my_var; }", false},
   10434             :       {"", "function inner2([a, my_var, b] = [1, 2, 3]) { }", false},
   10435             :       {"", "function inner2({x: my_var}) { my_var; }", false},
   10436             :       {"", "function inner2({x: my_var}) { }", false},
   10437             :       {"", "function inner2({x: my_var} = {x: 0}) { my_var; }", false},
   10438             :       {"", "function inner2({x: my_var} = {x: 0}) { }", false},
   10439             :       {"", "function inner2({my_var}) { my_var; }", false},
   10440             :       {"", "function inner2({my_var}) { }", false},
   10441             :       {"", "function inner2({my_var} = {my_var: 8}) { my_var; } ", false},
   10442             :       {"", "function inner2({my_var} = {my_var: 8}) { }", false},
   10443             :       {"", "my_var => my_var;", false},
   10444             :       {"", "my_var => { }", false},
   10445             :       {"", "(my_var = 5) => my_var;", false},
   10446             :       {"", "(my_var = 5) => { }", false},
   10447             :       {"", "(...my_var) => my_var;", false},
   10448             :       {"", "(...my_var) => { }", false},
   10449             :       {"", "([a, my_var, b]) => my_var;", false},
   10450             :       {"", "([a, my_var, b]) => { }", false},
   10451             :       {"", "([a, my_var, b] = [1, 2, 3]) => my_var;", false},
   10452             :       {"", "([a, my_var, b] = [1, 2, 3]) => { }", false},
   10453             :       {"", "({x: my_var}) => my_var;", false},
   10454             :       {"", "({x: my_var}) => { }", false},
   10455             :       {"", "({x: my_var} = {x: 0}) => my_var;", false},
   10456             :       {"", "({x: my_var} = {x: 0}) => { }", false},
   10457             :       {"", "({my_var}) => my_var;", false},
   10458             :       {"", "({my_var}) => { }", false},
   10459             :       {"", "({my_var} = {my_var: 5}) => my_var;", false},
   10460             :       {"", "({my_var} = {my_var: 5}) => { }", false},
   10461             :       {"", "({a, my_var}) => my_var;", false},
   10462             :       {"", "({a, my_var}) => { }", false},
   10463             :       {"", "({a, my_var} = {a: 0, my_var: 5}) => my_var;", false},
   10464             :       {"", "({a, my_var} = {a: 0, my_var: 5}) => { }", false},
   10465             :       {"", "({y, x: my_var}) => my_var;", false},
   10466             :       {"", "({y, x: my_var}) => { }", false},
   10467             :       {"", "({y, x: my_var} = {y: 0, x: 0}) => my_var;", false},
   10468             :       {"", "({y, x: my_var} = {y: 0, x: 0}) => { }", false},
   10469             :       {"", "try { } catch (my_var) { my_var; }", false},
   10470             :       {"", "try { } catch ([a, my_var, b]) { my_var; }", false},
   10471             :       {"", "try { } catch ({x: my_var}) { my_var; }", false},
   10472             :       {"", "try { } catch ({y, x: my_var}) { my_var; }", false},
   10473             :       {"", "try { } catch ({my_var}) { my_var; }", false},
   10474             :       {"", "for (let my_var in {}) { my_var; }", false},
   10475             :       {"", "for (let my_var in {}) { }", false},
   10476             :       {"", "for (let my_var of []) { my_var; }", false},
   10477             :       {"", "for (let my_var of []) { }", false},
   10478             :       {"", "for (let [a, my_var, b] in {}) { my_var; }", false},
   10479             :       {"", "for (let [a, my_var, b] of []) { my_var; }", false},
   10480             :       {"", "for (let {x: my_var} in {}) { my_var; }", false},
   10481             :       {"", "for (let {x: my_var} of []) { my_var; }", false},
   10482             :       {"", "for (let {my_var} in {}) { my_var; }", false},
   10483             :       {"", "for (let {my_var} of []) { my_var; }", false},
   10484             :       {"", "for (let {y, x: my_var} in {}) { my_var; }", false},
   10485             :       {"", "for (let {y, x: my_var} of []) { my_var; }", false},
   10486             :       {"", "for (let {a, my_var} in {}) { my_var; }", false},
   10487             :       {"", "for (let {a, my_var} of []) { my_var; }", false},
   10488             :       {"", "for (var my_var in {}) { my_var; }", false},
   10489             :       {"", "for (var my_var in {}) { }", false},
   10490             :       {"", "for (var my_var of []) { my_var; }", false},
   10491             :       {"", "for (var my_var of []) { }", false},
   10492             :       {"", "for (var [a, my_var, b] in {}) { my_var; }", false},
   10493             :       {"", "for (var [a, my_var, b] of []) { my_var; }", false},
   10494             :       {"", "for (var {x: my_var} in {}) { my_var; }", false},
   10495             :       {"", "for (var {x: my_var} of []) { my_var; }", false},
   10496             :       {"", "for (var {my_var} in {}) { my_var; }", false},
   10497             :       {"", "for (var {my_var} of []) { my_var; }", false},
   10498             :       {"", "for (var {y, x: my_var} in {}) { my_var; }", false},
   10499             :       {"", "for (var {y, x: my_var} of []) { my_var; }", false},
   10500             :       {"", "for (var {a, my_var} in {}) { my_var; }", false},
   10501             :       {"", "for (var {a, my_var} of []) { my_var; }", false},
   10502             :       {"", "for (var my_var in {}) { } my_var;", false},
   10503             :       {"", "for (var my_var of []) { } my_var;", false},
   10504             :       {"", "for (var [a, my_var, b] in {}) { } my_var;", false},
   10505             :       {"", "for (var [a, my_var, b] of []) { } my_var;", false},
   10506             :       {"", "for (var {x: my_var} in {}) { } my_var;", false},
   10507             :       {"", "for (var {x: my_var} of []) { } my_var;", false},
   10508             :       {"", "for (var {my_var} in {}) { } my_var;", false},
   10509             :       {"", "for (var {my_var} of []) { } my_var;", false},
   10510             :       {"", "for (var {y, x: my_var} in {}) { } my_var;", false},
   10511             :       {"", "for (var {y, x: my_var} of []) { } my_var;", false},
   10512             :       {"", "for (var {a, my_var} in {}) { } my_var;", false},
   10513             :       {"", "for (var {a, my_var} of []) { } my_var;", false},
   10514             :       {"", "for (let my_var = 0; my_var < 1; ++my_var) { my_var; }", false},
   10515             :       {"", "for (var my_var = 0; my_var < 1; ++my_var) { my_var; }", false},
   10516             :       {"", "for (var my_var = 0; my_var < 1; ++my_var) { } my_var; ", false},
   10517             :       {"", "for (let a = 0, my_var = 0; my_var < 1; ++my_var) { my_var }",
   10518             :        false},
   10519             :       {"", "for (var a = 0, my_var = 0; my_var < 1; ++my_var) { my_var }",
   10520             :        false},
   10521             :       {"", "class my_var {}; my_var; ", false},
   10522             :       {"", "function my_var() {} my_var;", false},
   10523             :       {"", "if (true) { function my_var() {} }  my_var;", false},
   10524             :       {"", "function inner2() { if (true) { function my_var() {} }  my_var; }",
   10525             :        false},
   10526             :       {"", "() => { if (true) { function my_var() {} }  my_var; }", false},
   10527             :       {"",
   10528             :        "if (true) { var my_var; if (true) { function my_var() {} } }  my_var;",
   10529             :        false},
   10530           5 :   };
   10531             : 
   10532          15 :   for (unsigned inner_ix = 0; inner_ix < arraysize(inner_functions);
   10533             :        ++inner_ix) {
   10534          10 :     const char* inner_function = inner_functions[inner_ix];
   10535          10 :     int inner_function_len = Utf8LengthHelper(inner_function) - 4;
   10536             : 
   10537        2060 :     for (unsigned i = 0; i < arraysize(inners); ++i) {
   10538        2050 :       int params_len = Utf8LengthHelper(inners[i].params);
   10539        2050 :       int source_len = Utf8LengthHelper(inners[i].source);
   10540        2050 :       int len = prefix_len + inner_function_len + params_len + source_len +
   10541        2050 :                 suffix_len;
   10542             : 
   10543        2050 :       i::ScopedVector<char> program(len + 1);
   10544        2050 :       i::SNPrintF(program, "%s", prefix);
   10545             :       i::SNPrintF(program + prefix_len, inner_function, inners[i].params,
   10546        4100 :                   inners[i].source);
   10547             :       i::SNPrintF(
   10548        2050 :           program + prefix_len + inner_function_len + params_len + source_len,
   10549        4100 :           "%s", suffix);
   10550             : 
   10551             :       i::Handle<i::String> source =
   10552        2050 :           factory->InternalizeUtf8String(program.start());
   10553        4100 :       source->PrintOn(stdout);
   10554             :       printf("\n");
   10555             : 
   10556        2050 :       i::Handle<i::Script> script = factory->NewScript(source);
   10557        4100 :       i::ParseInfo info(isolate, script);
   10558             : 
   10559        2050 :       CHECK(i::parsing::ParseProgram(&info, isolate));
   10560        2050 :       CHECK(i::Compiler::Analyze(&info));
   10561        2050 :       CHECK_NOT_NULL(info.literal());
   10562             : 
   10563        2050 :       i::Scope* scope = info.literal()->scope()->inner_scope();
   10564             :       DCHECK_NOT_NULL(scope);
   10565             :       DCHECK_NULL(scope->sibling());
   10566             :       DCHECK(scope->is_function_scope());
   10567             :       const i::AstRawString* var_name =
   10568        2050 :           info.ast_value_factory()->GetOneByteString("my_var");
   10569             :       i::Variable* var = scope->LookupForTesting(var_name);
   10570        2050 :       CHECK_EQ(inners[i].ctxt_allocate,
   10571             :                i::ScopeTestHelper::MustAllocateInContext(var));
   10572             :     }
   10573             :   }
   10574           5 : }
   10575             : 
   10576       25880 : TEST(EscapedStrictReservedWord) {
   10577             :   // Test that identifiers which are both escaped and only reserved in the
   10578             :   // strict mode are accepted in non-strict mode.
   10579           5 :   const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
   10580             : 
   10581             :   const char* statement_data[] = {"if (true) l\\u0065t: ;",
   10582             :                                   "function l\\u0065t() { }",
   10583             :                                   "(function l\\u0065t() { })",
   10584             :                                   "async function l\\u0065t() { }",
   10585             :                                   "(async function l\\u0065t() { })",
   10586             :                                   "l\\u0065t => 42",
   10587             :                                   "async l\\u0065t => 42",
   10588             :                                   "function packag\\u0065() {}",
   10589             :                                   "function impl\\u0065ments() {}",
   10590             :                                   "function privat\\u0065() {}",
   10591           5 :                                   nullptr};
   10592             : 
   10593           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
   10594           5 : }
   10595             : 
   10596       25880 : TEST(ForAwaitOf) {
   10597             :   // clang-format off
   10598             :   const char* context_data[][2] = {
   10599             :     { "async function f() { for await ", " ; }" },
   10600             :     { "async function f() { for await ", " { } }" },
   10601             :     { "async function * f() { for await ", " { } }" },
   10602             :     { "async function f() { 'use strict'; for await ", " ; }" },
   10603             :     { "async function f() { 'use strict'; for await ", "  { } }" },
   10604             :     { "async function * f() { 'use strict'; for await ", "  { } }" },
   10605             :     { "async function f() { for\nawait ", " ; }" },
   10606             :     { "async function f() { for\nawait ", " { } }" },
   10607             :     { "async function * f() { for\nawait ", " { } }" },
   10608             :     { "async function f() { 'use strict'; for\nawait ", " ; }" },
   10609             :     { "async function f() { 'use strict'; for\nawait ", " { } }" },
   10610             :     { "async function * f() { 'use strict'; for\nawait ", " { } }" },
   10611             :     { "async function f() { for await\n", " ; }" },
   10612             :     { "async function f() { for await\n", " { } }" },
   10613             :     { "async function * f() { for await\n", " { } }" },
   10614             :     { "async function f() { 'use strict'; for await\n", " ; }" },
   10615             :     { "async function f() { 'use strict'; for await\n", " { } }" },
   10616             :     { "async function * f() { 'use strict'; for await\n", " { } }" },
   10617             :     { nullptr, nullptr }
   10618           5 :   };
   10619             : 
   10620             :   const char* context_data2[][2] = {
   10621             :     { "async function f() { let a; for await ", " ; }" },
   10622             :     { "async function f() { let a; for await ", " { } }" },
   10623             :     { "async function * f() { let a; for await ", " { } }" },
   10624             :     { "async function f() { 'use strict'; let a; for await ", " ; }" },
   10625             :     { "async function f() { 'use strict'; let a; for await ", "  { } }" },
   10626             :     { "async function * f() { 'use strict'; let a; for await ", "  { } }" },
   10627             :     { "async function f() { let a; for\nawait ", " ; }" },
   10628             :     { "async function f() { let a; for\nawait ", " { } }" },
   10629             :     { "async function * f() { let a; for\nawait ", " { } }" },
   10630             :     { "async function f() { 'use strict'; let a; for\nawait ", " ; }" },
   10631             :     { "async function f() { 'use strict'; let a; for\nawait ", " { } }" },
   10632             :     { "async function * f() { 'use strict'; let a; for\nawait ", " { } }" },
   10633             :     { "async function f() { let a; for await\n", " ; }" },
   10634             :     { "async function f() { let a; for await\n", " { } }" },
   10635             :     { "async function * f() { let a; for await\n", " { } }" },
   10636             :     { "async function f() { 'use strict'; let a; for await\n", " ; }" },
   10637             :     { "async function f() { 'use strict'; let a; for await\n", " { } }" },
   10638             :     { "async function * f() { 'use strict'; let a; for await\n", " { } }" },
   10639             :     { nullptr, nullptr }
   10640           5 :   };
   10641             : 
   10642             :   const char* expr_data[] = {
   10643             :     // Primary Expressions
   10644             :     "(a of [])",
   10645             :     "(a.b of [])",
   10646             :     "([a] of [])",
   10647             :     "([a = 1] of [])",
   10648             :     "([a = 1, ...b] of [])",
   10649             :     "({a} of [])",
   10650             :     "({a: a} of [])",
   10651             :     "({'a': a} of [])",
   10652             :     "({\"a\": a} of [])",
   10653             :     "({[Symbol.iterator]: a} of [])",
   10654             :     "({0: a} of [])",
   10655             :     "({a = 1} of [])",
   10656             :     "({a: a = 1} of [])",
   10657             :     "({'a': a = 1} of [])",
   10658             :     "({\"a\": a = 1} of [])",
   10659             :     "({[Symbol.iterator]: a = 1} of [])",
   10660             :     "({0: a = 1} of [])",
   10661             :     nullptr
   10662           5 :   };
   10663             : 
   10664             :   const char* var_data[] = {
   10665             :     // VarDeclarations
   10666             :     "(var a of [])",
   10667             :     "(var [a] of [])",
   10668             :     "(var [a = 1] of [])",
   10669             :     "(var [a = 1, ...b] of [])",
   10670             :     "(var {a} of [])",
   10671             :     "(var {a: a} of [])",
   10672             :     "(var {'a': a} of [])",
   10673             :     "(var {\"a\": a} of [])",
   10674             :     "(var {[Symbol.iterator]: a} of [])",
   10675             :     "(var {0: a} of [])",
   10676             :     "(var {a = 1} of [])",
   10677             :     "(var {a: a = 1} of [])",
   10678             :     "(var {'a': a = 1} of [])",
   10679             :     "(var {\"a\": a = 1} of [])",
   10680             :     "(var {[Symbol.iterator]: a = 1} of [])",
   10681             :     "(var {0: a = 1} of [])",
   10682             :     nullptr
   10683           5 :   };
   10684             : 
   10685             :   const char* lexical_data[] = {
   10686             :     // LexicalDeclartions
   10687             :     "(let a of [])",
   10688             :     "(let [a] of [])",
   10689             :     "(let [a = 1] of [])",
   10690             :     "(let [a = 1, ...b] of [])",
   10691             :     "(let {a} of [])",
   10692             :     "(let {a: a} of [])",
   10693             :     "(let {'a': a} of [])",
   10694             :     "(let {\"a\": a} of [])",
   10695             :     "(let {[Symbol.iterator]: a} of [])",
   10696             :     "(let {0: a} of [])",
   10697             :     "(let {a = 1} of [])",
   10698             :     "(let {a: a = 1} of [])",
   10699             :     "(let {'a': a = 1} of [])",
   10700             :     "(let {\"a\": a = 1} of [])",
   10701             :     "(let {[Symbol.iterator]: a = 1} of [])",
   10702             :     "(let {0: a = 1} of [])",
   10703             : 
   10704             :     "(const a of [])",
   10705             :     "(const [a] of [])",
   10706             :     "(const [a = 1] of [])",
   10707             :     "(const [a = 1, ...b] of [])",
   10708             :     "(const {a} of [])",
   10709             :     "(const {a: a} of [])",
   10710             :     "(const {'a': a} of [])",
   10711             :     "(const {\"a\": a} of [])",
   10712             :     "(const {[Symbol.iterator]: a} of [])",
   10713             :     "(const {0: a} of [])",
   10714             :     "(const {a = 1} of [])",
   10715             :     "(const {a: a = 1} of [])",
   10716             :     "(const {'a': a = 1} of [])",
   10717             :     "(const {\"a\": a = 1} of [])",
   10718             :     "(const {[Symbol.iterator]: a = 1} of [])",
   10719             :     "(const {0: a = 1} of [])",
   10720             :     nullptr
   10721           5 :   };
   10722             :   // clang-format on
   10723           5 :   RunParserSyncTest(context_data, expr_data, kSuccess);
   10724           5 :   RunParserSyncTest(context_data2, expr_data, kSuccess);
   10725             : 
   10726           5 :   RunParserSyncTest(context_data, var_data, kSuccess);
   10727             :   // TODO(marja): PreParser doesn't report early errors.
   10728             :   //              (https://bugs.chromium.org/p/v8/issues/detail?id=2728)
   10729             :   // RunParserSyncTest(context_data2, var_data, kError, nullptr, 0,
   10730             :   // always_flags,
   10731             :   //                   arraysize(always_flags));
   10732             : 
   10733           5 :   RunParserSyncTest(context_data, lexical_data, kSuccess);
   10734           5 :   RunParserSyncTest(context_data2, lexical_data, kSuccess);
   10735           5 : }
   10736             : 
   10737       25880 : TEST(ForAwaitOfErrors) {
   10738             :   // clang-format off
   10739             :   const char* context_data[][2] = {
   10740             :     { "async function f() { for await ", " ; }" },
   10741             :     { "async function f() { for await ", " { } }" },
   10742             :     { "async function f() { 'use strict'; for await ", " ; }" },
   10743             :     { "async function f() { 'use strict'; for await ", "  { } }" },
   10744             :     { "async function * f() { for await ", " ; }" },
   10745             :     { "async function * f() { for await ", " { } }" },
   10746             :     { "async function * f() { 'use strict'; for await ", " ; }" },
   10747             :     { "async function * f() { 'use strict'; for await ", "  { } }" },
   10748             :     { nullptr, nullptr }
   10749           5 :   };
   10750             : 
   10751             :   const char* data[] = {
   10752             :     // Primary Expressions
   10753             :     "(a = 1 of [])",
   10754             :     "(a = 1) of [])",
   10755             :     "(a.b = 1 of [])",
   10756             :     "((a.b = 1) of [])",
   10757             :     "([a] = 1 of [])",
   10758             :     "(([a] = 1) of [])",
   10759             :     "([a = 1] = 1 of [])",
   10760             :     "(([a = 1] = 1) of [])",
   10761             :     "([a = 1 = 1, ...b] = 1 of [])",
   10762             :     "(([a = 1 = 1, ...b] = 1) of [])",
   10763             :     "({a} = 1 of [])",
   10764             :     "(({a} = 1) of [])",
   10765             :     "({a: a} = 1 of [])",
   10766             :     "(({a: a} = 1) of [])",
   10767             :     "({'a': a} = 1 of [])",
   10768             :     "(({'a': a} = 1) of [])",
   10769             :     "({\"a\": a} = 1 of [])",
   10770             :     "(({\"a\": a} = 1) of [])",
   10771             :     "({[Symbol.iterator]: a} = 1 of [])",
   10772             :     "(({[Symbol.iterator]: a} = 1) of [])",
   10773             :     "({0: a} = 1 of [])",
   10774             :     "(({0: a} = 1) of [])",
   10775             :     "({a = 1} = 1 of [])",
   10776             :     "(({a = 1} = 1) of [])",
   10777             :     "({a: a = 1} = 1 of [])",
   10778             :     "(({a: 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             :     "({[Symbol.iterator]: a = 1} = 1 of [])",
   10784             :     "(({[Symbol.iterator]: a = 1} = 1) of [])",
   10785             :     "({0: a = 1} = 1 of [])",
   10786             :     "(({0: a = 1} = 1) of [])",
   10787             :     "(function a() {} of [])",
   10788             :     "([1] of [])",
   10789             :     "({a: 1} of [])"
   10790             : 
   10791             :     // VarDeclarations
   10792             :     "(var a = 1 of [])",
   10793             :     "(var a, b of [])",
   10794             :     "(var [a] = 1 of [])",
   10795             :     "(var [a], b of [])",
   10796             :     "(var [a = 1] = 1 of [])",
   10797             :     "(var [a = 1], b of [])",
   10798             :     "(var [a = 1 = 1, ...b] of [])",
   10799             :     "(var [a = 1, ...b], c of [])",
   10800             :     "(var {a} = 1 of [])",
   10801             :     "(var {a}, b of [])",
   10802             :     "(var {a: a} = 1 of [])",
   10803             :     "(var {a: 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 {[Symbol.iterator]: a} = 1 of [])",
   10809             :     "(var {[Symbol.iterator]: a}, b of [])",
   10810             :     "(var {0: a} = 1 of [])",
   10811             :     "(var {0: a}, b of [])",
   10812             :     "(var {a = 1} = 1 of [])",
   10813             :     "(var {a = 1}, b of [])",
   10814             :     "(var {a: a = 1} = 1 of [])",
   10815             :     "(var {a: 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 {[Symbol.iterator]: a = 1} = 1 of [])",
   10821             :     "(var {[Symbol.iterator]: a = 1}, b of [])",
   10822             :     "(var {0: a = 1} = 1 of [])",
   10823             :     "(var {0: a = 1}, b of [])",
   10824             : 
   10825             :     // LexicalDeclartions
   10826             :     "(let a = 1 of [])",
   10827             :     "(let a, b of [])",
   10828             :     "(let [a] = 1 of [])",
   10829             :     "(let [a], b of [])",
   10830             :     "(let [a = 1] = 1 of [])",
   10831             :     "(let [a = 1], b of [])",
   10832             :     "(let [a = 1, ...b] = 1 of [])",
   10833             :     "(let [a = 1, ...b], c of [])",
   10834             :     "(let {a} = 1 of [])",
   10835             :     "(let {a}, b of [])",
   10836             :     "(let {a: a} = 1 of [])",
   10837             :     "(let {a: 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 {[Symbol.iterator]: a} = 1 of [])",
   10843             :     "(let {[Symbol.iterator]: a}, b of [])",
   10844             :     "(let {0: a} = 1 of [])",
   10845             :     "(let {0: a}, b of [])",
   10846             :     "(let {a = 1} = 1 of [])",
   10847             :     "(let {a = 1}, b of [])",
   10848             :     "(let {a: a = 1} = 1 of [])",
   10849             :     "(let {a: 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 {[Symbol.iterator]: a = 1} = 1 of [])",
   10855             :     "(let {[Symbol.iterator]: a = 1}, b of [])",
   10856             :     "(let {0: a = 1} = 1 of [])",
   10857             :     "(let {0: a = 1}, b of [])",
   10858             : 
   10859             :     "(const a = 1 of [])",
   10860             :     "(const a, b of [])",
   10861             :     "(const [a] = 1 of [])",
   10862             :     "(const [a], b of [])",
   10863             :     "(const [a = 1] = 1 of [])",
   10864             :     "(const [a = 1], b of [])",
   10865             :     "(const [a = 1, ...b] = 1 of [])",
   10866             :     "(const [a = 1, ...b], b of [])",
   10867             :     "(const {a} = 1 of [])",
   10868             :     "(const {a}, b of [])",
   10869             :     "(const {a: a} = 1 of [])",
   10870             :     "(const {a: 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 {[Symbol.iterator]: a} = 1 of [])",
   10876             :     "(const {[Symbol.iterator]: a}, b of [])",
   10877             :     "(const {0: a} = 1 of [])",
   10878             :     "(const {0: a}, b of [])",
   10879             :     "(const {a = 1} = 1 of [])",
   10880             :     "(const {a = 1}, b of [])",
   10881             :     "(const {a: a = 1} = 1 of [])",
   10882             :     "(const {a: 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 {[Symbol.iterator]: a = 1} = 1 of [])",
   10888             :     "(const {[Symbol.iterator]: a = 1}, b of [])",
   10889             :     "(const {0: a = 1} = 1 of [])",
   10890             :     "(const {0: a = 1}, b of [])",
   10891             : 
   10892             :     nullptr
   10893           5 :   };
   10894             :   // clang-format on
   10895           5 :   RunParserSyncTest(context_data, data, kError);
   10896           5 : }
   10897             : 
   10898       25880 : TEST(ForAwaitOfFunctionDeclaration) {
   10899             :   // clang-format off
   10900             :   const char* context_data[][2] = {
   10901             :     { "async function f() {", "}" },
   10902             :     { "async function f() { 'use strict'; ", "}" },
   10903             :     { nullptr, nullptr }
   10904           5 :   };
   10905             : 
   10906             :   const char* data[] = {
   10907             :     "for await (x of []) function d() {};",
   10908             :     "for await (x of []) function d() {}; return d;",
   10909             :     "for await (x of []) function* g() {};",
   10910             :     "for await (x of []) function* g() {}; return g;",
   10911             :     // TODO(caitp): handle async function declarations in ParseScopedStatement.
   10912             :     // "for await (x of []) async function a() {};",
   10913             :     // "for await (x of []) async function a() {}; return a;",
   10914             :     nullptr
   10915           5 :   };
   10916             : 
   10917             :   // clang-format on
   10918           5 :   RunParserSyncTest(context_data, data, kError);
   10919           5 : }
   10920             : 
   10921       25880 : TEST(AsyncGenerator) {
   10922             :   // clang-format off
   10923             :   const char* context_data[][2] = {
   10924             :     { "async function * gen() {", "}" },
   10925             :     { "(async function * gen() {", "})" },
   10926             :     { "(async function * () {", "})" },
   10927             :     { "({ async * gen () {", "} })" },
   10928             :     { nullptr, nullptr }
   10929           5 :   };
   10930             : 
   10931             :   const char* statement_data[] = {
   10932             :     // An async generator without a body is valid.
   10933             :     ""
   10934             :     // Valid yield expressions inside generators.
   10935             :     "yield 2;",
   10936             :     "yield * 2;",
   10937             :     "yield * \n 2;",
   10938             :     "yield yield 1;",
   10939             :     "yield * yield * 1;",
   10940             :     "yield 3 + (yield 4);",
   10941             :     "yield * 3 + (yield * 4);",
   10942             :     "(yield * 3) + (yield * 4);",
   10943             :     "yield 3; yield 4;",
   10944             :     "yield * 3; yield * 4;",
   10945             :     "(function (yield) { })",
   10946             :     "(function yield() { })",
   10947             :     "(function (await) { })",
   10948             :     "(function await() { })",
   10949             :     "yield { yield: 12 }",
   10950             :     "yield /* comment */ { yield: 12 }",
   10951             :     "yield * \n { yield: 12 }",
   10952             :     "yield /* comment */ * \n { yield: 12 }",
   10953             :     // You can return in an async generator.
   10954             :     "yield 1; return",
   10955             :     "yield * 1; return",
   10956             :     "yield 1; return 37",
   10957             :     "yield * 1; return 37",
   10958             :     "yield 1; return 37; yield 'dead';",
   10959             :     "yield * 1; return 37; yield * 'dead';",
   10960             :     // Yield/Await are still a valid key in object literals.
   10961             :     "({ yield: 1 })",
   10962             :     "({ get yield() { } })",
   10963             :     "({ await: 1 })",
   10964             :     "({ get await() { } })",
   10965             :     // And in assignment pattern computed properties
   10966             :     "({ [yield]: x } = { })",
   10967             :     "({ [await 1]: x } = { })",
   10968             :     // Yield without RHS.
   10969             :     "yield;",
   10970             :     "yield",
   10971             :     "yield\n",
   10972             :     "yield /* comment */"
   10973             :     "yield // comment\n"
   10974             :     "(yield)",
   10975             :     "[yield]",
   10976             :     "{yield}",
   10977             :     "yield, yield",
   10978             :     "yield; yield",
   10979             :     "(yield) ? yield : yield",
   10980             :     "(yield) \n ? yield : yield",
   10981             :     // If there is a newline before the next token, we don't look for RHS.
   10982             :     "yield\nfor (;;) {}",
   10983             :     "x = class extends (yield) {}",
   10984             :     "x = class extends f(yield) {}",
   10985             :     "x = class extends (null, yield) { }",
   10986             :     "x = class extends (a ? null : yield) { }",
   10987             :     "x = class extends (await 10) {}",
   10988             :     "x = class extends f(await 10) {}",
   10989             :     "x = class extends (null, await 10) { }",
   10990             :     "x = class extends (a ? null : await 10) { }",
   10991             : 
   10992             :     // More tests featuring AwaitExpressions
   10993             :     "await 10",
   10994             :     "await 10; return",
   10995             :     "await 10; return 20",
   10996             :     "await 10; return 20; yield 'dead'",
   10997             :     "await (yield 10)",
   10998             :     "await (yield 10); return",
   10999             :     "await (yield 10); return 20",
   11000             :     "await (yield 10); return 20; yield 'dead'",
   11001             :     "yield await 10",
   11002             :     "yield await 10; return",
   11003             :     "yield await 10; return 20",
   11004             :     "yield await 10; return 20; yield 'dead'",
   11005             :     "await /* comment */ 10",
   11006             :     "await // comment\n 10",
   11007             :     "yield await /* comment\n */ 10",
   11008             :     "yield await // comment\n 10",
   11009             :     "await (yield /* comment */)",
   11010             :     "await (yield // comment\n)",
   11011             :     nullptr
   11012           5 :   };
   11013             :   // clang-format on
   11014             : 
   11015           5 :   RunParserSyncTest(context_data, statement_data, kSuccess);
   11016           5 : }
   11017             : 
   11018       25880 : TEST(AsyncGeneratorErrors) {
   11019             :   // clang-format off
   11020             :   const char* context_data[][2] = {
   11021             :     { "async function * gen() {", "}" },
   11022             :     { "\"use strict\"; async function * gen() {", "}" },
   11023             :     { nullptr, nullptr }
   11024           5 :   };
   11025             : 
   11026             :   const char* statement_data[] = {
   11027             :     // Invalid yield expressions inside generators.
   11028             :     "var yield;",
   11029             :     "var await;",
   11030             :     "var foo, yield;",
   11031             :     "var foo, await;",
   11032             :     "try { } catch (yield) { }",
   11033             :     "try { } catch (await) { }",
   11034             :     "function yield() { }",
   11035             :     "function await() { }",
   11036             :     // The name of the NFE is bound in the generator, which does not permit
   11037             :     // yield or await to be identifiers.
   11038             :     "(async function * yield() { })",
   11039             :     "(async function * await() { })",
   11040             :     // Yield and Await aren't valid as a formal parameter for generators.
   11041             :     "async function * foo(yield) { }",
   11042             :     "(async function * foo(yield) { })",
   11043             :     "async function * foo(await) { }",
   11044             :     "(async function * foo(await) { })",
   11045             :     "yield = 1;",
   11046             :     "await = 1;",
   11047             :     "var foo = yield = 1;",
   11048             :     "var foo = await = 1;",
   11049             :     "++yield;",
   11050             :     "++await;",
   11051             :     "yield++;",
   11052             :     "await++;",
   11053             :     "yield *",
   11054             :     "(yield *)",
   11055             :     // Yield binds very loosely, so this parses as "yield (3 + yield 4)", which
   11056             :     // is invalid.
   11057             :     "yield 3 + yield 4;",
   11058             :     "yield: 34",
   11059             :     "yield ? 1 : 2",
   11060             :     // Parses as yield (/ yield): invalid.
   11061             :     "yield / yield",
   11062             :     "+ yield",
   11063             :     "+ yield 3",
   11064             :     // Invalid (no newline allowed between yield and *).
   11065             :     "yield\n*3",
   11066             :     // Invalid (we see a newline, so we parse {yield:42} as a statement, not an
   11067             :     // object literal, and yield is not a valid label).
   11068             :     "yield\n{yield: 42}",
   11069             :     "yield /* comment */\n {yield: 42}",
   11070             :     "yield //comment\n {yield: 42}",
   11071             :     // Destructuring binding and assignment are both disallowed
   11072             :     "var [yield] = [42];",
   11073             :     "var [await] = [42];",
   11074             :     "var {foo: yield} = {a: 42};",
   11075             :     "var {foo: await} = {a: 42};",
   11076             :     "[yield] = [42];",
   11077             :     "[await] = [42];",
   11078             :     "({a: yield} = {a: 42});",
   11079             :     "({a: await} = {a: 42});",
   11080             :     // Also disallow full yield/await expressions on LHS
   11081             :     "var [yield 24] = [42];",
   11082             :     "var [await 24] = [42];",
   11083             :     "var {foo: yield 24} = {a: 42};",
   11084             :     "var {foo: await 24} = {a: 42};",
   11085             :     "[yield 24] = [42];",
   11086             :     "[await 24] = [42];",
   11087             :     "({a: yield 24} = {a: 42});",
   11088             :     "({a: await 24} = {a: 42});",
   11089             :     "for (yield 'x' in {});",
   11090             :     "for (await 'x' in {});",
   11091             :     "for (yield 'x' of {});",
   11092             :     "for (await 'x' of {});",
   11093             :     "for (yield 'x' in {} in {});",
   11094             :     "for (await 'x' in {} in {});",
   11095             :     "for (yield 'x' in {} of {});",
   11096             :     "for (await 'x' in {} of {});",
   11097             :     "class C extends yield { }",
   11098             :     "class C extends await { }",
   11099             :     nullptr
   11100           5 :   };
   11101             :   // clang-format on
   11102             : 
   11103           5 :   RunParserSyncTest(context_data, statement_data, kError);
   11104           5 : }
   11105             : 
   11106       25880 : TEST(LexicalLoopVariable) {
   11107             :   i::Isolate* isolate = CcTest::i_isolate();
   11108             :   i::HandleScope scope(isolate);
   11109          10 :   LocalContext env;
   11110             :   typedef std::function<void(const i::ParseInfo& info, i::DeclarationScope*)>
   11111             :       TestCB;
   11112          50 :   auto TestProgram = [isolate](const char* program, TestCB test) {
   11113          50 :     i::Factory* const factory = isolate->factory();
   11114             :     i::Handle<i::String> source =
   11115         100 :         factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
   11116          50 :     i::Handle<i::Script> script = factory->NewScript(source);
   11117          50 :     i::ParseInfo info(isolate, script);
   11118             : 
   11119             :     info.set_allow_lazy_parsing(false);
   11120          50 :     CHECK(i::parsing::ParseProgram(&info, isolate));
   11121          50 :     CHECK(i::Rewriter::Rewrite(&info));
   11122          50 :     CHECK(i::DeclarationScope::Analyze(&info));
   11123          50 :     i::DeclarationScope::AllocateScopeInfos(&info, isolate);
   11124          50 :     CHECK_NOT_NULL(info.literal());
   11125             : 
   11126          50 :     i::DeclarationScope* script_scope = info.literal()->scope();
   11127          50 :     CHECK(script_scope->is_script_scope());
   11128             : 
   11129          50 :     test(info, script_scope);
   11130          55 :   };
   11131             : 
   11132             :   // Check `let` loop variables is a stack local when not captured by
   11133             :   // an eval or closure within the area of the loop body.
   11134             :   const char* local_bindings[] = {
   11135             :       "function loop() {"
   11136             :       "  for (let loop_var = 0; loop_var < 10; ++loop_var) {"
   11137             :       "  }"
   11138             :       "  eval('0');"
   11139             :       "}",
   11140             : 
   11141             :       "function loop() {"
   11142             :       "  for (let loop_var = 0; loop_var < 10; ++loop_var) {"
   11143             :       "  }"
   11144             :       "  function foo() {}"
   11145             :       "  foo();"
   11146             :       "}",
   11147           5 :   };
   11148          15 :   for (const char* source : local_bindings) {
   11149          10 :     TestProgram(source, [=](const i::ParseInfo& info, i::DeclarationScope* s) {
   11150          20 :       i::Scope* fn = s->inner_scope();
   11151          10 :       CHECK(fn->is_function_scope());
   11152             : 
   11153          25 :       i::Scope* loop_block = fn->inner_scope();
   11154          10 :       if (loop_block->is_function_scope()) loop_block = loop_block->sibling();
   11155          10 :       CHECK(loop_block->is_block_scope());
   11156             : 
   11157             :       const i::AstRawString* var_name =
   11158          10 :           info.ast_value_factory()->GetOneByteString("loop_var");
   11159             :       i::Variable* loop_var = loop_block->LookupLocal(var_name);
   11160          10 :       CHECK_NOT_NULL(loop_var);
   11161          10 :       CHECK(loop_var->IsStackLocal());
   11162          10 :       CHECK_EQ(loop_block->ContextLocalCount(), 0);
   11163          10 :       CHECK_NULL(loop_block->inner_scope());
   11164          30 :     });
   11165             :   }
   11166             : 
   11167             :   // Check `let` loop variable is not a stack local, and is duplicated in the
   11168             :   // loop body to ensure capturing can work correctly.
   11169             :   // In this version of the test, the inner loop block's duplicate `loop_var`
   11170             :   // binding is not captured, and is a local.
   11171             :   const char* context_bindings1[] = {
   11172             :       "function loop() {"
   11173             :       "  for (let loop_var = eval('0'); loop_var < 10; ++loop_var) {"
   11174             :       "  }"
   11175             :       "}",
   11176             : 
   11177             :       "function loop() {"
   11178             :       "  for (let loop_var = (() => (loop_var, 0))(); loop_var < 10;"
   11179             :       "       ++loop_var) {"
   11180             :       "  }"
   11181           5 :       "}"};
   11182          15 :   for (const char* source : context_bindings1) {
   11183          10 :     TestProgram(source, [=](const i::ParseInfo& info, i::DeclarationScope* s) {
   11184          20 :       i::Scope* fn = s->inner_scope();
   11185          10 :       CHECK(fn->is_function_scope());
   11186             : 
   11187          30 :       i::Scope* loop_block = fn->inner_scope();
   11188          10 :       CHECK(loop_block->is_block_scope());
   11189             : 
   11190             :       const i::AstRawString* var_name =
   11191          10 :           info.ast_value_factory()->GetOneByteString("loop_var");
   11192             :       i::Variable* loop_var = loop_block->LookupLocal(var_name);
   11193          10 :       CHECK_NOT_NULL(loop_var);
   11194          10 :       CHECK(loop_var->IsContextSlot());
   11195          10 :       CHECK_EQ(loop_block->ContextLocalCount(), 1);
   11196             : 
   11197             :       i::Variable* loop_var2 = loop_block->inner_scope()->LookupLocal(var_name);
   11198          10 :       CHECK_NE(loop_var, loop_var2);
   11199          10 :       CHECK(loop_var2->IsStackLocal());
   11200          10 :       CHECK_EQ(loop_block->inner_scope()->ContextLocalCount(), 0);
   11201          30 :     });
   11202             :   }
   11203             : 
   11204             :   // Check `let` loop variable is not a stack local, and is duplicated in the
   11205             :   // loop body to ensure capturing can work correctly.
   11206             :   // In this version of the test, the inner loop block's duplicate `loop_var`
   11207             :   // binding is captured, and must be context allocated.
   11208             :   const char* context_bindings2[] = {
   11209             :       "function loop() {"
   11210             :       "  for (let loop_var = 0; loop_var < 10; ++loop_var) {"
   11211             :       "    eval('0');"
   11212             :       "  }"
   11213             :       "}",
   11214             : 
   11215             :       "function loop() {"
   11216             :       "  for (let loop_var = 0; loop_var < eval('10'); ++loop_var) {"
   11217             :       "  }"
   11218             :       "}",
   11219             : 
   11220             :       "function loop() {"
   11221             :       "  for (let loop_var = 0; loop_var < 10; eval('++loop_var')) {"
   11222             :       "  }"
   11223             :       "}",
   11224           5 :   };
   11225             : 
   11226          20 :   for (const char* source : context_bindings2) {
   11227          15 :     TestProgram(source, [=](const i::ParseInfo& info, i::DeclarationScope* s) {
   11228          30 :       i::Scope* fn = s->inner_scope();
   11229          15 :       CHECK(fn->is_function_scope());
   11230             : 
   11231          45 :       i::Scope* loop_block = fn->inner_scope();
   11232          15 :       CHECK(loop_block->is_block_scope());
   11233             : 
   11234             :       const i::AstRawString* var_name =
   11235          15 :           info.ast_value_factory()->GetOneByteString("loop_var");
   11236             :       i::Variable* loop_var = loop_block->LookupLocal(var_name);
   11237          15 :       CHECK_NOT_NULL(loop_var);
   11238          15 :       CHECK(loop_var->IsContextSlot());
   11239          15 :       CHECK_EQ(loop_block->ContextLocalCount(), 1);
   11240             : 
   11241             :       i::Variable* loop_var2 = loop_block->inner_scope()->LookupLocal(var_name);
   11242          15 :       CHECK_NE(loop_var, loop_var2);
   11243          15 :       CHECK(loop_var2->IsContextSlot());
   11244          15 :       CHECK_EQ(loop_block->inner_scope()->ContextLocalCount(), 1);
   11245          45 :     });
   11246             :   }
   11247             : 
   11248             :   // Similar to the above, but the first block scope's variables are not
   11249             :   // captured due to the closure occurring in a nested scope.
   11250             :   const char* context_bindings3[] = {
   11251             :       "function loop() {"
   11252             :       "  for (let loop_var = 0; loop_var < 10; ++loop_var) {"
   11253             :       "    (() => loop_var)();"
   11254             :       "  }"
   11255             :       "}",
   11256             : 
   11257             :       "function loop() {"
   11258             :       "  for (let loop_var = 0; loop_var < (() => (loop_var, 10))();"
   11259             :       "       ++loop_var) {"
   11260             :       "  }"
   11261             :       "}",
   11262             : 
   11263             :       "function loop() {"
   11264             :       "  for (let loop_var = 0; loop_var < 10; (() => ++loop_var)()) {"
   11265             :       "  }"
   11266             :       "}",
   11267           5 :   };
   11268             : 
   11269          20 :   for (const char* source : context_bindings3) {
   11270          15 :     TestProgram(source, [=](const i::ParseInfo& info, i::DeclarationScope* s) {
   11271          30 :       i::Scope* fn = s->inner_scope();
   11272          15 :       CHECK(fn->is_function_scope());
   11273             : 
   11274          45 :       i::Scope* loop_block = fn->inner_scope();
   11275          15 :       CHECK(loop_block->is_block_scope());
   11276             : 
   11277             :       const i::AstRawString* var_name =
   11278          15 :           info.ast_value_factory()->GetOneByteString("loop_var");
   11279             :       i::Variable* loop_var = loop_block->LookupLocal(var_name);
   11280          15 :       CHECK_NOT_NULL(loop_var);
   11281          15 :       CHECK(loop_var->IsStackLocal());
   11282          15 :       CHECK_EQ(loop_block->ContextLocalCount(), 0);
   11283             : 
   11284             :       i::Variable* loop_var2 = loop_block->inner_scope()->LookupLocal(var_name);
   11285          15 :       CHECK_NE(loop_var, loop_var2);
   11286          15 :       CHECK(loop_var2->IsContextSlot());
   11287          15 :       CHECK_EQ(loop_block->inner_scope()->ContextLocalCount(), 1);
   11288          45 :     });
   11289             :   }
   11290           5 : }
   11291             : 
   11292       25880 : TEST(PrivateNamesSyntaxError) {
   11293             :   i::Isolate* isolate = CcTest::i_isolate();
   11294             :   i::HandleScope scope(isolate);
   11295          10 :   LocalContext env;
   11296             : 
   11297         155 :   auto test = [isolate](const char* program, bool is_lazy) {
   11298         155 :     i::FLAG_harmony_private_fields = true;
   11299         155 :     i::Factory* const factory = isolate->factory();
   11300             :     i::Handle<i::String> source =
   11301         310 :         factory->NewStringFromUtf8(i::CStrVector(program)).ToHandleChecked();
   11302         155 :     i::Handle<i::Script> script = factory->NewScript(source);
   11303         155 :     i::ParseInfo info(isolate, script);
   11304             : 
   11305             :     info.set_allow_lazy_parsing(is_lazy);
   11306         155 :     CHECK(i::parsing::ParseProgram(&info, isolate));
   11307         155 :     CHECK(i::Rewriter::Rewrite(&info));
   11308         155 :     CHECK(!i::DeclarationScope::Analyze(&info));
   11309         310 :     return info.pending_error_handler()->has_pending_error();
   11310         160 :   };
   11311             : 
   11312             :   const char* data[] = {
   11313             :       "class A {"
   11314             :       "  foo() { return this.#bar; }"
   11315             :       "}",
   11316             : 
   11317             :       "let A = class {"
   11318             :       "  foo() { return this.#bar; }"
   11319             :       "}",
   11320             : 
   11321             :       "class A {"
   11322             :       "  #foo;  "
   11323             :       "  bar() { return this.#baz; }"
   11324             :       "}",
   11325             : 
   11326             :       "let A = class {"
   11327             :       "  #foo;  "
   11328             :       "  bar() { return this.#baz; }"
   11329             :       "}",
   11330             : 
   11331             :       "class A {"
   11332             :       "  bar() {"
   11333             :       "    class D { #baz = 1; };"
   11334             :       "    return this.#baz;"
   11335             :       "  }"
   11336             :       "}",
   11337             : 
   11338             :       "let A = class {"
   11339             :       "  bar() {"
   11340             :       "    class D { #baz = 1; };"
   11341             :       "    return this.#baz;"
   11342             :       "  }"
   11343             :       "}",
   11344             : 
   11345             :       "a.#bar",
   11346             : 
   11347             :       "class Foo {};"
   11348             :       "Foo.#bar;",
   11349             : 
   11350             :       "let Foo = class {};"
   11351             :       "Foo.#bar;",
   11352             : 
   11353             :       "class Foo {};"
   11354             :       "(new Foo).#bar;",
   11355             : 
   11356             :       "let Foo = class {};"
   11357             :       "(new Foo).#bar;",
   11358             : 
   11359             :       "class Foo { #bar; };"
   11360             :       "(new Foo).#bar;",
   11361             : 
   11362             :       "let Foo = class { #bar; };"
   11363             :       "(new Foo).#bar;",
   11364             : 
   11365             :       "function t(){"
   11366             :       "  class Foo { getA() { return this.#foo; } }"
   11367             :       "}",
   11368             : 
   11369             :       "function t(){"
   11370             :       "  return class { getA() { return this.#foo; } }"
   11371             :       "}",
   11372           5 :   };
   11373             : 
   11374             :   // TODO(gsathya): The preparser does not track unresolved
   11375             :   // variables in top level function which fails this test.
   11376             :   // https://bugs.chromium.org/p/v8/issues/detail?id=7468
   11377             :   const char* parser_data[] = {
   11378             :       "function t() {"
   11379             :       "  return this.#foo;"
   11380             :       "}",
   11381           5 :   };
   11382             : 
   11383          80 :   for (const char* source : data) {
   11384          75 :     CHECK(test(source, true));
   11385          75 :     CHECK(test(source, false));
   11386             :   }
   11387             : 
   11388          10 :   for (const char* source : parser_data) {
   11389           5 :     CHECK(test(source, false));
   11390             :   }
   11391           5 : }
   11392             : 
   11393       25880 : TEST(HashbangSyntax) {
   11394             :   const char* context_data[][2] = {
   11395             :       {"#!\n", ""},
   11396             :       {"#!---IGNORED---\n", ""},
   11397             :       {"#!---IGNORED---\r", ""},
   11398             :       {"#!---IGNORED---\xE2\x80\xA8", ""},  // <U+2028>
   11399             :       {"#!---IGNORED---\xE2\x80\xA9", ""},  // <U+2029>
   11400           5 :       {nullptr, nullptr}};
   11401             : 
   11402           5 :   const char* data[] = {"function\nFN\n(\n)\n {\n}\nFN();", nullptr};
   11403             : 
   11404           5 :   i::FLAG_harmony_hashbang = true;
   11405           5 :   RunParserSyncTest(context_data, data, kSuccess);
   11406             :   RunParserSyncTest(context_data, data, kSuccess, nullptr, 0, nullptr, 0,
   11407           5 :                     nullptr, 0, true);
   11408             : 
   11409           5 :   i::FLAG_harmony_hashbang = false;
   11410           5 :   RunParserSyncTest(context_data, data, kError);
   11411             :   RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0, nullptr,
   11412           5 :                     0, true);
   11413           5 : }
   11414             : 
   11415       25880 : TEST(HashbangSyntaxErrors) {
   11416           5 :   const char* file_context_data[][2] = {{"", ""}, {nullptr, nullptr}};
   11417             :   const char* other_context_data[][2] = {{"/**/", ""},
   11418             :                                          {"//---\n", ""},
   11419             :                                          {";", ""},
   11420             :                                          {"function fn() {", "}"},
   11421             :                                          {"function* fn() {", "}"},
   11422             :                                          {"async function fn() {", "}"},
   11423             :                                          {"async function* fn() {", "}"},
   11424             :                                          {"() => {", "}"},
   11425             :                                          {"() => ", ""},
   11426             :                                          {"function fn(a = ", ") {}"},
   11427             :                                          {"function* fn(a = ", ") {}"},
   11428             :                                          {"async function fn(a = ", ") {}"},
   11429             :                                          {"async function* fn(a = ", ") {}"},
   11430             :                                          {"(a = ", ") => {}"},
   11431             :                                          {"(a = ", ") => a"},
   11432             :                                          {"class k {", "}"},
   11433             :                                          {"[", "]"},
   11434             :                                          {"{", "}"},
   11435             :                                          {"({", "})"},
   11436           5 :                                          {nullptr, nullptr}};
   11437             : 
   11438             :   const char* invalid_hashbang_data[] = {// Encoded characters are not allowed
   11439             :                                          "#\\u0021\n"
   11440             :                                          "#\\u{21}\n",
   11441             :                                          "#\\x21\n",
   11442             :                                          "#\\041\n",
   11443             :                                          "\\u0023!\n",
   11444             :                                          "\\u{23}!\n",
   11445             :                                          "\\x23!\n",
   11446             :                                          "\\043!\n",
   11447             :                                          "\\u0023\\u0021\n",
   11448             : 
   11449             :                                          "\n#!---IGNORED---\n",
   11450             :                                          " #!---IGNORED---\n",
   11451           5 :                                          nullptr};
   11452           5 :   const char* hashbang_data[] = {"#!\n", "#!---IGNORED---\n", nullptr};
   11453             : 
   11454          15 :   auto SyntaxErrorTest = [](const char* context_data[][2], const char* data[]) {
   11455          15 :     i::FLAG_harmony_hashbang = true;
   11456          15 :     RunParserSyncTest(context_data, data, kError);
   11457             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
   11458          15 :                       nullptr, 0, true);
   11459             : 
   11460          15 :     i::FLAG_harmony_hashbang = false;
   11461          15 :     RunParserSyncTest(context_data, data, kError);
   11462             :     RunParserSyncTest(context_data, data, kError, nullptr, 0, nullptr, 0,
   11463          15 :                       nullptr, 0, true);
   11464          15 :   };
   11465             : 
   11466           5 :   SyntaxErrorTest(file_context_data, invalid_hashbang_data);
   11467           5 :   SyntaxErrorTest(other_context_data, invalid_hashbang_data);
   11468           5 :   SyntaxErrorTest(other_context_data, hashbang_data);
   11469           5 : }
   11470             : 
   11471             : }  // namespace test_parsing
   11472             : }  // namespace internal
   11473       77625 : }  // namespace v8

Generated by: LCOV version 1.10