Skip to content

Commit 7e66ff6

Browse files
committed
Refactor error list out of configuration class
Each configuration object stores a buffering_error_reporter of errors encountered while parsing the config JSON. I think the configuration class is the wrong place for this. Move the error list into the configuration_loader class, storing it in loaded_config_file. This commit should not change behavior.
1 parent c19299c commit 7e66ff6

File tree

7 files changed

+97
-124
lines changed

7 files changed

+97
-124
lines changed

src/configuration-loader.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ configuration_loader::load_config_file(const char* config_path) {
127127
loaded_config_file* config_file = &config_it->second;
128128
config_file->config_path = &config_it->first;
129129
config_file->file_content = std::move(*config_json);
130-
config_file->config.load_from_json(&config_file->file_content);
130+
config_file->config.load_from_json(&config_file->file_content,
131+
&config_file->errors);
131132
return config_file;
132133
}
133134

@@ -179,7 +180,8 @@ configuration_loader::find_and_load_config_file_in_directory_and_ancestors(
179180
loaded_config_file* config_file = &config_it->second;
180181
config_file->config_path = &config_it->first;
181182
config_file->file_content = std::move(found->file_content);
182-
config_file->config.load_from_json(&config_file->file_content);
183+
config_file->config.load_from_json(&config_file->file_content,
184+
&config_file->errors);
183185
return config_file;
184186
}
185187

@@ -359,7 +361,9 @@ std::vector<configuration_change> configuration_loader::refresh() {
359361
loaded_config.config_path = &config_it->first;
360362
loaded_config.file_content = std::move(*latest_json);
361363
loaded_config.config.reset();
362-
loaded_config.config.load_from_json(&loaded_config.file_content);
364+
loaded_config.errors.clear();
365+
loaded_config.config.load_from_json(&loaded_config.file_content,
366+
&loaded_config.errors);
363367
config_file = &loaded_config;
364368
} else {
365369
config_file = &loaded_config_it->second;
@@ -426,7 +430,9 @@ std::vector<configuration_change> configuration_loader::refresh() {
426430
loaded_config.config_path = &config_it->first;
427431
loaded_config.file_content = std::move(latest->file_content);
428432
loaded_config.config.reset();
429-
loaded_config.config.load_from_json(&loaded_config.file_content);
433+
loaded_config.errors.clear();
434+
loaded_config.config.load_from_json(&loaded_config.file_content,
435+
&loaded_config.errors);
430436
config_file = &loaded_config;
431437
} else {
432438
config_file = &loaded_config_it->second;
@@ -462,7 +468,9 @@ std::vector<configuration_change> configuration_loader::refresh() {
462468
QLJS_ASSERT(*loaded_config.config_path == config_path);
463469
loaded_config.file_content = std::move(*config_json);
464470
loaded_config.config.reset();
465-
loaded_config.config.load_from_json(&loaded_config.file_content);
471+
loaded_config.errors.clear();
472+
loaded_config.config.load_from_json(&loaded_config.file_content,
473+
&loaded_config.errors);
466474

467475
for (const watched_config_path& watch : this->watched_config_paths_) {
468476
if (watch.actual_config_path == config_path) {

src/configuration.cpp

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <algorithm>
55
#include <quick-lint-js/char8.h>
66
#include <quick-lint-js/configuration.h>
7+
#include <quick-lint-js/error.h>
78
#include <quick-lint-js/global-variables.h>
89
#include <quick-lint-js/lint.h>
910
#include <quick-lint-js/narrow-cast.h>
@@ -175,7 +176,8 @@ void configuration::remove_global_variable(string8_view name) {
175176
this->globals_to_remove_.emplace_back(name);
176177
}
177178

178-
void configuration::load_from_json(padded_string_view json) {
179+
void configuration::load_from_json(padded_string_view json,
180+
error_reporter* reporter) {
179181
::simdjson::ondemand::parser json_parser;
180182
::simdjson::ondemand::document document;
181183
::simdjson::error_code parse_error =
@@ -185,15 +187,15 @@ void configuration::load_from_json(padded_string_view json) {
185187
narrow_cast<std::size_t>(json.padded_size()))
186188
.get(document);
187189
if (parse_error != ::simdjson::error_code::SUCCESS) {
188-
this->report_json_error(json);
190+
this->report_json_error(json, reporter);
189191
return;
190192
}
191193

192194
::simdjson::ondemand::value global_groups_value;
193195
switch (document["global-groups"].get(global_groups_value)) {
194196
case ::simdjson::error_code::SUCCESS:
195-
if (!this->load_global_groups_from_json(global_groups_value)) {
196-
this->report_json_error(json);
197+
if (!this->load_global_groups_from_json(global_groups_value, reporter)) {
198+
this->report_json_error(json, reporter);
197199
return;
198200
}
199201
break;
@@ -202,16 +204,16 @@ void configuration::load_from_json(padded_string_view json) {
202204
break;
203205

204206
default:
205-
this->report_json_error(json);
207+
this->report_json_error(json, reporter);
206208
return;
207209
}
208210

209211
auto globals = document["globals"];
210212
::simdjson::ondemand::object globals_value;
211213
switch (globals.get(globals_value)) {
212214
case ::simdjson::error_code::SUCCESS:
213-
if (!this->load_globals_from_json(globals_value)) {
214-
this->report_json_error(json);
215+
if (!this->load_globals_from_json(globals_value, reporter)) {
216+
this->report_json_error(json, reporter);
215217
return;
216218
}
217219
break;
@@ -222,11 +224,11 @@ void configuration::load_from_json(padded_string_view json) {
222224
::simdjson::ondemand::value v;
223225
if (globals.get(v) == ::simdjson::SUCCESS &&
224226
v.type().error() == ::simdjson::SUCCESS) {
225-
this->errors_.report(error_config_globals_type_mismatch{
227+
reporter->report(error_config_globals_type_mismatch{
226228
.value = span_of_json_value(v),
227229
});
228230
} else {
229-
this->report_json_error(json);
231+
this->report_json_error(json, reporter);
230232
return;
231233
}
232234
break;
@@ -236,36 +238,23 @@ void configuration::load_from_json(padded_string_view json) {
236238
break;
237239

238240
default:
239-
this->report_json_error(json);
241+
this->report_json_error(json, reporter);
240242
return;
241243
}
242244
}
243245

244-
void configuration::report_errors(error_reporter* reporter) {
245-
this->errors_.copy_into(reporter);
246-
this->errors_were_reported_ = true;
247-
}
248-
249-
bool configuration::have_errors() const noexcept {
250-
return !this->errors_.empty();
251-
}
252-
253-
bool configuration::errors_were_reported() const noexcept {
254-
return this->errors_were_reported_;
255-
}
256-
257246
void configuration::reset() {
258247
// TODO(strager): Make this more efficient by avoiding reallocations.
259248
this->globals_ = global_declared_variable_set();
260249
this->globals_to_remove_.clear();
261250
this->add_global_group_node_js_ = true;
262251
this->add_global_group_ecmascript_ = true;
263252
this->string_allocator_.memory_resource()->release();
264-
this->errors_.clear();
265253
}
266254

267255
bool configuration::load_global_groups_from_json(
268-
::simdjson::ondemand::value& global_groups_value) {
256+
::simdjson::ondemand::value& global_groups_value,
257+
error_reporter* reporter) {
269258
::simdjson::fallback::ondemand::json_type global_groups_value_type;
270259
if (global_groups_value.type().get(global_groups_value_type) !=
271260
::simdjson::SUCCESS) {
@@ -314,7 +303,7 @@ bool configuration::load_global_groups_from_json(
314303
if (global_group_value.type().error() != ::simdjson::SUCCESS) {
315304
return false;
316305
}
317-
this->errors_.report(error_config_global_groups_group_type_mismatch{
306+
reporter->report(error_config_global_groups_group_type_mismatch{
318307
.group = span_of_json_value(global_group_value),
319308
});
320309
break;
@@ -330,7 +319,7 @@ bool configuration::load_global_groups_from_json(
330319
case ::simdjson::fallback::ondemand::json_type::number:
331320
case ::simdjson::fallback::ondemand::json_type::object:
332321
case ::simdjson::fallback::ondemand::json_type::string:
333-
this->errors_.report(error_config_global_groups_type_mismatch{
322+
reporter->report(error_config_global_groups_type_mismatch{
334323
.value = span_of_json_value(global_groups_value),
335324
});
336325
break;
@@ -339,7 +328,7 @@ bool configuration::load_global_groups_from_json(
339328
}
340329

341330
bool configuration::load_globals_from_json(
342-
::simdjson::ondemand::object& globals_value) {
331+
::simdjson::ondemand::object& globals_value, error_reporter* reporter) {
343332
for (simdjson::simdjson_result<::simdjson::fallback::ondemand::field>
344333
global_field : globals_value) {
345334
std::string_view key;
@@ -379,20 +368,22 @@ bool configuration::load_globals_from_json(
379368
global_declared_variable* var = add_global_variable(global_name);
380369
if (!this->get_bool_or_default<
381370
error_config_globals_descriptor_shadowable_type_mismatch>(
382-
descriptor_object["shadowable"], &var->is_shadowable, true)) {
371+
descriptor_object["shadowable"], &var->is_shadowable, true,
372+
reporter)) {
383373
return false;
384374
}
385375
if (!this->get_bool_or_default<
386376
error_config_globals_descriptor_writable_type_mismatch>(
387-
descriptor_object["writable"], &var->is_writable, true)) {
377+
descriptor_object["writable"], &var->is_writable, true,
378+
reporter)) {
388379
return false;
389380
}
390381

391382
break;
392383
}
393384

394385
default:
395-
this->errors_.report(error_config_globals_descriptor_type_mismatch{
386+
reporter->report(error_config_globals_descriptor_type_mismatch{
396387
.descriptor = span_of_json_value(descriptor),
397388
});
398389
break;
@@ -418,7 +409,7 @@ bool configuration::should_remove_global_variable(string8_view name) {
418409
template <class Error>
419410
bool configuration::get_bool_or_default(
420411
::simdjson::simdjson_result<::simdjson::ondemand::value>&& value, bool* out,
421-
bool default_value) {
412+
bool default_value, error_reporter* reporter) {
422413
::simdjson::fallback::ondemand::value v;
423414
::simdjson::error_code error = value.get(v);
424415
switch (error) {
@@ -428,7 +419,7 @@ bool configuration::get_bool_or_default(
428419
return false;
429420
}
430421
if (type != ::simdjson::fallback::ondemand::json_type::boolean) {
431-
this->errors_.report(Error{span_of_json_value(v)});
422+
reporter->report(Error{span_of_json_value(v)});
432423
*out = default_value;
433424
return true;
434425
}
@@ -447,11 +438,12 @@ bool configuration::get_bool_or_default(
447438
}
448439
}
449440

450-
void configuration::report_json_error(padded_string_view json) {
441+
void configuration::report_json_error(padded_string_view json,
442+
error_reporter* reporter) {
451443
// TODO(strager): Produce better error messages. simdjson provides no location
452444
// information for errors:
453445
// https://github.com/simdjson/simdjson/issues/237
454-
this->errors_.report(error_config_json_syntax_error{
446+
reporter->report(error_config_json_syntax_error{
455447
.where = source_code_span(json.data(), json.data()),
456448
});
457449
}

src/lsp-server.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ void linting_lsp_server_handler<Linter>::
302302
if (config_file.ok()) {
303303
if (*config_file) {
304304
doc.config = &(*config_file)->config;
305-
if (doc.config->have_errors()) {
305+
if (!(*config_file)->errors.empty()) {
306306
byte_buffer& message_json = notification_jsons.emplace_back();
307307
this->write_configuration_errors_notification(
308308
document_path, *config_file, message_json);
@@ -424,7 +424,7 @@ void linting_lsp_server_handler<Linter>::
424424
notification_json.append_copy(u8R"--(,"diagnostics":)--");
425425
lsp_error_reporter error_reporter(notification_json,
426426
&config_file->file_content);
427-
config_file->config.report_errors(&error_reporter);
427+
config_file->errors.copy_into(&error_reporter);
428428
error_reporter.finish();
429429

430430
notification_json.append_copy(u8R"--(},"jsonrpc":"2.0"})--");

src/main.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,15 +192,16 @@ void handle_options(quick_lint_js::options o) {
192192
std::exit(1);
193193
}
194194
loaded_config_file *config_file = *config_result;
195-
if (config_file && !config_file->config.errors_were_reported()) {
195+
if (config_file && !config_file->config.errors_were_reported) {
196196
reporter.set_source(&config_file->file_content,
197197
file_to_lint{
198198
.path = config_file->config_path->c_str(),
199199
.config_file = nullptr,
200200
.is_stdin = false,
201201
.vim_bufnr = std::nullopt,
202202
});
203-
config_file->config.report_errors(reporter.get());
203+
config_file->errors.copy_into(reporter.get());
204+
config_file->config.errors_were_reported = true;
204205
}
205206
}
206207

src/quick-lint-js/configuration-loader.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define QUICK_LINT_JS_CONFIGURATION_LOADER_H
66

77
#include <optional>
8+
#include <quick-lint-js/buffering-error-reporter.h>
89
#include <quick-lint-js/configuration.h>
910
#include <quick-lint-js/file-canonical.h>
1011
#include <quick-lint-js/file.h>
@@ -44,6 +45,9 @@ struct loaded_config_file {
4445
// The content of the quick-lint-js.config file.
4546
padded_string file_content;
4647

48+
// Errors discovered while parsing file_content.
49+
buffering_error_reporter errors;
50+
4751
// The path to the quick-lint-js.config file. Never nullptr.
4852
const canonical_path* config_path;
4953
};

src/quick-lint-js/configuration.h

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#define QUICK_LINT_JS_CONFIGURATION_H
66

77
#include <optional>
8-
#include <quick-lint-js/buffering-error-reporter.h>
98
#include <quick-lint-js/char8.h>
109
#include <quick-lint-js/file-canonical.h>
1110
#include <quick-lint-js/lint.h>
@@ -27,36 +26,35 @@ class configuration {
2726
global_declared_variable* add_global_variable(string8_view name);
2827
void remove_global_variable(string8_view name);
2928

30-
void load_from_json(padded_string_view);
31-
32-
void report_errors(error_reporter*);
33-
bool have_errors() const noexcept;
34-
bool errors_were_reported() const noexcept;
29+
void load_from_json(padded_string_view, error_reporter*);
3530

3631
void reset();
3732

33+
// TODO(strager): Move this out of the configuration class. It's only used by
34+
// the CLI.
35+
bool errors_were_reported = false;
36+
3837
private:
39-
bool load_global_groups_from_json(simdjson::ondemand::value&);
40-
bool load_globals_from_json(simdjson::ondemand::object&);
38+
bool load_global_groups_from_json(simdjson::ondemand::value&,
39+
error_reporter*);
40+
bool load_globals_from_json(simdjson::ondemand::object&, error_reporter*);
4141

4242
bool should_remove_global_variable(string8_view name);
4343

4444
// Returns false on parse error, and true otherwise.
4545
template <class Error>
4646
bool get_bool_or_default(
4747
::simdjson::simdjson_result<::simdjson::ondemand::value>&& value,
48-
bool* out, bool default_value);
48+
bool* out, bool default_value, error_reporter*);
4949

50-
void report_json_error(padded_string_view json);
50+
void report_json_error(padded_string_view json, error_reporter*);
5151

5252
global_declared_variable_set globals_;
5353
std::vector<string8> globals_to_remove_;
5454
bool add_global_group_browser_ = true;
5555
bool add_global_group_node_js_ = true;
5656
bool add_global_group_ecmascript_ = true;
5757
monotonic_allocator string_allocator_;
58-
buffering_error_reporter errors_;
59-
bool errors_were_reported_ = false;
6058

6159
string8_view save_string(std::string_view s);
6260
};

0 commit comments

Comments
 (0)