Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/oxlint/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ impl CliRunner {
let lint_runner = match LintRunner::builder(options, linter)
.with_type_aware(self.options.type_aware)
.with_silent(misc_options.silent)
.with_fix_kind(fix_options.fix_kind())
.build()
{
Ok(runner) => runner,
Expand Down
26 changes: 19 additions & 7 deletions crates/oxc_language_server/src/linter/server_linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ impl ServerLinter {
lint_on_run: options.run,
diagnostics: ServerLinterDiagnostics::default(),
tsgo_linter: if options.type_aware {
Arc::new(Some(TsgoLinter::new(&root_path, config_store)))
Arc::new(Some(TsgoLinter::new(&root_path, config_store, fix_kind)))
} else {
Arc::new(None)
},
Expand Down Expand Up @@ -511,12 +511,16 @@ mod test {
}

#[test]
#[ignore = "Will be restored in #15048"]
#[cfg(not(target_endian = "big"))]
fn test_lint_on_run_on_type_on_save() {
Tester::new(
"fixtures/linter/lint_on_run/on_save",
Some(LintOptions { type_aware: true, run: Run::OnType, ..Default::default() }),
Some(LintOptions {
type_aware: true,
run: Run::OnType,
fix_kind: LintFixKindFlag::All,
..Default::default()
}),
)
.test_and_snapshot_single_file_with_run_type("on-save.ts", Run::OnSave);
}
Expand All @@ -532,12 +536,16 @@ mod test {
}

#[test]
#[ignore = "Will be restored in #15048"]
#[cfg(not(target_endian = "big"))]
fn test_lint_on_run_on_save_on_save() {
Tester::new(
"fixtures/linter/lint_on_run/on_type",
Some(LintOptions { type_aware: true, run: Run::OnSave, ..Default::default() }),
Some(LintOptions {
type_aware: true,
run: Run::OnSave,
fix_kind: LintFixKindFlag::All,
..Default::default()
}),
)
.test_and_snapshot_single_file_with_run_type("on-save.ts", Run::OnSave);
}
Expand Down Expand Up @@ -662,12 +670,16 @@ mod test {
}

#[test]
#[ignore = "Will be restored in #15048"]
#[cfg(not(target_endian = "big"))] // TODO: tsgolint doesn't support big endian?
fn test_tsgo_lint() {
let tester = Tester::new(
"fixtures/linter/tsgolint",
Some(LintOptions { type_aware: true, run: Run::OnSave, ..Default::default() }),
Some(LintOptions {
type_aware: true,
run: Run::OnSave,
fix_kind: LintFixKindFlag::All,
..Default::default()
}),
);
tester.test_and_snapshot_single_file("no-floating-promises/index.ts");
}
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_language_server/src/linter/tsgo_linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::{

use oxc_data_structures::rope::Rope;
use oxc_linter::{
ConfigStore, LINTABLE_EXTENSIONS, TsGoLintState, loader::LINT_PARTIAL_LOADER_EXTENSIONS,
read_to_string,
ConfigStore, FixKind, LINTABLE_EXTENSIONS, TsGoLintState,
loader::LINT_PARTIAL_LOADER_EXTENSIONS, read_to_string,
};
use rustc_hash::FxHashSet;
use tower_lsp_server::{UriExt, lsp_types::Uri};
Expand All @@ -20,8 +20,8 @@ pub struct TsgoLinter {
}

impl TsgoLinter {
pub fn new(root_uri: &Path, config_store: ConfigStore) -> Self {
let state = TsGoLintState::new(root_uri, config_store);
pub fn new(root_uri: &Path, config_store: ConfigStore, fix_kind: FixKind) -> Self {
let state = TsGoLintState::new(root_uri, config_store, fix_kind);
Self { state }
}

Expand Down
12 changes: 11 additions & 1 deletion crates/oxc_linter/src/lint_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use oxc_diagnostics::{DiagnosticSender, DiagnosticService};
use oxc_span::Span;

use crate::{
AllowWarnDeny, DisableDirectives, LintService, LintServiceOptions, Linter, TsGoLintState,
AllowWarnDeny, DisableDirectives, FixKind, LintService, LintServiceOptions, Linter,
TsGoLintState,
};

/// Unified runner that orchestrates both regular (oxc) and type-aware (tsgolint) linting
Expand Down Expand Up @@ -129,6 +130,7 @@ pub struct LintRunnerBuilder {
type_aware_enabled: bool,
lint_service_options: LintServiceOptions,
silent: bool,
fix_kind: FixKind,
}

impl LintRunnerBuilder {
Expand All @@ -138,6 +140,7 @@ impl LintRunnerBuilder {
type_aware_enabled: false,
lint_service_options,
silent: false,
fix_kind: FixKind::None,
}
}

Expand All @@ -153,6 +156,12 @@ impl LintRunnerBuilder {
self
}

#[must_use]
pub fn with_fix_kind(mut self, fix_kind: FixKind) -> Self {
self.fix_kind = fix_kind;
self
}

/// # Errors
/// Returns an error if the type-aware linter fails to initialize.
pub fn build(self) -> Result<LintRunner, String> {
Expand All @@ -162,6 +171,7 @@ impl LintRunnerBuilder {
match TsGoLintState::try_new(
self.lint_service_options.cwd(),
self.regular_linter.config.clone(),
self.fix_kind,
) {
Ok(state) => Some(state.with_silent(self.silent)),
Err(e) => return Err(e),
Expand Down
58 changes: 50 additions & 8 deletions crates/oxc_linter/src/tsgolint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use oxc_span::{SourceType, Span};

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

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

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

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

TsGoLintState { config_store, executable_path, cwd: cwd.to_path_buf(), silent: false }
TsGoLintState {
config_store,
executable_path,
cwd: cwd.to_path_buf(),
silent: false,
fix: fix_kind.contains(FixKind::Fix),
fix_suggestions: fix_kind.contains(FixKind::Suggestion),
}
}

/// Try to create a new TsGoLintState, returning an error if the executable cannot be found.
///
/// # Errors
/// Returns an error if the tsgolint executable cannot be found.
pub fn try_new(cwd: &Path, config_store: ConfigStore) -> Result<Self, String> {
pub fn try_new(
cwd: &Path,
config_store: ConfigStore,
fix_kind: FixKind,
) -> Result<Self, String> {
let executable_path = try_find_tsgolint_executable(cwd)?;

Ok(TsGoLintState { config_store, executable_path, cwd: cwd.to_path_buf(), silent: false })
Ok(TsGoLintState {
config_store,
executable_path,
cwd: cwd.to_path_buf(),
silent: false,
fix: fix_kind.contains(FixKind::Fix),
fix_suggestions: fix_kind.contains(FixKind::Suggestion),
})
}

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

if self.fix {
cmd.arg("-fix");
}

if self.fix_suggestions {
cmd.arg("-fix-suggestions");
}

if let Ok(trace_file) = std::env::var("OXLINT_TSGOLINT_TRACE") {
cmd.arg(format!("-trace={trace_file}"));
}
Expand Down Expand Up @@ -298,12 +329,23 @@ impl TsGoLintState {
let json_input = self.json_input(std::slice::from_ref(path), &mut resolved_configs);
let executable_path = self.executable_path.clone();

let fix = self.fix;
let fix_suggestions = self.fix_suggestions;
let handler = std::thread::spawn(move || {
let child = std::process::Command::new(&executable_path)
.arg("headless")
let mut cmd = std::process::Command::new(&executable_path);
cmd.arg("headless")
.stdin(std::process::Stdio::piped())
.stdout(std::process::Stdio::piped())
.spawn();
.stdout(std::process::Stdio::piped());

if fix {
cmd.arg("-fix");
}

if fix_suggestions {
cmd.arg("-fix-suggestions");
}

let child = cmd.spawn();

let mut child = match child {
Ok(c) => c,
Expand Down
2 changes: 2 additions & 0 deletions editors/vscode/tests/e2e_server.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ suite('E2E Diagnostics', () => {
await loadFixture('type_aware');
const firstDiagnostics = await getDiagnostics('index.ts');

await workspace.getConfiguration('oxc').update('fixKind', 'all');

strictEqual(firstDiagnostics.length, 0);

await workspace.getConfiguration('oxc').update('typeAware', true);
Expand Down
Loading