Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reformat returns a ParseError on error #715

Merged
merged 9 commits into from
Apr 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
### Changed

- `reformat` now takes a list of `Extension`s instead of a `Maybe` value containing the list ([#712]).
- `reformat` and `testAst` now returns a `ParseError` on error ([#715]).

### Fixed

Expand Down Expand Up @@ -342,6 +343,7 @@ This version is accidentally pushlished, and is the same as 5.3.3.
[@uhbif19]: https://github.com/uhbif19
[@toku-sa-n]: https://github.com/toku-sa-n

[#715]: https://github.com/mihaimaruseac/hindent/pull/715
[#712]: https://github.com/mihaimaruseac/hindent/pull/712
[#709]: https://github.com/mihaimaruseac/hindent/pull/709
[#708]: https://github.com/mihaimaruseac/hindent/pull/708
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ toCriterion = go
then (bench
(UTF8.toString desc)
(nf
(either error S.toLazyByteString .
(either (error . show) S.toLazyByteString .
reformat
HIndent.Config.defaultConfig
defaultExtensions
Expand Down
1 change: 1 addition & 0 deletions hindent.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ library
HIndent.CodeBlock
HIndent.CommandlineOptions
HIndent.Config
HIndent.Error
HIndent.GhcLibParserWrapper.GHC.Hs
HIndent.Language
HIndent.LanguageExtension
Expand Down
26 changes: 15 additions & 11 deletions src/HIndent.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import HIndent.CabalFile
import HIndent.CodeBlock
import HIndent.CommandlineOptions
import HIndent.Config
import HIndent.Error
import HIndent.GhcLibParserWrapper.GHC.Hs
import HIndent.LanguageExtension
import qualified HIndent.LanguageExtension.Conversion as CE
Expand All @@ -46,7 +47,7 @@ import HIndent.ModulePreprocessing
import HIndent.Parse
import HIndent.Pretty
import HIndent.Printer
import Options.Applicative hiding (action, style)
import Options.Applicative hiding (ParseError, action, style)
import Paths_hindent
import qualified System.Directory as IO
import System.Exit
Expand All @@ -69,13 +70,13 @@ hindent args = do
Run style exts action paths ->
if null paths
then L8.interact
(either error S.toLazyByteString .
(either (error . prettyParseError) S.toLazyByteString .
reformat style exts Nothing . L8.toStrict)
else forM_ paths $ \filepath -> do
cabalexts <- getCabalExtensionsForSourcePath filepath
text <- S.readFile filepath
case reformat style (cabalexts ++ exts) (Just filepath) text of
Left e -> error e
Left e -> error $ prettyParseError e
Right out ->
unless (L8.fromStrict text == S.toLazyByteString out) $
case action of
Expand All @@ -101,12 +102,12 @@ reformat ::
-> [Extension]
-> Maybe FilePath
-> ByteString
-> Either String Builder
-> Either ParseError Builder
reformat config mexts mfilepath =
preserveTrailingNewline
(fmap (mconcat . intersperse "\n") . mapM processBlock . cppSplitBlocks)
where
processBlock :: CodeBlock -> Either String Builder
processBlock :: CodeBlock -> Either ParseError Builder
processBlock (Shebang text) = Right $ S.byteString text
processBlock (CPPDirectives text) = Right $ S.byteString text
processBlock (HaskellSource yPos text) =
Expand All @@ -125,9 +126,12 @@ reformat config mexts mfilepath =
addPrefix prefix $ S.toLazyByteString $ prettyPrint config m
PFailed st ->
let rawErrLoc = psRealLoc $ loc st
adjustedLoc =
(srcLocLine rawErrLoc + yPos, srcLocCol rawErrLoc)
in Left $ "Parse failed near " ++ show adjustedLoc
in Left $
ParseError
{ errorLine = srcLocLine rawErrLoc + yPos
, errorCol = srcLocCol rawErrLoc
, errorFile = fromMaybe "<interactive>" mfilepath
}
unlines' = S.concat . intersperse "\n"
unlines'' = L.concat . intersperse "\n"
addPrefix :: ByteString -> L8.ByteString -> L8.ByteString
Expand Down Expand Up @@ -175,14 +179,14 @@ reformat config mexts mfilepath =
| otherwise = f x

-- | Generate an AST from the given module for debugging.
testAst :: ByteString -> Either String HsModule'
testAst :: ByteString -> Either ParseError HsModule'
testAst x =
case parseModule Nothing exts (UTF8.toString x) of
POk _ m -> Right $ modifyASTForPrettyPrinting m
PFailed st ->
Left $
"Parse failed near " ++
show ((,) <$> srcLocLine <*> srcLocCol $ psRealLoc $ loc st)
ParseError <$> srcLocLine <*> srcLocCol <*> pure "<interactive>" $
psRealLoc $ loc st
where
exts =
CE.uniqueExtensions $
Expand Down
20 changes: 20 additions & 0 deletions src/HIndent/Error.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{-# LANGUAGE RecordWildCards #-}

-- | Error types and functions.
module HIndent.Error
( ParseError(..)
, prettyParseError
) where

-- | Parse error type with the location.
data ParseError = ParseError
{ errorLine :: Int -- ^ The row of the parse error's location.
, errorCol :: Int -- ^ The column of the parse error's location.
, errorFile :: FilePath -- ^ The filename HIndent failed to parse.
} deriving (Eq, Ord, Show, Read)

-- | Pretty-print `ParseError`.
prettyParseError :: ParseError -> String
prettyParseError ParseError {..} =
"Parse failed at (" <>
show errorLine <> ", " <> show errorCol <> ") in " <> errorFile <> "."
3 changes: 2 additions & 1 deletion tests/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import Data.Version
import qualified HIndent
import HIndent.CodeBlock
import HIndent.Config
import HIndent.Error
import HIndent.Internal.Test.Markdone
import qualified HIndent.LanguageExtension as HIndent
import qualified System.Info
Expand All @@ -37,7 +38,7 @@ main = do

reformat :: Config -> S.ByteString -> ByteString
reformat cfg code =
either (("-- " <>) . L8.pack) S.toLazyByteString $
either (("-- " <>) . L8.pack . prettyParseError) S.toLazyByteString $
HIndent.reformat cfg HIndent.defaultExtensions Nothing code

-- | Convert the Markdone document to Spec benchmarks.
Expand Down
Loading