Skip to content

Commit 39aecc1

Browse files
camchenrycamc314
authored andcommitted
feat(linter): tsgolint: request fixes when necessary
1 parent 803af8c commit 39aecc1

File tree

6 files changed

+56
-13
lines changed

6 files changed

+56
-13
lines changed

apps/oxlint/src/lint.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ impl CliRunner {
343343
let lint_runner = match LintRunner::builder(options, linter)
344344
.with_type_aware(self.options.type_aware)
345345
.with_silent(misc_options.silent)
346+
.with_fix_kind(fix_options.fix_kind())
346347
.build()
347348
{
348349
Ok(runner) => runner,

crates/oxc_language_server/src/linter/server_linter.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl ServerLinter {
179179
lint_on_run: options.run,
180180
diagnostics: ServerLinterDiagnostics::default(),
181181
tsgo_linter: if options.type_aware {
182-
Arc::new(Some(TsgoLinter::new(&root_path, config_store)))
182+
Arc::new(Some(TsgoLinter::new(&root_path, config_store, fix_kind)))
183183
} else {
184184
Arc::new(None)
185185
},
@@ -511,7 +511,6 @@ mod test {
511511
}
512512

513513
#[test]
514-
#[ignore = "Will be restored in #15048"]
515514
#[cfg(not(target_endian = "big"))]
516515
fn test_lint_on_run_on_type_on_save() {
517516
Tester::new(
@@ -532,7 +531,6 @@ mod test {
532531
}
533532

534533
#[test]
535-
#[ignore = "Will be restored in #15048"]
536534
#[cfg(not(target_endian = "big"))]
537535
fn test_lint_on_run_on_save_on_save() {
538536
Tester::new(
@@ -662,7 +660,6 @@ mod test {
662660
}
663661

664662
#[test]
665-
#[ignore = "Will be restored in #15048"]
666663
#[cfg(not(target_endian = "big"))] // TODO: tsgolint doesn't support big endian?
667664
fn test_tsgo_lint() {
668665
let tester = Tester::new(

crates/oxc_language_server/src/linter/tsgo_linter.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use std::{
55

66
use oxc_data_structures::rope::Rope;
77
use oxc_linter::{
8-
ConfigStore, LINTABLE_EXTENSIONS, TsGoLintState, loader::LINT_PARTIAL_LOADER_EXTENSIONS,
9-
read_to_string,
8+
ConfigStore, FixKind, LINTABLE_EXTENSIONS, TsGoLintState,
9+
loader::LINT_PARTIAL_LOADER_EXTENSIONS, read_to_string,
1010
};
1111
use rustc_hash::FxHashSet;
1212
use tower_lsp_server::{UriExt, lsp_types::Uri};
@@ -20,8 +20,8 @@ pub struct TsgoLinter {
2020
}
2121

2222
impl TsgoLinter {
23-
pub fn new(root_uri: &Path, config_store: ConfigStore) -> Self {
24-
let state = TsGoLintState::new(root_uri, config_store);
23+
pub fn new(root_uri: &Path, config_store: ConfigStore, fix_kind: FixKind) -> Self {
24+
let state = TsGoLintState::new(root_uri, config_store, fix_kind);
2525
Self { state }
2626
}
2727

crates/oxc_linter/src/lint_runner.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ use oxc_diagnostics::{DiagnosticSender, DiagnosticService};
1010
use oxc_span::Span;
1111

1212
use crate::{
13-
AllowWarnDeny, DisableDirectives, LintService, LintServiceOptions, Linter, TsGoLintState,
13+
AllowWarnDeny, DisableDirectives, FixKind, LintService, LintServiceOptions, Linter,
14+
TsGoLintState,
1415
};
1516

1617
/// Unified runner that orchestrates both regular (oxc) and type-aware (tsgolint) linting
@@ -129,6 +130,7 @@ pub struct LintRunnerBuilder {
129130
type_aware_enabled: bool,
130131
lint_service_options: LintServiceOptions,
131132
silent: bool,
133+
fix_kind: FixKind,
132134
}
133135

134136
impl LintRunnerBuilder {
@@ -138,6 +140,7 @@ impl LintRunnerBuilder {
138140
type_aware_enabled: false,
139141
lint_service_options,
140142
silent: false,
143+
fix_kind: FixKind::None,
141144
}
142145
}
143146

@@ -153,6 +156,12 @@ impl LintRunnerBuilder {
153156
self
154157
}
155158

159+
#[must_use]
160+
pub fn with_fix_kind(mut self, fix_kind: FixKind) -> Self {
161+
self.fix_kind = fix_kind;
162+
self
163+
}
164+
156165
/// # Errors
157166
/// Returns an error if the type-aware linter fails to initialize.
158167
pub fn build(self) -> Result<LintRunner, String> {
@@ -162,6 +171,7 @@ impl LintRunnerBuilder {
162171
match TsGoLintState::try_new(
163172
self.lint_service_options.cwd(),
164173
self.regular_linter.config.clone(),
174+
self.fix_kind,
165175
) {
166176
Ok(state) => Some(state.with_silent(self.silent)),
167177
Err(e) => return Err(e),

crates/oxc_linter/src/tsgolint.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use oxc_span::{SourceType, Span};
1414

1515
use super::{AllowWarnDeny, ConfigStore, DisableDirectives, ResolvedLinterState, read_to_string};
1616

17+
use crate::FixKind;
1718
#[cfg(feature = "language_server")]
1819
use crate::fixer::{CompositeFix, Message, PossibleFixes};
1920

@@ -29,24 +30,46 @@ pub struct TsGoLintState {
2930
/// If `oxlint` will output the diagnostics or not.
3031
/// When `silent` is true, we do not need to access the file system for nice diagnostics messages.
3132
silent: bool,
33+
/// If `true`, request that fixes be returned from `tsgolint`.
34+
fix: bool,
35+
/// If `true`, request that suggestions be returned from `tsgolint`.
36+
fix_suggestions: bool,
3237
}
3338

3439
impl TsGoLintState {
35-
pub fn new(cwd: &Path, config_store: ConfigStore) -> Self {
40+
pub fn new(cwd: &Path, config_store: ConfigStore, fix_kind: FixKind) -> Self {
3641
let executable_path =
3742
try_find_tsgolint_executable(cwd).unwrap_or(PathBuf::from("tsgolint"));
3843

39-
TsGoLintState { config_store, executable_path, cwd: cwd.to_path_buf(), silent: false }
44+
TsGoLintState {
45+
config_store,
46+
executable_path,
47+
cwd: cwd.to_path_buf(),
48+
silent: false,
49+
fix: fix_kind.contains(FixKind::Fix),
50+
fix_suggestions: fix_kind.contains(FixKind::Suggestion),
51+
}
4052
}
4153

4254
/// Try to create a new TsGoLintState, returning an error if the executable cannot be found.
4355
///
4456
/// # Errors
4557
/// Returns an error if the tsgolint executable cannot be found.
46-
pub fn try_new(cwd: &Path, config_store: ConfigStore) -> Result<Self, String> {
58+
pub fn try_new(
59+
cwd: &Path,
60+
config_store: ConfigStore,
61+
fix_kind: FixKind,
62+
) -> Result<Self, String> {
4763
let executable_path = try_find_tsgolint_executable(cwd)?;
4864

49-
Ok(TsGoLintState { config_store, executable_path, cwd: cwd.to_path_buf(), silent: false })
65+
Ok(TsGoLintState {
66+
config_store,
67+
executable_path,
68+
cwd: cwd.to_path_buf(),
69+
silent: false,
70+
fix: fix_kind.contains(FixKind::Fix),
71+
fix_suggestions: fix_kind.contains(FixKind::Suggestion),
72+
})
5073
}
5174

5275
/// Set to `true` to skip file system reads.
@@ -90,6 +113,14 @@ impl TsGoLintState {
90113
.stdout(std::process::Stdio::piped())
91114
.stderr(stderr());
92115

116+
if self.fix {
117+
cmd.arg("-fix");
118+
}
119+
120+
if self.fix_suggestions {
121+
cmd.arg("-fix-suggestions");
122+
}
123+
93124
if let Ok(trace_file) = std::env::var("OXLINT_TSGOLINT_TRACE") {
94125
cmd.arg(format!("-trace={trace_file}"));
95126
}

editors/vscode/tests/e2e_server.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ suite('E2E Diagnostics', () => {
265265
await loadFixture('type_aware');
266266
const firstDiagnostics = await getDiagnostics('index.ts');
267267

268+
await workspace.getConfiguration('oxc').update('flags', {
269+
fix_kind: 'all',
270+
});
271+
268272
strictEqual(firstDiagnostics.length, 0);
269273

270274
await workspace.getConfiguration('oxc').update('typeAware', true);

0 commit comments

Comments
 (0)