Skip to content

Commit 8a1cfe6

Browse files
committed
Implemented Gen for ForeignTyRefs
1 parent a136f38 commit 8a1cfe6

File tree

1 file changed

+56
-29
lines changed
  • lambda-buffers-compiler/test/Test/LambdaBuffers/Compiler

1 file changed

+56
-29
lines changed

lambda-buffers-compiler/test/Test/LambdaBuffers/Compiler/Gen.hs

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ module Test.LambdaBuffers.Compiler.Gen (genCompilerInput) where
22

33
import Control.Lens ((&), (.~), (^.))
44
import Control.Monad (foldM)
5+
import Data.Either (isRight)
56
import Data.Foldable (Foldable (toList))
6-
import Data.List qualified as List
77
import Data.List.NonEmpty (NonEmpty ((:|)))
88
import Data.Map (Map)
99
import Data.Map qualified as Map
@@ -20,14 +20,14 @@ import Data.Text qualified as Text
2020
import Data.Traversable (for)
2121
import GHC.Enum qualified as Int
2222
import Proto.Compiler (ClassName, CompilerInput, ConstrName, Kind, Kind'KindRef (Kind'KIND_REF_TYPE), Module, ModuleName, ModuleNamePart, SourceInfo, Sum, Sum'Constructor, Ty, TyAbs, TyArg, TyBody, TyDef, TyName, VarName)
23-
import Proto.Compiler_Fields (argKind, argName, column, constrName, constructors, fields, file, kindArrow, kindRef, left, localTyRef, moduleName, modules, name, ntuple, parts, posFrom, posTo, right, row, sourceInfo, tyAbs, tyApp, tyArgs, tyBody, tyFunc, tyName, tyRef, tyVar, typeDefs, varName)
23+
import Proto.Compiler_Fields (argKind, argName, column, constrName, constructors, fields, file, foreignTyRef, kindArrow, kindRef, left, localTyRef, moduleName, modules, name, ntuple, parts, posFrom, posTo, right, row, sourceInfo, tyAbs, tyApp, tyArgs, tyBody, tyFunc, tyName, tyRef, tyVar, typeDefs, varName)
2424
import Proto.Compiler_Fields qualified as P
2525
import Test.QuickCheck qualified as QC (arbitraryPrintableChar)
2626
import Test.QuickCheck.Gen qualified as QC
2727

2828
-- | Upper bound on various generators
2929
limit :: Int
30-
limit = 10
30+
limit = 5
3131

3232
-- | Names
3333
genAlphaNum :: QC.Gen Char
@@ -88,27 +88,33 @@ genTyArg vn = do
8888
& argName .~ vn
8989
& argKind .~ starKind -- TODO(bladyjoker): Gen arbitrary kinds.
9090

91-
genSum :: Map TyName TyDef -> Set TyArg -> NESet ConstrName -> QC.Gen Sum
91+
genSum :: TyDefs -> Set TyArg -> NESet ConstrName -> QC.Gen Sum
9292
genSum tydefs args ctorNs = do
9393
let (ctorN :| ctorNs') = NESet.toList ctorNs
9494
ctorNs'' <- QC.sublistOf (toList ctorNs')
9595
ctors <- for (ctorN :| ctorNs'') (genConstructor tydefs args)
9696
return $ defMessage & constructors .~ toList ctors
9797

98-
genTy :: Kind -> Map TyName TyDef -> Set TyArg -> QC.Gen Ty
98+
genTy :: Kind -> TyDefs -> Set TyArg -> QC.Gen Ty
9999
genTy kind tydefs tyargs =
100100
QC.oneof $
101101
NESet.withNonEmpty [] (genTyVar kind) tyargs
102-
<> NEMap.withNonEmpty [] (genTyRef kind) tydefs
102+
<> genTyRef kind tydefs
103103
<> genTyApp kind tydefs tyargs
104104

105-
genTyRef :: Kind -> NEMap TyName TyDef -> [QC.Gen Ty]
106-
genTyRef kind tydefs = case [tyd | tyd <- toList tydefs, kindOf (tyd ^. tyAbs) == kind] of
105+
genTyRef :: Kind -> TyDefs -> [QC.Gen Ty]
106+
genTyRef kind tydefs = case [tyd | tyd <- Map.toList tydefs, kindOf (snd tyd ^. tyAbs) == kind] of
107107
[] -> []
108108
tyds ->
109109
[ do
110110
tydef <- QC.elements tyds
111-
return $ defMessage & tyRef . localTyRef . tyName .~ (tydef ^. tyName)
111+
case fst tydef of
112+
Left (mn, tyn) ->
113+
return $
114+
defMessage
115+
& tyRef . foreignTyRef . moduleName .~ mn
116+
& tyRef . foreignTyRef . tyName .~ tyn
117+
Right tyn -> return $ defMessage & tyRef . localTyRef . tyName .~ tyn
112118
]
113119

114120
genTyVar :: Kind -> NESet TyArg -> [QC.Gen Ty]
@@ -120,7 +126,7 @@ genTyVar kind args = case [tyarg | tyarg <- toList args, tyarg ^. argKind == kin
120126
return $ defMessage & tyVar . varName .~ (tyarg ^. argName)
121127
]
122128

123-
genTyApp :: Kind -> Map TyName TyDef -> Set TyArg -> [QC.Gen Ty]
129+
genTyApp :: Kind -> TyDefs -> Set TyArg -> [QC.Gen Ty]
124130
genTyApp kind tydefs args =
125131
let kindFunc =
126132
defMessage
@@ -138,31 +144,31 @@ genTyApp kind tydefs args =
138144
& tyApp . tyArgs .~ [tyarg] -- TODO(bladyjoker): Generate list arguments
139145
]
140146

141-
genConstructor :: Map TyName TyDef -> Set TyArg -> ConstrName -> QC.Gen Sum'Constructor
147+
genConstructor :: TyDefs -> Set TyArg -> ConstrName -> QC.Gen Sum'Constructor
142148
genConstructor tydefs args cn = do
143149
tys <- QC.chooseInt (0, limit) >>= vecOf (genTy starKind tydefs args)
144150
return $
145151
defMessage
146152
& constrName .~ cn
147153
& P.product . ntuple . fields .~ tys
148154

149-
genTyBodySum :: Map TyName TyDef -> Set TyArg -> NESet ConstrName -> QC.Gen TyBody
155+
genTyBodySum :: TyDefs -> Set TyArg -> NESet ConstrName -> QC.Gen TyBody
150156
genTyBodySum tydefs args ctors = do
151157
b <- genSum tydefs args ctors
152158
return $ defMessage & P.sum .~ b
153159

154160
genTyBodyOpaque :: QC.Gen TyBody
155161
genTyBodyOpaque = return $ defMessage & P.opaque .~ defMessage
156162

157-
genTyBody :: Map TyName TyDef -> Set TyArg -> NESet ConstrName -> QC.Gen TyBody
163+
genTyBody :: TyDefs -> Set TyArg -> NESet ConstrName -> QC.Gen TyBody
158164
genTyBody tydefs args ctorNs =
159165
QC.oneof $
160166
[ genTyBodyOpaque
161167
]
162168
-- Gen TyBody'Sum only if there's some TyDefs and TyArgs available
163169
<> [genTyBodySum tydefs args ctorNs | not (tydefs == mempty && args == mempty)]
164170

165-
genTyAbs :: Map TyName TyDef -> NESet ConstrName -> QC.Gen TyAbs
171+
genTyAbs :: TyDefs -> NESet ConstrName -> QC.Gen TyAbs
166172
genTyAbs tydefs ctorNs = do
167173
vns <-
168174
if tydefs == mempty
@@ -175,37 +181,54 @@ genTyAbs tydefs ctorNs = do
175181
& tyArgs .~ toList args
176182
& tyBody .~ body
177183

178-
genTyDef :: Map TyName TyDef -> TyName -> NESet ConstrName -> QC.Gen TyDef
184+
type TyDefs = Map (Either (ModuleName, TyName) TyName) TyDef
185+
186+
genTyDef :: TyDefs -> TyName -> NESet ConstrName -> QC.Gen TyDef
179187
genTyDef tydefs tyn ctors = do
180188
tyabs <- genTyAbs tydefs ctors
181-
return $
189+
withSourceInfo $
182190
defMessage
183191
& tyName .~ tyn
184192
& tyAbs .~ tyabs
185193

186-
genModule :: ModuleName -> QC.Gen Module
187-
genModule mn = do
188-
tyNs <- QC.chooseInt (1, limit) >>= nesetOf genTyName
194+
genModule :: Map ModuleName Module -> ModuleName -> QC.Gen Module
195+
genModule availableMods mn = do
196+
tyNs <- QC.chooseInt (0, limit) >>= nesetOf genTyName
189197
ctorNs <- QC.chooseInt (length tyNs, length tyNs * limit) >>= nesetOf genConstrName
190198
tyNsWithCtorNs <- Map.map NESet.fromList <$> distribute (toList ctorNs) (NESet.toSet tyNs)
199+
let foreignTyDefs = collectTyDefs availableMods
191200
tydefs <-
192201
foldM
193-
( \availableTyDefs (tyN, ctorNs') -> do
194-
tydef <- genTyDef availableTyDefs tyN ctorNs'
195-
return $ Map.insert tyN tydef availableTyDefs
202+
( \allTyDefs (tyN, ctorNs') -> do
203+
tydef <- genTyDef allTyDefs tyN ctorNs'
204+
return $ Map.insert (Right tyN) tydef allTyDefs
196205
)
197-
mempty
206+
foreignTyDefs
198207
(Map.toList tyNsWithCtorNs)
199208
return $
200209
defMessage
201210
& moduleName .~ mn
202-
& typeDefs .~ toList tydefs
211+
& typeDefs .~ ([tydef | (n, tydef) <- Map.toList tydefs, isRight n])
212+
where
213+
collectTyDefs :: Map ModuleName Module -> TyDefs
214+
collectTyDefs mods =
215+
snd
216+
<$> indexBy
217+
(\(m, tydef) -> Left (m ^. moduleName, tydef ^. tyName))
218+
[(m, tydef) | m <- toList mods, tydef <- m ^. typeDefs]
203219

204220
genCompilerInput :: QC.Gen CompilerInput
205221
genCompilerInput = do
206-
mns <- QC.chooseInt (1, limit) >>= vecOf genModuleName
207-
ms <- for (List.nub mns) genModule
208-
return $ defMessage & modules .~ ms
222+
mns <- QC.chooseInt (0, limit) >>= setOf genModuleName
223+
ms <-
224+
foldM
225+
( \availableMods mn -> do
226+
m <- genModule availableMods mn
227+
return $ Map.insert mn m availableMods
228+
)
229+
mempty
230+
(toList mns)
231+
return $ defMessage & modules .~ toList ms
209232

210233
-- | Utils
211234

@@ -246,8 +269,12 @@ partition xs = go xs []
246269
_indexBy :: Ord k => (a -> k) -> NonEmpty a -> NEMap k a
247270
_indexBy keyF (x :| xs) = foldl (\t x' -> NEMap.insert (keyF x') x' t) (NEMap.singleton (keyF x) x) xs
248271

249-
_withSourceInfo :: HasField a "sourceInfo" SourceInfo => a -> QC.Gen a
250-
_withSourceInfo msg = do
272+
-- | Index a list given a key function.
273+
indexBy :: Foldable t => Ord k => (a -> k) -> t a -> Map k a
274+
indexBy keyF = foldl (\t x -> Map.insert (keyF x) x t) mempty
275+
276+
withSourceInfo :: HasField a "sourceInfo" SourceInfo => a -> QC.Gen a
277+
withSourceInfo msg = do
251278
f <- Text.pack <$> vecOf QC.arbitraryPrintableChar 10
252279
i <- QC.chooseInt (0, Int.maxBound)
253280
let pos =

0 commit comments

Comments
 (0)