Support where clauses, let bindings and case expressions in case splitting (fixes #395)
This commit is contained in:
parent
833d9ce058
commit
56cc237e26
@ -72,7 +72,7 @@ getSrcSpanTypeForFnSplit modSum lineNo colNo = do
|
|||||||
p@ParsedModule{pm_parsed_source = _pms} <- G.parseModule modSum
|
p@ParsedModule{pm_parsed_source = _pms} <- G.parseModule modSum
|
||||||
tcm@TypecheckedModule{tm_typechecked_source = tcs} <- G.typecheckModule p
|
tcm@TypecheckedModule{tm_typechecked_source = tcs} <- G.typecheckModule p
|
||||||
let varPat = find isPatternVar $ listifySpans tcs (lineNo, colNo) :: Maybe (LPat Id)
|
let varPat = find isPatternVar $ listifySpans tcs (lineNo, colNo) :: Maybe (LPat Id)
|
||||||
match:_ = listifySpans tcs (lineNo, colNo) :: [Gap.GLMatchI]
|
match = last $ listifySpans tcs (lineNo, colNo) :: Gap.GLMatchI
|
||||||
case varPat of
|
case varPat of
|
||||||
Nothing -> return Nothing
|
Nothing -> return Nothing
|
||||||
Just varPat' -> do
|
Just varPat' -> do
|
||||||
@ -188,8 +188,11 @@ getCaseSplitText text (SplitToTextInfo { sVarName = sVN, sBindingSpan = sBS
|
|||||||
, sVarSpan = sVS, sTycons = sT }) =
|
, sVarSpan = sVS, sTycons = sT }) =
|
||||||
let bindingText = getBindingText text sBS
|
let bindingText = getBindingText text sBS
|
||||||
difference = srcSpanDifference sBS sVS
|
difference = srcSpanDifference sBS sVS
|
||||||
replaced = concatMap (replaceVarWithTyCon bindingText difference sVN) sT
|
replaced = map (replaceVarWithTyCon bindingText difference sVN) sT
|
||||||
in T.unpack $ T.intercalate (T.pack "\n") replaced
|
-- The newly generated bindings need to be indented to align with the
|
||||||
|
-- original binding.
|
||||||
|
replaced' = head replaced : map (indentBindingTo sBS) (tail replaced)
|
||||||
|
in T.unpack $ T.intercalate (T.pack "\n") (concat replaced')
|
||||||
|
|
||||||
getBindingText :: [T.Text] -> SrcSpan -> [T.Text]
|
getBindingText :: [T.Text] -> SrcSpan -> [T.Text]
|
||||||
getBindingText text srcSpan =
|
getBindingText text srcSpan =
|
||||||
@ -220,3 +223,9 @@ replaceVarWithTyCon text (vsl,vsc,_,vec) varname tycon =
|
|||||||
then T.take vsc line `T.append` tycon'' `T.append` T.drop vec line
|
then T.take vsc line `T.append` tycon'' `T.append` T.drop vec line
|
||||||
else T.replicate spacesToAdd (T.pack " ") `T.append` line)
|
else T.replicate spacesToAdd (T.pack " ") `T.append` line)
|
||||||
[0 ..] text
|
[0 ..] text
|
||||||
|
|
||||||
|
indentBindingTo :: SrcSpan -> [T.Text] -> [T.Text]
|
||||||
|
indentBindingTo bndLoc binds =
|
||||||
|
let Just (_,sl,_,_) = Gap.getSrcSpan bndLoc
|
||||||
|
indent = (T.replicate (sl - 1) (T.pack " ") `T.append`)
|
||||||
|
in indent (head binds) : tail binds
|
||||||
|
@ -34,6 +34,7 @@ Extra-Source-Files: ChangeLog
|
|||||||
test/data/broken-cabal/cabal.sandbox.config.in
|
test/data/broken-cabal/cabal.sandbox.config.in
|
||||||
test/data/broken-sandbox/*.cabal
|
test/data/broken-sandbox/*.cabal
|
||||||
test/data/broken-sandbox/cabal.sandbox.config
|
test/data/broken-sandbox/cabal.sandbox.config
|
||||||
|
test/data/case-split/*.hs
|
||||||
test/data/cabal-flags/*.cabal
|
test/data/cabal-flags/*.cabal
|
||||||
test/data/check-test-subdir/*.cabal
|
test/data/check-test-subdir/*.cabal
|
||||||
test/data/check-test-subdir/src/Check/Test/*.hs
|
test/data/check-test-subdir/src/Check/Test/*.hs
|
||||||
|
@ -18,3 +18,24 @@ spec = do
|
|||||||
res `shouldBe` "24 1 24 30"++
|
res `shouldBe` "24 1 24 30"++
|
||||||
" \"mlAppend Nil y = _mlAppend_body\NUL"++
|
" \"mlAppend Nil y = _mlAppend_body\NUL"++
|
||||||
"mlAppend (Cons x1 x2) y = _mlAppend_body\"\n"
|
"mlAppend (Cons x1 x2) y = _mlAppend_body\"\n"
|
||||||
|
|
||||||
|
it "works with case expressions" $ do
|
||||||
|
withDirectory_ "test/data/case-split" $ do
|
||||||
|
res <- runD $ splits "Vect.hs" 28 20
|
||||||
|
res `shouldBe` "28 19 28 39"++
|
||||||
|
" \"Nil -> _mlAppend_body\NUL"++
|
||||||
|
" (Cons x'1 x'2) -> _mlAppend_body\"\n"
|
||||||
|
|
||||||
|
it "works with where clauses" $ do
|
||||||
|
withDirectory_ "test/data/case-split" $ do
|
||||||
|
res <- runD $ splits "Vect.hs" 34 17
|
||||||
|
res `shouldBe` "34 5 34 43"++
|
||||||
|
" \"mlReverse' Nil accum = _mlReverse_body\NUL"++
|
||||||
|
" mlReverse' (Cons xs'1 xs'2) accum = _mlReverse_body\"\n"
|
||||||
|
|
||||||
|
it "works with let bindings" $ do
|
||||||
|
withDirectory_ "test/data/case-split" $ do
|
||||||
|
res <- runD $ splits "Vect.hs" 38 33
|
||||||
|
res `shouldBe` "38 21 38 59"++
|
||||||
|
" \"mlReverse' Nil accum = _mlReverse_body\NUL"++
|
||||||
|
" mlReverse' (Cons xs'1 xs'2) accum = _mlReverse_body\"\n"
|
||||||
|
@ -22,3 +22,18 @@ data MyList a = Nil | Cons a (MyList a)
|
|||||||
|
|
||||||
mlAppend :: MyList a -> MyList a -> MyList a
|
mlAppend :: MyList a -> MyList a -> MyList a
|
||||||
mlAppend x y = _mlAppend_body
|
mlAppend x y = _mlAppend_body
|
||||||
|
|
||||||
|
mlAppend2 :: MyList a -> MyList a -> MyList a
|
||||||
|
mlAppend2 x y = case x of
|
||||||
|
x' -> _mlAppend_body
|
||||||
|
|
||||||
|
mlReverse :: MyList a -> MyList a
|
||||||
|
mlReverse xs = mlReverse' xs Nil
|
||||||
|
where
|
||||||
|
mlReverse' :: MyList a -> MyList a -> MyList a
|
||||||
|
mlReverse' xs' accum = _mlReverse_body
|
||||||
|
|
||||||
|
mlReverse2 :: MyList a -> MyList a
|
||||||
|
mlReverse2 xs = let mlReverse' :: MyList a -> MyList a -> MyList a
|
||||||
|
mlReverse' xs' accum = _mlReverse_body
|
||||||
|
in mlReverse' xs Nil
|
||||||
|
Loading…
Reference in New Issue
Block a user