content: {-# OPTIONS_GHC -Wall #-}
  {-# LANGUAGE OverloadedStrings #-}
  module Reporting.Warning
    ( Warning(..)
    , Context(..)
    , toReport
    )
    where
  
  
  import Data.Monoid ((<>))
  import qualified Data.Name as Name
  
  import qualified AST.Canonical as Can
  import qualified AST.Utils.Type as Type
  import qualified Reporting.Annotation as A
  import qualified Reporting.Doc as D
  import qualified Reporting.Report as Report
  import qualified Reporting.Render.Code as Code
  import qualified Reporting.Render.Type as RT
  import qualified Reporting.Render.Type.Localizer as L
  
  
  
  -- ALL POSSIBLE WARNINGS
  
  
  data Warning
    = UnusedImport A.Region Name.Name
    | UnusedVariable A.Region Context Name.Name
    | MissingTypeAnnotation A.Region Name.Name Can.Type
  
  
  data Context = Def | Pattern
  
  
  
  -- TO REPORT
  
  
  toReport :: L.Localizer -> Code.Source -> Warning -> Report.Report
  toReport localizer source warning =
    case warning of
      UnusedImport region moduleName ->
        Report.Report "unused import" region [] $
          Code.toSnippet source region Nothing
            (
              D.reflow $
                "Nothing from the `" <> Name.toChars moduleName <> "` module is used in this file."
            ,
              "I recommend removing unused imports."
            )
  
      UnusedVariable region context name ->
        let title = defOrPat context "unused definition" "unused variable" in
        Report.Report title region [] $
          Code.toSnippet source region Nothing
            (
              D.reflow $
                "You are not using `" <> Name.toChars name <> "` anywhere."
            ,
              D.stack
                [ D.reflow $
                    "Is there a typo? Maybe you intended to use `" <> Name.toChars name
                    <> "` somewhere but typed another name instead?"
                , D.reflow $
                    defOrPat context
                      ( "If you are sure there is no typo, remove the definition.\
                        \ This way future readers will not have to wonder why it is there!"
                      )
                      ( "If you are sure there is no typo, replace `" <> Name.toChars name
                        <> "` with _ so future readers will not have to wonder why it is there!"
                      )
                ]
            )
  
      MissingTypeAnnotation region name inferredType ->
          Report.Report "missing type annotation" region [] $
            Code.toSnippet source region Nothing
              (
                D.reflow $
                  case Type.deepDealias inferredType of
                    Can.TLambda _ _ ->
                      "The `" <> Name.toChars name <> "` function has no type annotation."
  
                    _ ->
                      "The `" <> Name.toChars name <> "` definition has no type annotation."
              ,
                D.stack
                  [ "I inferred the type annotation myself though! You can copy it into your code:"
                  , D.green $ D.hang 4 $ D.sep $
                      [ D.fromName name <> " :"
                      , RT.canToDoc localizer RT.None inferredType
                      ]
                  ]
              )
  
  
  defOrPat :: Context -> a -> a -> a
  defOrPat context def pat =
    case context of
      Def -> def
      Pattern -> pat
  
  