c:_ -> return (Just c)
-getCurrentBreakTick :: GHCi (Maybe BreakIndex)
-getCurrentBreakTick = do
- session <- getSession
- resumes <- io $ GHC.getResumeContext session
- case resumes of
- [] -> return Nothing
- (r:rs) -> do
- let ix = GHC.resumeHistoryIx r
- if ix == 0
- then return (GHC.breakInfo_number `fmap` GHC.resumeBreakInfo r)
- else do
- let hist = GHC.resumeHistory r !! (ix-1)
- let tick = GHC.getHistoryTick hist
- return (Just tick)
-
getCurrentBreakSpan :: GHCi (Maybe SrcSpan)
getCurrentBreakSpan = do
session <- getSession
stepOverCmd [] = do
mb_span <- getCurrentBreakSpan
- session <- getSession
case mb_span of
Nothing -> stepCmd []
- Just curr_loc -> do
- Just tick <- getCurrentBreakTick
- Just mod <- getCurrentBreakModule
- parent <- io$ GHC.findEnclosingDeclSpanByTick session mod tick
+ Just loc -> do
+ Just mod <- getCurrentBreakModule
+ parent <- enclosingTickSpan mod loc
allTicksRightmost <- (sortBy rightmost . map snd) `fmap`
ticksIn mod parent
let lastTick = null allTicksRightmost ||
- head allTicksRightmost == curr_loc
+ head allTicksRightmost == loc
if not lastTick
- then let f t = t `isSubspanOf` parent &&
- (curr_loc `leftmost_largest` t == LT)
- in doContinue f GHC.SingleStep
- else printForUser (text "Warning: no more breakpoints in this function body, switching to :step") >>
- doContinue (const True) GHC.SingleStep
+ then doContinue (`isSubspanOf` parent) GHC.SingleStep
+ else doContinue (const True) GHC.SingleStep
stepOverCmd expression = stepCmd expression
{-
- The first tricky bit in stepOver is detecting that we have
+ So, the only tricky part in stepOver is detecting that we have
arrived to the last tick in an expression, in which case we must
step normally to the next tick.
What we do is:
1. Retrieve the enclosing expression block (with a tick)
2. Retrieve all the ticks there and sort them out by 'rightness'
3. See if the current tick turned out the first one in the list
-
- The second tricky bit is how to step over recursive calls.
-
-}
--ticksIn :: Module -> SrcSpan -> GHCi [Tick]
, srcSpanEnd src >= srcSpanEnd span
]
+enclosingTickSpan :: Module -> SrcSpan -> GHCi SrcSpan
+enclosingTickSpan mod src = do
+ ticks <- getTickArray mod
+ let line = srcSpanStartLine src
+ ASSERT (inRange (bounds ticks) line) do
+ let enclosing_spans = [ span | (_,span) <- ticks ! line
+ , srcSpanEnd span >= srcSpanEnd src]
+ return . head . sortBy leftmost_largest $ enclosing_spans
+
traceCmd :: String -> GHCi ()
traceCmd [] = doContinue (const True) GHC.RunAndLogSteps
traceCmd expression = do runStmt expression GHC.RunAndLogSteps; return ()
Resume(resumeStmt, resumeThreadId, resumeBreakInfo, resumeSpan,
resumeHistory, resumeHistoryIx),
History(historyBreakInfo, historyEnclosingDecl),
- GHC.getHistorySpan, getHistoryModule, getHistoryTick,
- GHC.findEnclosingDeclSpanByTick,
+ GHC.getHistorySpan, getHistoryModule,
getResumeContext,
abandon, abandonAll,
InteractiveEval.back,
getHistorySpan :: Session -> History -> IO SrcSpan
getHistorySpan sess h = withSession sess $ \hsc_env ->
return$ InteractiveEval.getHistorySpan hsc_env h
-
-findEnclosingDeclSpanByTick :: Session -> Module -> BreakIndex -> IO SrcSpan
-findEnclosingDeclSpanByTick sess m t = withSession sess $ \ hsc_env ->
- return$ InteractiveEval.findEnclosingDeclSpanByTick hsc_env m t
#endif
resume,
abandon, abandonAll,
getResumeContext,
- getHistoryTick,
getHistorySpan,
getHistoryModule,
- findEnclosingDeclSpanByTick,
back, forward,
setContext, getContext,
nameSetToGlobalRdrEnv,
(getHistorySpan hsc_env h)
in h
-getHistoryTick :: History -> BreakIndex
-getHistoryTick = breakInfo_number . historyBreakInfo
-
getHistoryModule :: History -> Module
getHistoryModule = breakInfo_module . historyBreakInfo
-- ^^ assumes md_types is sorted
in decl
--- | Finds the span of the (smallest) function containing this BreakIndex
-findEnclosingDeclSpanByTick :: HscEnv -> Module -> BreakIndex -> SrcSpan
-findEnclosingDeclSpanByTick hsc_env mod tick =
- case lookupUFM (hsc_HPT hsc_env) (moduleName mod) of
- Nothing -> panic "findEnclosingDecl"
- Just hmi -> let
- modbreaks = md_modBreaks (hm_details hmi)
- in ASSERT (inRange (bounds (modBreaks_decls modbreaks)) tick)
- modBreaks_decls modbreaks ! tick
-
-- | Find the Module corresponding to a FilePath
findModuleFromFile :: HscEnv -> FilePath -> Maybe Module
findModuleFromFile hsc_env fp =