packages feed

splint-1.0.2.0: src/ghc-9.2/Splint.hs

module Splint where

import qualified GHC.Data.Bag as Bag
import qualified GHC.Driver.Errors as Errors
import qualified GHC.Hs as Hs
import qualified GHC.Plugins as Plugins
import qualified GHC.Types.Error as Error
import qualified GHC.Utils.Logger as Logger
import qualified Language.Haskell.HLint as HLint
import qualified Splint.Settings as Settings

plugin :: Plugins.Plugin
plugin = Plugins.defaultPlugin
  { Plugins.parsedResultAction = parsedResultAction
  , Plugins.pluginRecompile = Plugins.purePlugin
  }

parsedResultAction
  :: [Plugins.CommandLineOption]
  -> Plugins.ModSummary
  -> Hs.HsParsedModule
  -> Plugins.Hsc Hs.HsParsedModule
parsedResultAction commandLineOptions _modSummary hsParsedModule = do
  (_parseFlags, classifies, hint) <- Plugins.liftIO
    $ Settings.load commandLineOptions
  logger <- Logger.getLogger
  dynFlags <- Plugins.getDynFlags
  Plugins.liftIO
    . Errors.printOrThrowWarnings logger dynFlags
    . Bag.listToBag
    . fmap ideaToWarnMsg
    . filter ((/=) HLint.Ignore . HLint.ideaSeverity)
    . HLint.applyHints classifies hint
    . pure
    . HLint.createModuleEx
    $ Hs.hpm_module hsParsedModule
  pure hsParsedModule

ideaToWarnMsg :: HLint.Idea -> Error.WarnMsg
ideaToWarnMsg idea =
  Error.mkPlainWarnMsg (ideaToSrcSpan idea) (ideaToSDoc idea)

ideaToSrcSpan :: HLint.Idea -> Plugins.SrcSpan
ideaToSrcSpan idea = case HLint.unpackSrcSpan $ HLint.ideaSpan idea of
  Nothing -> Plugins.noSrcSpan
  Just (filePath, (startLine, startColumn), (endLine, endColumn)) ->
    let fastString = Plugins.mkFastString filePath
    in
      Plugins.mkSrcSpan
        (Plugins.mkSrcLoc fastString startLine startColumn)
        (Plugins.mkSrcLoc fastString endLine endColumn)

ideaToSDoc :: HLint.Idea -> Error.SDoc
ideaToSDoc idea = Plugins.vcat
  [ Plugins.text $ HLint.ideaHint idea
  , case HLint.ideaTo idea of
    Just to | not $ null to -> Plugins.text $ "Perhaps: " <> to
    _ -> Plugins.empty
  , Plugins.vcat
  . fmap (Plugins.text . mappend "Note: " . show)
  $ HLint.ideaNote idea
  ]