@@ -2,8 +2,8 @@ module Test.LambdaBuffers.Compiler.Gen (genCompilerInput) where
22
33import Control.Lens ((&) , (.~) , (^.) )
44import Control.Monad (foldM )
5+ import Data.Either (isRight )
56import Data.Foldable (Foldable (toList ))
6- import Data.List qualified as List
77import Data.List.NonEmpty (NonEmpty ((:|) ))
88import Data.Map (Map )
99import Data.Map qualified as Map
@@ -20,14 +20,14 @@ import Data.Text qualified as Text
2020import Data.Traversable (for )
2121import GHC.Enum qualified as Int
2222import 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 )
2424import Proto.Compiler_Fields qualified as P
2525import Test.QuickCheck qualified as QC (arbitraryPrintableChar )
2626import Test.QuickCheck.Gen qualified as QC
2727
2828-- | Upper bound on various generators
2929limit :: Int
30- limit = 10
30+ limit = 5
3131
3232-- | Names
3333genAlphaNum :: 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
9292genSum 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
9999genTy 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
114120genTyVar :: 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 ]
124130genTyApp 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
142148genConstructor 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
150156genTyBodySum tydefs args ctors = do
151157 b <- genSum tydefs args ctors
152158 return $ defMessage & P. sum .~ b
153159
154160genTyBodyOpaque :: QC. Gen TyBody
155161genTyBodyOpaque = 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
158164genTyBody 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
166172genTyAbs 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
179187genTyDef 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
204220genCompilerInput :: QC. Gen CompilerInput
205221genCompilerInput = 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