{-# LANGUAGE RecordWildCards, NoMonomorphismRestriction #-}
module Idea(
Idea(..),
rawIdea, rawIdea', idea, idea', suggest, suggest', warn, warn',ignore, ignore',
rawIdeaN, rawIdeaN', suggestN, suggestN', ignoreN, ignoreN', ignoreNoSuggestion',
showIdeasJson, showANSI,
Note(..), showNotes,
Severity(..),
) where
import Data.Functor
import Data.List.Extra
import HSE.All
import Config.Type
import HsColour
import Refact.Types hiding (SrcSpan)
import qualified Refact.Types as R
import Prelude
import qualified SrcLoc as GHC
import qualified Outputable
import qualified GHC.Util as GHC
data Idea = Idea
{Idea -> [String]
ideaModule :: [String]
,Idea -> [String]
ideaDecl :: [String]
,Idea -> Severity
ideaSeverity :: Severity
,Idea -> String
ideaHint :: String
,Idea -> SrcSpan
ideaSpan :: SrcSpan
,Idea -> String
ideaFrom :: String
,Idea -> Maybe String
ideaTo :: Maybe String
,Idea -> [Note]
ideaNote :: [Note]
,Idea -> [Refactoring SrcSpan]
ideaRefactoring :: [Refactoring R.SrcSpan]
}
deriving (Idea -> Idea -> Bool
(Idea -> Idea -> Bool) -> (Idea -> Idea -> Bool) -> Eq Idea
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Idea -> Idea -> Bool
$c/= :: Idea -> Idea -> Bool
== :: Idea -> Idea -> Bool
$c== :: Idea -> Idea -> Bool
Eq,Eq Idea
Eq Idea =>
(Idea -> Idea -> Ordering)
-> (Idea -> Idea -> Bool)
-> (Idea -> Idea -> Bool)
-> (Idea -> Idea -> Bool)
-> (Idea -> Idea -> Bool)
-> (Idea -> Idea -> Idea)
-> (Idea -> Idea -> Idea)
-> Ord Idea
Idea -> Idea -> Bool
Idea -> Idea -> Ordering
Idea -> Idea -> Idea
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Idea -> Idea -> Idea
$cmin :: Idea -> Idea -> Idea
max :: Idea -> Idea -> Idea
$cmax :: Idea -> Idea -> Idea
>= :: Idea -> Idea -> Bool
$c>= :: Idea -> Idea -> Bool
> :: Idea -> Idea -> Bool
$c> :: Idea -> Idea -> Bool
<= :: Idea -> Idea -> Bool
$c<= :: Idea -> Idea -> Bool
< :: Idea -> Idea -> Bool
$c< :: Idea -> Idea -> Bool
compare :: Idea -> Idea -> Ordering
$ccompare :: Idea -> Idea -> Ordering
$cp1Ord :: Eq Idea
Ord)
showIdeaJson :: Idea -> String
showIdeaJson :: Idea -> String
showIdeaJson idea :: Idea
idea@Idea{ideaSpan :: Idea -> SrcSpan
ideaSpan=srcSpan :: SrcSpan
srcSpan@SrcSpan{..}, ..} = [(String, String)] -> String
forall a. Show a => [(a, String)] -> String
dict
[("module", [String] -> String
list ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
str [String]
ideaModule)
,("decl", [String] -> String
list ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
str [String]
ideaDecl)
,("severity", String -> String
str (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Severity -> String
forall a. Show a => a -> String
show Severity
ideaSeverity)
,("hint", String -> String
str String
ideaHint)
,("file", String -> String
str String
srcSpanFilename)
,("startLine", Int -> String
forall a. Show a => a -> String
show Int
srcSpanStartLine)
,("startColumn", Int -> String
forall a. Show a => a -> String
show Int
srcSpanStartColumn)
,("endLine", Int -> String
forall a. Show a => a -> String
show Int
srcSpanEndLine)
,("endColumn", Int -> String
forall a. Show a => a -> String
show Int
srcSpanEndColumn)
,("from", String -> String
str String
ideaFrom)
,("to", String -> (String -> String) -> Maybe String -> String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe "null" String -> String
str Maybe String
ideaTo)
,("note", [String] -> String
list ((Note -> String) -> [Note] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> String
str (String -> String) -> (Note -> String) -> Note -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Note -> String
forall a. Show a => a -> String
show) [Note]
ideaNote))
,("refactorings", String -> String
str (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ [Refactoring SrcSpan] -> String
forall a. Show a => a -> String
show [Refactoring SrcSpan]
ideaRefactoring)
]
where
str :: String -> String
str x :: String
x = "\"" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
escapeJSON String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\""
dict :: [(a, String)] -> String
dict xs :: [(a, String)]
xs = "{" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate "," [a -> String
forall a. Show a => a -> String
show a
k String -> String -> String
forall a. [a] -> [a] -> [a]
++ ":" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
v | (k :: a
k,v :: String
v) <- [(a, String)]
xs] String -> String -> String
forall a. [a] -> [a] -> [a]
++ "}"
list :: [String] -> String
list xs :: [String]
xs = "[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate "," [String]
xs String -> String -> String
forall a. [a] -> [a] -> [a]
++ "]"
showIdeasJson :: [Idea] -> String
showIdeasJson :: [Idea] -> String
showIdeasJson ideas :: [Idea]
ideas = "[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate "\n," ((Idea -> String) -> [Idea] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Idea -> String
showIdeaJson [Idea]
ideas) String -> String -> String
forall a. [a] -> [a] -> [a]
++ "]"
instance Show Idea where
show :: Idea -> String
show = (String -> String) -> Idea -> String
showEx String -> String
forall a. a -> a
id
showANSI :: IO (Idea -> String)
showANSI :: IO (Idea -> String)
showANSI = (String -> String) -> Idea -> String
showEx ((String -> String) -> Idea -> String)
-> IO (String -> String) -> IO (Idea -> String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (String -> String)
hsColourConsole
showEx :: (String -> String) -> Idea -> String
showEx :: (String -> String) -> Idea -> String
showEx tt :: String -> String
tt Idea{..} = [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$
[SrcLoc -> String
showSrcLoc (SrcSpan -> SrcLoc
forall si. SrcInfo si => si -> SrcLoc
getPointLoc SrcSpan
ideaSpan) String -> String -> String
forall a. [a] -> [a] -> [a]
++ ": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (if String
ideaHint String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== "" then "" else Severity -> String
forall a. Show a => a -> String
show Severity
ideaSeverity String -> String -> String
forall a. [a] -> [a] -> [a]
++ ": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ideaHint)] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
String -> Maybe String -> [String]
f "Found" (String -> Maybe String
forall a. a -> Maybe a
Just String
ideaFrom) [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ String -> Maybe String -> [String]
f "Perhaps" Maybe String
ideaTo [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
["Note: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
n | let n :: String
n = [Note] -> String
showNotes [Note]
ideaNote, String
n String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= ""]
where
f :: String -> Maybe String -> [String]
f msg :: String
msg Nothing = []
f msg :: String
msg (Just x :: String
x) | [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
xs = [String
msg String -> String -> String
forall a. [a] -> [a] -> [a]
++ " you should remove it."]
| Bool
otherwise = (String
msg String -> String -> String
forall a. [a] -> [a] -> [a]
++ ":") String -> [String] -> [String]
forall a. a -> [a] -> [a]
: (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (" "String -> String -> String
forall a. [a] -> [a] -> [a]
++) [String]
xs
where xs :: [String]
xs = String -> [String]
lines (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ String -> String
tt String
x
rawIdea :: Severity -> String -> SrcSpan -> String -> Maybe String -> [Note]-> [Refactoring R.SrcSpan] -> Idea
rawIdea :: Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
rawIdea = [String]
-> [String]
-> Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
Idea [] []
rawIdea' :: Severity -> String -> GHC.SrcSpan -> String -> Maybe String -> [Note]-> [Refactoring R.SrcSpan] -> Idea
rawIdea' :: Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
rawIdea' a :: Severity
a b :: String
b c :: SrcSpan
c = [String]
-> [String]
-> Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
Idea [] [] Severity
a String
b (SrcSpan -> SrcSpan
ghcSpanToHSE SrcSpan
c)
rawIdeaN :: Severity -> String -> SrcSpan -> String -> Maybe String -> [Note] -> Idea
rawIdeaN :: Severity
-> String -> SrcSpan -> String -> Maybe String -> [Note] -> Idea
rawIdeaN a :: Severity
a b :: String
b c :: SrcSpan
c d :: String
d e :: Maybe String
e f :: [Note]
f = [String]
-> [String]
-> Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
Idea [] [] Severity
a String
b SrcSpan
c String
d Maybe String
e [Note]
f []
rawIdeaN' :: Severity -> String -> GHC.SrcSpan -> String -> Maybe String -> [Note] -> Idea
rawIdeaN' :: Severity
-> String -> SrcSpan -> String -> Maybe String -> [Note] -> Idea
rawIdeaN' a :: Severity
a b :: String
b c :: SrcSpan
c d :: String
d e :: Maybe String
e f :: [Note]
f = [String]
-> [String]
-> Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
Idea [] [] Severity
a String
b (SrcSpan -> SrcSpan
ghcSpanToHSE SrcSpan
c) String
d Maybe String
e [Note]
f []
idea :: (Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
Severity -> String -> ast SrcSpanInfo -> a -> [Refactoring R.SrcSpan] -> Idea
idea :: Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
idea severity :: Severity
severity hint :: String
hint from :: ast SrcSpanInfo
from to :: a
to = Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
rawIdea Severity
severity String
hint (SrcSpanInfo -> SrcSpan
srcInfoSpan (SrcSpanInfo -> SrcSpan) -> SrcSpanInfo -> SrcSpan
forall a b. (a -> b) -> a -> b
$ ast SrcSpanInfo -> SrcSpanInfo
forall (ast :: * -> *) l. Annotated ast => ast l -> l
ann ast SrcSpanInfo
from) (ast SrcSpanInfo -> String
forall a. Pretty a => a -> String
f ast SrcSpanInfo
from) (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Pretty a => a -> String
f a
to) []
where f :: a -> String
f = String -> String
trimStart (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Pretty a => a -> String
prettyPrint
idea' :: (GHC.HasSrcSpan a, Outputable.Outputable a, GHC.HasSrcSpan b, Outputable.Outputable b) =>
Severity -> String -> a -> b -> [Refactoring R.SrcSpan] -> Idea
idea' :: Severity -> String -> a -> b -> [Refactoring SrcSpan] -> Idea
idea' severity :: Severity
severity hint :: String
hint from :: a
from to :: b
to =
Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
rawIdea Severity
severity String
hint (SrcSpan -> SrcSpan
ghcSpanToHSE (a -> SrcSpan
forall a. HasSrcSpan a => a -> SrcSpan
GHC.getLoc a
from)) (a -> String
forall a. Outputable a => a -> String
GHC.unsafePrettyPrint a
from) (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ b -> String
forall a. Outputable a => a -> String
GHC.unsafePrettyPrint b
to) []
suggest :: (Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
String -> ast SrcSpanInfo -> a -> [Refactoring R.SrcSpan] -> Idea
suggest :: String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
suggest = Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
forall (ast :: * -> *) a.
(Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
idea Severity
Suggestion
suggest' :: (GHC.HasSrcSpan a, Outputable.Outputable a, GHC.HasSrcSpan b, Outputable.Outputable b) =>
String -> a -> b -> [Refactoring R.SrcSpan] -> Idea
suggest' :: String -> a -> b -> [Refactoring SrcSpan] -> Idea
suggest' = Severity -> String -> a -> b -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
Severity -> String -> a -> b -> [Refactoring SrcSpan] -> Idea
idea' Severity
Suggestion
warn :: (Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
String -> ast SrcSpanInfo -> a -> [Refactoring R.SrcSpan] -> Idea
warn :: String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
warn = Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
forall (ast :: * -> *) a.
(Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
idea Severity
Warning
warn' :: (GHC.HasSrcSpan a, Outputable.Outputable a, GHC.HasSrcSpan b, Outputable.Outputable b) =>
String -> a -> b -> [Refactoring R.SrcSpan] -> Idea
warn' :: String -> a -> b -> [Refactoring SrcSpan] -> Idea
warn' = Severity -> String -> a -> b -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
Severity -> String -> a -> b -> [Refactoring SrcSpan] -> Idea
idea' Severity
Warning
ignoreNoSuggestion' :: (GHC.HasSrcSpan a, Outputable.Outputable a)
=> String -> a -> Idea
ignoreNoSuggestion' :: String -> a -> Idea
ignoreNoSuggestion' hint :: String
hint x :: a
x = Severity
-> String -> SrcSpan -> String -> Maybe String -> [Note] -> Idea
rawIdeaN Severity
Ignore String
hint (SrcSpan -> SrcSpan
ghcSpanToHSE (a -> SrcSpan
forall a. HasSrcSpan a => a -> SrcSpan
GHC.getLoc a
x)) (a -> String
forall a. Outputable a => a -> String
GHC.unsafePrettyPrint a
x) Maybe String
forall a. Maybe a
Nothing []
ignore :: (Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
String -> ast SrcSpanInfo -> a -> [Refactoring R.SrcSpan] -> Idea
ignore :: String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
ignore = Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
forall (ast :: * -> *) a.
(Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
idea Severity
Ignore
ignore' :: (GHC.HasSrcSpan a, Outputable.Outputable a) =>
String -> a -> a -> [Refactoring R.SrcSpan] -> Idea
ignore' :: String -> a -> a -> [Refactoring SrcSpan] -> Idea
ignore' = Severity -> String -> a -> a -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
Severity -> String -> a -> b -> [Refactoring SrcSpan] -> Idea
idea' Severity
Ignore
ideaN :: (Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
Severity -> String -> ast SrcSpanInfo -> a -> Idea
ideaN :: Severity -> String -> ast SrcSpanInfo -> a -> Idea
ideaN severity :: Severity
severity hint :: String
hint from :: ast SrcSpanInfo
from to :: a
to = Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
forall (ast :: * -> *) a.
(Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
Severity
-> String -> ast SrcSpanInfo -> a -> [Refactoring SrcSpan] -> Idea
idea Severity
severity String
hint ast SrcSpanInfo
from a
to []
ideaN' :: (GHC.HasSrcSpan a, Outputable.Outputable a) =>
Severity -> String -> a -> a -> Idea
ideaN' :: Severity -> String -> a -> a -> Idea
ideaN' severity :: Severity
severity hint :: String
hint from :: a
from to :: a
to = Severity -> String -> a -> a -> [Refactoring SrcSpan] -> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
Severity -> String -> a -> b -> [Refactoring SrcSpan] -> Idea
idea' Severity
severity String
hint a
from a
to []
suggestN :: (Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
String -> ast SrcSpanInfo -> a -> Idea
suggestN :: String -> ast SrcSpanInfo -> a -> Idea
suggestN = Severity -> String -> ast SrcSpanInfo -> a -> Idea
forall (ast :: * -> *) a.
(Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
Severity -> String -> ast SrcSpanInfo -> a -> Idea
ideaN Severity
Suggestion
suggestN' :: (GHC.HasSrcSpan a, Outputable.Outputable a) =>
String -> a -> a -> Idea
suggestN' :: String -> a -> a -> Idea
suggestN' = Severity -> String -> a -> a -> Idea
forall a.
(HasSrcSpan a, Outputable a) =>
Severity -> String -> a -> a -> Idea
ideaN' Severity
Suggestion
ignoreN :: (Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
String -> ast SrcSpanInfo -> a -> Idea
ignoreN :: String -> ast SrcSpanInfo -> a -> Idea
ignoreN = Severity -> String -> ast SrcSpanInfo -> a -> Idea
forall (ast :: * -> *) a.
(Annotated ast, Pretty a, Pretty (ast SrcSpanInfo)) =>
Severity -> String -> ast SrcSpanInfo -> a -> Idea
ideaN Severity
Ignore
ignoreN' :: (GHC.HasSrcSpan a, Outputable.Outputable a) =>
String -> a -> a -> Idea
ignoreN' :: String -> a -> a -> Idea
ignoreN' = Severity -> String -> a -> a -> Idea
forall a.
(HasSrcSpan a, Outputable a) =>
Severity -> String -> a -> a -> Idea
ideaN' Severity
Ignore