Skip to content

Commit 485faa1

Browse files
committed
refactor(fe): simplify interface to parse_and_lint
Accept a File_Language instead of a bunch of booleans. This removes the need for a helper conversion function in callers.
1 parent ca92c74 commit 485faa1

File tree

9 files changed

+68
-89
lines changed

9 files changed

+68
-89
lines changed

plugin/vscode/quick-lint-js/vscode/qljs-document.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class QLJS_Lintable_Document : public QLJS_Document_Base {
161161
this->uri());
162162
parse_and_lint(this->document_.string(), diag_reporter,
163163
this->config_->globals(),
164-
get_linter_options_from_language(this->language_));
164+
Linter_Options{.language = this->language_});
165165

166166
return std::move(diag_reporter).diagnostics();
167167
}

src/quick-lint-js/c-api.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,24 @@ void qljs_web_demo_set_config(QLJS_Web_Demo_Document* js_document,
5353

5454
void qljs_web_demo_set_language_options(QLJS_Web_Demo_Document* p,
5555
QLJS_Language_Options options) {
56-
p->linter_options_.jsx = options & qljs_language_options_jsx_bit;
57-
p->linter_options_.typescript =
58-
options & qljs_language_options_typescript_bit;
56+
switch (options & (qljs_language_options_jsx_bit |
57+
qljs_language_options_typescript_bit)) {
58+
case 0:
59+
p->linter_options_.language = File_Language::javascript;
60+
break;
61+
case qljs_language_options_jsx_bit:
62+
p->linter_options_.language = File_Language::javascript_jsx;
63+
break;
64+
case qljs_language_options_typescript_bit:
65+
p->linter_options_.language = File_Language::typescript;
66+
break;
67+
case qljs_language_options_jsx_bit | qljs_language_options_typescript_bit:
68+
p->linter_options_.language = File_Language::typescript_jsx;
69+
break;
70+
default:
71+
QLJS_UNREACHABLE();
72+
break;
73+
}
5974
p->is_config_json_ = options & qljs_language_options_config_json_bit;
6075
}
6176

src/quick-lint-js/cli/main.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,10 @@ void run(Options o) {
299299
if (!source.ok()) {
300300
source.error().print_and_exit();
301301
}
302-
Linter_Options lint_options =
303-
get_linter_options_from_language(get_language(file, o));
304-
lint_options.print_parser_visits = o.print_parser_visits;
302+
Linter_Options lint_options = {
303+
.language = get_language(file, o),
304+
.print_parser_visits = o.print_parser_visits,
305+
};
305306
reporter->set_source(&*source, file);
306307
parse_and_lint(&*source, *reporter->get(), config->globals(),
307308
lint_options);

src/quick-lint-js/fe/linter.cpp

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,63 +11,55 @@
1111
#include <quick-lint-js/fe/parse.h>
1212
#include <quick-lint-js/fe/variable-analyzer.h>
1313
#include <quick-lint-js/io/output-stream.h>
14+
#include <quick-lint-js/port/unreachable.h>
1415

1516
namespace quick_lint_js {
1617
bool operator==(Linter_Options lhs, Linter_Options rhs) {
17-
return lhs.jsx == rhs.jsx && lhs.typescript == rhs.typescript &&
18-
lhs.typescript_definition == rhs.typescript_definition &&
18+
return lhs.language == rhs.language &&
1919
lhs.print_parser_visits == rhs.print_parser_visits;
2020
}
2121

2222
bool operator!=(Linter_Options lhs, Linter_Options rhs) {
2323
return !(lhs == rhs);
2424
}
2525

26-
Linter_Options get_linter_options_from_language(File_Language language) {
27-
Linter_Options o;
28-
switch (language) {
26+
void parse_and_lint(Padded_String_View code, Diag_Reporter& reporter,
27+
const Global_Declared_Variable_Set& globals,
28+
Linter_Options options) {
29+
Parser_Options parser_options;
30+
switch (options.language) {
2931
case File_Language::javascript:
30-
o.jsx = false;
31-
o.typescript = false;
32+
parser_options.jsx = false;
33+
parser_options.typescript = false;
3234
break;
3335
case File_Language::javascript_jsx:
34-
o.jsx = true;
35-
o.typescript = false;
36+
parser_options.jsx = true;
37+
parser_options.typescript = false;
3638
break;
3739
case File_Language::typescript:
38-
o.jsx = false;
39-
o.typescript = true;
40+
parser_options.jsx = false;
41+
parser_options.typescript = true;
4042
break;
4143
case File_Language::typescript_definition:
42-
o.jsx = false;
43-
o.typescript = true;
44-
o.typescript_definition = true;
44+
parser_options.jsx = false;
45+
parser_options.typescript = true;
46+
parser_options.typescript_definition_file = true;
4547
break;
4648
case File_Language::typescript_jsx:
47-
o.jsx = true;
48-
o.typescript = true;
49+
parser_options.jsx = true;
50+
parser_options.typescript = true;
4951
break;
5052
}
51-
return o;
52-
}
5353

54-
void parse_and_lint(Padded_String_View code, Diag_Reporter& reporter,
55-
const Global_Declared_Variable_Set& globals,
56-
Linter_Options options) {
57-
Parser p(code, &reporter,
58-
Parser_Options{
59-
.jsx = options.jsx,
60-
.typescript = options.typescript,
61-
.typescript_definition_file = options.typescript_definition,
62-
});
54+
Parser p(code, &reporter, parser_options);
6355
Variable_Analyzer var_analyzer(
6456
&reporter, &globals,
6557
Variable_Analyzer_Options{
66-
.allow_deleting_typescript_variable = !options.typescript,
67-
.eval_can_declare_variables = !options.typescript,
58+
.allow_deleting_typescript_variable = !parser_options.typescript,
59+
.eval_can_declare_variables = !parser_options.typescript,
6860
// TODO(strager): Deduplicate with typescript_var_options in tests.
69-
.can_assign_to_class = !options.typescript,
70-
.import_variable_can_be_runtime_or_type = options.typescript,
61+
.can_assign_to_class = !parser_options.typescript,
62+
.import_variable_can_be_runtime_or_type = parser_options.typescript,
7163
});
7264

7365
#if defined(__EMSCRIPTEN__)

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

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,7 @@ class Padded_String_View;
1212

1313
// TODO(#465): Accept parser options from quick-lint-js.config or CLI options.
1414
struct Linter_Options {
15-
// If true, parse and lint JSX language extensions:
16-
// https://facebook.github.io/jsx/
17-
bool jsx = true;
18-
19-
// If true, parse and lint TypeScript instead of JavaScript.
20-
bool typescript = false;
21-
22-
// If true, parse as a TypeScript definition file (.d.ts).
23-
//
24-
// Invariant: typescript_definition implies typescript.
25-
bool typescript_definition = false;
15+
File_Language language;
2616

2717
// If true, print a human-readable representation of parser visits to stderr.
2818
bool print_parser_visits = false;
@@ -31,8 +21,6 @@ struct Linter_Options {
3121
friend bool operator!=(Linter_Options, Linter_Options);
3222
};
3323

34-
Linter_Options get_linter_options_from_language(File_Language);
35-
3624
void parse_and_lint(Padded_String_View code, Diag_Reporter&,
3725
const Global_Declared_Variable_Set&, Linter_Options);
3826
}

src/quick-lint-js/lsp/lsp-server.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,7 +754,7 @@ LSP_Linter::~LSP_Linter() = default;
754754
void LSP_Linter::lint(LSP_Documents::Lintable_Document& doc,
755755
String8_View uri_json,
756756
Outgoing_JSON_RPC_Message_Queue& outgoing_messages) {
757-
this->lint(*doc.config, get_linter_options_from_language(doc.language),
757+
this->lint(*doc.config, Linter_Options{.language = doc.language},
758758
doc.doc.string(), uri_json, doc.version_json, outgoing_messages);
759759
}
760760

test/test-lsp-server.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,7 @@ TEST_F(Test_Linting_LSP_Server, javascript_language_ids_enable_jsx) {
607607
auto lint_callback = [&](Configuration&, Linter_Options lint_options,
608608
Padded_String_View, String8_View, String8_View,
609609
Outgoing_JSON_RPC_Message_Queue&) {
610-
EXPECT_TRUE(lint_options.jsx);
611-
EXPECT_FALSE(lint_options.typescript);
610+
EXPECT_EQ(lint_options.language, File_Language::javascript_jsx);
612611
};
613612
this->linter.lint_callback = lint_callback;
614613

@@ -640,8 +639,7 @@ TEST_F(Test_Linting_LSP_Server, typescript_language_ids_enable_typescript) {
640639
auto lint_callback = [&](Configuration&, Linter_Options lint_options,
641640
Padded_String_View, String8_View, String8_View,
642641
Outgoing_JSON_RPC_Message_Queue&) {
643-
EXPECT_TRUE(lint_options.typescript);
644-
EXPECT_FALSE(lint_options.jsx);
642+
EXPECT_EQ(lint_options.language, File_Language::typescript);
645643
};
646644
this->linter.lint_callback = lint_callback;
647645

@@ -673,8 +671,7 @@ TEST_F(Test_Linting_LSP_Server, tsx_language_ids_enable_typescript_jsx) {
673671
auto lint_callback = [&](Configuration&, Linter_Options lint_options,
674672
Padded_String_View, String8_View, String8_View,
675673
Outgoing_JSON_RPC_Message_Queue&) {
676-
EXPECT_TRUE(lint_options.typescript);
677-
EXPECT_TRUE(lint_options.jsx);
674+
EXPECT_EQ(lint_options.language, File_Language::typescript_jsx);
678675
};
679676
this->linter.lint_callback = lint_callback;
680677

test/test-typescript-test.cpp

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,7 @@ TEST(Test_TypeScript_Test, typescript_file_is_linted) {
215215
ASSERT_EQ(units.size(), 2);
216216
std::optional<Linter_Options> options = units[0].get_linter_options();
217217
ASSERT_TRUE(options.has_value());
218-
EXPECT_TRUE(options->typescript);
219-
EXPECT_FALSE(options->jsx);
218+
EXPECT_EQ(options->language, File_Language::typescript);
220219
}
221220

222221
{
@@ -229,8 +228,7 @@ TEST(Test_TypeScript_Test, typescript_file_is_linted) {
229228
ASSERT_EQ(units.size(), 2);
230229
std::optional<Linter_Options> options = units[1].get_linter_options();
231230
ASSERT_TRUE(options.has_value());
232-
EXPECT_TRUE(options->typescript);
233-
EXPECT_FALSE(options->jsx);
231+
EXPECT_EQ(options->language, File_Language::typescript);
234232
}
235233
}
236234

@@ -245,8 +243,7 @@ TEST(Test_TypeScript_Test, typescript_react_file_is_linted) {
245243
ASSERT_EQ(units.size(), 2);
246244
std::optional<Linter_Options> options = units[0].get_linter_options();
247245
ASSERT_TRUE(options.has_value());
248-
EXPECT_TRUE(options->typescript);
249-
EXPECT_TRUE(options->jsx);
246+
EXPECT_EQ(options->language, File_Language::typescript_jsx);
250247
}
251248

252249
{
@@ -259,8 +256,7 @@ TEST(Test_TypeScript_Test, typescript_react_file_is_linted) {
259256
ASSERT_EQ(units.size(), 2);
260257
std::optional<Linter_Options> options = units[1].get_linter_options();
261258
ASSERT_TRUE(options.has_value());
262-
EXPECT_TRUE(options->typescript);
263-
EXPECT_TRUE(options->jsx);
259+
EXPECT_EQ(options->language, File_Language::typescript_jsx);
264260
}
265261
}
266262

@@ -273,9 +269,7 @@ TEST(Test_TypeScript_Test, typescript_definition_file) {
273269
ASSERT_EQ(units.size(), 1);
274270
std::optional<Linter_Options> options = units[0].get_linter_options();
275271
ASSERT_TRUE(options.has_value());
276-
EXPECT_TRUE(options->typescript);
277-
EXPECT_TRUE(options->typescript_definition);
278-
EXPECT_FALSE(options->jsx);
272+
EXPECT_EQ(options->language, File_Language::typescript_definition);
279273
}
280274

281275
TEST(Test_TypeScript_Test, typescript_definition_file_with_weird_extension) {
@@ -287,8 +281,7 @@ TEST(Test_TypeScript_Test, typescript_definition_file_with_weird_extension) {
287281
ASSERT_EQ(units.size(), 1);
288282
std::optional<Linter_Options> options = units[0].get_linter_options();
289283
ASSERT_TRUE(options.has_value());
290-
EXPECT_TRUE(options->typescript);
291-
EXPECT_TRUE(options->typescript_definition);
284+
EXPECT_EQ(options->language, File_Language::typescript_definition);
292285
}
293286

294287
TEST(Test_TypeScript_Test, javascript_file_is_linted) {
@@ -303,17 +296,13 @@ TEST(Test_TypeScript_Test, javascript_file_is_linted) {
303296

304297
std::optional<Linter_Options> options = units[0].get_linter_options();
305298
ASSERT_TRUE(options.has_value());
306-
EXPECT_FALSE(options->typescript);
307-
// FIXME(strager): Should we only set jsx=true if a @jsx directive is
308-
// present?
309-
EXPECT_TRUE(options->jsx);
299+
// FIXME(strager): Should we only enable jsx if a @jsx directive is present?
300+
EXPECT_EQ(options->language, File_Language::javascript_jsx);
310301

311302
options = units[1].get_linter_options();
312303
ASSERT_TRUE(options.has_value());
313-
EXPECT_FALSE(options->typescript);
314-
// FIXME(strager): Should we only set jsx=true if a @jsx directive is
315-
// present?
316-
EXPECT_TRUE(options->jsx);
304+
// FIXME(strager): Should we only enable jsx if a @jsx directive is present?
305+
EXPECT_EQ(options->language, File_Language::javascript_jsx);
317306
}
318307
}
319308

@@ -329,13 +318,11 @@ TEST(Test_TypeScript_Test, javascript_react_file_is_linted) {
329318

330319
std::optional<Linter_Options> options = units[0].get_linter_options();
331320
ASSERT_TRUE(options.has_value());
332-
EXPECT_FALSE(options->typescript);
333-
EXPECT_TRUE(options->jsx);
321+
EXPECT_EQ(options->language, File_Language::javascript_jsx);
334322

335323
options = units[1].get_linter_options();
336324
ASSERT_TRUE(options.has_value());
337-
EXPECT_FALSE(options->typescript);
338-
EXPECT_TRUE(options->jsx);
325+
EXPECT_EQ(options->language, File_Language::javascript_jsx);
339326
}
340327
}
341328

tools/test-typescript/typescript-test.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,20 +134,19 @@ std::optional<Linter_Options> TypeScript_Test_Unit::get_linter_options() const {
134134
return std::nullopt;
135135
}
136136
if (contains(String8_View(this->name), u8".d."_sv)) {
137-
return Linter_Options{
138-
.jsx = false, .typescript = true, .typescript_definition = true};
137+
return Linter_Options{.language = File_Language::typescript_definition};
139138
}
140139
if (ends_with(String8_View(this->name), u8".ts"_sv)) {
141-
return Linter_Options{.jsx = false, .typescript = true};
140+
return Linter_Options{.language = File_Language::typescript};
142141
}
143142
if (ends_with(String8_View(this->name), u8".tsx"_sv)) {
144-
return Linter_Options{.jsx = true, .typescript = true};
143+
return Linter_Options{.language = File_Language::typescript_jsx};
145144
}
146145
if (ends_with(String8_View(this->name), u8".js"_sv)) {
147-
return Linter_Options{.jsx = true, .typescript = false};
146+
return Linter_Options{.language = File_Language::javascript_jsx};
148147
}
149148
if (ends_with(String8_View(this->name), u8".jsx"_sv)) {
150-
return Linter_Options{.jsx = true, .typescript = false};
149+
return Linter_Options{.language = File_Language::javascript_jsx};
151150
}
152151
// Don't lint unknown file extensions. See
153152
// TypeScript/tests/cases/conformance/moduleResolution/bundler/bundlerImportTsExtensions.ts

0 commit comments

Comments
 (0)