Respect special where ind.; Some layouting fixes
parent
9949ed7225
commit
6b748ea3eb
|
@ -74,6 +74,7 @@ library {
|
||||||
, strict >=0.3.2 && <0.4
|
, strict >=0.3.2 && <0.4
|
||||||
, monad-memo >=0.4.1 && <0.5
|
, monad-memo >=0.4.1 && <0.5
|
||||||
, unsafe >=0.0 && <0.1
|
, unsafe >=0.0 && <0.1
|
||||||
|
, safe >=0.3.9 && <0.4
|
||||||
, deepseq >=1.4.2.0 && <1.5
|
, deepseq >=1.4.2.0 && <1.5
|
||||||
}
|
}
|
||||||
default-extensions: {
|
default-extensions: {
|
||||||
|
@ -129,6 +130,7 @@ executable brittany
|
||||||
, uniplate
|
, uniplate
|
||||||
, strict
|
, strict
|
||||||
, monad-memo
|
, monad-memo
|
||||||
|
, safe
|
||||||
}
|
}
|
||||||
hs-source-dirs: src-brittany
|
hs-source-dirs: src-brittany
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
@ -193,6 +195,7 @@ test-suite unittests
|
||||||
, uniplate
|
, uniplate
|
||||||
, strict
|
, strict
|
||||||
, monad-memo
|
, monad-memo
|
||||||
|
, safe
|
||||||
}
|
}
|
||||||
ghc-options: -Wall
|
ghc-options: -Wall
|
||||||
main-is: TestMain.hs
|
main-is: TestMain.hs
|
||||||
|
|
|
@ -768,6 +768,8 @@ transformSimplifyFloating = stepBO .> stepFull
|
||||||
-- note that semantically, stepFull is completely sufficient.
|
-- note that semantically, stepFull is completely sufficient.
|
||||||
-- but the bottom-up switch-to-top-down-on-match transformation has much
|
-- but the bottom-up switch-to-top-down-on-match transformation has much
|
||||||
-- better complexity.
|
-- better complexity.
|
||||||
|
-- UPDATE: by now, stepBO does more than stepFull; for semantic equivalence
|
||||||
|
-- the push/pop cases would need to be copied over
|
||||||
where
|
where
|
||||||
descendPost = transformDownMay $ \case
|
descendPost = transformDownMay $ \case
|
||||||
-- post floating in
|
-- post floating in
|
||||||
|
@ -796,19 +798,19 @@ transformSimplifyFloating = stepBO .> stepFull
|
||||||
Just $ BDAddBaseY indent $ BDAnnotationPrior annKey1 x
|
Just $ BDAddBaseY indent $ BDAnnotationPrior annKey1 x
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
descendBYPush = transformDownMay $ \case
|
descendBYPush = transformDownMay $ \case
|
||||||
BDBaseYPushCur (BDCols sig cols) ->
|
BDBaseYPushCur (BDCols sig cols@(_:_)) ->
|
||||||
Just $ BDCols sig (BDBaseYPushCur (List.head cols) : List.tail cols)
|
Just $ BDCols sig (BDBaseYPushCur (List.head cols) : List.tail cols)
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
descendBYPop = transformDownMay $ \case
|
descendBYPop = transformDownMay $ \case
|
||||||
BDBaseYPop (BDCols sig cols) ->
|
BDBaseYPop (BDCols sig cols@(_:_)) ->
|
||||||
Just $ BDCols sig (List.init cols ++ [BDBaseYPop (List.last cols)])
|
Just $ BDCols sig (List.init cols ++ [BDBaseYPop (List.last cols)])
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
descendILPush = transformDownMay $ \case
|
descendILPush = transformDownMay $ \case
|
||||||
BDIndentLevelPushCur (BDCols sig cols) ->
|
BDIndentLevelPushCur (BDCols sig cols@(_:_)) ->
|
||||||
Just $ BDCols sig (BDIndentLevelPushCur (List.head cols) : List.tail cols)
|
Just $ BDCols sig (BDIndentLevelPushCur (List.head cols) : List.tail cols)
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
descendILPop = transformDownMay $ \case
|
descendILPop = transformDownMay $ \case
|
||||||
BDIndentLevelPop (BDCols sig cols) ->
|
BDIndentLevelPop (BDCols sig cols@(_:_)) ->
|
||||||
Just $ BDCols sig (List.init cols ++ [BDIndentLevelPop (List.last cols)])
|
Just $ BDCols sig (List.init cols ++ [BDIndentLevelPop (List.last cols)])
|
||||||
_ -> Nothing
|
_ -> Nothing
|
||||||
descendAddB = transformDownMay $ \case
|
descendAddB = transformDownMay $ \case
|
||||||
|
|
|
@ -149,11 +149,25 @@ layoutPatternBindFinal binderDoc mPatDoc clauseDocs mWhereDocs = do
|
||||||
patPartParWrap = case mPatDoc of
|
patPartParWrap = case mPatDoc of
|
||||||
Nothing -> id
|
Nothing -> id
|
||||||
Just patDoc -> docPar (return patDoc)
|
Just patDoc -> docPar (return patDoc)
|
||||||
_whereIndent <- mAsk
|
whereIndent <- mAsk
|
||||||
<&> _conf_layout
|
<&> _conf_layout
|
||||||
.> _lconfig_indentWhereSpecial
|
.> _lconfig_indentWhereSpecial
|
||||||
.> runIdentity
|
.> runIdentity
|
||||||
.> Bool.bool BrIndentRegular (BrIndentSpecial 1)
|
.> Bool.bool BrIndentRegular (BrIndentSpecial 1)
|
||||||
|
-- TODO: apart from this, there probably are more nodes below which could
|
||||||
|
-- be shared between alternatives.
|
||||||
|
wherePartMultiLine :: [ToBriDocM BriDocNumbered] <- case mWhereDocs of
|
||||||
|
Nothing -> return $ []
|
||||||
|
Just ws -> fmap (fmap return) $ sequence $ return @[]
|
||||||
|
$ docEnsureIndent whereIndent
|
||||||
|
$ docLines
|
||||||
|
[ docLit $ Text.pack "where"
|
||||||
|
, docEnsureIndent whereIndent
|
||||||
|
$ docSetIndentLevel
|
||||||
|
$ docNonBottomSpacing
|
||||||
|
$ docLines
|
||||||
|
$ return <$> ws
|
||||||
|
]
|
||||||
docAlt $
|
docAlt $
|
||||||
-- one-line solution
|
-- one-line solution
|
||||||
[ docCols ColBindingLine
|
[ docCols ColBindingLine
|
||||||
|
@ -177,38 +191,48 @@ layoutPatternBindFinal binderDoc mPatDoc clauseDocs mWhereDocs = do
|
||||||
$ [appSep $ docLit $ Text.pack "|"]
|
$ [appSep $ docLit $ Text.pack "|"]
|
||||||
++ List.intersperse docCommaSep (return <$> gs)
|
++ List.intersperse docCommaSep (return <$> gs)
|
||||||
++ [docSeparator]
|
++ [docSeparator]
|
||||||
, let
|
, wherePart <- case mWhereDocs of
|
||||||
wherePart = case mWhereDocs of
|
Nothing -> return @[] $ docEmpty
|
||||||
Nothing -> docEmpty
|
Just [w] -> return @[] $ docSeq
|
||||||
Just [w] -> docAlt
|
|
||||||
[ docSeq
|
|
||||||
[ docSeparator
|
[ docSeparator
|
||||||
, appSep $ docLit $ Text.pack "where"
|
, appSep $ docLit $ Text.pack "where"
|
||||||
, docSetIndentLevel $ docForceSingleline $ return w
|
, docSetIndentLevel $ docForceSingleline $ return w
|
||||||
]
|
]
|
||||||
, docAddBaseY BrIndentRegular
|
_ -> []
|
||||||
$ docPar docEmpty
|
|
||||||
$ docAddBaseY BrIndentRegular
|
|
||||||
$ docPar
|
|
||||||
(docLit $ Text.pack "where")
|
|
||||||
(docSetIndentLevel $ return w)
|
|
||||||
]
|
|
||||||
Just ws ->
|
|
||||||
docAddBaseY BrIndentRegular
|
|
||||||
$ docPar docEmpty
|
|
||||||
$ docAddBaseY BrIndentRegular
|
|
||||||
$ docPar
|
|
||||||
(docLit $ Text.pack "where")
|
|
||||||
(docSetIndentLevel $ docLines $ return <$> ws)
|
|
||||||
] ++
|
] ++
|
||||||
-- two-line solution
|
-- one-line solution + where in next line(s)
|
||||||
|
[ docLines
|
||||||
|
$ [ docCols ColBindingLine
|
||||||
|
[ docSeq
|
||||||
|
(patPartInline ++ [guardPart])
|
||||||
|
, docSeq
|
||||||
|
[ appSep $ return binderDoc
|
||||||
|
, lineMod $ return body
|
||||||
|
]
|
||||||
|
]
|
||||||
|
] ++ wherePartMultiLine
|
||||||
|
| [(guards, body, bodyRaw)] <- [clauseDocs]
|
||||||
|
, let lineMod = case mWhereDocs of
|
||||||
|
Nothing | isExpressionTypeHeadPar bodyRaw ->
|
||||||
|
docAddBaseY BrIndentRegular
|
||||||
|
_ -> docForceSingleline
|
||||||
|
, let guardPart = case guards of
|
||||||
|
[] -> docEmpty
|
||||||
|
[g] -> docSeq [appSep $ docLit $ Text.pack "|", return g, docSeparator]
|
||||||
|
gs -> docSeq
|
||||||
|
$ [appSep $ docLit $ Text.pack "|"]
|
||||||
|
++ List.intersperse docCommaSep (return <$> gs)
|
||||||
|
++ [docSeparator]
|
||||||
|
, Data.Maybe.isJust mWhereDocs
|
||||||
|
] ++
|
||||||
|
-- two-line solution + where in next line(s)
|
||||||
[ docLines
|
[ docLines
|
||||||
$ [ docForceSingleline
|
$ [ docForceSingleline
|
||||||
$ docSeq (patPartInline ++ [guardPart, return binderDoc])
|
$ docSeq (patPartInline ++ [guardPart, return binderDoc])
|
||||||
, docEnsureIndent BrIndentRegular
|
, docEnsureIndent BrIndentRegular
|
||||||
$ docForceSingleline
|
$ docForceSingleline
|
||||||
$ return body
|
$ return body
|
||||||
] ++ wherePart
|
] ++ wherePartMultiLine
|
||||||
| [(guards, body, _bodyRaw)] <- [clauseDocs]
|
| [(guards, body, _bodyRaw)] <- [clauseDocs]
|
||||||
, let guardPart = case guards of
|
, let guardPart = case guards of
|
||||||
[] -> docEmpty
|
[] -> docEmpty
|
||||||
|
@ -217,14 +241,9 @@ layoutPatternBindFinal binderDoc mPatDoc clauseDocs mWhereDocs = do
|
||||||
$ [appSep $ docLit $ Text.pack "|"]
|
$ [appSep $ docLit $ Text.pack "|"]
|
||||||
++ List.intersperse docCommaSep (return <$> gs)
|
++ List.intersperse docCommaSep (return <$> gs)
|
||||||
++ [docSeparator]
|
++ [docSeparator]
|
||||||
, let wherePart = case mWhereDocs of
|
|
||||||
Nothing -> []
|
|
||||||
Just ws -> pure $ docEnsureIndent BrIndentRegular $ docPar
|
|
||||||
(docLit $ Text.pack "where")
|
|
||||||
(docSetIndentLevel $ docLines $ return <$> ws)
|
|
||||||
] ++
|
] ++
|
||||||
-- pattern and exactly one clause in single line, body and where
|
-- pattern and exactly one clause in single line, body as par;
|
||||||
-- indented if necessary.
|
-- where in following lines
|
||||||
[ docLines
|
[ docLines
|
||||||
$ [ docCols ColBindingLine
|
$ [ docCols ColBindingLine
|
||||||
[ docSeq
|
[ docSeq
|
||||||
|
@ -238,7 +257,7 @@ layoutPatternBindFinal binderDoc mPatDoc clauseDocs mWhereDocs = do
|
||||||
-- ]
|
-- ]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
] ++ wherePart
|
] ++ wherePartMultiLine
|
||||||
| [(guards, body, bodyRaw)] <- [clauseDocs]
|
| [(guards, body, bodyRaw)] <- [clauseDocs]
|
||||||
, let lineMod = case () of
|
, let lineMod = case () of
|
||||||
_ | isExpressionTypeHeadPar bodyRaw -> id
|
_ | isExpressionTypeHeadPar bodyRaw -> id
|
||||||
|
@ -249,20 +268,15 @@ layoutPatternBindFinal binderDoc mPatDoc clauseDocs mWhereDocs = do
|
||||||
gs -> docSeq
|
gs -> docSeq
|
||||||
$ [appSep $ docLit $ Text.pack "|"]
|
$ [appSep $ docLit $ Text.pack "|"]
|
||||||
++ List.intersperse docCommaSep (return <$> gs)
|
++ List.intersperse docCommaSep (return <$> gs)
|
||||||
, let wherePart = case mWhereDocs of
|
|
||||||
Nothing -> []
|
|
||||||
Just ws -> pure $ docEnsureIndent BrIndentRegular $ docPar
|
|
||||||
(docLit $ Text.pack "where")
|
|
||||||
(docSetIndentLevel $ docLines $ return <$> ws)
|
|
||||||
] ++
|
] ++
|
||||||
-- pattern and exactly one clause in single line, body in new line.
|
-- pattern and exactly one clause in single line, body in new line.
|
||||||
[ docAddBaseY BrIndentRegular
|
[ docLines
|
||||||
$ docPar
|
$ [ docSeq (patPartInline ++ [appSep $ guardPart, return binderDoc])
|
||||||
(docSeq (patPartInline ++ [appSep $ guardPart, return binderDoc]))
|
, docEnsureIndent BrIndentRegular
|
||||||
( docNonBottomSpacing
|
$ docNonBottomSpacing
|
||||||
$ docLines
|
$ docLines
|
||||||
$ [ docAddBaseY BrIndentRegular $ return body ] ++ wherePart
|
$ [ docAddBaseY BrIndentRegular $ return body ]
|
||||||
)
|
] ++ wherePartMultiLine
|
||||||
| [(guards, body, _)] <- [clauseDocs]
|
| [(guards, body, _)] <- [clauseDocs]
|
||||||
, let guardPart = case guards of
|
, let guardPart = case guards of
|
||||||
[] -> docEmpty
|
[] -> docEmpty
|
||||||
|
@ -270,17 +284,13 @@ layoutPatternBindFinal binderDoc mPatDoc clauseDocs mWhereDocs = do
|
||||||
gs -> docSeq
|
gs -> docSeq
|
||||||
$ [appSep $ docLit $ Text.pack "|"]
|
$ [appSep $ docLit $ Text.pack "|"]
|
||||||
++ List.intersperse docCommaSep (return <$> gs)
|
++ List.intersperse docCommaSep (return <$> gs)
|
||||||
, let wherePart = case mWhereDocs of
|
|
||||||
Nothing -> []
|
|
||||||
Just ws -> pure $ docAddBaseY BrIndentRegular $ docPar
|
|
||||||
(docLit $ Text.pack "where")
|
|
||||||
(docSetIndentLevel $ docLines $ return <$> ws)
|
|
||||||
] ++
|
] ++
|
||||||
-- conservative approach: everything starts on the left.
|
-- conservative approach: everything starts on the left.
|
||||||
[ docAddBaseY BrIndentRegular
|
[ docLines $
|
||||||
$ patPartParWrap
|
[ patPartParWrap
|
||||||
$ docLines $
|
$ docLines
|
||||||
(clauseDocs >>= \(guardDocs, bodyDoc, _) ->
|
$ fmap (docEnsureIndent BrIndentRegular)
|
||||||
|
$ clauseDocs >>= \(guardDocs, bodyDoc, _) ->
|
||||||
(case guardDocs of
|
(case guardDocs of
|
||||||
[] -> []
|
[] -> []
|
||||||
[g] -> [docSeq [appSep $ docLit $ Text.pack "|", return g]]
|
[g] -> [docSeq [appSep $ docLit $ Text.pack "|", return g]]
|
||||||
|
@ -295,13 +305,5 @@ layoutPatternBindFinal binderDoc mPatDoc clauseDocs mWhereDocs = do
|
||||||
[ appSep $ return binderDoc
|
[ appSep $ return binderDoc
|
||||||
, docAddBaseY BrIndentRegular $ return bodyDoc]
|
, docAddBaseY BrIndentRegular $ return bodyDoc]
|
||||||
]
|
]
|
||||||
) ++
|
] ++ wherePartMultiLine
|
||||||
(case mWhereDocs of
|
|
||||||
Nothing -> []
|
|
||||||
Just whereDocs ->
|
|
||||||
[ docAddBaseY BrIndentRegular
|
|
||||||
$ docPar (docLit $ Text.pack "where")
|
|
||||||
$ docSetIndentLevel $ docLines (return <$> whereDocs)
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -46,7 +46,7 @@ layoutStmt lstmt@(L _ stmt) = docWrapNode lstmt $ case stmt of
|
||||||
Just [bindDoc] -> docAlt
|
Just [bindDoc] -> docAlt
|
||||||
[ docCols ColDoLet
|
[ docCols ColDoLet
|
||||||
[ appSep $ docLit $ Text.pack "let"
|
[ appSep $ docLit $ Text.pack "let"
|
||||||
, docSetIndentLevel $ docAddBaseY BrIndentRegular (return bindDoc)
|
, docSetIndentLevel $ return bindDoc
|
||||||
]
|
]
|
||||||
, docAddBaseY BrIndentRegular $ docPar
|
, docAddBaseY BrIndentRegular $ docPar
|
||||||
(docLit $ Text.pack "let")
|
(docLit $ Text.pack "let")
|
||||||
|
@ -59,17 +59,17 @@ layoutStmt lstmt@(L _ stmt) = docWrapNode lstmt $ case stmt of
|
||||||
[ docLines
|
[ docLines
|
||||||
$ (docCols ColDoLet
|
$ (docCols ColDoLet
|
||||||
[ appSep $ docLit $ Text.pack "let"
|
[ appSep $ docLit $ Text.pack "let"
|
||||||
, docSetIndentLevel $ docAddBaseY BrIndentRegular (return bindDoc1)
|
, docSetIndentLevel $ return bindDoc1
|
||||||
])
|
])
|
||||||
: (bindDocr <&> \bindDoc ->
|
: (bindDocr <&> \bindDoc ->
|
||||||
docCols ColDoLet
|
docCols ColDoLet
|
||||||
[ docEnsureIndent (BrIndentSpecial 4) docEmpty
|
[ docEnsureIndent (BrIndentSpecial 4) docEmpty
|
||||||
, docSetIndentLevel $ docAddBaseY BrIndentRegular (return bindDoc)
|
, docSetIndentLevel $ return bindDoc
|
||||||
])
|
])
|
||||||
, docAddBaseY BrIndentRegular
|
, docAddBaseY BrIndentRegular
|
||||||
$ docPar
|
$ docPar
|
||||||
(docLit $ Text.pack "let")
|
(docLit $ Text.pack "let")
|
||||||
(docSetIndentLevel $ docAddBaseY BrIndentRegular $ docLines $ return <$> bindDocs)
|
(docSetIndentLevel $ docLines $ return <$> bindDocs)
|
||||||
]
|
]
|
||||||
BodyStmt expr _ _ _ -> do
|
BodyStmt expr _ _ _ -> do
|
||||||
expDoc <- docSharedWrapper layoutExpr expr
|
expDoc <- docSharedWrapper layoutExpr expr
|
||||||
|
|
|
@ -83,10 +83,10 @@ data LayoutState = LayoutState
|
||||||
}
|
}
|
||||||
|
|
||||||
lstate_baseY :: LayoutState -> Int
|
lstate_baseY :: LayoutState -> Int
|
||||||
lstate_baseY = head . _lstate_baseYs
|
lstate_baseY = Safe.headNote "lstate_baseY" . _lstate_baseYs
|
||||||
|
|
||||||
lstate_indLevel :: LayoutState -> Int
|
lstate_indLevel :: LayoutState -> Int
|
||||||
lstate_indLevel = head . _lstate_indLevels
|
lstate_indLevel = Safe.headNote "lstate_baseY" . _lstate_indLevels
|
||||||
|
|
||||||
-- evil, incomplete Show instance; only for debugging.
|
-- evil, incomplete Show instance; only for debugging.
|
||||||
instance Show LayoutState where
|
instance Show LayoutState where
|
||||||
|
|
|
@ -428,6 +428,8 @@ import qualified Control.Monad.Trans.State.Strict as StateS
|
||||||
|
|
||||||
import qualified Data.Strict.Maybe as Strict
|
import qualified Data.Strict.Maybe as Strict
|
||||||
|
|
||||||
|
import qualified Safe as Safe
|
||||||
|
|
||||||
import Data.Functor.Identity ( Identity(..) )
|
import Data.Functor.Identity ( Identity(..) )
|
||||||
import Control.Concurrent.Chan ( Chan )
|
import Control.Concurrent.Chan ( Chan )
|
||||||
import Control.Concurrent.MVar ( MVar )
|
import Control.Concurrent.MVar ( MVar )
|
||||||
|
|
Loading…
Reference in New Issue