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

Side by Side Diff: test/cctest/test-parsing.cc

Issue 160073006: Implement handling of arrow functions in the parser (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Same, plus a rebase and conflicts resolved Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/preparser.h ('K') | « src/token.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 int marker; 285 int marker;
286 CcTest::i_isolate()->stack_guard()->SetStackLimit( 286 CcTest::i_isolate()->stack_guard()->SetStackLimit(
287 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 287 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
288 288
289 const char* programs[] = { 289 const char* programs[] = {
290 "{label: 42}", 290 "{label: 42}",
291 "var x = 42;", 291 "var x = 42;",
292 "function foo(x, y) { return x + y; }", 292 "function foo(x, y) { return x + y; }",
293 "%ArgleBargle(glop);", 293 "%ArgleBargle(glop);",
294 "var x = new new Function('this.x = 42');", 294 "var x = new new Function('this.x = 42');",
295 "var f = (x, y) => x + y;",
295 NULL 296 NULL
296 }; 297 };
297 298
298 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit(); 299 uintptr_t stack_limit = CcTest::i_isolate()->stack_guard()->real_climit();
299 for (int i = 0; programs[i]; i++) { 300 for (int i = 0; programs[i]; i++) {
300 const char* program = programs[i]; 301 const char* program = programs[i];
301 i::Utf8ToUtf16CharacterStream stream( 302 i::Utf8ToUtf16CharacterStream stream(
302 reinterpret_cast<const i::byte*>(program), 303 reinterpret_cast<const i::byte*>(program),
303 static_cast<unsigned>(strlen(program))); 304 static_cast<unsigned>(strlen(program)));
304 i::CompleteParserRecorder log; 305 i::CompleteParserRecorder log;
305 i::Scanner scanner(CcTest::i_isolate()->unicode_cache()); 306 i::Scanner scanner(CcTest::i_isolate()->unicode_cache());
306 scanner.Initialize(&stream); 307 scanner.Initialize(&stream);
307 308
308 i::PreParser preparser(&scanner, &log, stack_limit); 309 i::PreParser preparser(&scanner, &log, stack_limit);
309 preparser.set_allow_lazy(true); 310 preparser.set_allow_lazy(true);
310 preparser.set_allow_natives_syntax(true); 311 preparser.set_allow_natives_syntax(true);
312 preparser.set_allow_arrow_functions(true);
311 i::PreParser::PreParseResult result = preparser.PreParseProgram(); 313 i::PreParser::PreParseResult result = preparser.PreParseProgram();
312 CHECK_EQ(i::PreParser::kPreParseSuccess, result); 314 CHECK_EQ(i::PreParser::kPreParseSuccess, result);
313 i::ScriptData data(log.ExtractData()); 315 i::ScriptData data(log.ExtractData());
314 CHECK(!data.has_error()); 316 CHECK(!data.has_error());
315 } 317 }
316 } 318 }
317 319
318 320
319 TEST(StandAlonePreParserNoNatives) { 321 TEST(StandAlonePreParserNoNatives) {
320 v8::V8::Initialize(); 322 v8::V8::Initialize();
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 i += input_offset; 909 i += input_offset;
908 character_length -= output_adjust; 910 character_length -= output_adjust;
909 } 911 }
910 } 912 }
911 } 913 }
912 return character_length; 914 return character_length;
913 } 915 }
914 916
915 917
916 TEST(ScopePositions) { 918 TEST(ScopePositions) {
917 v8::internal::FLAG_harmony_scoping = true; 919 i::FLAG_harmony_scoping = true;
918 920
919 // Test the parser for correctly setting the start and end positions 921 // Test the parser for correctly setting the start and end positions
920 // of a scope. We check the scope positions of exactly one scope 922 // of a scope. We check the scope positions of exactly one scope
921 // nested in the global scope of a program. 'inner source' is the 923 // nested in the global scope of a program. 'inner source' is the
922 // source code that determines the part of the source belonging 924 // source code that determines the part of the source belonging
923 // to the nested scope. 'outer_prefix' and 'outer_suffix' are 925 // to the nested scope. 'outer_prefix' and 'outer_suffix' are
924 // parts of the source that belong to the global scope. 926 // parts of the source that belong to the global scope.
925 struct SourceData { 927 struct SourceData {
926 const char* outer_prefix; 928 const char* outer_prefix;
927 const char* inner_source; 929 const char* inner_source;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 " }", "\n" 965 " }", "\n"
964 " more;", i::BLOCK_SCOPE, i::STRICT }, 966 " more;", i::BLOCK_SCOPE, i::STRICT },
965 { " start;\n" 967 { " start;\n"
966 " function fun", "(a,b) { infunction; }", " more;", 968 " function fun", "(a,b) { infunction; }", " more;",
967 i::FUNCTION_SCOPE, i::SLOPPY }, 969 i::FUNCTION_SCOPE, i::SLOPPY },
968 { " start;\n" 970 { " start;\n"
969 " function fun", "(a,b) {\n" 971 " function fun", "(a,b) {\n"
970 " infunction;\n" 972 " infunction;\n"
971 " }", "\n" 973 " }", "\n"
972 " more;", i::FUNCTION_SCOPE, i::SLOPPY }, 974 " more;", i::FUNCTION_SCOPE, i::SLOPPY },
973 { " (function fun", "(a,b) { infunction; }", ")();", 975 { " start;\n"
marja 2014/07/01 07:23:40 Why this change?
976 " (function fun", "(a,b) { infunction; }", ")();",
974 i::FUNCTION_SCOPE, i::SLOPPY }, 977 i::FUNCTION_SCOPE, i::SLOPPY },
975 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;", 978 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", " more;",
976 i::BLOCK_SCOPE, i::STRICT }, 979 i::BLOCK_SCOPE, i::STRICT },
977 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;", 980 { " for ", "(let x = 1 ; x < 10; ++ x) { block; }", "; more;",
978 i::BLOCK_SCOPE, i::STRICT }, 981 i::BLOCK_SCOPE, i::STRICT },
979 { " for ", "(let x = 1 ; x < 10; ++ x) {\n" 982 { " for ", "(let x = 1 ; x < 10; ++ x) {\n"
980 " block;\n" 983 " block;\n"
981 " }", "\n" 984 " }", "\n"
982 " more;", i::BLOCK_SCOPE, i::STRICT }, 985 " more;", i::BLOCK_SCOPE, i::STRICT },
983 { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;", 986 { " for ", "(let x = 1 ; x < 10; ++ x) statement;", " more;",
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
1174 } 1177 }
1175 1178
1176 1179
1177 enum ParserFlag { 1180 enum ParserFlag {
1178 kAllowLazy, 1181 kAllowLazy,
1179 kAllowNativesSyntax, 1182 kAllowNativesSyntax,
1180 kAllowHarmonyScoping, 1183 kAllowHarmonyScoping,
1181 kAllowModules, 1184 kAllowModules,
1182 kAllowGenerators, 1185 kAllowGenerators,
1183 kAllowForOf, 1186 kAllowForOf,
1184 kAllowHarmonyNumericLiterals 1187 kAllowHarmonyNumericLiterals,
1188 kAllowArrowFunctions
1185 }; 1189 };
1186 1190
1187 1191
1188 enum ParserSyncTestResult { 1192 enum ParserSyncTestResult {
1189 kSuccessOrError, 1193 kSuccessOrError,
1190 kSuccess, 1194 kSuccess,
1191 kError 1195 kError
1192 }; 1196 };
1193 1197
1194 template <typename Traits> 1198 template <typename Traits>
1195 void SetParserFlags(i::ParserBase<Traits>* parser, 1199 void SetParserFlags(i::ParserBase<Traits>* parser,
1196 i::EnumSet<ParserFlag> flags) { 1200 i::EnumSet<ParserFlag> flags) {
1197 parser->set_allow_lazy(flags.Contains(kAllowLazy)); 1201 parser->set_allow_lazy(flags.Contains(kAllowLazy));
1198 parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax)); 1202 parser->set_allow_natives_syntax(flags.Contains(kAllowNativesSyntax));
1199 parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping)); 1203 parser->set_allow_harmony_scoping(flags.Contains(kAllowHarmonyScoping));
1200 parser->set_allow_modules(flags.Contains(kAllowModules)); 1204 parser->set_allow_modules(flags.Contains(kAllowModules));
1201 parser->set_allow_generators(flags.Contains(kAllowGenerators)); 1205 parser->set_allow_generators(flags.Contains(kAllowGenerators));
1202 parser->set_allow_for_of(flags.Contains(kAllowForOf)); 1206 parser->set_allow_for_of(flags.Contains(kAllowForOf));
1203 parser->set_allow_harmony_numeric_literals( 1207 parser->set_allow_harmony_numeric_literals(
1204 flags.Contains(kAllowHarmonyNumericLiterals)); 1208 flags.Contains(kAllowHarmonyNumericLiterals));
1209 parser->set_allow_arrow_functions(flags.Contains(kAllowArrowFunctions));
1205 } 1210 }
1206 1211
1207 1212
1208 void TestParserSyncWithFlags(i::Handle<i::String> source, 1213 void TestParserSyncWithFlags(i::Handle<i::String> source,
1209 i::EnumSet<ParserFlag> flags, 1214 i::EnumSet<ParserFlag> flags,
1210 ParserSyncTestResult result) { 1215 ParserSyncTestResult result) {
1211 i::Isolate* isolate = CcTest::i_isolate(); 1216 i::Isolate* isolate = CcTest::i_isolate();
1212 i::Factory* factory = isolate->factory(); 1217 i::Factory* factory = isolate->factory();
1213 1218
1214 uintptr_t stack_limit = isolate->stack_guard()->real_climit(); 1219 uintptr_t stack_limit = isolate->stack_guard()->real_climit();
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1399 v8::HandleScope handles(CcTest::isolate()); 1404 v8::HandleScope handles(CcTest::isolate());
1400 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); 1405 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1401 v8::Context::Scope context_scope(context); 1406 v8::Context::Scope context_scope(context);
1402 1407
1403 int marker; 1408 int marker;
1404 CcTest::i_isolate()->stack_guard()->SetStackLimit( 1409 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1405 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 1410 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1406 1411
1407 static const ParserFlag flags1[] = { 1412 static const ParserFlag flags1[] = {
1408 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, 1413 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1409 kAllowForOf 1414 kAllowForOf, kAllowArrowFunctions
1410 }; 1415 };
1411 for (int i = 0; context_data[i][0] != NULL; ++i) { 1416 for (int i = 0; context_data[i][0] != NULL; ++i) {
1412 for (int j = 0; statement_data[j] != NULL; ++j) { 1417 for (int j = 0; statement_data[j] != NULL; ++j) {
1413 for (int k = 0; termination_data[k] != NULL; ++k) { 1418 for (int k = 0; termination_data[k] != NULL; ++k) {
1414 int kPrefixLen = i::StrLength(context_data[i][0]); 1419 int kPrefixLen = i::StrLength(context_data[i][0]);
1415 int kStatementLen = i::StrLength(statement_data[j]); 1420 int kStatementLen = i::StrLength(statement_data[j]);
1416 int kTerminationLen = i::StrLength(termination_data[k]); 1421 int kTerminationLen = i::StrLength(termination_data[k]);
1417 int kSuffixLen = i::StrLength(context_data[i][1]); 1422 int kSuffixLen = i::StrLength(context_data[i][1]);
1418 int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen 1423 int kProgramSize = kPrefixLen + kStatementLen + kTerminationLen
1419 + kSuffixLen + i::StrLength("label: for (;;) { }"); 1424 + kSuffixLen + i::StrLength("label: for (;;) { }");
1420 1425
1421 // Plug the source code pieces together. 1426 // Plug the source code pieces together.
1422 i::ScopedVector<char> program(kProgramSize + 1); 1427 i::ScopedVector<char> program(kProgramSize + 1);
1423 int length = i::SNPrintF(program, 1428 int length = i::SNPrintF(program,
1424 "label: for (;;) { %s%s%s%s }", 1429 "label: for (;;) { %s%s%s%s }",
1425 context_data[i][0], 1430 context_data[i][0],
1426 statement_data[j], 1431 statement_data[j],
1427 termination_data[k], 1432 termination_data[k],
1428 context_data[i][1]); 1433 context_data[i][1]);
1429 CHECK(length == kProgramSize); 1434 CHECK(length == kProgramSize);
1430 TestParserSync(program.start(), flags1, ARRAY_SIZE(flags1)); 1435 TestParserSync(program.start(), flags1, ARRAY_SIZE(flags1),
1436 kSuccessOrError);
1431 } 1437 }
1432 } 1438 }
1433 } 1439 }
1434 1440
1435 // Neither Harmony numeric literals nor our natives syntax have any 1441 // Neither Harmony numeric literals nor our natives syntax have any
1436 // interaction with the flags above, so test these separately to reduce 1442 // interaction with the flags above, so test these separately to reduce
1437 // the combinatorial explosion. 1443 // the combinatorial explosion.
1438 static const ParserFlag flags2[] = { kAllowHarmonyNumericLiterals }; 1444 static const ParserFlag flags2[] = { kAllowHarmonyNumericLiterals };
1439 TestParserSync("0o1234", flags2, ARRAY_SIZE(flags2)); 1445 TestParserSync("0o1234", flags2, ARRAY_SIZE(flags2), kSuccessOrError);
1440 TestParserSync("0b1011", flags2, ARRAY_SIZE(flags2)); 1446 TestParserSync("0b1011", flags2, ARRAY_SIZE(flags2), kSuccessOrError);
1441 1447
1442 static const ParserFlag flags3[] = { kAllowNativesSyntax }; 1448 static const ParserFlag flags3[] = { kAllowNativesSyntax };
1443 TestParserSync("%DebugPrint(123)", flags3, ARRAY_SIZE(flags3)); 1449 TestParserSync("%DebugPrint(123)", flags3, ARRAY_SIZE(flags3), kSuccessOrError );
1444 } 1450 }
1445 1451
1446 1452
1447 TEST(StrictOctal) { 1453 TEST(StrictOctal) {
1448 // Test that syntax error caused by octal literal is reported correctly as 1454 // Test that syntax error caused by octal literal is reported correctly as
1449 // such (issue 2220). 1455 // such (issue 2220).
1450 v8::V8::Initialize(); 1456 v8::V8::Initialize();
1457
marja 2014/07/01 07:23:40 This file seems to contain some unintentional chan
1451 v8::HandleScope scope(CcTest::isolate()); 1458 v8::HandleScope scope(CcTest::isolate());
1452 v8::Context::Scope context_scope( 1459 v8::Context::Scope context_scope(
1453 v8::Context::New(CcTest::isolate())); 1460 v8::Context::New(CcTest::isolate()));
1454 v8::TryCatch try_catch; 1461 v8::TryCatch try_catch;
1455 const char* script = 1462 const char* script =
1456 "\"use strict\"; \n" 1463 "\"use strict\"; \n"
1457 "a = function() { \n" 1464 "a = function() { \n"
1458 " b = function() { \n" 1465 " b = function() { \n"
1459 " 01; \n" 1466 " 01; \n"
1460 " }; \n" 1467 " }; \n"
(...skipping 16 matching lines...) Expand all
1477 v8::HandleScope handles(CcTest::isolate()); 1484 v8::HandleScope handles(CcTest::isolate());
1478 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate()); 1485 v8::Handle<v8::Context> context = v8::Context::New(CcTest::isolate());
1479 v8::Context::Scope context_scope(context); 1486 v8::Context::Scope context_scope(context);
1480 1487
1481 int marker; 1488 int marker;
1482 CcTest::i_isolate()->stack_guard()->SetStackLimit( 1489 CcTest::i_isolate()->stack_guard()->SetStackLimit(
1483 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024); 1490 reinterpret_cast<uintptr_t>(&marker) - 128 * 1024);
1484 1491
1485 static const ParserFlag default_flags[] = { 1492 static const ParserFlag default_flags[] = {
1486 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators, 1493 kAllowLazy, kAllowHarmonyScoping, kAllowModules, kAllowGenerators,
1487 kAllowForOf, kAllowNativesSyntax 1494 kAllowForOf, kAllowNativesSyntax, kAllowArrowFunctions
1488 }; 1495 };
1489 ParserFlag* generated_flags = NULL; 1496 ParserFlag* generated_flags = NULL;
1490 if (flags == NULL) { 1497 if (flags == NULL) {
1491 flags = default_flags; 1498 flags = default_flags;
1492 flags_len = ARRAY_SIZE(default_flags); 1499 flags_len = ARRAY_SIZE(default_flags);
1493 if (always_true_flags != NULL) { 1500 if (always_true_flags != NULL) {
1494 // Remove always_true_flags from default_flags. 1501 // Remove always_true_flags from default_flags.
1495 CHECK(always_true_flags_len < flags_len); 1502 CHECK(always_true_flags_len < flags_len);
1496 generated_flags = new ParserFlag[flags_len - always_true_flags_len]; 1503 generated_flags = new ParserFlag[flags_len - always_true_flags_len];
1497 int flag_index = 0; 1504 int flag_index = 0;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 "var foo, eval;", 1561 "var foo, eval;",
1555 "var foo, arguments;", 1562 "var foo, arguments;",
1556 "try { } catch (eval) { }", 1563 "try { } catch (eval) { }",
1557 "try { } catch (arguments) { }", 1564 "try { } catch (arguments) { }",
1558 "function eval() { }", 1565 "function eval() { }",
1559 "function arguments() { }", 1566 "function arguments() { }",
1560 "function foo(eval) { }", 1567 "function foo(eval) { }",
1561 "function foo(arguments) { }", 1568 "function foo(arguments) { }",
1562 "function foo(bar, eval) { }", 1569 "function foo(bar, eval) { }",
1563 "function foo(bar, arguments) { }", 1570 "function foo(bar, arguments) { }",
1571 "(eval) => { }",
1572 "(arguments) => { }",
1573 "(foo, eval) => { }",
1574 "(foo, arguments) => { }",
1564 "eval = 1;", 1575 "eval = 1;",
1565 "arguments = 1;", 1576 "arguments = 1;",
1566 "var foo = eval = 1;", 1577 "var foo = eval = 1;",
1567 "var foo = arguments = 1;", 1578 "var foo = arguments = 1;",
1568 "++eval;", 1579 "++eval;",
1569 "++arguments;", 1580 "++arguments;",
1570 "eval++;", 1581 "eval++;",
1571 "arguments++;", 1582 "arguments++;",
1572 NULL 1583 NULL
1573 }; 1584 };
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1610 }; 1621 };
1611 1622
1612 RunParserSyncTest(context_data, statement_data, kSuccess); 1623 RunParserSyncTest(context_data, statement_data, kSuccess);
1613 } 1624 }
1614 1625
1615 1626
1616 TEST(NoErrorsEvalAndArgumentsStrict) { 1627 TEST(NoErrorsEvalAndArgumentsStrict) {
1617 const char* context_data[][2] = { 1628 const char* context_data[][2] = {
1618 { "\"use strict\";", "" }, 1629 { "\"use strict\";", "" },
1619 { "function test_func() { \"use strict\";", "}" }, 1630 { "function test_func() { \"use strict\";", "}" },
1631 { "() => { \"use strict\"; ", "}" },
1620 { NULL, NULL } 1632 { NULL, NULL }
1621 }; 1633 };
1622 1634
1623 const char* statement_data[] = { 1635 const char* statement_data[] = {
1624 "eval;", 1636 "eval;",
1625 "arguments;", 1637 "arguments;",
1626 "var foo = eval;", 1638 "var foo = eval;",
1627 "var foo = arguments;", 1639 "var foo = arguments;",
1628 "var foo = { eval: 1 };", 1640 "var foo = { eval: 1 };",
1629 "var foo = { arguments: 1 };", 1641 "var foo = { arguments: 1 };",
1630 "var foo = { }; foo.eval = {};", 1642 "var foo = { }; foo.eval = {};",
1631 "var foo = { }; foo.arguments = {};", 1643 "var foo = { }; foo.arguments = {};",
1632 NULL 1644 NULL
1633 }; 1645 };
1634 1646
1635 RunParserSyncTest(context_data, statement_data, kSuccess); 1647 static const ParserFlag always_flags[] = { kAllowArrowFunctions };
1648 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
1649 always_flags, ARRAY_SIZE(always_flags));
1636 } 1650 }
1637 1651
1638 1652
1639 TEST(ErrorsFutureStrictReservedWords) { 1653 TEST(ErrorsFutureStrictReservedWords) {
1640 // Tests that both preparsing and parsing produce the right kind of errors for 1654 // Tests that both preparsing and parsing produce the right kind of errors for
1641 // using future strict reserved words as identifiers. Without the strict mode, 1655 // using future strict reserved words as identifiers. Without the strict mode,
1642 // it's ok to use future strict reserved words as identifiers. With the strict 1656 // it's ok to use future strict reserved words as identifiers. With the strict
1643 // mode, it isn't. 1657 // mode, it isn't.
1644 const char* context_data[][2] = { 1658 const char* context_data[][2] = {
1645 { "\"use strict\";", "" }, 1659 { "\"use strict\";", "" },
1646 { "function test_func() {\"use strict\"; ", "}"}, 1660 { "function test_func() {\"use strict\"; ", "}"},
1661 { "() => { \"use strict\"; ", "}" },
1647 { NULL, NULL } 1662 { NULL, NULL }
1648 }; 1663 };
1649 1664
1650 const char* statement_data[] = { 1665 const char* statement_data[] = {
1651 "var interface;", 1666 "var interface;",
1652 "var foo, interface;", 1667 "var foo, interface;",
1653 "try { } catch (interface) { }", 1668 "try { } catch (interface) { }",
1654 "function interface() { }", 1669 "function interface() { }",
1655 "function foo(interface) { }", 1670 "function foo(interface) { }",
1656 "function foo(bar, interface) { }", 1671 "function foo(bar, interface) { }",
1672 "(interface) => { }",
1673 "(bar, interface) => { }",
1657 "interface = 1;", 1674 "interface = 1;",
1658 "var foo = interface = 1;", 1675 "var foo = interface = 1;",
1659 "++interface;", 1676 "++interface;",
1660 "interface++;", 1677 "interface++;",
1661 NULL 1678 NULL
1662 }; 1679 };
1663 1680
1664 RunParserSyncTest(context_data, statement_data, kError); 1681 static const ParserFlag always_flags[] = { kAllowArrowFunctions };
1682 RunParserSyncTest(context_data, statement_data, kError, NULL, 0,
1683 always_flags, ARRAY_SIZE(always_flags));
1665 } 1684 }
1666 1685
1667 1686
1668 TEST(NoErrorsFutureStrictReservedWords) { 1687 TEST(NoErrorsFutureStrictReservedWords) {
1669 const char* context_data[][2] = { 1688 const char* context_data[][2] = {
1670 { "", "" }, 1689 { "", "" },
1671 { "function test_func() {", "}"}, 1690 { "function test_func() {", "}"},
1691 { "() => {", "}" },
1672 { NULL, NULL } 1692 { NULL, NULL }
1673 }; 1693 };
1674 1694
1675 const char* statement_data[] = { 1695 const char* statement_data[] = {
1676 "var interface;", 1696 "var interface;",
1677 "var foo, interface;", 1697 "var foo, interface;",
1678 "try { } catch (interface) { }", 1698 "try { } catch (interface) { }",
1679 "function interface() { }", 1699 "function interface() { }",
1680 "function foo(interface) { }", 1700 "function foo(interface) { }",
1681 "function foo(bar, interface) { }", 1701 "function foo(bar, interface) { }",
1682 "interface = 1;", 1702 "interface = 1;",
1683 "var foo = interface = 1;", 1703 "var foo = interface = 1;",
1684 "++interface;", 1704 "++interface;",
1685 "interface++;", 1705 "interface++;",
1686 NULL 1706 NULL
1687 }; 1707 };
1688 1708
1689 RunParserSyncTest(context_data, statement_data, kSuccess); 1709 static const ParserFlag always_flags[] = { kAllowArrowFunctions };
1710 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
1711 always_flags, ARRAY_SIZE(always_flags));
1712
1690 } 1713 }
1691 1714
1692 1715
1693 TEST(ErrorsReservedWords) { 1716 TEST(ErrorsReservedWords) {
1694 // Tests that both preparsing and parsing produce the right kind of errors for 1717 // Tests that both preparsing and parsing produce the right kind of errors for
1695 // using future reserved words as identifiers. These tests don't depend on the 1718 // using future reserved words as identifiers. These tests don't depend on the
1696 // strict mode. 1719 // strict mode.
1697 const char* context_data[][2] = { 1720 const char* context_data[][2] = {
1698 { "", "" }, 1721 { "", "" },
1699 { "\"use strict\";", "" }, 1722 { "\"use strict\";", "" },
1700 { "var eval; function test_func() {", "}"}, 1723 { "var eval; function test_func() {", "}"},
1701 { "var eval; function test_func() {\"use strict\"; ", "}"}, 1724 { "var eval; function test_func() {\"use strict\"; ", "}"},
1725 { "var eval; () => {", "}" },
1726 { "var eval; () => {\"use strict\"; ", "}" },
1702 { NULL, NULL } 1727 { NULL, NULL }
1703 }; 1728 };
1704 1729
1705 const char* statement_data[] = { 1730 const char* statement_data[] = {
1706 "var super;", 1731 "var super;",
1707 "var foo, super;", 1732 "var foo, super;",
1708 "try { } catch (super) { }", 1733 "try { } catch (super) { }",
1709 "function super() { }", 1734 "function super() { }",
1710 "function foo(super) { }", 1735 "function foo(super) { }",
1711 "function foo(bar, super) { }", 1736 "function foo(bar, super) { }",
1737 "(super) => { }",
1738 "(bar, super) => { }",
1712 "super = 1;", 1739 "super = 1;",
1713 "var foo = super = 1;", 1740 "var foo = super = 1;",
1714 "++super;", 1741 "++super;",
1715 "super++;", 1742 "super++;",
1716 "function foo super", 1743 "function foo super",
1717 NULL 1744 NULL
1718 }; 1745 };
1719 1746
1720 RunParserSyncTest(context_data, statement_data, kError); 1747 RunParserSyncTest(context_data, statement_data, kError);
1721 } 1748 }
1722 1749
1723 1750
1724 TEST(NoErrorsYieldSloppy) { 1751 TEST(NoErrorsYieldSloppy) {
1725 // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a 1752 // In sloppy mode, it's okay to use "yield" as identifier, *except* inside a
1726 // generator (see next test). 1753 // generator (see next test).
1727 const char* context_data[][2] = { 1754 const char* context_data[][2] = {
1728 { "", "" }, 1755 { "", "" },
1729 { "function is_not_gen() {", "}" }, 1756 { "function is_not_gen() {", "}" },
1757 { "() => {", "}" },
1730 { NULL, NULL } 1758 { NULL, NULL }
1731 }; 1759 };
1732 1760
1733 const char* statement_data[] = { 1761 const char* statement_data[] = {
1734 "var yield;", 1762 "var yield;",
1735 "var foo, yield;", 1763 "var foo, yield;",
1736 "try { } catch (yield) { }", 1764 "try { } catch (yield) { }",
1737 "function yield() { }", 1765 "function yield() { }",
1738 "function foo(yield) { }", 1766 "function foo(yield) { }",
1739 "function foo(bar, yield) { }", 1767 "function foo(bar, yield) { }",
1740 "yield = 1;", 1768 "yield = 1;",
1741 "var foo = yield = 1;", 1769 "var foo = yield = 1;",
1742 "++yield;", 1770 "++yield;",
1743 "yield++;", 1771 "yield++;",
1744 NULL 1772 NULL
1745 }; 1773 };
1746 1774
1747 RunParserSyncTest(context_data, statement_data, kSuccess); 1775 static const ParserFlag always_flags[] = { kAllowArrowFunctions };
1776 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
1777 always_flags, ARRAY_SIZE(always_flags));
1748 } 1778 }
1749 1779
1750 1780
1751 TEST(ErrorsYieldSloppyGenerator) { 1781 TEST(ErrorsYieldSloppyGenerator) {
1752 const char* context_data[][2] = { 1782 const char* context_data[][2] = {
1753 { "function * is_gen() {", "}" }, 1783 { "function * is_gen() {", "}" },
1754 { NULL, NULL } 1784 { NULL, NULL }
1755 }; 1785 };
1756 1786
1757 const char* statement_data[] = { 1787 const char* statement_data[] = {
(...skipping 16 matching lines...) Expand all
1774 // so this test works both with and without the kAllowGenerators flag. 1804 // so this test works both with and without the kAllowGenerators flag.
1775 RunParserSyncTest(context_data, statement_data, kError); 1805 RunParserSyncTest(context_data, statement_data, kError);
1776 } 1806 }
1777 1807
1778 1808
1779 TEST(ErrorsYieldStrict) { 1809 TEST(ErrorsYieldStrict) {
1780 const char* context_data[][2] = { 1810 const char* context_data[][2] = {
1781 { "\"use strict\";", "" }, 1811 { "\"use strict\";", "" },
1782 { "\"use strict\"; function is_not_gen() {", "}" }, 1812 { "\"use strict\"; function is_not_gen() {", "}" },
1783 { "function test_func() {\"use strict\"; ", "}"}, 1813 { "function test_func() {\"use strict\"; ", "}"},
1814 { "() => {\"use strict\"; ", "}" },
1784 { NULL, NULL } 1815 { NULL, NULL }
1785 }; 1816 };
1786 1817
1787 const char* statement_data[] = { 1818 const char* statement_data[] = {
1788 "var yield;", 1819 "var yield;",
1789 "var foo, yield;", 1820 "var foo, yield;",
1790 "try { } catch (yield) { }", 1821 "try { } catch (yield) { }",
1791 "function yield() { }", 1822 "function yield() { }",
1792 "function foo(yield) { }", 1823 "function foo(yield) { }",
1793 "function foo(bar, yield) { }", 1824 "function foo(bar, yield) { }",
1825 "(yield) => { }",
1826 "(bar, yield) => { }",
1794 "yield = 1;", 1827 "yield = 1;",
1795 "var foo = yield = 1;", 1828 "var foo = yield = 1;",
1796 "++yield;", 1829 "++yield;",
1797 "yield++;", 1830 "yield++;",
1798 NULL 1831 NULL
1799 }; 1832 };
1800 1833
1801 RunParserSyncTest(context_data, statement_data, kError); 1834 RunParserSyncTest(context_data, statement_data, kError);
1802 } 1835 }
1803 1836
1804 1837
1805 TEST(NoErrorsYield) { 1838 TEST(NoErrorsYield) {
1806 const char* context_data[][2] = { 1839 const char* context_data[][2] = {
1807 { "function * is_gen() {", "}" }, 1840 { "function * is_gen() {", "}" },
1808 { NULL, NULL } 1841 { NULL, NULL }
1809 }; 1842 };
1810 1843
1811 const char* statement_data[] = { 1844 const char* statement_data[] = {
1812 "yield 2;", // this is legal inside generator 1845 "yield 2;", // this is legal inside generator
1813 "yield * 2;", // this is legal inside generator 1846 "yield * 2;", // this is legal inside generator
1814 NULL 1847 NULL
1815 }; 1848 };
1816 1849
1817 // This test requires kAllowGenerators to succeed. 1850 // This test requires kAllowGenerators to succeed.
1818 static const ParserFlag always_true_flags[] = { 1851 static const ParserFlag always_true_flags[] = {
1819 kAllowGenerators 1852 kAllowGenerators,
1820 }; 1853 };
1821 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, 1854 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
1822 always_true_flags, 1); 1855 always_true_flags, 1);
1823 } 1856 }
1824 1857
1825 1858
1826 TEST(ErrorsNameOfStrictFunction) { 1859 TEST(ErrorsNameOfStrictFunction) {
1827 // Tests that illegal tokens as names of a strict function produce the correct 1860 // Tests that illegal tokens as names of a strict function produce the correct
1828 // errors. 1861 // errors.
1829 const char* context_data[][2] = { 1862 const char* context_data[][2] = {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1864 RunParserSyncTest(context_data, statement_data, kSuccess); 1897 RunParserSyncTest(context_data, statement_data, kSuccess);
1865 } 1898 }
1866 1899
1867 1900
1868 1901
1869 TEST(ErrorsIllegalWordsAsLabelsSloppy) { 1902 TEST(ErrorsIllegalWordsAsLabelsSloppy) {
1870 // Using future reserved words as labels is always an error. 1903 // Using future reserved words as labels is always an error.
1871 const char* context_data[][2] = { 1904 const char* context_data[][2] = {
1872 { "", ""}, 1905 { "", ""},
1873 { "function test_func() {", "}" }, 1906 { "function test_func() {", "}" },
1907 { "() => {", "}" },
1874 { NULL, NULL } 1908 { NULL, NULL }
1875 }; 1909 };
1876 1910
1877 const char* statement_data[] = { 1911 const char* statement_data[] = {
1878 "super: while(true) { break super; }", 1912 "super: while(true) { break super; }",
1879 NULL 1913 NULL
1880 }; 1914 };
1881 1915
1882 RunParserSyncTest(context_data, statement_data, kError); 1916 RunParserSyncTest(context_data, statement_data, kError);
1883 } 1917 }
1884 1918
1885 1919
1886 TEST(ErrorsIllegalWordsAsLabelsStrict) { 1920 TEST(ErrorsIllegalWordsAsLabelsStrict) {
1887 // Tests that illegal tokens as labels produce the correct errors. 1921 // Tests that illegal tokens as labels produce the correct errors.
1888 const char* context_data[][2] = { 1922 const char* context_data[][2] = {
1889 { "\"use strict\";", "" }, 1923 { "\"use strict\";", "" },
1890 { "function test_func() {\"use strict\"; ", "}"}, 1924 { "function test_func() {\"use strict\"; ", "}"},
1925 { "() => {\"use strict\"; ", "}" },
1891 { NULL, NULL } 1926 { NULL, NULL }
1892 }; 1927 };
1893 1928
1894 const char* statement_data[] = { 1929 const char* statement_data[] = {
1895 "super: while(true) { break super; }", 1930 "super: while(true) { break super; }",
1896 "interface: while(true) { break interface; }", 1931 "interface: while(true) { break interface; }",
1897 "yield: while(true) { break yield; }", 1932 "yield: while(true) { break yield; }",
1898 NULL 1933 NULL
1899 }; 1934 };
1900 1935
1901 RunParserSyncTest(context_data, statement_data, kError); 1936 RunParserSyncTest(context_data, statement_data, kError);
1902 } 1937 }
1903 1938
1904 1939
1905 TEST(NoErrorsIllegalWordsAsLabels) { 1940 TEST(NoErrorsIllegalWordsAsLabels) {
1906 // Using eval and arguments as labels is legal even in strict mode. 1941 // Using eval and arguments as labels is legal even in strict mode.
1907 const char* context_data[][2] = { 1942 const char* context_data[][2] = {
1908 { "", ""}, 1943 { "", ""},
1909 { "function test_func() {", "}" }, 1944 { "function test_func() {", "}" },
1945 { "() => {", "}" },
1910 { "\"use strict\";", "" }, 1946 { "\"use strict\";", "" },
1911 { "\"use strict\"; function test_func() {", "}" }, 1947 { "\"use strict\"; function test_func() {", "}" },
1948 { "\"use strict\"; () => {", "}" },
1912 { NULL, NULL } 1949 { NULL, NULL }
1913 }; 1950 };
1914 1951
1915 const char* statement_data[] = { 1952 const char* statement_data[] = {
1916 "mylabel: while(true) { break mylabel; }", 1953 "mylabel: while(true) { break mylabel; }",
1917 "eval: while(true) { break eval; }", 1954 "eval: while(true) { break eval; }",
1918 "arguments: while(true) { break arguments; }", 1955 "arguments: while(true) { break arguments; }",
1919 NULL 1956 NULL
1920 }; 1957 };
1921 1958
1922 RunParserSyncTest(context_data, statement_data, kSuccess); 1959 static const ParserFlag always_flags[] = { kAllowArrowFunctions };
1960 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
1961 always_flags, ARRAY_SIZE(always_flags));
1923 } 1962 }
1924 1963
1925 1964
1926 TEST(ErrorsParenthesizedLabels) { 1965 TEST(ErrorsParenthesizedLabels) {
1927 // Parenthesized identifiers shouldn't be recognized as labels. 1966 // Parenthesized identifiers shouldn't be recognized as labels.
1928 const char* context_data[][2] = { 1967 const char* context_data[][2] = {
1929 { "", ""}, 1968 { "", ""},
1930 { "function test_func() {", "}" }, 1969 { "function test_func() {", "}" },
1970 { "() => {", "}" },
1931 { NULL, NULL } 1971 { NULL, NULL }
1932 }; 1972 };
1933 1973
1934 const char* statement_data[] = { 1974 const char* statement_data[] = {
1935 "(mylabel): while(true) { break mylabel; }", 1975 "(mylabel): while(true) { break mylabel; }",
1936 NULL 1976 NULL
1937 }; 1977 };
1938 1978
1939 RunParserSyncTest(context_data, statement_data, kError); 1979 RunParserSyncTest(context_data, statement_data, kError);
1940 } 1980 }
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2170 NULL 2210 NULL
2171 }; 2211 };
2172 2212
2173 // This test requires kAllowNativesSyntax to succeed. 2213 // This test requires kAllowNativesSyntax to succeed.
2174 static const ParserFlag always_true_flags[] = { 2214 static const ParserFlag always_true_flags[] = {
2175 kAllowNativesSyntax 2215 kAllowNativesSyntax
2176 }; 2216 };
2177 2217
2178 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0, 2218 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
2179 always_true_flags, 1); 2219 always_true_flags, 1);
2220 RunParserSyncTest(context_data, statement_data, kSuccessOrError);
2180 } 2221 }
2181 2222
2182 2223
2183 TEST(NoErrorsNewExpression) { 2224 TEST(NoErrorsNewExpression) {
2184 const char* context_data[][2] = { 2225 const char* context_data[][2] = {
2185 {"", ""}, 2226 {"", ""},
2186 {"var f =", ""}, 2227 {"var f =", ""},
2187 { NULL, NULL } 2228 { NULL, NULL }
2188 }; 2229 };
2189 2230
(...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after
2764 LocalContext env; 2805 LocalContext env;
2765 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; 2806 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
2766 global_use_counts = use_counts; 2807 global_use_counts = use_counts;
2767 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); 2808 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
2768 CompileRun("\"use asm\";\n" 2809 CompileRun("\"use asm\";\n"
2769 "var foo = 1;\n" 2810 "var foo = 1;\n"
2770 "\"use asm\";\n" // Only the first one counts. 2811 "\"use asm\";\n" // Only the first one counts.
2771 "function bar() { \"use asm\"; var baz = 1; }"); 2812 "function bar() { \"use asm\"; var baz = 1; }");
2772 CHECK_EQ(2, use_counts[v8::Isolate::kUseAsm]); 2813 CHECK_EQ(2, use_counts[v8::Isolate::kUseAsm]);
2773 } 2814 }
2815
2816
2817 TEST(ErrorsArrowFunctions) {
marja 2014/07/01 07:23:40 I like this test! :)
2818 // Tests that parser and preparser generate the same kind of errors
2819 // on invalid arrow function syntax.
2820 const char* context_data[][2] = {
2821 {"", ";"},
2822 {"v = ", ";"},
2823 {"bar ? (", ") : baz;"},
2824 {"bar ? baz : (", ");"},
2825 {"bar[", "];"},
2826 {"bar, ", ";"},
2827 {"", ", bar;"},
2828 { NULL, NULL }
2829 };
2830
2831 const char* statement_data[] = {
2832 "=> 0",
2833 "=>",
2834 "() =>",
2835 "=> {}",
2836 ") => {}",
2837 ", => {}",
2838 "(,) => {}",
2839 "return => {}",
2840 "() => {'value': 42}",
2841
2842 // Check that the early return introduced in ParsePrimaryExpression
2843 // does not accept stray closing parentheses.
2844 ")",
2845 ") => 0",
2846 "foo[()]",
2847 "()",
2848
2849 // Parameter lists with extra parens should be recognized as errors.
2850 "(()) => 0",
2851 "((x)) => 0",
2852 "((x, y)) => 0",
2853 "(x, (y)) => 0",
2854 "((x, y, z)) => 0",
2855 "(x, (y, z)) => 0",
2856 "((x, y), z) => 0",
2857
2858 // Parameter lists are always validated as strict, so those are errors.
2859 "eval => {}",
2860 "arguments => {}",
2861 "yield => {}",
2862 "interface => {}",
2863 "(eval) => {}",
2864 "(arguments) => {}",
2865 "(yield) => {}",
2866 "(interface) => {}",
2867 "(eval, bar) => {}",
2868 "(bar, eval) => {}",
2869 "(bar, arguments) => {}",
2870 "(bar, yield) => {}",
2871 "(bar, interface) => {}",
2872 // TODO(aperez): Detecting duplicates does not work in PreParser.
2873 //"(bar, bar) => {}",
2874
2875 // The parameter list is parsed as an expression, but only
2876 // a comma-separated list of identifier is valid.
2877 "32 => {}",
2878 "(32) => {}",
2879 "(a, 32) => {}",
2880 "if => {}",
2881 "(if) => {}",
2882 "(a, if) => {}",
2883 "a + b => {}",
2884 "(a + b) => {}",
2885 "(a + b, c) => {}",
2886 "(a, b - c) => {}",
2887 "\"a\" => {}",
2888 "(\"a\") => {}",
2889 "(\"a\", b) => {}",
2890 "(a, \"b\") => {}",
2891 "-a => {}",
2892 "(-a) => {}",
2893 "(-a, b) => {}",
2894 "(a, -b) => {}",
2895 "{} => {}",
2896 "({}) => {}",
2897 "(a, {}) => {}",
2898 "({}, a) => {}",
2899 "a++ => {}",
2900 "(a++) => {}",
2901 "(a++, b) => {}",
2902 "(a, b++) => {}",
2903 "[] => {}",
2904 "([]) => {}",
2905 "(a, []) => {}",
2906 "([], a) => {}",
2907 "(a = b) => {}",
2908 "(a = b, c) => {}",
2909 "(a, b = c) => {}",
2910 "(foo ? bar : baz) => {}",
2911 "(a, foo ? bar : baz) => {}",
2912 "(foo ? bar : baz, a) => {}",
2913
2914 NULL
2915 };
2916
2917 RunParserSyncTest(context_data, statement_data, kError);
2918 }
2919
2920
2921 TEST(NoErrorsArrowFunctions) {
2922 // Tests that parser and preparser accept valid arrow functions syntax.
2923 const char* context_data[][2] = {
2924 {"", ";"},
2925 // TODO(aperez): Uncomment this when ParseArrowFunctionLiteral()
2926 // generates code and returns a non-NULL expression. Currently it
2927 // crashes when expression->set_is_parenthesized(true) is called.
2928 //{"bar ? (", ") : baz;"},
2929 //{"bar ? baz : (", ");"},
2930 {"bar, ", ";"},
2931 {"", ", bar;"},
2932 { NULL, NULL }
2933 };
2934
2935 const char* statement_data[] = {
2936 "() => {}",
2937 "() => { return 42 }",
2938 "x => { return x; }",
2939 "(x) => { return x; }",
2940 "(x, y) => { return x + y; }",
2941 "(x, y, z) => { return x + y + z; }",
2942 "(x, y) => { x.a = y; }",
2943 "() => 42",
2944 "x => x",
2945 "x => x * x",
2946 "(x) => x",
2947 "(x) => x * x",
2948 "(x, y) => x + y",
2949 "(x, y, z) => x, y, z",
2950 "(x, y) => x.a = y",
2951 "() => ({'value': 42})",
2952 "x => y => x + y",
2953 "(x, y) => (u, v) => x*u + y*v",
2954 "(x, y) => z => z * (x + y)",
2955 "x => (y, z) => z * (x + y)",
2956
2957 // Those are comma-separated expressions, with arrow functions as items.
2958 // They stress the code for validating arrow function parameter lists.
2959 "a, b => 0",
2960 "a, b, (c, d) => 0",
2961 "(a, b, (c, d) => 0)",
2962 "(a, b) => 0, (c, d) => 1",
2963 "(a, b => {}, a => a + 1)",
2964 // TODO(aperez): Uncomment this when ParseArrowFunctionLiteral()
2965 // generates code and returns a non-NULL expression. Currently it
2966 // crashes when expression->set_is_parenthesized(true) is called.
2967 //"((a, b) => {}, (a => a + 1))",
2968 //"(a, (a, (b, c) => 0))",
2969
2970 // Arrow has more precedence, this is the same as: foo ? bar : (baz = {})
2971 "foo ? bar : baz => {}",
2972
2973 NULL
2974 };
2975
2976 static const ParserFlag always_flags[] = { kAllowArrowFunctions };
2977 RunParserSyncTest(context_data, statement_data, kSuccess, NULL, 0,
2978 always_flags, ARRAY_SIZE(always_flags));
2979 }
OLDNEW
« src/preparser.h ('K') | « src/token.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698