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
6 changes: 3 additions & 3 deletions crates/oxc_language_server/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ impl LanguageServer for Backend {
self.file_system.write().await.set(uri, content.clone());
}

if let Some(diagnostics) = worker.run_diagnostic_on_change(uri, content).await {
if let Some(diagnostics) = worker.run_diagnostic_on_change(uri, content.as_deref()).await {
self.client
.publish_diagnostics(uri.clone(), diagnostics, Some(params.text_document.version))
.await;
Expand All @@ -516,7 +516,7 @@ impl LanguageServer for Backend {
self.file_system.write().await.set(uri, content.clone());
}

if let Some(diagnostics) = worker.run_diagnostic(uri, Some(content)).await {
if let Some(diagnostics) = worker.run_diagnostic(uri, Some(&content)).await {
self.client
.publish_diagnostics(uri.clone(), diagnostics, Some(params.text_document.version))
.await;
Expand Down Expand Up @@ -599,7 +599,7 @@ impl LanguageServer for Backend {
let Some(worker) = workers.iter().find(|worker| worker.is_responsible_for_uri(uri)) else {
return Ok(None);
};
Ok(worker.format_file(uri, self.file_system.read().await.get(uri)).await)
Ok(worker.format_file(uri, self.file_system.read().await.get(uri).as_deref()).await)
}
}

Expand Down
26 changes: 16 additions & 10 deletions crates/oxc_language_server/src/formatter/server_formatter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,28 +199,34 @@ impl Tool for ServerFormatter {
}
}

fn run_format(&self, uri: &Uri, content: Option<String>) -> Option<Vec<TextEdit>> {
fn run_format(&self, uri: &Uri, content: Option<&str>) -> Option<Vec<TextEdit>> {
// Formatter is disabled
if !self.should_run {
return None;
}

let path = uri.to_file_path()?;
let source_type = get_supported_source_type(&path).map(enable_jsx_source_type)?;
// Declaring Variable to satisfy borrow checker
let file_content;
let source_text = if let Some(content) = content {
content
} else {
#[cfg(not(all(test, windows)))]
let source_text = std::fs::read_to_string(&path).ok()?;
{
file_content = std::fs::read_to_string(&path).ok()?;
}
#[cfg(all(test, windows))]
#[expect(clippy::disallowed_methods)] // no `cow_replace` in tests are fine
// On Windows, convert CRLF to LF for consistent formatting results
let source_text = std::fs::read_to_string(&path).ok()?.replace("\r\n", "\n");
source_text
{
file_content = std::fs::read_to_string(&path).ok()?.replace("\r\n", "\n");
}
&file_content
};

let allocator = Allocator::new();
let ret = Parser::new(&allocator, &source_text, source_type)
let ret = Parser::new(&allocator, source_text, source_type)
.with_options(get_parse_options())
.parse();

Expand All @@ -231,14 +237,14 @@ impl Tool for ServerFormatter {
let code = Formatter::new(&allocator, self.options.clone()).build(&ret.program);

// nothing has changed
if code == source_text {
if code == *source_text {
return Some(vec![]);
}

let (start, end, replacement) = compute_minimal_text_edit(&source_text, &code);
let rope = Rope::from(source_text.as_str());
let (start_line, start_character) = get_line_column(&rope, start, &source_text);
let (end_line, end_character) = get_line_column(&rope, end, &source_text);
let (start, end, replacement) = compute_minimal_text_edit(source_text, &code);
let rope = Rope::from(source_text);
let (start_line, start_character) = get_line_column(&rope, start, source_text);
let (end_line, end_character) = get_line_column(&rope, end, source_text);

Some(vec![TextEdit::new(
Range::new(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,17 @@ impl IsolatedLintHandler {
Self { runner, unused_directives_severity: lint_options.report_unused_directive }
}

pub fn run_single(&self, uri: &Uri, content: Option<String>) -> Option<Vec<DiagnosticReport>> {
pub fn run_single(&self, uri: &Uri, content: Option<&str>) -> Option<Vec<DiagnosticReport>> {
let path = uri.to_file_path()?;

if !Self::should_lint_path(&path) {
return None;
}

let source_text = content.or_else(|| read_to_string(&path).ok())?;
let source_text =
if let Some(content) = content { content } else { &read_to_string(&path).ok()? };

let mut diagnostics = self.lint_path(&path, uri, &source_text);
let mut diagnostics = self.lint_path(&path, uri, source_text);
diagnostics.append(&mut generate_inverted_diagnostics(&diagnostics, uri));
Some(diagnostics)
}
Expand Down
12 changes: 4 additions & 8 deletions crates/oxc_language_server/src/linter/server_linter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ impl Tool for ServerLinter {
/// Lint a file with the current linter
/// - If the file is not lintable or ignored, [`None`] is returned
/// - If the file is lintable, but no diagnostics are found, an empty vector is returned
fn run_diagnostic(&self, uri: &Uri, content: Option<String>) -> Option<Vec<Diagnostic>> {
fn run_diagnostic(&self, uri: &Uri, content: Option<&str>) -> Option<Vec<Diagnostic>> {
self.run_file(uri, content)
.map(|reports| reports.into_iter().map(|report| report.diagnostic).collect())
}
Expand All @@ -467,7 +467,7 @@ impl Tool for ServerLinter {
fn run_diagnostic_on_change(
&self,
uri: &Uri,
content: Option<String>,
content: Option<&str>,
) -> Option<Vec<Diagnostic>> {
if self.run != Run::OnType {
return None;
Expand All @@ -479,11 +479,7 @@ impl Tool for ServerLinter {
/// - If the file is not lintable or ignored, [`None`] is returned
/// - If the linter is not set to `OnSave`, [`None`] is returned
/// - If the file is lintable, but no diagnostics are found, an empty vector is returned
fn run_diagnostic_on_save(
&self,
uri: &Uri,
content: Option<String>,
) -> Option<Vec<Diagnostic>> {
fn run_diagnostic_on_save(&self, uri: &Uri, content: Option<&str>) -> Option<Vec<Diagnostic>> {
if self.run != Run::OnSave {
return None;
}
Expand Down Expand Up @@ -563,7 +559,7 @@ impl ServerLinter {
}

/// Lint a single file, return `None` if the file is ignored.
fn run_file(&self, uri: &Uri, content: Option<String>) -> Option<Vec<DiagnosticReport>> {
fn run_file(&self, uri: &Uri, content: Option<&str>) -> Option<Vec<DiagnosticReport>> {
if self.is_ignored(uri) {
return None;
}
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_language_server/src/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,15 @@ pub trait Tool: Sized {
/// Returns a vector of `TextEdit` representing the formatting changes.
///
/// Not all tools will implement formatting, so the default implementation returns `None`.
fn run_format(&self, _uri: &Uri, _content: Option<String>) -> Option<Vec<TextEdit>> {
fn run_format(&self, _uri: &Uri, _content: Option<&str>) -> Option<Vec<TextEdit>> {
None
}

/// Run diagnostics on the content of the given URI.
/// If `content` is `None`, the tool should read the content from the file system.
/// Returns a vector of `Diagnostic` representing the diagnostic results.
/// Not all tools will implement diagnostics, so the default implementation returns `None`.
fn run_diagnostic(&self, _uri: &Uri, _content: Option<String>) -> Option<Vec<Diagnostic>> {
fn run_diagnostic(&self, _uri: &Uri, _content: Option<&str>) -> Option<Vec<Diagnostic>> {
None
}

Expand All @@ -88,7 +88,7 @@ pub trait Tool: Sized {
fn run_diagnostic_on_save(
&self,
_uri: &Uri,
_content: Option<String>,
_content: Option<&str>,
) -> Option<Vec<Diagnostic>> {
None
}
Expand All @@ -100,7 +100,7 @@ pub trait Tool: Sized {
fn run_diagnostic_on_change(
&self,
_uri: &Uri,
_content: Option<String>,
_content: Option<&str>,
) -> Option<Vec<Diagnostic>> {
None
}
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_language_server/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ impl WorkspaceWorker {
pub async fn run_diagnostic(
&self,
uri: &Uri,
content: Option<String>,
content: Option<&str>,
) -> Option<Vec<Diagnostic>> {
let Some(server_linter) = &*self.server_linter.read().await else {
return None;
Expand All @@ -162,7 +162,7 @@ impl WorkspaceWorker {
pub async fn run_diagnostic_on_change(
&self,
uri: &Uri,
content: Option<String>,
content: Option<&str>,
) -> Option<Vec<Diagnostic>> {
let Some(server_linter) = &*self.server_linter.read().await else {
return None;
Expand All @@ -175,7 +175,7 @@ impl WorkspaceWorker {
pub async fn run_diagnostic_on_save(
&self,
uri: &Uri,
content: Option<String>,
content: Option<&str>,
) -> Option<Vec<Diagnostic>> {
let Some(server_linter) = &*self.server_linter.read().await else {
return None;
Expand All @@ -187,7 +187,7 @@ impl WorkspaceWorker {
/// Format a file with the current formatter
/// - If no file is not formattable or ignored, [`None`] is returned
/// - If the file is formattable, but no changes are made, an empty vector is returned
pub async fn format_file(&self, uri: &Uri, content: Option<String>) -> Option<Vec<TextEdit>> {
pub async fn format_file(&self, uri: &Uri, content: Option<&str>) -> Option<Vec<TextEdit>> {
let Some(server_formatter) = &*self.server_formatter.read().await else {
return None;
};
Expand Down
Loading