From 901898d7494634f7fd4fe219ce81a16fec4c9d02 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 19:35:33 -0700 Subject: [PATCH 01/12] Tidying runDoc call Original commit f94bde27ce59c15c811649317a9217b906480328 --- src/CSharp.purs | 45 +++++++++++++++++++++++++++------------------ src/Doc.purs | 20 ++++++++++---------- src/Golang.purs | 46 ++++++++++++++++++++++++++++------------------ src/Types.purs | 13 +++++++++++-- 4 files changed, 76 insertions(+), 48 deletions(-) diff --git a/src/CSharp.purs b/src/CSharp.purs index 8d9b0c1f..fa66f310 100644 --- a/src/CSharp.purs +++ b/src/CSharp.purs @@ -26,7 +26,7 @@ import Utils (removeElement) type CSDoc = Doc Unit forbiddenNames :: Array String -forbiddenNames = [ "Converter", "JsonConverter", "Type" ] +forbiddenNames = ["Converter", "JsonConverter", "Type"] renderer :: Renderer renderer = @@ -36,24 +36,33 @@ renderer = , render: renderGraphToCSharp } +transforms :: RendererTransformations +transforms = { + nameForClass, + unionName, + unionPredicate, + nextNameToTry: \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 - _ -> Nothing - nameForClass (IRClassData { names }) = - csNameStyle $ combineNames names - nextNameToTry s = - "Other" <> s +renderGraphToCSharp graph = runDoc csharpDoc transforms graph unit + +unionPredicate :: IRType -> Maybe (Set IRType) +unionPredicate = case _ of + IRUnion ur -> + let s = unionToSet ur + in + if isNothing $ nullableFromSet s then + Just s + else + Nothing + _ -> Nothing + + +nameForClass :: IRClassData -> String +nameForClass (IRClassData { names }) = + csNameStyle $ combineNames names unionName :: List String -> String unionName s = diff --git a/src/Doc.purs b/src/Doc.purs index 0d175e46..4351ddd2 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -22,6 +22,7 @@ module Doc import IR import IRGraph import Prelude +import Types import Control.Monad.RWS (RWS, evalRWS, asks, gets, modify, tell) import Data.Foldable (for_, intercalate, sequence_) @@ -45,18 +46,17 @@ 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 = +runDoc :: forall r a. Doc r a -> RendererTransformations -> IRGraph -> r -> String +runDoc (Doc w) t graph rendererInfo = 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.nextNameToTry 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.nextNameToTry 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, rendererInfo } { indent: 0 } # snd typeNameForUnion :: IRGraph -> IRType -> String typeNameForUnion graph = case _ of diff --git a/src/Golang.purs b/src/Golang.purs index c478782e..498a2a83 100644 --- a/src/Golang.purs +++ b/src/Golang.purs @@ -32,25 +32,35 @@ renderer = , render: renderGraphToGolang } +transforms :: RendererTransformations +transforms = { + nameForClass, + unionName, + unionPredicate, + nextNameToTry: \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 - _ -> Nothing - nameForClass (IRClassData { names }) = goNameStyle $ combineNames names - unionName components = - "OneOf" <> (goNameStyle $ intercalate "_" $ components) - nextNameToTry s = - "Other" <> s +renderGraphToGolang graph = runDoc golangDoc transforms graph unit + +unionPredicate :: IRType -> Maybe (Set IRType) +unionPredicate = case _ of + IRUnion ur -> + let s = unionToSet ur + in + if isNothing $ nullableFromSet s then + Just s + else + Nothing + _ -> Nothing + +nameForClass :: IRClassData -> String +nameForClass (IRClassData { names }) = goNameStyle $ combineNames names + +unionName :: L.List String -> String +unionName components = + "OneOf" <> (goNameStyle $ intercalate "_" $ components) isValueType :: IRType -> Boolean isValueType IRInteger = true diff --git a/src/Types.purs b/src/Types.purs index af92340f..e5c27077 100644 --- a/src/Types.purs +++ b/src/Types.purs @@ -2,14 +2,23 @@ module Types where import Prelude -import Data.List as L +import Data.Set (Set()) +import Data.List (List()) +import Data.Maybe (Maybe()) import IRGraph -import Doc type Renderer = { name :: String, extension :: String, aceMode :: String, render :: IRGraph -> String +} + +type RendererTransformations = { + nameForClass :: IRClassData -> String, + unionName :: List String -> String, + unionPredicate :: IRType -> Maybe (Set IRType), + nextNameToTry :: String -> String, + forbiddenNames :: Array String } \ No newline at end of file From a1447c53e79f5c4b843e57522264a26ab7f8bc50 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 19:40:57 -0700 Subject: [PATCH 02/12] Remove rendererInfo Original commit 0835a12c1adb78d383f1e8f827bcff6261114630 --- src/CSharp.purs | 32 +++++++++++++++----------------- src/Doc.purs | 48 ++++++++++++++++++++++-------------------------- src/Golang.purs | 28 ++++++++++++---------------- 3 files changed, 49 insertions(+), 59 deletions(-) diff --git a/src/CSharp.purs b/src/CSharp.purs index fa66f310..22204848 100644 --- a/src/CSharp.purs +++ b/src/CSharp.purs @@ -23,8 +23,6 @@ import Partial.Unsafe (unsafePartial) import Utils (removeElement) -type CSDoc = Doc Unit - forbiddenNames :: Array String forbiddenNames = ["Converter", "JsonConverter", "Type"] @@ -46,7 +44,7 @@ transforms = { } renderGraphToCSharp :: IRGraph -> String -renderGraphToCSharp graph = runDoc csharpDoc transforms graph unit +renderGraphToCSharp graph = runDoc csharpDoc transforms graph unionPredicate :: IRType -> Maybe (Set IRType) unionPredicate = case _ of @@ -107,7 +105,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 @@ -115,7 +113,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" @@ -135,7 +133,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: // @@ -169,7 +167,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 @@ -215,35 +213,35 @@ 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 :: IRType -> Doc String unionFieldName t = do graph <- getGraph let typeName = typeNameForUnion graph t pure $ csNameStyle typeName -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 @@ -251,7 +249,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 @@ -260,7 +258,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 @@ -269,7 +267,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 @@ -304,7 +302,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 diff --git a/src/Doc.purs b/src/Doc.purs index 4351ddd2..d797d226 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -6,7 +6,6 @@ module Doc , getClassNames , getUnions , getUnionNames - , getRendererInfo , lookupName , lookupClassName , lookupUnionName @@ -37,17 +36,17 @@ 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 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 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) +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 -runDoc :: forall r a. Doc r a -> RendererTransformations -> IRGraph -> r -> String -runDoc (Doc w) t graph rendererInfo = +runDoc :: forall a. Doc a -> RendererTransformations -> IRGraph -> String +runDoc (Doc w) t graph = let classes = classesInGraph graph forbidden = S.fromFoldable t.forbiddenNames classNames = transformNames t.nameForClass t.nextNameToTry forbidden classes @@ -56,7 +55,7 @@ runDoc (Doc w) t graph rendererInfo = nameForUnion s = t.unionName $ map (typeNameForUnion graph) $ L.sort $ L.fromFoldable s unionNames = transformNames nameForUnion t.nextNameToTry forbiddenForUnions $ map (\s -> Tuple s s) unions in - evalRWS w { graph, classNames, unionNames, unions, rendererInfo } { indent: 0 } # snd + evalRWS w { graph, classNames, unionNames, unions } { indent: 0 } # snd typeNameForUnion :: IRGraph -> IRType -> String typeNameForUnion graph = case _ of @@ -74,25 +73,22 @@ typeNameForUnion graph = case _ of IRMap t -> typeNameForUnion graph t <> "_map" IRUnion _ -> "union" -getGraph :: forall r. Doc r IRGraph +getGraph :: Doc IRGraph getGraph = Doc (asks _.graph) -getClassNames :: forall r. Doc r (Map Int String) +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 +97,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 +124,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 diff --git a/src/Golang.purs b/src/Golang.purs index 498a2a83..b7506c26 100644 --- a/src/Golang.purs +++ b/src/Golang.purs @@ -20,10 +20,6 @@ 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" @@ -42,7 +38,7 @@ transforms = { } renderGraphToGolang :: IRGraph -> String -renderGraphToGolang graph = runDoc golangDoc transforms graph unit +renderGraphToGolang graph = runDoc golangDoc transforms graph unionPredicate :: IRType -> Maybe (Set IRType) unionPredicate = case _ of @@ -92,7 +88,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 @@ -100,7 +96,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{}" @@ -120,7 +116,7 @@ renderTypeToGolang = case _ of goNameStyle :: String -> String goNameStyle = camelCase >>> capitalize >>> legalizeIdentifier -golangDoc :: GoDoc Unit +golangDoc :: Doc Unit golangDoc = do line "package main" blank @@ -251,7 +247,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 @@ -263,7 +259,7 @@ renderGolangType classIndex (IRClassData { names, properties }) = do line $ csPropName <> " " <> rendered <> " `json:\"" <> (stringEscape pname) <> "\"`" line "}" -unionFieldName :: IRType -> GoDoc String +unionFieldName :: IRType -> Doc String unionFieldName t = do graph <- getGraph let typeName = typeNameForUnion graph t @@ -272,7 +268,7 @@ unionFieldName t = do 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 @@ -310,7 +306,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 @@ -327,12 +323,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 @@ -345,9 +341,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 From cc5db4255f65f45dd35f286c24c040a3ea5a2e0e Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 19:58:27 -0700 Subject: [PATCH 03/12] Put Transforms functions in the renderer Original commit 13a8d44400e0c67f874d5b89658c2c85325bcc59 --- src/CSharp.purs | 22 ++++++++-------------- src/Doc.purs | 29 ++++++++++++++++++++++++++--- src/Golang.purs | 22 ++++++++-------------- src/Main.purs | 19 ++++++++++--------- src/Types.purs | 24 ------------------------ 5 files changed, 52 insertions(+), 64 deletions(-) delete mode 100644 src/Types.purs diff --git a/src/CSharp.purs b/src/CSharp.purs index 22204848..fe95df9e 100644 --- a/src/CSharp.purs +++ b/src/CSharp.purs @@ -5,7 +5,6 @@ module CSharp import Doc import IRGraph import Prelude -import Types import Data.Char.Unicode (GeneralCategory(..), generalCategory, isLetter) import Data.Foldable (find, for_, intercalate) @@ -31,21 +30,16 @@ renderer = { name: "C#" , aceMode: "csharp" , extension: "cs" - , render: renderGraphToCSharp + , doc: csharpDoc + , transforms: + { nameForClass + , unionName + , unionPredicate + , nextNameToTry: \s -> "Other" <> s + , forbiddenNames + } } -transforms :: RendererTransformations -transforms = { - nameForClass, - unionName, - unionPredicate, - nextNameToTry: \s -> "Other" <> s, - forbiddenNames -} - -renderGraphToCSharp :: IRGraph -> String -renderGraphToCSharp graph = runDoc csharpDoc transforms graph - unionPredicate :: IRType -> Maybe (Set IRType) unionPredicate = case _ of IRUnion ur -> diff --git a/src/Doc.purs b/src/Doc.purs index d797d226..b4ba0a8b 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -1,5 +1,7 @@ module Doc ( Doc + , Renderer + , Transforms , getGraph , getClasses , getClass @@ -15,13 +17,13 @@ module Doc , indent -- Build Doc Unit with monad syntax, then render to string , runDoc + , runRenderer , typeNameForUnion ) where import IR import IRGraph import Prelude -import Types import Control.Monad.RWS (RWS, evalRWS, asks, gets, modify, tell) import Data.Foldable (for_, intercalate, sequence_) @@ -35,8 +37,26 @@ import Data.Set as S import Data.String as String import Data.Tuple (Tuple(..), snd) +type Renderer = { + name :: String, + extension :: String, + aceMode :: String, + doc :: Doc Unit, + transforms :: Transforms +} + +type Transforms = { + nameForClass :: IRClassData -> String, + unionName :: List String -> String, + unionPredicate :: IRType -> Maybe (Set IRType), + nextNameToTry :: 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 @@ -44,8 +64,11 @@ derive newtype instance applyDoc :: Apply Doc derive newtype instance applicativeDoc :: Applicative Doc derive newtype instance bindDoc :: Bind Doc derive newtype instance monadDoc :: Monad Doc - -runDoc :: forall a. Doc a -> RendererTransformations -> IRGraph -> String + +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 forbidden = S.fromFoldable t.forbiddenNames diff --git a/src/Golang.purs b/src/Golang.purs index b7506c26..6e33c491 100644 --- a/src/Golang.purs +++ b/src/Golang.purs @@ -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) @@ -25,21 +24,16 @@ renderer = { name: "Go" , aceMode: "golang" , extension: "go" - , render: renderGraphToGolang + , doc: golangDoc + , transforms: + { nameForClass + , unionName + , unionPredicate + , nextNameToTry: \s -> "Other" <> s + , forbiddenNames: [] + } } -transforms :: RendererTransformations -transforms = { - nameForClass, - unionName, - unionPredicate, - nextNameToTry: \s -> "Other" <> s, - forbiddenNames: [] -} - -renderGraphToGolang :: IRGraph -> String -renderGraphToGolang graph = runDoc golangDoc transforms graph - unionPredicate :: IRType -> Maybe (Set IRType) unionPredicate = case _ of IRUnion ur -> diff --git a/src/Main.purs b/src/Main.purs index cd7faf7f..56aaa780 100644 --- a/src/Main.purs +++ b/src/Main.purs @@ -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 diff --git a/src/Types.purs b/src/Types.purs deleted file mode 100644 index e5c27077..00000000 --- a/src/Types.purs +++ /dev/null @@ -1,24 +0,0 @@ -module Types where - -import Prelude - -import Data.Set (Set()) -import Data.List (List()) -import Data.Maybe (Maybe()) - -import IRGraph - -type Renderer = { - name :: String, - extension :: String, - aceMode :: String, - render :: IRGraph -> String -} - -type RendererTransformations = { - nameForClass :: IRClassData -> String, - unionName :: List String -> String, - unionPredicate :: IRType -> Maybe (Set IRType), - nextNameToTry :: String -> String, - forbiddenNames :: Array String -} \ No newline at end of file From d028698ef68688aa10c925ec3997451a6f77bb99 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:05:54 -0700 Subject: [PATCH 04/12] Renderer no longer need the graph directly Original commit 942fedcc45090688d33ce8eb1999746f9e1aec00 --- src/CSharp.purs | 8 ++------ src/Doc.purs | 14 ++++++++++++-- src/Golang.purs | 8 ++------ 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/CSharp.purs b/src/CSharp.purs index fe95df9e..ee2ebc80 100644 --- a/src/CSharp.purs +++ b/src/CSharp.purs @@ -169,8 +169,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 @@ -219,10 +218,7 @@ renderNullDeserializer types = line "break;" unionFieldName :: IRType -> Doc String -unionFieldName t = do - graph <- getGraph - let typeName = typeNameForUnion graph t - pure $ csNameStyle typeName +unionFieldName t = csNameStyle <$> getTypeNameForUnion t deserialize :: String -> String -> Doc Unit deserialize fieldName typeName = do diff --git a/src/Doc.purs b/src/Doc.purs index b4ba0a8b..1937c9c4 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -2,7 +2,7 @@ module Doc ( Doc , Renderer , Transforms - , getGraph + , getTopLevel , getClasses , getClass , getClassNames @@ -18,7 +18,7 @@ module Doc -- Build Doc Unit with monad syntax, then render to string , runDoc , runRenderer - , typeNameForUnion + , getTypeNameForUnion ) where import IR @@ -96,9 +96,19 @@ typeNameForUnion graph = case _ of IRMap t -> typeNameForUnion graph t <> "_map" IRUnion _ -> "union" +getTypeNameForUnion :: IRType -> Doc String +getTypeNameForUnion typ = do + g <- getGraph + pure $ typeNameForUnion g typ + getGraph :: Doc IRGraph getGraph = Doc (asks _.graph) +getTopLevel :: Doc IRType +getTopLevel = do + IRGraph { toplevel } <- getGraph + pure toplevel + getClassNames :: Doc (Map Int String) getClassNames = Doc (asks _.classNames) diff --git a/src/Golang.purs b/src/Golang.purs index 6e33c491..54dab148 100644 --- a/src/Golang.purs +++ b/src/Golang.purs @@ -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 @@ -254,10 +253,7 @@ renderGolangType classIndex (IRClassData { names, properties }) = do line "}" unionFieldName :: IRType -> Doc String -unionFieldName t = do - graph <- getGraph - let typeName = typeNameForUnion graph t - pure $ goNameStyle typeName +unionFieldName t = goNameStyle <$> getTypeNameForUnion t compoundPredicates :: Array (IRType -> Boolean) compoundPredicates = [isArray, isClass, isMap] From 8941899bd375579ae6793b08171cfbac2d774051 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:12:53 -0700 Subject: [PATCH 05/12] Tidy Original commit a39189d8558e85fff75f8b438a841d3d0d1b6895 --- src/CSharp.purs | 14 +++++--------- src/Golang.purs | 14 +++++++------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/CSharp.purs b/src/CSharp.purs index ee2ebc80..32b8ad45 100644 --- a/src/CSharp.purs +++ b/src/CSharp.purs @@ -44,22 +44,18 @@ unionPredicate :: IRType -> Maybe (Set IRType) unionPredicate = case _ of IRUnion ur -> let s = unionToSet ur - in - if isNothing $ nullableFromSet s then - Just s - else - Nothing + in case nullableFromSet s of + Nothing -> Just s + _ -> Nothing _ -> Nothing nameForClass :: IRClassData -> String -nameForClass (IRClassData { names }) = - csNameStyle $ combineNames names +nameForClass (IRClassData { names }) = csNameStyle $ combineNames names unionName :: List String -> String unionName s = - s - # L.sort + L.sort s <#> csNameStyle # intercalate "Or" diff --git a/src/Golang.purs b/src/Golang.purs index 54dab148..0d38802d 100644 --- a/src/Golang.purs +++ b/src/Golang.purs @@ -38,19 +38,19 @@ unionPredicate :: IRType -> Maybe (Set IRType) unionPredicate = case _ of IRUnion ur -> let s = unionToSet ur - in - if isNothing $ nullableFromSet s then - Just s - else - Nothing + in case nullableFromSet s of + Nothing -> Just s + _ -> Nothing _ -> Nothing nameForClass :: IRClassData -> String nameForClass (IRClassData { names }) = goNameStyle $ combineNames names unionName :: L.List String -> String -unionName components = - "OneOf" <> (goNameStyle $ intercalate "_" $ components) +unionName s = + L.sort s + <#> goNameStyle + # intercalate "Or" isValueType :: IRType -> Boolean isValueType IRInteger = true From 81349c3095f3c4ee9a53f8ce716243900a5d1364 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:15:51 -0700 Subject: [PATCH 06/12] Tidy Original commit 27982284607073d0cdc32ba500ce982d2d0b7602 --- src/CSharp.purs | 2 +- src/Doc.purs | 6 +++--- src/Golang.purs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CSharp.purs b/src/CSharp.purs index 32b8ad45..59e8dabf 100644 --- a/src/CSharp.purs +++ b/src/CSharp.purs @@ -35,7 +35,7 @@ renderer = { nameForClass , unionName , unionPredicate - , nextNameToTry: \s -> "Other" <> s + , nextName: ("Other" <> _) , forbiddenNames } } diff --git a/src/Doc.purs b/src/Doc.purs index 1937c9c4..4db321a1 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -49,7 +49,7 @@ type Transforms = { nameForClass :: IRClassData -> String, unionName :: List String -> String, unionPredicate :: IRType -> Maybe (Set IRType), - nextNameToTry :: String -> String, + nextName :: String -> String, forbiddenNames :: Array String } @@ -72,11 +72,11 @@ runDoc :: forall a. Doc a -> Transforms -> IRGraph -> String runDoc (Doc w) t graph = let classes = classesInGraph graph forbidden = S.fromFoldable t.forbiddenNames - classNames = transformNames t.nameForClass t.nextNameToTry forbidden classes + 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.nextNameToTry forbiddenForUnions $ map (\s -> Tuple s s) unions + unionNames = transformNames nameForUnion t.nextName forbiddenForUnions $ map (\s -> Tuple s s) unions in evalRWS w { graph, classNames, unionNames, unions } { indent: 0 } # snd diff --git a/src/Golang.purs b/src/Golang.purs index 0d38802d..5dc0b799 100644 --- a/src/Golang.purs +++ b/src/Golang.purs @@ -29,7 +29,7 @@ renderer = { nameForClass , unionName , unionPredicate - , nextNameToTry: \s -> "Other" <> s + , nextName: ("Other" <> _) , forbiddenNames: [] } } From 368492d166ed8925a9347d5325a83626ecf57a3e Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:17:07 -0700 Subject: [PATCH 07/12] Tidy Original commit c83faec08e6b21cb8a4a6c8c6e2b7daaf27b29e0 --- src/Doc.purs | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/Doc.purs b/src/Doc.purs index 4db321a1..81fdab3f 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -37,25 +37,30 @@ import Data.Set as S import Data.String as String import Data.Tuple (Tuple(..), snd) -type Renderer = { - name :: String, - extension :: String, - aceMode :: String, - doc :: Doc Unit, - transforms :: Transforms -} +type Renderer = + { name :: String + , extension :: String + , aceMode :: String + , doc :: Doc Unit + , transforms :: Transforms + } -type Transforms = { - nameForClass :: IRClassData -> String, - unionName :: List String -> String, - unionPredicate :: IRType -> Maybe (Set IRType), - nextName :: String -> String, - forbiddenNames :: Array String -} +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) } +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) From 632bf213f089c3c6cff8addc9cb1784cc8bb3414 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:23:21 -0700 Subject: [PATCH 08/12] Unused Original commit 48ad3b158bf60a13853ac1061474444e9ca22c6d --- src/Doc.purs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Doc.purs b/src/Doc.purs index 81fdab3f..69886f7a 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -5,7 +5,6 @@ module Doc , getTopLevel , getClasses , getClass - , getClassNames , getUnions , getUnionNames , lookupName From 552fe3f872216fc09b98b6bc85a704cf43f09656 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:23:26 -0700 Subject: [PATCH 09/12] Tidy Original commit a665738b26eba12431e59c59e633976f951498c2 --- src/Doc.purs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Doc.purs b/src/Doc.purs index 69886f7a..a575ab3d 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -20,12 +20,13 @@ module Doc , getTypeNameForUnion ) where -import IR -import IRGraph import Prelude +import IR +import IRGraph + 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) From 760395d6bb47f3ce1700fe487808340b129e35e6 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:24:18 -0700 Subject: [PATCH 10/12] Tidy Original commit 8cfbcad237665dad6bb8037bcf17bb5bcfdd9905 --- src/Doc.purs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Doc.purs b/src/Doc.purs index a575ab3d..9cad89b0 100644 --- a/src/Doc.purs +++ b/src/Doc.purs @@ -96,8 +96,7 @@ 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" From 971f88c39db7a97f96e963730d0e5a9fa3124714 Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:27:04 -0700 Subject: [PATCH 11/12] IDE didn't like this Original commit a1564de64933d66254c965745294bfe4a5de2699 --- src/CSharp.purs | 2 +- src/Golang.purs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CSharp.purs b/src/CSharp.purs index 59e8dabf..72c8bb2f 100644 --- a/src/CSharp.purs +++ b/src/CSharp.purs @@ -35,7 +35,7 @@ renderer = { nameForClass , unionName , unionPredicate - , nextName: ("Other" <> _) + , nextName: \s -> "Other" <> s , forbiddenNames } } diff --git a/src/Golang.purs b/src/Golang.purs index 5dc0b799..ac232a67 100644 --- a/src/Golang.purs +++ b/src/Golang.purs @@ -29,7 +29,7 @@ renderer = { nameForClass , unionName , unionPredicate - , nextName: ("Other" <> _) + , nextName: \s -> "Other" <> s , forbiddenNames: [] } } From d1e73a434f6d3708520c8893fc03269565c5b11d Mon Sep 17 00:00:00 2001 From: David Siegel Date: Tue, 25 Jul 2017 20:27:37 -0700 Subject: [PATCH 12/12] Tidy Original commit 95d618e1b05af4b8b8feb3bb11a9f04e7dc05192 --- src/CSharp.purs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/CSharp.purs b/src/CSharp.purs index 72c8bb2f..c6816554 100644 --- a/src/CSharp.purs +++ b/src/CSharp.purs @@ -10,9 +10,8 @@ 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 @@ -47,8 +46,7 @@ unionPredicate = case _ of in case nullableFromSet s of Nothing -> Just s _ -> Nothing - _ -> Nothing - + _ -> Nothing nameForClass :: IRClassData -> String nameForClass (IRClassData { names }) = csNameStyle $ combineNames names