diff --git a/jerry-core/parser/js/js-parser-internal.h b/jerry-core/parser/js/js-parser-internal.h
index 09c50c69e..9e9202378 100644
--- a/jerry-core/parser/js/js-parser-internal.h
+++ b/jerry-core/parser/js/js-parser-internal.h
@@ -828,6 +828,7 @@ uint16_t scanner_decode_map_to (parser_scope_stack_t *stack_item_p);
uint16_t scanner_save_literal (parser_context_t *context_p, uint16_t ident_index);
bool scanner_literal_is_const_reg (parser_context_t *context_p, uint16_t literal_index);
bool scanner_literal_is_created (parser_context_t *context_p, uint16_t literal_index);
+bool scanner_literal_exists (parser_context_t *context_p, uint16_t literal_index);
#endif /* ENABLED (JERRY_ESNEXT) */
void scanner_scan_all (parser_context_t *context_p, const uint8_t *arg_list_p, const uint8_t *arg_list_end_p,
diff --git a/jerry-core/parser/js/js-parser-module.c b/jerry-core/parser/js/js-parser-module.c
index 861ae4d71..26cba3fa8 100644
--- a/jerry-core/parser/js/js-parser-module.c
+++ b/jerry-core/parser/js/js-parser-module.c
@@ -353,6 +353,15 @@ parser_module_create_module_node (parser_context_t *context_p) /**< parser conte
void
parser_module_parse_export_clause (parser_context_t *context_p) /**< parser context */
{
+ bool has_module_specifier = false;
+
+ if (context_p->source_p == context_p->next_scanner_info_p->source_p)
+ {
+ has_module_specifier = true;
+ JERRY_ASSERT (context_p->next_scanner_info_p->type == SCANNER_TYPE_EXPORT_MODULE_SPECIFIER);
+ scanner_release_next (context_p, sizeof (scanner_info_t));
+ }
+
JERRY_ASSERT (context_p->token.type == LEXER_LEFT_BRACE);
lexer_next_token (context_p);
@@ -377,6 +386,12 @@ parser_module_parse_export_clause (parser_context_t *context_p) /**< parser cont
lexer_construct_literal_object (context_p, &context_p->token.lit_location, LEXER_NEW_IDENT_LITERAL);
+ if (!has_module_specifier
+ && !scanner_literal_exists (context_p, context_p->lit_object.index))
+ {
+ parser_raise_error (context_p, PARSER_ERR_EXPORT_NOT_DEFINED);
+ }
+
uint16_t local_name_index = context_p->lit_object.index;
uint16_t export_name_index = PARSER_MAXIMUM_NUMBER_OF_LITERALS;
diff --git a/jerry-core/parser/js/js-parser-util.c b/jerry-core/parser/js/js-parser-util.c
index 1338b6587..de3639fb9 100644
--- a/jerry-core/parser/js/js-parser-util.c
+++ b/jerry-core/parser/js/js-parser-util.c
@@ -1418,6 +1418,10 @@ parser_error_to_string (parser_error_t error) /**< error code */
{
return "Duplicated imported binding name.";
}
+ case PARSER_ERR_EXPORT_NOT_DEFINED:
+ {
+ return "Export not defined in module.";
+ }
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
default:
diff --git a/jerry-core/parser/js/js-parser.h b/jerry-core/parser/js/js-parser.h
index 155a985b2..1febf70e9 100644
--- a/jerry-core/parser/js/js-parser.h
+++ b/jerry-core/parser/js/js-parser.h
@@ -179,6 +179,7 @@ typedef enum
PARSER_ERR_RIGHT_BRACE_COMMA_EXPECTED, /**< right brace or comma expected */
PARSER_ERR_DUPLICATED_EXPORT_IDENTIFIER, /**< duplicated export identifier name */
PARSER_ERR_DUPLICATED_IMPORT_BINDING, /**< duplicated import binding name */
+ PARSER_ERR_EXPORT_NOT_DEFINED, /**< export is not defined in module */
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
PARSER_ERR_NON_STRICT_ARG_DEFINITION /**< non-strict argument definition */
diff --git a/jerry-core/parser/js/js-scanner-util.c b/jerry-core/parser/js/js-scanner-util.c
index e28e1dfc7..0dd13274f 100644
--- a/jerry-core/parser/js/js-scanner-util.c
+++ b/jerry-core/parser/js/js-scanner-util.c
@@ -1764,7 +1764,8 @@ scanner_cleanup (parser_context_t *context_p) /**< context */
|| scanner_info_p->type == SCANNER_TYPE_CLASS_CONSTRUCTOR
|| scanner_info_p->type == SCANNER_TYPE_OBJECT_LITERAL_WITH_SUPER
|| scanner_info_p->type == SCANNER_TYPE_ERR_REDECLARED
- || scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION);
+ || scanner_info_p->type == SCANNER_TYPE_ERR_ASYNC_FUNCTION
+ || scanner_info_p->type == SCANNER_TYPE_EXPORT_MODULE_SPECIFIER);
#else /* !ENABLED (JERRY_ESNEXT) */
JERRY_ASSERT (scanner_info_p->type == SCANNER_TYPE_END_ARGUMENTS);
#endif /* ENABLED (JERRY_ESNEXT) */
@@ -2713,6 +2714,31 @@ scanner_literal_is_created (parser_context_t *context_p, /**< context */
return (scope_stack_p->map_to & PARSER_SCOPE_STACK_IS_LOCAL_CREATED) != 0;
} /* scanner_literal_is_created */
+/**
+ * Checks whether the literal exists.
+ *
+ * @return true if the literal exists, false otherwise
+ */
+bool
+scanner_literal_exists (parser_context_t *context_p, /**< context */
+ uint16_t literal_index) /**< literal index */
+{
+ JERRY_ASSERT (literal_index < PARSER_REGISTER_START);
+
+ parser_scope_stack_t *scope_stack_p = context_p->scope_stack_p + context_p->scope_stack_top;
+
+ while (scope_stack_p-- > context_p->scope_stack_p)
+ {
+ if (scope_stack_p->map_from != PARSER_SCOPE_STACK_FUNC
+ && scanner_decode_map_to (scope_stack_p) == literal_index)
+ {
+ return true;
+ }
+ }
+
+ return false;
+} /* scanner_literal_exists */
+
#endif /* ENABLED (JERRY_ESNEXT) */
/**
diff --git a/jerry-core/parser/js/js-scanner.c b/jerry-core/parser/js/js-scanner.c
index 414dad995..41887b687 100644
--- a/jerry-core/parser/js/js-scanner.c
+++ b/jerry-core/parser/js/js-scanner.c
@@ -1879,6 +1879,9 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
return SCAN_NEXT_TOKEN;
}
+ scanner_source_start_t source_start;
+ source_start.source_p = context_p->source_p;
+
if (context_p->token.type == LEXER_LEFT_BRACE)
{
lexer_next_token (context_p);
@@ -1924,6 +1927,9 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
return SCAN_KEEP_TOKEN;
}
+ scanner_info_t *info_p = scanner_insert_info (context_p, source_start.source_p, sizeof (scanner_info_t));
+ info_p->type = SCANNER_TYPE_EXPORT_MODULE_SPECIFIER;
+
lexer_next_token (context_p);
if (context_p->token.type != LEXER_LITERAL
@@ -3737,6 +3743,13 @@ scan_completed:
print_location = false;
break;
}
+ case SCANNER_TYPE_EXPORT_MODULE_SPECIFIER:
+ {
+ JERRY_DEBUG_MSG (" EXPORT_WITH_MODULE_SPECIFIER: source:%d\n",
+ (int) (info_p->source_p - source_start_p));
+ print_location = false;
+ break;
+ }
#endif /* ENABLED (JERRY_ESNEXT) */
}
diff --git a/jerry-core/parser/js/js-scanner.h b/jerry-core/parser/js/js-scanner.h
index 9608ba78f..57d070044 100644
--- a/jerry-core/parser/js/js-scanner.h
+++ b/jerry-core/parser/js/js-scanner.h
@@ -53,6 +53,7 @@ typedef enum
SCANNER_TYPE_ERR_REDECLARED, /**< syntax error: a variable is redeclared */
SCANNER_TYPE_ERR_ASYNC_FUNCTION, /**< an invalid async function follows */
SCANNER_TYPE_OBJECT_LITERAL_WITH_SUPER, /**< object literal with inner super reference */
+ SCANNER_TYPE_EXPORT_MODULE_SPECIFIER, /**< export with module specifier */
#endif /* ENABLED (JERRY_ESNEXT) */
} scanner_info_type_t;
diff --git a/tests/test262-es6-excludelist.xml b/tests/test262-es6-excludelist.xml
index f77fa1980..7d9bcc1ff 100644
--- a/tests/test262-es6-excludelist.xml
+++ b/tests/test262-es6-excludelist.xml
@@ -301,7 +301,6 @@
No longer a SyntaxError in ES11
No longer a SyntaxError in ES11
-
ES2018 change: next method must be cached
diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml
index da520a0b7..75f973793 100644
--- a/tests/test262-esnext-excludelist.xml
+++ b/tests/test262-esnext-excludelist.xml
@@ -742,8 +742,6 @@
-
-