Skip to content

Commit

Permalink
Use Install.Rule for TypeVariant
Browse files Browse the repository at this point in the history
  • Loading branch information
jfmengels committed Jul 25, 2024
1 parent 2b4d64e commit 42fb4fe
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 82 deletions.
129 changes: 70 additions & 59 deletions preview/src/ReviewConfig.elm
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,13 @@ configAtmospheric =
|> Install.insertFieldInTypeAlias
, InitializerCmd.config "Backend" "init" [ "Time.now |> Task.perform GotFastTick", "MagicLink.Helper.getAtmosphericRandomNumbers" ]
|> Install.initializerCmd
]
, TypeVariant.makeRule "Types"
"BackendMsg"
[ "GotAtmosphericRandomNumbers (Result Http.Error String)"
, "SetLocalUuidStuff (List Int)"
, "GotFastTick Time.Posix"
, TypeVariant.config "Types"
"BackendMsg"
[ "GotAtmosphericRandomNumbers (Result Http.Error String)"
, "SetLocalUuidStuff (List Int)"
, "GotFastTick Time.Posix"
]
|> Install.addTypeVariant
]
]

Expand Down Expand Up @@ -131,18 +132,22 @@ configMagicLinkMinimal =
|> Install.insertFieldInTypeAlias
, Initializer.config "Frontend" "initLoaded" [ { field = "magicLinkModel", value = "Pages.SignIn.init loadingModel.initUrl" } ]
|> Install.initializer
]
, TypeVariant.makeRule "Types" "FrontendMsg" [ "AuthFrontendMsg MagicLink.Types.Msg" ]
, TypeVariant.makeRule "Types" "BackendMsg" [ "AuthBackendMsg Auth.Common.BackendMsg" ]
, TypeVariant.makeRule "Types" "ToBackend" [ "AuthToBackend Auth.Common.ToBackend" ]
, TypeVariant.makeRule "Types"
"ToFrontend"
[ "AuthToFrontend Auth.Common.ToFrontend"
, "AuthSuccess Auth.Common.UserInfo"
, "UserInfoMsg (Maybe Auth.Common.UserInfo)"
, "GetLoginTokenRateLimited"
, "RegistrationError String"
, "SignInError String"
, TypeVariant.config "Types" "FrontendMsg" [ "AuthFrontendMsg MagicLink.Types.Msg" ]
|> Install.addTypeVariant
, TypeVariant.config "Types" "BackendMsg" [ "AuthBackendMsg Auth.Common.BackendMsg" ]
|> Install.addTypeVariant
, TypeVariant.config "Types" "ToBackend" [ "AuthToBackend Auth.Common.ToBackend" ]
|> Install.addTypeVariant
, TypeVariant.config "Types"
"ToFrontend"
[ "AuthToFrontend Auth.Common.ToFrontend"
, "AuthSuccess Auth.Common.UserInfo"
, "UserInfoMsg (Maybe Auth.Common.UserInfo)"
, "GetLoginTokenRateLimited"
, "RegistrationError String"
, "SignInError String"
]
|> Install.addTypeVariant
]
]

Expand All @@ -167,26 +172,29 @@ configAuthTypes =
|> Install.insertFieldInTypeAlias
, FieldInTypeAlias.config "Types" "LoadedModel" [ "magicLinkModel : MagicLink.Types.Model" ]
|> Install.insertFieldInTypeAlias
]
, TypeVariant.makeRule "Types"
"FrontendMsg"
[ "SignInUser User.SignInData"
, "AuthFrontendMsg MagicLink.Types.Msg"
, "SetRoute_ Route"
, "LiftMsg MagicLink.Types.Msg"
]
, TypeVariant.makeRule "Types"
"BackendMsg"
[ "AuthBackendMsg Auth.Common.BackendMsg"
, "AutoLogin SessionId User.SignInData"
, "OnConnected SessionId ClientId"
]
, TypeVariant.makeRule "Types"
"ToBackend"
[ "AuthToBackend Auth.Common.ToBackend"
, "AddUser String String String"
, "RequestSignUp String String String"
, "GetUserDictionary"
, TypeVariant.config "Types"
"FrontendMsg"
[ "SignInUser User.SignInData"
, "AuthFrontendMsg MagicLink.Types.Msg"
, "SetRoute_ Route"
, "LiftMsg MagicLink.Types.Msg"
]
|> Install.addTypeVariant
, TypeVariant.config "Types"
"BackendMsg"
[ "AuthBackendMsg Auth.Common.BackendMsg"
, "AutoLogin SessionId User.SignInData"
, "OnConnected SessionId ClientId"
]
|> Install.addTypeVariant
, TypeVariant.config "Types"
"ToBackend"
[ "AuthToBackend Auth.Common.ToBackend"
, "AddUser String String String"
, "RequestSignUp String String String"
, "GetUserDictionary"
]
|> Install.addTypeVariant
]
]

Expand Down Expand Up @@ -222,20 +230,21 @@ configAuthFrontend =
|> Install.initializer
, Install.Type.config "Types" "BackendDataStatus" [ "Sunny", "LoadedBackendData", "Spell String Int" ]
|> Install.addType
]
, TypeVariant.makeRule "Types"
"ToFrontend"
[ "AuthToFrontend Auth.Common.ToFrontend"
, "AuthSuccess Auth.Common.UserInfo"
, "UserInfoMsg (Maybe Auth.Common.UserInfo)"
, "CheckSignInResponse (Result BackendDataStatus User.SignInData)"
, "GetLoginTokenRateLimited"
, "RegistrationError String"
, "SignInError String"
, "UserSignedIn (Maybe User.User)"
, "UserRegistered User.User"
, "GotUserDictionary (Dict.Dict User.EmailString User.User)"
, "GotMessage String"
, TypeVariant.config "Types"
"ToFrontend"
[ "AuthToFrontend Auth.Common.ToFrontend"
, "AuthSuccess Auth.Common.UserInfo"
, "UserInfoMsg (Maybe Auth.Common.UserInfo)"
, "CheckSignInResponse (Result BackendDataStatus User.SignInData)"
, "GetLoginTokenRateLimited"
, "RegistrationError String"
, "SignInError String"
, "UserSignedIn (Maybe User.User)"
, "UserRegistered User.User"
, "GotUserDictionary (Dict.Dict User.EmailString User.User)"
, "GotMessage String"
]
|> Install.addTypeVariant
]
]

Expand Down Expand Up @@ -294,10 +303,11 @@ configAuthBackend adminConfig =

configRoute : List Rule
configRoute =
[ -- ROUTE
TypeVariant.makeRule "Route" "Route" [ "NotesRoute", "SignInRoute", "AdminRoute" ]
, Install.rule "REPLACEME"
[ ElementToList.add
[ Install.rule "REPLACEME"
[ -- ROUTE
TypeVariant.config "Route" "Route" [ "NotesRoute", "SignInRoute", "AdminRoute" ]
|> Install.addTypeVariant
, ElementToList.add
"Route"
"routesAndNames"
[ "(NotesRoute, \"notes\")", "(SignInRoute, \"signin\")", "(AdminRoute, \"admin\")" ]
Expand All @@ -317,9 +327,10 @@ addPages pageData =

addPage : ( String, String ) -> List Rule
addPage ( pageTitle, routeName ) =
[ TypeVariant.makeRule "Route" "Route" [ pageTitle ++ "Route" ]
, Install.rule "REPLACEME"
[ ClauseInCase.config "View.Main" "loadedView" (pageTitle ++ "Route") ("generic model Pages." ++ pageTitle ++ ".view")
[ Install.rule "REPLACEME"
[ TypeVariant.config "Route" "Route" [ pageTitle ++ "Route" ]
|> Install.addTypeVariant
, ClauseInCase.config "View.Main" "loadedView" (pageTitle ++ "Route") ("generic model Pages." ++ pageTitle ++ ".view")
|> Install.insertClauseInCase
, Import.qualified "View.Main" [ "Pages." ++ pageTitle ]
|> Install.addImport
Expand Down
26 changes: 24 additions & 2 deletions src/Install.elm
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
module Install exposing
( rule
, Installation
, addImport, addElementToList, insertFunction, replaceFunction, insertClauseInCase, insertFieldInTypeAlias, initializer, initializerCmd, subscription, addType
, addImport, addElementToList, insertFunction, replaceFunction, insertClauseInCase, insertFieldInTypeAlias, initializer, initializerCmd, subscription, addType, addTypeVariant
)

{-| TODO REPLACEME
@docs rule
@docs Installation
@docs addImport, addElementToList, insertFunction, replaceFunction, insertClauseInCase, insertFieldInTypeAlias, initializer, initializerCmd, subscription, addType
@docs addImport, addElementToList, insertFunction, replaceFunction, insertClauseInCase, insertFieldInTypeAlias, initializer, initializerCmd, subscription, addType, addTypeVariant
-}

Expand All @@ -35,8 +35,10 @@ import Install.Internal.InsertFunction
import Install.Internal.ReplaceFunction
import Install.Internal.Subscription
import Install.Internal.Type
import Install.Internal.TypeVariant
import Install.Subscription
import Install.Type
import Install.TypeVariant
import Review.Rule as Rule exposing (Error, Rule)


Expand All @@ -51,6 +53,7 @@ type alias Context =
, initializerCmd : List Install.InitializerCmd.Config
, subscription : List Install.Subscription.Config
, addType : List ( Install.Type.Config, Install.Internal.Type.Context )
, addTypeVariant : List Install.TypeVariant.Config
}


Expand All @@ -67,6 +70,7 @@ type Installation
| InitializerCmd Install.InitializerCmd.Config
| Subscription Install.Subscription.Config
| AddType Install.Type.Config
| AddTypeVariant Install.TypeVariant.Config


{-| Add an import, defined by [`Install.Import.config`](Install-Import#config).
Expand Down Expand Up @@ -139,6 +143,13 @@ addType =
AddType


{-| Add a type variant, defined by [`Install.TypeVariant.config`](Install-TypeVariant#config).
-}
addTypeVariant : Install.TypeVariant.Config -> Installation
addTypeVariant =
AddTypeVariant


{-| Create a rule from a list of transformations.
-}
rule : String -> List Installation -> Rule
Expand Down Expand Up @@ -228,6 +239,13 @@ initContext installations =

else
context

AddTypeVariant ((Install.Internal.TypeVariant.Config { hostModuleName }) as config) ->
if moduleName == hostModuleName then
{ context | addTypeVariant = config :: context.addTypeVariant }

else
context
)
{ importContexts = []
, elementToList = []
Expand All @@ -239,6 +257,7 @@ initContext installations =
, initializerCmd = []
, subscription = []
, addType = []
, addTypeVariant = []
}
installations
)
Expand Down Expand Up @@ -300,6 +319,9 @@ declarationVisitor node context =
, List.concatMap
(\config -> Install.Internal.Subscription.declarationVisitor config node)
context.subscription
, List.concatMap
(\config -> Install.Internal.TypeVariant.declarationVisitor config node)
context.addTypeVariant
]
in
( errors
Expand Down
89 changes: 89 additions & 0 deletions src/Install/Internal/TypeVariant.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
module Install.Internal.TypeVariant exposing
( Config(..)
, declarationVisitor
)

import Elm.Syntax.Declaration as Declaration exposing (Declaration)
import Elm.Syntax.ModuleName exposing (ModuleName)
import Elm.Syntax.Node as Node exposing (Node)
import Elm.Syntax.Range exposing (Range)
import Review.Fix as Fix exposing (Fix)
import Review.Rule as Rule exposing (Error, Rule)
import Set exposing (Set)
import Set.Extra


type Config
= Config
{ hostModuleName : ModuleName
, typeName : String
, variants : List String
}


declarationVisitor : Config -> Node Declaration -> List (Error {})
declarationVisitor (Config config) node =
case Node.value node of
Declaration.CustomTypeDeclaration type_ ->
let
variantName : String -> Maybe String
variantName variantString =
variantString |> String.split " " |> List.head |> Maybe.map String.trim

variantCodeItem variantString =
"\n | " ++ variantString

variantNames =
List.filterMap variantName config.variants

shouldFix : Node Declaration -> Bool
shouldFix node_ =
let
variantsOfNode : Set String
variantsOfNode =
case Node.value node_ of
Declaration.CustomTypeDeclaration type__ ->
type__.constructors
|> List.map (Node.value >> .name >> Node.value)
|> Set.fromList

_ ->
Set.empty
in
not <| Set.Extra.isSubsetOf variantsOfNode (Set.fromList variantNames)
in
if Node.value type_.name == config.typeName && shouldFix node then
let
variantCode =
List.map variantCodeItem config.variants |> String.concat
in
[ errorWithFix config.typeName variantNames variantCode node (Just <| Node.range node) ]

else
[]

_ ->
[]


errorWithFix : String -> List String -> String -> Node a -> Maybe Range -> Error {}
errorWithFix typeName_ variantNames variantCode node errorRange =
Rule.errorWithFix
{ message = "Add variants [" ++ String.join ", " variantNames ++ "] to " ++ typeName_
, details =
[ ""
]
}
(Node.range node)
(case errorRange of
Just range ->
[ fixMissingVariant range.end variantCode ]

Nothing ->
[]
)


fixMissingVariant : { row : Int, column : Int } -> String -> Fix
fixMissingVariant { row, column } variantCode =
Fix.insertAt { row = row, column = column } variantCode
Loading

0 comments on commit 42fb4fe

Please sign in to comment.