Skip to content

Commit 2f6df3f

Browse files
committed
fnl: typo
1 parent e1e84c6 commit 2f6df3f

File tree

12 files changed

+88
-29
lines changed

12 files changed

+88
-29
lines changed

bin/src/modules/fnl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct FineNewLineCheck {}
1717

1818
impl Module for FineNewLineCheck {
1919
fn name(&self) -> &'static str {
20-
"Fine New Line Check"
20+
"Final New Line Check"
2121
}
2222

2323
fn check(&self, ctx: &Context) -> Result<Report, crate::Error> {

hls/src/config/lints.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use tracing::{debug, warn};
1111
use url::Url;
1212

1313
use crate::{
14+
config::ConfigAnalyzer,
1415
diag_manager::DiagManager,
1516
preprocessor::PreprocessorAnalyzer,
1617
workspace::{EditorWorkspace, EditorWorkspaces},
@@ -85,6 +86,20 @@ async fn check_addon(source: WorkspacePath, workspace: EditorWorkspace) {
8586
lsp_diags.entry(file).or_insert_with(Vec::new).push(diag);
8687
}
8788
}
89+
let config_analyzer = ConfigAnalyzer::get();
90+
config_analyzer.functions_defined.insert(
91+
{
92+
// `/folder/addon/blah` => addon
93+
let parts: Vec<&str> = source.as_str().split('/').collect();
94+
if parts.len() < 3 {
95+
warn!("Invalid config path: {}", source.as_str());
96+
parts[1].to_string()
97+
} else {
98+
parts[2].to_string()
99+
}
100+
},
101+
report.functions_defined().clone(),
102+
);
88103
}
89104
Err(err) => {
90105
warn!("failed to process config: {:?}", err);

hls/src/config/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
use std::sync::LazyLock;
1+
use std::sync::{Arc, LazyLock};
22

3+
use dashmap::DashMap;
4+
use hemtt_workspace::addons::DefinedFunctions;
35
use tower_lsp::Client;
46
use url::Url;
57

@@ -8,11 +10,15 @@ use crate::workspace::EditorWorkspace;
810
mod lints;
911

1012
#[derive(Clone)]
11-
pub struct ConfigAnalyzer {}
13+
pub struct ConfigAnalyzer {
14+
pub(crate) functions_defined: Arc<DashMap<String, DefinedFunctions>>,
15+
}
1216

1317
impl ConfigAnalyzer {
1418
pub fn get() -> Self {
15-
static SINGLETON: LazyLock<ConfigAnalyzer> = LazyLock::new(|| ConfigAnalyzer {});
19+
static SINGLETON: LazyLock<ConfigAnalyzer> = LazyLock::new(|| ConfigAnalyzer {
20+
functions_defined: Arc::new(DashMap::new()),
21+
});
1622
(*SINGLETON).clone()
1723
}
1824

hls/src/main.rs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::workspace::EditorWorkspaces;
1515

1616
mod audio;
1717
mod color;
18+
mod completion;
1819
mod config;
1920
mod diag_manager;
2021
mod files;
@@ -59,6 +60,19 @@ impl LanguageServer for Backend {
5960
work_done_progress: None,
6061
},
6162
}),
63+
completion_provider: Some(CompletionOptions {
64+
resolve_provider: Some(false),
65+
trigger_characters: Some(vec![
66+
"(".to_string(),
67+
",".to_string(),
68+
"\\".to_string(),
69+
]),
70+
all_commit_characters: None,
71+
work_done_progress_options: WorkDoneProgressOptions {
72+
work_done_progress: None,
73+
},
74+
completion_item: None,
75+
}),
6276
definition_provider: Some(OneOf::Left(true)),
6377
color_provider: Some(ColorProviderCapability::Options(
6478
StaticTextDocumentColorProviderOptions {
@@ -110,7 +124,6 @@ impl LanguageServer for Backend {
110124
}
111125

112126
async fn did_change_watched_files(&self, params: DidChangeWatchedFilesParams) {
113-
debug!("did_change_watched_files");
114127
for x in params.changes {
115128
if x.uri.path().contains(".toml") {
116129
ConfigAnalyzer::get()
@@ -124,7 +137,6 @@ impl LanguageServer for Backend {
124137
}
125138

126139
async fn did_open(&self, params: DidOpenTextDocumentParams) {
127-
debug!("did_open: {:?}", params.text_document.uri);
128140
let document = TextDocumentItem {
129141
uri: params.text_document.uri.clone(),
130142
text: TextInformation::Full(&params.text_document.text),
@@ -151,7 +163,6 @@ impl LanguageServer for Backend {
151163
}
152164

153165
async fn did_save(&self, params: DidSaveTextDocumentParams) {
154-
debug!("did_save: {:?}", params.text_document.uri);
155166
ConfigAnalyzer::get()
156167
.on_save(params.text_document.uri.clone(), self.client.clone())
157168
.await;
@@ -170,7 +181,6 @@ impl LanguageServer for Backend {
170181
}
171182

172183
async fn did_close(&self, params: DidCloseTextDocumentParams) {
173-
debug!("did_close: {:?}", params.text_document.uri);
174184
FileCache::get().on_close(&params.text_document.uri).await;
175185
SqfAnalyzer::get().on_close(&params.text_document.uri).await;
176186
PreprocessorAnalyzer::get()
@@ -208,6 +218,16 @@ impl LanguageServer for Backend {
208218
) -> Result<Vec<ColorPresentation>> {
209219
color::presentation(params).await
210220
}
221+
222+
async fn completion(&self, params: CompletionParams) -> Result<Option<CompletionResponse>> {
223+
let uri = &params.text_document_position.text_document.uri;
224+
let (_, ext) = uri.path().rsplit_once('.').unwrap_or((uri.path(), ""));
225+
let ext = ext.to_lowercase();
226+
if ["sqf", "ext", "cpp", "hpp", "inc"].contains(&ext.as_str()) {
227+
return completion::completion(params.text_document_position, params.context).await;
228+
}
229+
Ok(None)
230+
}
211231
}
212232

213233
impl Backend {

hls/src/preprocessor/signature.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ use hemtt_workspace::reporting::Definition;
22
use tower_lsp::lsp_types::{
33
ParameterInformation, ParameterLabel, SignatureHelp, SignatureHelpParams, SignatureInformation,
44
};
5-
use tracing::{debug, warn};
5+
use tracing::warn;
66

77
use crate::{files::FileCache, workspace::EditorWorkspaces};
88

99
use super::PreprocessorAnalyzer;
1010

1111
impl PreprocessorAnalyzer {
1212
pub async fn signature_help(&self, params: &SignatureHelpParams) -> Option<SignatureHelp> {
13-
debug!("signature_help: {:?}", params);
1413
let url = &params.text_document_position_params.text_document.uri;
1514
let path = url.to_file_path().ok()?;
1615
#[derive(Debug, PartialEq, Eq)]

hls/src/sqf/lints.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ impl Cache {
4141
async fn check_addons(workspace: EditorWorkspace, database: Arc<Database>, client: Client) {
4242
debug!("sqf: checking addons");
4343
let mut futures = JoinSet::new();
44+
let mut next_addons = Vec::new();
4445
for addon in workspace.root().addons() {
4546
let Ok(source) = workspace.root().join(addon.as_str()) else {
4647
warn!("failed to join addon {:?}", addon);
@@ -68,6 +69,7 @@ async fn check_addons(workspace: EditorWorkspace, database: Arc<Database>, clien
6869
));
6970
}
7071
}
72+
next_addons.push(addon);
7173
}
7274
tokio::spawn(async move {
7375
futures.join_all().await;
@@ -104,13 +106,24 @@ async fn check_sqf(
104106
let workspace_files = WorkspaceFiles::new();
105107
match hemtt_sqf::parser::run(&database, &processed) {
106108
Ok(sqf) => {
107-
let (codes, _) = hemtt_sqf::analyze::analyze(
109+
let (codes, report) = hemtt_sqf::analyze::analyze(
108110
&sqf,
109111
workspace.config().as_ref(),
110112
&processed,
111-
addon,
113+
addon.clone(),
112114
database,
113115
);
116+
if let Some(report) = report {
117+
let cache = SqfAnalyzer::get();
118+
let mut functions_defined = cache
119+
.functions_defined
120+
.entry(addon.name().to_string())
121+
.or_insert_with(HashMap::new);
122+
functions_defined.insert(
123+
source.as_str().to_string(),
124+
report.functions_defined().clone(),
125+
);
126+
}
114127
for code in codes {
115128
let Some(diag) = code.diagnostic() else {
116129
warn!("failed to get diagnostic");

hls/src/sqf/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ mod compiled;
22
mod hover;
33
mod lints;
44

5-
use std::sync::{Arc, LazyLock};
5+
use std::{
6+
collections::HashMap,
7+
sync::{Arc, LazyLock},
8+
};
69

710
use dashmap::DashMap;
811
use hemtt_sqf::parser::database::Database;
9-
use hemtt_workspace::reporting::Token;
12+
use hemtt_workspace::{addons::DefinedFunctions, reporting::Token};
1013
use tower_lsp::Client;
1114
use tracing::{error, warn};
1215
use url::Url;
@@ -21,13 +24,15 @@ use crate::{
2124
pub struct SqfAnalyzer {
2225
tokens: Arc<DashMap<Url, Vec<Arc<Token>>>>,
2326
databases: Arc<DashMap<EditorWorkspace, Arc<Database>>>,
27+
pub(crate) functions_defined: Arc<DashMap<String, HashMap<String, DefinedFunctions>>>,
2428
}
2529

2630
impl SqfAnalyzer {
2731
pub fn get() -> Self {
2832
static SINGLETON: LazyLock<SqfAnalyzer> = LazyLock::new(|| SqfAnalyzer {
2933
tokens: Arc::new(DashMap::new()),
3034
databases: Arc::new(DashMap::new()),
35+
functions_defined: Arc::new(DashMap::new()),
3136
});
3237
(*SINGLETON).clone()
3338
}

libs/config/src/analyze/lints/collect_cfgfunctions.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ impl LintRunner<LintData> for Runner {
7676
for function in properties_category {
7777
let Property::Class(func_class) = function else { continue };
7878
let Some(class_name) = func_class.name() else { continue; };
79-
let func_name = format!("{prefix_real}_fnc_{}",class_name.as_str()).to_lowercase();
79+
let func_name = format!("{prefix_real}_fnc_{}",class_name.as_str());
80+
let func_name_lower = func_name.to_lowercase();
8081
let mut functions_defined = data.functions_defined.lock().expect("mutex safety");
81-
functions_defined.insert(func_name);
82+
functions_defined.insert((func_name_lower, func_name.into()));
8283
}
8384
}
8485
}

libs/config/tests/lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ fn test_c09_magwell_missing_magazine() {
8383
#[test]
8484
fn test_collect_cfgfunctions() {
8585
let (_, report) = lint(stringify!(collect_cfgfunctions));
86-
let mut functions_defined: Vec<&String> = report.functions_defined().iter().collect();
86+
let mut functions_defined: Vec<&String> = report.functions_defined().iter().map(|(s, _)| s).collect();
8787
functions_defined.sort();
8888
insta::assert_compact_debug_snapshot!(functions_defined);
8989
}

libs/sqf/src/analyze/lints/s29_function_undefined.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ impl LintRunner<LintData> for RunnerExpression {
133133
return vec![];
134134
}
135135
};
136-
let func_name = func_name.to_lowercase();
137-
if is_project_func(&func_name, project) {
136+
let func_name_lower = func_name.to_lowercase();
137+
if is_project_func(&func_name_lower, project) {
138138
let mut functions_defined =
139139
data.functions_defined.lock().expect("mutex safety");
140-
functions_defined.insert(func_name);
140+
functions_defined.insert((func_name_lower, func_name.clone()));
141141
}
142142
}
143143
_ => {}
@@ -167,10 +167,10 @@ impl LintRunner<LintData> for RunnerStatement {
167167
let Statement::AssignGlobal(func_name, _, _) = target else {
168168
return Vec::new();
169169
};
170-
let func_name = func_name.to_lowercase();
171-
if is_project_func(&func_name, project) {
170+
let func_name_lower = func_name.to_lowercase();
171+
if is_project_func(&func_name_lower, project) {
172172
let mut functions_defined = data.functions_defined.lock().expect("mutex safety");
173-
functions_defined.insert(func_name);
173+
functions_defined.insert((func_name_lower, func_name.clone().into()));
174174
}
175175

176176
vec![]
@@ -206,7 +206,7 @@ impl LintRunner<LintData> for RunnerFinal {
206206
if let Some(toml::Value::Array(ignore)) = config.option("ignore") {
207207
for i in ignore {
208208
if let Value::String(i) = i {
209-
all_defined.insert(i.to_lowercase());
209+
all_defined.insert((i.to_lowercase(), i.clone().into()));
210210
}
211211
}
212212
}
@@ -220,14 +220,14 @@ impl LintRunner<LintData> for RunnerFinal {
220220
.expect("not juliet")
221221
.clone();
222222
for (func, position, start, end, file) in used {
223-
if !all_defined.contains(&func) {
223+
if !all_defined.iter().any(|(s, _)| s == &func) {
224224
all_missing.entry(func).or_insert(Vec::new()).push((position, start, end, file));
225225
}
226226
}
227227
}
228228

229229
for (func, positions) in all_missing {
230-
let similar = similar_values(&func, &all_defined.iter().map(std::string::String::as_str).collect::<Vec<_>>())
230+
let similar = similar_values(&func, &all_defined.iter().map(|(s, _)| s.as_str()).collect::<Vec<_>>())
231231
.into_iter()
232232
.map(std::string::ToString::to_string)
233233
.collect();

0 commit comments

Comments
 (0)