diff --git a/Cargo.lock b/Cargo.lock index 80ba68f..a95f1d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -286,7 +286,7 @@ checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "logic_lint" -version = "0.1.4" +version = "0.1.5" dependencies = [ "lazy-regex", "tag_code", @@ -301,7 +301,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mindustry_logic_bang_lang" -version = "0.15.6" +version = "0.15.7" dependencies = [ "display_source", "logic_lint", diff --git a/Cargo.toml b/Cargo.toml index db6f937..bd66c8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mindustry_logic_bang_lang" -version = "0.15.6" +version = "0.15.7" edition = "2021" authors = ["A4-Tacks "] diff --git a/tools/logic_lint/Cargo.toml b/tools/logic_lint/Cargo.toml index 49ebe0b..f3fbad0 100644 --- a/tools/logic_lint/Cargo.toml +++ b/tools/logic_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "logic_lint" -version = "0.1.4" +version = "0.1.5" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/tools/logic_lint/src/lib.rs b/tools/logic_lint/src/lib.rs index 1eb7373..2b57f8f 100644 --- a/tools/logic_lint/src/lib.rs +++ b/tools/logic_lint/src/lib.rs @@ -1,7 +1,7 @@ pub mod lints; use core::fmt; -use std::{borrow::Cow, collections::HashMap, ops::Deref}; +use std::{borrow::Cow, collections::HashSet, ops::Deref}; use lints::get_useds; use tag_code::mdt_logic_split_unwraped; @@ -61,12 +61,19 @@ impl<'a> Line<'a> { pub fn len(&self) -> usize { self.args().len() } + + pub fn is_empty(&self) -> bool { + self.args().is_empty() + } } #[derive(Debug)] pub struct Source<'a> { lines: Vec>, - used_vars: HashMap<&'a str, Vec>>, + /// 行中只读的量表, + /// 如果一行同时对一个量进行了读写, + /// 那么它将不会出现在这个表中 + readonly_used_vars: HashSet<&'a str>, } impl<'a> Source<'a> { pub fn from_str(s: &'a str) -> Self { @@ -77,25 +84,29 @@ impl<'a> Source<'a> { .map(|(lineno, line)| Line::from_line(lineno, line)) .collect::>(); - let mut used_vars: HashMap<&str, Vec>> = HashMap::new(); - lines.iter() + let readonly_used_vars = lines.iter() .filter_map(get_useds) - .flatten() - .filter_map(|used| ( - used.as_read().map(Var::value)?, - *used.as_read().unwrap() - ).into()) - .chain(env_assignables.iter() - .map(|&var| (var, Var::new_nonlocation(var)))) - .for_each(|(key, var)| { - used_vars.entry(key) - .or_default() - .push(var) - }); + .flat_map(|args| { + args.clone() + .into_iter() + .filter(move |arg| { + if arg.method().is_assign() { + return false; + } + !args.iter().any(|x| { + x.method().is_assign() + && x.var().value() == arg.var().value() + }) + }) + }) + .filter_map(|used| used.as_read() + .map(Var::value)) + .chain(env_assignables.iter().copied()) + .collect(); Self { lines, - used_vars, + readonly_used_vars, } } @@ -137,6 +148,10 @@ impl<'a> Source<'a> { eprintln!("{}", fmtter) } } + + pub fn used_vars(&self) -> &HashSet<&'a str> { + &self.readonly_used_vars + } } #[derive(Debug, Clone, Copy)] diff --git a/tools/logic_lint/src/lints.rs b/tools/logic_lint/src/lints.rs index da6578b..29b1942 100644 --- a/tools/logic_lint/src/lints.rs +++ b/tools/logic_lint/src/lints.rs @@ -230,17 +230,9 @@ fn check_assign_var<'a>( VarType::Var(_) => { let mut lints = Vec::new(); lints.extend(check_var(src, line, var)); - 'x: { - if let Some(useds) = src.used_vars.get(var.value()) { - if useds.iter() - .any(|used| used.lineno() != var.lineno()) - { - break 'x; - } - } - if regex_is_match!(r"^_(?:$|[^_])", var.value()) { - break 'x; - } + if !src.used_vars().contains(var.value()) + && !regex_is_match!(r"^_(?:$|[^_])", var.value()) + { lints.push(Lint::new(var, WarningLint::NeverUsed)); } vec_optiter(lints.into())