Skip to content

Commit d5adaec

Browse files
committed
Refactor: make 'delete x' call visit_variable_delete_use
error_redundant_delete_statement_on_variable is handled by the parser. The logic needs to know some linter state, so I want to move the logic into the linter. Make this possible by having the parser call visit_variable_delete_use instead of visit_variable_use for 'delete x'. This makes 'delete' similar to 'typeof'. This commit should not change behavior.
1 parent 47ce368 commit d5adaec

13 files changed

+94
-21
lines changed

src/lint.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ void linter::visit_variable_assignment(identifier name) {
345345
}
346346
}
347347

348+
void linter::visit_variable_delete_use(identifier name) {
349+
this->visit_variable_use(name, used_variable_kind::use);
350+
}
351+
348352
void linter::visit_variable_export_use(identifier name) {
349353
this->visit_variable_use(name, used_variable_kind::_export);
350354
}

src/main.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ class debug_visitor {
302302
<< '\n';
303303
}
304304

305+
void visit_variable_delete_use(identifier name) {
306+
std::cerr << "variable delete use: " << out_string8(name.normalized_name())
307+
<< '\n';
308+
}
309+
305310
void visit_variable_export_use(identifier name) {
306311
std::cerr << "variable export use: " << out_string8(name.normalized_name())
307312
<< '\n';
@@ -410,6 +415,11 @@ class multi_visitor {
410415
this->visitor_2_->visit_variable_declaration(name, kind);
411416
}
412417

418+
void visit_variable_delete_use(identifier name) {
419+
this->visitor_1_->visit_variable_delete_use(name);
420+
this->visitor_2_->visit_variable_delete_use(name);
421+
}
422+
413423
void visit_variable_export_use(identifier name) {
414424
this->visitor_1_->visit_variable_export_use(name);
415425
this->visitor_2_->visit_variable_export_use(name);

src/parse.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,10 +236,13 @@ expression* parser::parse_primary_expression(precedence prec) {
236236
});
237237
}
238238
expression* ast =
239-
type == token_type::kw_typeof
240-
? this->make_expression<expression::_typeof>(child, operator_span)
241-
: this->make_expression<expression::unary_operator>(child,
242-
operator_span);
239+
type == token_type::kw_delete
240+
? this->make_expression<expression::_delete>(child, operator_span)
241+
: type == token_type::kw_typeof
242+
? this->make_expression<expression::_typeof>(child,
243+
operator_span)
244+
: this->make_expression<expression::unary_operator>(
245+
child, operator_span);
243246
if (type == token_type::kw_delete &&
244247
child->kind() == expression_kind::variable) {
245248
this->error_reporter_->report(
@@ -1264,6 +1267,7 @@ void parser::parse_arrow_function_expression_remainder(
12641267
break;
12651268

12661269
case expression_kind::_class:
1270+
case expression_kind::_delete:
12671271
case expression_kind::_invalid:
12681272
case expression_kind::_new:
12691273
case expression_kind::_template:

src/quick-lint-js/buffering-visitor.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ class buffering_visitor {
8383
case visit_kind::variable_assignment:
8484
target.visit_variable_assignment(v.name);
8585
break;
86+
case visit_kind::variable_delete_use:
87+
target.visit_variable_delete_use(v.name);
88+
break;
8689
case visit_kind::variable_export_use:
8790
target.visit_variable_export_use(v.name);
8891
break;
@@ -172,6 +175,10 @@ class buffering_visitor {
172175
this->visits_.emplace_back(visit_kind::variable_declaration, name, kind);
173176
}
174177

178+
void visit_variable_delete_use(identifier name) {
179+
this->visits_.emplace_back(visit_kind::variable_delete_use, name);
180+
}
181+
175182
void visit_variable_export_use(identifier name) {
176183
this->visits_.emplace_back(visit_kind::variable_export_use, name);
177184
}
@@ -203,6 +210,7 @@ class buffering_visitor {
203210
property_declaration_with_name,
204211
property_declaration_without_name,
205212
variable_assignment,
213+
variable_delete_use,
206214
variable_export_use,
207215
variable_typeof_use,
208216
variable_use,

src/quick-lint-js/expression.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class expression;
3636

3737
enum class expression_kind {
3838
_class,
39+
_delete,
3940
_invalid,
4041
_new,
4142
_template,
@@ -156,6 +157,7 @@ class expression {
156157
class expression_with_prefix_operator_base;
157158

158159
class _class;
160+
class _delete;
159161
class _invalid;
160162
class _new;
161163
class _template;
@@ -366,6 +368,17 @@ class expression::expression_with_prefix_operator_base : public expression {
366368
expression *child_;
367369
};
368370

371+
class expression::_delete final
372+
: public expression::expression_with_prefix_operator_base {
373+
public:
374+
static constexpr expression_kind kind = expression_kind::_delete;
375+
376+
explicit _delete(expression *child, source_code_span operator_span) noexcept
377+
: expression::expression_with_prefix_operator_base(kind, child,
378+
operator_span) {}
379+
};
380+
static_assert(expression_arena::is_allocatable<expression::_delete>);
381+
369382
class expression::_class : public expression {
370383
public:
371384
static constexpr expression_kind kind = expression_kind::_class;
@@ -1166,6 +1179,7 @@ inline auto expression::with_derived(Func &&func) {
11661179

11671180
switch (this->kind()) {
11681181
QLJS_EXPRESSION_CASE(_class)
1182+
QLJS_EXPRESSION_CASE(_delete)
11691183
QLJS_EXPRESSION_CASE(_invalid)
11701184
QLJS_EXPRESSION_CASE(_new)
11711185
QLJS_EXPRESSION_CASE(_template)

src/quick-lint-js/lint.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class linter {
8282
void visit_property_declaration(std::optional<identifier>);
8383
void visit_variable_declaration(identifier name, variable_kind kind);
8484
void visit_variable_assignment(identifier name);
85+
void visit_variable_delete_use(identifier name);
8586
void visit_variable_export_use(identifier name);
8687
void visit_variable_typeof_use(identifier name);
8788
void visit_variable_use(identifier name);

src/quick-lint-js/null-visitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class null_visitor {
2828
void visit_property_declaration(std::optional<identifier>) {}
2929
void visit_variable_assignment(identifier) {}
3030
void visit_variable_declaration(identifier, variable_kind) {}
31+
void visit_variable_delete_use(identifier) {}
3132
void visit_variable_export_use(identifier) {}
3233
void visit_variable_typeof_use(identifier) {}
3334
void visit_variable_use(identifier) {}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ concept parse_visitor = requires(Visitor v, identifier name,
5050
{v.visit_property_declaration(std::optional<identifier>(name))};
5151
{v.visit_variable_assignment(name)};
5252
{v.visit_variable_declaration(name, var_kind)};
53+
{v.visit_variable_delete_use(name)};
5354
{v.visit_variable_export_use(name)};
5455
{v.visit_variable_typeof_use(name)};
5556
{v.visit_variable_use(name)};

src/quick-lint-js/parse.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,6 +796,15 @@ class parser {
796796
}
797797
break;
798798
}
799+
case expression_kind::_delete: {
800+
expression *child = ast->child_0();
801+
if (child->kind() == expression_kind::variable) {
802+
v.visit_variable_delete_use(child->variable_identifier());
803+
} else {
804+
this->visit_expression(child, v, context);
805+
}
806+
break;
807+
}
799808
case expression_kind::await:
800809
case expression_kind::spread:
801810
case expression_kind::unary_operator:
@@ -3554,6 +3563,7 @@ class parser {
35543563
}
35553564

35563565
case expression_kind::_class:
3566+
case expression_kind::_delete:
35573567
case expression_kind::_new:
35583568
case expression_kind::_template:
35593569
case expression_kind::_typeof:

test/quick-lint-js/spy-visitor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ struct spy_visitor : public error_collector {
158158
};
159159
std::vector<visited_variable_declaration> variable_declarations;
160160

161+
void visit_variable_delete_use(identifier name) {
162+
this->variable_uses.emplace_back(
163+
visited_variable_use{string8(name.normalized_name())});
164+
this->visits.emplace_back("visit_variable_delete_use");
165+
}
166+
161167
void visit_variable_export_use(identifier name) {
162168
this->variable_uses.emplace_back(
163169
visited_variable_use{string8(name.normalized_name())});

0 commit comments

Comments
 (0)