Skip to content

Commit f5b2757

Browse files
committed
fix(typescript): fix false positive with import and var with same name
The following is valid TypeScript if the imported x is a type-only declaration (e.g. an interface): import {x} from './mod'; x = 42; var x; quick-lint-js incorrectly emits a warning for this code. Fix it. Unfortunately, this fix introduces another bug where we do not diagnose the following code: import {x} from './mod'; x = 42; I prefer the new bug because it does not reject valid code.
1 parent 7c0792a commit f5b2757

File tree

4 files changed

+36
-5
lines changed

4 files changed

+36
-5
lines changed

docs/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66
quick-lint-js' version numbers are arbitrary. quick-lint-js does *not* adhere to
77
Semantic Versioning.
88

9+
## Unreleased
10+
11+
### Fixed
12+
13+
* TypeScript support (still experimental):
14+
* Assigning to a variable with the same name as an `import`ed type no longer
15+
falsely reports [E0185][] ("assignment to imported variable").
16+
917
## 2.19.0 (2023-12-30)
1018

1119
[Downloads](https://c.quick-lint-js.com/releases/2.19.0/)

src/quick-lint-js/fe/variable-analyzer.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -876,11 +876,15 @@ void Variable_Analyzer::report_error_if_assignment_is_illegal(
876876
QLJS_WARNING_PUSH
877877
QLJS_WARNING_IGNORE_GCC("-Wnull-dereference")
878878

879-
this->diag_reporter_->report(Diag_Assignment_To_Imported_Variable{
880-
.declaration = declaration->span(),
881-
.assignment = assignment.span(),
882-
.var_kind = kind,
883-
});
879+
// HACK(#1141): Avoid false positives in TypeScript by disabling this
880+
// diagnostic for now.
881+
if (!this->options_.import_variable_can_be_runtime_or_type) {
882+
this->diag_reporter_->report(Diag_Assignment_To_Imported_Variable{
883+
.declaration = declaration->span(),
884+
.assignment = assignment.span(),
885+
.var_kind = kind,
886+
});
887+
}
884888

885889
QLJS_WARNING_POP
886890
break;

test/test-variable-analyzer-module.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ TEST(Test_Variable_Analyzer_Module, assign_to_immutable_imported_variable) {
3636
u8"^ .assignment"_diag
3737
u8"{.var_kind=Variable_Kind::_import}"_diag,
3838
javascript_analyze_options, default_globals);
39+
40+
// TODO(#1141): Report Diag_Assignment_To_Imported_Variable in TypeScript.
3941
}
4042

4143
TEST(Test_Variable_Analyzer_Module, export_use_after_declaration_is_okay) {

test/test-variable-analyzer-multiple-declarations.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,23 @@ TEST(Test_Variable_Analyzer_Multiple_Declarations,
290290
}
291291
}
292292

293+
TEST(
294+
Test_Variable_Analyzer_Multiple_Declarations,
295+
using_implicit_type_import_and_runtime_variable_with_same_name_is_not_an_error) {
296+
test_parse_and_analyze(u8"import x from ''; let x; x;"_sv, no_diags,
297+
typescript_analyze_options, default_globals);
298+
test_parse_and_analyze(u8"let x; import x from ''; x;"_sv, no_diags,
299+
typescript_analyze_options, default_globals);
300+
test_parse_and_analyze(u8"import x from ''; x; var x;"_sv, no_diags,
301+
typescript_analyze_options, default_globals);
302+
test_parse_and_analyze(u8"import x from ''; let x; x = null;"_sv, no_diags,
303+
typescript_analyze_options, default_globals);
304+
test_parse_and_analyze(u8"import x from ''; let x; x = null;"_sv, no_diags,
305+
typescript_analyze_options, default_globals);
306+
test_parse_and_analyze(u8"import x from ''; x = null; var x;"_sv, no_diags,
307+
typescript_analyze_options, default_globals);
308+
}
309+
293310
TEST(Test_Variable_Analyzer_Multiple_Declarations,
294311
typescript_import_does_not_conflict_with_type_only_variables) {
295312
for (String8_View other_thing : {

0 commit comments

Comments
 (0)