Index: test/cctest/test-parsing.cc |
diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc |
index 37b40e37ae3bb204d045b4531ff948c901cee7ad..be9f7f782a899c6034654566a4cb827f7060eb53 100644 |
--- a/test/cctest/test-parsing.cc |
+++ b/test/cctest/test-parsing.cc |
@@ -1285,6 +1285,7 @@ enum ParserFlag { |
kAllowHarmonyTrailingCommas, |
kAllowHarmonyClassFields, |
kAllowHarmonyObjectRestSpread, |
+ kAllowHarmonyDynamicImport, |
}; |
enum ParserSyncTestResult { |
@@ -1302,6 +1303,7 @@ void SetGlobalFlags(i::EnumSet<ParserFlag> flags) { |
i::FLAG_harmony_class_fields = flags.Contains(kAllowHarmonyClassFields); |
i::FLAG_harmony_object_rest_spread = |
flags.Contains(kAllowHarmonyObjectRestSpread); |
+ i::FLAG_harmony_dynamic_import = flags.Contains(kAllowHarmonyDynamicImport); |
} |
void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) { |
@@ -1316,13 +1318,15 @@ void SetParserFlags(i::PreParser* parser, i::EnumSet<ParserFlag> flags) { |
flags.Contains(kAllowHarmonyClassFields)); |
parser->set_allow_harmony_object_rest_spread( |
flags.Contains(kAllowHarmonyObjectRestSpread)); |
+ parser->set_allow_harmony_dynamic_import( |
+ flags.Contains(kAllowHarmonyDynamicImport)); |
} |
void TestParserSyncWithFlags(i::Handle<i::String> source, |
i::EnumSet<ParserFlag> flags, |
ParserSyncTestResult result, |
- bool is_module = false, |
- bool test_preparser = true) { |
+ bool is_module = false, bool test_preparser = true, |
+ bool ignore_error_msg = false) { |
i::Isolate* isolate = CcTest::i_isolate(); |
i::Factory* factory = isolate->factory(); |
@@ -1399,7 +1403,7 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
CHECK(false); |
} |
// Check that preparser and parser produce the same error. |
- if (test_preparser) { |
+ if (test_preparser && !ignore_error_msg) { |
i::Handle<i::String> preparser_message = |
pending_error_handler.FormatMessage(CcTest::i_isolate()); |
if (!i::String::Equals(message_string, preparser_message)) { |
@@ -1446,7 +1450,6 @@ void TestParserSyncWithFlags(i::Handle<i::String> source, |
} |
} |
- |
void TestParserSync(const char* source, const ParserFlag* varying_flags, |
size_t varying_flags_length, |
ParserSyncTestResult result = kSuccessOrError, |
@@ -1454,7 +1457,8 @@ void TestParserSync(const char* source, const ParserFlag* varying_flags, |
size_t always_true_flags_length = 0, |
const ParserFlag* always_false_flags = NULL, |
size_t always_false_flags_length = 0, |
- bool is_module = false, bool test_preparser = true) { |
+ bool is_module = false, bool test_preparser = true, |
+ bool ignore_error_msg = false) { |
i::Handle<i::String> str = |
CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source); |
for (int bits = 0; bits < (1 << varying_flags_length); bits++) { |
@@ -1471,7 +1475,8 @@ void TestParserSync(const char* source, const ParserFlag* varying_flags, |
++flag_index) { |
flags.Remove(always_false_flags[flag_index]); |
} |
- TestParserSyncWithFlags(str, flags, result, is_module, test_preparser); |
+ TestParserSyncWithFlags(str, flags, result, is_module, test_preparser, |
+ ignore_error_msg); |
} |
} |
@@ -1611,16 +1616,13 @@ TEST(StrictOctal) { |
*exception)); |
} |
- |
-void RunParserSyncTest(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 is_module = false, |
- bool test_preparser = true) { |
+void RunParserSyncTest( |
+ 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 is_module = false, |
+ bool test_preparser = true, bool ignore_error_msg = false) { |
v8::HandleScope handles(CcTest::isolate()); |
v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate()); |
v8::Context::Scope context_scope(context); |
@@ -1675,25 +1677,23 @@ void RunParserSyncTest(const char* context_data[][2], |
CHECK(length == kProgramSize); |
TestParserSync(program.start(), flags, flags_len, result, |
always_true_flags, always_true_len, always_false_flags, |
- always_false_len, is_module, test_preparser); |
+ always_false_len, is_module, test_preparser, |
+ ignore_error_msg); |
} |
} |
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 test_preparser = true) { |
+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 test_preparser = true, |
+ bool ignore_error_msg = false) { |
RunParserSyncTest(context_data, statement_data, result, flags, flags_len, |
always_true_flags, always_true_len, always_false_flags, |
- always_false_len, true, test_preparser); |
+ always_false_len, true, test_preparser, ignore_error_msg); |
} |
@@ -4142,6 +4142,140 @@ TEST(SuperErrors) { |
RunParserSyncTest(context_data, expression_data, kError); |
} |
+TEST(ImportExpressionSuccess) { |
+ // clang-format off |
+ const char* context_data[][2] = { |
+ {"", ""}, |
+ {NULL, NULL} |
+ }; |
+ |
+ const char* data[] = { |
+ "new import(x)", |
+ "import(1)", |
+ "import(y=x)", |
+ "f(...[import(y=x)])", |
+ "x = {[import(y=x)]: 1}", |
+ "var {[import(y=x)]: x} = {}", |
+ "({[import(y=x)]: x} = {})", |
+ "async () => { await import(x) }", |
+ "() => { import(x) }", |
+ "(import(y=x))", |
+ "{import(y=x)}", |
+ "import(import(x))", |
+ "x = import(x)", |
+ "var x = import(x)", |
+ "let x = import(x)", |
+ "for(x of import(x)) {}", |
+ "import(x).then()", |
+ NULL |
+ }; |
+ |
+ // clang-format on |
+ |
+ // We ignore test error messages because the error message from the |
+ // parser/preparser is different for the same data depending on the |
+ // context. |
+ // For example, a top level "import(" is parsed as an |
+ // import declaration. The parser parses the import token correctly |
+ // and then shows an "Unexpected token (" error message. The |
+ // preparser does not understand the import keyword (this test is |
+ // run without kAllowHarmonyDynamicImport flag), so this results in |
+ // an "Unexpected token import" error. |
+ RunParserSyncTest(context_data, data, kError); |
+ RunModuleParserSyncTest(context_data, data, kError, NULL, 0, NULL, 0, NULL, 0, |
+ true, true); |
+ static const ParserFlag flags[] = {kAllowHarmonyDynamicImport}; |
+ RunParserSyncTest(context_data, data, kSuccess, NULL, 0, flags, |
+ arraysize(flags)); |
+ RunModuleParserSyncTest(context_data, data, kSuccess, NULL, 0, flags, |
+ arraysize(flags)); |
+} |
+ |
+TEST(ImportExpressionErrors) { |
+ { |
+ // clang-format off |
+ const char* context_data[][2] = { |
+ {"", ""}, |
+ {"var ", ""}, |
+ {"let ", ""}, |
+ {"new ", ""}, |
+ {NULL, NULL} |
+ }; |
+ |
+ const char* data[] = { |
+ "import(", |
+ "import)", |
+ "import()", |
+ "import('x", |
+ "import('x']", |
+ "import['x')", |
+ "import = x", |
+ "import[", |
+ "import[]", |
+ "import]", |
+ "import[x]", |
+ "import{", |
+ "import{x", |
+ "import{x}", |
+ "import(x, y)", |
+ "import(...y)", |
+ "import(x,)", |
+ "import(,)", |
+ "import(,y)", |
+ "import(;)", |
+ "[import]", |
+ "{import}", |
+ "import+", |
+ "import = 1", |
+ "import.wat", |
+ NULL |
+ }; |
+ |
+ // clang-format on |
+ RunParserSyncTest(context_data, data, kError); |
+ // We ignore the error messages for the reason explained in the |
+ // ImportExpressionSuccess test. |
+ RunModuleParserSyncTest(context_data, data, kError, NULL, 0, NULL, 0, NULL, |
+ 0, true, true); |
+ static const ParserFlag flags[] = {kAllowHarmonyDynamicImport}; |
+ RunParserSyncTest(context_data, data, kError, NULL, 0, flags, |
+ arraysize(flags)); |
+ |
+ // We ignore test error messages because the error message from |
+ // the parser/preparser is different for the same data depending |
+ // on the context. For example, a top level "import{" is parsed |
+ // as an import declaration. The parser parses the import token |
+ // correctly and then shows an "Unexpected end of input" error |
+ // message because of the '{'. The preparser shows an "Unexpected |
+ // token {" because it's not a valid token in a CallExpression. |
+ RunModuleParserSyncTest(context_data, data, kError, NULL, 0, flags, |
+ arraysize(flags), NULL, 0, true, true); |
+ } |
+ |
+ { |
+ // clang-format off |
+ const char* context_data[][2] = { |
+ {"var ", ""}, |
+ {"let ", ""}, |
+ {NULL, NULL} |
+ }; |
+ |
+ const char* data[] = { |
+ "import('x')", |
+ NULL |
+ }; |
+ |
+ // clang-format on |
+ RunParserSyncTest(context_data, data, kError); |
+ RunModuleParserSyncTest(context_data, data, kError); |
+ |
+ static const ParserFlag flags[] = {kAllowHarmonyDynamicImport}; |
+ RunParserSyncTest(context_data, data, kError, NULL, 0, flags, |
+ arraysize(flags)); |
+ RunModuleParserSyncTest(context_data, data, kError, NULL, 0, flags, |
+ arraysize(flags)); |
+ } |
+} |
TEST(SuperCall) { |
const char* context_data[][2] = {{"", ""}, |