11{-# LANGUAGE BlockArguments #-}
22{-# LANGUAGE LambdaCase #-}
33{-# LANGUAGE TypeApplications #-}
4+ {-# LANGUAGE RecordWildCards #-}
45module Language.Haskell.Stylish.Step.Signature where
56
67import RdrName (RdrName )
78import SrcLoc (GenLocated (.. ), Located )
8- import GHC.Hs.Decls (HsDecl (.. ))
9- import GHC.Hs.Binds (Sig (.. ))
9+ import GHC.Hs.Decls
10+ import GHC.Hs.Binds
11+ import GHC.Hs.Types
1012import GHC.Hs.Extension (GhcPs )
1113
1214--------------------------------------------------------------------------------
1315import Language.Haskell.Stylish.Block
1416import Language.Haskell.Stylish.Step
1517import Language.Haskell.Stylish.Module
16- import Language.Haskell.Stylish.Editor (change )
17- import Language.Haskell.Stylish.GHC (getStartLineUnsafe , getEndLineUnsafe )
18+ import Language.Haskell.Stylish.Editor (change , noop )
19+ import Language.Haskell.Stylish.GHC (getStartLineUnsafe , getEndLineUnsafe , getEndColumnUnsafe )
1820import Language.Haskell.Stylish.Editor (Change , applyChanges )
21+ import Language.Haskell.Stylish.Printer
1922
2023-- TODO unify with type alias from Data.hs
2124type ChangeLine = Change String
2225
26+ data MaxColumns
27+ = MaxColumns ! Int
28+ | NoMaxColumns
29+ deriving (Show , Eq )
30+
31+ fits :: Int -> MaxColumns -> Bool
32+ fits _ NoMaxColumns = True
33+ fits v (MaxColumns limit) = v <= limit
34+
2335data Config = Config
24- { cMaxColumns :: Int
36+ { cMaxColumns :: MaxColumns
2537 }
2638
2739step :: Config -> Step
@@ -32,15 +44,40 @@ changes cfg m = fmap (formatSignatureDecl cfg m) (topLevelFunctionSignatures m)
3244
3345topLevelFunctionSignatures :: Module -> [Located SignatureDecl ]
3446topLevelFunctionSignatures = queryModule @ (Located (HsDecl GhcPs )) \ case
35- L pos (SigD _ (TypeSig _ [name] _)) -> [L pos $ MkSignatureDecl name]
47+ L pos (SigD _ (TypeSig _ [name] (HsWC _ (HsIB _ (L _ funTy@ (HsFunTy _ _ _ )))))) ->
48+ [L pos $ MkSignatureDecl name (listParameters funTy)]
3649 _ -> []
3750
51+ listParameters :: HsType GhcPs -> [Located RdrName ]
52+ listParameters (HsFunTy _ (L _ arg2) (L _ arg3)) = listParameters arg2 <> listParameters arg3
53+ listParameters (HsTyVar _ _promotionFlag name) = [name]
54+ listParameters _ = []
55+
3856data SignatureDecl = MkSignatureDecl
3957 { sigName :: Located RdrName
58+ , sigParameters :: [Located RdrName ]
4059 }
4160
4261formatSignatureDecl :: Config -> Module -> Located SignatureDecl -> ChangeLine
43- formatSignatureDecl _cfg _m ldecl = change originalDeclBlock id
62+ formatSignatureDecl Config {.. } m ldecl@ (L _declPos decl) = do
63+ let block = originalDeclBlock
64+ declLength = getEndColumnUnsafe ldecl
65+ if fits declLength cMaxColumns then
66+ noop block
67+ else
68+ change block (const printDecl)
69+
4470 where
4571 originalDeclBlock =
4672 Block (getStartLineUnsafe ldecl) (getEndLineUnsafe ldecl)
73+
74+ printerConfig = PrinterConfig
75+ { columns = case cMaxColumns of
76+ NoMaxColumns -> Nothing
77+ MaxColumns n -> Just n
78+ }
79+
80+ printDecl = runPrinter_ printerConfig [] m do
81+ (putRdrName $ sigName decl) >> space >> putText " ::" >> newline
82+ spaces 5 >> (putRdrName $ head $ sigParameters decl) >> newline
83+ traverse (\ para -> spaces 2 >> putText " ->" >> space >> (putRdrName para) >> newline) (tail $ sigParameters decl)
0 commit comments