Skip to content

Commit 7534ebc

Browse files
committed
refactor diagnostic system
1 parent cde210f commit 7534ebc

File tree

6 files changed

+69
-108
lines changed

6 files changed

+69
-108
lines changed

crates/code_analysis/src/db_index/diagnostic/analyze_error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rowan::TextRange;
22

33
use crate::DiagnosticCode;
44

5-
#[derive(Debug)]
5+
#[derive(Debug, Clone)]
66
pub struct AnalyzeError {
77
pub kind: DiagnosticCode,
88
pub message: String,
Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,21 @@
11
use crate::DiagnosticCode;
22

3-
use super::{DiagnosticContext, LuaChecker};
3+
use super::DiagnosticContext;
44

5-
const CODES: &[DiagnosticCode] = &[DiagnosticCode::TypeNotFound, DiagnosticCode::DuplicateType];
5+
pub const CODES: &[DiagnosticCode] = &[DiagnosticCode::TypeNotFound, DiagnosticCode::DuplicateType];
66

7-
#[derive(Debug)]
8-
pub struct Checker();
9-
10-
impl LuaChecker for Checker {
11-
fn check(&self, context: &mut DiagnosticContext) -> Option<()> {
12-
let errors = {
13-
let db = context.get_db();
14-
let file_id = context.get_file_id();
15-
let diagnostic_index = db.get_diagnostic_index();
16-
let errors = diagnostic_index.get_diagnostics(file_id)?;
17-
let mut analyze_errs = Vec::new();
18-
for error in errors {
19-
if error.kind == DiagnosticCode::TypeNotFound {
20-
analyze_errs.push((error.message.clone(), error.range.clone()));
21-
}
22-
}
23-
24-
analyze_errs
25-
};
26-
27-
for analyze_err in errors {
28-
context.add_diagnostic(
29-
DiagnosticCode::TypeNotFound,
30-
analyze_err.1,
31-
analyze_err.0,
32-
None,
33-
);
34-
}
35-
Some(())
7+
pub fn check(context: &mut DiagnosticContext) -> Option<()> {
8+
let db = context.get_db();
9+
let file_id = context.get_file_id();
10+
let diagnostic_index = db.get_diagnostic_index();
11+
let errors: Vec<_> = diagnostic_index
12+
.get_diagnostics(file_id)?
13+
.iter()
14+
.map(|e| e.clone())
15+
.collect();
16+
for error in errors {
17+
context.add_diagnostic(error.kind, error.range, error.message, None);
3618
}
3719

38-
fn support_codes(&self) -> &[DiagnosticCode] {
39-
CODES
40-
}
20+
Some(())
4121
}

crates/code_analysis/src/diagnostic/checker/mod.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,33 @@
1-
mod syntax_error;
21
mod analyze_error;
2+
mod syntax_error;
33

44
use lsp_types::{Diagnostic, DiagnosticSeverity, DiagnosticTag, NumberOrString};
55
use rowan::TextRange;
6-
use std::{collections::HashSet, fmt::Debug, sync::Arc};
6+
use std::{collections::HashSet, sync::Arc};
77

88
use crate::{db_index::DbIndex, semantic::SemanticModel, FileId};
99

10-
use super::{lua_diagnostic_code::{get_default_severity, is_code_default_enable}, DiagnosticCode};
11-
12-
pub trait LuaChecker: Debug + Send + Sync {
13-
fn check(&self, context: &mut DiagnosticContext) -> Option<()>;
14-
15-
fn support_codes(&self) -> &[DiagnosticCode];
16-
}
10+
use super::{
11+
lua_diagnostic_code::{get_default_severity, is_code_default_enable},
12+
DiagnosticCode,
13+
};
14+
15+
pub fn check_file(context: &mut DiagnosticContext) -> Option<()> {
16+
macro_rules! check {
17+
($module:ident) => {
18+
if $module::CODES
19+
.iter()
20+
.any(|code| context.is_checker_enable_by_code(code))
21+
{
22+
$module::check(context);
23+
}
24+
};
25+
}
1726

18-
macro_rules! checker {
19-
($name:ident) => {
20-
Box::new($name::Checker())
21-
};
22-
}
27+
check!(syntax_error);
28+
check!(analyze_error);
2329

24-
pub fn init_checkers() -> Vec<Box<dyn LuaChecker>> {
25-
vec![
26-
checker!(syntax_error),
27-
checker!(analyze_error),
28-
]
30+
Some(())
2931
}
3032

3133
pub struct DiagnosticContext<'a> {
@@ -45,7 +47,7 @@ impl<'a> DiagnosticContext<'a> {
4547
semantic_model,
4648
diagnostics: Vec::new(),
4749
workspace_disabled,
48-
workspace_enabled
50+
workspace_enabled,
4951
}
5052
}
5153

@@ -64,6 +66,10 @@ impl<'a> DiagnosticContext<'a> {
6466
message: String,
6567
data: Option<serde_json::Value>,
6668
) {
69+
if !self.is_checker_enable_by_code(&code) {
70+
return;
71+
}
72+
6773
if !self.should_report_diagnostic(&code, &range) {
6874
return;
6975
}
@@ -132,10 +138,7 @@ impl<'a> DiagnosticContext<'a> {
132138
self.diagnostics
133139
}
134140

135-
pub fn is_checker_enable_by_code(
136-
&self,
137-
code: &DiagnosticCode,
138-
) -> bool {
141+
pub fn is_checker_enable_by_code(&self, code: &DiagnosticCode) -> bool {
139142
let file_id = self.get_file_id();
140143
let db = self.get_db();
141144
let diagnostic_index = db.get_diagnostic_index();
Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,21 @@
11
use crate::DiagnosticCode;
22

3-
use super::{DiagnosticContext, LuaChecker};
3+
use super::DiagnosticContext;
44

5-
const CODES: &[DiagnosticCode] = &[DiagnosticCode::SyntaxError];
5+
pub const CODES: &[DiagnosticCode] = &[DiagnosticCode::SyntaxError];
66

7-
#[derive(Debug)]
8-
pub struct Checker();
9-
10-
impl LuaChecker for Checker {
11-
fn check(&self, context: &mut DiagnosticContext) -> Option<()> {
12-
let semantic_model = &context.semantic_model;
13-
if let Some(parse_errors) = semantic_model.get_file_parse_error() {
14-
for parse_error in parse_errors {
15-
context.add_diagnostic(
16-
DiagnosticCode::SyntaxError,
17-
parse_error.1,
18-
parse_error.0,
19-
None,
20-
);
21-
}
7+
pub fn check(context: &mut DiagnosticContext) -> Option<()> {
8+
let semantic_model = &context.semantic_model;
9+
if let Some(parse_errors) = semantic_model.get_file_parse_error() {
10+
for parse_error in parse_errors {
11+
context.add_diagnostic(
12+
DiagnosticCode::SyntaxError,
13+
parse_error.1,
14+
parse_error.0,
15+
None,
16+
);
2217
}
23-
24-
Some(())
2518
}
2619

27-
fn support_codes(&self) -> &[DiagnosticCode] {
28-
CODES
29-
}
20+
Some(())
3021
}

crates/code_analysis/src/diagnostic/lua_diagnostic.rs

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
use std::{collections::HashSet, sync::Arc};
22

3-
pub use super::checker::{DiagnosticContext, LuaChecker};
4-
use super::{checker::init_checkers, DiagnosticCode};
3+
pub use super::checker::DiagnosticContext;
4+
use super::{checker::check_file, DiagnosticCode};
55
use crate::{Emmyrc, FileId, LuaCompilation};
66
use lsp_types::Diagnostic;
77
use tokio_util::sync::CancellationToken;
88

99
#[derive(Debug)]
1010
pub struct LuaDiagnostic {
11-
checkers: Vec<Box<dyn LuaChecker>>,
1211
enable: bool,
1312
workspace_enabled: Arc<HashSet<DiagnosticCode>>,
1413
workspace_disabled: Arc<HashSet<DiagnosticCode>>,
@@ -17,17 +16,12 @@ pub struct LuaDiagnostic {
1716
impl LuaDiagnostic {
1817
pub fn new() -> Self {
1918
Self {
20-
checkers: init_checkers(),
2119
enable: true,
2220
workspace_enabled: HashSet::new().into(),
2321
workspace_disabled: HashSet::new().into(),
2422
}
2523
}
2624

27-
pub fn add_checker(&mut self, checker: Box<dyn LuaChecker>) {
28-
self.checkers.push(checker);
29-
}
30-
3125
pub fn update_config(&mut self, emmyrc: Arc<Emmyrc>) {
3226
self.enable = emmyrc.diagnostics.enable;
3327
self.workspace_disabled = Arc::new(emmyrc.diagnostics.disable.iter().cloned().collect());
@@ -44,27 +38,18 @@ impl LuaDiagnostic {
4438
return None;
4539
}
4640

41+
if cancel_token.is_cancelled() {
42+
return None;
43+
}
44+
4745
let model = compilation.get_semantic_model(file_id)?;
4846
let mut context = DiagnosticContext::new(
4947
model,
5048
self.workspace_enabled.clone(),
5149
self.workspace_disabled.clone(),
5250
);
53-
for checker in &self.checkers {
54-
if cancel_token.is_cancelled() {
55-
return None;
56-
}
57-
58-
let codes = checker.support_codes();
59-
let can_check = codes
60-
.iter()
61-
.any(|code| context.is_checker_enable_by_code(code));
62-
if !can_check {
63-
continue;
64-
}
6551

66-
checker.check(&mut context);
67-
}
52+
check_file(&mut context);
6853

6954
Some(context.get_diagnostics())
7055
}

crates/emmylua_ls/src/handlers/defination/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ mod goto_def_defination;
22
mod goto_doc_see;
33
mod goto_module_file;
44

5-
use emmylua_parser::{LuaAstNode, LuaAstToken, LuaDocTagSee, LuaNameToken, LuaStringToken, LuaTokenKind};
5+
use emmylua_parser::{
6+
LuaAstNode, LuaAstToken, LuaDocTagSee, LuaNameToken, LuaStringToken, LuaTokenKind,
7+
};
68
use goto_def_defination::goto_def_defination;
79
use goto_doc_see::goto_doc_see;
810
use goto_module_file::goto_module_file;
@@ -54,16 +56,16 @@ pub async fn on_goto_defination_handler(
5456
if let Some(module_response) = goto_module_file(&semantic_model, string_token) {
5557
return Some(module_response);
5658
}
57-
let document = semantic_model.get_document();
58-
let lsp_location = document.to_lsp_location(token.text_range())?;
59-
return Some(GotoDefinitionResponse::Scalar(lsp_location));
6059
} else if let Some(name_token) = LuaNameToken::cast(token.clone()) {
6160
if let Some(doc_see) = name_token.get_parent::<LuaDocTagSee>() {
6261
return goto_doc_see(&semantic_model, doc_see, name_token);
6362
}
6463
}
6564

66-
None
65+
// goto self
66+
let document = semantic_model.get_document();
67+
let lsp_location = document.to_lsp_location(token.text_range())?;
68+
Some(GotoDefinitionResponse::Scalar(lsp_location))
6769
}
6870

6971
pub fn register_capabilities(

0 commit comments

Comments
 (0)