def _next_trace_frames(
        self,
        session: Session,
        trace_frame: TraceFrameQueryResult,
        visited_ids: Set[int],
        backwards: bool = False,
    ) -> List[TraceFrameQueryResult]:
        """Finds all trace frames that the given trace_frame flows to.

        When backwards=True, the result will include the parameter trace_frame,
        since we are filtering on the parameter's callee.
        """
        query = (
            session.query(
                TraceFrame.id,
                TraceFrame.caller_id,
                CallerText.contents.label("caller"),
                TraceFrame.caller_port,
                TraceFrame.callee_id,
                CalleeText.contents.label("callee"),
                TraceFrame.callee_port,
                TraceFrame.callee_location,
                TraceFrame.kind,
                FilenameText.contents.label("filename"),
                TraceFrameLeafAssoc.trace_length,
            )
            .filter(TraceFrame.run_id == self.current_run_id)
            .filter(TraceFrame.kind == trace_frame.kind)
            .join(CallerText, CallerText.id == TraceFrame.caller_id)
            .join(CalleeText, CalleeText.id == TraceFrame.callee_id)
            .join(FilenameText, FilenameText.id == TraceFrame.filename_id)
            .filter(
                TraceFrame.caller_id != TraceFrame.callee_id
            )  # skip recursive calls for now
        )
        if backwards:
            query = query.filter(TraceFrame.callee_id == trace_frame.caller_id).filter(
                TraceFrame.callee_port == trace_frame.caller_port
            )
        else:
            query = query.filter(TraceFrame.caller_id == trace_frame.callee_id).filter(
                TraceFrame.caller_port == trace_frame.callee_port
            )

        results = (
            query.join(
                TraceFrameLeafAssoc, TraceFrameLeafAssoc.trace_frame_id == TraceFrame.id
            )
            .group_by(TraceFrame.id)
            .order_by(TraceFrameLeafAssoc.trace_length, TraceFrame.callee_location)
        )
        filter_leaves = (
            self.sources if trace_frame.kind == TraceKind.POSTCONDITION else self.sinks
        )

        filtered_results = []
        for frame in results:
            if int(frame.id) not in visited_ids and filter_leaves.intersection(
                set(
                    self._get_leaves_trace_frame(
                        session,
                        int(frame.id),
                        self._trace_kind_to_shared_text_kind(frame.kind),
                    )
                )
            ):
                filtered_results.append(frame)

        return filtered_results
def _next_trace_frames ( self , session : Session , trace_frame : TraceFrameQueryResult , visited_ids : Set [ int ] , backwards : bool = False , ) -> List [ TraceFrameQueryResult ] : query = ( session . query ( TraceFrame . id , TraceFrame . caller_id , CallerText . contents . label ( "caller" ) , TraceFrame . caller_port , TraceFrame . callee_id , CalleeText . contents . label ( "callee" ) , TraceFrame . callee_port , TraceFrame . callee_location , TraceFrame . kind , FilenameText . contents . label ( "filename" ) , TraceFrameLeafAssoc . trace_length , ) . filter ( TraceFrame . run_id == self . current_run_id ) . filter ( TraceFrame . kind == trace_frame . kind ) . join ( CallerText , CallerText . id == TraceFrame . caller_id ) . join ( CalleeText , CalleeText . id == TraceFrame . callee_id ) . join ( FilenameText , FilenameText . id == TraceFrame . filename_id ) . filter ( TraceFrame . caller_id != TraceFrame . callee_id ) ) if backwards : query = query . filter ( TraceFrame . callee_id == trace_frame . caller_id ) . filter ( TraceFrame . callee_port == trace_frame . caller_port ) else : query = query . filter ( TraceFrame . caller_id == trace_frame . callee_id ) . filter ( TraceFrame . caller_port == trace_frame . callee_port ) results = ( query . join ( TraceFrameLeafAssoc , TraceFrameLeafAssoc . trace_frame_id == TraceFrame . id ) . group_by ( TraceFrame . id ) . order_by ( TraceFrameLeafAssoc . trace_length , TraceFrame . callee_location ) ) filter_leaves = ( self . sources if trace_frame . kind == TraceKind . POSTCONDITION else self . sinks ) filtered_results = [ ] for frame in results : if int ( frame . id ) not in visited_ids and filter_leaves . intersection ( set ( self . _get_leaves_trace_frame ( session , int ( frame . id ) , self . _trace_kind_to_shared_text_kind ( frame . kind ) , ) ) ) : filtered_results . append ( frame ) return filtered_results
Finds all trace frames that the given trace_frame flows to.

        When backwards=True, the result will include the parameter trace_frame,
        since we are filtering on the parameter's callee.