| ... |
... |
@@ -251,7 +251,7 @@ addTickLHsBind (L pos (XHsBindsLR bind@(AbsBinds { abs_binds = binds |
|
251
|
251
|
|
|
252
|
252
|
add_rec_sels env =
|
|
253
|
253
|
env{ recSelBinds = recSelBinds env `extendVarEnvList`
|
|
254
|
|
- [ (abe_mono, abe_poly)
|
|
|
254
|
+ [ (abe_mono, [abe_poly])
|
|
255
|
255
|
| ABE{ abe_poly, abe_mono } <- abs_exports
|
|
256
|
256
|
, RecSelId{} <- [idDetails abe_poly] ] }
|
|
257
|
257
|
|
| ... |
... |
@@ -270,8 +270,8 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches |
|
270
|
270
|
case tickish of { ProfNotes | inline -> return (L pos funBind); _ -> do
|
|
271
|
271
|
|
|
272
|
272
|
-- See Note [Record-selector ticks]
|
|
273
|
|
- selTick <- recSelTick id
|
|
274
|
|
- case selTick of { Just tick -> tick_rec_sel tick; _ -> do
|
|
|
273
|
+ selTicks <- recSelTick id
|
|
|
274
|
+ case selTicks of { Just ticks -> tick_rec_sel ticks; _ -> do
|
|
275
|
275
|
|
|
276
|
276
|
(fvs, mg) <-
|
|
277
|
277
|
getFreeVars $
|
| ... |
... |
@@ -303,8 +303,8 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches |
|
303
|
303
|
} }
|
|
304
|
304
|
where
|
|
305
|
305
|
-- See Note [Record-selector ticks]
|
|
306
|
|
- tick_rec_sel tick =
|
|
307
|
|
- pure $ L pos $ funBind { fun_ext = second (tick :) (fun_ext funBind) }
|
|
|
306
|
+ tick_rec_sel ticks =
|
|
|
307
|
+ pure $ L pos $ funBind { fun_ext = second (ticks ++) (fun_ext funBind) }
|
|
308
|
308
|
|
|
309
|
309
|
|
|
310
|
310
|
-- Note [Record-selector ticks]
|
| ... |
... |
@@ -319,9 +319,8 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches |
|
319
|
319
|
-- coverage purposes to improve the developer experience.
|
|
320
|
320
|
--
|
|
321
|
321
|
-- This is done by keeping track of which 'Id's are effectively bound to
|
|
322
|
|
--- record fields (using NamedFieldPuns or RecordWildCards) in 'TickTransEnv's
|
|
323
|
|
--- 'recSelBinds', and making 'HsVar's corresponding to those fields tick the
|
|
324
|
|
--- appropriate box when executed.
|
|
|
322
|
+-- record fields in 'TickTransEnv's 'recSelBinds', and making 'HsVar's
|
|
|
323
|
+-- corresponding to those fields tick the appropriate box when executed.
|
|
325
|
324
|
--
|
|
326
|
325
|
-- To enable that, we also treat 'FunBind's for record selector functions
|
|
327
|
326
|
-- specially. We only create a TopLevelBox for the record selector function,
|
| ... |
... |
@@ -330,10 +329,7 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches |
|
330
|
329
|
-- the fun_matches match group for record selector functions.
|
|
331
|
330
|
--
|
|
332
|
331
|
-- This scheme could be extended further in the future, making coverage for
|
|
333
|
|
--- constructor fields (named or even positional) mean that the field was
|
|
334
|
|
--- accessed at run-time. For the time being, we only cover NamedFieldPuns and
|
|
335
|
|
--- RecordWildCards binds to cover most practical use-cases while keeping it
|
|
336
|
|
--- simple.
|
|
|
332
|
+-- positional constructor fields mean that the field was accessed at run-time.
|
|
337
|
333
|
|
|
338
|
334
|
-- TODO: Revisit this
|
|
339
|
335
|
addTickLHsBind (L pos (pat@(PatBind { pat_lhs = lhs
|
| ... |
... |
@@ -519,7 +515,7 @@ addTickHsExpr :: HsExpr GhcTc -> TM (HsExpr GhcTc) |
|
519
|
515
|
-- See Note [Record-selector ticks]
|
|
520
|
516
|
addTickHsExpr e@(HsVar _ (L _ id)) =
|
|
521
|
517
|
freeVar id >> recSelTick id >>= pure . maybe e wrap
|
|
522
|
|
- where wrap tick = XExpr . HsTick tick . noLocA $ e
|
|
|
518
|
+ where wrap = foldr (\tick -> XExpr . HsTick tick . noLocA) e
|
|
523
|
519
|
addTickHsExpr e@(HsIPVar {}) = return e
|
|
524
|
520
|
addTickHsExpr e@(HsOverLit {}) = return e
|
|
525
|
521
|
addTickHsExpr e@(HsOverLabel{}) = return e
|
| ... |
... |
@@ -1086,7 +1082,7 @@ data TickTransEnv = TTE { fileName :: FastString |
|
1086
|
1082
|
, blackList :: Set RealSrcSpan
|
|
1087
|
1083
|
, this_mod :: Module
|
|
1088
|
1084
|
, tickishType :: TickishType
|
|
1089
|
|
- , recSelBinds :: IdEnv Id
|
|
|
1085
|
+ , recSelBinds :: IdEnv [Id]
|
|
1090
|
1086
|
}
|
|
1091
|
1087
|
|
|
1092
|
1088
|
-- deriving Show
|
| ... |
... |
@@ -1241,11 +1237,12 @@ allocTickBox boxLabel countEntries topOnly pos m |
|
1241
|
1237
|
tickish <- mkTickish boxLabel countEntries topOnly pos fvs (declPath env)
|
|
1242
|
1238
|
return (this_loc (XExpr $ HsTick tickish $ this_loc e))
|
|
1243
|
1239
|
|
|
1244
|
|
-recSelTick :: Id -> TM (Maybe CoreTickish)
|
|
|
1240
|
+recSelTick :: Id -> TM (Maybe [CoreTickish])
|
|
1245
|
1241
|
recSelTick id = ifDensity TickForCoverage maybe_tick (pure Nothing)
|
|
1246
|
1242
|
where
|
|
1247
|
1243
|
maybe_tick = getEnv >>=
|
|
1248
|
|
- maybe (pure Nothing) tick . (`lookupVarEnv` id) . recSelBinds
|
|
|
1244
|
+ maybe (pure Nothing) tick_all . (`lookupVarEnv` id) . recSelBinds
|
|
|
1245
|
+ tick_all = fmap (Just . catMaybes) . mapM tick
|
|
1249
|
1246
|
tick sel = getState >>=
|
|
1250
|
1247
|
maybe (alloc sel) (pure . Just) . (`lookupVarEnv` sel) . recSelTicks
|
|
1251
|
1248
|
alloc sel = allocATickBox (box sel) False False (getSrcSpan sel) noFVs
|
| ... |
... |
@@ -1367,7 +1364,7 @@ class CollectBinders a where |
|
1367
|
1364
|
--
|
|
1368
|
1365
|
-- See Note [Record-selector ticks].
|
|
1369
|
1366
|
class CollectFldBinders a where
|
|
1370
|
|
- collectFldBinds :: a -> IdEnv Id
|
|
|
1367
|
+ collectFldBinds :: a -> IdEnv [Id]
|
|
1371
|
1368
|
|
|
1372
|
1369
|
instance CollectBinders (LocatedA (Pat GhcTc)) where
|
|
1373
|
1370
|
collectBinds = collectPatBinders CollNoDictBinders
|
| ... |
... |
@@ -1385,41 +1382,39 @@ instance (CollectFldBinders a) => CollectFldBinders [a] where |
|
1385
|
1382
|
instance (CollectFldBinders e) => CollectFldBinders (GenLocated l e) where
|
|
1386
|
1383
|
collectFldBinds = collectFldBinds . unLoc
|
|
1387
|
1384
|
instance CollectFldBinders (Pat GhcTc) where
|
|
1388
|
|
- collectFldBinds ConPat{ pat_args = RecCon HsRecFields{ rec_flds, rec_dotdot } } =
|
|
1389
|
|
- collectFldBinds rec_flds `plusVarEnv` plusVarEnvList (zipWith fld_bnds [0..] rec_flds)
|
|
1390
|
|
- where n_explicit | Just (L _ (RecFieldsDotDot n)) <- rec_dotdot = n
|
|
1391
|
|
- | otherwise = length rec_flds
|
|
1392
|
|
- fld_bnds n (L _ HsFieldBind{ hfbLHS = L _ FieldOcc{ foLabel = L _ sel }
|
|
1393
|
|
- , hfbRHS = L _ (VarPat _ (L _ var))
|
|
1394
|
|
- , hfbPun })
|
|
1395
|
|
- | hfbPun || n >= n_explicit = unitVarEnv var sel
|
|
1396
|
|
- fld_bnds _ _ = emptyVarEnv
|
|
1397
|
|
- collectFldBinds ConPat{ pat_args = PrefixCon pats } = collectFldBinds pats
|
|
1398
|
|
- collectFldBinds ConPat{ pat_args = InfixCon p1 p2 } = collectFldBinds [p1, p2]
|
|
1399
|
|
- collectFldBinds (LazyPat _ pat) = collectFldBinds pat
|
|
1400
|
|
- collectFldBinds (BangPat _ pat) = collectFldBinds pat
|
|
1401
|
|
- collectFldBinds (AsPat _ _ pat) = collectFldBinds pat
|
|
1402
|
|
- collectFldBinds (ViewPat _ _ pat) = collectFldBinds pat
|
|
1403
|
|
- collectFldBinds (ParPat _ pat) = collectFldBinds pat
|
|
1404
|
|
- collectFldBinds (ListPat _ pats) = collectFldBinds pats
|
|
1405
|
|
- collectFldBinds (TuplePat _ pats _) = collectFldBinds pats
|
|
1406
|
|
- collectFldBinds (SumPat _ pats _ _) = collectFldBinds pats
|
|
1407
|
|
- collectFldBinds (SigPat _ pat _) = collectFldBinds pat
|
|
1408
|
|
- collectFldBinds (XPat exp) = collectFldBinds exp
|
|
1409
|
|
- collectFldBinds VarPat{} = emptyVarEnv
|
|
1410
|
|
- collectFldBinds WildPat{} = emptyVarEnv
|
|
1411
|
|
- collectFldBinds OrPat{} = emptyVarEnv
|
|
1412
|
|
- collectFldBinds LitPat{} = emptyVarEnv
|
|
1413
|
|
- collectFldBinds NPat{} = emptyVarEnv
|
|
1414
|
|
- collectFldBinds NPlusKPat{} = emptyVarEnv
|
|
1415
|
|
- collectFldBinds SplicePat{} = emptyVarEnv
|
|
1416
|
|
- collectFldBinds EmbTyPat{} = emptyVarEnv
|
|
1417
|
|
- collectFldBinds InvisPat{} = emptyVarEnv
|
|
|
1385
|
+ collectFldBinds = go [] where
|
|
|
1386
|
+ go path ConPat{ pat_args = RecCon HsRecFields{ rec_flds } } =
|
|
|
1387
|
+ plusVarEnvList (map fld_binds rec_flds)
|
|
|
1388
|
+ where fld_binds (L _ HsFieldBind{ hfbLHS = L _ FieldOcc{ foLabel = L _ sel }
|
|
|
1389
|
+ , hfbRHS = L _ rhs })
|
|
|
1390
|
+ = go (sel:path) rhs
|
|
|
1391
|
+ go path ConPat{ pat_args = PrefixCon ps } =
|
|
|
1392
|
+ plusVarEnvList (map (go path . unLoc) ps)
|
|
|
1393
|
+ go path ConPat{ pat_args = InfixCon (L _ p1) (L _ p2) } =
|
|
|
1394
|
+ go path p1 `plusVarEnv` go path p2
|
|
|
1395
|
+ go [] VarPat{} = emptyVarEnv
|
|
|
1396
|
+ go path (VarPat _ (L _ var)) = unitVarEnv var path
|
|
|
1397
|
+ go path (LazyPat _ (L _ p)) = go path p
|
|
|
1398
|
+ go path (BangPat _ (L _ p)) = go path p
|
|
|
1399
|
+ go path (AsPat _ _ (L _ p)) = go path p
|
|
|
1400
|
+ go path (ViewPat _ _ (L _ p)) = go path p
|
|
|
1401
|
+ go path (ParPat _ (L _ p)) = go path p
|
|
|
1402
|
+ go path (SigPat _ (L _ p) _) = go path p
|
|
|
1403
|
+ go path (SumPat _ (L _ p) _ _) = go path p
|
|
|
1404
|
+ go path (XPat (CoPat _ p _)) = go path p
|
|
|
1405
|
+ go path (XPat (ExpansionPat _ p)) = go path p
|
|
|
1406
|
+ go path (ListPat _ ps) = plusVarEnvList (map (go path . unLoc) ps)
|
|
|
1407
|
+ go path (TuplePat _ ps _) = plusVarEnvList (map (go path . unLoc) ps)
|
|
|
1408
|
+ go _ WildPat{} = emptyVarEnv
|
|
|
1409
|
+ go _ OrPat{} = emptyVarEnv
|
|
|
1410
|
+ go _ LitPat{} = emptyVarEnv
|
|
|
1411
|
+ go _ NPat{} = emptyVarEnv
|
|
|
1412
|
+ go _ NPlusKPat{} = emptyVarEnv
|
|
|
1413
|
+ go _ SplicePat{} = emptyVarEnv
|
|
|
1414
|
+ go _ EmbTyPat{} = emptyVarEnv
|
|
|
1415
|
+ go _ InvisPat{} = emptyVarEnv
|
|
1418
|
1416
|
instance (CollectFldBinders r) => CollectFldBinders (HsFieldBind l r) where
|
|
1419
|
1417
|
collectFldBinds = collectFldBinds . hfbRHS
|
|
1420
|
|
-instance CollectFldBinders XXPatGhcTc where
|
|
1421
|
|
- collectFldBinds (CoPat _ pat _) = collectFldBinds pat
|
|
1422
|
|
- collectFldBinds (ExpansionPat _ pat) = collectFldBinds pat
|
|
1423
|
1418
|
instance CollectFldBinders (HsLocalBinds GhcTc) where
|
|
1424
|
1419
|
collectFldBinds (HsValBinds _ bnds) = collectFldBinds bnds
|
|
1425
|
1420
|
collectFldBinds HsIPBinds{} = emptyVarEnv
|
| ... |
... |
@@ -1430,9 +1425,9 @@ instance CollectFldBinders (HsValBinds GhcTc) where |
|
1430
|
1425
|
instance CollectFldBinders (HsBind GhcTc) where
|
|
1431
|
1426
|
collectFldBinds PatBind{ pat_lhs } = collectFldBinds pat_lhs
|
|
1432
|
1427
|
collectFldBinds (XHsBindsLR AbsBinds{ abs_exports, abs_binds }) =
|
|
1433
|
|
- mkVarEnv [ (abe_poly, sel)
|
|
|
1428
|
+ mkVarEnv [ (abe_poly, sels)
|
|
1434
|
1429
|
| ABE{ abe_poly, abe_mono } <- abs_exports
|
|
1435
|
|
- , Just sel <- [lookupVarEnv monos abe_mono] ]
|
|
|
1430
|
+ , Just sels <- [lookupVarEnv monos abe_mono] ]
|
|
1436
|
1431
|
where monos = collectFldBinds abs_binds
|
|
1437
|
1432
|
collectFldBinds VarBind{} = emptyVarEnv
|
|
1438
|
1433
|
collectFldBinds FunBind{} = emptyVarEnv
|