CurryInfo: currydoc-5.0.0 / CurryDoc.Generators.JSON

classes: Info
 
documentation: Info
 
name: Info
 CurryDoc.Generators.JSON
operations: Info
 generateJSON
sourcecode: Info
 
module CurryDoc.Generators.JSON ( generateJSON ) where

import CurryDoc.Info
import CurryDoc.Info.Export
import CurryDoc.Data.CurryDoc

import JSON.Data
import JSON.Pretty
import AbstractCurry.Types
import AbstractCurry.Pretty
import Text.Pretty

import Data.List

class ToJSON a where
  toJSON :: a -> JValue

-- | Converts a CurryDoc to a JSON string.
generateJSON :: CurryDoc -> IO String
generateJSON = return . ppJSON . toJSON

instance ToJSON CurryDoc where
  toJSON (CurryDoc name (ModuleHeader header _) ds _) = JObject
    ([("module", JString name)] ++
     map jsonHeader  header     ++
     [jsonFunctions fs, jsonTypes ts, jsonTypeclasses cs])
    where ds' = flattenExport ds
          fs  = filter isCurryDocFuncDecl  ds'
          ts  = filter isCurryDocTypeDecl  ds'
          cs  = filter isCurryDocClassDecl ds'

instance ToJSON CurryDocDecl where
  toJSON (CurryDocTypeDecl    (mname, name) vs      ty   cs) = JObject
    [ (       "datatype", JString "type"          )
    , (    "module-name", JString mname           )
    , ( "type-variables", jsonVars vs             )
    , (           "name", JString  name           )
    , (           "type", toJSON ty               )
    , (       "comments", toJSON cs               )]
  toJSON (CurryDocDataDecl    (mname, name) vs _ ex cons cs) = JObject
    [ (       "datatype", JString "data"          )
    , (    "module-name", JString mname           )
    , (           "name", JString  name           )
    , ( "type-variables", jsonVars vs             )
    , (       "external", toJSON ex               )
    , (   "constructors", JArray (map (toJSONCons r) cons ))
    , (       "comments", toJSON cs               )]
    where r     = foldr (\v t -> CTApply t (CTVar v)) (CTCons (mname, name)) vs
  toJSON (CurryDocNewtypeDecl (mname, name) vs _    cons cs) = JObject
    [ (       "datatype", JString "newtype"       )
    , (    "module-name", JString mname           )
    , (           "name", JString  name           )
    , ( "type-variables", jsonVars vs             )
    , (   "constructors", JArray (map (toJSONCons r) cons'))
    , (       "comments", toJSON cs               )]
    where r     = foldr (\v t -> CTApply t (CTVar v)) (CTCons (mname, name)) vs
          cons' = case cons of
                    Just c  -> [c]
                    Nothing -> []

  toJSON (CurryDocClassDecl (mname, name) cx vs fdeps ds cs) = JObject
    [ (     "module-name", JString mname          )
    , (            "name", JString  name          )
    , (         "context", toJSON cx              )
    , (  "type-variables", JArray $ map jsonVar vs)
    , ( "class-functions", toJSON ds              )
    , ( "functional-deps", toJSON fdeps           )
    , (        "comments", toJSON cs              )]

  toJSON (CurryDocFunctionDecl (mname, name) ty _ _ cs) = JObject
    [ ("module-name", JString mname)
    , (       "name", JString  name)
    , (       "type", toJSON ty    )
    , (   "comments", toJSON cs    )]

instance ToJSON CurryDocFunDep where
  toJSON (CurryDocFunDep (xs, ys)) = JObject 
    [ ("lhs", jsonVars xs) 
    , ("rhs", jsonVars ys)]

instance ToJSON a => ToJSON [a] where
  toJSON = JArray . map toJSON

instance ToJSON Bool where
  toJSON True  = JTrue
  toJSON False = JFalse

instance ToJSON CContext where
  toJSON (CContext cs) = JArray (map (JString . ppConstraint) cs)

instance ToJSON CQualTypeExpr where
  toJSON (CQualType (CContext []        ) ty) =
    JString (ppType ty)
  toJSON (CQualType (CContext [x]       ) ty) =
    JString (ppConstraint x ++ " => " ++ ppType ty)
  toJSON (CQualType (CContext xs@(_:_:_)) ty) =
    JString ("(" ++ intercalate ", " (map ppConstraint xs) ++ ") => "
                 ++ ppType ty)

instance ToJSON CTypeExpr where
  toJSON = JString . ppType

instance ToJSON Comment where
  toJSON (NestedComment c) = JString c
  toJSON (LineComment   c) = JString c

toJSONCons :: CTypeExpr -> CurryDocCons -> JValue
toJSONCons ty (CurryDocConstr (mname, name) args        _ cs) = JObject
    [ ("constructor", JString "constructor"         )
    , ("module-name", JString mname                 )
    , (       "name", JString  name                 )
    , (       "type", jsonListTypes (args ++ [ty])  )
    , (   "comments", toJSON cs                     )]
toJSONCons ty (CurryDocConsOp (mname, name) arg1 arg2   _ cs) = JObject
    [ ("constructor", JString "operator"            )
    , ("module-name", JString mname                 )
    , (       "name", JString  name                 )
    , (       "type", jsonListTypes [arg1, arg2, ty])
    , (   "comments", toJSON cs                     )]
toJSONCons ty (CurryDocRecord (mname, name) args fields _ cs) = JObject
    [ ("constructor", JString "constructor"         )
    , ("module-name", JString mname                 )
    , (       "name", JString  name                 )
    , (       "type", jsonListTypes (args ++ [ty])  )
    , (     "fields", toJSON fields                 )
    , (   "comments", toJSON cs                     )]

instance ToJSON CurryDocField where
  toJSON (CurryDocField (mname, name) ty _ cs) = JObject
    [ ("module-name", JString mname)
    , (       "name", JString  name)
    , (       "type", toJSON ty    )
    , (   "comments", toJSON cs    )]


jsonListTypes :: [CTypeExpr] -> JValue
jsonListTypes = JString . intercalate " -> " . map ppType

jsonVar :: CTVarIName -> JValue
jsonVar = JString . snd

jsonVars :: [CTVarIName] -> JValue
jsonVars = JArray . map jsonVar

ppConstraint :: CConstraint -> String
ppConstraint ((_, name), ts) = name ++ " " ++ unwords (map ppType ts)

ppType :: CTypeExpr -> String
ppType = unwords . concatMap words . lines
       . pPrint . ppCTypeExpr (setNoQualification defaultOptions)

jsonHeader :: (HeaderField, String) -> (String, JValue)
jsonHeader (Description, d) = ("description", JString d)
jsonHeader (Category   , d) = ("category"   , JString d)
jsonHeader (Author     , d) = ("author"     , JString d)
jsonHeader (Version    , d) = ("version"    , JString d)

jsonFunctions   :: [CurryDocDecl] -> (String, JValue)
jsonFunctions   ds = ("functions"  , toJSON ds)

jsonTypes       :: [CurryDocDecl] -> (String, JValue)
jsonTypes       ds = ("types"      , toJSON ds)

jsonTypeclasses :: [CurryDocDecl] -> (String, JValue)
jsonTypeclasses ds = ("typeclasses", toJSON ds)
types: Info
 
unsafe: Info
 unsafe due to modules CASS.Registry Analysis.NondetOps System.IO.Unsafe Analysis.UnsafeModule