11{-# LANGUAGE DeriveFunctor #-}
2+ {-# LANGUAGE TupleSections #-}
3+ {-# LANGUAGE InstanceSigs #-}
24{-# LANGUAGE MultiParamTypeClasses #-}
35{-# LANGUAGE OverloadedStrings #-}
46{-# LANGUAGE RankNTypes #-}
@@ -69,12 +71,14 @@ module Distribution.FieldGrammar.Parsec
6971 , freeTextIgnoreDotlineVers
7072 ) where
7173
74+ import Distribution.Compat.Lens
7275import Distribution.Compat.Newtype
7376import Distribution.Compat.Prelude
7477import Distribution.Utils.Generic (fromUTF8BS )
7578import Distribution.Utils.String (trim )
7679import Prelude ()
7780
81+ import Data.Monoid (Last (.. ))
7882import qualified Data.ByteString as BS
7983import qualified Data.List.NonEmpty as NE
8084import qualified Data.Map.Strict as Map
@@ -88,6 +92,7 @@ import Distribution.FieldGrammar.Class
8892import Distribution.Fields.Field
8993import Distribution.Fields.ParseResult
9094import Distribution.Parsec
95+ import Distribution.Trivia
9196import Distribution.Parsec.FieldLineStream
9297import Distribution.Parsec.Position (positionCol , positionRow )
9398
@@ -271,14 +276,47 @@ instance FieldGrammar Parsec ParsecFieldGrammar where
271276 | v >= freeTextIgnoreDotlineVers -> pure (ShortText. toShortText $ fieldlinesToFreeText3 pos fls)
272277 | otherwise -> pure (ShortText. toShortText $ fieldlinesToFreeText fls)
273278
279+ monoidalFieldAla
280+ :: forall b a s
281+ . (Parsec b , Monoid a , Newtype a b )
282+ => FieldName
283+ -> (a -> b )
284+ -> ALens' s a
285+ -> ParsecFieldGrammar s a
274286 monoidalFieldAla fn _pack _extract = ParsecFG (Set. singleton fn) Set. empty parser
275287 where
288+ parser :: CabalSpecVersion -> Fields Position -> ParseResult src a
276289 parser v fields = case Map. lookup fn fields of
277290 Nothing -> pure mempty
278291 Just xs -> foldMap (unpack' _pack) <$> traverse (parseOne v) xs
279292
293+ parseOne :: CabalSpecVersion -> NamelessField Position -> ParseResult src b
280294 parseOne v (MkNamelessField pos fls) = runFieldParser pos parsec v fls
281295
296+ -- TODO(leana8959): maybe define monoidalFieldAla base on monoidalFieldAlaAnn
297+ --
298+ -- This function allows us to manage the position coming from a parsed field
299+ -- In the printer, it can... IDK? Annotate the pretty doc position?
300+ monoidalFieldAlaAnn
301+ :: forall b a s u
302+ . (Parsec b , Monoid u , Newtype a b )
303+ => FieldName
304+ -> (a -> b )
305+ -> ALens' s a
306+ -> (Positions -> a -> u )
307+ -> ParsecFieldGrammar s u
308+ monoidalFieldAlaAnn fn _pack _extract attachPos = ParsecFG (Set. singleton fn) Set. empty parser
309+ where
310+ parser :: CabalSpecVersion -> Fields Position -> ParseResult src u
311+ parser v fields = case Map. lookup fn fields of
312+ Nothing -> pure mempty
313+ Just xs -> foldMap (\ (p, b) -> attachPos p $ unpack' _pack b) <$> traverse (parseOne v) xs
314+
315+ parseOne :: CabalSpecVersion -> NamelessField Position -> ParseResult src (Positions , b )
316+ parseOne v (MkNamelessField pos fls) = do
317+ (linePos, x) <- runFieldParser pos (liftA2 (,) (liftParsec P. getPosition) parsec) v fls
318+ pure (Positions (Just pos) (undefined linePos) Nothing , x)
319+
282320 prefixedFields fnPfx _extract = ParsecFG mempty (Set. singleton fnPfx) (\ _ fs -> pure (parser fs))
283321 where
284322 parser :: Fields Position -> [(String , String )]
0 commit comments