Skip to content

Commit 0b58caf

Browse files
committed
Fix and refine the error messages
1 parent 6673392 commit 0b58caf

File tree

2 files changed

+35
-20
lines changed

2 files changed

+35
-20
lines changed

.github/main.workflow

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ action "Test all rust project" {
4747
args = [
4848
"cargo install just",
4949
"just test",
50-
"mv target/debug/${BIN} ${HOME}/.cargo/bin/${BIN}",
5150
]
5251
env = { PWD = "/github/workspace", BIN = "scrap" }
5352
}

packages/core/src/semantics/transition/analyze.rs

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ impl SemanticCheck for Transition<'_> {
3737

3838
// WARNING: don't insert anything since the insertion is already done in analyze_error >-down-to-> check_error
3939
Ok(self.at.as_ref().and_then(|event| {
40-
// FIXME: not working on auto-transition
4140
let has_same_event = t_cache
4241
.keys()
4342
.filter(|&key| key != &Some(event.into()))
@@ -53,6 +52,7 @@ impl SemanticCheck for Transition<'_> {
5352
}
5453
}
5554

55+
// WARNING: not performant because of using concatenated String as a key which cause filtering
5656
impl From<&Event<'_>> for String {
5757
fn from(event: &Event<'_>) -> Self {
5858
format!("{}?{}", event.name.unwrap_or(""), event.guard.unwrap_or(""))
@@ -83,12 +83,26 @@ trait EventKey<'i>: Into<Option<&'i String>> {
8383
.filter(|e| none_empty(e.split('?')) == guard)
8484
.and_then(|e| none_empty(e.rsplit('?')))
8585
}
86+
fn as_expression(self) -> String {
87+
self.into().map(String::as_str).as_expression()
88+
}
8689
}
8790

8891
impl<'o> Trigger<'o> for &'o Option<&'o str> {}
8992
trait Trigger<'o>: Into<Option<&'o &'o str>> {
9093
fn as_expression(self) -> String {
91-
self.into().map(|s| " @ ".to_owned() + &s).unwrap_or_default()
94+
self.into()
95+
.map(|s| {
96+
format!(
97+
" @ {trigger}{guard}",
98+
trigger = none_empty(s.rsplit('?')).unwrap_or_default(),
99+
guard = none_empty(s.split('?'))
100+
.filter(|_| s.contains('?'))
101+
.map(|g| format!("[{}]", g))
102+
.unwrap_or_default(),
103+
)
104+
})
105+
.unwrap_or_default()
92106
}
93107
fn as_key(self, guard: &str) -> Option<String> {
94108
Some(format!("{}?{}", self.into().unwrap_or(&""), guard))
@@ -154,7 +168,7 @@ impl Transition<'_> {
154168
trigger
155169
),
156170
None => format!(
157-
"duplicate transient transition: {} -> {},{}",
171+
"duplicate transient-transition: {} -> {},{}",
158172
self.from.name,
159173
self.to.as_ref().unwrap_or(&self.from).name,
160174
prev_target
@@ -163,31 +177,33 @@ impl Transition<'_> {
163177
}
164178

165179
fn warn_conflict(&self, cache: &CacheMap) -> String {
180+
const REASON: &str = "never had a chance to trigger";
166181
match &self.at {
167-
Some(_) => {
168-
let prev_target = cache.get(&None).expect("cache without trigger");
169-
format!("conflict with: {} -> {}", self.from.name, prev_target)
182+
Some(event) => {
183+
let (prev_target, trigger) = (
184+
cache.get(&None).expect("cache without trigger"),
185+
event.name.expect("not auto-transition"),
186+
);
187+
format!("{} {} because: {} -> {}", trigger, REASON, self.from.name, prev_target)
170188
}
171189
None => {
172-
let prev_targets: Vec<&str> = cache
173-
.iter()
174-
.filter_map(|(trigger, target)| trigger.as_ref().and(Some(target.as_str())))
175-
.collect();
176-
let prev_triggers: Vec<String> = cache.keys().filter_map(ToOwned::to_owned).collect();
177-
format!(
178-
"conflict with: {} -> {} @ {}",
179-
self.from.name,
180-
prev_targets.join(","),
181-
prev_triggers.join(",")
182-
)
190+
let caches = cache.iter().filter(|(event, _)| event.has_trigger());
191+
192+
let mut messages = format!("conflict with {} {{\n", self.from.name);
193+
for (event, target) in caches.clone() {
194+
writeln!(&mut messages, "\t -> {}{}", target, event.as_expression()).expect("utf-8");
195+
}
196+
messages += " }";
197+
198+
let triggers = caches.filter_map(|(event, _)| event.get_trigger()).collect::<Vec<&str>>();
199+
write!(&mut messages, "\n because {} {}", triggers.join(","), REASON).expect("utf-8");
200+
messages
183201
}
184202
}
185203
}
186204

187-
// WARNING: not performant because of using concatenated String as a key which cause to filter
188205
fn warn_nondeterministic(&self, cache: &CacheMap) -> String {
189206
let mut messages = String::from("non-deterministic transition of ");
190-
// (trigger, guard) = (rsplit('?'), split('?')) each call .last()
191207
match &self.at {
192208
Some(event) => {
193209
let guards = cache.keys().filter_map(|k| k.guards_with_same_trigger(event.name));

0 commit comments

Comments
 (0)