Skip to content

Commit

Permalink
[#70] Tripped by comments before pragmas
Browse files Browse the repository at this point in the history
Resolves #70
  • Loading branch information
vrom911 committed Oct 14, 2022
1 parent be93e91 commit a5ad6a0
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 7 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
`extensions` uses [PVP Versioning][1].
The changelog is available [on GitHub][2].

## Unreleased

* [#70](https://github.com/kowainik/extensions/issues/70):
Parse empty lines and spaces in before comments and pragmas in the beginning
of the file.

## 0.0.0.1 — May 9, 2020 🎖️

* Handle one more parsing case.
Expand Down
17 changes: 10 additions & 7 deletions src/Extensions/Module.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import Data.List (nub)
import Data.List.NonEmpty (NonEmpty (..))
import System.Directory (doesFileExist)
import Text.Parsec (alphaNum, between, char, eof, many, many1, manyTill, noneOf, oneOf, parse,
sepBy1, try, (<|>))
sepBy1, skipMany, try, (<|>))
import Text.Parsec.ByteString (Parser)
import Text.Parsec.Char (anyChar, endOfLine, letter, newline, space, spaces, string)
import Text.Read (readMaybe)
Expand Down Expand Up @@ -106,9 +106,12 @@ It parses language pragmas or comments until end of file or the first line with
the function/import/module name.
-}
extensionsP :: Parser [ParsedExtension]
extensionsP = concat <$> manyTill
(try singleExtensionsP <|> try optionsGhcP <|> try commentP <|> try cppP)
(eof <|> (() <$ manyTill endOfLine letter))
extensionsP = concat <$>
( newLines *>
manyTill
(try singleExtensionsP <|> try optionsGhcP <|> try commentP <|> try cppP)
(eof <|> (() <$ manyTill endOfLine letter))
)

{- | Single LANGUAGE pragma parser.
Expand All @@ -124,7 +127,7 @@ singleExtensionsP =
languagePragmaP (commaSep (nonExtP *> extensionP <* nonExtP) <* spaces)

nonExtP :: Parser ()
nonExtP = () <$ many (try cppP <|> try commentP)
nonExtP = skipMany (try cppP <|> try commentP)

{- | Parses all known and unknown 'OnOffExtension's or 'SafeHaskellExtension's.
-}
Expand Down Expand Up @@ -165,7 +168,7 @@ pragmaP pragmaNameP p = between

-- | Comma separated parser. Newlines and spaces are allowed around comma.
commaSep :: Parser a -> Parser [a]
commaSep p = p `sepBy1` (try $ newLines *> char ',' <* newLines)
commaSep p = p `sepBy1` try (newLines *> char ',' <* newLines)

{- | Haskell comment parser.
Supports both single-line comments:
Expand Down Expand Up @@ -211,4 +214,4 @@ cppP =

-- | Any combination of spaces and newlines.
newLines :: Parser ()
newLines = () <$ many (space <|> endOfLine)
newLines = skipMany (space <|> endOfLine)
16 changes: 16 additions & 0 deletions test/Test/Extensions/Module.hs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,22 @@ multiLineCommentsSpec = describe "Parsing extensions with multi-line comments" $
itShouldParse
"{- Haskelll -} {-# {- extension -} LANGUAGE {- called -} LambdaCase {- and nothing else -} #-} {- matters -}"
[LambdaCase]
itShouldParse (unlines
[ ""
, "{- |"
, "Hello"
, "-}"
, "{-# LANGUAGE CPP #-}"
])
[Cpp]
itShouldParse (unlines
[ ""
, "-- | Hey"
, "-- Hello"
, "--"
, "module Abc"
])
[]
itShouldParse (unlines
[ "{-# LANGUAGE TypeApplications , LambdaCase #-}"
, "{- hello -}"
Expand Down

0 comments on commit a5ad6a0

Please sign in to comment.