Skip to content

Commit 731ed87

Browse files
committed
Use pre-whitespace position for source end locations
Fixes #743
1 parent 820499d commit 731ed87

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

src/Nix/Parser.hs

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ import Control.Applicative hiding ( many
5353
import Control.DeepSeq
5454
import Control.Monad
5555
import Control.Monad.Combinators.Expr
56+
import Control.Monad.State.Strict
5657
import Data.Char ( isAlpha
5758
, isDigit
5859
, isSpace
5960
)
6061
import Data.Data ( Data(..) )
6162
import Data.Functor
62-
import Data.Functor.Identity
6363
import Data.HashSet ( HashSet )
6464
import qualified Data.HashSet as HashSet
6565
import Data.List.NonEmpty ( NonEmpty(..) )
@@ -81,7 +81,7 @@ import Nix.Render
8181
import Prettyprinter ( Doc
8282
, pretty
8383
)
84-
import Text.Megaparsec
84+
import Text.Megaparsec hiding ( State )
8585
import Text.Megaparsec.Char
8686
import qualified Text.Megaparsec.Char.Lexer as L
8787

@@ -439,7 +439,9 @@ skipLineComment' prefix = string prefix
439439
*> void (takeWhileP (Just "character") (\x -> x /= '\n' && x /= '\r'))
440440

441441
whiteSpace :: Parser ()
442-
whiteSpace = L.space space1 lineCmnt blockCmnt
442+
whiteSpace = do
443+
put =<< getSourcePos
444+
L.space space1 lineCmnt blockCmnt
443445
where
444446
lineCmnt = skipLineComment' "#"
445447
blockCmnt = L.skipBlockComment "/*" "*/"
@@ -513,20 +515,24 @@ reservedNames :: HashSet Text
513515
reservedNames = HashSet.fromList
514516
["let", "in", "if", "then", "else", "assert", "with", "rec", "inherit"]
515517

516-
type Parser = ParsecT Void Text Identity
518+
type Parser = ParsecT Void Text (State SourcePos)
517519

518520
data Result a = Success a | Failure (Doc Void) deriving (Show, Functor)
519521

520522
parseFromFileEx :: MonadFile m => Parser a -> FilePath -> m (Result a)
521523
parseFromFileEx p path = do
522524
txt <- decodeUtf8 <$> readFile path
523-
pure $ either (Failure . pretty . errorBundlePretty) Success $ parse p
524-
path
525-
txt
525+
pure
526+
$ either (Failure . pretty . errorBundlePretty) Success
527+
. flip evalState (initialPos path)
528+
$ runParserT p path txt
526529

527530
parseFromText :: Parser a -> Text -> Result a
528531
parseFromText p txt =
529-
either (Failure . pretty . errorBundlePretty) Success $ parse p "<string>" txt
532+
let file = "<string>"
533+
in either (Failure . pretty . errorBundlePretty) Success
534+
. flip evalState (initialPos file)
535+
$ runParserT p file txt
530536

531537
{- Parser.Operators -}
532538

@@ -546,7 +552,7 @@ annotateLocation :: Parser a -> Parser (Ann SrcSpan a)
546552
annotateLocation p = do
547553
begin <- getSourcePos
548554
res <- p
549-
end <- getSourcePos
555+
end <- get -- The state set before the last whitespace
550556
pure $ Ann (SrcSpan begin end) res
551557

552558
annotateLocation1 :: Parser (NExprF NExprLoc) -> Parser NExprLoc

0 commit comments

Comments
 (0)