Skip to content

fix shebang line parsing #2725

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

Closed
wants to merge 2 commits into from
Closed

Conversation

kokobd
Copy link
Collaborator

@kokobd kokobd commented Feb 19, 2022

This will fix #2724.

The PR is created with a test case for this, without any actual code fix currently.

@kokobd
Copy link
Collaborator Author

kokobd commented Feb 19, 2022

In hls, we are not using the parseModule in ghc-exactprint directly. Instead, we manually call GHC's api and construct Anns using relativiseApiAnns. So something is different between the parsing in hls and ghc-exactprint. Let's take a look at ghc-exactprint-0.6.4:

-- | Internal part of 'parseModuleFromString'.
parseModuleFromStringInternal :: Parser GHC.ParsedSource
parseModuleFromStringInternal dflags fileName str =
  let (str1, lp) = stripLinePragmas str
      res        = case runParser GHC.parseModule dflags fileName str1 of
#if __GLASGOW_HASKELL__ > 808
        GHC.PFailed pst     -> Left (GHC.getErrorMessages pst dflags)
#elif __GLASGOW_HASKELL__ >= 804
        GHC.PFailed _ ss m  -> Left (ss, GHC.showSDoc dflags m)
#else
        GHC.PFailed ss m    -> Left (ss, GHC.showSDoc dflags m)
#endif
        GHC.POk     x  pmod -> Right (mkApiAnns x, lp, dflags, pmod)
  in  postParseTransform res normalLayout

It calls stripLinePragmas which itself handles shebang specially, as below (in another function, checkLine)

checkLine :: Int -> String -> (String, Maybe Comment)
checkLine line s
  |  "{-# LINE" `isPrefixOf` s =
       let (pragma, res) = getPragma s
           size   = length pragma
           mSrcLoc = mkSrcLoc (mkFastString "LINE")
           ss     = mkSrcSpan (mSrcLoc line 1) (mSrcLoc line (size+1))
       in (res, Just $ mkComment pragma (rs ss))
  -- Deal with shebang/cpp directives too
  -- x |  "#" `isPrefixOf` s = ("",Just $ Comment ((line, 1), (line, length s)) s)
  |  "#!" `isPrefixOf` s =
    let mSrcLoc = mkSrcLoc (mkFastString "SHEBANG")
        ss = mkSrcSpan (mSrcLoc line 1) (mSrcLoc line (length s))

In ghcide, I can't find code handling shebang like this, in getParsedModuleWithCommentsRule. And the test case shows it is not handled properly.

To fix this, I'm going to add a call stripLinePragmas in ghcide, like what has been done in ghc-exactprint

@michaelpj
Copy link
Collaborator

In hls, we are not using the parseModule in ghc-exactprint directly.

Do you know why? Could we start using it?

@kokobd
Copy link
Collaborator Author

kokobd commented Feb 28, 2022

In hls, we are not using the parseModule in ghc-exactprint directly.

That's probably because we need pass our own DynFlags and some other options to GHC's parser.

Moreover, I recently discovered that, using ghc-9.2.1 with ghc-exactprint-1.5.0 together will NOT exactprint shebang lines.

@kokobd
Copy link
Collaborator Author

kokobd commented Jul 8, 2022

This is harder than I thought. Closing.

@kokobd kokobd closed this Jul 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

shebang lines are lost in exactprint
2 participants