Skip to content

Commit

Permalink
Add LSP option to hide compiler warnings and errors (FuelLabs#3749)
Browse files Browse the repository at this point in the history
Closes FuelLabs#3745

Co-authored-by: Joshua Batty <[email protected]>
  • Loading branch information
sdankel and JoshuaBatty authored Jan 11, 2023
1 parent 5b04a8d commit 2930f48
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 29 deletions.
28 changes: 19 additions & 9 deletions sway-lsp/src/capabilities/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,35 @@ use sway_error::error::CompileError;
use sway_error::warning::CompileWarning;
use sway_types::{LineCol, Spanned};

pub fn get_diagnostics(warnings: &[CompileWarning], errors: &[CompileError]) -> Vec<Diagnostic> {
let errors = errors.iter().map(|error| Diagnostic {
#[derive(Debug)]
pub struct Diagnostics {
pub warnings: Vec<Diagnostic>,
pub errors: Vec<Diagnostic>,
}

fn get_error_diagnostics(errors: &[CompileError]) -> Vec<Diagnostic> {
Vec::from_iter(errors.iter().map(|error| Diagnostic {
range: get_range(error.span().line_col()),
severity: Some(DiagnosticSeverity::ERROR),
message: format!("{}", error),
..Default::default()
});
}))
}

let warnings = warnings.iter().map(|warning| Diagnostic {
fn get_warning_diagnostics(warnings: &[CompileWarning]) -> Vec<Diagnostic> {
Vec::from_iter(warnings.iter().map(|warning| Diagnostic {
range: get_range(warning.span().line_col()),
severity: Some(DiagnosticSeverity::WARNING),
message: warning.to_friendly_warning_string(),
..Default::default()
});
}))
}

let mut all = Vec::with_capacity(errors.len() + warnings.len());
all.extend(errors);
all.extend(warnings);
all
pub fn get_diagnostics(warnings: &[CompileWarning], errors: &[CompileError]) -> Diagnostics {
Diagnostics {
warnings: get_warning_diagnostics(warnings),
errors: get_error_diagnostics(errors),
}
}

fn get_range((start, end): (LineCol, LineCol)) -> Range {
Expand Down
19 changes: 19 additions & 0 deletions sway-lsp/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ pub struct Config {
pub logging: LoggingConfig,
#[serde(default)]
pub inlay_hints: InlayHintsConfig,
#[serde(default)]
pub diagnostic: DiagnosticConfig,
#[serde(default, skip_serializing)]
trace: TraceConfig,
}
Expand All @@ -24,6 +26,23 @@ pub struct DebugConfig {
pub show_collected_tokens_as_warnings: Warnings,
}

// Options for displaying compiler diagnostics
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DiagnosticConfig {
pub show_warnings: bool,
pub show_errors: bool,
}

impl Default for DiagnosticConfig {
fn default() -> Self {
Self {
show_warnings: true,
show_errors: true,
}
}
}

#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct LoggingConfig {
#[serde(with = "LevelFilterDef")]
Expand Down
20 changes: 10 additions & 10 deletions sway-lsp/src/core/session.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
capabilities::{
self,
diagnostic::{get_diagnostics, Diagnostics},
formatting::get_page_text_edit,
runnable::{Runnable, RunnableType},
},
Expand Down Expand Up @@ -31,8 +32,8 @@ use sway_core::{
use sway_types::Spanned;
use sway_utils::helpers::get_sway_files;
use tower_lsp::lsp_types::{
CompletionItem, Diagnostic, GotoDefinitionResponse, Location, Position, Range,
SymbolInformation, TextDocumentContentChangeEvent, TextEdit, Url,
CompletionItem, GotoDefinitionResponse, Location, Position, Range, SymbolInformation,
TextDocumentContentChangeEvent, TextEdit, Url,
};

pub type Documents = DashMap<String, TextDocument>;
Expand Down Expand Up @@ -109,7 +110,7 @@ impl Session {
&self.token_map
}

pub fn parse_project(&self, uri: &Url) -> Result<Vec<Diagnostic>, LanguageServerError> {
pub fn parse_project(&self, uri: &Url) -> Result<Diagnostics, LanguageServerError> {
self.token_map.clear();
self.runnables.clear();

Expand Down Expand Up @@ -141,7 +142,10 @@ impl Session {
pkg::BuildPlan::from_lock_and_manifests(&lock_path, &member_manifests, locked, offline)
.map_err(LanguageServerError::BuildPlanFailed)?;

let mut diagnostics = Vec::new();
let mut diagnostics = Diagnostics {
warnings: vec![],
errors: vec![],
};
let type_engine = &*self.type_engine.read();
let declaration_engine = &*self.declaration_engine.read();
let engines = Engines::new(type_engine, declaration_engine);
Expand Down Expand Up @@ -189,8 +193,7 @@ impl Session {
self.save_parsed_program(parsed.to_owned().clone());
self.save_typed_program(typed_program.to_owned().clone());

diagnostics =
capabilities::diagnostic::get_diagnostics(&ast_res.warnings, &ast_res.errors);
diagnostics = get_diagnostics(&ast_res.warnings, &ast_res.errors);
} else {
// Collect tokens from dependencies and the standard library prelude.
let dependency = Dependency::new(&self.token_map);
Expand Down Expand Up @@ -363,10 +366,7 @@ impl Session {
.value
.as_ref()
.ok_or(LanguageServerError::FailedToParse {
diagnostics: capabilities::diagnostic::get_diagnostics(
&ast_res.warnings,
&ast_res.errors,
),
diagnostics: get_diagnostics(&ast_res.warnings, &ast_res.errors),
})
}

Expand Down
5 changes: 3 additions & 2 deletions sway-lsp/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use swayfmt::FormatterError;
use thiserror::Error;
use tower_lsp::lsp_types::Diagnostic;

use crate::capabilities::diagnostic::Diagnostics;

#[derive(Debug, Error)]
pub enum LanguageServerError {
Expand All @@ -16,7 +17,7 @@ pub enum LanguageServerError {
#[error("Failed to compile. {0}")]
FailedToCompile(anyhow::Error),
#[error("Failed to parse document")]
FailedToParse { diagnostics: Vec<Diagnostic> },
FailedToParse { diagnostics: Diagnostics },
#[error("Error formatting document: {0}")]
FormatError(FormatterError),
}
Expand Down
30 changes: 22 additions & 8 deletions sway-lsp/src/server.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use crate::error::DocumentError;
use crate::{
capabilities,
capabilities::{self, diagnostic::Diagnostics},
config::{Config, Warnings},
core::{session::Session, sync},
error::{DirectoryError, LanguageServerError},
Expand Down Expand Up @@ -67,7 +67,10 @@ impl Backend {
if let LanguageServerError::FailedToParse { diagnostics } = err {
diagnostics
} else {
vec![]
Diagnostics {
warnings: vec![],
errors: vec![],
}
}
}
};
Expand Down Expand Up @@ -145,20 +148,31 @@ impl Backend {
uri: &Url,
workspace_uri: &Url,
session: Arc<Session>,
diagnostics: Vec<Diagnostic>,
diagnostics: Diagnostics,
) {
let diagnostics_res = {
let debug = &self.config.read().debug;
let mut diagnostics_to_publish = vec![];
let config = &self.config.read();
let tokens = session.token_map().tokens_for_file(uri);
match debug.show_collected_tokens_as_warnings {
Warnings::Default => diagnostics,
match config.debug.show_collected_tokens_as_warnings {
// If collected_tokens_as_warnings is Parsed or Typed,
// take over the normal error and warning display behavior
// and instead show the either the parsed or typed tokens as warnings.
// This is useful for debugging the lsp parser.
Warnings::Parsed => debug::generate_warnings_for_parsed_tokens(tokens),
Warnings::Typed => debug::generate_warnings_for_typed_tokens(tokens),
Warnings::Parsed => diagnostics_to_publish
.extend(debug::generate_warnings_for_parsed_tokens(tokens)),
Warnings::Typed => {
diagnostics_to_publish.extend(debug::generate_warnings_for_typed_tokens(tokens))
}
Warnings::Default => {}
}
if config.diagnostic.show_warnings {
diagnostics_to_publish.extend(diagnostics.warnings);
}
if config.diagnostic.show_errors {
diagnostics_to_publish.extend(diagnostics.errors);
}
diagnostics_to_publish
};

// Note: Even if the computed diagnostics vec is empty, we still have to push the empty Vec
Expand Down

0 comments on commit 2930f48

Please sign in to comment.