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)