@@ -2017,6 +2017,23 @@ void parser::parse_and_visit_switch(parse_visitor_base &v) {
20172017
20182018void parser::parse_and_visit_typescript_namespace (
20192019 parse_visitor_base &v, source_code_span namespace_keyword_span) {
2020+ this ->parse_and_visit_typescript_namespace_head (v, namespace_keyword_span);
2021+
2022+ if (this ->peek ().type != token_type::left_curly) {
2023+ this ->diag_reporter_ ->report (diag_missing_body_for_typescript_namespace{
2024+ .expected_body =
2025+ source_code_span::unit (this ->lexer_ .end_of_previous_token ()),
2026+ });
2027+ return ;
2028+ }
2029+
2030+ v.visit_enter_namespace_scope ();
2031+ this ->parse_and_visit_statement_block_no_scope (v);
2032+ v.visit_exit_namespace_scope ();
2033+ }
2034+
2035+ void parser::parse_and_visit_typescript_namespace_head (
2036+ parse_visitor_base &v, source_code_span namespace_keyword_span) {
20202037 if (this ->peek ().has_leading_newline ) {
20212038 this ->diag_reporter_ ->report (
20222039 diag_newline_not_allowed_after_namespace_keyword{
@@ -2043,6 +2060,14 @@ void parser::parse_and_visit_typescript_namespace(
20432060 QLJS_PARSER_UNIMPLEMENTED ();
20442061 break ;
20452062 }
2063+ }
2064+
2065+ void parser::parse_and_visit_typescript_declare_namespace (
2066+ parse_visitor_base &v, source_code_span declare_keyword_span) {
2067+ QLJS_ASSERT (this ->peek ().type == token_type::kw_namespace);
2068+ source_code_span namespace_keyword_span = this ->peek ().span ();
2069+ this ->skip ();
2070+ this ->parse_and_visit_typescript_namespace_head (v, namespace_keyword_span);
20462071
20472072 if (this ->peek ().type != token_type::left_curly) {
20482073 this ->diag_reporter_ ->report (diag_missing_body_for_typescript_namespace{
@@ -2051,9 +2076,62 @@ void parser::parse_and_visit_typescript_namespace(
20512076 });
20522077 return ;
20532078 }
2079+ source_code_span left_curly_span = this ->peek ().span ();
2080+ this ->skip ();
20542081
20552082 v.visit_enter_namespace_scope ();
2056- this ->parse_and_visit_statement_block_no_scope (v);
2083+ for (;;) {
2084+ switch (this ->peek ().type ) {
2085+ // TODO(strager): Deduplicate list with
2086+ // parse_and_visit_possible_declare_statement.
2087+ case token_type::kw_abstract:
2088+ case token_type::kw_async:
2089+ case token_type::kw_class:
2090+ case token_type::kw_const:
2091+ case token_type::kw_enum:
2092+ case token_type::kw_function:
2093+ case token_type::kw_let:
2094+ case token_type::kw_namespace:
2095+ case token_type::kw_var:
2096+ this ->parse_and_visit_declare_statement (v, declare_keyword_span);
2097+ break ;
2098+
2099+ case token_type::right_curly:
2100+ this ->skip ();
2101+ goto done;
2102+
2103+ case token_type::end_of_file:
2104+ this ->diag_reporter_ ->report (diag_unclosed_code_block{
2105+ .block_open = left_curly_span,
2106+ });
2107+ goto done;
2108+
2109+ case token_type::kw_declare: {
2110+ this ->diag_reporter_ ->report (
2111+ diag_declare_keyword_is_not_allowed_inside_declare_namespace{
2112+ .declare_keyword = this ->peek ().span (),
2113+ .declare_namespace_declare_keyword = declare_keyword_span,
2114+ });
2115+ bool parsed_statement = this ->parse_and_visit_statement (
2116+ v, parse_statement_type::any_statement_in_block);
2117+ QLJS_ASSERT (parsed_statement);
2118+ break ;
2119+ }
2120+
2121+ default : {
2122+ this ->diag_reporter_ ->report (
2123+ diag_declare_namespace_cannot_contain_statement{
2124+ .first_statement_token = this ->peek ().span (),
2125+ .declare_keyword = declare_keyword_span,
2126+ });
2127+ bool parsed_statement = this ->parse_and_visit_statement (
2128+ v, parse_statement_type::any_statement_in_block);
2129+ QLJS_ASSERT (parsed_statement);
2130+ break ;
2131+ }
2132+ }
2133+ }
2134+ done:
20572135 v.visit_exit_namespace_scope ();
20582136}
20592137
@@ -4480,6 +4558,7 @@ parser::parse_and_visit_possible_declare_statement(parse_visitor_base &v) {
44804558 case token_type::kw_type:
44814559 case token_type::kw_var:
44824560 case token_type::kw_function:
4561+ case token_type::kw_namespace:
44834562 this ->lexer_ .commit_transaction (std::move (transaction));
44844563 this ->parse_and_visit_declare_statement (v, declare_keyword_span);
44854564 return parse_possible_declare_result::parsed;
@@ -4680,6 +4759,11 @@ void parser::parse_and_visit_declare_statement(
46804759 break ;
46814760 }
46824761
4762+ // declare namespace ns {}
4763+ case token_type::kw_namespace:
4764+ this ->parse_and_visit_typescript_declare_namespace (v, declare_keyword_span);
4765+ break ;
4766+
46834767 // declare: // Label.
46844768 // declare();
46854769 case token_type::colon:
0 commit comments