Skip to content

Commit

Permalink
修复lint在同行中读写不视为读, 仅在唯一的一行生效
Browse files Browse the repository at this point in the history
  • Loading branch information
A4-Tacks committed Mar 29, 2024
1 parent 06824bd commit 50ae5b1
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 32 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mindustry_logic_bang_lang"
version = "0.15.6"
version = "0.15.7"
edition = "2021"

authors = ["A4-Tacks <[email protected]>"]
Expand Down
2 changes: 1 addition & 1 deletion tools/logic_lint/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
Expand Down
49 changes: 32 additions & 17 deletions tools/logic_lint/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<Line<'a>>,
used_vars: HashMap<&'a str, Vec<Var<'a>>>,
/// 行中只读的量表,
/// 如果一行同时对一个量进行了读写,
/// 那么它将不会出现在这个表中
readonly_used_vars: HashSet<&'a str>,
}
impl<'a> Source<'a> {
pub fn from_str(s: &'a str) -> Self {
Expand All @@ -77,25 +84,29 @@ impl<'a> Source<'a> {
.map(|(lineno, line)| Line::from_line(lineno, line))
.collect::<Vec<_>>();

let mut used_vars: HashMap<&str, Vec<Var<'_>>> = 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,
}
}

Expand Down Expand Up @@ -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)]
Expand Down
14 changes: 3 additions & 11 deletions tools/logic_lint/src/lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down

0 comments on commit 50ae5b1

Please sign in to comment.