1use std::collections::{HashSet, BTreeMap};
2use std::vec::Vec;
3use std::fmt::{Formatter, Result, Display};
4use crate::data::Event::*;
5use crate::hover_messages;
6pub static LINE_SPACE: i64 = 30;
10pub trait Visualizable {
12 fn get_name_from_hash(&self, hash: &u64) -> Option<String>;
14
15 fn get_state(&self, hash: &u64, line_number: &usize) -> Option<State>;
17
18 fn get_states(&self, hash: &u64) -> Vec::<(usize, usize, State)>;
21
22 fn _append_event(&mut self, resource_access_point: &ResourceAccessPoint, event: Event, line_number: &usize);
25
26 fn append_processed_external_event(&mut self, event: ExternalEvent, line_number: usize);
28
29 fn append_external_event(&mut self, event: ExternalEvent, line_number: &usize);
31 fn is_mut(&self, hash: &u64 ) -> bool;
33 fn is_mutref(&self, hash: &u64) -> bool;
35
36 fn calc_state(&self, previous_state: & State, event: & Event, event_line: usize, hash: &u64) -> State;
37}
38
39
40#[derive(Clone, Hash, PartialEq, Eq, Debug)]
45pub enum ResourceAccessPoint {
46 Owner(Owner),
47 MutRef(MutRef),
48 StaticRef(StaticRef),
49 Function(Function),
50 Struct(Struct),
51}
52
53#[derive(Clone, Hash, PartialEq, Eq, Debug)]
55pub struct Owner {
56 pub name: String,
57 pub hash: u64,
58 pub is_mut: bool, }
60
61#[derive(Clone, Hash, PartialEq, Eq, Debug)]
63pub struct Struct {
64 pub name: String,
65 pub hash: u64,
66 pub owner: u64,
67 pub is_mut: bool,
68 pub is_member: bool
69}
70
71#[derive(Clone, Hash, PartialEq, Eq, Debug)]
73pub struct MutRef { pub name: String,
75 pub hash: u64,
76 pub is_mut: bool,
77}
78
79#[derive(Clone, Hash, PartialEq, Eq, Debug)]
81pub struct StaticRef { pub name: String,
83 pub hash: u64,
84 pub is_mut: bool,
85}
86
87#[derive(Clone, Hash, PartialEq, Eq, Debug)]
88pub struct Function {
89 pub name: String,
90 pub hash: u64,
91}
92
93
94impl ResourceAccessPoint {
95 pub fn hash(&self) -> &u64 {
97 match self {
98 ResourceAccessPoint::Owner(Owner{hash, ..}) => hash,
99 ResourceAccessPoint::Struct(Struct{hash, ..}) => hash,
100 ResourceAccessPoint::MutRef(MutRef{hash, ..}) => hash,
101 ResourceAccessPoint::StaticRef(StaticRef{hash, ..}) => hash,
102 ResourceAccessPoint::Function(Function{hash, ..}) => hash,
103 }
104 }
105
106 pub fn name(&self) -> &String {
108 match self {
109 ResourceAccessPoint::Owner(Owner{name, ..}) => name,
110 ResourceAccessPoint::Struct(Struct{name, ..}) => name,
111 ResourceAccessPoint::MutRef(MutRef{name, ..}) => name,
112 ResourceAccessPoint::StaticRef(StaticRef{name, ..}) => name,
113 ResourceAccessPoint::Function(Function{name, ..}) => name,
114 }
115 }
116
117 pub fn is_mut(&self) -> bool {
119 match self {
120 ResourceAccessPoint::Owner(Owner{is_mut, ..}) => is_mut.to_owned(),
121 ResourceAccessPoint::Struct(Struct{is_mut, ..}) => is_mut.to_owned(),
122 ResourceAccessPoint::MutRef(MutRef{is_mut, ..}) => is_mut.to_owned(),
123 ResourceAccessPoint::StaticRef(StaticRef{is_mut, ..}) => is_mut.to_owned(),
124 ResourceAccessPoint::Function(_) => false,
125 }
126 }
127
128 pub fn is_ref(&self) -> bool {
129 match self {
130 ResourceAccessPoint::Owner(_) => false,
131 ResourceAccessPoint::Struct(_) => false,
132 ResourceAccessPoint::MutRef(_) => true,
133 ResourceAccessPoint::StaticRef(_) => true,
134 ResourceAccessPoint::Function(_) => false,
135 }
136 }
137
138 pub fn is_mutref(&self) -> bool {
139 match self {
140 ResourceAccessPoint::MutRef(_) => true,
141 _ => false
142 }
143 }
144
145 pub fn is_struct_group(&self) -> bool {
146 match self {
147 ResourceAccessPoint::Owner(_) => false,
148 ResourceAccessPoint::Struct(_) => true,
149 ResourceAccessPoint::MutRef(_) => false,
150 ResourceAccessPoint::StaticRef(_) => false,
151 ResourceAccessPoint::Function(_) => false,
152 }
153 }
154
155 pub fn is_struct(&self) -> bool {
156 match self {
157 ResourceAccessPoint::Owner(_) => false,
158 ResourceAccessPoint::Struct(Struct{is_member, ..}) => !is_member.to_owned(),
159 ResourceAccessPoint::MutRef(_) => false,
160 ResourceAccessPoint::StaticRef(_) => false,
161 ResourceAccessPoint::Function(_) => false,
162 }
163 }
164
165 pub fn is_member(&self) -> bool {
166 match self {
167 ResourceAccessPoint::Owner(_) => false,
168 ResourceAccessPoint::Struct(Struct{is_member, ..}) => is_member.to_owned(),
169 ResourceAccessPoint::MutRef(_) => false,
170 ResourceAccessPoint::StaticRef(_) => false,
171 ResourceAccessPoint::Function(_) => false,
172 }
173 }
174
175 pub fn get_owner(&self) -> u64 {
176 match self {
177 ResourceAccessPoint::Owner(Owner{hash, ..}) => hash.to_owned(),
178 ResourceAccessPoint::Struct(Struct{owner, ..}) => owner.to_owned(),
179 ResourceAccessPoint::MutRef(MutRef{hash, ..}) => hash.to_owned(),
180 ResourceAccessPoint::StaticRef(StaticRef{hash, ..}) => hash.to_owned(),
181 ResourceAccessPoint::Function(Function{hash, ..}) => hash.to_owned(),
182 }
183 }
184}
185
186#[derive(Clone, Hash, PartialEq, Eq, Debug)]
187pub enum ExternalEvent {
188 Bind {
190 from: Option<ResourceAccessPoint>,
191 to: Option<ResourceAccessPoint>
192 },
193 Copy {
194 from: Option<ResourceAccessPoint>,
195 to: Option<ResourceAccessPoint>
196 },
197 Move {
198 from: Option<ResourceAccessPoint>,
199 to: Option<ResourceAccessPoint>,
200 },
201 StaticBorrow {
202 from: Option<ResourceAccessPoint>,
203 to: Option<ResourceAccessPoint>,
204 },
205 MutableBorrow {
206 from: Option<ResourceAccessPoint>,
207 to: Option<ResourceAccessPoint>,
208 },
209 StaticDie {
210 from: Option<ResourceAccessPoint>,
212 to: Option<ResourceAccessPoint>,
213 },
214 MutableDie {
215 from: Option<ResourceAccessPoint>,
217 to: Option<ResourceAccessPoint>,
218 },
219 PassByStaticReference {
223 from: Option<ResourceAccessPoint>,
224 to: Option<ResourceAccessPoint>, },
226 PassByMutableReference {
227 from: Option<ResourceAccessPoint>,
228 to: Option<ResourceAccessPoint>, },
230 GoOutOfScope {
231 ro: ResourceAccessPoint
232 },
233 InitRefParam {
235 param: ResourceAccessPoint,
236 },
237}
238
239
240#[derive(Debug)]
246pub enum Event {
247 Acquire {
261 from: Option<ResourceAccessPoint>
262 },
263 Duplicate {
272 to: Option<ResourceAccessPoint>
273 },
274 Copy {
278 from: Option<ResourceAccessPoint>
279 },
280 Move {
289 to: Option<ResourceAccessPoint>
290 },
291 MutableLend {
292 to: Option<ResourceAccessPoint>
293 },
294 MutableBorrow {
295 from: ResourceAccessPoint
296 },
297 MutableDie {
298 to: Option<ResourceAccessPoint>
299 },
300 MutableReacquire {
301 from: Option<ResourceAccessPoint>
302 },
303 StaticLend {
304 to: Option<ResourceAccessPoint>
305 },
306 StaticBorrow {
307 from: ResourceAccessPoint
308 },
309 StaticDie {
310 to: Option<ResourceAccessPoint>
311 },
312 StaticReacquire {
313 from: Option<ResourceAccessPoint>
314 },
315 OwnerGoOutOfScope,
318 RefGoOutOfScope,
321 InitRefParam {
324 param: ResourceAccessPoint
325 },
326}
327
328#[derive(Clone)]
331pub enum State {
332 OutOfScope,
334 ResourceMoved {
337 move_to: Option<ResourceAccessPoint>,
338 move_at_line: usize
339 },
340 FullPrivilege,
342 PartialPrivilege {
353 borrow_count: u32,
354 borrow_to: HashSet<ResourceAccessPoint>
355 },
356 RevokedPrivilege {
359 to: Option<ResourceAccessPoint>,
360 borrow_to: Option<ResourceAccessPoint>,
361 },
362 Invalid,
364}
365
366impl std::fmt::Display for State {
367 fn fmt(&self, f: &mut std::fmt::Formatter) -> Result {
368 match self {
369 State::OutOfScope => write!(f, "OutOfScope"),
370 State::ResourceMoved { move_to: _, move_at_line: _ } => write!(f, "ResourceMoved"),
371 State::FullPrivilege => write!(f, "FullPrivilege"),
372 State::PartialPrivilege { .. } => write!(f, "PartialPrivilege"),
373 State::RevokedPrivilege { .. } => write!(f, "RevokedPrivilege"),
374 State::Invalid => write!(f, "Invalid"),
375 }
376 }
377}
378
379
380fn safe_message(
381 message_functor: fn(&String, &String) -> String,
382 my_name: &String,
383 some_target: &Option<ResourceAccessPoint>
384) -> String {
385 if let Some(target) = some_target {
386 message_functor(my_name, target.name())
387 }
388 else {
389 message_functor(my_name, &"another value".to_owned())
390 }
391}
392
393
394impl State {
395 pub fn print_message_with_name(&self, my_name: &String) -> String {
396 match self {
397 State::OutOfScope => {
398 hover_messages::state_out_of_scope(my_name)
399 }
400 State::ResourceMoved{ move_to , move_at_line: _ } => {
401 safe_message(hover_messages::state_resource_moved, my_name, move_to)
402 }
403 State::FullPrivilege => {
404 hover_messages::state_full_privilege(my_name)
405 }
406 State::PartialPrivilege { .. } => {
407 hover_messages::state_partial_privilege(my_name)
408 }
409 State::RevokedPrivilege { to: _, borrow_to } => {
410 safe_message(hover_messages::state_resource_revoked, my_name, borrow_to)
411 }
412 State::Invalid => {
413 hover_messages::state_invalid(my_name)
414 }
415 }
416 }
417}
418
419impl Display for Event {
421 fn fmt(&self, f: &mut Formatter) -> Result {
422 let mut from_ro = None;
423 let mut to_ro = None;
424 let mut display = match self {
425 Event::Acquire{ from } => { from_ro = from.to_owned(); "" },
426 Event::Duplicate{ to } => { to_ro = to.to_owned(); "Copying resource" },
427 Event::Copy{ from } => { from_ro = from.to_owned(); "Copying resource from some variable" },
428 Event::Move{ to } => { to_ro = to.to_owned(); "Moving resource" },
429 Event::MutableLend{ to } => { to_ro = to.to_owned(); "Mutable lend" },
430 Event::MutableBorrow{ from } => { from_ro = Some(from.to_owned()); "Fully borrows resource" },
431 Event::MutableDie{ to } => { to_ro = to.to_owned(); "Fully returns resource"},
432 Event::MutableReacquire{ from } => { from_ro = from.to_owned(); "Fully reacquires resource" },
433 Event::StaticLend{ to } => { to_ro = to.to_owned(); "Partially lends resource" },
434 Event::StaticBorrow{ from } => { from_ro = Some(from.to_owned()); "Partially borrows resource" },
435 Event::StaticDie{ to } => { to_ro = to.to_owned(); "Partially returns resource"},
436 Event::StaticReacquire{ from } => { from_ro = from.to_owned(); "Partially reacquires resource" },
437 Event::InitRefParam{ param: _ } => { "Function parameter is initialized" },
438 Event::OwnerGoOutOfScope => { "Goes out of Scope as an owner of resource" },
439 Event::RefGoOutOfScope => { "Goes out of Scope as a reference to resource" },
440 }.to_string();
441
442 if let Some(from_ro) = from_ro {
443 display = format!("{} from {}", display, &(from_ro.name()));
444 };
445 if let Some(to_ro) = to_ro {
446 display = format!("{} to {}", display, &(to_ro.name()));
447 };
448 write!(f, "{}", display)
449 }
450}
451
452impl Event {
453 pub fn print_message_with_name(&self, my_name: &String) -> String {
454 match self {
455 OwnerGoOutOfScope => {
457 hover_messages::event_dot_owner_go_out_out_scope(my_name)
458 }
459 RefGoOutOfScope => {
460 hover_messages::event_dot_ref_go_out_out_scope(my_name)
461 }
462 InitRefParam{ param: _ } => {
463 hover_messages::event_dot_init_param(my_name)
464 }
465 Duplicate{ to } => {
467 safe_message(hover_messages::event_dot_copy_to, my_name, to)
468 }
469 Move{ to } => {
470 match to {
471 Some(_) => safe_message(hover_messages::event_dot_move_to, my_name, to),
472 None => safe_message(hover_messages::event_dot_move_to_caller, my_name, to)
474 }
475
476 }
477 StaticLend{ to } => {
478 safe_message(hover_messages::event_dot_static_lend, my_name, to)
479 }
480 MutableLend{ to } => {
481 safe_message(hover_messages::event_dot_mut_lend, my_name, to)
482 }
483 StaticDie{ to } => {
484 safe_message(hover_messages::event_dot_static_return, my_name, to)
485 }
486 MutableDie{ to } => {
487 safe_message(hover_messages::event_dot_mut_return, my_name, to)
488 }
489 Acquire{ from } => {
491 safe_message(hover_messages::event_dot_acquire, my_name, from)
492 }
493 Copy{ from } => {
494 safe_message(hover_messages::event_dot_copy_from, my_name, from)
495 }
496 MutableBorrow{ from } => {
497 hover_messages::event_dot_mut_borrow(my_name, from.name())
498 }
499 StaticBorrow{ from } => {
500 hover_messages::event_dot_static_borrow(my_name, from.name())
501 }
502 StaticReacquire{ from } => {
503 safe_message(hover_messages::event_dot_static_reacquire, my_name, from)
504 }
505 MutableReacquire{ from } => {
506 safe_message(hover_messages::event_dot_mut_reacquire, my_name, from)
507 }
508 }
509 }
510}
511
512#[derive(Debug)]
515pub struct Timeline {
516 pub resource_access_point: ResourceAccessPoint, pub history: Vec<(usize, Event)>,
520}
521
522#[derive(Debug)]
524pub struct StructsInfo {
525 pub structs: Vec<(i64, i64, i64)>,
527}
528
529#[derive(Debug)]
533pub struct VisualizationData {
534 pub timelines: BTreeMap<u64, Timeline>,
539
540 pub external_events: Vec<(usize, ExternalEvent)>,
541 pub preprocess_external_events: Vec<(usize, ExternalEvent)>,
543 pub event_line_map: BTreeMap<usize, Vec<ExternalEvent>>,
545}
546
547#[allow(non_snake_case)]
548pub fn ResourceAccessPoint_extract (external_event : &ExternalEvent) -> (&Option<ResourceAccessPoint>, &Option<ResourceAccessPoint>){
549 let (from, to) = match external_event {
550 ExternalEvent::Bind{from: from_ro, to: to_ro} => (from_ro, to_ro),
551 ExternalEvent::Copy{from: from_ro, to: to_ro} => (from_ro, to_ro),
552 ExternalEvent::Move{from: from_ro, to: to_ro} => (from_ro, to_ro),
553 ExternalEvent::StaticBorrow{from: from_ro, to: to_ro} => (from_ro, to_ro),
554 ExternalEvent::StaticDie{from: from_ro, to: to_ro} => (from_ro, to_ro),
555 ExternalEvent::MutableBorrow{from: from_ro, to: to_ro} => (from_ro, to_ro),
556 ExternalEvent::MutableDie{from: from_ro, to: to_ro} => (from_ro, to_ro),
557 ExternalEvent::PassByMutableReference{from: from_ro, to: to_ro} => (from_ro, to_ro),
558 ExternalEvent::PassByStaticReference{from: from_ro, to: to_ro} => (from_ro, to_ro),
559 _ => (&None, &None),
560 };
561 (from, to)
562}
563
564impl Visualizable for VisualizationData {
567 fn get_name_from_hash(&self, hash: &u64) -> Option<String> {
568 match self.timelines.get(hash) {
569 Some(timeline) => Some(timeline.resource_access_point.name().to_owned()),
570 _ => None
571 }
572 }
573
574 fn is_mut(&self, hash: &u64) -> bool {
576 self.timelines[hash].resource_access_point.is_mut()
577 }
578
579 fn is_mutref(&self, hash: &u64) -> bool {
581 self.timelines[hash].resource_access_point.is_mutref()
582 }
583
584 fn calc_state(&self, previous_state: & State, event: & Event, event_line: usize, hash: &u64) -> State {
586 fn event_invalid(event: & Event) -> bool {
589 match event {
590 Event::StaticBorrow{ from: ResourceAccessPoint::Function(_) } => true,
591 Event::MutableBorrow{ from: ResourceAccessPoint::Function(_) } => true,
592 Event::StaticDie{ to: Some(ResourceAccessPoint::Function(_)) } => true,
593 Event::MutableDie{ to: Some(ResourceAccessPoint::Function(_)) } => true,
594 _ => false,
595 }
596 }
597 if event_invalid(event) { return State::Invalid; }
598
599 match (previous_state, event) {
600 (State::Invalid, _) =>
601 State::Invalid,
602
603 (State::OutOfScope, Event::Acquire{ .. }) =>
604 State::FullPrivilege,
605
606 (State::OutOfScope, Event::Copy{ .. }) =>
607 State::FullPrivilege,
608
609 (State::OutOfScope, Event::StaticBorrow{ from: ro }) =>
610 State::PartialPrivilege {
611 borrow_count: 1,
612 borrow_to: [ro.to_owned()].iter().cloned().collect()
613 },
614
615 (State::OutOfScope, Event::MutableBorrow{ .. }) =>
616 State::FullPrivilege,
617
618 (State::OutOfScope, Event::InitRefParam{ param: ro }) => {
619 match ro {
620 ResourceAccessPoint::Function(..) => {
621 panic!("Cannot initialize function as as valid parameter!")
622 },
623 ResourceAccessPoint::Owner(..) | ResourceAccessPoint::MutRef(..) => {
624 State::FullPrivilege
625 },
626 ResourceAccessPoint::Struct(..) => {
627 State::FullPrivilege
628 },
629 ResourceAccessPoint::StaticRef(..) => {
630 State::PartialPrivilege {
631 borrow_count: 1,
632 borrow_to: [ro.to_owned()].iter().cloned().collect()
633 }
634 }
635 }
636 },
637
638 (State::FullPrivilege, Event::Move{to: to_ro}) =>
639 State::ResourceMoved{ move_to: to_ro.to_owned(), move_at_line: event_line },
640
641 (State::ResourceMoved{ .. }, Event::Acquire{ .. }) => {
642 if self.is_mut(hash) {
643 State::FullPrivilege
644 }
645 else { eprintln!("Immutable variable {} cannot reacquire resources!", self.get_name_from_hash(hash).unwrap());
647 std::process::exit(1);
648 }
649 },
650
651 (State::FullPrivilege, Event::MutableLend{ to: to_ro }) => {
652 if self.is_mut(hash) | self.is_mutref(hash) {
656 State::RevokedPrivilege{ to: None, borrow_to: to_ro.to_owned() }
657 } else {
658 State::Invalid
659 }
660 },
661
662 (State::FullPrivilege, Event::MutableDie{ .. }) =>
664 State::OutOfScope,
665
666 (State::FullPrivilege, Event::Acquire{ from: _ }) | (State::FullPrivilege, Event::Copy{ from: _ }) => {
667 if self.is_mut(hash) {
668 State::FullPrivilege
669 }
670 else {
671 State::Invalid
672 }
673 },
674
675 (State::FullPrivilege, Event::OwnerGoOutOfScope) =>
676 State::OutOfScope,
677
678 (State::FullPrivilege, Event::RefGoOutOfScope) =>
679 State::OutOfScope,
680
681 (State::FullPrivilege, Event::StaticLend{ to: to_ro }) =>
682 State::PartialPrivilege {
683 borrow_count: 1,
684 borrow_to: [(to_ro.to_owned().unwrap())].iter().cloned().collect() },
686
687 (State::PartialPrivilege{ .. }, Event::MutableLend{ .. }) =>
688 State::Invalid,
689
690 (State::PartialPrivilege{ borrow_count: current, borrow_to }, Event::StaticLend{ to: to_ro }) => {
691 let mut new_borrow_to = borrow_to.clone();
692 new_borrow_to.insert(to_ro.to_owned().unwrap());
694 State::PartialPrivilege {
695 borrow_count: current+1,
696 borrow_to: new_borrow_to,
697 }
698 }
699
700 (State::PartialPrivilege{ .. }, Event::StaticDie{ .. }) =>
702 State::OutOfScope,
703
704 (State::PartialPrivilege{ borrow_count, borrow_to }, Event::StaticReacquire{ from: ro }) => {
705 let new_borrow_count = borrow_count - 1;
706 if borrow_count - 1 == 0 {
708 State::FullPrivilege
709 } else {
710 let mut new_borrow_to = borrow_to.clone();
711 assert_eq!(new_borrow_to.remove(&ro.to_owned().unwrap()), true); State::PartialPrivilege{
715 borrow_count: new_borrow_count,
716 borrow_to: new_borrow_to,
717 }
718 }
719 }
720
721 (State::PartialPrivilege{ .. }, Event::OwnerGoOutOfScope) =>
722 State::OutOfScope,
723
724 (State::PartialPrivilege{ .. }, Event::RefGoOutOfScope) =>
725 State::OutOfScope,
726
727 (State::RevokedPrivilege{ .. }, Event::MutableReacquire{ .. }) =>
728 State::FullPrivilege,
729
730 (_, Event::Duplicate { .. }) =>
731 (*previous_state).clone(),
732
733 (_, _) => State::Invalid,
734 }
735 }
736
737 fn get_states(&self, hash: &u64) -> Vec::<(usize, usize, State)> {
738 let mut states = Vec::<(usize, usize, State)>::new();
739 let mut previous_line_number: usize = 1;
740 let mut prev_state = State::OutOfScope;
741 for (line_number, event) in self.timelines[hash].history.iter() {
742 states.push(
743 (previous_line_number, *line_number, prev_state.clone())
744 );
745 prev_state = self.calc_state(&prev_state, &event, *line_number, hash);
746 previous_line_number = *line_number;
747 }
748 states.push(
749 (previous_line_number, previous_line_number, prev_state.clone())
750 );
751 states
752 }
753
754 fn get_state(&self, hash: &u64, _line_number: &usize) -> Option<State> {
755 match self.timelines.get(hash) {
757 Some(_timeline) => {
758 Some(State::OutOfScope)
760 },
761 _ => None
762 }
763 }
764
765 fn append_external_event(&mut self, event: ExternalEvent, line_number: &usize) {
766 self.preprocess_external_events.push((*line_number, event.clone()));
768 let resourceaccesspoint = ResourceAccessPoint_extract(&event);
770 match (resourceaccesspoint.0, resourceaccesspoint.1, &event) {
771 (Some(ResourceAccessPoint::Function(_)), Some(ResourceAccessPoint::Function(_)), _) => {
772 },
774 (Some(ResourceAccessPoint::Function(_from_function)), Some(_to_variable), _) => {
775 },
777 (Some(_from_variable), Some(ResourceAccessPoint::Function(_function)),
778 ExternalEvent::PassByStaticReference{..}) => {
779 },
781 (Some(_from_variable), Some(ResourceAccessPoint::Function(_function)),
782 ExternalEvent::PassByMutableReference{..}) => {
783 },
785 (Some(_from_variable), Some(ResourceAccessPoint::Function(_to_function)), _) => {
786 },
788 (Some(_from_variable), Some(_to_variable), _) => {
789 if let Some(event_vec) = self.event_line_map.get_mut(&line_number) {
790 event_vec.push(event);
793 } else {
794 let vec = vec![event];
795 self.event_line_map.insert(line_number.clone(), vec);
796 }
797 },
798 _ => ()
799 }
800 }
801
802 fn _append_event(&mut self, resource_access_point: &ResourceAccessPoint, event: Event, line_number: &usize) {
805 let hash = &resource_access_point.hash();
806 match self.timelines.get(hash) {
809 None => {
810 let timeline = Timeline {
811 resource_access_point: resource_access_point.clone(),
812 history: Vec::new(),
813 };
814 self.timelines.insert(**hash, timeline);
815 },
816 _ => {}
817 }
818
819 match self.timelines.get_mut(hash) {
821 Some(timeline) => {
822 timeline.history.push(
823 (*line_number, event)
824 );
825 },
826 _ => {
827 panic!("Timeline disappeared right after creation or when we could index it. This is impossible.");
828 }
829 }
830 }
831
832
833 fn append_processed_external_event(&mut self, event: ExternalEvent, line_number: usize) {
836 self.external_events.push((line_number, event.clone()));
837
838 fn maybe_append_event(vd: &mut VisualizationData, resource_access_point: &Option<ResourceAccessPoint>, event: Event, line_number : &usize) {
840 if let Some(ro) = resource_access_point {
841 vd._append_event(&ro, event, line_number)
842 };
843 }
844
845 match event {
846 ExternalEvent::Move{from: from_ro, to: to_ro} => {
848 maybe_append_event(self, &to_ro, Event::Acquire{from : from_ro.to_owned()}, &line_number);
849 maybe_append_event(self, &from_ro, Event::Move{to : to_ro.to_owned()}, &line_number);
850 },
851 ExternalEvent::Bind{from: from_ro, to: to_ro} => {
853 maybe_append_event(self, &to_ro, Event::Acquire{from : from_ro.to_owned()}, &line_number);
854 maybe_append_event(self, &from_ro, Event::Duplicate{to : to_ro.to_owned()}, &line_number);
855 },
856 ExternalEvent::Copy{from: from_ro, to: to_ro} => {
858 maybe_append_event(self, &to_ro, Event::Copy{from : from_ro.to_owned()}, &line_number);
859 maybe_append_event(self, &from_ro, Event::Duplicate{to : to_ro.to_owned()}, &line_number);
860 },
861 ExternalEvent::StaticBorrow{from: from_ro, to: to_ro} => {
862 maybe_append_event(self, &from_ro, Event::StaticLend{to : to_ro.to_owned()}, &line_number);
863 if let Some(some_from_ro) = from_ro {
864 maybe_append_event(self, &to_ro, Event::StaticBorrow{from : some_from_ro.to_owned()}, &line_number);
865 }
866 },
867 ExternalEvent::StaticDie{from: from_ro, to: to_ro} => {
868 maybe_append_event(self, &to_ro, Event::StaticReacquire{from : from_ro.to_owned()}, &line_number);
869 maybe_append_event(self, &from_ro, Event::StaticDie{to : to_ro.to_owned()}, &line_number);
870 },
871 ExternalEvent::MutableBorrow{from: from_ro, to: to_ro} => {
872 maybe_append_event(self, &from_ro, Event::MutableLend{to : to_ro.to_owned()}, &line_number);
873 if let Some(some_from_ro) = from_ro {
874 maybe_append_event(self, &to_ro, Event::MutableBorrow{from : some_from_ro.to_owned()}, &line_number);
875 }
876 },
877 ExternalEvent::MutableDie{from: from_ro, to: to_ro} => {
878 maybe_append_event(self, &to_ro, Event::MutableReacquire{from : from_ro.to_owned()}, &line_number);
879 maybe_append_event(self, &from_ro, Event::MutableDie{to : to_ro.to_owned()}, &line_number);
880 },
881 ExternalEvent::PassByStaticReference{from: from_ro, to: to_ro} => {
883 maybe_append_event(self, &from_ro.to_owned(), Event::StaticLend{to : to_ro.to_owned()}, &line_number);
884 if let Some(some_from_ro) = from_ro.to_owned() {
885 maybe_append_event(self, &to_ro.to_owned(), Event::StaticBorrow{from : some_from_ro.to_owned()}, &line_number);
886 } else {
887 eprintln!("Must pass a function to PassByStaticReference.to!");
888 std::process::exit(1);
889 }
890 maybe_append_event(self, &from_ro, Event::StaticReacquire{from : to_ro.to_owned()}, &line_number);
891 maybe_append_event(self, &to_ro, Event::StaticDie{to : from_ro.to_owned()}, &line_number);
892 },
893 ExternalEvent::PassByMutableReference{from: from_ro, to: to_ro} => {
894 maybe_append_event(self, &from_ro, Event::MutableLend{to : to_ro.to_owned()}, &line_number);
895 if let Some(some_from_ro) = from_ro.to_owned() {
896 maybe_append_event(self, &to_ro, Event::MutableBorrow{from : some_from_ro.to_owned()}, &line_number);
897 } else {
898 eprintln!("Must pass a function to PassByMutableReference.to!");
899 std::process::exit(1);
900 }
901 maybe_append_event(self, &from_ro, Event::MutableReacquire{from : to_ro.to_owned()}, &line_number);
902 maybe_append_event(self, &to_ro, Event::MutableDie{to : from_ro.to_owned()}, &line_number);
903 },
904 ExternalEvent::InitRefParam{param: ro} => {
905 maybe_append_event(self, &Some(ro.clone()), Event::InitRefParam{param : ro.to_owned()}, &line_number);
906 },
907 ExternalEvent::GoOutOfScope{ro} => {
908 match ro {
909 ResourceAccessPoint::Owner(..) => {
910 maybe_append_event(self, &Some(ro), Event::OwnerGoOutOfScope, &line_number);
911 },
912 ResourceAccessPoint::Struct(..) => {
913 maybe_append_event(self, &Some(ro), Event::OwnerGoOutOfScope, &line_number);
914 },
915 ResourceAccessPoint::MutRef(..) => {
916 maybe_append_event(self, &Some(ro), Event::RefGoOutOfScope, &line_number);
917 },
918 ResourceAccessPoint::StaticRef(..) => {
919 maybe_append_event(self, &Some(ro), Event::RefGoOutOfScope, &line_number);
920 },
921 ResourceAccessPoint::Function(func) => {
922 println!(
923 "Functions do not go out of scope! We do not expect to see \"{}\" here.",
924 func.name
925 );
926 std::process::exit(1);
927 }
928 }
929 },
930 }
931 }
932}
933
934