1
+ {-# LANGUAGE BlockArguments #-}
1
2
{-# LANGUAGE OverloadedLabels #-}
2
3
{-# LANGUAGE OverloadedRecordDot #-}
3
4
@@ -13,6 +14,8 @@ import Data.Text qualified as T
13
14
import Data.Text.Lazy qualified as TL
14
15
import GHC.Err (error )
15
16
import Hedgehog (
17
+ GenT ,
18
+ LabelName ,
16
19
PropertyT ,
17
20
annotate ,
18
21
annotateShow ,
@@ -46,17 +49,22 @@ import Primer.App (
46
49
NodeType (.. ),
47
50
ProgError (ActionError , DefAlreadyExists ),
48
51
Selection' (.. ),
52
+ TypeDefConsSelection (TypeDefConsSelection ),
53
+ TypeDefNodeSelection (TypeDefConsNodeSelection , TypeDefParamNodeSelection ),
54
+ TypeDefSelection (TypeDefSelection ),
49
55
appProg ,
50
56
checkAppWellFormed ,
51
57
handleEditRequest ,
52
58
progAllDefs ,
53
59
progAllTypeDefs ,
60
+ progAllTypeDefsMeta ,
54
61
progCxt ,
55
62
progImports ,
56
63
progModules ,
57
64
progSmartHoles ,
58
65
runEditAppM ,
59
66
)
67
+ import Primer.App.Base (TypeDefConsFieldSelection (.. ))
60
68
import Primer.Builtins (builtinModuleName , cCons , tList , tNat )
61
69
import Primer.Core (
62
70
Expr ,
@@ -112,6 +120,7 @@ import Primer.Module (
112
120
import Primer.Name (Name (unName ))
113
121
import Primer.Test.TestM (evalTestM )
114
122
import Primer.Test.Util (clearMeta , testNoSevereLogs )
123
+ import Primer.TypeDef (ASTTypeDef (astTypeDefConstructors ), TypeDef (TypeDefAST , TypeDefPrim ), ValCon (.. ), astTypeDefParameters , typeDefAST )
115
124
import Primer.Typecheck (
116
125
CheckEverythingRequest (CheckEverything , toCheck , trusted ),
117
126
SmartHoles (NoSmartHoles , SmartHoles ),
@@ -242,27 +251,95 @@ tasty_available_actions_accepted = withTests 500 $
242
251
-- We only test SmartHoles mode (which is the only supported user-facing
243
252
-- mode - NoSmartHoles is only used for internal sanity testing etc)
244
253
a <- forAllT $ genApp SmartHoles cxt
254
+ let allTypes = progAllTypeDefsMeta $ appProg a
245
255
let allDefs = progAllDefs $ appProg a
246
256
let isMutable = \ case
247
257
Editable -> True
248
258
NonEditable -> False
249
- (defName, (defMut, def)) <-
250
- maybe discard ( \ (t, x) -> label t >> pure x)
251
- =<< forAllT
252
- ( case partition (isMutable . fst . snd ) $ Map. toList allDefs of
259
+ let genDef :: Map name ( Editable , def ) -> GenT WT ( Maybe ( LabelName , ( Editable , ( name , def ))))
260
+ genDef m =
261
+ second ( \ (n, (e, t)) -> (e, (n, t)))
262
+ <<$>> case partition (isMutable . fst . snd ) $ Map. toList m of
253
263
([] , [] ) -> pure Nothing
254
264
(mut, [] ) -> Just . (" all mut" ,) <$> Gen. element mut
255
265
([] , immut) -> Just . (" all immut" ,) <$> Gen. element immut
256
266
(mut, immut) -> Just . (" mixed mut/immut" ,) <$> Gen. frequency [(9 , Gen. element mut), (1 , Gen. element immut)]
267
+ (defMut, typeOrTermDef) <-
268
+ maybe discard (\ (t, x) -> label t >> pure x)
269
+ =<< forAllT
270
+ ( Gen. choice
271
+ [ second (second Left ) <<$>> genDef allTypes
272
+ , second (second Right ) <<$>> genDef allDefs
273
+ ]
257
274
)
258
275
collect defMut
259
- case def of
260
- DefAST {} -> label " AST"
261
- DefPrim {} -> label " Prim"
262
- (loc, acts) <-
263
- fmap (first (SelectionDef . DefSelection defName) . snd ) . forAllWithT fst $
264
- Gen. frequency $
265
- catMaybes
276
+ case typeOrTermDef of
277
+ Left (_, t) ->
278
+ label " type" >> case t of
279
+ TypeDefPrim {} -> label " Prim"
280
+ TypeDefAST {} -> label " AST"
281
+ Right (_, t) ->
282
+ label " term" >> case t of
283
+ DefPrim {} -> label " Prim"
284
+ DefAST {} -> label " AST"
285
+ (def, (loc, acts)) <- case typeOrTermDef of
286
+ Left (defName, def) ->
287
+ (,)
288
+ <$> maybe (annotate " primitive type def" >> failure) (pure . Left ) (typeDefAST def)
289
+ <*> (fmap snd . forAllWithT fst ) case typeDefAST def of
290
+ Nothing -> Gen. discard
291
+ Just def' ->
292
+ let typeDefSel = SelectionTypeDef . TypeDefSelection defName
293
+ forTypeDef = (" forTypeDef" , (typeDefSel Nothing , Available. forTypeDef l defMut))
294
+ in Gen. frequency
295
+ [ (1 , pure forTypeDef)
296
+ ,
297
+ ( 2
298
+ , case astTypeDefParameters def' of
299
+ [] -> pure forTypeDef
300
+ ps -> do
301
+ (p, _) <- Gen. element ps
302
+ pure
303
+ ( " forTypeDefParamNode"
304
+ ,
305
+ ( typeDefSel $ Just $ TypeDefParamNodeSelection p
306
+ , Available. forTypeDefParamNode l defMut
307
+ )
308
+ )
309
+ )
310
+ ,
311
+ ( 5
312
+ , case astTypeDefConstructors def' of
313
+ [] -> pure forTypeDef
314
+ cs -> do
315
+ ValCon {valConName, valConArgs} <- Gen. element cs
316
+ let typeDefConsNodeSel = typeDefSel . Just . TypeDefConsNodeSelection . TypeDefConsSelection valConName
317
+ forTypeDefConsNode = (" forTypeDefConsNode" , (typeDefConsNodeSel Nothing , Available. forTypeDefConsNode l defMut))
318
+ case valConArgs of
319
+ [] -> pure forTypeDefConsNode
320
+ as ->
321
+ Gen. frequency
322
+ [ (1 , pure forTypeDefConsNode)
323
+ ,
324
+ ( 5
325
+ , do
326
+ (n, t) <- Gen. element $ zip [0 .. ] as
327
+ i <- Gen. element $ t ^.. typeIDs
328
+ pure
329
+ ( " forTypeDefConsFieldNode"
330
+ ,
331
+ ( typeDefConsNodeSel . Just $ TypeDefConsFieldSelection n i
332
+ , Available. forTypeDefConsFieldNode l defMut def' valConName n i
333
+ )
334
+ )
335
+ )
336
+ ]
337
+ )
338
+ ]
339
+ Right (defName, def) ->
340
+ (,)
341
+ <$> maybe (annotate " primitive def" >> failure) (pure . Right ) (defAST def)
342
+ <*> (fmap (first (SelectionDef . DefSelection defName) . snd ) . forAllWithT fst . Gen. frequency . catMaybes)
266
343
[ Just (1 , pure (" forDef" , (Nothing , Available. forDef (snd <$> allDefs) l defMut defName)))
267
344
, defAST def <&> \ d' -> (2 ,) $ do
268
345
let ty = astDefType d'
@@ -284,21 +361,19 @@ tasty_available_actions_accepted = withTests 500 $
284
361
collect action
285
362
case action of
286
363
Available. NoInput act' -> do
287
- def' <- maybe (annotate " primitive def" >> failure) pure $ defAST def
288
364
progActs <-
289
365
either (\ e -> annotateShow e >> failure) pure $
290
- toProgActionNoInput (map snd $ progAllDefs $ appProg a) ( Right def') loc act'
366
+ toProgActionNoInput (map snd $ progAllDefs $ appProg a) def loc act'
291
367
actionSucceeds (handleEditRequest progActs) a
292
368
Available. Input act' -> do
293
- def' <- maybe (annotate " primitive def" >> failure) pure $ defAST def
294
369
Available. Options {Available. opts, Available. free} <-
295
370
maybe (annotate " id not found" >> failure) pure $
296
371
Available. options
297
372
(map snd $ progAllTypeDefs $ appProg a)
298
373
(map snd $ progAllDefs $ appProg a)
299
374
(progCxt $ appProg a)
300
375
l
301
- ( Right def')
376
+ def
302
377
loc
303
378
act'
304
379
let opts' = [Gen. element $ (Offered ,) <$> opts | not (null opts)]
@@ -312,7 +387,7 @@ tasty_available_actions_accepted = withTests 500 $
312
387
[] -> annotate " no options" >> success
313
388
options -> do
314
389
opt <- forAllT $ Gen. choice options
315
- progActs <- either (\ e -> annotateShow e >> failure) pure $ toProgActionInput ( Right def') loc (snd opt) act'
390
+ progActs <- either (\ e -> annotateShow e >> failure) pure $ toProgActionInput def loc (snd opt) act'
316
391
actionSucceedsOrCapture (fst opt) (handleEditRequest progActs) a
317
392
where
318
393
runEditAppMLogs ::
0 commit comments