@@ -828,6 +828,12 @@ void parser::parse_end_of_expression_statement() {
828828}
829829
830830void parser::parse_and_visit_export (parse_visitor_base &v) {
831+ this ->parse_and_visit_export (v, /* declare_keyword_span=*/ std::nullopt );
832+ }
833+
834+ void parser::parse_and_visit_export (
835+ parse_visitor_base &v,
836+ std::optional<source_code_span> declare_namespace_declare_keyword) {
831837 QLJS_ASSERT (this ->peek ().type == token_type::kw_export);
832838 source_code_span export_token_span = this ->peek ().span ();
833839 this ->skip ();
@@ -837,6 +843,12 @@ void parser::parse_and_visit_export(parse_visitor_base &v) {
837843 switch (this ->peek ().type ) {
838844 // export default class C {}
839845 case token_type::kw_default:
846+ if (declare_namespace_declare_keyword.has_value ()) {
847+ this ->diag_reporter_ ->report (diag_declare_namespace_cannot_export_default{
848+ .default_keyword = this ->peek ().span (),
849+ .declare_keyword = *declare_namespace_declare_keyword,
850+ });
851+ }
840852 this ->skip ();
841853 switch (this ->peek ().type ) {
842854 // export default async function f() {}
@@ -954,6 +966,12 @@ void parser::parse_and_visit_export(parse_visitor_base &v) {
954966 }
955967 }
956968 QLJS_PARSER_UNIMPLEMENTED_IF_NOT_TOKEN (token_type::kw_from);
969+ if (declare_namespace_declare_keyword.has_value ()) {
970+ this ->diag_reporter_ ->report (diag_declare_namespace_cannot_import_module{
971+ .importing_keyword = this ->peek ().span (),
972+ .declare_keyword = *declare_namespace_declare_keyword,
973+ });
974+ }
957975 this ->skip ();
958976 QLJS_PARSER_UNIMPLEMENTED_IF_NOT_TOKEN (token_type::string);
959977 this ->skip ();
@@ -974,6 +992,13 @@ void parser::parse_and_visit_export(parse_visitor_base &v) {
974992 /* out_exported_bad_tokens=*/ &exported_bad_tokens);
975993 if (this ->peek ().type == token_type::kw_from) {
976994 // export {a, b, c} from "module";
995+ if (declare_namespace_declare_keyword.has_value ()) {
996+ this ->diag_reporter_ ->report (
997+ diag_declare_namespace_cannot_import_module{
998+ .importing_keyword = this ->peek ().span (),
999+ .declare_keyword = *declare_namespace_declare_keyword,
1000+ });
1001+ }
9771002 this ->skip ();
9781003 QLJS_PARSER_UNIMPLEMENTED_IF_NOT_TOKEN (token_type::string);
9791004 this ->skip ();
@@ -1008,23 +1033,34 @@ void parser::parse_and_visit_export(parse_visitor_base &v) {
10081033 }
10091034
10101035 // export async function f() {}
1011- case token_type::kw_async: {
1012- const char8 *async_token_begin = this ->peek ().begin ;
1013- this ->skip ();
1014- QLJS_PARSER_UNIMPLEMENTED_IF_NOT_TOKEN (token_type::kw_function);
1015- this ->parse_and_visit_function_declaration (
1016- v, function_attributes::async,
1017- /* begin=*/ async_token_begin,
1018- /* require_name=*/ name_requirement::required_for_export);
1036+ case token_type::kw_async:
1037+ if (declare_namespace_declare_keyword.has_value ()) {
1038+ // declare namespace ns { export async function f(); }
1039+ this ->parse_and_visit_declare_statement (
1040+ v, *declare_namespace_declare_keyword);
1041+ } else {
1042+ const char8 *async_token_begin = this ->peek ().begin ;
1043+ this ->skip ();
1044+ QLJS_PARSER_UNIMPLEMENTED_IF_NOT_TOKEN (token_type::kw_function);
1045+ this ->parse_and_visit_function_declaration (
1046+ v, function_attributes::async,
1047+ /* begin=*/ async_token_begin,
1048+ /* require_name=*/ name_requirement::required_for_export);
1049+ }
10191050 break ;
1020- }
10211051
10221052 // export function f() {}
10231053 case token_type::kw_function:
1024- this ->parse_and_visit_function_declaration (
1025- v, function_attributes::normal,
1026- /* begin=*/ this ->peek ().begin ,
1027- /* require_name=*/ name_requirement::required_for_export);
1054+ if (declare_namespace_declare_keyword.has_value ()) {
1055+ // declare namespace ns { export function f(); }
1056+ this ->parse_and_visit_declare_statement (
1057+ v, *declare_namespace_declare_keyword);
1058+ } else {
1059+ this ->parse_and_visit_function_declaration (
1060+ v, function_attributes::normal,
1061+ /* begin=*/ this ->peek ().begin ,
1062+ /* require_name=*/ name_requirement::required_for_export);
1063+ }
10281064 break ;
10291065
10301066 // export class C {}
@@ -1033,6 +1069,7 @@ void parser::parse_and_visit_export(parse_visitor_base &v) {
10331069 v, parse_class_options{
10341070 .require_name = name_requirement::required_for_export,
10351071 .abstract_keyword_span = std::nullopt ,
1072+ .declare_keyword_span = declare_namespace_declare_keyword,
10361073 });
10371074 break ;
10381075
@@ -1051,6 +1088,7 @@ void parser::parse_and_visit_export(parse_visitor_base &v) {
10511088 v, parse_class_options{
10521089 .require_name = name_requirement::required_for_export,
10531090 .abstract_keyword_span = abstract_keyword,
1091+ .declare_keyword_span = declare_namespace_declare_keyword,
10541092 });
10551093 break ;
10561094 }
@@ -1060,7 +1098,14 @@ void parser::parse_and_visit_export(parse_visitor_base &v) {
10601098 case token_type::kw_const:
10611099 case token_type::kw_let:
10621100 case token_type::kw_var:
1063- this ->parse_and_visit_variable_declaration_statement (v);
1101+ if (declare_namespace_declare_keyword.has_value ()) {
1102+ // declare namespace ns { export let x; }
1103+ // declare namespace ns { export const enum E {} }
1104+ this ->parse_and_visit_declare_statement (
1105+ v, *declare_namespace_declare_keyword);
1106+ } else {
1107+ this ->parse_and_visit_variable_declaration_statement (v);
1108+ }
10641109 break ;
10651110
10661111 // export interface I {} // TypeScript only.
@@ -1109,17 +1154,27 @@ void parser::parse_and_visit_export(parse_visitor_base &v) {
11091154 // export namespace ns {} // TypeScript only.
11101155 case token_type::kw_module:
11111156 case token_type::kw_namespace: {
1112- source_code_span namespace_keyword = this ->peek ().span ();
1113- this ->skip ();
1114- this ->parse_and_visit_typescript_namespace (
1115- v,
1116- /* export_keyword_span=*/ export_token_span, namespace_keyword);
1157+ if (declare_namespace_declare_keyword.has_value ()) {
1158+ // declare namespace ns { export namespace subns {} }
1159+ this ->parse_and_visit_typescript_declare_namespace (
1160+ v, *declare_namespace_declare_keyword);
1161+ } else {
1162+ // export namespace ns {}
1163+ source_code_span namespace_keyword = this ->peek ().span ();
1164+ this ->skip ();
1165+ this ->parse_and_visit_typescript_namespace (
1166+ v,
1167+ /* export_keyword_span=*/ export_token_span, namespace_keyword);
1168+ }
11171169 break ;
11181170 }
11191171
11201172 // export enum E {} // TypeScript only.
11211173 case token_type::kw_enum:
1122- this ->parse_and_visit_typescript_enum (v, enum_kind::normal);
1174+ this ->parse_and_visit_typescript_enum (
1175+ v, declare_namespace_declare_keyword.has_value ()
1176+ ? enum_kind::declare_enum
1177+ : enum_kind::normal);
11231178 break ;
11241179
11251180 // export stuff; // Invalid.
@@ -2144,6 +2199,10 @@ void parser::parse_and_visit_typescript_declare_namespace(
21442199 this ->parse_and_visit_declare_statement (v, declare_keyword_span);
21452200 break ;
21462201
2202+ case token_type::kw_export:
2203+ this ->parse_and_visit_export (v, declare_keyword_span);
2204+ break ;
2205+
21472206 case token_type::right_curly:
21482207 this ->skip ();
21492208 goto done;
@@ -3487,7 +3546,7 @@ void parser::parse_and_visit_import(
34873546 if (declare_namespace_declare_keyword.has_value ()) {
34883547 this ->diag_reporter_ ->report (
34893548 diag_declare_namespace_cannot_import_module{
3490- .import_keyword = import_span,
3549+ .importing_keyword = import_span,
34913550 .declare_keyword = *declare_namespace_declare_keyword,
34923551 });
34933552 }
@@ -3539,7 +3598,7 @@ void parser::parse_and_visit_import(
35393598 case token_type::string:
35403599 if (declare_namespace_declare_keyword.has_value ()) {
35413600 this ->diag_reporter_ ->report (diag_declare_namespace_cannot_import_module{
3542- .import_keyword = import_span,
3601+ .importing_keyword = import_span,
35433602 .declare_keyword = *declare_namespace_declare_keyword,
35443603 });
35453604 }
0 commit comments