Skip to content

Commit

Permalink
fix(lsp): correctly infer file source from un-named files
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico committed Jan 3, 2024
1 parent 3c24e4c commit a2195b7
Show file tree
Hide file tree
Showing 7 changed files with 197 additions and 163 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ Biome now scores 97% compatibility with Prettier and features more than 180 lint
#### Bug fixes
- Fix [#933](https://github.com/biomejs/biome/issues/933). Some files are properly ignored in the LSP too. E.g. `package.json`, `tsconfig.json`, etc.
- Fix [#1394](https://github.com/biomejs/biome/issues/1394), by inferring the language extension from the internal saved files. Now newly created files JavaScript correctly show diagnostics.
### Formatter
Expand Down
168 changes: 90 additions & 78 deletions crates/biome_service/src/file_handlers/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ use biome_rowan::{AstNode, BatchMutationExt, Direction, FileSource, NodeCache};
use std::borrow::Cow;
use std::fmt::Debug;
use std::path::PathBuf;
use tracing::{debug, error, info, trace};
use tracing::{debug, debug_span, error, info, trace};

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
Expand Down Expand Up @@ -267,89 +267,101 @@ fn debug_formatter_ir(
}

fn lint(params: LintParams) -> LintResults {
let Ok(file_source) = params.parse.file_source(params.path) else {
return LintResults {
errors: 0,
diagnostics: vec![],
skipped_diagnostics: 0,
};
};
let tree = params.parse.tree();
let mut diagnostics = params.parse.into_diagnostics();
debug_span!("Linting JavaScript file", path =? params.path, language =? params.language)
.in_scope(move || {
let file_source = match params.parse.file_source(params.path) {
Ok(file_source) => file_source,
Err(_) => {
if let Some(file_source) = params.language.as_js_file_source() {
file_source
} else {
return LintResults {
errors: 0,
diagnostics: vec![],
skipped_diagnostics: 0,
};
}
}
};
let tree = params.parse.tree();
let mut diagnostics = params.parse.into_diagnostics();

let analyzer_options =
compute_analyzer_options(&params.settings, PathBuf::from(params.path.as_path()));
let analyzer_options =
compute_analyzer_options(&params.settings, PathBuf::from(params.path.as_path()));

let mut diagnostic_count = diagnostics.len() as u64;
let mut errors = diagnostics
.iter()
.filter(|diag| diag.severity() <= Severity::Error)
.count();
let mut diagnostic_count = diagnostics.len() as u64;
let mut errors = diagnostics
.iter()
.filter(|diag| diag.severity() <= Severity::Error)
.count();

let has_lint = params.filter.categories.contains(RuleCategories::LINT);

info!("Analyze file {}", params.path.display());
let (_, analyze_diagnostics) = analyze(
&tree,
params.filter,
&analyzer_options,
file_source,
|signal| {
if let Some(mut diagnostic) = signal.diagnostic() {
// Do not report unused suppression comment diagnostics if this is a syntax-only analyzer pass
if !has_lint
&& diagnostic.category() == Some(category!("suppressions/unused"))
{
return ControlFlow::<Never>::Continue(());
}

let has_lint = params.filter.categories.contains(RuleCategories::LINT);
diagnostic_count += 1;

// We do now check if the severity of the diagnostics should be changed.
// The configuration allows to change the severity of the diagnostics emitted by rules.
let severity = diagnostic
.category()
.filter(|category| category.name().starts_with("lint/"))
.map(|category| {
params
.rules
.and_then(|rules| rules.get_severity_from_code(category))
.unwrap_or(Severity::Warning)
})
.unwrap_or_else(|| diagnostic.severity());

if severity >= Severity::Error {
errors += 1;
}

info!("Analyze file {}", params.path.display());
let (_, analyze_diagnostics) = analyze(
&tree,
params.filter,
&analyzer_options,
file_source,
|signal| {
if let Some(mut diagnostic) = signal.diagnostic() {
// Do not report unused suppression comment diagnostics if this is a syntax-only analyzer pass
if !has_lint && diagnostic.category() == Some(category!("suppressions/unused")) {
return ControlFlow::<Never>::Continue(());
}
if diagnostic_count <= params.max_diagnostics {
for action in signal.actions() {
if !action.is_suppression() {
diagnostic = diagnostic.add_code_suggestion(action.into());
}
}

diagnostic_count += 1;

// We do now check if the severity of the diagnostics should be changed.
// The configuration allows to change the severity of the diagnostics emitted by rules.
let severity = diagnostic
.category()
.filter(|category| category.name().starts_with("lint/"))
.map(|category| {
params
.rules
.and_then(|rules| rules.get_severity_from_code(category))
.unwrap_or(Severity::Warning)
})
.unwrap_or_else(|| diagnostic.severity());

if severity >= Severity::Error {
errors += 1;
}
let error = diagnostic.with_severity(severity);

if diagnostic_count <= params.max_diagnostics {
for action in signal.actions() {
if !action.is_suppression() {
diagnostic = diagnostic.add_code_suggestion(action.into());
diagnostics.push(biome_diagnostics::serde::Diagnostic::new(error));
}
}

let error = diagnostic.with_severity(severity);

diagnostics.push(biome_diagnostics::serde::Diagnostic::new(error));
}
ControlFlow::<Never>::Continue(())
},
);

diagnostics.extend(
analyze_diagnostics
.into_iter()
.map(biome_diagnostics::serde::Diagnostic::new)
.collect::<Vec<_>>(),
);
let skipped_diagnostics = diagnostic_count.saturating_sub(diagnostics.len() as u64);

LintResults {
diagnostics,
errors,
skipped_diagnostics,
}

ControlFlow::<Never>::Continue(())
},
);

diagnostics.extend(
analyze_diagnostics
.into_iter()
.map(biome_diagnostics::serde::Diagnostic::new)
.collect::<Vec<_>>(),
);
let skipped_diagnostics = diagnostic_count.saturating_sub(diagnostics.len() as u64);

LintResults {
diagnostics,
errors,
skipped_diagnostics,
}
})
}

struct ActionsVisitor<'a> {
Expand Down Expand Up @@ -380,7 +392,7 @@ impl RegistryVisitor<JsLanguage> for ActionsVisitor<'_> {
}
}

#[tracing::instrument(level = "trace", skip(parse))]
#[tracing::instrument(level = "debug", skip(parse, settings))]
fn code_actions(
parse: AnyParse,
range: TextRange,
Expand Down Expand Up @@ -555,7 +567,7 @@ fn fix_all(params: FixAllParams) -> Result<FixFileResult, WorkspaceError> {
}
}

#[tracing::instrument(level = "trace", skip(parse))]
#[tracing::instrument(level = "trace", skip(parse, settings))]
fn format(
rome_path: &RomePath,
parse: AnyParse,
Expand All @@ -576,7 +588,7 @@ fn format(
}
}
}
#[tracing::instrument(level = "trace", skip(parse))]
#[tracing::instrument(level = "trace", skip(parse, settings))]
fn format_range(
rome_path: &RomePath,
parse: AnyParse,
Expand All @@ -590,7 +602,7 @@ fn format_range(
Ok(printed)
}

#[tracing::instrument(level = "trace", skip(parse))]
#[tracing::instrument(level = "trace", skip(parse, settings))]
fn format_on_type(
rome_path: &RomePath,
parse: AnyParse,
Expand Down
Loading

0 comments on commit a2195b7

Please sign in to comment.