lots of portability changes (#1405)
[ghc-hetmet.git] / compiler / deSugar / Coverage.lhs
index 3a3b745..e97ab42 100644 (file)
@@ -24,16 +24,12 @@ import Data.List
 import FastString
 import HscTypes        
 import StaticFlags
-import UniqFM
-import Type
 import TyCon
 import FiniteMap
-import PackageConfig 
 
 import Data.Array
-import System.Time (ClockTime(..))
 import System.IO   (FilePath)
-#if __GLASGOW_HASKELL__ < 603
+#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 603
 import Compat.Directory ( createDirectoryIfMissing )
 #else
 import System.Directory ( createDirectoryIfMissing )
@@ -44,7 +40,6 @@ import Trace.Hpc.Util
 
 import BreakArray 
 import Data.HashTable   ( hashString )
-
 \end{code}
 
 
@@ -59,7 +54,7 @@ addCoverageTicksToBinds
         :: DynFlags
         -> Module
         -> ModLocation          -- of the current module
-       -> [TyCon]              -- type constructor in this module
+        -> [TyCon]             -- type constructor in this module
         -> LHsBinds Id
         -> IO (LHsBinds Id, HpcInfo, ModBreaks)
 
@@ -82,7 +77,7 @@ addCoverageTicksToBinds dflags mod mod_loc tyCons binds = do
                       , inScope      = emptyVarSet
                      , blackList    = listToFM [ (getSrcSpan (tyConName tyCon),()) 
                                                | tyCon <- tyCons ]
-                     , declBlock    = noSrcSpan })
+                      })
                   (TT 
                      { tickBoxCount = 0
                      , mixEntries   = []
@@ -102,7 +97,7 @@ addCoverageTicksToBinds dflags mod mod_loc tyCons binds = do
      createDirectoryIfMissing True hpc_mod_dir
      modTime <- getModificationTime orig_file
      let entries' = [ (hpcPos, box) 
-                    | (span,_,box,_) <- entries, hpcPos <- [mkHpcPos span] ]
+                    | (span,_,box) <- entries, hpcPos <- [mkHpcPos span] ]
      when (length entries' /= tickBoxCount st) $ do
        panic "the number of .mix entries are inconsistent"
      let hashNo = mixHash orig_file modTime tabStop entries'
@@ -116,16 +111,13 @@ addCoverageTicksToBinds dflags mod mod_loc tyCons binds = do
   breakArray <- newBreakArray $ length entries
 
   let locsTicks = listArray (0,tickBoxCount st-1) 
-                     [ span | (span,_,_,_) <- entries ]
+                     [ span | (span,_,_) <- entries ]
       varsTicks = listArray (0,tickBoxCount st-1) 
-                     [ vars | (_,vars,_,_) <- entries ]
-      declsTicks = listArray (0,tickBoxCount st-1) 
-                     [ decls| (_,_,_,decls) <- entries ] 
+                     [ vars | (_,vars,_) <- entries ]
       modBreaks = emptyModBreaks 
                   { modBreaks_flags = breakArray 
                   , modBreaks_locs  = locsTicks 
                   , modBreaks_vars  = varsTicks
-                  , modBreaks_decls = declsTicks
                   } 
 
   doIfSet_dyn dflags  Opt_D_dump_hpc $ do
@@ -145,16 +137,16 @@ addTickLHsBinds :: LHsBinds Id -> TM (LHsBinds Id)
 addTickLHsBinds binds = mapBagM addTickLHsBind binds
 
 addTickLHsBind :: LHsBind Id -> TM (LHsBind Id)
-addTickLHsBind (L pos t@(AbsBinds abs_tvs abs_dicts abs_exports abs_binds)) = do
+addTickLHsBind (L pos (AbsBinds abs_tvs abs_dicts abs_exports abs_binds)) = do
   abs_binds' <- addTickLHsBinds abs_binds
   return $ L pos $ AbsBinds abs_tvs abs_dicts abs_exports abs_binds'
 addTickLHsBind (L pos (funBind@(FunBind { fun_id = (L _ id)  }))) = do 
   let name = getOccString id
   decl_path <- getPathEntry
 
-  (fvs, mg@(MatchGroup matches' ty)) <- 
+  (fvs, (MatchGroup matches' ty)) <- 
         getFreeVars $
-        addPathEntry name pos $
+        addPathEntry name $
         addTickMatchGroup (fun_matches funBind)
 
   blackListed <- isBlackListed pos
@@ -183,7 +175,7 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = (L _ id)  }))) = do
 -- TODO: Revisit this
 addTickLHsBind (L pos (pat@(PatBind { pat_rhs = rhs }))) = do
   let name = "(...)"
-  rhs' <- addPathEntry name pos $ addTickGRHSs False rhs
+  rhs' <- addPathEntry name $ addTickGRHSs False rhs
 {-
   decl_path <- getPathEntry
   tick_me <- allocTickBox (if null decl_path
@@ -192,12 +184,8 @@ addTickLHsBind (L pos (pat@(PatBind { pat_rhs = rhs }))) = do
 -}                        
   return $ L pos $ pat { pat_rhs = rhs' }
 
-{- only internal stuff, not from source, uses VarBind, so we ignore it.
-addTickLHsBind (VarBind var_id var_rhs) = do
-  var_rhs' <- addTickLHsExpr var_rhs  
-  return $ VarBind var_id var_rhs'
--}
-addTickLHsBind other = return other
+-- Only internal stuff, not from source, uses VarBind, so we ignore it.
+addTickLHsBind var_bind@(L _ (VarBind {})) = return var_bind
 
 -- Add a tick to the expression no matter what it is.  There is one exception:
 -- for the debugger, if the expression is a 'let', then we don't want to add
@@ -246,7 +234,7 @@ isGoodBreakExpr (RecordCon {}) = True
 isGoodBreakExpr (RecordUpd {}) = True
 isGoodBreakExpr (ArithSeq {})  = True
 isGoodBreakExpr (PArrSeq {})   = True
-isGoodBreakExpr other          = False 
+isGoodBreakExpr _other         = False 
 
 addTickLHsExprOptAlt :: Bool -> LHsExpr Id -> TM (LHsExpr Id)
 addTickLHsExprOptAlt oneOfMany (L pos e0)
@@ -265,7 +253,7 @@ addTickHsExpr e@(HsVar id) = do freeVar id; return e
 addTickHsExpr e@(HsIPVar _) = return e
 addTickHsExpr e@(HsOverLit _) = return e
 addTickHsExpr e@(HsLit _) = return e
-addTickHsExpr e@(HsLam matchgroup) =
+addTickHsExpr (HsLam matchgroup) =
         liftM HsLam (addTickMatchGroup matchgroup)
 addTickHsExpr (HsApp e1 e2) = 
        liftM2 HsApp (addTickLHsExprNever e1) (addTickLHsExpr e2)
@@ -342,7 +330,7 @@ addTickHsExpr (ArithSeq      ty arith_seq) =
        liftM2 ArithSeq 
                (return ty)
                (addTickArithSeqInfo arith_seq)
-addTickHsExpr (HsTickPragma (file,(l1,c1),(l2,c2)) (L pos e0)) = do
+addTickHsExpr (HsTickPragma _ (L pos e0)) = do
     e2 <- allocTickBox (ExpBox False) pos $
                 addTickHsExpr e0
     return $ unLoc e2
@@ -382,16 +370,12 @@ addTickHsExpr (HsArrForm e fix cmdtop) =
               (return fix)
               (mapM (liftL (addTickHsCmdTop)) cmdtop)
 
-addTickHsExpr e@(HsType ty) = return e
+addTickHsExpr e@(HsType _) = return e
 
 -- Others dhould never happen in expression content.
-addTickHsExpr e@(ExprWithTySig {}) = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(EAsPat _ _)       = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(ELazyPat _)       = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(EWildPat)         = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(HsBinTick _ _ _)  = pprPanic "addTickHsExpr" (ppr e)
-addTickHsExpr e@(HsTick _ _ _)     = pprPanic "addTickHsExpr" (ppr e)
+addTickHsExpr e  = pprPanic "addTickHsExpr" (ppr e)
 
+addTickMatchGroup :: MatchGroup Id -> TM (MatchGroup Id)
 addTickMatchGroup (MatchGroup matches ty) = do
   let isOneOfMany = matchesOneOfMany matches
   matches' <- mapM (liftL (addTickMatch isOneOfMany)) matches
@@ -413,10 +397,10 @@ addTickGRHSs isOneOfMany (GRHSs guarded local_binds) = do
     binders = map unLoc (collectLocalBinders local_binds)
 
 addTickGRHS :: Bool -> GRHS Id -> TM (GRHS Id)
-addTickGRHS isOneOfMany (GRHS stmts expr@(L pos _)) = do
+addTickGRHS isOneOfMany (GRHS stmts expr) = do
   (stmts',expr') <- addTickLStmts' (Just $ BinBox $ GuardBinBox) stmts
                         (if opt_Hpc then addTickLHsExprOptAlt isOneOfMany expr
-                                    else addPathEntry "" pos $ addTickLHsExprAlways expr)
+                                    else addTickLHsExprAlways expr)
   return $ GRHS stmts' expr'
 
 addTickLStmts :: (Maybe (Bool -> BoxLabel)) -> [LStmt Id] -> TM [LStmt Id]
@@ -435,7 +419,7 @@ addTickLStmts' isGuard lstmts res
         binders = map unLoc (collectLStmtsBinders lstmts)
 
 addTickStmt :: (Maybe (Bool -> BoxLabel)) -> Stmt Id -> TM (Stmt Id)
-addTickStmt isGuard (BindStmt pat e bind fail) = do
+addTickStmt _isGuard (BindStmt pat e bind fail) = do
        liftM4 BindStmt
                (addTickLPat pat)
                (addTickLHsExprAlways e)
@@ -443,23 +427,34 @@ addTickStmt isGuard (BindStmt pat e bind fail) = do
                (addTickSyntaxExpr hpcSrcSpan fail)
 addTickStmt isGuard (ExprStmt e bind' ty) = do
        liftM3 ExprStmt
-               (addTick e)
+               (addTick isGuard e)
                (addTickSyntaxExpr hpcSrcSpan bind')
                (return ty)
-  where
-   addTick e | Just fn <- isGuard = addBinTickLHsExpr fn e
-             | otherwise          = addTickLHsExprAlways e
-
-addTickStmt isGuard (LetStmt binds) = do
+addTickStmt _isGuard (LetStmt binds) = do
        liftM LetStmt
                (addTickHsLocalBinds binds)
 addTickStmt isGuard (ParStmt pairs) = do
-       liftM ParStmt (mapM process pairs)
-  where
-       process (stmts,ids) = 
-               liftM2 (,) 
-                       (addTickLStmts isGuard stmts)
-                       (return ids)
+    liftM ParStmt 
+        (mapM (addTickStmtAndBinders isGuard) pairs)
+addTickStmt isGuard (TransformStmt (stmts, ids) usingExpr maybeByExpr) = do
+    liftM3 TransformStmt 
+        (addTickStmtAndBinders isGuard (stmts, ids))
+        (addTickLHsExprAlways usingExpr)
+        (addTickMaybeByLHsExpr maybeByExpr)
+addTickStmt isGuard (GroupStmt (stmts, binderMap) groupByClause) = do
+    liftM2 GroupStmt 
+        (addTickStmtAndBinders isGuard (stmts, binderMap))
+        (case groupByClause of
+            GroupByNothing usingExpr -> addTickLHsExprAlways usingExpr >>= (return . GroupByNothing)
+            GroupBySomething eitherUsingExpr byExpr -> do
+                eitherUsingExpr' <- mapEitherM addTickLHsExprAlways (addTickSyntaxExpr hpcSrcSpan) eitherUsingExpr
+                byExpr' <- addTickLHsExprAlways byExpr
+                return $ GroupBySomething eitherUsingExpr' byExpr')
+    where
+        mapEitherM f g x = do
+          case x of
+            Left a -> f a >>= (return . Left)
+            Right b -> g b >>= (return . Right)
 addTickStmt isGuard (RecStmt stmts ids1 ids2 tys dictbinds) = do
        liftM5 RecStmt 
                (addTickLStmts isGuard stmts)
@@ -468,6 +463,23 @@ addTickStmt isGuard (RecStmt stmts ids1 ids2 tys dictbinds) = do
                (return tys)
                (addTickDictBinds dictbinds)
 
+addTick :: Maybe (Bool -> BoxLabel) -> LHsExpr Id -> TM (LHsExpr Id)
+addTick isGuard e | Just fn <- isGuard = addBinTickLHsExpr fn e
+                  | otherwise          = addTickLHsExprAlways e
+
+addTickStmtAndBinders :: Maybe (Bool -> BoxLabel) -> ([LStmt Id], a) 
+                      -> TM ([LStmt Id], a)
+addTickStmtAndBinders isGuard (stmts, ids) = 
+    liftM2 (,) 
+        (addTickLStmts isGuard stmts)
+        (return ids)
+
+addTickMaybeByLHsExpr :: Maybe (LHsExpr Id) -> TM (Maybe (LHsExpr Id))
+addTickMaybeByLHsExpr maybeByExpr = 
+    case maybeByExpr of
+        Nothing -> return Nothing
+        Just byExpr -> addTickLHsExprAlways byExpr >>= (return . Just)
+
 addTickHsLocalBinds :: HsLocalBinds Id -> TM (HsLocalBinds Id)
 addTickHsLocalBinds (HsValBinds binds) = 
        liftM HsValBinds 
@@ -477,6 +489,7 @@ addTickHsLocalBinds (HsIPBinds binds)  =
                (addTickHsIPBinds binds)
 addTickHsLocalBinds (EmptyLocalBinds)  = return EmptyLocalBinds
 
+addTickHsValBinds :: HsValBindsLR Id a -> TM (HsValBindsLR Id b)
 addTickHsValBinds (ValBindsOut binds sigs) =
        liftM2 ValBindsOut
                (mapM (\ (rec,binds') -> 
@@ -485,7 +498,9 @@ addTickHsValBinds (ValBindsOut binds sigs) =
                                        (addTickLHsBinds binds'))
                        binds)
                (return sigs)
+addTickHsValBinds _ = panic "addTickHsValBinds"
 
+addTickHsIPBinds :: HsIPBinds Id -> TM (HsIPBinds Id)
 addTickHsIPBinds (IPBinds ipbinds dictbinds) =
        liftM2 IPBinds
                (mapM (liftL (addTickIPBind)) ipbinds)
@@ -557,12 +572,12 @@ data TickTransEnv = TTE { fileName      :: FastString
                        , declPath     :: [String]
                         , inScope      :: VarSet
                        , blackList   :: FiniteMap SrcSpan ()
-                        , declBlock   :: SrcSpan
                        }
 
 --     deriving Show
 
 type FreeVars = OccEnv Id
+noFVs :: FreeVars
 noFVs = emptyOccEnv
 
 -- Note [freevars]
@@ -582,7 +597,7 @@ data TM a = TM { unTM :: TickTransEnv -> TickTransState -> (a,FreeVars,TickTrans
         -- monad (FreeVars).
 
 instance Monad TM where
-  return a = TM $ \ env st -> (a,noFVs,st)
+  return a = TM $ \ _env st -> (a,noFVs,st)
   (TM m) >>= k = TM $ \ env st -> 
                                case m env st of
                                  (r1,fv1,st1) -> 
@@ -593,8 +608,8 @@ instance Monad TM where
 -- getState :: TM TickTransState
 -- getState = TM $ \ env st -> (st, noFVs, st)
 
-setState :: (TickTransState -> TickTransState) -> TM ()
-setState f = TM $ \ env st -> ((), noFVs, f st)
+-- setState :: (TickTransState -> TickTransState) -> TM ()
+-- setState f = TM $ \ env st -> ((), noFVs, f st)
 
 getEnv :: TM TickTransEnv
 getEnv = TM $ \ env st -> (env, noFVs, st)
@@ -614,8 +629,8 @@ freeVar id = TM $ \ env st ->
                    then ((), unitOccEnv (nameOccName (idName id)) id, st)
                    else ((), noFVs, st)
 
-addPathEntry :: String -> SrcSpan -> TM a -> TM a
-addPathEntry nm src = withEnv (\ env -> env { declPath = declPath env ++ [nm], declBlock = src })
+addPathEntry :: String -> TM a -> TM a
+addPathEntry nm = withEnv (\ env -> env { declPath = declPath env ++ [nm] })
 
 getPathEntry :: TM [String]
 getPathEntry = declPath `liftM` getEnv
@@ -635,7 +650,7 @@ bindLocals :: [Id] -> TM a -> TM a
 bindLocals new_ids (TM m)
   = TM $ \ env st -> 
                  case m env{ inScope = inScope env `extendVarSetList` new_ids } st of
-                   (r, fv, st') -> (r, fv `delListFromUFM` occs, st')
+                   (r, fv, st') -> (r, fv `delListFromOccEnv` occs, st')
   where occs = [ nameOccName (idName id) | id <- new_ids ] 
 
 isBlackListed :: SrcSpan -> TM Bool
@@ -651,27 +666,25 @@ allocTickBox boxLabel pos m | isGoodSrcSpan' pos =
   sameFileName pos 
     (do e <- m; return (L pos e)) $ do
   (fvs, e) <- getFreeVars m
-  TM $ \ env st ->
+  TM $ \ _env st ->
     let c = tickBoxCount st
         ids = occEnvElts fvs
         mes = mixEntries st
-        parentBlock = if declBlock env == noSrcSpan then pos else declBlock env
-        me = (pos, map (nameOccName.idName) ids, boxLabel, parentBlock)
-    in 
+        me = (pos, map (nameOccName.idName) ids, boxLabel)
+    in
     ( L pos (HsTick c ids (L pos e))
     , fvs
     , st {tickBoxCount=c+1,mixEntries=me:mes}
     )
-allocTickBox boxLabel pos m = do e <- m; return (L pos e)
+allocTickBox _boxLabel pos m = do e <- m; return (L pos e)
 
 -- the tick application inherits the source position of its
 -- expression argument to support nested box allocations 
 allocATickBox :: BoxLabel -> SrcSpan -> FreeVars -> TM (Maybe (Int,[Id]))
 allocATickBox boxLabel pos fvs | isGoodSrcSpan' pos = 
   sameFileName pos 
-    (return Nothing) $ TM $ \ env st ->
-  let parentBlock = if declBlock env == noSrcSpan then pos else declBlock env
-      me = (pos, map (nameOccName.idName) ids, boxLabel, parentBlock)
+    (return Nothing) $ TM $ \ _env st ->
+  let me = (pos, map (nameOccName.idName) ids, boxLabel)
       c = tickBoxCount st
       mes = mixEntries st
       ids = occEnvElts fvs
@@ -679,14 +692,13 @@ allocATickBox boxLabel pos fvs | isGoodSrcSpan' pos =
      , noFVs
      , st {tickBoxCount=c+1, mixEntries=me:mes}
      )
-allocATickBox boxLabel pos fvs = return Nothing
+allocATickBox _boxLabel _pos _fvs = return Nothing
 
 allocBinTickBox :: (Bool -> BoxLabel) -> LHsExpr Id -> TM (LHsExpr Id)
-allocBinTickBox boxLabel (L pos e) | isGoodSrcSpan' pos = TM $ \ env st ->
-  let parentBlock = if declBlock env == noSrcSpan then pos else declBlock env
-      meT = (pos,[],boxLabel True, parentBlock)
-      meF = (pos,[],boxLabel False, parentBlock)
-      meE = (pos,[],ExpBox False, parentBlock)
+allocBinTickBox boxLabel (L pos e) | isGoodSrcSpan' pos = TM $ \ _env st ->
+  let meT = (pos,[],boxLabel True)
+      meF = (pos,[],boxLabel False)
+      meE = (pos,[],ExpBox False)
       c = tickBoxCount st
       mes = mixEntries st
   in 
@@ -698,13 +710,15 @@ allocBinTickBox boxLabel (L pos e) | isGoodSrcSpan' pos = TM $ \ env st ->
              , noFVs
              , st {tickBoxCount=c+3 , mixEntries=meF:meT:meE:mes}
              )
-        else ( L pos $ HsTick c [] $ L pos e
+        else
+             ( L pos $ HsTick c [] $ L pos e
              , noFVs
              , st {tickBoxCount=c+1,mixEntries=meE:mes}
              )
 
-allocBinTickBox boxLabel e = return e
+allocBinTickBox _boxLabel e = return e
 
+isGoodSrcSpan' :: SrcSpan -> Bool
 isGoodSrcSpan' pos
    | not (isGoodSrcSpan pos) = False
    | start == end            = False
@@ -726,8 +740,7 @@ mkHpcPos pos
                     , srcLocCol end
                     )
 
-noHpcPos = toHpcPos (0,0,0,0)
-
+hpcSrcSpan :: SrcSpan
 hpcSrcSpan = mkGeneralSrcSpan (FSLIT("Haskell Program Coverage internals"))
 \end{code}
 
@@ -741,9 +754,7 @@ matchesOneOfMany lmatches = sum (map matchCount lmatches) > 1
 
 
 \begin{code}
-type ParentDecl= SrcSpan
-type TickSpan  = SrcSpan
-type MixEntry_ = (TickSpan, [OccName], BoxLabel, ParentDecl)
+type MixEntry_ = (SrcSpan, [OccName], BoxLabel)
 
 -- For the hash value, we hash everything: the file name, 
 --  the timestamp of the original source file, the tab stop,