Skip to content

Commit 4b1782a

Browse files
committed
feat(typescript): error on module import inside 'declare namespace'
1 parent 4535f78 commit 4b1782a

15 files changed

+220
-37
lines changed

po/de.po

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,15 @@ msgstr ""
316316
msgid "'declare' here"
317317
msgstr "Funktionsaufruf beginnt hier"
318318

319+
#: src/quick-lint-js/diag/diagnostic-types.h
320+
msgid "cannot import a module from inside a 'declare namespace'"
321+
msgstr ""
322+
323+
#: src/quick-lint-js/diag/diagnostic-types.h
324+
#, fuzzy
325+
msgid "'declare namespace' starts here"
326+
msgstr "Array beginnt hier"
327+
319328
#: src/quick-lint-js/diag/diagnostic-types.h
320329
#, fuzzy
321330
msgid "'declare {1}' cannot have initializer"
@@ -1424,11 +1433,6 @@ msgstr ""
14241433
msgid "move the 'extends' clause before 'implements' here"
14251434
msgstr ""
14261435

1427-
#: src/quick-lint-js/diag/diagnostic-types.h
1428-
#, fuzzy
1429-
msgid "cannot use 'declare' keyword with 'import'"
1430-
msgstr "Kann keine Variable namens 'let' deklarieren und exportieren"
1431-
14321436
#: src/quick-lint-js/diag/diagnostic-types.h
14331437
#, fuzzy
14341438
msgid "TypeScript import aliases are not allowed in JavaScript"
@@ -1916,6 +1920,11 @@ msgstr "Funktion '{0}' wird im Block-Scope vor ihrer Deklaration aufgerufen"
19161920
msgid "function declared here"
19171921
msgstr "Funktion wird hier deklariert"
19181922

1923+
#: src/quick-lint-js/diag/diagnostic-types.h
1924+
#, fuzzy
1925+
msgid "cannot use 'declare' keyword with 'import'"
1926+
msgstr "Kann keine Variable namens 'let' deklarieren und exportieren"
1927+
19191928
#: src/quick-lint-js/diag/diagnostic-types.h
19201929
#, fuzzy
19211930
msgid "TypeScript interface fields cannot be initalized"

po/[email protected]

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,15 @@ msgstr "TypeScript's 'interface' feature is not allowed in JavaScript code"
271271
msgid "'declare' here"
272272
msgstr "IIFE started here"
273273

274+
#: src/quick-lint-js/diag/diagnostic-types.h
275+
msgid "cannot import a module from inside a 'declare namespace'"
276+
msgstr ""
277+
278+
#: src/quick-lint-js/diag/diagnostic-types.h
279+
#, fuzzy
280+
msgid "'declare namespace' starts here"
281+
msgstr "you opened Pandora's Box here"
282+
274283
#: src/quick-lint-js/diag/diagnostic-types.h
275284
#, fuzzy
276285
msgid "'declare {1}' cannot have initializer"
@@ -1351,11 +1360,6 @@ msgstr ""
13511360
msgid "move the 'extends' clause before 'implements' here"
13521361
msgstr ""
13531362

1354-
#: src/quick-lint-js/diag/diagnostic-types.h
1355-
#, fuzzy
1356-
msgid "cannot use 'declare' keyword with 'import'"
1357-
msgstr "variables don't belong here"
1358-
13591363
#: src/quick-lint-js/diag/diagnostic-types.h
13601364
#, fuzzy
13611365
msgid "TypeScript import aliases are not allowed in JavaScript"
@@ -1792,6 +1796,11 @@ msgstr "this code freaks Safari out"
17921796
msgid "function declared here"
17931797
msgstr "Safari hates this"
17941798

1799+
#: src/quick-lint-js/diag/diagnostic-types.h
1800+
#, fuzzy
1801+
msgid "cannot use 'declare' keyword with 'import'"
1802+
msgstr "variables don't belong here"
1803+
17951804
#: src/quick-lint-js/diag/diagnostic-types.h
17961805
msgid "TypeScript interface fields cannot be initalized"
17971806
msgstr "why are you trying to initialize this field? it's an interface!"

po/fr_FR.po

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,15 @@ msgstr ""
324324
msgid "'declare' here"
325325
msgstr "appel de fonction débuté ici"
326326

327+
#: src/quick-lint-js/diag/diagnostic-types.h
328+
msgid "cannot import a module from inside a 'declare namespace'"
329+
msgstr ""
330+
331+
#: src/quick-lint-js/diag/diagnostic-types.h
332+
#, fuzzy
333+
msgid "'declare namespace' starts here"
334+
msgstr "tableau débuté ici"
335+
327336
#: src/quick-lint-js/diag/diagnostic-types.h
328337
#, fuzzy
329338
msgid "'declare {1}' cannot have initializer"
@@ -1440,12 +1449,6 @@ msgstr ""
14401449
msgid "move the 'extends' clause before 'implements' here"
14411450
msgstr ""
14421451

1443-
#: src/quick-lint-js/diag/diagnostic-types.h
1444-
#, fuzzy
1445-
msgid "cannot use 'declare' keyword with 'import'"
1446-
msgstr ""
1447-
"impossible de déclarer et d'exporter une variable avec 'export default'"
1448-
14491452
#: src/quick-lint-js/diag/diagnostic-types.h
14501453
#, fuzzy
14511454
msgid "TypeScript import aliases are not allowed in JavaScript"
@@ -1933,6 +1936,12 @@ msgstr "fonction appelée avant sa déclaration dans la portée de bloc : {0}"
19331936
msgid "function declared here"
19341937
msgstr "fonction déclarée ici"
19351938

1939+
#: src/quick-lint-js/diag/diagnostic-types.h
1940+
#, fuzzy
1941+
msgid "cannot use 'declare' keyword with 'import'"
1942+
msgstr ""
1943+
"impossible de déclarer et d'exporter une variable avec 'export default'"
1944+
19361945
#: src/quick-lint-js/diag/diagnostic-types.h
19371946
#, fuzzy
19381947
msgid "TypeScript interface fields cannot be initalized"

po/messages.pot

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ msgstr ""
259259
msgid "'declare' here"
260260
msgstr ""
261261

262+
#: src/quick-lint-js/diag/diagnostic-types.h
263+
msgid "cannot import a module from inside a 'declare namespace'"
264+
msgstr ""
265+
266+
#: src/quick-lint-js/diag/diagnostic-types.h
267+
msgid "'declare namespace' starts here"
268+
msgstr ""
269+
262270
#: src/quick-lint-js/diag/diagnostic-types.h
263271
msgid "'declare {1}' cannot have initializer"
264272
msgstr ""
@@ -1243,10 +1251,6 @@ msgstr ""
12431251
msgid "move the 'extends' clause before 'implements' here"
12441252
msgstr ""
12451253

1246-
#: src/quick-lint-js/diag/diagnostic-types.h
1247-
msgid "cannot use 'declare' keyword with 'import'"
1248-
msgstr ""
1249-
12501254
#: src/quick-lint-js/diag/diagnostic-types.h
12511255
msgid "TypeScript import aliases are not allowed in JavaScript"
12521256
msgstr ""
@@ -1650,6 +1654,10 @@ msgstr ""
16501654
msgid "function declared here"
16511655
msgstr ""
16521656

1657+
#: src/quick-lint-js/diag/diagnostic-types.h
1658+
msgid "cannot use 'declare' keyword with 'import'"
1659+
msgstr ""
1660+
16531661
#: src/quick-lint-js/diag/diagnostic-types.h
16541662
msgid "TypeScript interface fields cannot be initalized"
16551663
msgstr ""

po/pt_BR.po

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,15 @@ msgstr "interfaces não podem conter blocos estáticos"
272272
msgid "'declare' here"
273273
msgstr "'function' está aqui"
274274

275+
#: src/quick-lint-js/diag/diagnostic-types.h
276+
msgid "cannot import a module from inside a 'declare namespace'"
277+
msgstr ""
278+
279+
#: src/quick-lint-js/diag/diagnostic-types.h
280+
#, fuzzy
281+
msgid "'declare namespace' starts here"
282+
msgstr "array iniciou aqui"
283+
275284
#: src/quick-lint-js/diag/diagnostic-types.h
276285
#, fuzzy
277286
msgid "'declare {1}' cannot have initializer"
@@ -1289,11 +1298,6 @@ msgstr "'extends' precisa ficar antes do 'implements'"
12891298
msgid "move the 'extends' clause before 'implements' here"
12901299
msgstr "mova a cláusula 'extends' para antes do 'implements' aqui"
12911300

1292-
#: src/quick-lint-js/diag/diagnostic-types.h
1293-
#, fuzzy
1294-
msgid "cannot use 'declare' keyword with 'import'"
1295-
msgstr "não é possível declarar e exportar variável com 'export default'"
1296-
12971301
#: src/quick-lint-js/diag/diagnostic-types.h
12981302
msgid "TypeScript import aliases are not allowed in JavaScript"
12991303
msgstr "apelidos de importação do TypeScript não são permitidos em JavaScript"
@@ -1722,6 +1726,11 @@ msgstr "função chamada antes de ser declarada: {0}"
17221726
msgid "function declared here"
17231727
msgstr "função declarada aqui"
17241728

1729+
#: src/quick-lint-js/diag/diagnostic-types.h
1730+
#, fuzzy
1731+
msgid "cannot use 'declare' keyword with 'import'"
1732+
msgstr "não é possível declarar e exportar variável com 'export default'"
1733+
17251734
#: src/quick-lint-js/diag/diagnostic-types.h
17261735
msgid "TypeScript interface fields cannot be initalized"
17271736
msgstr "campos de interfaces do TypeScript não podem ser inicializados"

po/sv_SE.po

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,15 @@ msgstr "TypeScripts 'enum' är inte ännu implementerad av quick-lint-js"
287287
msgid "'declare' here"
288288
msgstr "funktionkallelse startar här"
289289

290+
#: src/quick-lint-js/diag/diagnostic-types.h
291+
msgid "cannot import a module from inside a 'declare namespace'"
292+
msgstr ""
293+
294+
#: src/quick-lint-js/diag/diagnostic-types.h
295+
#, fuzzy
296+
msgid "'declare namespace' starts here"
297+
msgstr "lista startar här"
298+
290299
#: src/quick-lint-js/diag/diagnostic-types.h
291300
#, fuzzy
292301
msgid "'declare {1}' cannot have initializer"
@@ -1344,11 +1353,6 @@ msgstr ""
13441353
msgid "move the 'extends' clause before 'implements' here"
13451354
msgstr ""
13461355

1347-
#: src/quick-lint-js/diag/diagnostic-types.h
1348-
#, fuzzy
1349-
msgid "cannot use 'declare' keyword with 'import'"
1350-
msgstr "kan inte deklarera och exportera variabel med 'export default'"
1351-
13521356
#: src/quick-lint-js/diag/diagnostic-types.h
13531357
#, fuzzy
13541358
msgid "TypeScript import aliases are not allowed in JavaScript"
@@ -1793,6 +1797,11 @@ msgstr "funktion kallad före deklaration i blockstycke: {0}"
17931797
msgid "function declared here"
17941798
msgstr "funktion deklarerad här"
17951799

1800+
#: src/quick-lint-js/diag/diagnostic-types.h
1801+
#, fuzzy
1802+
msgid "cannot use 'declare' keyword with 'import'"
1803+
msgstr "kan inte deklarera och exportera variabel med 'export default'"
1804+
17961805
#: src/quick-lint-js/diag/diagnostic-types.h
17971806
#, fuzzy
17981807
msgid "TypeScript interface fields cannot be initalized"

src/quick-lint-js/diag/diagnostic-types.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,19 @@
329329
first_statement_token) \
330330
MESSAGE(QLJS_TRANSLATABLE("'declare' here"), declare_keyword)) \
331331
\
332+
QLJS_DIAG_TYPE( \
333+
diag_declare_namespace_cannot_import_module, "E0362", \
334+
diagnostic_severity::error, \
335+
{ \
336+
source_code_span import_keyword; \
337+
source_code_span declare_keyword; \
338+
}, \
339+
MESSAGE(QLJS_TRANSLATABLE( \
340+
"cannot import a module from inside a 'declare namespace'"), \
341+
import_keyword) \
342+
MESSAGE(QLJS_TRANSLATABLE("'declare namespace' starts here"), \
343+
declare_keyword)) \
344+
\
332345
QLJS_DIAG_TYPE( \
333346
diag_declare_var_cannot_have_initializer, "E0351", \
334347
diagnostic_severity::error, \

src/quick-lint-js/fe/parse-statement.cpp

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3260,6 +3260,13 @@ void parser::parse_and_visit_if(parse_visitor_base &v) {
32603260
}
32613261

32623262
void parser::parse_and_visit_import(parse_visitor_base &v) {
3263+
this->parse_and_visit_import(
3264+
v, /*declare_namespace_declare_keyword=*/std::nullopt);
3265+
}
3266+
3267+
void parser::parse_and_visit_import(
3268+
parse_visitor_base &v,
3269+
std::optional<source_code_span> declare_namespace_declare_keyword) {
32633270
QLJS_ASSERT(this->peek().type == token_type::kw_import);
32643271
source_code_span import_span = this->peek().span();
32653272
this->skip();
@@ -3477,6 +3484,14 @@ void parser::parse_and_visit_import(parse_visitor_base &v) {
34773484
if (this->peek().type == token_type::left_paren &&
34783485
namespace_name.normalized_name() == u8"require"_sv) {
34793486
// import fs = require("fs");
3487+
if (declare_namespace_declare_keyword.has_value()) {
3488+
this->diag_reporter_->report(
3489+
diag_declare_namespace_cannot_import_module{
3490+
.import_keyword = import_span,
3491+
.declare_keyword = *declare_namespace_declare_keyword,
3492+
});
3493+
}
3494+
34803495
this->skip();
34813496
QLJS_PARSER_UNIMPLEMENTED_IF_NOT_TOKEN(token_type::string);
34823497
this->skip();
@@ -3522,6 +3537,12 @@ void parser::parse_and_visit_import(parse_visitor_base &v) {
35223537
switch (this->peek().type) {
35233538
// import fs from 'fs';
35243539
case token_type::string:
3540+
if (declare_namespace_declare_keyword.has_value()) {
3541+
this->diag_reporter_->report(diag_declare_namespace_cannot_import_module{
3542+
.import_keyword = import_span,
3543+
.declare_keyword = *declare_namespace_declare_keyword,
3544+
});
3545+
}
35253546
this->skip();
35263547
break;
35273548

@@ -4612,16 +4633,20 @@ parser::parse_and_visit_possible_declare_statement(parse_visitor_base &v) {
46124633
case token_type::kw_type:
46134634
case token_type::kw_var:
46144635
case token_type::kw_namespace:
4615-
parse_as_declare_statement:
46164636
this->lexer_.commit_transaction(std::move(transaction));
46174637
this->parse_and_visit_declare_statement(v, declare_keyword_span);
46184638
return parse_possible_declare_result::parsed;
46194639

4640+
// declare import fs from 'fs'; // Invalid.
4641+
// declare import ns = otherns; // Invalid.
46204642
case token_type::kw_import:
4643+
this->lexer_.commit_transaction(std::move(transaction));
46214644
this->diag_reporter_->report(diag_import_cannot_have_declare_keyword{
46224645
.declare_keyword = declare_keyword_span,
46234646
});
4624-
goto parse_as_declare_statement;
4647+
this->parse_and_visit_import(
4648+
v, /*declare_namespace_declare_keyword=*/std::nullopt);
4649+
return parse_possible_declare_result::parsed;
46254650

46264651
// declare: // Label.
46274652
// declare();
@@ -4826,8 +4851,12 @@ void parser::parse_and_visit_declare_statement(
48264851
break;
48274852

48284853
// declare namespace ns { import a = b; }
4854+
// declare namespace ns { import a from "b"; } // Invalid.
48294855
case token_type::kw_import:
4830-
this->parse_and_visit_import(v);
4856+
// NOTE(strager): 'declare import a from "b";' is handled by
4857+
// parse_and_visit_possible_declare_statement.
4858+
this->parse_and_visit_import(
4859+
v, /*declare_namespace_declare_keyword=*/declare_keyword_span);
48314860
break;
48324861

48334862
// declare: // Label.

src/quick-lint-js/fe/parse.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ class parser {
424424
void error_on_function_statement(statement_kind statement_kind);
425425

426426
void parse_and_visit_import(parse_visitor_base &v);
427+
void parse_and_visit_import(
428+
parse_visitor_base &v,
429+
std::optional<source_code_span> declare_namespace_declare_keyword);
427430
void parse_and_visit_name_space_import(parse_visitor_base &v);
428431
void parse_and_visit_named_exports_for_import(parse_visitor_base &v);
429432
void parse_and_visit_named_exports_for_typescript_type_only_import(

src/quick-lint-js/i18n/translation-table-generated.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ const translation_table translation_data = {
4848
{0, 0, 0, 0, 0, 38}, //
4949
{0, 0, 0, 0, 0, 24}, //
5050
{0, 0, 0, 0, 0, 65}, //
51+
{0, 0, 0, 0, 0, 32}, //
5152
{0, 0, 0, 0, 0, 38}, //
5253
{0, 0, 0, 0, 0, 27}, //
5354
{0, 0, 0, 0, 0, 15}, //
@@ -160,7 +161,8 @@ const translation_table translation_data = {
160161
{45, 26, 69, 51, 48, 38}, //
161162
{45, 35, 49, 51, 43, 35}, //
162163
{76, 25, 67, 54, 48, 43}, //
163-
{35, 37, 28, 33, 25, 20}, //
164+
{0, 0, 0, 0, 0, 20}, //
165+
{35, 37, 28, 33, 25, 57}, //
164166
{45, 67, 67, 54, 58, 43}, //
165167
{74, 45, 80, 74, 69, 63}, //
166168
{0, 0, 0, 67, 0, 53}, //
@@ -1759,6 +1761,7 @@ const translation_table translation_data = {
17591761
u8"'declare function' cannot have a body\0"
17601762
u8"'declare function' here\0"
17611763
u8"'declare namespace' cannot contain statements, only declarations\0"
1764+
u8"'declare namespace' starts here\0"
17621765
u8"'declare {1}' cannot have initializer\0"
17631766
u8"'declare {1}' started here\0"
17641767
u8"'declare' here\0"
@@ -1872,6 +1875,7 @@ const translation_table translation_data = {
18721875
u8"cannot export variable named 'let'\0"
18731876
u8"cannot export variable named keyword '{0}'\0"
18741877
u8"cannot import 'let'\0"
1878+
u8"cannot import a module from inside a 'declare namespace'\0"
18751879
u8"cannot import variable named keyword '{0}'\0"
18761880
u8"cannot reference private variables without object; use 'this.'\0"
18771881
u8"cannot update variable with '{0}' while declaring it\0"

0 commit comments

Comments
 (0)