Skip to content

Commit 9dd4710

Browse files
committed
feat(configuration): add jsx-mode to quick-lint-js.config
Allow users to override the React detection heuristics used for some JSX diagnostics.
1 parent fe5742f commit 9dd4710

22 files changed

+543
-11
lines changed

docs/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Semantic Versioning.
1010

1111
### Added
1212

13+
* quick-lint-js's JSX diagnostics can now be configured via quick-lint-js's [JSX
14+
mode][] mechanism. New JSX modes are `"none"`, `"react"`, and `"auto"`
15+
(default).
1316
* Writing a namespace alias with `import type`, such as in
1417
`import type ns = otherns;`, now reports [E0717][] ("namespace alias cannot
1518
use 'import type'"). (Implemented by [koopiehoop][].)
@@ -1322,6 +1325,7 @@ Beta release.
13221325

13231326
[Bun]: https://bun.sh/
13241327
[Deno]: https://deno.land/
1328+
[JSX Mode]: https://quick-lint-js.com/errors/jsx/
13251329
[cli-language]: ../cli/#language
13261330
[cmake-install-component-build-tools-patch]: https://github.com/quick-lint/quick-lint-js/commit/3923f0df76d24b73d57f15eec61ab190ea048093.patch
13271331
[coc.nvim]: https://github.com/neoclide/coc.nvim

docs/config.adoc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,23 @@ Each group name is a string.
114114
For the list of group names, see the <<Global Groups>> section.
115115
--
116116

117+
*jsx-mode*:: Optional.
118+
How to lint intrinsic JSX elements.
119+
+
120+
--
121+
*jsx-mode* is a string.
122+
Possible values are as follows:
123+
124+
- *"auto"* (default): Determine the JSX flavor automatically using various heuristics.
125+
See the link:https://quick-lint-js.com/errors/jsx/#auto[JSX linting documentation] for more information about these heuristics.
126+
- *"react"*: Assume that JSX is intended for the React.js framework.
127+
- *"none"*: Disable all framework-specific JSX linting rules.
128+
129+
See the link:https://quick-lint-js.com/errors/jsx/[JSX linting documentation] for more information on which rules are configured by *jsx-mode*.
130+
131+
Introduced in quick-lint-js version 3.1.0.
132+
--
133+
117134
[#globals]
118135
== Globals
119136

docs/errors/E0191.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,8 @@ function TodoEntry({addTodo, changePendingTodo}) {
2929
}
3030
```
3131

32+
This diagnostic enabled in the `"react"` [JSX mode][].
33+
3234
Introduced in quick-lint-js version 2.0.0.
35+
36+
[JSX Mode]: https://quick-lint-js.com/errors/jsx/

docs/errors/E0192.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@ function Header({columns}) {
3030
}
3131
```
3232

33+
This diagnostic enabled in the `"react"` [JSX mode][].
34+
3335
Introduced in quick-lint-js version 2.0.0.
36+
37+
[JSX Mode]: https://quick-lint-js.com/errors/jsx/

docs/errors/E0193.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,8 @@ function Title({page}) {
2929
}
3030
```
3131

32+
This diagnostic enabled in the `"react"` [JSX mode][].
33+
3234
Introduced in quick-lint-js version 2.0.0.
35+
36+
[JSX Mode]: https://quick-lint-js.com/errors/jsx/

docs/man/quick-lint-js.config.5

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,57 @@ If \fBglobal\-groups\fP is a non\-empty array, then global variables are defined
226226
Each group name is a string.
227227
For the list of group names, see the GLOBAL GROUPS section.
228228
.RE
229+
.sp
230+
\fBjsx\-mode\fP
231+
.RS 4
232+
Optional.
233+
How to lint intrinsic JSX elements.
234+
.sp
235+
\fBjsx\-mode\fP is a string.
236+
Possible values are as follows:
237+
.sp
238+
.RS 4
239+
.ie n \{\
240+
\h'-04'\(bu\h'+03'\c
241+
.\}
242+
.el \{\
243+
. sp -1
244+
. IP \(bu 2.3
245+
.\}
246+
\fB"auto"\fP (default): Determine the JSX flavor automatically using various heuristics.
247+
See the \c
248+
.URL "https://quick\-lint\-js.com/errors/jsx/#auto" "JSX linting documentation" ""
249+
for more information about these heuristics.
250+
.RE
251+
.sp
252+
.RS 4
253+
.ie n \{\
254+
\h'-04'\(bu\h'+03'\c
255+
.\}
256+
.el \{\
257+
. sp -1
258+
. IP \(bu 2.3
259+
.\}
260+
\fB"react"\fP: Assume that JSX is intended for the React.js framework.
261+
.RE
262+
.sp
263+
.RS 4
264+
.ie n \{\
265+
\h'-04'\(bu\h'+03'\c
266+
.\}
267+
.el \{\
268+
. sp -1
269+
. IP \(bu 2.3
270+
.\}
271+
\fB"none"\fP: Disable all framework\-specific JSX linting rules.
272+
.RE
273+
.sp
274+
See the \c
275+
.URL "https://quick\-lint\-js.com/errors/jsx/" "JSX linting documentation" ""
276+
for more information on which rules are configured by \fBjsx\-mode\fP.
277+
.sp
278+
Introduced in quick\-lint\-js version 3.1.0.
279+
.RE
229280
.SH "GLOBALS"
230281
.sp
231282
The \fBglobals\fP configuration property tells quick\-lint\-js what global variables to assume exist.

docs/quick-lint-js.config.schema.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@
6262
"uniqueItems": true
6363
}
6464
]
65+
},
66+
67+
"jsx-mode": {
68+
"description": "How to lint intrinsic JSX elements.",
69+
"type": "string",
70+
"enum": ["auto", "none", "react"]
6571
}
6672
}
6773
}

po/messages.pot

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,14 @@ msgstr ""
709709
msgid "\"globals\" must be an object"
710710
msgstr ""
711711

712+
#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
713+
msgid "\"jsx-mode\" must be a string; try \"none\" or \"react\""
714+
msgstr ""
715+
716+
#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
717+
msgid "unknown JSX mode; try \"none\" or \"react\""
718+
msgstr ""
719+
712720
#: src/quick-lint-js/diag/diagnostic-metadata-generated.cpp
713721
msgid "depth limit exceeded"
714722
msgstr ""

src/quick-lint-js/configuration/configuration.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,57 @@ void Configuration::load_from_json(Padded_String_View json,
135135
this->report_json_error(json, out_diags);
136136
return;
137137
}
138+
139+
auto jsx_mode = document["jsx-mode"];
140+
std::string_view jsx_mode_string;
141+
switch (jsx_mode.get(jsx_mode_string)) {
142+
case ::simdjson::error_code::SUCCESS: {
143+
if (jsx_mode_string == "auto"sv) {
144+
this->jsx_mode = Parser_JSX_Mode::auto_detect;
145+
} else if (jsx_mode_string == "react"sv) {
146+
this->jsx_mode = Parser_JSX_Mode::react;
147+
} else if (jsx_mode_string == "none"sv) {
148+
this->jsx_mode = Parser_JSX_Mode::none;
149+
} else {
150+
::simdjson::ondemand::value v;
151+
if (jsx_mode.get(v) == ::simdjson::SUCCESS) {
152+
out_diags->add(Diag_Config_JSX_Mode_Unrecognized{
153+
.value = span_of_json_value(v),
154+
});
155+
} else {
156+
this->report_json_error(json, out_diags);
157+
}
158+
}
159+
break;
160+
}
161+
162+
case ::simdjson::error_code::INCORRECT_TYPE: {
163+
// Either "jsx-mode" has the wrong type or there is a syntax error. simdjson
164+
// gives us INCORRECT_TYPE in both cases.
165+
::simdjson::ondemand::value v;
166+
if (jsx_mode.get(v) == ::simdjson::SUCCESS &&
167+
v.type().error() == ::simdjson::SUCCESS) {
168+
out_diags->add(Diag_Config_JSX_Mode_Type_Mismatch{
169+
.value = span_of_json_value(v),
170+
});
171+
} else {
172+
this->report_json_error(json, out_diags);
173+
return;
174+
}
175+
break;
176+
}
177+
178+
case ::simdjson::error_code::NO_SUCH_FIELD:
179+
break;
180+
181+
default:
182+
this->report_json_error(json, out_diags);
183+
return;
184+
}
138185
}
139186

140187
void Configuration::reset() {
188+
this->jsx_mode = Parser_JSX_Mode::auto_detect;
141189
this->globals_.clear();
142190
this->globals_to_remove_.clear();
143191
this->did_add_globals_from_groups_ = false;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <quick-lint-js/container/vector.h>
1212
#include <quick-lint-js/fe/global-declared-variable-set.h>
1313
#include <quick-lint-js/fe/global-variables.h>
14+
#include <quick-lint-js/fe/parse.h>
1415
#include <quick-lint-js/port/char8.h>
1516
#include <quick-lint-js/simdjson-fwd.h>
1617
#include <vector>
@@ -22,6 +23,8 @@ class Configuration {
2223
public:
2324
explicit Configuration();
2425

26+
Parser_JSX_Mode jsx_mode;
27+
2528
const Global_Declared_Variable_Set& globals();
2629

2730
void reset_global_groups();

0 commit comments

Comments
 (0)