{-# LANGUAGE ImportQualifiedPost #-}

{-
<TEST>
{- MISSING HASH #-} -- {-# MISSING HASH #-}
<COMMENT> {- INLINE X -}
{- INLINE Y -} -- {-# INLINE Y #-}
{- INLINE[~k] f -} -- {-# INLINE[~k] f #-}
{- NOINLINE Y -} -- {-# NOINLINE Y #-}
{- UNKNOWN Y -}
<COMMENT> INLINE X
</TEST>
-}


module Hint.Comment(commentHint) where

import Hint.Type
import Data.Char
import Data.List.Extra
import Refact.Types(Refactoring(ModifyComment))
import GHC.Types.SrcLoc
import GHC.Parser.Annotation
import GHC.Util
import GHC.Data.Strict qualified

directives :: [String]
directives :: [[Char]]
directives = [Char] -> [[Char]]
words ([Char] -> [[Char]]) -> [Char] -> [[Char]]
forall a b. (a -> b) -> a -> b
$
    [Char]
"LANGUAGE OPTIONS_GHC INCLUDE WARNING DEPRECATED MINIMAL INLINE NOINLINE INLINABLE " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++
    [Char]
"CONLIKE LINE SPECIALIZE SPECIALISE UNPACK NOUNPACK SOURCE"


commentHint :: ModuHint
commentHint :: ModuHint
commentHint Scope
_ ModuleEx
m = (LEpaComment -> [Idea]) -> [LEpaComment] -> [Idea]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap LEpaComment -> [Idea]
chk (ModuleEx -> [LEpaComment]
ghcComments ModuleEx
m)
    where
        chk :: LEpaComment -> [Idea]
        chk :: LEpaComment -> [Idea]
chk LEpaComment
comm
          | Bool
isMultiline, [Char]
"#" [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` [Char]
s Bool -> Bool -> Bool
&& Bool -> Bool
not ([Char]
"#" [Char] -> [Char] -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` [Char]
s) = [[Char] -> LEpaComment -> [Char] -> Idea
grab [Char]
"Fix pragma markup" LEpaComment
comm ([Char] -> Idea) -> [Char] -> Idea
forall a b. (a -> b) -> a -> b
$ Char
'#'Char -> [Char] -> [Char]
forall a. a -> [a] -> [a]
:[Char]
s]
          | Bool
isMultiline, [Char]
name [Char] -> [[Char]] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [[Char]]
directives = [[Char] -> LEpaComment -> [Char] -> Idea
grab [Char]
"Use pragma syntax" LEpaComment
comm ([Char] -> Idea) -> [Char] -> Idea
forall a b. (a -> b) -> a -> b
$ [Char]
"# " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
trim [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" #"]
               where
                 isMultiline :: Bool
isMultiline = LEpaComment -> Bool
isCommentMultiline LEpaComment
comm
                 s :: [Char]
s = LEpaComment -> [Char]
commentText LEpaComment
comm
                 name :: [Char]
name = (Char -> Bool) -> [Char] -> [Char]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (\Char
x -> Char -> Bool
isAlphaNum Char
x Bool -> Bool -> Bool
|| Char
x Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_') ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char]
trimStart [Char]
s
        chk LEpaComment
_ = []

        grab :: String -> LEpaComment -> String -> Idea
        grab :: [Char] -> LEpaComment -> [Char] -> Idea
grab [Char]
msg o :: LEpaComment
o@(L Anchor
pos EpaComment
_) [Char]
s2 =
          let s1 :: [Char]
s1 = LEpaComment -> [Char]
commentText LEpaComment
o
              loc :: SrcSpan
loc = RealSrcSpan -> Maybe BufSpan -> SrcSpan
RealSrcSpan (Anchor -> RealSrcSpan
anchor Anchor
pos) Maybe BufSpan
forall a. Maybe a
GHC.Data.Strict.Nothing
          in
          Severity
-> [Char]
-> SrcSpan
-> [Char]
-> Maybe [Char]
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
rawIdea Severity
Suggestion [Char]
msg SrcSpan
loc ([Char] -> [Char]
f [Char]
s1) ([Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char]
f [Char]
s2) [] (SrcSpan -> [Refactoring SrcSpan]
refact SrcSpan
loc)
            where f :: [Char] -> [Char]
f [Char]
s = if LEpaComment -> Bool
isCommentMultiline LEpaComment
o then [Char]
"{-" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"-}" else [Char]
"--" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
s
                  refact :: SrcSpan -> [Refactoring SrcSpan]
refact SrcSpan
loc = [SrcSpan -> [Char] -> Refactoring SrcSpan
forall a. a -> [Char] -> Refactoring a
ModifyComment (SrcSpan -> SrcSpan
toRefactSrcSpan SrcSpan
loc) ([Char] -> [Char]
f [Char]
s2)]