Update codegen branch and add more code for generating update function.

This commit is contained in:
Dillon Kearns 2022-09-21 09:11:36 -07:00
parent 3672ad15c9
commit 3708ec261d
4 changed files with 298 additions and 36 deletions

View File

@ -18,6 +18,7 @@ topLevelValue name expression =
{ declaration : Elm.Declaration
, call : List Elm.Expression -> Elm.Expression
, callFrom : List String -> List Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
declaration_ =
Elm.Declare.function name

View File

@ -64,15 +64,15 @@ file templates basePath =
templates
|> List.filterMap RoutePattern.fromModuleName
segmentsToRouteFn : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
segmentsToRouteFn : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
segmentsToRouteFn =
segmentsToRoute routes
routeToPathFn : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
routeToPathFn : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
routeToPathFn =
routeToPath routes
toPath : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
toPath : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
toPath =
Elm.Declare.fn "toPath"
( "route", Elm.Annotation.named [] "Route" |> Just )
@ -136,7 +136,7 @@ file templates basePath =
)
)
toString : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
toString : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
toString =
Elm.Declare.fn "toString"
( "route", Elm.Annotation.named [] "Route" |> Just )
@ -159,7 +159,7 @@ file templates basePath =
)
)
toLink : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression -> Elm.Expression }
toLink : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
toLink =
Elm.Declare.fn2 "toLink"
( "toAnchorTag", Nothing )
@ -223,7 +223,7 @@ file templates basePath =
)
splitPath : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
splitPath : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
splitPath =
Elm.Declare.fn "splitPath"
( "path", Just Gen.Path.annotation_.path )
@ -236,7 +236,7 @@ splitPath =
)
maybeToList : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
maybeToList : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
maybeToList =
Elm.Declare.fn "maybeToList"
( "maybeString", Just (Elm.Annotation.maybe Elm.Annotation.string) )
@ -251,7 +251,7 @@ maybeToList =
segmentsToRoute :
List RoutePattern
-> { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
-> { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
segmentsToRoute routes =
Elm.Declare.fn "segmentsToRoute"
( "segments"
@ -296,7 +296,9 @@ segmentsToRoute routes =
)
routeToPath : List RoutePattern -> { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression }
routeToPath :
List RoutePattern
-> { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression, value : List String -> Elm.Expression }
routeToPath routes =
Elm.Declare.fn "routeToPath"
( "route", Just (Elm.Annotation.named [] "Route") )

View File

@ -3,24 +3,19 @@ module GenerateMain exposing (..)
import Elm exposing (File)
import Elm.Annotation as Type
import Elm.Case
import Elm.CodeGen
import Elm.Declare
import Elm.Extra exposing (expose, fnIgnore, topLevelValue)
import Elm.Let
import Elm.Op
import Elm.Pretty
import Elm.Pattern
import Gen.ApiRoute
import Gen.Basics
import Gen.Browser.Navigation
import Gen.Bytes
import Gen.Bytes.Decode
import Gen.Bytes.Encode
import Gen.CodeGen.Generate exposing (Error)
import Gen.DataSource
import Gen.Dict
import Gen.Head
import Gen.Html
import Gen.Html.Attributes
import Gen.HtmlPrinter
import Gen.Json.Decode
import Gen.Json.Encode
@ -34,12 +29,9 @@ import Gen.Pages.Transition
import Gen.Path
import Gen.Platform.Sub
import Gen.Server.Response
import Gen.String
import Gen.Tuple
import Gen.Url
import Pages.Internal.RoutePattern as RoutePattern exposing (RoutePattern)
import Pretty
import Regex exposing (Regex)
type Phase
@ -66,7 +58,7 @@ otherFile routes phaseString =
}
config =
{ init = Elm.apply (Elm.val "init") [ Elm.nothing ]
, update = Elm.val "update"
, update = update.value []
, subscriptions = Elm.val "subscriptions"
, sharedData =
Elm.value { name = "template", importFrom = [ "Shared" ], annotation = Nothing }
@ -235,6 +227,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
subscriptions =
Elm.Declare.fn3 "subscriptions"
@ -264,6 +257,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
onActionData =
Elm.Declare.fn "onActionData"
@ -303,6 +297,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
templateSubscriptions =
Elm.Declare.fn3 "templateSubscriptions"
@ -354,6 +349,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
dataForRoute =
Elm.Declare.fn
@ -402,6 +398,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
action =
Elm.Declare.fn
@ -442,7 +439,12 @@ otherFile routes phaseString =
)
)
init : { declaration : Elm.Declaration, call : Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression, callFrom : List String -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression }
init :
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
init =
Elm.Declare.fn6 "init"
( "currentGlobalModel", Type.maybe (Type.named [ "Shared" ] "Model") |> Just )
@ -621,6 +623,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : List Elm.Expression -> Elm.Expression
, callFrom : List String -> List Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
update =
Elm.Declare.function "update"
@ -635,24 +638,170 @@ otherFile routes phaseString =
, ( "sharedData", Type.named [ "Shared" ] "Data" |> Just )
, ( "pageData", Type.named [] "PageData" |> Just )
, ( "navigationKey", Type.named [ "Browser", "Navigation" ] "Key" |> Type.maybe |> Just )
, ( "msg", Type.named [] "Msg" |> Type.maybe |> Just )
, ( "msg", Type.named [] "Msg" |> Just )
, ( "model", Type.named [] "Model" |> Just )
]
(\args ->
case args of
[ pageFormState, fetchers, transition, sharedData, pageData, navigationKey, msg, model ] ->
let
defaultValue =
--( model.page, Effect.none, ( model.global, Effect.none ) )
Elm.triple
(model |> Elm.get "page")
(Elm.value { annotation = Nothing, importFrom = [ "Effect" ], name = "none" })
(Elm.tuple
(model |> Elm.get "global")
(Elm.value { annotation = Nothing, importFrom = [ "Effect" ], name = "none" })
Elm.Case.custom msg
Type.unit
([ Elm.Pattern.variant1 "MsgErrorPage____" (Elm.Pattern.var "msg_")
|> Elm.Case.patternToBranch
(\msg_ ->
todo
)
in
todo
, Elm.Pattern.variant1 "MsgGlobal" (Elm.Pattern.var "msg_")
|> Elm.Case.patternToBranch
(\msg_ ->
todo
)
, Elm.Pattern.variant1 "OnPageChange" (Elm.Pattern.var "record")
|> Elm.Case.patternToBranch
(\record ->
todo
)
]
++ (routes
|> List.map
(\route ->
Elm.Pattern.variant1
("Msg"
++ (RoutePattern.toModuleName route |> String.join "__")
)
(Elm.Pattern.var "msg_")
|> Elm.Case.patternToBranch
(\msg_ ->
Elm.Case.custom
(Elm.triple
(model |> Elm.get "page")
pageData
(Gen.Maybe.call_.map3
(toTriple.value [])
(model
|> Elm.get "current"
|> Gen.Maybe.andThen
(Elm.get "metadata")
)
(model
|> Elm.get "current"
|> Gen.Maybe.andThen
(Elm.get "pageUrl")
)
(model
|> Elm.get "current"
|> Gen.Maybe.map
(Elm.get "path")
)
)
)
Type.unit
[ Elm.Pattern.triple
(Elm.Pattern.variant1
("Model"
++ (RoutePattern.toModuleName route |> String.join "__")
)
(Elm.Pattern.var "pageModel")
)
(Elm.Pattern.variant1
("Data"
++ (RoutePattern.toModuleName route |> String.join "__")
)
(Elm.Pattern.var "thisPageData")
)
(Elm.Pattern.variant1
"Just"
(Elm.Pattern.triple
(routeToSyntaxPattern route)
(Elm.Pattern.var "pageUrl")
(Elm.Pattern.var "justPage")
)
)
|> Elm.Case.patternToBranch
(\( pageModel, thisPageData, ( maybeRouteParams, pageUrl, justPage ) ) ->
Elm.Let.letIn
(\( updatedPageModel, pageCmd, ( newGlobalModel, newGlobalCmd ) ) ->
Elm.tuple
(model
|> Elm.updateRecord
[ ( "page", updatedPageModel )
, ( "global", newGlobalModel )
]
)
(Elm.apply
(Elm.value
{ name = "batch"
, importFrom = [ "Effect" ]
, annotation = Nothing
}
)
[ Elm.list
[ pageCmd
, Elm.apply
(Elm.value
{ name = "map"
, importFrom = [ "Effect" ]
, annotation = Nothing
}
)
[ Elm.val "MsgGlobal"
, newGlobalCmd
]
]
]
)
)
|> Elm.Let.destructure
(Elm.Pattern.triple
(Elm.Pattern.var "updatedPageModel")
(Elm.Pattern.var "pageCmd")
(Elm.Pattern.tuple (Elm.Pattern.var "newGlobalModel")
(Elm.Pattern.var "newGlobalCmd")
)
)
(fooFn.call
--todo
(Elm.val ("Model" ++ (RoutePattern.toModuleName route |> String.join "__")))
(Elm.val ("Msg" ++ (RoutePattern.toModuleName route |> String.join "__")))
model
(Elm.apply
(Elm.value
{ annotation = Nothing
, importFrom = "Route" :: RoutePattern.toModuleName route
, name = "route"
}
|> Elm.get "update"
)
[ pageUrl
, Elm.record
[ ( "data", thisPageData )
, ( "sharedData", sharedData )
, ( "action", Elm.nothing )
, ( "routeParams", maybeRouteParams |> Maybe.withDefault (Elm.record []) )
, ( "path", justPage |> Elm.get "path" )
, ( "submit", todo )
, ( "transition", transition )
, ( "fetchers", todo )
, ( "pageFormState", pageFormState )
]
, msg_
, pageModel
, model |> Elm.get "global"
]
)
)
|> Elm.Let.toExpression
)
, Elm.Pattern.ignore
|> Elm.Case.patternToBranch
(\() ->
Elm.tuple model effectNone
)
]
)
)
)
)
|> Elm.withType
(Type.tuple
(Type.named [] "Model")
@ -663,10 +812,88 @@ otherFile routes phaseString =
todo
)
fooFn :
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
fooFn =
{-
fooFn :
(a -> PageModel)
-> (b -> Msg)
-> Model
-> ( a, Effect.Effect b, Maybe Shared.Msg )
-> ( PageModel, Effect.Effect Msg, ( Shared.Model, Effect.Effect Msg ) )
fooFn wrapModel wrapMsg model triple =
Debug.todo ""
-}
Elm.Declare.fn4 "fooFn"
( "wrapModel", Nothing )
( "wrapMsg", Nothing )
( "model", Type.named [] "Model" |> Just )
( "triple", Nothing )
(\wrapModel wrapMsg model triple ->
Elm.Case.custom triple
Type.unit
[ Elm.Pattern.triple
(Elm.Pattern.var "a")
(Elm.Pattern.var "b")
(Elm.Pattern.var "c")
|> Elm.Case.patternToBranch
(\( a, b, c ) ->
Elm.triple
(Elm.apply wrapModel [ a ])
(Elm.apply
(Elm.value { name = "map", importFrom = [ "Effect" ], annotation = Nothing })
[ wrapMsg, b ]
)
(Elm.Case.maybe c
{ nothing =
Elm.tuple
(model |> Elm.get "global")
effectNone
, just =
( "sharedMsg"
, \sharedMsg ->
Elm.apply
(Elm.value
{ importFrom = [ "Shared" ]
, name = "template"
, annotation = Nothing
}
|> Elm.get "update"
)
[ sharedMsg
, model |> Elm.get "global"
]
)
}
)
)
]
)
toTriple :
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
toTriple =
Elm.Declare.fn3 "toTriple"
( "a", Nothing )
( "b", Nothing )
( "c", Nothing )
(\a b c -> Elm.triple a b c)
initErrorPage :
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
initErrorPage =
Elm.Declare.fn "initErrorPage"
@ -695,6 +922,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
handleRoute =
Elm.Declare.fn "handleRoute"
@ -768,6 +996,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
encodeActionData =
Elm.Declare.fn "encodeActionData"
@ -800,6 +1029,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
byteEncodePageData =
Elm.Declare.fn "byteEncodePageData"
@ -848,6 +1078,7 @@ otherFile routes phaseString =
{ declaration : Elm.Declaration
, call : Elm.Expression -> Elm.Expression
, callFrom : List String -> Elm.Expression -> Elm.Expression
, value : List String -> Elm.Expression
}
byteDecodePageData =
Elm.Declare.fn "byteDecodePageData"
@ -1226,9 +1457,15 @@ otherFile routes phaseString =
, ( "current"
, Type.maybe
(Type.record
[ ( "path", Type.named [ "Path" ] "Path" )
, ( "query", Type.string |> Type.maybe )
, ( "fragment", Type.string |> Type.maybe )
[ ( "path"
, Type.record
[ ( "path", Type.named [ "Path" ] "Path" )
, ( "query", Type.string |> Type.maybe )
, ( "fragment", Type.string |> Type.maybe )
]
)
, ( "metadata", Type.maybe (Type.named [ "Route" ] "Route") )
, ( "pageUrl", Type.maybe (Type.named [ "Pages", "PageUrl" ] "PageUrl") )
]
)
)
@ -1327,7 +1564,9 @@ otherFile routes phaseString =
|> expose
, config.declaration
, dataForRoute.declaration
, toTriple.declaration
, action.declaration
, fooFn.declaration
, templateSubscriptions.declaration
, onActionData.declaration
, byteEncodePageData.declaration
@ -1363,6 +1602,22 @@ otherFile routes phaseString =
]
routeToSyntaxPattern : RoutePattern -> Elm.Pattern.Pattern (Maybe Elm.Expression)
routeToSyntaxPattern route =
let
moduleName : String
moduleName =
"Route." ++ (RoutePattern.toModuleName route |> String.join "__")
in
if RoutePattern.hasRouteParams route then
Elm.Pattern.variant1 moduleName
(Elm.Pattern.var "routeParams" |> Elm.Pattern.map Just)
else
Elm.Pattern.variant0 moduleName
|> Elm.Pattern.map (\() -> Nothing)
applyIdentityTo : Elm.Expression -> Elm.Expression
applyIdentityTo to =
Elm.apply to [ Gen.Basics.values_.identity ]
@ -1409,3 +1664,7 @@ routePatternToSyntax route =
)
|> Elm.maybe
}
effectNone =
Elm.value { annotation = Nothing, importFrom = [ "Effect" ], name = "none" }

@ -1 +1 @@
Subproject commit a23c1cf4fd160968a1eee2e9d9ecea695dbf7478
Subproject commit 48e3e9ef2bce091c57ce3a08c9b687146ad0e8af