Skip to content

Commit 4533c76

Browse files
committed
WIP: figure out how to thread position in field grammar
1 parent ed0f9dc commit 4533c76

4 files changed

Lines changed: 71 additions & 0 deletions

File tree

Cabal-syntax/src/Distribution/FieldGrammar/Class.hs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import Prelude ()
1919

2020
import Distribution.CabalSpecVersion (CabalSpecVersion)
2121
import Distribution.Compat.Newtype (Newtype)
22+
import Distribution.Trivia
23+
import Distribution.Parsec.Position (Position)
2224
import Distribution.FieldGrammar.Newtypes
2325
import Distribution.Fields.Field
2426
import Distribution.Utils.ShortText
@@ -132,6 +134,22 @@ class
132134
-- ^ lens into the field
133135
-> g s a
134136

137+
-- | Monoidal field.
138+
--
139+
-- Values are combined with 'mappend'.
140+
--
141+
-- /Note:/ 'optionalFieldAla' is a @monoidalField@ with 'Last' monoid.
142+
monoidalFieldAlaAnn
143+
:: (c b, Monoid u, Newtype a b)
144+
=> FieldName
145+
-- ^ field name
146+
-> (a -> b)
147+
-- ^ 'pack'
148+
-> ALens' s a
149+
-- ^ lens into the field
150+
-> (Positions -> a -> u)
151+
-> g s u
152+
135153
-- | Parser matching all fields with a name starting with a prefix.
136154
prefixedFields
137155
:: FieldName

Cabal-syntax/src/Distribution/FieldGrammar/Parsec.hs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
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
7275
import Distribution.Compat.Newtype
7376
import Distribution.Compat.Prelude
7477
import Distribution.Utils.Generic (fromUTF8BS)
7578
import Distribution.Utils.String (trim)
7679
import Prelude ()
7780

81+
import Data.Monoid (Last (..))
7882
import qualified Data.ByteString as BS
7983
import qualified Data.List.NonEmpty as NE
8084
import qualified Data.Map.Strict as Map
@@ -88,6 +92,7 @@ import Distribution.FieldGrammar.Class
8892
import Distribution.Fields.Field
8993
import Distribution.Fields.ParseResult
9094
import Distribution.Parsec
95+
import Distribution.Trivia
9196
import Distribution.Parsec.FieldLineStream
9297
import 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)]

Cabal-syntax/src/Distribution/PackageDescription/FieldGrammar.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,20 @@ buildInfoFieldGrammar =
695695
{-# SPECIALIZE buildInfoFieldGrammar :: ParsecFieldGrammar' BuildInfoAnn #-}
696696
{-# SPECIALIZE buildInfoFieldGrammar :: PrettyFieldGrammar' BuildInfoAnn #-}
697697

698+
699+
onlyBuildDepends
700+
:: forall mod c g
701+
. ( FieldGrammar c g
702+
, Applicative (g (BuildInfoWith mod))
703+
, L.HasBuildInfoWith mod (BuildInfoWith mod)
704+
, L.HasBuildInfoWith mod [DependencyWith mod]
705+
, c (List CommaVCat (Identity (DependencyWith mod)) (DependencyWith mod))
706+
)
707+
=> g [DependencyWith mod] [DependencyWith mod]
708+
onlyBuildDepends = monoidalFieldAla "build-depends" (formatDependencyList @mod) L.targetBuildDepends
709+
{-# SPECIALIZE onlyBuildDepends :: ParsecFieldGrammar' [DependencyAnn] #-}
710+
{-# SPECIALIZE onlyBuildDepends :: PrettyFieldGrammar' [DependencyAnn] #-}
711+
698712
hsSourceDirsGrammar
699713
:: forall mod c g
700714
. ( FieldGrammar c g

Cabal-syntax/src/Distribution/Parsec.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ module Distribution.Parsec
6464
, parsecLeadingOptCommaListAnn
6565
, parsecStandard
6666
, parsecUnqualComponentName
67+
, liftParsec
6768
) where
6869

6970
import Data.ByteString (ByteString)

0 commit comments

Comments
 (0)