Chromium Code Reviews| Index: test/cctest/test-parsing.cc |
| diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc |
| index ec5d5f9d9badc157b88a26b9e543642ccd5b0712..4a0a48185913c83867ccdda70ba853736bb50c6e 100644 |
| --- a/test/cctest/test-parsing.cc |
| +++ b/test/cctest/test-parsing.cc |
| @@ -1532,7 +1532,8 @@ void SetParserFlags(i::ParserBase<Traits>* parser, |
| void TestParserSyncWithFlags(i::Handle<i::String> source, |
| i::EnumSet<ParserFlag> flags, |
| - ParserSyncTestResult result) { |
| + ParserSyncTestResult result, |
| + bool is_module = false) { |
| i::Isolate* isolate = CcTest::i_isolate(); |
| i::Factory* factory = isolate->factory(); |
| @@ -1542,7 +1543,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
| // Preparse the data. |
| i::CompleteParserRecorder log; |
| - { |
| + if (!is_module) { |
|
adamk
2015/11/04 23:42:02
Please add something of this form to make this cle
caitp (gmail)
2015/11/06 19:08:06
Done.
|
| i::Scanner scanner(isolate->unicode_cache()); |
| i::GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| i::Zone zone; |
| @@ -1556,7 +1557,6 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
| &preparser_materialized_literals); |
| CHECK_EQ(i::PreParser::kPreParseSuccess, result); |
| } |
| - |
| bool preparse_error = log.HasError(); |
| // Parse the data |
| @@ -1567,7 +1567,11 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
| i::ParseInfo info(&zone, script); |
| i::Parser parser(&info); |
| SetParserFlags(&parser, flags); |
| - info.set_global(); |
| + if (is_module) { |
| + info.set_module(); |
| + } else { |
| + info.set_global(); |
| + } |
| parser.Parse(&info); |
| function = info.literal(); |
| if (function) { |
| @@ -1596,7 +1600,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
| CHECK(false); |
| } |
| - if (!preparse_error) { |
| + if (!is_module && !preparse_error) { |
|
adamk
2015/11/04 23:42:02
and then use it here too
|
| v8::base::OS::Print( |
| "Parser failed on:\n" |
| "\t%s\n" |
| @@ -1607,21 +1611,22 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
| CHECK(false); |
| } |
| // Check that preparser and parser produce the same error. |
| - i::Handle<i::String> preparser_message = |
| - FormatMessage(log.ErrorMessageData()); |
| - if (!i::String::Equals(message_string, preparser_message)) { |
| - v8::base::OS::Print( |
| - "Expected parser and preparser to produce the same error on:\n" |
| - "\t%s\n" |
| - "However, found the following error messages\n" |
| - "\tparser: %s\n" |
| - "\tpreparser: %s\n", |
| - source->ToCString().get(), |
| - message_string->ToCString().get(), |
| - preparser_message->ToCString().get()); |
| - CHECK(false); |
| + if (!is_module) { |
|
adamk
2015/11/04 23:42:02
and here
|
| + i::Handle<i::String> preparser_message = |
| + FormatMessage(log.ErrorMessageData()); |
| + if (!i::String::Equals(message_string, preparser_message)) { |
| + v8::base::OS::Print( |
| + "Expected parser and preparser to produce the same error on:\n" |
| + "\t%s\n" |
| + "However, found the following error messages\n" |
| + "\tparser: %s\n" |
| + "\tpreparser: %s\n", |
| + source->ToCString().get(), message_string->ToCString().get(), |
| + preparser_message->ToCString().get()); |
| + CHECK(false); |
| + } |
| } |
| - } else if (preparse_error) { |
| + } else if (!is_module && preparse_error) { |
|
adamk
2015/11/04 23:42:02
and here
|
| v8::base::OS::Print( |
| "Preparser failed on:\n" |
| "\t%s\n" |
| @@ -1638,7 +1643,8 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
| "However, parser and preparser succeeded", |
| source->ToCString().get()); |
| CHECK(false); |
| - } else if (preparser_materialized_literals != parser_materialized_literals) { |
| + } else if (!is_module && |
|
adamk
2015/11/04 23:42:02
and here
|
| + preparser_materialized_literals != parser_materialized_literals) { |
| v8::base::OS::Print( |
| "Preparser materialized literals (%d) differ from Parser materialized " |
| "literals (%d) on:\n" |
| @@ -1651,14 +1657,14 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
| } |
| -void TestParserSync(const char* source, |
| - const ParserFlag* varying_flags, |
| +void TestParserSync(const char* source, const ParserFlag* varying_flags, |
| size_t varying_flags_length, |
| ParserSyncTestResult result = kSuccessOrError, |
| const ParserFlag* always_true_flags = NULL, |
| size_t always_true_flags_length = 0, |
| const ParserFlag* always_false_flags = NULL, |
| - size_t always_false_flags_length = 0) { |
| + size_t always_false_flags_length = 0, |
| + bool is_module = false) { |
| i::Handle<i::String> str = |
| CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source); |
| for (int bits = 0; bits < (1 << varying_flags_length); bits++) { |
| @@ -1675,7 +1681,7 @@ void TestParserSync(const char* source, |
| ++flag_index) { |
| flags.Remove(always_false_flags[flag_index]); |
| } |
| - TestParserSyncWithFlags(str, flags, result); |
| + TestParserSyncWithFlags(str, flags, result, is_module); |
| } |
| } |
| @@ -1819,12 +1825,11 @@ TEST(StrictOctal) { |
| void RunParserSyncTest(const char* context_data[][2], |
| const char* statement_data[], |
| ParserSyncTestResult result, |
| - const ParserFlag* flags = NULL, |
| - int flags_len = 0, |
| + const ParserFlag* flags = NULL, int flags_len = 0, |
| const ParserFlag* always_true_flags = NULL, |
| int always_true_len = 0, |
| const ParserFlag* always_false_flags = NULL, |
| - int always_false_len = 0) { |
| + int always_false_len = 0, bool is_module = false) { |
| v8::HandleScope handles(CcTest::isolate()); |
| v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate()); |
| v8::Context::Scope context_scope(context); |
| @@ -1877,20 +1882,32 @@ void RunParserSyncTest(const char* context_data[][2], |
| statement_data[j], |
| context_data[i][1]); |
| CHECK(length == kProgramSize); |
| - TestParserSync(program.start(), |
| - flags, |
| - flags_len, |
| - result, |
| - always_true_flags, |
| - always_true_len, |
| - always_false_flags, |
| - always_false_len); |
| + TestParserSync(program.start(), flags, flags_len, result, |
| + always_true_flags, always_true_len, always_false_flags, |
| + always_false_len, is_module); |
| } |
| } |
| delete[] generated_flags; |
| } |
| +void RunModuleParserSyncTest(const char* context_data[][2], |
| + const char* statement_data[], |
| + ParserSyncTestResult result, |
| + const ParserFlag* flags = NULL, int flags_len = 0, |
| + const ParserFlag* always_true_flags = NULL, |
| + int always_true_len = 0, |
| + const ParserFlag* always_false_flags = NULL, |
| + int always_false_len = 0) { |
| + bool flag = i::FLAG_harmony_modules; |
| + i::FLAG_harmony_modules = true; |
| + RunParserSyncTest(context_data, statement_data, result, flags, flags_len, |
| + always_true_flags, always_true_len, always_false_flags, |
| + always_false_len, true); |
| + i::FLAG_harmony_modules = flag; |
| +} |
| + |
| + |
| TEST(ErrorsEvalAndArguments) { |
| // Tests that both preparsing and parsing produce the right kind of errors for |
| // using "eval" and "arguments" as identifiers. Without the strict mode, it's |
| @@ -7235,3 +7252,151 @@ TEST(LetSloppyOnly) { |
| RunParserSyncTest(context_data, fail_data, kError, NULL, 0, fail_flags, |
| arraysize(fail_flags)); |
| } |
| + |
| + |
| +TEST(EscapedKeywords) { |
| + // clang-format off |
| + const char* sloppy_context_data[][2] = { |
| + {"", ""}, |
| + {NULL, NULL} |
| + }; |
| + |
| + const char* strict_context_data[][2] = { |
| + {"'use strict';", ""}, |
| + {NULL, NULL} |
| + }; |
| + |
| + const char* fail_data[] = { |
| + "for (var i = 0; i < 100; ++i) { br\\u0065ak; }", |
| + "cl\\u0061ss Foo {}", |
| + "var x = cl\\u0061ss {}", |
| + "\\u0063onst foo = 1;", |
| + "while (i < 10) { if (i++ & 1) c\\u006fntinue; this.x++; }", |
| + "d\\u0065bugger;", |
| + "d\\u0065lete this.a;", |
| + "\\u0063o { } while(0)", |
| + "if (d\\u006f { true }) {}", |
| + "if (false) { this.a = 1; } \\u0065lse { this.b = 1; }", |
| + "e\\u0078port var foo;", |
| + "try { } catch (e) {} f\\u0069nally { }", |
| + "f\\u006fr (var i = 0; i < 10; ++i);", |
| + "f\\u0075nction fn() {}", |
| + "var f = f\\u0075nction() {}", |
| + "\\u0069f (true) { }", |
| + "\\u0069mport blah from './foo.js';", |
| + "n\\u0065w function f() {}", |
| + "(function() { r\\u0065turn; })()", |
| + "class C extends function() {} { constructor() { sup\\u0065r() } }", |
| + "class C extends function() {} { constructor() { sup\\u0065r.a = 1 } }", |
| + "sw\\u0069tch (this.a) {}", |
| + "var x = th\\u0069s;", |
| + "th\\u0069s.a = 1;", |
| + "thr\\u006fw 'boo';", |
| + "t\\u0072y { true } catch (e) {}", |
| + "var x = typ\\u0065of 'blah'", |
| + "v\\u0061r a = true", |
| + "var v\\u0061r = true", |
| + "(function() { return v\\u006fid 0; })()", |
| + "wh\\u0069le (true) { }", |
| + "w\\u0069th (this.scope) { }", |
| + "(function*() { y\\u0069eld 1; })()", |
| + |
| + "var \\u0065num = 1;", |
| + "var { \\u0065num } = {}", |
| + "(\\u0065num = 1);", |
| + |
| + // Null / Boolean literals |
| + "(x === n\\u0075ll);", |
| + "var x = n\\u0075ll;", |
| + "var n\\u0075ll = 1;", |
| + "var { n\\u0075ll } = { 1 };", |
| + "n\\u0075ll = 1;", |
| + "(x === tr\\u0075e);", |
| + "var x = tr\\u0075e;", |
| + "var tr\\u0075e = 1;", |
| + "var { tr\\u0075e } = {};", |
| + "tr\\u0075e = 1;", |
| + "(x === f\\u0061lse);", |
| + "var x = f\\u0061lse;", |
| + "var f\\u0061lse = 1;", |
| + "var { f\\u0061lse } = {};", |
| + "f\\u0061lse = 1;", |
| + |
| + // TODO(caitp): consistent error messages for labeled statements and |
| + // expressions |
| + "switch (this.a) { c\\u0061se 6: break; }", |
| + "try { } c\\u0061tch (e) {}", |
| + "switch (this.a) { d\\u0065fault: break; }", |
| + "class C \\u0065xtends function B() {} {}", |
| + "for (var a i\\u006e this) {}", |
| + "if ('foo' \\u0069n this) {}", |
| + "if (this \\u0069nstanceof Array) {}", |
| + "(n\\u0065w function f() {})", |
| + "(typ\\u0065of 123)", |
| + "(v\\u006fid 0)", |
| + "do { ; } wh\\u0069le (true) { }", |
| + "(function*() { return (n++, y\\u0069eld 1); })()", |
| + "class C { st\\u0061tic bar() {} }", |
| + |
| + "(y\\u0069eld);", |
| + "var y\\u0069eld = 1;", |
| + "var { y\\u0069eld } = {};", |
| + NULL |
| + }; |
| + // clang-format on |
| + |
| + static const ParserFlag always_flags[] = {kAllowHarmonySloppy, |
| + kAllowHarmonyDestructuring}; |
| + RunParserSyncTest(sloppy_context_data, fail_data, kError, NULL, 0, |
| + always_flags, arraysize(always_flags)); |
| + RunParserSyncTest(strict_context_data, fail_data, kError, NULL, 0, |
| + always_flags, arraysize(always_flags)); |
| + RunModuleParserSyncTest(sloppy_context_data, fail_data, kError, NULL, 0, |
| + always_flags, arraysize(always_flags)); |
| + |
| + // clang-format off |
| + const char* let_data[] = { |
| + "var l\\u0065t = 1;", |
| + "l\\u0065t = 1;", |
| + "(l\\u0065t === 1);", |
| + NULL |
| + }; |
| + // clang-format on |
| + |
| + RunParserSyncTest(sloppy_context_data, let_data, kError, NULL, 0, |
| + always_flags, arraysize(always_flags)); |
| + RunParserSyncTest(strict_context_data, let_data, kError, NULL, 0, |
| + always_flags, arraysize(always_flags)); |
| + |
| + static const ParserFlag sloppy_let_flags[] = { |
| + kAllowHarmonySloppy, kAllowHarmonySloppyLet, kAllowHarmonyDestructuring}; |
| + RunParserSyncTest(sloppy_context_data, let_data, kError, NULL, 0, |
| + sloppy_let_flags, arraysize(sloppy_let_flags)); |
| + |
| + // Non-errors in sloppy mode |
| + const char* valid_data[] = {"(\\u0069mplements = 1);", |
| + "var impl\\u0065ments = 1;", |
| + "var { impl\\u0065ments } = {};", |
| + "(\\u0069nterface = 1);", |
| + "var int\\u0065rface = 1;", |
| + "var { int\\u0065rface } = {};", |
| + "(p\\u0061ckage = 1);", |
| + "var packa\\u0067e = 1;", |
| + "var { packa\\u0067e } = {};", |
| + "(p\\u0072ivate = 1);", |
| + "var p\\u0072ivate;", |
| + "var { p\\u0072ivate } = {};", |
| + "(prot\\u0065cted);", |
| + "var prot\\u0065cted = 1;", |
| + "var { prot\\u0065cted } = {};", |
| + "(publ\\u0069c);", |
| + "var publ\\u0069c = 1;", |
| + "var { publ\\u0069c } = {};", |
| + NULL}; |
| + RunParserSyncTest(sloppy_context_data, valid_data, kSuccess, NULL, 0, |
| + always_flags, arraysize(always_flags)); |
| + RunParserSyncTest(strict_context_data, valid_data, kError, NULL, 0, |
| + always_flags, arraysize(always_flags)); |
| + RunModuleParserSyncTest(strict_context_data, valid_data, kError, NULL, 0, |
| + always_flags, arraysize(always_flags)); |
| +} |