sourcecode:
|
{- |
Author : Kai-Oliver Prott
Version : March 2025
Datastructures and operations to generate abstract CurryDoc.
-}
module CurryDoc.Info
( generateCurryDocInfosWithAnalysis, generateCurryDocInfos,
module CurryDoc.Info.Comments,
module CurryDoc.Info.Goodies,
module CurryDoc.Info.Header,
module CurryDoc.Data.CurryDoc ) where
import CurryDoc.Data.AnaInfo
import CurryDoc.Data.CurryDoc
import CurryDoc.Info.Comments
import CurryDoc.Info.Analysis
import CurryDoc.Info.Header
import CurryDoc.Info.Export
import CurryDoc.Info.AbstractCurry
import CurryDoc.Info.Goodies
import FlatCurry.Types ( Prog)
import AbstractCurry.Types ( QName, MName, CurryProg(..) )
import AbstractCurry.Select
import Curry.Span
import Curry.Types
import Data.List ( partition, find )
import Data.Maybe ( fromMaybe )
-- | Generates the abstract `CurryDoc` with extended analysis.
generateCurryDocInfosWithAnalysis :: AnaInfo -> String -> [(Span, Comment)]
-> Module a -> CurryProg
-> [(String, CurryDoc)] -> CurryDoc
generateCurryDocInfosWithAnalysis ai mn cs m acy@(CurryProg _ _ _ _ _ _ fun ops)
= genCDoc (addAnaInfoToCurryDocDecls ai ops fun) mn cs m acy
-- | Generates the abstract `CurryDoc` with simple analysis.
generateCurryDocInfos :: String -> [(Span, Comment)]
-> Module a -> CurryProg
-> [(String, CurryDoc)] -> CurryDoc
generateCurryDocInfos mn cs m acy@(CurryProg _ _ _ _ _ _ fun ops)
= genCDoc (addShortAnaInfoToCurryDocDecls ops fun) mn cs m acy
genCDoc :: ([CurryDocDecl] -> [CurryDocDecl])
-> String -> [(Span, Comment)]
-> Module a -> CurryProg
-> [(String, CurryDoc)] -> CurryDoc
genCDoc f mname cs m acy importDoc =
CurryDoc mname mhead export (imports acy)
where
(declsC, moduleC, exportList) = associateCurryDoc cs m
importDecls = map (\(x,CurryDoc _ _ ex _) -> (x,flattenExport ex)) importDoc
decls = addAbstractCurryProg acy declsC
mhead = readModuleHeader moduleC
export = structureDecls ((mname, f decls) : importDecls) mname $
concatMap (inlineExport (getImports m) importDoc
mname (map curryDocDeclName decls))
(fromMaybe (genExportList acy) $ hasSections $ exportList)
-- | Demotes the export structure to `Nothing` if it has no sections.
--
-- This is used to avoid empty export sections in the final `CurryDoc`
-- because we consider empty sections as not useful, and we can fall
-- back to using a default export structure. See `genCDoc`.
hasSections :: Maybe [ExportEntry QName] -> Maybe [ExportEntry QName]
hasSections xs = do
entries <- xs
guard (any isExportSection entries)
return entries
-- | Inserts the declarations into the export structure.
structureDecls :: [(String, [CurryDocDecl])] -> MName
-> [ExportEntry QName]
-> [ExportEntry CurryDocDecl]
structureDecls _ _ [] = []
structureDecls ds mname (ExportSection c n ex : rest) =
ExportSection c n (structureDecls ds mname ex)
: structureDecls ds mname rest
structureDecls ds mname (ExportEntry q : rest) =
maybe [] (:[]) (getFromModule ds q) ++
structureDecls ds mname rest
structureDecls ds mname (ExportEntryModule m : rest) =
ExportEntryModule m : structureDecls ds mname rest
-- lookup the required declaration
getFromModule :: [(String, [CurryDocDecl])] -> QName
-> Maybe (ExportEntry CurryDocDecl)
getFromModule im qname@(mname, _) =
lookup mname im >>= lookupCurryDocDecl qname >>= return . ExportEntry
lookupCurryDocDecl :: QName -> [CurryDocDecl] -> Maybe CurryDocDecl
lookupCurryDocDecl _ [] = Nothing
lookupCurryDocDecl n (d:ds) = case d of
CurryDocTypeDecl n' _ _ _
| n =~= n' -> Just d
| otherwise -> lookupCurryDocDecl n ds
CurryDocDataDecl n' _ _ _ _ _
| n =~= n' -> Just d
| otherwise -> lookupCurryDocDecl n ds
CurryDocNewtypeDecl n' _ _ _ _
| n =~= n' -> Just d
| otherwise -> lookupCurryDocDecl n ds
CurryDocClassDecl n' _ _ _ _ _
| n =~= n' -> Just d
| otherwise -> lookupCurryDocDecl n ds
CurryDocFunctionDecl n' _ _ _ _
| n =~= n' -> Just d
| otherwise -> lookupCurryDocDecl n ds
|