diff --git a/stack-graphs/include/stack-graphs.h b/stack-graphs/include/stack-graphs.h index 12c7f09b1..4f23e3dde 100644 --- a/stack-graphs/include/stack-graphs.h +++ b/stack-graphs/include/stack-graphs.h @@ -294,7 +294,6 @@ struct sg_partial_scope_stack { // The handle of the first element in the partial scope stack, or SG_LIST_EMPTY_HANDLE if the // list is empty, or 0 if the list is null. sg_partial_scope_stack_cell_handle cells; - enum sg_deque_direction direction; uint32_t length; // The scope stack variable representing the unknown content of a partial scope stack, or 0 if // the variable is missing. (If so, this partial scope stack can only match a scope stack @@ -345,7 +344,6 @@ struct sg_partial_symbol_stack { // The handle of the first element in the partial symbol stack, or SG_LIST_EMPTY_HANDLE if the // list is empty, or 0 if the list is null. sg_partial_symbol_stack_cell_handle cells; - enum sg_deque_direction direction; uint32_t length; // The symbol stack variable representing the unknown content of a partial symbol stack, or 0 // if the variable is missing. (If so, this partial symbol stack can only match a symbol diff --git a/stack-graphs/src/arena.rs b/stack-graphs/src/arena.rs index 7380f4a8d..6feaa3f7d 100644 --- a/stack-graphs/src/arena.rs +++ b/stack-graphs/src/arena.rs @@ -693,7 +693,7 @@ where /// Ensures that the reversal of this list is available. It can be useful to precalculate this /// when you have mutable access to the arena, so that you can then reverse and un-reverse the /// list later when you only have shared access to it. - pub fn ensure_reversal_available(&mut self, arena: &mut ReversibleListArena) { + pub fn ensure_reversal_available(&self, arena: &mut ReversibleListArena) { // First check to see if the list has already been reversed. if self.is_empty() { // The empty list is already reversed. @@ -869,9 +869,7 @@ impl Copy for ReversibleList {} /// /// [`List`]: struct.List.html #[repr(C)] -#[derive(Niche)] pub struct Deque { - #[niche] list: ReversibleList, direction: DequeDirection, } @@ -964,6 +962,11 @@ where self.direction = DequeDirection::Forwards; } + /// Ensures that this deque has computed both directions of elements. + pub fn ensure_both_directions(&self, arena: &mut DequeArena) { + self.list.ensure_reversal_available(arena); + } + /// Pushes a new element onto the front of this deque. pub fn push_front(&mut self, arena: &mut DequeArena, element: T) { self.ensure_forwards(arena); diff --git a/stack-graphs/src/c.rs b/stack-graphs/src/c.rs index 00b7bb359..998d4cf2e 100644 --- a/stack-graphs/src/c.rs +++ b/stack-graphs/src/c.rs @@ -770,7 +770,6 @@ pub struct sg_partial_symbol_stack { /// The handle of the first element in the partial symbol stack, or SG_LIST_EMPTY_HANDLE if the /// list is empty, or 0 if the list is null. pub cells: sg_partial_symbol_stack_cell_handle, - pub direction: sg_deque_direction, pub length: u32, /// The symbol stack variable representing the unknown content of a partial symbol stack, or 0 /// if the variable is missing. (If so, this partial symbol stack can only match a symbol @@ -854,13 +853,12 @@ pub extern "C" fn sg_partial_path_arena_add_partial_symbol_stacks( } else { PartialSymbolStack::from_variable(variables[i].try_into().unwrap()) }; - for j in 0..length { + for j in (0..length).rev() { let symbol = symbols_slice[j].into(); - stack.push_back(partials, symbol); + stack.push_front(partials, symbol); } - // We pushed the edges onto the list in reverse order. Requesting a forwards iterator - // before we return ensures that it will also be available in forwards order. - let _ = stack.iter(partials); + // We ensure that the list will also be available in reverse order. + stack.ensure_both_directions(partials); out[i] = stack.into(); unsafe { symbols = symbols.add(length) }; } @@ -880,7 +878,6 @@ pub struct sg_partial_scope_stack { /// The handle of the first element in the partial scope stack, or SG_LIST_EMPTY_HANDLE if the /// list is empty, or 0 if the list is null. pub cells: sg_partial_scope_stack_cell_handle, - pub direction: sg_deque_direction, pub length: u32, /// The scope stack variable representing the unknown content of a partial scope stack, or 0 if /// the variable is missing. (If so, this partial scope stack can only match a scope stack @@ -964,13 +961,12 @@ pub extern "C" fn sg_partial_path_arena_add_partial_scope_stacks( } else { PartialScopeStack::from_variable(variables[i].try_into().unwrap()) }; - for j in 0..length { + for j in (0..length).rev() { let node = scopes_slice[j].into(); - stack.push_back(partials, node); + stack.push_front(partials, node); } - // We pushed the edges onto the list in reverse order. Requesting a forwards iterator - // before we return ensures that it will also be available in forwards order. - let _ = stack.iter_scopes(partials); + // We ensure that the list will also be available in reverse order. + stack.ensure_both_directions(partials); out[i] = stack.into(); unsafe { scopes = scopes.add(length) }; } @@ -1077,9 +1073,8 @@ pub extern "C" fn sg_partial_path_arena_add_partial_path_edge_lists( let edge: PartialPathEdge = edges_slice[j].into(); list.push_back(partials, edge); } - // We pushed the edges onto the list in reverse order. Requesting a forwards iterator - // before we return ensures that it will also be available in forwards order. - let _ = list.iter(partials); + // We ensure that the list will also be available in reverse order. + list.ensure_both_directions(partials); out[i] = list.into(); unsafe { edges = edges.add(length) }; } @@ -1182,7 +1177,7 @@ pub extern "C" fn sg_partial_path_arena_find_partial_paths_in_file( graph, file, &AtomicUsizeCancellationFlag(cancellation_flag), - |_graph, partials, mut path| { + |_graph, partials, path| { path.ensure_both_directions(partials); partial_path_list.partial_paths.push(path); }, diff --git a/stack-graphs/src/json.rs b/stack-graphs/src/json.rs index 19a143a1c..41c0ebea6 100644 --- a/stack-graphs/src/json.rs +++ b/stack-graphs/src/json.rs @@ -694,7 +694,7 @@ impl Serialize for InPartialPaths<'_, &PartialSymbolStack> { if symbol_stack.has_variable() { len += 1; } - let symbols = symbol_stack.iter_unordered(paths).collect::>(); + let symbols = symbol_stack.iter(paths).collect::>(); let mut ser = serializer.serialize_struct("partial_symbol_stack", len)?; ser.serialize_field("symbols", &self.with(&symbols))?; @@ -765,7 +765,7 @@ impl Serialize for InPartialPaths<'_, &PartialScopeStack> { len += 1; } let scopes = scope_stack - .iter_unordered(paths) + .iter(paths) .map(|n| graph[n].id()) .collect::>(); diff --git a/stack-graphs/src/partial.rs b/stack-graphs/src/partial.rs index 8d3d655f1..a012c9bc0 100644 --- a/stack-graphs/src/partial.rs +++ b/stack-graphs/src/partial.rs @@ -46,6 +46,8 @@ use smallvec::SmallVec; use crate::arena::Deque; use crate::arena::DequeArena; use crate::arena::Handle; +use crate::arena::ReversibleList; +use crate::arena::ReversibleListArena; use crate::cycles::Appendables; use crate::cycles::AppendingCycleDetector; use crate::graph::Edge; @@ -443,7 +445,7 @@ impl DisplayWithPartialPaths for PartialScopedSymbol { #[derive(Clone, Copy, Niche)] pub struct PartialSymbolStack { #[niche] - symbols: Deque, + symbols: ReversibleList, length: u32, variable: ControlledOption, } @@ -481,7 +483,7 @@ impl PartialSymbolStack { /// Returns an empty partial symbol stack. pub fn empty() -> PartialSymbolStack { PartialSymbolStack { - symbols: Deque::empty(), + symbols: ReversibleList::empty(), length: 0, variable: ControlledOption::none(), } @@ -490,7 +492,7 @@ impl PartialSymbolStack { /// Returns a partial symbol stack containing only a symbol stack variable. pub fn from_variable(variable: SymbolStackVariable) -> PartialSymbolStack { PartialSymbolStack { - symbols: Deque::empty(), + symbols: ReversibleList::empty(), length: 0, variable: ControlledOption::some(variable), } @@ -519,13 +521,19 @@ impl PartialSymbolStack { None => Self::empty(), }; while let Some(symbol) = self.pop_front(partials) { - result.push_back(partials, symbol.with_offset(scope_variable_offset)); + result.push_front(partials, symbol.with_offset(scope_variable_offset)); } + result.reverse(partials); result } - fn prepend(&mut self, partials: &mut PartialPaths, mut head: Deque) { - while let Some(head) = head.pop_back(&mut partials.partial_symbol_stacks).copied() { + fn prepend( + &mut self, + partials: &mut PartialPaths, + mut head: ReversibleList, + ) { + head.reverse(&mut partials.partial_symbol_stacks); + while let Some(head) = head.pop_front(&mut partials.partial_symbol_stacks).copied() { self.push_front(partials, head); } } @@ -537,13 +545,6 @@ impl PartialSymbolStack { .push_front(&mut partials.partial_symbol_stacks, symbol); } - /// Pushes a new [`PartialScopedSymbol`][] onto the back of this partial symbol stack. - pub fn push_back(&mut self, partials: &mut PartialPaths, symbol: PartialScopedSymbol) { - self.length += 1; - self.symbols - .push_back(&mut partials.partial_symbol_stacks, symbol); - } - /// Removes and returns the [`PartialScopedSymbol`][] at the front of this partial symbol /// stack. If the stack is empty, returns `None`. pub fn pop_front(&mut self, partials: &mut PartialPaths) -> Option { @@ -557,17 +558,8 @@ impl PartialSymbolStack { result } - /// Removes and returns the [`PartialScopedSymbol`][] at the back of this partial symbol stack. - /// If the stack is empty, returns `None`. - pub fn pop_back(&mut self, partials: &mut PartialPaths) -> Option { - let result = self - .symbols - .pop_back(&mut partials.partial_symbol_stacks) - .copied(); - if result.is_some() { - self.length -= 1; - } - result + pub fn reverse(&mut self, partials: &mut PartialPaths) { + self.symbols.reverse(&mut partials.partial_symbol_stacks); } pub fn display<'a>( @@ -618,7 +610,8 @@ impl PartialSymbolStack { // Then prepend all of the scoped symbols that appear at the beginning of this stack, // applying the bindings to any attached scopes as well. - while let Some(partial_symbol) = self.pop_back(partials) { + self.reverse(partials); + while let Some(partial_symbol) = self.pop_front(partials) { let partial_symbol = partial_symbol.apply_partial_bindings(partials, scope_bindings)?; result.push_front(partials, partial_symbol); } @@ -642,13 +635,14 @@ impl PartialSymbolStack { let mut lhs = self; // First, look at the shortest common prefix of lhs and rhs, and verify that they match. - let mut head = Deque::empty(); + let mut head = ReversibleList::empty(); while lhs.contains_symbols() && rhs.contains_symbols() { let mut lhs_front = lhs.pop_front(partials).unwrap(); let rhs_front = rhs.pop_front(partials).unwrap(); lhs_front.unify(partials, rhs_front, scope_bindings)?; - head.push_back(&mut partials.partial_symbol_stacks, lhs_front); + head.push_front(&mut partials.partial_symbol_stacks, lhs_front); } + head.reverse(&mut partials.partial_symbol_stacks); // Now at most one stack still has symbols. Zero, one, or both of them have variables. // Let's do a case analysis on all of those possibilities. @@ -798,39 +792,19 @@ impl PartialSymbolStack { /// Returns an iterator over the contents of this partial symbol stack. pub fn iter<'a>( - &self, - partials: &'a mut PartialPaths, - ) -> impl Iterator + 'a { - self.symbols - .iter(&mut partials.partial_symbol_stacks) - .copied() - } - - /// Returns an iterator over the contents of this partial symbol stack, with no guarantee - /// about the ordering of the elements. - pub fn iter_unordered<'a>( &self, partials: &'a PartialPaths, ) -> impl Iterator + 'a { - self.symbols - .iter_unordered(&partials.partial_symbol_stacks) - .copied() + self.symbols.iter(&partials.partial_symbol_stacks).copied() } pub fn variable(&self) -> Option { - self.variable.clone().into_option() + self.variable.into_option() } - fn ensure_both_directions(&mut self, partials: &mut PartialPaths) { - self.symbols - .ensure_backwards(&mut partials.partial_symbol_stacks); + pub fn ensure_both_directions(&self, partials: &mut PartialPaths) { self.symbols - .ensure_forwards(&mut partials.partial_symbol_stacks); - } - - fn ensure_forwards(&mut self, partials: &mut PartialPaths) { - self.symbols - .ensure_forwards(&mut partials.partial_symbol_stacks); + .ensure_reversal_available(&mut partials.partial_symbol_stacks); } /// Returns the largest value of any symbol stack variable in this partial symbol stack. @@ -845,7 +819,7 @@ impl PartialSymbolStack { pub fn largest_scope_stack_variable(&self, partials: &PartialPaths) -> u32 { // We don't have to check the postconditions, because it's not valid for a postcondition to // refer to a variable that doesn't exist in the precondition. - self.iter_unordered(partials) + self.iter(partials) .filter_map(|symbol| symbol.scopes.into_option()) .filter_map(|scopes| scopes.variable.into_option()) .map(ScopeStackVariable::as_u32) @@ -855,28 +829,13 @@ impl PartialSymbolStack { } impl DisplayWithPartialPaths for PartialSymbolStack { - fn prepare(&mut self, graph: &StackGraph, partials: &mut PartialPaths) { - // Ensure that our deque is pointed forwards while we still have a mutable reference to the - // arena. - self.symbols - .ensure_forwards(&mut partials.partial_symbol_stacks); - // And then prepare each symbol in the stack. - let mut symbols = self.symbols; - while let Some(mut symbol) = symbols - .pop_front(&mut partials.partial_symbol_stacks) - .copied() - { - symbol.prepare(graph, partials); - } - } - fn display_with( &self, graph: &StackGraph, partials: &PartialPaths, f: &mut std::fmt::Formatter, ) -> std::fmt::Result { - for symbol in self.symbols.iter_reused(&partials.partial_symbol_stacks) { + for symbol in self.symbols.iter(&partials.partial_symbol_stacks) { symbol.display_with(graph, partials, f)?; } if let Some(variable) = self.variable.into_option() { @@ -899,7 +858,7 @@ impl DisplayWithPartialPaths for PartialSymbolStack { #[derive(Clone, Copy, Niche)] pub struct PartialScopeStack { #[niche] - scopes: Deque>, + scopes: ReversibleList>, length: u32, variable: ControlledOption, } @@ -937,7 +896,7 @@ impl PartialScopeStack { /// Returns an empty partial scope stack. pub fn empty() -> PartialScopeStack { PartialScopeStack { - scopes: Deque::empty(), + scopes: ReversibleList::empty(), length: 0, variable: ControlledOption::none(), } @@ -946,7 +905,7 @@ impl PartialScopeStack { /// Returns a partial scope stack containing only a scope stack variable. pub fn from_variable(variable: ScopeStackVariable) -> PartialScopeStack { PartialScopeStack { - scopes: Deque::empty(), + scopes: ReversibleList::empty(), length: 0, variable: ControlledOption::some(variable), } @@ -1011,7 +970,8 @@ impl PartialScopeStack { }; // Then prepend all of the scopes that appear at the beginning of this stack. - while let Some(scope) = self.pop_back(partials) { + self.reverse(partials); + while let Some(scope) = self.pop_front(partials) { result.push_front(partials, scope); } Ok(result) @@ -1128,16 +1088,6 @@ impl PartialScopeStack { .push_front(&mut partials.partial_scope_stacks, node); } - /// Pushes a new [`Node`][] onto the back of this partial scope stack. The node must be an - /// _exported scope node_. - /// - /// [`Node`]: ../graph/enum.Node.html - pub fn push_back(&mut self, partials: &mut PartialPaths, node: Handle) { - self.length += 1; - self.scopes - .push_back(&mut partials.partial_scope_stacks, node); - } - /// Removes and returns the [`Node`][] at the front of this partial scope stack. If the stack /// does not contain any exported scope nodes, returns `None`. pub fn pop_front(&mut self, partials: &mut PartialPaths) -> Option> { @@ -1151,17 +1101,8 @@ impl PartialScopeStack { result } - /// Removes and returns the [`Node`][] at the back of this partial scope stack. If the stack - /// does not contain any exported scope nodes, returns `None`. - pub fn pop_back(&mut self, partials: &mut PartialPaths) -> Option> { - let result = self - .scopes - .pop_back(&mut partials.partial_scope_stacks) - .copied(); - if result.is_some() { - self.length -= 1; - } - result + pub fn reverse(&mut self, partials: &mut PartialPaths) { + self.scopes.reverse(&mut partials.partial_scope_stacks) } /// Returns the scope stack variable at the end of this partial scope stack. If the stack does @@ -1200,24 +1141,8 @@ impl PartialScopeStack { } /// Returns an iterator over the scopes in this partial scope stack. - pub fn iter_scopes<'a>( - &self, - partials: &'a mut PartialPaths, - ) -> impl Iterator> + 'a { - self.scopes - .iter(&mut partials.partial_scope_stacks) - .copied() - } - - /// Returns an iterator over the contents of this partial scope stack, with no guarantee - /// about the ordering of the elements. - pub fn iter_unordered<'a>( - &self, - partials: &'a PartialPaths, - ) -> impl Iterator> + 'a { - self.scopes - .iter_unordered(&partials.partial_scope_stacks) - .copied() + pub fn iter<'a>(&self, partials: &'a PartialPaths) -> impl Iterator> + 'a { + self.scopes.iter(&partials.partial_scope_stacks).copied() } pub fn display<'a>( @@ -1228,16 +1153,9 @@ impl PartialScopeStack { display_with(self, graph, partials) } - fn ensure_both_directions(&mut self, partials: &mut PartialPaths) { - self.scopes - .ensure_backwards(&mut partials.partial_scope_stacks); - self.scopes - .ensure_forwards(&mut partials.partial_scope_stacks); - } - - fn ensure_forwards(&mut self, partials: &mut PartialPaths) { + pub fn ensure_both_directions(&self, partials: &mut PartialPaths) { self.scopes - .ensure_forwards(&mut partials.partial_scope_stacks); + .ensure_reversal_available(&mut partials.partial_scope_stacks); } /// Returns the largest value of any scope stack variable in this partial scope stack. @@ -1250,11 +1168,6 @@ impl PartialScopeStack { } impl DisplayWithPartialPaths for PartialScopeStack { - fn prepare(&mut self, _graph: &StackGraph, partials: &mut PartialPaths) { - self.scopes - .ensure_forwards(&mut partials.partial_scope_stacks); - } - fn display_with( &self, graph: &StackGraph, @@ -1262,7 +1175,7 @@ impl DisplayWithPartialPaths for PartialScopeStack { f: &mut std::fmt::Formatter, ) -> std::fmt::Result { let mut first = true; - for scope in self.scopes.iter_reused(&partials.partial_scope_stacks) { + for scope in self.scopes.iter(&partials.partial_scope_stacks) { if first { first = false; } else { @@ -1507,9 +1420,8 @@ impl DisplayWithPartialPaths for PartialPathEdge { /// The edges in a path keep track of precedence information so that we can correctly handle /// shadowed definitions. #[repr(C)] -#[derive(Clone, Copy, Niche)] +#[derive(Clone, Copy)] pub struct PartialPathEdgeList { - #[niche] edges: Deque, length: u32, } @@ -1653,10 +1565,9 @@ impl PartialPathEdgeList { .copied() } - fn ensure_both_directions(&mut self, partials: &mut PartialPaths) { + pub fn ensure_both_directions(&self, partials: &mut PartialPaths) { self.edges - .ensure_backwards(&mut partials.partial_path_edges); - self.edges.ensure_forwards(&mut partials.partial_path_edges); + .ensure_both_directions(&mut partials.partial_path_edges); } fn ensure_forwards(&mut self, partials: &mut PartialPaths) { @@ -1889,7 +1800,7 @@ impl PartialPath { /// Ensures that the content of this partial path is available in both forwards and backwards /// directions. - pub fn ensure_both_directions(&mut self, partials: &mut PartialPaths) { + pub fn ensure_both_directions(&self, partials: &mut PartialPaths) { self.symbol_stack_precondition .ensure_both_directions(partials); self.symbol_stack_postcondition @@ -1902,40 +1813,21 @@ impl PartialPath { let mut stack = self.symbol_stack_precondition; while let Some(symbol) = stack.pop_front(partials) { - if let Some(mut scopes) = symbol.scopes.into_option() { + if let Some(scopes) = symbol.scopes.into_option() { scopes.ensure_both_directions(partials); } } let mut stack = self.symbol_stack_postcondition; while let Some(symbol) = stack.pop_front(partials) { - if let Some(mut scopes) = symbol.scopes.into_option() { + if let Some(scopes) = symbol.scopes.into_option() { scopes.ensure_both_directions(partials); } } } - /// Ensures that the content of this partial path is in forwards direction. pub fn ensure_forwards(&mut self, partials: &mut PartialPaths) { - self.symbol_stack_precondition.ensure_forwards(partials); - self.symbol_stack_postcondition.ensure_forwards(partials); - self.scope_stack_precondition.ensure_forwards(partials); - self.scope_stack_postcondition.ensure_forwards(partials); self.edges.ensure_forwards(partials); - - let mut stack = self.symbol_stack_precondition; - while let Some(symbol) = stack.pop_front(partials) { - if let Some(mut scopes) = symbol.scopes.into_option() { - scopes.ensure_forwards(partials); - } - } - - let mut stack = self.symbol_stack_postcondition; - while let Some(symbol) = stack.pop_front(partials) { - if let Some(mut scopes) = symbol.scopes.into_option() { - scopes.ensure_forwards(partials); - } - } } /// Returns the largest value of any symbol stack variable in this partial path. @@ -2310,7 +2202,13 @@ impl Node { scope_stack_variable, )), }; - symbol_stack_precondition.push_back(partials, precondition_symbol); + *symbol_stack_precondition = { + let mut symbol_stack_precondition = *symbol_stack_precondition; + symbol_stack_precondition.reverse(partials); + symbol_stack_precondition.push_front(partials, precondition_symbol); + symbol_stack_precondition.reverse(partials); + symbol_stack_precondition + }; *scope_stack_postcondition = PartialScopeStack::from_variable(scope_stack_variable); } @@ -2332,7 +2230,13 @@ impl Node { symbol: sink.symbol, scopes: ControlledOption::none(), }; - symbol_stack_precondition.push_back(partials, precondition_symbol); + *symbol_stack_precondition = { + let mut symbol_stack_precondition = *symbol_stack_precondition; + symbol_stack_precondition.reverse(partials); + symbol_stack_precondition.push_front(partials, precondition_symbol); + symbol_stack_precondition.reverse(partials); + symbol_stack_precondition + }; } } Self::PushScopedSymbol(sink) => { @@ -2768,16 +2672,16 @@ struct Join { /// Manages the state of a collection of partial paths built up as part of the partial-path-finding /// algorithm or path-stitching algorithm. pub struct PartialPaths { - pub(crate) partial_symbol_stacks: DequeArena, - pub(crate) partial_scope_stacks: DequeArena>, + pub(crate) partial_symbol_stacks: ReversibleListArena, + pub(crate) partial_scope_stacks: ReversibleListArena>, pub(crate) partial_path_edges: DequeArena, } impl PartialPaths { pub fn new() -> PartialPaths { PartialPaths { - partial_symbol_stacks: Deque::new_arena(), - partial_scope_stacks: Deque::new_arena(), + partial_symbol_stacks: ReversibleList::new_arena(), + partial_scope_stacks: ReversibleList::new_arena(), partial_path_edges: Deque::new_arena(), } } diff --git a/stack-graphs/src/stitching.rs b/stack-graphs/src/stitching.rs index 151ffe57e..5de928324 100644 --- a/stack-graphs/src/stitching.rs +++ b/stack-graphs/src/stitching.rs @@ -305,10 +305,10 @@ impl Database { self.partial_paths.iter_handles() } - pub fn ensure_both_directions(&mut self, partials: &mut PartialPaths) { + pub fn ensure_both_directions(&self, partials: &mut PartialPaths) { for path in self.partial_paths.iter_handles() { self.partial_paths - .get_mut(path) + .get(path) .ensure_both_directions(partials); } } diff --git a/stack-graphs/tests/it/c/can_find_qualified_definitions_with_phased_partial_path_stitching.rs b/stack-graphs/tests/it/c/can_find_qualified_definitions_with_phased_partial_path_stitching.rs index 32967fa1a..f1537f57f 100644 --- a/stack-graphs/tests/it/c/can_find_qualified_definitions_with_phased_partial_path_stitching.rs +++ b/stack-graphs/tests/it/c/can_find_qualified_definitions_with_phased_partial_path_stitching.rs @@ -125,7 +125,7 @@ fn check_find_qualified_definitions( let mut partial_symbol_stack = PartialSymbolStack::empty(); for stack_symbol in stack_symbols { let symbol = rust_graph.add_symbol(stack_symbol); - partial_symbol_stack.push_back( + partial_symbol_stack.push_front( rust_partials, PartialScopedSymbol { symbol, @@ -133,6 +133,7 @@ fn check_find_qualified_definitions( }, ); } + partial_symbol_stack.reverse(rust_partials); // Create the forward partial path stitcher. let initial_partial_path = PartialPath { @@ -182,12 +183,12 @@ fn check_find_qualified_definitions( // Ditto for any attached scopes in the symbol stack pre- and postcondition. assert!(partial_path .symbol_stack_precondition - .iter_unordered(rust_partials) + .iter(rust_partials) .filter_map(|symbol| symbol.scopes.into_option()) .all(|stack| stack.have_reversal(rust_partials))); assert!(partial_path .symbol_stack_postcondition - .iter_unordered(rust_partials) + .iter(rust_partials) .filter_map(|symbol| symbol.scopes.into_option()) .all(|stack| stack.have_reversal(rust_partials))); diff --git a/stack-graphs/tests/it/c/can_jump_to_definition_with_phased_partial_path_stitching.rs b/stack-graphs/tests/it/c/can_jump_to_definition_with_phased_partial_path_stitching.rs index e6ee81796..770857131 100644 --- a/stack-graphs/tests/it/c/can_jump_to_definition_with_phased_partial_path_stitching.rs +++ b/stack-graphs/tests/it/c/can_jump_to_definition_with_phased_partial_path_stitching.rs @@ -167,12 +167,12 @@ fn check_jump_to_definition(graph: &TestGraph, file: &str, expected_partial_path // Ditto for any attached scopes in the symbol stack pre- and postcondition. assert!(partial_path .symbol_stack_precondition - .iter_unordered(rust_partials) + .iter(rust_partials) .filter_map(|symbol| symbol.scopes.into_option()) .all(|stack| stack.have_reversal(rust_partials))); assert!(partial_path .symbol_stack_postcondition - .iter_unordered(rust_partials) + .iter(rust_partials) .filter_map(|symbol| symbol.scopes.into_option()) .all(|stack| stack.have_reversal(rust_partials))); diff --git a/stack-graphs/tests/it/c/partial.rs b/stack-graphs/tests/it/c/partial.rs index fa3463eea..1f04b86de 100644 --- a/stack-graphs/tests/it/c/partial.rs +++ b/stack-graphs/tests/it/c/partial.rs @@ -6,9 +6,7 @@ // ------------------------------------------------------------------------------------------------ use controlled_option::ControlledOption; -use either::Either; use libc::c_char; -use stack_graphs::c::sg_deque_direction; use stack_graphs::c::sg_file_handle; use stack_graphs::c::sg_node; use stack_graphs::c::sg_node_handle; @@ -39,7 +37,6 @@ use stack_graphs::c::sg_stack_graph_new; use stack_graphs::c::sg_symbol_handle; use stack_graphs::c::SG_LIST_EMPTY_HANDLE; use stack_graphs::c::SG_NULL_HANDLE; -use stack_graphs::partial::PartialPathEdgeList; use stack_graphs::partial::PartialScopeStack; use stack_graphs::partial::PartialSymbolStack; @@ -95,7 +92,6 @@ fn add_exported_scope( fn empty_partial_scope_stack() -> sg_partial_scope_stack { sg_partial_scope_stack { cells: SG_NULL_HANDLE, - direction: sg_deque_direction::SG_DEQUE_FORWARDS, length: 0, variable: 0, } @@ -115,11 +111,6 @@ fn partial_symbol_stack_contains( ) -> bool { let cells = unsafe { std::slice::from_raw_parts(cells.cells, cells.count) }; let mut current = stack.cells; - let expected = if stack.direction == sg_deque_direction::SG_DEQUE_FORWARDS { - Either::Left(expected.iter()) - } else { - Either::Right(expected.iter().rev()) - }; for node in expected { if current == SG_LIST_EMPTY_HANDLE { return false; @@ -241,11 +232,6 @@ fn partial_scope_stack_contains( ) -> bool { let cells = unsafe { std::slice::from_raw_parts(cells.cells, cells.count) }; let mut current = stack.cells; - let expected = if stack.direction == sg_deque_direction::SG_DEQUE_FORWARDS { - Either::Left(expected.iter()) - } else { - Either::Right(expected.iter().rev()) - }; for node in expected { if current == SG_LIST_EMPTY_HANDLE { return false; @@ -355,12 +341,7 @@ fn partial_path_edge_list_contains( ) -> bool { let cells = unsafe { std::slice::from_raw_parts(cells.cells, cells.count) }; let mut current = list.cells; - let expected = if list.direction == sg_deque_direction::SG_DEQUE_FORWARDS { - Either::Left(expected.iter()) - } else { - Either::Right(expected.iter().rev()) - }; - for node in expected { + for node in expected.iter().rev() { if current == SG_LIST_EMPTY_HANDLE { return false; } @@ -434,13 +415,3 @@ fn can_create_partial_path_edge_lists() { sg_partial_path_arena_free(partials); sg_stack_graph_free(graph); } - -#[test] -#[allow(unused_assignments)] -fn verify_null_partial_path_edge_list_representation() { - let bytes = [0x55u8; std::mem::size_of::()]; - let mut rust: ControlledOption = unsafe { std::mem::transmute(bytes) }; - rust = ControlledOption::none(); - let c: sg_partial_path_edge_list = unsafe { std::mem::transmute(rust) }; - assert_eq!(c.cells, SG_NULL_HANDLE); -} diff --git a/stack-graphs/tests/it/util.rs b/stack-graphs/tests/it/util.rs index 9f62ae0b9..9facdcc85 100644 --- a/stack-graphs/tests/it/util.rs +++ b/stack-graphs/tests/it/util.rs @@ -103,7 +103,7 @@ pub(crate) fn create_symbol_stack( } else { PartialSymbolStack::empty() }; - for scoped_symbol in contents.0 { + for scoped_symbol in contents.0.iter().rev() { let symbol = graph.add_symbol(scoped_symbol.0); let scopes = scoped_symbol .1 @@ -112,7 +112,7 @@ pub(crate) fn create_symbol_stack( symbol, scopes: ControlledOption::from_option(scopes), }; - stack.push_back(partials, scoped_symbol); + stack.push_front(partials, scoped_symbol); } stack } @@ -128,13 +128,13 @@ pub(crate) fn create_scope_stack( } else { PartialScopeStack::empty() }; - for scope in contents.0 { + for scope in contents.0.iter().rev() { let node_id = NodeID::new_in_file(file, *scope); let node = match graph.node_for_id(node_id) { Some(node) => node, None => graph.add_scope_node(node_id, true).unwrap(), }; - stack.push_back(partials, node); + stack.push_front(partials, node); } stack }