{-# 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