Skip to content

Commit 9682bdd

Browse files
committed
[Refactor] Replacements report what was the fill
1 parent bbfe1a8 commit 9682bdd

File tree

3 files changed

+36
-8
lines changed

3 files changed

+36
-8
lines changed

src/Synth/Repair.hs

+13-6
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,21 @@ justTcExpr cc parsed = do
111111
getExprTy :: HscEnv -> LHsExpr GhcTc -> IO (Maybe Type)
112112
getExprTy hsc_env expr = fmap CoreUtils.exprType . snd <$> deSugarExpr hsc_env expr
113113

114-
replacements :: LHsExpr GhcPs -> [[HsExpr GhcPs]] -> [([SrcSpan], LHsExpr GhcPs)]
114+
replacements :: LHsExpr GhcPs -> [[HsExpr GhcPs]] -> [([(SrcSpan, HsExpr GhcPs)], LHsExpr GhcPs)]
115115
replacements r [] = [([], r)]
116116
replacements e (first_hole_fit : rest) = concat rest_fit_res
117117
where
118-
res = map (\(l, e) -> ([l], e)) (mapMaybe (fillHole e) first_hole_fit)
119-
(first_fit_locs, first_fit_res) = unzip res
120-
rest_fit_res = zipWith addL first_fit_locs $ map (`replacements` rest) first_fit_res
121-
addL :: [SrcSpan] -> [([SrcSpan], LHsExpr GhcPs)] -> [([SrcSpan], LHsExpr GhcPs)]
118+
-- mapMaybe', but keep the result
119+
mapMaybe' :: (a -> Maybe b) -> [a] -> [(a, b)]
120+
mapMaybe' _ [] = []
121+
mapMaybe' f (a : as) = (case f a of Just b -> ((a, b) :); _ -> id) $ mapMaybe' f as
122+
res = map (\(e, (l, r)) -> ([(l, e)], r)) (mapMaybe' (fillHole e) first_hole_fit)
123+
(first_fit_locs_and_e, first_fit_res) = unzip res
124+
rest_fit_res = zipWith addL first_fit_locs_and_e $ map (`replacements` rest) first_fit_res
125+
addL ::
126+
[(SrcSpan, HsExpr GhcPs)] ->
127+
[([(SrcSpan, HsExpr GhcPs)], LHsExpr GhcPs)] ->
128+
[([(SrcSpan, HsExpr GhcPs)], LHsExpr GhcPs)]
122129
addL srcs reses = map (first (srcs ++)) reses
123130

124131
-- Translate from the old String based version to the new LHsExpr version.
@@ -307,7 +314,7 @@ repair cc tp@EProb {..} =
307314
-- We add the context by replacing a hole in a let.
308315
let inContext = noLoc . HsLet NoExtField e_ctxt
309316
holeyContext = inContext hole
310-
undefContext = inContext $ noLoc $ HsVar NoExtField $ noLoc $ mkVarUnqual $ fsLit "undefined"
317+
undefContext = inContext $ noLoc undefVar
311318

312319
-- We find expressions that can be used as candidates in the program
313320
expr_cands <- getExprFitCands cc undefContext

src/Synth/Util.hs

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import Data.Bits
55
import Data.Char (isSpace)
66
import Data.List (intercalate, sort)
77
import GHC
8+
import GhcPlugins (fsLit, mkVarUnqual)
89
import SrcLoc
910
import Synth.Types
1011
import System.Environment (getArgs)
@@ -14,6 +15,9 @@ progAtTy :: EExpr -> EType -> EExpr
1415
progAtTy e_prog e_ty =
1516
noLoc $ ExprWithTySig NoExtField (noLoc $ HsPar NoExtField e_prog) e_ty
1617

18+
undefVar :: HsExpr GhcPs
19+
undefVar = HsVar NoExtField $ noLoc $ mkVarUnqual $ fsLit "undefined"
20+
1721
-- Removes whitespace before and after a string
1822
trim :: String -> String
1923
trim = reverse . dropWhile isSpace . reverse . dropWhile isSpace

tests/Tests.hs

+19-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Data.Bits (finiteBitSize)
99
import Data.Dynamic (fromDynamic)
1010
import Data.List (find)
1111
import qualified Data.Map as Map
12-
import Data.Maybe (isJust)
12+
import Data.Maybe (isJust, mapMaybe)
1313
import Data.Tree
1414
import Data.Tuple (swap)
1515
import GhcPlugins (GenLocated (L), getLoc, unLoc)
@@ -23,6 +23,7 @@ import Synth.Eval
2323
showUnsafe,
2424
traceTarget,
2525
)
26+
import Synth.Fill (fillHole)
2627
import Synth.Flatten
2728
import Synth.Repair
2829
( failingProps,
@@ -455,7 +456,23 @@ sanctifyTests =
455456
expr <- runJustParseExpr cc' r_prog
456457
-- There are 7 ways to replace parts of the broken function in BrokenModule
457458
-- with holes:
458-
length (sanctifyExpr expr) @?= 7
459+
length (sanctifyExpr expr) @?= 7,
460+
localOption (mkTimeout 1_000_000) $
461+
testCase "Fill foldl program" $ do
462+
let cc =
463+
CompConf
464+
{ hole_lvl = 0,
465+
packages = ["base", "process", "QuickCheck"],
466+
importStmts = ["import Prelude"]
467+
}
468+
toFix = "tests/BrokenModule.hs"
469+
repair_target = Just "broken"
470+
(cc', _, [RProb {..}]) <- moduleToProb cc toFix repair_target
471+
expr <- runJustParseExpr cc' r_prog
472+
let (holes, holey) = unzip $ sanctifyExpr expr
473+
filled = mapMaybe (`fillHole` undefVar) holey
474+
length filled @?= 7
475+
all (uncurry (==)) (zip holes (map fst filled)) @? "All fillings should match holes!"
459476
]
460477

461478
moduleTests =

0 commit comments

Comments
 (0)