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
29 changes: 8 additions & 21 deletions bin/src/modules/rapifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use std::{collections::HashMap, path::PathBuf, sync::RwLock};
use hemtt_config::{
Config,
analyze::{lint_all, lint_check},
parse,
rapify::Rapify,
};
use hemtt_workspace::{
WorkspacePath,
addons::{Addon, Location},
reporting::CodesExt,
};
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
use vfs::VfsFileType;
Expand Down Expand Up @@ -124,29 +124,16 @@ pub fn rapify(addon: &Addon, path: &WorkspacePath, ctx: &Context) -> Result<Repo
return Err(e.into());
}
};
for warning in processed.warnings() {
report.push(warning.clone());
let checked = hemtt_config::check::check(&processed, Some(ctx.config()));
let had_errors = checked.codes.failed();
for code in checked.codes {
report.push(code);
}
let configreport = match parse(Some(ctx.config()), &processed) {
Ok(configreport) => configreport,
Err(errors) => {
for e in &errors {
report.push(e.clone());
}
return Ok(report);
}
let Some(configreport) = checked.config else {
return Ok(report);
};
configreport.push_to_addon(addon);
configreport.notes_and_helps().into_iter().for_each(|e| {
report.push(e.clone());
});
configreport.warnings().into_iter().for_each(|e| {
report.push(e.clone());
});
configreport.errors().into_iter().for_each(|e| {
report.push(e.clone());
});
if !configreport.errors().is_empty() {
if had_errors {
return Ok(report);
}
let out = if std::path::Path::new(&path.filename())
Expand Down
62 changes: 20 additions & 42 deletions bin/src/modules/sqf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::sync::Arc;

use hemtt_common::version::Version;
use hemtt_sqf::{
analyze::{analyze, lint_all, lint_check},
parser::{ParserError, database::Database},
analyze::{lint_all, lint_check},
parser::database::Database,
};
use hemtt_workspace::reporting::{Code, CodesExt, Diagnostic, Severity};
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
Expand Down Expand Up @@ -90,48 +90,26 @@ impl Module for SQFCompiler {
return Err(e.into());
}
};
for warning in processed.warnings() {
report.push(warning.clone());
let checked = hemtt_sqf::check::check(
&processed,
Some(ctx.config()),
addon,
database.clone(),
);
if let Some(sqf_report) = checked.report {
sqf_report.push_to_addon(addon);
}
match hemtt_sqf::parser::run(&database, &processed) {
Ok(sqf) => {
let (codes, sqf_report) = analyze(
&sqf,
Some(ctx.config()),
&processed,
addon.clone(),
database.clone(),
);
if let Some(sqf_report) = sqf_report {
sqf_report.push_to_addon(addon);
}
if !codes.failed() {
let mut out = entry.with_extension("sqfc")?.create_file()?;
sqf.optimize().compile_to_writer(&processed, &mut out)?;
progress.inc(1);
}
for code in codes {
report.push(code);
}
Ok(report)
}
Err(ParserError::ParsingError(e)) => {
if hemtt_sqf::is_cba_settings(processed.as_str()) {
debug!("skipping apparent CBA settings file: {}", entry);
} else {
for error in e {
report.push(error);
}
}
Ok(report)
}
Err(ParserError::LexingError(e)) => {
for error in e {
report.push(error);
}
Ok(report)
}
if let Some(sqf) = checked.statements
&& !checked.codes.failed()
{
let mut out = entry.with_extension("sqfc")?.create_file()?;
sqf.optimize().compile_to_writer(&processed, &mut out)?;
progress.inc(1);
}
for code in checked.codes {
report.push(code);
}
Ok(report)
})
.collect::<Result<Vec<Report>, Error>>()?;
for new_report in reports {
Expand Down
75 changes: 31 additions & 44 deletions hls/src/config/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,53 +79,40 @@ async fn check_addon(source: WorkspacePath, workspace: EditorWorkspace) {
Ok(processed) => {
{
let workspace_files = WorkspaceFiles::new();
match hemtt_config::parse(workspace.config().as_ref(), &processed) {
Ok(report) => {
for code in report.warnings().iter().chain(report.errors().iter()) {
warn!("code: {:?}", code);
let Some(diag) = code.diagnostic() else {
continue;
};
if diag.labels.iter().all(|l| l.file().is_include()) {
continue;
}
let lsp_diag = diag.to_lsp(&workspace_files);
for (file, diag) in lsp_diag {
lsp_diags.entry(file).or_insert_with(Vec::new).push(diag);
}
}
let config_analyzer = ConfigAnalyzer::get();
config_analyzer.functions_defined.insert(
{
// `/folder/addon/blah` => addon
let parts: Vec<&str> = source.as_str().split('/').collect();
if parts.len() < 3 {
warn!("Invalid config path: {}", source.as_str());
if parts.len() == 2 {
parts[1].to_string()
} else {
source.as_str().to_string()
}
let checked = hemtt_config::check::check(&processed, workspace.config().as_ref());
for code in &checked.codes {
let Some(diag) = code.diagnostic() else {
continue;
};
// a diagnostic inside a vendored include is not actionable
// from the project, so it is not shown
if diag.labels.iter().all(|l| l.file().is_include()) {
continue;
}
let lsp_diag = diag.to_lsp(&workspace_files);
for (file, diag) in lsp_diag {
lsp_diags.entry(file).or_insert_with(Vec::new).push(diag);
}
}
if let Some(report) = checked.config {
let config_analyzer = ConfigAnalyzer::get();
config_analyzer.functions_defined.insert(
{
// `/folder/addon/blah` => addon
let parts: Vec<&str> = source.as_str().split('/').collect();
if parts.len() < 3 {
warn!("Invalid config path: {}", source.as_str());
if parts.len() == 2 {
parts[1].to_string()
} else {
parts[2].to_string()
source.as_str().to_string()
}
},
report.functions_defined().clone(),
);
}
Err(err) => {
warn!("failed to process config: {:?}", err);
for error in err {
warn!("error: {:?}", error);
let Some(diag) = error.diagnostic() else {
continue;
};
let lsp_diag = diag.to_lsp(&workspace_files);
for (file, diag) in lsp_diag {
lsp_diags.entry(file).or_insert_with(Vec::new).push(diag);
} else {
parts[2].to_string()
}
}
}
},
report.functions_defined().clone(),
);
}
}
let sources = processed.included_files().to_owned();
Expand Down
86 changes: 28 additions & 58 deletions hls/src/sqf/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,65 +124,35 @@ async fn check_sqf(
Ok(processed) => {
{
let workspace_files = WorkspaceFiles::new();
match hemtt_sqf::parser::run(&database, &processed) {
Ok(sqf) => {
let (codes, report) = hemtt_sqf::analyze::analyze(
&sqf,
workspace.config().as_ref(),
&processed,
addon.clone(),
database,
);
if let Some(report) = report {
let cache = SqfAnalyzer::get();
let mut functions_defined = cache
.functions_defined
.entry(addon.name().to_string())
.or_insert_with(HashMap::new);
functions_defined.insert(
source.as_str().to_string(),
report.functions_defined().clone(),
);
}
for code in codes {
let Some(diag) = code.diagnostic() else {
warn!("failed to get diagnostic");
continue;
};
if diag.labels.iter().all(|l| l.file().is_include()) {
continue;
}
let lsp_diag = diag.to_lsp(&workspace_files);
for (file, diag) in lsp_diag {
lsp_diags.entry(file).or_insert_with(Vec::new).push(diag);
}
}
}
Err(hemtt_sqf::parser::ParserError::ParsingError(e)) => {
if hemtt_sqf::is_cba_settings(processed.as_str()) {
debug!("skipping apparent CBA settings file: {}", source);
} else {
for error in e {
let Some(diag) = error.diagnostic() else {
continue;
};
let diag = diag.to_lsp(&workspace_files);
for (file, diag) in diag {
lsp_diags.entry(file).or_insert_with(Vec::new).push(diag);
}
}
}
let checked = hemtt_sqf::check::check(
&processed,
workspace.config().as_ref(),
&addon,
database,
);
if let Some(report) = checked.report {
let cache = SqfAnalyzer::get();
let mut functions_defined = cache
.functions_defined
.entry(addon.name().to_string())
.or_insert_with(HashMap::new);
functions_defined.insert(
source.as_str().to_string(),
report.functions_defined().clone(),
);
}
for code in checked.codes {
let Some(diag) = code.diagnostic() else {
continue;
};
// a diagnostic inside a vendored include is not actionable
// from the project, so it is not shown
if diag.labels.iter().all(|l| l.file().is_include()) {
continue;
}
Err(e) => {
for error in e.codes() {
let Some(diag) = error.diagnostic() else {
continue;
};
let diag = diag.to_lsp(&workspace_files);
for (file, diag) in diag {
lsp_diags.entry(file).or_insert_with(Vec::new).push(diag);
}
}
let lsp_diag = diag.to_lsp(&workspace_files);
for (file, diag) in lsp_diag {
lsp_diags.entry(file).or_insert_with(Vec::new).push(diag);
}
}
}
Expand Down
Loading