lspitzner / brittany

haskell source code formatter
GNU Affero General Public License v3.0
690 stars 72 forks source link

brittany often fails on files with TemplateHaskell #206

Open dspies-leapyear opened 5 years ago

dspies-leapyear commented 5 years ago

Unfortunately I don't know exactly what's causing it because it doesn't seem to fails on all files which use TemplateHaskell, but it does seem to happen on a lot of them.

On https://github.com/dspies-leapyear/persistwrap/blob/0d98f924208e2f4936e06c0b28ac5d223812c0fe/persistwrap-table/test/PersistWrap/TableSpec.hs

I get brittanyCmd: HsSpliceTy{} Brittany error - invalid output

tfausak commented 5 years ago

Can you provide a smaller failing example? There's a lot going on in that file. It's not clear what the problem could be.

charlescrain commented 5 years ago

I got this error whenever brittany puts some template haskell on its own line.

Ex:


import           Data.FileEmbed                 ( embedStringFile , makeRelativeToProject)
import           Data.Text                            ( Text )

data Example = Example { longExampleRecordName :: Text }

mkExampleWithTH = Example
  { longExampleRecordName     = $(embedStringFile =<< makeRelativeToProject "./example/with/long/path/to/file")
  }

gets formatted to

mkExampleWithTH = Example
  { longExampleRecordName =
    $(embedStringFile =<< makeRelativeToProject "./example/with/long/path/to/file")
  }

and then whenever I attempt to format, it errors with:

ERROR: encountered unknown syntactical constructs: HsSpliceE{} 

If written so that the TH isn't at the beginning of line, it works fine, so there is a work around.

ghorn commented 5 years ago

I can reproduce this as well with a slightly different example:

{-# LANGUAGE QuasiQuotes #-}

module Test
  ( foo
  ) where

foo :: String
foo =
  [fmt|this causes error|]

gives this error:

ERROR: brittany pretty printer returned syntactically invalid result.
ERROR: encountered unknown syntactical constructs:
HsSpliceE{} at Test.hs:9:3-26

If the quasiquote is on the same line as foo = then there is no error.

andys8 commented 4 years ago

Another example:

Fails

f = case parse of
  Left  err  -> error (formatErr err)
  Right res -> res
 where
  parse = lexAndParse
    "File"
    $(runIO (readFile "prelude/File.ext") >>= \x -> [| x |])
HsSpliceE{} at src/Bot/Dsl/Prelude.hs:25:5-63
make: *** [Makefile:106: format] Error 1

Working

f = case parse of
  Left  err  -> error (formatErr err)
  Right res -> res
 where
  content = $(runIO (readFile "prelude/File.ext") >>= \x -> [| x |])
  parse = lexAndParse "File" content
tfausak commented 4 years ago

Here's a minimal example:

{-# language TemplateHaskell #-}
module I206 where
x = $( works )
y =
 $( doesn't work )
$ stack exec -- brittany --version
brittany version 0.12.1.1
Copyright (C) 2016-2019 Lennart Spitzner
Copyright (C) 2019 PRODA LTD
There is NO WARRANTY, to the extent permitted by law.
$ stack exec -- brittany --output-on-errors I206.hs
ERROR: brittany pretty printer returned syntactically invalid result.
ERROR: encountered unknown syntactical constructs:
HsSpliceE{} at I206.hs:5:2-18
{-# language TemplateHaskell #-}
module I206 where
x = $( works )
y = {- BRITTANY ERROR UNHANDLED SYNTACTICAL CONSTRUCT -}

You can work around this by adding a -- brittany-disable-next-binding comment above the troublesome splice.

{-# language TemplateHaskell #-}
module I206 where
x = $( works )
-- brittany-disable-next-binding
y =
 $( doesn't work )

I wasn't able to reproduce the error with quasi quotes.

majkrzak commented 4 years ago

I'm not exactly sure if it is related or should be spearated issue, but when trying to format:

get "/" $ do
  setHeader "Content-Type" "text/html"
  raw $ fromStrict $(embedFile "app/index.html")

I'm getting ...ct $ (em... which results in broken code

tfausak commented 2 years ago

To fix the embedFile problem you need to let Brittany know that the TemplateHaskell language extension is enabled. You can do that by either adding the {-# LANGUAGE TemplateHaskell #-} pragma to the file, or calling Brittany with --ghc-options -XTemplateHaskell.