1+ {-# LANGUAGE BlockArguments #-}
12{-# LANGUAGE GADTs #-}
3+ {-# LANGUAGE OverloadedLabels #-}
24{-# LANGUAGE OverloadedRecordDot #-}
35
46module Primer.Action (
@@ -17,6 +19,7 @@ module Primer.Action (
1719 uniquifyDefName ,
1820 toProgActionInput ,
1921 toProgActionNoInput ,
22+ applyActionsToField ,
2023) where
2124
2225import Foreword hiding (mod )
@@ -27,10 +30,11 @@ import Data.Bifunctor.Swap qualified as Swap
2730import Data.Generics.Product (typed )
2831import Data.List (findIndex )
2932import Data.List.NonEmpty qualified as NE
33+ import Data.Map (insert )
3034import Data.Map.Strict qualified as Map
3135import Data.Set qualified as Set
3236import Data.Text qualified as T
33- import Optics (set , (%) , (?~) , (^.) , (^?) , _Just )
37+ import Optics (over , set , (%) , (?~) , (^.) , (^?) , _Just )
3438import Primer.Action.Actions (Action (.. ), Movement (.. ), QualifiedText )
3539import Primer.Action.Available qualified as Available
3640import Primer.Action.Errors (ActionError (.. ))
@@ -40,6 +44,7 @@ import Primer.App.Base (
4044 NodeSelection (.. ),
4145 NodeType (.. ),
4246 Selection' (.. ),
47+ TypeDefConsFieldSelection (.. ),
4348 TypeDefConsSelection (.. ),
4449 TypeDefNodeSelection (.. ),
4550 TypeDefSelection (.. ),
@@ -60,6 +65,7 @@ import Primer.Core (
6065 Type' (.. ),
6166 TypeCache (.. ),
6267 TypeCacheBoth (.. ),
68+ TypeMeta ,
6369 ValConName ,
6470 baseName ,
6571 bindName ,
@@ -102,7 +108,7 @@ import Primer.Def (
102108 Def (.. ),
103109 DefMap ,
104110 )
105- import Primer.Module (Module , insertDef )
111+ import Primer.Module (Module ( moduleTypes ) , insertDef )
106112import Primer.Name (Name , NameCounter , unName , unsafeMkName )
107113import Primer.Name.Fresh (
108114 isFresh ,
@@ -238,6 +244,49 @@ applyActionsToTypeSig smartHoles imports (mod, mods) (defName, def) actions =
238244 -- In this case we just refocus on the top of the type.
239245 z -> maybe unwrapError pure (focusType (unfocusLoc z))
240246
247+ applyActionsToField ::
248+ (MonadFresh ID m , MonadFresh NameCounter m ) =>
249+ SmartHoles ->
250+ [Module ] ->
251+ (Module , [Module ]) ->
252+ (Name , ValConName , Int , ASTTypeDef TypeMeta ) ->
253+ [Action ] ->
254+ m (Either ActionError ([Module ], TypeZ ))
255+ applyActionsToField smartHoles imports (mod , mods) (tyName, conName', index, tyDef) actions =
256+ runReaderT
257+ go
258+ (buildTypingContextFromModules (mod : mods <> imports) smartHoles)
259+ & runExceptT
260+ where
261+ go :: ActionM m => m ([Module ], TypeZ )
262+ go = do
263+ (valCons, zt) <-
264+ (maybe (throwError $ InternalFailure " applyActionsToField: con name not found" ) pure =<< ) $
265+ flip (findAndAdjustA' ((== conName') . valConName)) (astTypeDefConstructors tyDef) \ (ValCon _ ts) -> do
266+ (t, zt) <-
267+ maybe (throwError $ InternalFailure " applyActionsToField: con field index out of bounds" ) pure
268+ =<< flip (adjustAtA' index) ts \ fieldType -> do
269+ zt <- withWrappedType fieldType \ zt ->
270+ foldlM (\ l -> local addParamsToCxt . flip applyActionAndSynth l) (InType zt) actions
271+ pure (target (top zt), zt)
272+ pure (ValCon conName' t, zt)
273+ let mod' = mod {moduleTypes = insert tyName (TypeDefAST tyDef{astTypeDefConstructors = valCons}) $ moduleTypes mod }
274+ (,zt) <$> checkEverything smartHoles (CheckEverything {trusted = imports, toCheck = mod' : mods})
275+ addParamsToCxt :: TC. Cxt -> TC. Cxt
276+ addParamsToCxt = over # localCxt (<> Map. fromList (map (bimap unLocalName TC. K ) $ astTypeDefParameters tyDef))
277+ withWrappedType :: ActionM m => Type -> (TypeZ -> m Loc ) -> m TypeZ
278+ withWrappedType ty f = do
279+ wrappedType <- ann emptyHole (pure ty)
280+ let unwrapError = throwError $ InternalFailure " applyActionsToField: failed to unwrap type"
281+ wrapError = throwError $ InternalFailure " applyActionsToField: failed to wrap type"
282+ focusedType = focusType $ focus wrappedType
283+ case focusedType of
284+ Nothing -> wrapError
285+ Just wrappedTy ->
286+ f wrappedTy >>= \ case
287+ InType zt -> pure zt
288+ z -> maybe unwrapError pure (focusType (unfocusLoc z))
289+
241290data Refocus = Refocus
242291 { pre :: Loc
243292 , post :: Expr
@@ -866,7 +915,7 @@ renameForall b zt = case target zt of
866915-- | Convert a high-level 'Available.NoInputAction' to a concrete sequence of 'ProgAction's.
867916toProgActionNoInput ::
868917 DefMap ->
869- Either (ASTTypeDef () ) ASTDef ->
918+ Either (ASTTypeDef a ) ASTDef ->
870919 Selection' ID ->
871920 Available. NoInputAction ->
872921 Either ActionError [ProgAction ]
@@ -958,15 +1007,21 @@ toProgActionNoInput defs def0 sel0 = \case
9581007 typeNodeSel >>= \ case
9591008 (s0, TypeDefConsNodeSelection s) -> pure (s0, s)
9601009 _ -> Left NeedTypeDefConsSelection
1010+ conFieldSel = do
1011+ (ty, s) <- conSel
1012+ maybe (Left NeedTypeDefConsFieldSelection ) (pure . (ty,s. con,)) s. field
9611013 toProgAction actions = do
962- sel <- termSel
963- toProg' actions sel. def <$> maybeToEither NoNodeSelection sel. node
1014+ case sel0 of
1015+ SelectionDef sel -> toProg' actions sel. def <$> maybeToEither NoNodeSelection sel. node
1016+ SelectionTypeDef _ -> do
1017+ (t, c, f) <- conFieldSel
1018+ pure [ConFieldAction t c f. index $ SetCursor f. meta : actions]
9641019 termDef = first (const NeedTermDef ) def0
9651020
9661021-- | Convert a high-level 'Available.InputAction', and associated 'Available.Option',
9671022-- to a concrete sequence of 'ProgAction's.
9681023toProgActionInput ::
969- Either (ASTTypeDef () ) ASTDef ->
1024+ Either (ASTTypeDef a ) ASTDef ->
9701025 Selection' ID ->
9711026 Available. Option ->
9721027 Available. InputAction ->
@@ -1079,9 +1134,15 @@ toProgActionInput def0 sel0 opt0 = \case
10791134 optGlobal = case opt0. context of
10801135 Nothing -> Left $ NeedLocal opt0
10811136 Just q -> pure (q, opt0. option)
1137+ conFieldSel = do
1138+ (ty, s) <- conSel
1139+ maybe (Left NeedTypeDefConsFieldSelection ) (pure . (ty,s. con,)) s. field
10821140 toProg actions = do
1083- sel <- termSel
1084- toProg' actions sel. def <$> maybeToEither NoNodeSelection sel. node
1141+ case sel0 of
1142+ SelectionDef sel -> toProg' actions sel. def <$> maybeToEither NoNodeSelection sel. node
1143+ SelectionTypeDef _ -> do
1144+ (t, c, f) <- conFieldSel
1145+ pure [ConFieldAction t c f. index $ SetCursor f. meta : actions]
10851146 offerRefined = do
10861147 id <- nodeID
10871148 def <- termDef
0 commit comments