Merge pull request #35 from dvdsgl/doc-render-refactor
Cleanup Doc and Renderer Original commit 4a95cae60c9963125ce2d9a1082e9495f32af853
This commit is contained in:
Коммит
5ad2d7df2b
|
@ -5,15 +5,13 @@ module CSharp
|
|||
import Doc
|
||||
import IRGraph
|
||||
import Prelude
|
||||
import Types
|
||||
|
||||
import Data.Char.Unicode (GeneralCategory(..), generalCategory, isLetter)
|
||||
import Data.Foldable (find, for_, intercalate)
|
||||
import Data.List (List, (:))
|
||||
import Data.List as L
|
||||
import Data.Map (Map)
|
||||
import Data.Map as M
|
||||
import Data.Maybe (Maybe(..), isNothing)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Set (Set)
|
||||
import Data.Set as S
|
||||
import Data.String as Str
|
||||
|
@ -23,42 +21,39 @@ import Partial.Unsafe (unsafePartial)
|
|||
|
||||
import Utils (removeElement)
|
||||
|
||||
type CSDoc = Doc Unit
|
||||
|
||||
forbiddenNames :: Array String
|
||||
forbiddenNames = [ "Converter", "JsonConverter", "Type" ]
|
||||
forbiddenNames = ["Converter", "JsonConverter", "Type"]
|
||||
|
||||
renderer :: Renderer
|
||||
renderer =
|
||||
{ name: "C#"
|
||||
, aceMode: "csharp"
|
||||
, extension: "cs"
|
||||
, render: renderGraphToCSharp
|
||||
, doc: csharpDoc
|
||||
, transforms:
|
||||
{ nameForClass
|
||||
, unionName
|
||||
, unionPredicate
|
||||
, nextName: \s -> "Other" <> s
|
||||
, forbiddenNames
|
||||
}
|
||||
}
|
||||
|
||||
renderGraphToCSharp :: IRGraph -> String
|
||||
renderGraphToCSharp graph =
|
||||
runDoc csharpDoc nameForClass unionName unionPredicate nextNameToTry (S.fromFoldable forbiddenNames) graph unit
|
||||
where
|
||||
unionPredicate =
|
||||
case _ of
|
||||
IRUnion ur ->
|
||||
let s = unionToSet ur
|
||||
in
|
||||
if isNothing $ nullableFromSet s then
|
||||
Just s
|
||||
else
|
||||
Nothing
|
||||
unionPredicate :: IRType -> Maybe (Set IRType)
|
||||
unionPredicate = case _ of
|
||||
IRUnion ur ->
|
||||
let s = unionToSet ur
|
||||
in case nullableFromSet s of
|
||||
Nothing -> Just s
|
||||
_ -> Nothing
|
||||
nameForClass (IRClassData { names }) =
|
||||
csNameStyle $ combineNames names
|
||||
nextNameToTry s =
|
||||
"Other" <> s
|
||||
_ -> Nothing
|
||||
|
||||
nameForClass :: IRClassData -> String
|
||||
nameForClass (IRClassData { names }) = csNameStyle $ combineNames names
|
||||
|
||||
unionName :: List String -> String
|
||||
unionName s =
|
||||
s
|
||||
# L.sort
|
||||
L.sort s
|
||||
<#> csNameStyle
|
||||
# intercalate "Or"
|
||||
|
||||
|
@ -98,7 +93,7 @@ legalizeIdentifier str =
|
|||
else
|
||||
legalizeIdentifier ("_" <> str)
|
||||
|
||||
renderUnionToCSharp :: Set IRType -> CSDoc String
|
||||
renderUnionToCSharp :: Set IRType -> Doc String
|
||||
renderUnionToCSharp s =
|
||||
case nullableFromSet s of
|
||||
Just x -> do
|
||||
|
@ -106,7 +101,7 @@ renderUnionToCSharp s =
|
|||
pure if isValueType x then rendered <> "?" else rendered
|
||||
Nothing -> lookupUnionName s
|
||||
|
||||
renderTypeToCSharp :: IRType -> CSDoc String
|
||||
renderTypeToCSharp :: IRType -> Doc String
|
||||
renderTypeToCSharp = case _ of
|
||||
IRNothing -> pure "object"
|
||||
IRNull -> pure "object"
|
||||
|
@ -126,7 +121,7 @@ renderTypeToCSharp = case _ of
|
|||
csNameStyle :: String -> String
|
||||
csNameStyle = camelCase >>> capitalize >>> legalizeIdentifier
|
||||
|
||||
csharpDoc :: CSDoc Unit
|
||||
csharpDoc :: Doc Unit
|
||||
csharpDoc = do
|
||||
line """// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do:
|
||||
//
|
||||
|
@ -160,7 +155,7 @@ stringIfTrue :: Boolean -> String -> String
|
|||
stringIfTrue true s = s
|
||||
stringIfTrue false _ = ""
|
||||
|
||||
renderJsonConverter :: CSDoc Unit
|
||||
renderJsonConverter :: Doc Unit
|
||||
renderJsonConverter = do
|
||||
unionNames <- getUnionNames
|
||||
let haveUnions = not $ M.isEmpty unionNames
|
||||
|
@ -168,8 +163,7 @@ renderJsonConverter = do
|
|||
line $ "public class Converter" <> stringIfTrue haveUnions ": JsonConverter"
|
||||
line "{"
|
||||
indent do
|
||||
IRGraph { toplevel } <- getGraph
|
||||
toplevelType <- renderTypeToCSharp toplevel
|
||||
toplevelType <- getTopLevel >>= renderTypeToCSharp
|
||||
line "// Loading helpers"
|
||||
let converterParam = stringIfTrue haveUnions ", new Converter()"
|
||||
line
|
||||
|
@ -206,35 +200,32 @@ renderJsonConverter = do
|
|||
line "public override bool CanWrite => false;"
|
||||
line "}"
|
||||
|
||||
tokenCase :: String -> CSDoc Unit
|
||||
tokenCase :: String -> Doc Unit
|
||||
tokenCase tokenType =
|
||||
line $ "case JsonToken." <> tokenType <> ":"
|
||||
|
||||
renderNullDeserializer :: Set IRType -> CSDoc Unit
|
||||
renderNullDeserializer :: Set IRType -> Doc Unit
|
||||
renderNullDeserializer types =
|
||||
when (S.member IRNull types) do
|
||||
tokenCase "Null"
|
||||
indent do
|
||||
line "break;"
|
||||
|
||||
unionFieldName :: IRType -> CSDoc String
|
||||
unionFieldName t = do
|
||||
graph <- getGraph
|
||||
let typeName = typeNameForUnion graph t
|
||||
pure $ csNameStyle typeName
|
||||
unionFieldName :: IRType -> Doc String
|
||||
unionFieldName t = csNameStyle <$> getTypeNameForUnion t
|
||||
|
||||
deserialize :: String -> String -> CSDoc Unit
|
||||
deserialize :: String -> String -> Doc Unit
|
||||
deserialize fieldName typeName = do
|
||||
line $ fieldName <> " = serializer.Deserialize<" <> typeName <> ">(reader);"
|
||||
line "break;"
|
||||
|
||||
deserializeType :: IRType -> CSDoc Unit
|
||||
deserializeType :: IRType -> Doc Unit
|
||||
deserializeType t = do
|
||||
fieldName <- unionFieldName t
|
||||
renderedType <- renderTypeToCSharp t
|
||||
deserialize fieldName renderedType
|
||||
|
||||
renderPrimitiveDeserializer :: List String -> IRType -> Set IRType -> CSDoc Unit
|
||||
renderPrimitiveDeserializer :: List String -> IRType -> Set IRType -> Doc Unit
|
||||
renderPrimitiveDeserializer tokenTypes t types =
|
||||
when (S.member t types) do
|
||||
for_ tokenTypes \tokenType -> do
|
||||
|
@ -242,7 +233,7 @@ renderPrimitiveDeserializer tokenTypes t types =
|
|||
indent do
|
||||
deserializeType t
|
||||
|
||||
renderDoubleDeserializer :: Set IRType -> CSDoc Unit
|
||||
renderDoubleDeserializer :: Set IRType -> Doc Unit
|
||||
renderDoubleDeserializer types =
|
||||
when (S.member IRDouble types) do
|
||||
unless (S.member IRInteger types) do
|
||||
|
@ -251,7 +242,7 @@ renderDoubleDeserializer types =
|
|||
indent do
|
||||
deserializeType IRDouble
|
||||
|
||||
renderGenericDeserializer :: (IRType -> Boolean) -> String -> Set IRType -> CSDoc Unit
|
||||
renderGenericDeserializer :: (IRType -> Boolean) -> String -> Set IRType -> Doc Unit
|
||||
renderGenericDeserializer predicate tokenType types = unsafePartial $
|
||||
case find predicate types of
|
||||
Nothing -> pure unit
|
||||
|
@ -260,7 +251,7 @@ renderGenericDeserializer predicate tokenType types = unsafePartial $
|
|||
indent do
|
||||
deserializeType t
|
||||
|
||||
renderCSharpUnion :: Set IRType -> CSDoc Unit
|
||||
renderCSharpUnion :: Set IRType -> Doc Unit
|
||||
renderCSharpUnion allTypes = do
|
||||
name <- lookupUnionName allTypes
|
||||
let { element: emptyOrNull, rest: nonNullTypes } = removeElement (_ == IRNull) allTypes
|
||||
|
@ -295,7 +286,7 @@ renderCSharpUnion allTypes = do
|
|||
line "}"
|
||||
line "}"
|
||||
|
||||
renderCSharpClass :: IRClassData -> String -> CSDoc Unit
|
||||
renderCSharpClass :: IRClassData -> String -> Doc Unit
|
||||
renderCSharpClass (IRClassData { names, properties }) className = do
|
||||
let propertyNames = transformNames csNameStyle ("Other" <> _) (S.singleton className) $ map (\n -> Tuple n n) $ M.keys properties
|
||||
line $ "public class " <> className
|
||||
|
|
117
src/Doc.purs
117
src/Doc.purs
|
@ -1,12 +1,12 @@
|
|||
module Doc
|
||||
( Doc
|
||||
, getGraph
|
||||
, Renderer
|
||||
, Transforms
|
||||
, getTopLevel
|
||||
, getClasses
|
||||
, getClass
|
||||
, getClassNames
|
||||
, getUnions
|
||||
, getUnionNames
|
||||
, getRendererInfo
|
||||
, lookupName
|
||||
, lookupClassName
|
||||
, lookupUnionName
|
||||
|
@ -16,15 +16,17 @@ module Doc
|
|||
, indent
|
||||
-- Build Doc Unit with monad syntax, then render to string
|
||||
, runDoc
|
||||
, typeNameForUnion
|
||||
, runRenderer
|
||||
, getTypeNameForUnion
|
||||
) where
|
||||
|
||||
import Prelude
|
||||
|
||||
import IR
|
||||
import IRGraph
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.RWS (RWS, evalRWS, asks, gets, modify, tell)
|
||||
import Data.Foldable (for_, intercalate, sequence_)
|
||||
import Data.Foldable (for_)
|
||||
import Data.List (List)
|
||||
import Data.List as L
|
||||
import Data.Map (Map)
|
||||
|
@ -35,28 +37,53 @@ import Data.Set as S
|
|||
import Data.String as String
|
||||
import Data.Tuple (Tuple(..), snd)
|
||||
|
||||
type DocState = { indent :: Int }
|
||||
type DocEnv r = { graph :: IRGraph, classNames :: Map Int String, unionNames :: Map (Set IRType) String, unions :: List (Set IRType), rendererInfo :: r }
|
||||
newtype Doc r a = Doc (RWS (DocEnv r) String DocState a)
|
||||
type Renderer =
|
||||
{ name :: String
|
||||
, extension :: String
|
||||
, aceMode :: String
|
||||
, doc :: Doc Unit
|
||||
, transforms :: Transforms
|
||||
}
|
||||
|
||||
derive newtype instance functorDoc :: Functor (Doc r)
|
||||
derive newtype instance applyDoc :: Apply (Doc r)
|
||||
derive newtype instance applicativeDoc :: Applicative (Doc r)
|
||||
derive newtype instance bindDoc :: Bind (Doc r)
|
||||
derive newtype instance monadDoc :: Monad (Doc r)
|
||||
|
||||
runDoc :: forall r a. Doc r a -> (IRClassData -> String) -> (List String -> String) -> (IRType -> Maybe (Set IRType)) -> (String -> String) -> (Set String) -> IRGraph -> r -> String
|
||||
runDoc (Doc w) nameForClass unionName unionPredicate nextNameToTry forbiddenNames graph rendererInfo =
|
||||
type Transforms =
|
||||
{ nameForClass :: IRClassData -> String
|
||||
, unionName :: List String -> String
|
||||
, unionPredicate :: IRType -> Maybe (Set IRType)
|
||||
, nextName :: String -> String
|
||||
, forbiddenNames :: Array String
|
||||
}
|
||||
|
||||
type DocState = { indent :: Int }
|
||||
|
||||
type DocEnv =
|
||||
{ graph :: IRGraph
|
||||
, classNames :: Map Int String
|
||||
, unionNames :: Map (Set IRType) String
|
||||
, unions :: List (Set IRType)
|
||||
}
|
||||
|
||||
newtype Doc a = Doc (RWS DocEnv String DocState a)
|
||||
|
||||
derive newtype instance functorDoc :: Functor Doc
|
||||
derive newtype instance applyDoc :: Apply Doc
|
||||
derive newtype instance applicativeDoc :: Applicative Doc
|
||||
derive newtype instance bindDoc :: Bind Doc
|
||||
derive newtype instance monadDoc :: Monad Doc
|
||||
|
||||
runRenderer :: Renderer -> IRGraph -> String
|
||||
runRenderer { doc, transforms } = runDoc doc transforms
|
||||
|
||||
runDoc :: forall a. Doc a -> Transforms -> IRGraph -> String
|
||||
runDoc (Doc w) t graph =
|
||||
let classes = classesInGraph graph
|
||||
classNames = transformNames nameForClass nextNameToTry forbiddenNames classes
|
||||
unions = L.fromFoldable $ filterTypes unionPredicate graph
|
||||
forbiddenForUnions = S.union forbiddenNames $ S.fromFoldable $ M.values classNames
|
||||
unionNames = transformNames nameForUnion nextNameToTry forbiddenForUnions $ map (\s -> Tuple s s) unions
|
||||
forbidden = S.fromFoldable t.forbiddenNames
|
||||
classNames = transformNames t.nameForClass t.nextName forbidden classes
|
||||
unions = L.fromFoldable $ filterTypes t.unionPredicate graph
|
||||
forbiddenForUnions = S.union forbidden $ S.fromFoldable $ M.values classNames
|
||||
nameForUnion s = t.unionName $ map (typeNameForUnion graph) $ L.sort $ L.fromFoldable s
|
||||
unionNames = transformNames nameForUnion t.nextName forbiddenForUnions $ map (\s -> Tuple s s) unions
|
||||
in
|
||||
evalRWS w { graph, classNames, unionNames, unions, rendererInfo } { indent: 0 } # snd
|
||||
where
|
||||
nameForUnion s =
|
||||
unionName $ map (typeNameForUnion graph) $ L.sort $ L.fromFoldable s
|
||||
evalRWS w { graph, classNames, unionNames, unions } { indent: 0 } # snd
|
||||
|
||||
typeNameForUnion :: IRGraph -> IRType -> String
|
||||
typeNameForUnion graph = case _ of
|
||||
|
@ -69,30 +96,36 @@ typeNameForUnion graph = case _ of
|
|||
IRArray a -> typeNameForUnion graph a <> "_array"
|
||||
IRClass i ->
|
||||
let IRClassData { names } = getClassFromGraph graph i
|
||||
in
|
||||
combineNames names
|
||||
in combineNames names
|
||||
IRMap t -> typeNameForUnion graph t <> "_map"
|
||||
IRUnion _ -> "union"
|
||||
|
||||
getGraph :: forall r. Doc r IRGraph
|
||||
getTypeNameForUnion :: IRType -> Doc String
|
||||
getTypeNameForUnion typ = do
|
||||
g <- getGraph
|
||||
pure $ typeNameForUnion g typ
|
||||
|
||||
getGraph :: Doc IRGraph
|
||||
getGraph = Doc (asks _.graph)
|
||||
|
||||
getClassNames :: forall r. Doc r (Map Int String)
|
||||
getTopLevel :: Doc IRType
|
||||
getTopLevel = do
|
||||
IRGraph { toplevel } <- getGraph
|
||||
pure toplevel
|
||||
|
||||
getClassNames :: Doc (Map Int String)
|
||||
getClassNames = Doc (asks _.classNames)
|
||||
|
||||
getUnions :: forall r. Doc r (List (Set IRType))
|
||||
getUnions :: Doc (List (Set IRType))
|
||||
getUnions = Doc (asks _.unions)
|
||||
|
||||
getUnionNames :: forall r. Doc r (Map (Set IRType) String)
|
||||
getUnionNames :: Doc (Map (Set IRType) String)
|
||||
getUnionNames = Doc (asks _.unionNames)
|
||||
|
||||
getRendererInfo :: forall r. Doc r r
|
||||
getRendererInfo = Doc (asks _.rendererInfo)
|
||||
|
||||
getClasses :: forall r. Doc r (L.List (Tuple Int IRClassData))
|
||||
getClasses :: Doc (L.List (Tuple Int IRClassData))
|
||||
getClasses = classesInGraph <$> getGraph
|
||||
|
||||
getClass :: forall r. Int -> Doc r IRClassData
|
||||
getClass :: Int -> Doc IRClassData
|
||||
getClass i = do
|
||||
graph <- getGraph
|
||||
pure $ getClassFromGraph graph i
|
||||
|
@ -101,18 +134,18 @@ lookupName :: forall a. Ord a => a -> Map a String -> String
|
|||
lookupName original nameMap =
|
||||
fromMaybe "NAME_NOT_PROCESSED" $ M.lookup original nameMap
|
||||
|
||||
lookupClassName :: forall r. Int -> Doc r String
|
||||
lookupClassName :: Int -> Doc String
|
||||
lookupClassName i = do
|
||||
classNames <- getClassNames
|
||||
pure $ lookupName i classNames
|
||||
|
||||
lookupUnionName :: forall r. Set IRType -> Doc r String
|
||||
lookupUnionName :: Set IRType -> Doc String
|
||||
lookupUnionName s = do
|
||||
unionNames <- getUnionNames
|
||||
pure $ lookupName s unionNames
|
||||
|
||||
-- Given a potentially multi-line string, render each line at the current indent level
|
||||
line :: forall r. String -> Doc r Unit
|
||||
line :: String -> Doc Unit
|
||||
line s = do
|
||||
indent <- Doc (gets _.indent)
|
||||
let whitespace = times "\t" indent
|
||||
|
@ -128,13 +161,13 @@ times s n | n < 1 = ""
|
|||
times s 1 = s
|
||||
times s n = s <> times s (n - 1)
|
||||
|
||||
string :: forall r. String -> Doc r Unit
|
||||
string :: String -> Doc Unit
|
||||
string = Doc <<< tell
|
||||
|
||||
blank :: forall r. Doc r Unit
|
||||
blank :: Doc Unit
|
||||
blank = string "\n"
|
||||
|
||||
indent :: forall r a. Doc r a -> Doc r a
|
||||
indent :: forall a. Doc a -> Doc a
|
||||
indent doc = do
|
||||
Doc $ modify (\s -> { indent: s.indent + 1 })
|
||||
a <- doc
|
||||
|
|
|
@ -5,7 +5,6 @@ module Golang
|
|||
import Doc
|
||||
import IRGraph
|
||||
import Prelude
|
||||
import Types
|
||||
|
||||
import Data.Array as A
|
||||
import Data.Char.Unicode (isDigit, isLetter)
|
||||
|
@ -20,37 +19,38 @@ import Data.String.Util (capitalize, camelCase, stringEscape)
|
|||
import Data.Tuple (Tuple(..))
|
||||
import Utils (mapM, removeElement)
|
||||
|
||||
-- data GoInfo = GoInfo { classNames :: Map Int String }
|
||||
|
||||
type GoDoc = Doc Unit
|
||||
|
||||
renderer :: Renderer
|
||||
renderer =
|
||||
{ name: "Go"
|
||||
, aceMode: "golang"
|
||||
, extension: "go"
|
||||
, render: renderGraphToGolang
|
||||
, doc: golangDoc
|
||||
, transforms:
|
||||
{ nameForClass
|
||||
, unionName
|
||||
, unionPredicate
|
||||
, nextName: \s -> "Other" <> s
|
||||
, forbiddenNames: []
|
||||
}
|
||||
}
|
||||
|
||||
renderGraphToGolang :: IRGraph -> String
|
||||
renderGraphToGolang graph =
|
||||
runDoc golangDoc nameForClass unionName unionPredicate nextNameToTry S.empty graph unit
|
||||
where
|
||||
unionPredicate =
|
||||
case _ of
|
||||
IRUnion ur ->
|
||||
let s = unionToSet ur
|
||||
in
|
||||
if isNothing $ nullableFromSet s then
|
||||
Just s
|
||||
else
|
||||
Nothing
|
||||
unionPredicate :: IRType -> Maybe (Set IRType)
|
||||
unionPredicate = case _ of
|
||||
IRUnion ur ->
|
||||
let s = unionToSet ur
|
||||
in case nullableFromSet s of
|
||||
Nothing -> Just s
|
||||
_ -> Nothing
|
||||
nameForClass (IRClassData { names }) = goNameStyle $ combineNames names
|
||||
unionName components =
|
||||
"OneOf" <> (goNameStyle $ intercalate "_" $ components)
|
||||
nextNameToTry s =
|
||||
"Other" <> s
|
||||
_ -> Nothing
|
||||
|
||||
nameForClass :: IRClassData -> String
|
||||
nameForClass (IRClassData { names }) = goNameStyle $ combineNames names
|
||||
|
||||
unionName :: L.List String -> String
|
||||
unionName s =
|
||||
L.sort s
|
||||
<#> goNameStyle
|
||||
# intercalate "Or"
|
||||
|
||||
isValueType :: IRType -> Boolean
|
||||
isValueType IRInteger = true
|
||||
|
@ -82,7 +82,7 @@ legalizeIdentifier str =
|
|||
else
|
||||
legalizeIdentifier ("_" <> str)
|
||||
|
||||
renderUnionToGolang :: Set IRType -> GoDoc String
|
||||
renderUnionToGolang :: Set IRType -> Doc String
|
||||
renderUnionToGolang s =
|
||||
case nullableFromSet s of
|
||||
Just x -> do
|
||||
|
@ -90,7 +90,7 @@ renderUnionToGolang s =
|
|||
pure if isValueType x then "*" <> rendered else rendered
|
||||
Nothing -> lookupUnionName s
|
||||
|
||||
renderTypeToGolang :: IRType -> GoDoc String
|
||||
renderTypeToGolang :: IRType -> Doc String
|
||||
renderTypeToGolang = case _ of
|
||||
IRNothing -> pure "interface{}"
|
||||
IRNull -> pure "interface{}"
|
||||
|
@ -110,7 +110,7 @@ renderTypeToGolang = case _ of
|
|||
goNameStyle :: String -> String
|
||||
goNameStyle = camelCase >>> capitalize >>> legalizeIdentifier
|
||||
|
||||
golangDoc :: GoDoc Unit
|
||||
golangDoc :: Doc Unit
|
||||
golangDoc = do
|
||||
line "package main"
|
||||
blank
|
||||
|
@ -120,8 +120,7 @@ golangDoc = do
|
|||
line "import \"errors\""
|
||||
line "import \"encoding/json\""
|
||||
blank
|
||||
IRGraph { toplevel } <- getGraph
|
||||
renderedToplevel <- renderTypeToGolang toplevel
|
||||
renderedToplevel <- getTopLevel >>= renderTypeToGolang
|
||||
line $ "type Root " <> renderedToplevel
|
||||
blank
|
||||
classes <- getClasses
|
||||
|
@ -241,7 +240,7 @@ func marshalUnion(pi *int64, pf *float64, pb *bool, ps *string, haveArray bool,
|
|||
renderGolangUnion types
|
||||
blank
|
||||
|
||||
renderGolangType :: Int -> IRClassData -> GoDoc Unit
|
||||
renderGolangType :: Int -> IRClassData -> Doc Unit
|
||||
renderGolangType classIndex (IRClassData { names, properties }) = do
|
||||
className <- lookupClassName classIndex
|
||||
let propertyNames = transformNames goNameStyle ("Other" <> _) S.empty $ map (\n -> Tuple n n) $ Map.keys properties
|
||||
|
@ -253,16 +252,13 @@ renderGolangType classIndex (IRClassData { names, properties }) = do
|
|||
line $ csPropName <> " " <> rendered <> " `json:\"" <> (stringEscape pname) <> "\"`"
|
||||
line "}"
|
||||
|
||||
unionFieldName :: IRType -> GoDoc String
|
||||
unionFieldName t = do
|
||||
graph <- getGraph
|
||||
let typeName = typeNameForUnion graph t
|
||||
pure $ goNameStyle typeName
|
||||
unionFieldName :: IRType -> Doc String
|
||||
unionFieldName t = goNameStyle <$> getTypeNameForUnion t
|
||||
|
||||
compoundPredicates :: Array (IRType -> Boolean)
|
||||
compoundPredicates = [isArray, isClass, isMap]
|
||||
|
||||
renderGolangUnion :: Set IRType -> GoDoc Unit
|
||||
renderGolangUnion :: Set IRType -> Doc Unit
|
||||
renderGolangUnion allTypes = do
|
||||
name <- lookupUnionName allTypes
|
||||
let { element: emptyOrNull, rest: nonNullTypes } = removeElement (_ == IRNull) allTypes
|
||||
|
@ -300,7 +296,7 @@ renderGolangUnion allTypes = do
|
|||
line $ "return marshalUnion(" <> args <> ", " <> isNullableString <> ")"
|
||||
line "}"
|
||||
where
|
||||
ifClass :: (String -> GoDoc Unit) -> GoDoc Unit
|
||||
ifClass :: (String -> Doc Unit) -> Doc Unit
|
||||
ifClass f =
|
||||
let { element } = removeElement isClass allTypes
|
||||
in
|
||||
|
@ -317,12 +313,12 @@ renderGolangUnion allTypes = do
|
|||
name <- unionFieldName t
|
||||
line $ "x." <> name <> " = nil"
|
||||
Nothing -> pure unit
|
||||
makeArgs :: (IRType -> GoDoc String) -> ((IRType -> Boolean) -> GoDoc String) -> GoDoc String
|
||||
makeArgs :: (IRType -> Doc String) -> ((IRType -> Boolean) -> Doc String) -> Doc String
|
||||
makeArgs primitive compound = do
|
||||
primitiveArgs <- mapM primitive $ L.fromFoldable [IRInteger, IRDouble, IRBool, IRString]
|
||||
compoundArgs <- mapM compound $ L.fromFoldable compoundPredicates
|
||||
pure $ intercalate ", " $ A.concat [A.fromFoldable primitiveArgs, A.fromFoldable compoundArgs]
|
||||
memberArg :: String -> (String -> String) -> (IRType -> Boolean) -> GoDoc String
|
||||
memberArg :: String -> (String -> String) -> (IRType -> Boolean) -> Doc String
|
||||
memberArg notPresentValue renderPresent p =
|
||||
let { element } = removeElement p allTypes
|
||||
in
|
||||
|
@ -335,9 +331,9 @@ renderGolangUnion allTypes = do
|
|||
memberArg "nil" ("&x." <> _) (eq t)
|
||||
compoundUnmarshalArg p =
|
||||
memberArg "false, nil" ("true, &x." <> _) p
|
||||
primitiveMarshalArg :: IRType -> GoDoc String
|
||||
primitiveMarshalArg :: IRType -> Doc String
|
||||
primitiveMarshalArg t =
|
||||
memberArg "nil" ("x." <> _) (eq t)
|
||||
compoundMarshalArg :: (IRType -> Boolean) -> GoDoc String
|
||||
compoundMarshalArg :: (IRType -> Boolean) -> Doc String
|
||||
compoundMarshalArg p =
|
||||
memberArg "false, nil" (\n -> "x." <> n <> " != nil, x." <> n) p
|
||||
|
|
|
@ -4,7 +4,6 @@ import IR
|
|||
import IRGraph
|
||||
import Prelude
|
||||
import Transformations
|
||||
import Types
|
||||
|
||||
import CSharp as CSharp
|
||||
import Data.Argonaut.Core (Json, foldJson)
|
||||
|
@ -16,12 +15,13 @@ import Data.Set as S
|
|||
import Data.StrMap as StrMap
|
||||
import Data.String.Util (singular)
|
||||
import Data.Tuple (Tuple(..))
|
||||
|
||||
import Doc as Doc
|
||||
import Golang (renderer)
|
||||
|
||||
import Golang as Golang
|
||||
import Utils (mapM)
|
||||
|
||||
renderers :: Array Renderer
|
||||
renderers :: Array Doc.Renderer
|
||||
renderers = [CSharp.renderer, Golang.renderer]
|
||||
|
||||
makeTypeFromJson :: String -> Json -> IR IRType
|
||||
|
@ -50,13 +50,14 @@ makeTypeAndUnify name json = runIR do
|
|||
replaceSimilarClasses
|
||||
makeMaps
|
||||
|
||||
renderJson :: Renderer -> Json -> String
|
||||
renderJson renderer =
|
||||
makeTypeAndUnify "TopLevel"
|
||||
>>> regatherClassNames
|
||||
>>> renderer.render
|
||||
renderJson :: Doc.Renderer -> Json -> String
|
||||
renderJson renderer json =
|
||||
json
|
||||
# makeTypeAndUnify "TopLevel"
|
||||
# regatherClassNames
|
||||
# Doc.runRenderer renderer
|
||||
|
||||
renderJsonString :: Renderer -> String -> Either String String
|
||||
renderJsonString :: Doc.Renderer -> String -> Either String String
|
||||
renderJsonString renderer json =
|
||||
jsonParser json
|
||||
<#> renderJson renderer
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
module Types where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.List as L
|
||||
|
||||
import IRGraph
|
||||
import Doc
|
||||
|
||||
type Renderer = {
|
||||
name :: String,
|
||||
extension :: String,
|
||||
aceMode :: String,
|
||||
render :: IRGraph -> String
|
||||
}
|
Загрузка…
Ссылка в новой задаче