Support associated data decls with multiple constructors

ghc92
Lennart Spitzner 2023-05-09 17:47:11 +00:00
parent 94fcf56b28
commit 7e56701bc2
4 changed files with 181 additions and 151 deletions

View File

@ -973,3 +973,12 @@ func =
func = func =
fromIntegral aaaaaaaaaaaaaaaaaaa fromIntegral aaaaaaaaaaaaaaaaaaa
/ fromIntegral (aaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbb) / fromIntegral (aaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbb)
#test multi-constructor associated data decl
data POtfuggj
instance BMGuwigoc POtfuggj where
data KVeeweknc POtfuggj r
= ILpieakli
| USilcnhkYaraposqu (WeyOoovf (Nubwlhtjd EculdW.QaeopznkAc r))
deriving stock (Lirylfj1, Jexr)
deriving anyclass Qart2.Vrzxuvcf

View File

@ -15,7 +15,7 @@ import Language.Haskell.Brittany.Internal.Components.BriDoc
layoutDataDecl layoutDataDecl
:: LTyClDecl GhcPs :: Maybe (LTyClDecl GhcPs)
-> EpAnn [AddEpAnn] -> EpAnn [AddEpAnn]
-> LIdP GhcPs -> LIdP GhcPs
-> LHsQTyVars GhcPs -> LHsQTyVars GhcPs
@ -53,19 +53,51 @@ layoutDataDecl ltycl declEpAnn name (HsQTvs _ bndrs) pats defn = case defn of
, docSeparator , docSeparator
, docHandleComms epAnn $ rhsDoc , docHandleComms epAnn $ rhsDoc
] ]
else briDocByExactNoComment ltycl else maybe
_ -> briDocByExactNoComment ltycl (error
$ "Unsupported form of DataFamInstDecl:"
++ " ConDeclH98 with context"
)
briDocByExactNoComment
ltycl
_ -> maybe
(error
$ "Unsupported form of DataFamInstDecl:"
++ " ConDeclH98 with forall"
)
briDocByExactNoComment
ltycl
HsDataDefn NoExtField NewType _ _ Just{} _ _ -> maybe
(error $ "Unsupported form of DataFamInstDecl: NewType _ _ Just _ _")
briDocByExactNoComment
ltycl
HsDataDefn NoExtField NewType _ _ Nothing _ _ -> maybe
(error $ "Unsupported form of DataFamInstDecl: NewType _ _ Nothing _ _")
briDocByExactNoComment
ltycl
-- data MyData = MyData ..
-- data MyData a b -- data MyData = MyData { .. }
-- (zero constructors) HsDataDefn NoExtField DataType ctxMay _ctype Nothing conss mDerivs -> do
HsDataDefn NoExtField DataType ctxMay _ctype Nothing [] mDerivs -> do
lhsContextDoc <- case ctxMay of lhsContextDoc <- case ctxMay of
Just (L _ lhsContext) -> shareDoc $ createContextDoc lhsContext Just (L _ lhsContext) -> shareDoc $ createContextDoc lhsContext
Nothing -> pure docEmpty Nothing -> pure docEmpty
nameStr <- lrdrNameToTextAnn name nameStr <- lrdrNameToTextAnn name
tyVarLine <- return <$> createBndrDoc bndrs tyVarLine <- return <$> createBndrDoc bndrs
patDocs <- mapM shareDoc $ layoutHsTyPats pats patDocs <- mapM shareDoc $ layoutHsTyPats pats
lhsDoc <- shareDoc $ docSeq
[ -- TOOD92 docNodeAnnKW ltycl (Just GHC.AnnData) $
appSep $ docLitS "data"
, docForceSingleline $ lhsContextDoc
, appSep $ docLit nameStr
, appSep tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
let prefixes = "=" : repeat "|"
layoutConssResult <- mapM layoutConDecl (zip prefixes conss)
case sequence layoutConssResult of
Left err -> maybe (error err) briDocByExactNoComment ltycl
Right [] -> do
docHandleComms declEpAnn $ createDerivingPar mDerivs $ docSeq docHandleComms declEpAnn $ createDerivingPar mDerivs $ docSeq
[ appSep $ docLitS "data" [ appSep $ docLitS "data"
, lhsContextDoc , lhsContextDoc
@ -73,151 +105,140 @@ layoutDataDecl ltycl declEpAnn name (HsQTvs _ bndrs) pats defn = case defn of
, appSep tyVarLine , appSep tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]] , docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
] ]
Right [(consDocSl, consDocMl)] -> do
-- data MyData = MyData ..
-- data MyData = MyData { .. }
HsDataDefn NoExtField DataType ctxMay _ctype Nothing [cons] mDerivs ->
case cons of
(L _ (ConDeclH98 epAnn consName _hasExt qvars mRhsContext details _conDoc))
-> do
lhsContextDoc <- case ctxMay of
Just (L _ lhsContext) -> shareDoc $ createContextDoc lhsContext
Nothing -> pure docEmpty
nameStr <- lrdrNameToTextAnn name
consNameStr <- lrdrNameToTextAnn consName
tyVarLine <- return <$> createBndrDoc bndrs
patDocs <- mapM shareDoc $ layoutHsTyPats pats
forallDocMay <- case createForallDoc qvars of
Nothing -> pure Nothing
Just x -> Just . pure <$> x
rhsContextDocMay <- case mRhsContext of
Nothing -> pure Nothing
Just (L _ ctxt) -> Just . pure <$> createContextDoc ctxt
rhsDoc <- return <$> createDetailsDoc consNameStr details
let posEqual = obtainAnnPos epAnn AnnEqual
consDoc <-
shareDoc
$ docHandleComms epAnn
$ docHandleComms posEqual
$ docNonBottomSpacing
$ case (forallDocMay, rhsContextDocMay) of
(Just forallDoc, Just rhsContextDoc) -> docLines
[ docSeq
[docLitS "=", docSeparator, docForceSingleline forallDoc]
, docSeq
[ docLitS "."
, docSeparator
, docSetBaseY $ docLines [rhsContextDoc, docSetBaseY rhsDoc]
]
]
(Just forallDoc, Nothing) -> docLines
[ docSeq
[docLitS "=", docSeparator, docForceSingleline forallDoc]
, docSeq [docLitS ".", docSeparator, rhsDoc]
]
(Nothing, Just rhsContextDoc) -> docSeq
[ docLitS "="
, docSeparator
, docSetBaseY $ docLines [rhsContextDoc, docSetBaseY rhsDoc]
]
(Nothing, Nothing) ->
docSeq [docLitS "=", docSeparator, rhsDoc]
docHandleComms declEpAnn $ createDerivingPar mDerivs $ docAlt docHandleComms declEpAnn $ createDerivingPar mDerivs $ docAlt
[ -- data D = forall a . Show a => D a [ -- data D = forall a . Show a => D a
docSeq docSeq [lhsDoc, consDocSl]
[ -- TOOD92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docSeq
[ appSep $ docLitS "data"
, docForceSingleline $ lhsContextDoc
, appSep $ docLit nameStr
, appSep tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
, docHandleComms epAnn $ docHandleComms posEqual $ docLitS "="
, docSeparator
, docSetIndentLevel $ docSeq
[ case forallDocMay of
Nothing -> docEmpty
Just forallDoc ->
docSeq
[ docForceSingleline forallDoc
, docSeparator
, docLitS "."
, docSeparator
]
, maybe docEmpty docForceSingleline rhsContextDocMay
, rhsDoc
]
]
, -- data D , -- data D
-- = forall a . Show a => D a -- = forall a . Show a => D a
docAddBaseY BrIndentRegular $ docPar -- data D
( -- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docSeq
[ appSep $ docLitS "data"
, docForceSingleline lhsContextDoc
, appSep $ docLit nameStr
, tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
)
(docSeq
[ docHandleComms epAnn $ docHandleComms posEqual $ docLitS "="
, docSeparator
, docSetIndentLevel $ docSeq
[ case forallDocMay of
Nothing -> docEmpty
Just forallDoc ->
docSeq
[ docForceSingleline forallDoc
, docSeparator
, docLitS "."
, docSeparator
]
, maybe docEmpty docForceSingleline rhsContextDocMay
, rhsDoc
]
]
)
, -- data D
-- = forall a -- = forall a
-- . Show a => -- . Show a =>
-- D a -- D a
docAddBaseY BrIndentRegular $ docPar docAddBaseY BrIndentRegular
( -- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $ $ docPar lhsDoc
docSeq (docNonBottomSpacing $ docAlt [consDocSl, consDocMl])
[ appSep $ docLitS "data"
, docForceSingleline lhsContextDoc
, appSep $ docLit nameStr
, tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
)
consDoc
, -- data , -- data
-- Show a => -- Show a =>
-- D -- D
-- = forall a -- = rhsDoc
-- . Show a =>
-- D a
-- This alternative is only for -XDatatypeContexts. -- This alternative is only for -XDatatypeContexts.
-- But I think it is rather unlikely this will trigger without -- But I think it is rather unlikely this will trigger without
-- -XDataTypeContexts, especially with the `docNonBottomSpacing` -- -XDataTypeContexts, especially with the `docNonBottomSpacing`
-- above, so while not strictly necessary, this should not -- above, so while not strictly necessary, this should not
-- hurt. -- hurt.
docAddBaseY BrIndentRegular $ docPar docAddBaseY BrIndentRegular $ docPar
(docLitS "data") (-- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docLitS "data")
(docLines (docLines
[ lhsContextDoc [ lhsContextDoc
, -- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $ , docSeq
docSeq [appSep $ docLit nameStr, tyVarLine, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]] [ appSep $ docLit nameStr
, consDoc , tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
, consDocMl
] ]
) )
] ]
_ -> briDocByExactNoComment ltycl Right consDocTuples -> do
docHandleComms declEpAnn
$ createDerivingPar mDerivs
$ docAddBaseY BrIndentRegular
$ docPar
(docAlt
[ -- data Show a => D a
lhsDoc
, -- data
-- Show a =>
-- D
-- This alternative is only for -XDatatypeContexts.
-- But I think it is rather unlikely this will trigger without
-- -XDataTypeContexts, especially with the `docNonBottomSpacing`
-- above, so while not strictly necessary, this should not
-- hurt.
docAddBaseY BrIndentRegular $ docPar
(-- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docLitS "data")
(docLines
[ lhsContextDoc
, docSeq
[ appSep $ docLit nameStr
, tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
]
)
]
)
(docLines $ [docAlt [sl, ml] | (sl, ml) <- consDocTuples])
HsDataDefn NoExtField DataType _ _ Just{} _ _ -> maybe
(error $ "Unsupported form of DataFamInstDecl: DataType _ _ Just _ _")
briDocByExactNoComment
ltycl
layoutConDecl
:: (String, LConDecl GhcPs)
-> ToBriDocM
(Either String (ToBriDocM BriDocNumbered, ToBriDocM BriDocNumbered))
layoutConDecl (prefix, L _ con) = case con of
ConDeclH98 epAnn consName _hasExt qvars mRhsContext details _conDoc -> do
consNameStr <- lrdrNameToTextAnn consName
forallDocMay <- case createForallDoc qvars of
Nothing -> pure Nothing
Just x -> Just . pure <$> x
rhsContextDocMay <- case mRhsContext of
Nothing -> pure Nothing
Just (L _ ctxt) -> Just . pure <$> createContextDoc ctxt
detailsDoc <- shareDoc $ createDetailsDoc consNameStr details
let posEqual = obtainAnnPos epAnn AnnEqual
pure $ Right
( docSeq
[ docHandleComms epAnn $ docHandleComms posEqual $ docLitS prefix
, docSeparator
, docSetIndentLevel $ docSeq
[ case forallDocMay of
Nothing -> docEmpty
Just forallDoc -> docSeq
[ docForceSingleline forallDoc
, docSeparator
, docLitS "."
, docSeparator
]
, maybe docEmpty docForceSingleline rhsContextDocMay
, detailsDoc
]
]
, docHandleComms epAnn
$ docHandleComms posEqual
$ docNonBottomSpacing
$ case (forallDocMay, rhsContextDocMay) of
(Just forallDoc, Just rhsContextDoc) -> docLines
[ docSeq
[docLitS prefix, docSeparator, docForceSingleline forallDoc]
, docSeq
[ docLitS "."
, docSeparator
, docSetBaseY $ docLines [rhsContextDoc, docSetBaseY detailsDoc]
]
]
(Just forallDoc, Nothing) -> docLines
[ docSeq
[docLitS prefix, docSeparator, docForceSingleline forallDoc]
, docSeq [docLitS ".", docSeparator, detailsDoc]
]
(Nothing, Just rhsContextDoc) -> docSeq
[ docLitS prefix
, docSeparator
, docSetBaseY $ docLines [rhsContextDoc, docSetBaseY detailsDoc]
]
(Nothing, Nothing) -> docSeq
[docLitS prefix, docSeparator, detailsDoc]
)
ConDeclGADT{} -> pure
$ Left "Unsupported: ConDeclGADT inside DataFamInstDecl"
_ -> briDocByExactNoComment ltycl
layoutHsTyPats layoutHsTyPats
:: [LHsTypeArg GhcPs] -> [ToBriDocM BriDocNumbered] :: [LHsTypeArg GhcPs] -> [ToBriDocM BriDocNumbered]

View File

@ -808,7 +808,7 @@ layoutTyCl ltycl@(L _loc tycl) = case tycl of
typeDoc typeDoc
DataDecl epAnn name tyVars _ dataDefn -> do DataDecl epAnn name tyVars _ dataDefn -> do
layouters <- mAsk layouters <- mAsk
layout_dataDecl layouters ltycl epAnn name tyVars [] dataDefn layout_dataDecl layouters (Just ltycl) epAnn name tyVars [] dataDefn
_ -> briDocByExactNoComment ltycl _ -> briDocByExactNoComment ltycl
layoutTyVarBndr :: Bool -> ToBriDoc (HsTyVarBndr ()) layoutTyVarBndr :: Bool -> ToBriDoc (HsTyVarBndr ())
@ -976,7 +976,7 @@ layoutClsInst (L declLoc _) cid = do
layouters <- mAsk layouters <- mAsk
layout_dataDecl layout_dataDecl
layouters layouters
(error "Unsupported form of DataFamInstDecl") Nothing
epAnn epAnn
tycon tycon
(case bndrs of (case bndrs of

View File

@ -236,7 +236,7 @@ data Layouters = Layouters
) )
) )
, layout_dataDecl , layout_dataDecl
:: GHC.LTyClDecl GhcPs :: Maybe (GHC.LTyClDecl GhcPs)
-> GHC.EpAnn [GHC.AddEpAnn] -> GHC.EpAnn [GHC.AddEpAnn]
-> GHC.LIdP GhcPs -> GHC.LIdP GhcPs
-> GHC.LHsQTyVars GhcPs -> GHC.LHsQTyVars GhcPs