Merge branch 'master' into stack-13.14-compat
# Conflicts: # brittany.cabalpull/222/head
commit
3e1938aa7f
|
@ -12,3 +12,4 @@ local/
|
||||||
cabal.sandbox.config
|
cabal.sandbox.config
|
||||||
cabal.project.local
|
cabal.project.local
|
||||||
.ghc.environment.*
|
.ghc.environment.*
|
||||||
|
result
|
|
@ -94,6 +94,12 @@ log the size of the input, but _not_ the full input/output of requests.)
|
||||||
aura -A brittany
|
aura -A brittany
|
||||||
~~~~
|
~~~~
|
||||||
|
|
||||||
|
- via `nix`:
|
||||||
|
~~~.sh
|
||||||
|
nix build -f release.nix # or 'nix-build -f release.nix'
|
||||||
|
nix-env -i ./result
|
||||||
|
~~~
|
||||||
|
|
||||||
# Editor Integration
|
# Editor Integration
|
||||||
|
|
||||||
#### Sublime text
|
#### Sublime text
|
||||||
|
@ -111,6 +117,8 @@ log the size of the input, but _not_ the full input/output of requests.)
|
||||||
brittany built in.
|
brittany built in.
|
||||||
#### Atom
|
#### Atom
|
||||||
[Atom Beautify](https://atom.io/packages/atom-beautify) supports brittany as a formatter for Haskell. Since the default formatter is set to hindent, you will need to change this setting to brittany, after installing the extension.
|
[Atom Beautify](https://atom.io/packages/atom-beautify) supports brittany as a formatter for Haskell. Since the default formatter is set to hindent, you will need to change this setting to brittany, after installing the extension.
|
||||||
|
#### Emacs
|
||||||
|
[format-all](https://github.com/lassik/emacs-format-all-the-code) support brittany as the default formatter for Haskell.
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ library {
|
||||||
{ base >=4.9 && <4.13
|
{ base >=4.9 && <4.13
|
||||||
, ghc >=8.0.1 && <8.7
|
, ghc >=8.0.1 && <8.7
|
||||||
, ghc-paths >=0.1.0.9 && <0.2
|
, ghc-paths >=0.1.0.9 && <0.2
|
||||||
, ghc-exactprint >=0.5.8 && <0.7
|
, ghc-exactprint >=0.5.8 && <0.6.2
|
||||||
, transformers >=0.5.2.0 && <0.6
|
, transformers >=0.5.2.0 && <0.6
|
||||||
, containers >=0.5.7.1 && <0.7
|
, containers >=0.5.7.1 && <0.7
|
||||||
, mtl >=2.2.1 && <2.3
|
, mtl >=2.2.1 && <2.3
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
{ mkDerivation, aeson, base, butcher, bytestring, cmdargs
|
||||||
|
, containers, czipwith, data-tree-print, deepseq, directory, extra
|
||||||
|
, filepath, ghc, ghc-boot-th, ghc-exactprint, ghc-paths, hspec
|
||||||
|
, monad-memo, mtl, multistate, neat-interpolation, parsec, pretty
|
||||||
|
, random, safe, semigroups, stdenv, strict, syb, text, transformers
|
||||||
|
, uniplate, unsafe, yaml
|
||||||
|
}:
|
||||||
|
mkDerivation {
|
||||||
|
pname = "brittany";
|
||||||
|
version = "0.11.0.0";
|
||||||
|
src = ./.;
|
||||||
|
isLibrary = true;
|
||||||
|
isExecutable = true;
|
||||||
|
libraryHaskellDepends = [
|
||||||
|
aeson base butcher bytestring cmdargs containers czipwith
|
||||||
|
data-tree-print deepseq directory extra filepath ghc ghc-boot-th
|
||||||
|
ghc-exactprint ghc-paths monad-memo mtl multistate
|
||||||
|
neat-interpolation pretty random safe semigroups strict syb text
|
||||||
|
transformers uniplate unsafe yaml
|
||||||
|
];
|
||||||
|
executableHaskellDepends = [
|
||||||
|
aeson base butcher bytestring cmdargs containers czipwith
|
||||||
|
data-tree-print deepseq directory extra filepath ghc ghc-boot-th
|
||||||
|
ghc-exactprint ghc-paths monad-memo mtl multistate
|
||||||
|
neat-interpolation pretty safe semigroups strict syb text
|
||||||
|
transformers uniplate unsafe yaml
|
||||||
|
];
|
||||||
|
testHaskellDepends = [
|
||||||
|
aeson base butcher bytestring cmdargs containers czipwith
|
||||||
|
data-tree-print deepseq directory extra filepath ghc ghc-boot-th
|
||||||
|
ghc-exactprint ghc-paths hspec monad-memo mtl multistate
|
||||||
|
neat-interpolation parsec pretty safe semigroups strict syb text
|
||||||
|
transformers uniplate unsafe yaml
|
||||||
|
];
|
||||||
|
homepage = "https://github.com/lspitzner/brittany/";
|
||||||
|
description = "Haskell source code formatter";
|
||||||
|
license = stdenv.lib.licenses.agpl3;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
url = "https://github.com/nixos/nixpkgs.git";
|
||||||
|
ref = "release-18.09";
|
||||||
|
rev = "b9fa31cea0e119ecf1867af4944ddc2f7633aacd";
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
{ pkgs ? import (fetchGit (import ./pkgs.nix)) {}
|
||||||
|
, compiler ? "ghc822"
|
||||||
|
}:
|
||||||
|
|
||||||
|
pkgs.haskell.packages.${compiler}.callPackage ./shell.nix {}
|
|
@ -0,0 +1,13 @@
|
||||||
|
{ pkgs ? import (fetchGit (import ./pkgs.nix)) {}
|
||||||
|
, compiler ? "ghc822"
|
||||||
|
}:
|
||||||
|
|
||||||
|
pkgs.haskell.packages.${compiler}.developPackage {
|
||||||
|
root = ./.;
|
||||||
|
name = "brittany";
|
||||||
|
overrides = with pkgs.haskell.lib; self: super: {
|
||||||
|
};
|
||||||
|
source-overrides = {
|
||||||
|
ghc-exactprint = "0.5.8.0";
|
||||||
|
};
|
||||||
|
}
|
|
@ -531,6 +531,45 @@ func = if cond
|
||||||
-- test
|
-- test
|
||||||
abc
|
abc
|
||||||
|
|
||||||
|
#test nonempty-case-short
|
||||||
|
func = case x of
|
||||||
|
False -> False
|
||||||
|
True -> True
|
||||||
|
|
||||||
|
#test nonempty-case-long
|
||||||
|
func =
|
||||||
|
case
|
||||||
|
lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
|
||||||
|
lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
|
||||||
|
of
|
||||||
|
False -> False
|
||||||
|
True -> True
|
||||||
|
|
||||||
|
#test nonempty-case-long-do
|
||||||
|
func = do
|
||||||
|
case
|
||||||
|
lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
|
||||||
|
lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
|
||||||
|
of
|
||||||
|
False -> False
|
||||||
|
True -> True
|
||||||
|
|
||||||
|
#test empty-case-short
|
||||||
|
func = case x of {}
|
||||||
|
|
||||||
|
#test empty-case-long
|
||||||
|
func =
|
||||||
|
case
|
||||||
|
lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
|
||||||
|
lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
|
||||||
|
of {}
|
||||||
|
|
||||||
|
#test empty-case-long-do
|
||||||
|
func = do
|
||||||
|
case
|
||||||
|
lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
|
||||||
|
lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd
|
||||||
|
of {}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -1155,3 +1194,44 @@ func = do
|
||||||
|
|
||||||
other :: Other
|
other :: Other
|
||||||
other = True
|
other = True
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
###############################################################################
|
||||||
|
###############################################################################
|
||||||
|
#group typefam.instance
|
||||||
|
###############################################################################
|
||||||
|
###############################################################################
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
#test simple-typefam-instance
|
||||||
|
|
||||||
|
type instance MyFam Bool = String
|
||||||
|
|
||||||
|
#test simple-typefam-instance-param-type
|
||||||
|
|
||||||
|
type instance MyFam (Maybe a) = a -> Bool
|
||||||
|
|
||||||
|
#test simple-typefam-instance-parens
|
||||||
|
|
||||||
|
type instance (MyFam (String -> Int)) = String
|
||||||
|
|
||||||
|
#test simple-typefam-instance-overflow
|
||||||
|
|
||||||
|
type instance MyFam ALongishType
|
||||||
|
= AMuchLongerTypeThanThat
|
||||||
|
-> AnEvenLongerTypeThanTheLastOne
|
||||||
|
-> ShouldDefinitelyOverflow
|
||||||
|
|
||||||
|
#test simple-typefam-instance-comments
|
||||||
|
|
||||||
|
-- | A happy family
|
||||||
|
type instance MyFam Bool -- This is an odd one
|
||||||
|
= AnotherType -- Here's another
|
||||||
|
|
||||||
|
#test simple-typefam-instance-parens-comment
|
||||||
|
|
||||||
|
-- | A happy family
|
||||||
|
type instance (MyFam Bool) -- This is an odd one
|
||||||
|
= -- Here's another
|
||||||
|
AnotherType
|
||||||
|
|
|
@ -650,3 +650,13 @@ jaicyhHumzo btrKpeyiFej mava = do
|
||||||
)
|
)
|
||||||
Xcde{} -> (s, Pioemav)
|
Xcde{} -> (s, Pioemav)
|
||||||
pure imomue
|
pure imomue
|
||||||
|
|
||||||
|
#test issue 214
|
||||||
|
-- brittany { lconfig_indentPolicy: IndentPolicyMultiple }
|
||||||
|
foo = bar
|
||||||
|
arg1 -- this is the first argument
|
||||||
|
arg2 -- this is the second argument
|
||||||
|
arg3 -- this is the third argument, now I'll skip one comment
|
||||||
|
arg4
|
||||||
|
arg5 -- this is the fifth argument
|
||||||
|
arg6 -- this is the sixth argument
|
||||||
|
|
|
@ -9,6 +9,7 @@ module Language.Haskell.Brittany.Internal.LayouterBasics
|
||||||
, lrdrNameToTextAnnTypeEqualityIsSpecialAndRespectTick
|
, lrdrNameToTextAnnTypeEqualityIsSpecialAndRespectTick
|
||||||
, askIndent
|
, askIndent
|
||||||
, extractAllComments
|
, extractAllComments
|
||||||
|
, extractRestComments
|
||||||
, filterAnns
|
, filterAnns
|
||||||
, docEmpty
|
, docEmpty
|
||||||
, docLit
|
, docLit
|
||||||
|
@ -64,6 +65,8 @@ module Language.Haskell.Brittany.Internal.LayouterBasics
|
||||||
, hasAnyCommentsBelow
|
, hasAnyCommentsBelow
|
||||||
, hasAnyCommentsConnected
|
, hasAnyCommentsConnected
|
||||||
, hasAnyCommentsPrior
|
, hasAnyCommentsPrior
|
||||||
|
, hasAnyRegularCommentsConnected
|
||||||
|
, hasAnyRegularCommentsRest
|
||||||
, hasAnnKeywordComment
|
, hasAnnKeywordComment
|
||||||
, hasAnnKeyword
|
, hasAnnKeyword
|
||||||
)
|
)
|
||||||
|
@ -263,9 +266,13 @@ askIndent = confUnpack . _lconfig_indentAmount . _conf_layout <$> mAsk
|
||||||
extractAllComments
|
extractAllComments
|
||||||
:: ExactPrint.Annotation -> [(ExactPrint.Comment, ExactPrint.DeltaPos)]
|
:: ExactPrint.Annotation -> [(ExactPrint.Comment, ExactPrint.DeltaPos)]
|
||||||
extractAllComments ann =
|
extractAllComments ann =
|
||||||
ExactPrint.annPriorComments ann
|
ExactPrint.annPriorComments ann ++ extractRestComments ann
|
||||||
++ ExactPrint.annFollowingComments ann
|
|
||||||
++ ( ExactPrint.annsDP ann >>= \case
|
extractRestComments
|
||||||
|
:: ExactPrint.Annotation -> [(ExactPrint.Comment, ExactPrint.DeltaPos)]
|
||||||
|
extractRestComments ann =
|
||||||
|
ExactPrint.annFollowingComments ann
|
||||||
|
++ (ExactPrint.annsDP ann >>= \case
|
||||||
(ExactPrint.AnnComment com, dp) -> [(com, dp)]
|
(ExactPrint.AnnComment com, dp) -> [(com, dp)]
|
||||||
_ -> []
|
_ -> []
|
||||||
)
|
)
|
||||||
|
@ -278,31 +285,51 @@ filterAnns ast =
|
||||||
-- a) connected to any node below (in AST sense) the given node AND
|
-- a) connected to any node below (in AST sense) the given node AND
|
||||||
-- b) after (in source code order) the node.
|
-- b) after (in source code order) the node.
|
||||||
hasAnyCommentsBelow :: Data ast => GHC.Located ast -> ToBriDocM Bool
|
hasAnyCommentsBelow :: Data ast => GHC.Located ast -> ToBriDocM Bool
|
||||||
hasAnyCommentsBelow ast@(L l _) = do
|
hasAnyCommentsBelow ast@(L l _) =
|
||||||
anns <- filterAnns ast <$> mAsk
|
List.any (\(c, _) -> ExactPrint.commentIdentifier c > l)
|
||||||
return
|
<$> astConnectedComments ast
|
||||||
$ List.any (\(c, _) -> ExactPrint.commentIdentifier c > l)
|
|
||||||
$ (=<<) extractAllComments
|
|
||||||
$ Map.elems
|
|
||||||
$ anns
|
|
||||||
|
|
||||||
-- | True if there are any comments that are
|
-- | True if there are any comments that are connected to any node below (in AST
|
||||||
-- connected to any node below (in AST sense) the given node
|
-- sense) the given node
|
||||||
hasAnyCommentsConnected :: Data ast => GHC.Located ast -> ToBriDocM Bool
|
hasAnyCommentsConnected :: Data ast => GHC.Located ast -> ToBriDocM Bool
|
||||||
hasAnyCommentsConnected ast = do
|
hasAnyCommentsConnected ast = not . null <$> astConnectedComments ast
|
||||||
|
|
||||||
|
-- | True if there are any regular comments connected to any node below (in AST
|
||||||
|
-- sense) the given node
|
||||||
|
hasAnyRegularCommentsConnected :: Data ast => GHC.Located ast -> ToBriDocM Bool
|
||||||
|
hasAnyRegularCommentsConnected ast =
|
||||||
|
any isRegularComment <$> astConnectedComments ast
|
||||||
|
|
||||||
|
-- | Regular comments are comments that are actually "source code comments",
|
||||||
|
-- i.e. things that start with "--" or "{-". In contrast to comment-annotations
|
||||||
|
-- used by ghc-exactprint for capturing symbols (and their exact positioning).
|
||||||
|
--
|
||||||
|
-- Only the type instance layouter makes use of this filter currently, but
|
||||||
|
-- it might make sense to apply it more aggressively or make it the default -
|
||||||
|
-- I believe that most of the time we branch on the existence of comments, we
|
||||||
|
-- only care about "regular" comments. We simply did not need the distinction
|
||||||
|
-- because "irregular" comments are not that common outside of type/data decls.
|
||||||
|
isRegularComment :: (ExactPrint.Comment, ExactPrint.DeltaPos) -> Bool
|
||||||
|
isRegularComment = (== Nothing) . ExactPrint.Types.commentOrigin . fst
|
||||||
|
|
||||||
|
astConnectedComments
|
||||||
|
:: Data ast
|
||||||
|
=> GHC.Located ast
|
||||||
|
-> ToBriDocM [(ExactPrint.Types.Comment, ExactPrint.Types.DeltaPos)]
|
||||||
|
astConnectedComments ast = do
|
||||||
anns <- filterAnns ast <$> mAsk
|
anns <- filterAnns ast <$> mAsk
|
||||||
return
|
pure $ extractAllComments =<< Map.elems anns
|
||||||
$ not
|
|
||||||
$ null
|
|
||||||
$ (=<<) extractAllComments
|
|
||||||
$ Map.elems
|
|
||||||
$ anns
|
|
||||||
|
|
||||||
hasAnyCommentsPrior :: Data ast => GHC.Located ast -> ToBriDocM Bool
|
hasAnyCommentsPrior :: Data ast => GHC.Located ast -> ToBriDocM Bool
|
||||||
hasAnyCommentsPrior ast = astAnn ast <&> \case
|
hasAnyCommentsPrior ast = astAnn ast <&> \case
|
||||||
Nothing -> False
|
Nothing -> False
|
||||||
Just (ExactPrint.Types.Ann _ priors _ _ _ _) -> not $ null priors
|
Just (ExactPrint.Types.Ann _ priors _ _ _ _) -> not $ null priors
|
||||||
|
|
||||||
|
hasAnyRegularCommentsRest :: Data ast => GHC.Located ast -> ToBriDocM Bool
|
||||||
|
hasAnyRegularCommentsRest ast = astAnn ast <&> \case
|
||||||
|
Nothing -> False
|
||||||
|
Just ann -> any isRegularComment (extractRestComments ann)
|
||||||
|
|
||||||
hasAnnKeywordComment
|
hasAnnKeywordComment
|
||||||
:: Data ast => GHC.Located ast -> AnnKeywordId -> ToBriDocM Bool
|
:: Data ast => GHC.Located ast -> AnnKeywordId -> ToBriDocM Bool
|
||||||
hasAnnKeywordComment ast annKeyword = astAnn ast <&> \case
|
hasAnnKeywordComment ast annKeyword = astAnn ast <&> \case
|
||||||
|
|
|
@ -33,6 +33,9 @@ import GHC ( runGhc
|
||||||
)
|
)
|
||||||
import SrcLoc ( SrcSpan, noSrcSpan, Located , getLoc, unLoc )
|
import SrcLoc ( SrcSpan, noSrcSpan, Located , getLoc, unLoc )
|
||||||
import HsSyn
|
import HsSyn
|
||||||
|
#if MIN_VERSION_ghc(8,6,0)
|
||||||
|
import HsExtension (NoExt (..))
|
||||||
|
#endif
|
||||||
import Name
|
import Name
|
||||||
import BasicTypes ( InlinePragma(..)
|
import BasicTypes ( InlinePragma(..)
|
||||||
, Activation(..)
|
, Activation(..)
|
||||||
|
@ -62,7 +65,8 @@ layoutDecl d@(L loc decl) = case decl of
|
||||||
Left ns -> docLines $ return <$> ns
|
Left ns -> docLines $ return <$> ns
|
||||||
Right n -> return n
|
Right n -> return n
|
||||||
TyClD _ tycl -> withTransformedAnns d $ layoutTyCl (L loc tycl)
|
TyClD _ tycl -> withTransformedAnns d $ layoutTyCl (L loc tycl)
|
||||||
InstD _ (TyFamInstD{}) -> layoutTyFamInstDWorkaround d
|
InstD _ (TyFamInstD _ tfid) ->
|
||||||
|
withTransformedAnns d $ layoutTyFamInstDecl False (L loc tfid)
|
||||||
InstD _ (ClsInstD _ inst) ->
|
InstD _ (ClsInstD _ inst) ->
|
||||||
withTransformedAnns d $ layoutClsInst (L loc inst)
|
withTransformedAnns d $ layoutClsInst (L loc inst)
|
||||||
_ -> briDocByExactNoComment d
|
_ -> briDocByExactNoComment d
|
||||||
|
@ -73,25 +77,12 @@ layoutDecl d@(L loc decl) = case decl of
|
||||||
Left ns -> docLines $ return <$> ns
|
Left ns -> docLines $ return <$> ns
|
||||||
Right n -> return n
|
Right n -> return n
|
||||||
TyClD tycl -> withTransformedAnns d $ layoutTyCl (L loc tycl)
|
TyClD tycl -> withTransformedAnns d $ layoutTyCl (L loc tycl)
|
||||||
InstD (TyFamInstD{}) -> layoutTyFamInstDWorkaround d
|
InstD (TyFamInstD tfid) ->
|
||||||
|
withTransformedAnns d $ layoutTyFamInstDecl False (L loc tfid)
|
||||||
InstD (ClsInstD inst) -> withTransformedAnns d $ layoutClsInst (L loc inst)
|
InstD (ClsInstD inst) -> withTransformedAnns d $ layoutClsInst (L loc inst)
|
||||||
_ -> briDocByExactNoComment d
|
_ -> briDocByExactNoComment d
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
layoutTyFamInstDWorkaround :: ToBriDoc HsDecl
|
|
||||||
layoutTyFamInstDWorkaround d = do
|
|
||||||
-- this is a (temporary (..)) workaround for "type instance" decls
|
|
||||||
-- that do not round-trip through exactprint properly.
|
|
||||||
let fixer s = case List.stripPrefix "type " s of
|
|
||||||
Just rest | not ("instance" `isPrefixOf` rest) ->
|
|
||||||
"type instance " ++ rest
|
|
||||||
_ -> s
|
|
||||||
str <- mAsk <&> \anns ->
|
|
||||||
intercalate "\n" $ fmap fixer $ lines' $ ExactPrint.exactPrint d anns
|
|
||||||
allocateNode $ BDFExternal (ExactPrint.mkAnnKey d)
|
|
||||||
(foldedAnnKeys d)
|
|
||||||
False
|
|
||||||
(Text.pack str)
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- Sig
|
-- Sig
|
||||||
|
@ -156,24 +147,11 @@ layoutSig lsig@(L _loc sig) = case sig of
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
else
|
else layoutLhsAndType
|
||||||
docAlt
|
hasComments
|
||||||
$ [ docSeq
|
(appSep . docWrapNodeRest lsig $ docLit nameStr)
|
||||||
[ appSep $ docWrapNodeRest lsig $ docLit nameStr
|
"::"
|
||||||
, appSep $ docLit $ Text.pack "::"
|
typeDoc
|
||||||
, docForceSingleline typeDoc
|
|
||||||
]
|
|
||||||
| not hasComments
|
|
||||||
]
|
|
||||||
++ [ docAddBaseY BrIndentRegular $ docPar
|
|
||||||
(docWrapNodeRest lsig $ docLit nameStr)
|
|
||||||
( docCols
|
|
||||||
ColTyOpPrefix
|
|
||||||
[ docLit $ Text.pack ":: "
|
|
||||||
, docAddBaseY (BrIndentSpecial 3) $ typeDoc
|
|
||||||
]
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
specStringCompat
|
specStringCompat
|
||||||
:: MonadMultiWriter [BrittanyError] m => LSig GhcPs -> InlineSpec -> m String
|
:: MonadMultiWriter [BrittanyError] m => LSig GhcPs -> InlineSpec -> m String
|
||||||
|
@ -754,12 +732,7 @@ layoutSynDecl isInfix wrapNodeRest name vars typ = do
|
||||||
sharedLhs <- docSharedWrapper id lhs
|
sharedLhs <- docSharedWrapper id lhs
|
||||||
typeDoc <- docSharedWrapper layoutType typ
|
typeDoc <- docSharedWrapper layoutType typ
|
||||||
hasComments <- hasAnyCommentsConnected typ
|
hasComments <- hasAnyCommentsConnected typ
|
||||||
runFilteredAlternative $ do
|
layoutLhsAndType hasComments sharedLhs "=" typeDoc
|
||||||
addAlternativeCond (not hasComments) $ docSeq
|
|
||||||
[sharedLhs, appSep $ docLit $ Text.pack "=", docForceSingleline typeDoc]
|
|
||||||
addAlternative $ docAddBaseY BrIndentRegular $ docPar
|
|
||||||
sharedLhs
|
|
||||||
(docCols ColTyOpPrefix [appSep $ docLit $ Text.pack "=", typeDoc])
|
|
||||||
|
|
||||||
layoutTyVarBndr :: Bool -> ToBriDoc HsTyVarBndr
|
layoutTyVarBndr :: Bool -> ToBriDoc HsTyVarBndr
|
||||||
layoutTyVarBndr needsSep lbndr@(L _ bndr) = do
|
layoutTyVarBndr needsSep lbndr@(L _ bndr) = do
|
||||||
|
@ -788,6 +761,55 @@ layoutTyVarBndr needsSep lbndr@(L _ bndr) = do
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- TyFamInstDecl
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
layoutTyFamInstDecl :: Bool -> ToBriDoc TyFamInstDecl
|
||||||
|
layoutTyFamInstDecl inClass (L loc tfid) = do
|
||||||
|
let
|
||||||
|
#if MIN_VERSION_ghc(8,6,0)
|
||||||
|
linst = L loc (TyFamInstD NoExt tfid)
|
||||||
|
feqn@(FamEqn _ name pats _fixity typ) = hsib_body $ tfid_eqn tfid
|
||||||
|
lfeqn = L loc feqn
|
||||||
|
#elif MIN_VERSION_ghc(8,4,0)
|
||||||
|
linst = L loc (TyFamInstD tfid)
|
||||||
|
feqn@(FamEqn name pats _fixity typ) = hsib_body $ tfid_eqn tfid
|
||||||
|
lfeqn = L loc feqn
|
||||||
|
#elif MIN_VERSION_ghc(8,2,0)
|
||||||
|
linst = L loc (TyFamInstD tfid)
|
||||||
|
lfeqn@(L _ (TyFamEqn name boundPats _fixity typ)) = tfid_eqn tfid
|
||||||
|
pats = hsib_body boundPats
|
||||||
|
#else
|
||||||
|
linst = L loc (TyFamInstD tfid)
|
||||||
|
lfeqn@(L _ (TyFamEqn name boundPats typ)) = tfid_eqn tfid
|
||||||
|
pats = hsib_body boundPats
|
||||||
|
#endif
|
||||||
|
docWrapNodePrior linst $ do
|
||||||
|
nameStr <- lrdrNameToTextAnn name
|
||||||
|
needsParens <- hasAnnKeyword lfeqn AnnOpenP
|
||||||
|
let
|
||||||
|
instanceDoc = if inClass
|
||||||
|
then docLit $ Text.pack "type"
|
||||||
|
else docSeq
|
||||||
|
[appSep . docLit $ Text.pack "type", docLit $ Text.pack "instance"]
|
||||||
|
lhs =
|
||||||
|
docWrapNode lfeqn
|
||||||
|
. appSep
|
||||||
|
. docWrapNodeRest linst
|
||||||
|
. docSeq
|
||||||
|
$ (appSep instanceDoc :)
|
||||||
|
$ [ docParenL | needsParens ]
|
||||||
|
++ [appSep $ docWrapNode name $ docLit nameStr]
|
||||||
|
++ intersperse docSeparator (layoutType <$> pats)
|
||||||
|
++ [ docParenR | needsParens ]
|
||||||
|
hasComments <- (||)
|
||||||
|
<$> hasAnyRegularCommentsConnected lfeqn
|
||||||
|
<*> hasAnyRegularCommentsRest linst
|
||||||
|
typeDoc <- docSharedWrapper layoutType typ
|
||||||
|
layoutLhsAndType hasComments lhs "=" typeDoc
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
-- ClsInstDecl
|
-- ClsInstDecl
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
@ -855,12 +877,7 @@ layoutClsInst lcid@(L _ cid) = docLines
|
||||||
layoutAndLocateTyFamInsts
|
layoutAndLocateTyFamInsts
|
||||||
:: ToBriDocC (TyFamInstDecl GhcPs) (Located BriDocNumbered)
|
:: ToBriDocC (TyFamInstDecl GhcPs) (Located BriDocNumbered)
|
||||||
layoutAndLocateTyFamInsts ltfid@(L loc _) =
|
layoutAndLocateTyFamInsts ltfid@(L loc _) =
|
||||||
L loc <$> layoutTyFamInstDecl ltfid
|
L loc <$> layoutTyFamInstDecl True ltfid
|
||||||
|
|
||||||
-- | Send to ExactPrint then remove unecessary whitespace
|
|
||||||
layoutTyFamInstDecl :: ToBriDoc TyFamInstDecl
|
|
||||||
layoutTyFamInstDecl ltfid =
|
|
||||||
fmap stripWhitespace <$> briDocByExactNoComment ltfid
|
|
||||||
|
|
||||||
layoutAndLocateDataFamInsts
|
layoutAndLocateDataFamInsts
|
||||||
:: ToBriDocC (DataFamInstDecl GhcPs) (Located BriDocNumbered)
|
:: ToBriDocC (DataFamInstDecl GhcPs) (Located BriDocNumbered)
|
||||||
|
@ -928,3 +945,32 @@ layoutClsInst lcid@(L _ cid) = docLines
|
||||||
isTypeOrData t' =
|
isTypeOrData t' =
|
||||||
(Text.pack "type" `Text.isPrefixOf` t')
|
(Text.pack "type" `Text.isPrefixOf` t')
|
||||||
|| (Text.pack "data" `Text.isPrefixOf` t')
|
|| (Text.pack "data" `Text.isPrefixOf` t')
|
||||||
|
|
||||||
|
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
-- Common Helpers
|
||||||
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
layoutLhsAndType
|
||||||
|
:: Bool
|
||||||
|
-> ToBriDocM BriDocNumbered
|
||||||
|
-> String
|
||||||
|
-> ToBriDocM BriDocNumbered
|
||||||
|
-> ToBriDocM BriDocNumbered
|
||||||
|
layoutLhsAndType hasComments lhs sep typeDoc = do
|
||||||
|
let sepDoc = appSep . docLit $ Text.pack sep
|
||||||
|
runFilteredAlternative $ do
|
||||||
|
-- (separators probably are "=" or "::")
|
||||||
|
-- lhs = type
|
||||||
|
-- lhs :: type
|
||||||
|
addAlternativeCond (not hasComments)
|
||||||
|
$ docSeq [lhs, sepDoc, docForceSingleline typeDoc]
|
||||||
|
-- lhs
|
||||||
|
-- :: typeA
|
||||||
|
-- -> typeB
|
||||||
|
-- lhs
|
||||||
|
-- = typeA
|
||||||
|
-- -> typeB
|
||||||
|
addAlternative $ docAddBaseY BrIndentRegular $ docPar lhs $ docCols
|
||||||
|
ColTyOpPrefix
|
||||||
|
[sepDoc, docAddBaseY (BrIndentSpecial (length sep + 1)) typeDoc]
|
||||||
|
|
|
@ -136,6 +136,17 @@ layoutExpr lexpr@(L _ expr) = do
|
||||||
#if MIN_VERSION_ghc(8,6,0) /* ghc-8.6 */
|
#if MIN_VERSION_ghc(8,6,0) /* ghc-8.6 */
|
||||||
HsLamCase _ XMatchGroup{} ->
|
HsLamCase _ XMatchGroup{} ->
|
||||||
error "brittany internal error: HsLamCase XMatchGroup"
|
error "brittany internal error: HsLamCase XMatchGroup"
|
||||||
|
#endif
|
||||||
|
#if MIN_VERSION_ghc(8,6,0) /* ghc-8.6 */
|
||||||
|
HsLamCase _ (MG _ (L _ []) _) -> do
|
||||||
|
#elif MIN_VERSION_ghc(8,2,0) /* ghc-8.2 8.4*/
|
||||||
|
HsLamCase (MG (L _ []) _ _ _) -> do
|
||||||
|
#else /* ghc-8.0 */
|
||||||
|
HsLamCase _ (MG (L _ []) _ _ _) -> do
|
||||||
|
#endif
|
||||||
|
docSetParSpacing $ docAddBaseY BrIndentRegular $
|
||||||
|
(docLit $ Text.pack "\\case {}")
|
||||||
|
#if MIN_VERSION_ghc(8,6,0) /* ghc-8.6 */
|
||||||
HsLamCase _ (MG _ lmatches@(L _ matches) _) -> do
|
HsLamCase _ (MG _ lmatches@(L _ matches) _) -> do
|
||||||
#elif MIN_VERSION_ghc(8,2,0) /* ghc-8.2 8.4*/
|
#elif MIN_VERSION_ghc(8,2,0) /* ghc-8.2 8.4*/
|
||||||
HsLamCase (MG lmatches@(L _ matches) _ _ _) -> do
|
HsLamCase (MG lmatches@(L _ matches) _ _ _) -> do
|
||||||
|
@ -172,9 +183,10 @@ layoutExpr lexpr@(L _ expr) = do
|
||||||
_ -> docSeq
|
_ -> docSeq
|
||||||
headDoc <- docSharedWrapper layoutExpr headE
|
headDoc <- docSharedWrapper layoutExpr headE
|
||||||
paramDocs <- docSharedWrapper layoutExpr `mapM` paramEs
|
paramDocs <- docSharedWrapper layoutExpr `mapM` paramEs
|
||||||
|
hasComments <- hasAnyCommentsConnected exp2
|
||||||
runFilteredAlternative $ do
|
runFilteredAlternative $ do
|
||||||
-- foo x y
|
-- foo x y
|
||||||
addAlternative
|
addAlternativeCond (not hasComments)
|
||||||
$ colsOrSequence
|
$ colsOrSequence
|
||||||
$ appSep (docForceSingleline headDoc)
|
$ appSep (docForceSingleline headDoc)
|
||||||
: spacifyDocs (docForceSingleline <$> paramDocs)
|
: spacifyDocs (docForceSingleline <$> paramDocs)
|
||||||
|
@ -520,6 +532,27 @@ layoutExpr lexpr@(L _ expr) = do
|
||||||
#if MIN_VERSION_ghc(8,6,0) /* ghc-8.6 */
|
#if MIN_VERSION_ghc(8,6,0) /* ghc-8.6 */
|
||||||
HsCase _ _ XMatchGroup{} ->
|
HsCase _ _ XMatchGroup{} ->
|
||||||
error "brittany internal error: HsCase XMatchGroup"
|
error "brittany internal error: HsCase XMatchGroup"
|
||||||
|
#endif
|
||||||
|
#if MIN_VERSION_ghc(8,6,0) /* ghc-8.6 */
|
||||||
|
HsCase _ cExp (MG _ (L _ []) _) -> do
|
||||||
|
#else
|
||||||
|
HsCase cExp (MG (L _ []) _ _ _) -> do
|
||||||
|
#endif
|
||||||
|
cExpDoc <- docSharedWrapper layoutExpr cExp
|
||||||
|
docAlt
|
||||||
|
[ docAddBaseY BrIndentRegular
|
||||||
|
$ docSeq
|
||||||
|
[ appSep $ docLit $ Text.pack "case"
|
||||||
|
, appSep $ docForceSingleline cExpDoc
|
||||||
|
, docLit $ Text.pack "of {}"
|
||||||
|
]
|
||||||
|
, docPar
|
||||||
|
( docAddBaseY BrIndentRegular
|
||||||
|
$ docPar (docLit $ Text.pack "case") cExpDoc
|
||||||
|
)
|
||||||
|
(docLit $ Text.pack "of {}")
|
||||||
|
]
|
||||||
|
#if MIN_VERSION_ghc(8,6,0) /* ghc-8.6 */
|
||||||
HsCase _ cExp (MG _ lmatches@(L _ matches) _) -> do
|
HsCase _ cExp (MG _ lmatches@(L _ matches) _) -> do
|
||||||
#else
|
#else
|
||||||
HsCase cExp (MG lmatches@(L _ matches) _ _ _) -> do
|
HsCase cExp (MG lmatches@(L _ matches) _ _ _) -> do
|
||||||
|
|
Loading…
Reference in New Issue