{-# LANGUAGE PatternGuards, ScopedTypeVariables, RecordWildCards #-}
module Hint.Import(importHint) where
import Hint.Type(ModuHint,ModuleEx(..),Idea(..),Severity(..),suggest',toSS',rawIdea',rawIdeaN')
import Refact.Types hiding (ModuleName)
import qualified Refact.Types as R
import Data.Tuple.Extra
import Data.List.Extra
import Data.Generics.Uniplate.Operations
import Data.Maybe
import Control.Applicative
import Prelude
import FastString
import BasicTypes
import RdrName
import Module
import HsSyn
import SrcLoc
import GHC.Util
importHint :: ModuHint
importHint :: ModuHint
importHint _ ModuleEx {ghcModule :: ModuleEx -> Located (HsModule GhcPs)
ghcModule=L _ HsModule{hsmodImports :: forall pass. HsModule pass -> [LImportDecl pass]
hsmodImports=[LImportDecl GhcPs]
ms}} =
(((ModuleName, Maybe String), [LImportDecl GhcPs]) -> [Idea])
-> [((ModuleName, Maybe String), [LImportDecl GhcPs])] -> [Idea]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([LImportDecl GhcPs] -> [Idea]
reduceImports ([LImportDecl GhcPs] -> [Idea])
-> (((ModuleName, Maybe String), [LImportDecl GhcPs])
-> [LImportDecl GhcPs])
-> ((ModuleName, Maybe String), [LImportDecl GhcPs])
-> [Idea]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ModuleName, Maybe String), [LImportDecl GhcPs])
-> [LImportDecl GhcPs]
forall a b. (a, b) -> b
snd) (
[((ModuleName, Maybe String), LImportDecl GhcPs)]
-> [((ModuleName, Maybe String), [LImportDecl GhcPs])]
forall k v. Ord k => [(k, v)] -> [(k, [v])]
groupSort [((ModuleName
n, Maybe String
pkg), LImportDecl GhcPs
i) | LImportDecl GhcPs
i <- [LImportDecl GhcPs]
ms
, Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ ImportDecl GhcPs -> Bool
forall pass. ImportDecl pass -> Bool
ideclSource (LImportDecl GhcPs -> SrcSpanLess (LImportDecl GhcPs)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc LImportDecl GhcPs
i)
, let i' :: SrcSpanLess (LImportDecl GhcPs)
i' = LImportDecl GhcPs -> SrcSpanLess (LImportDecl GhcPs)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc LImportDecl GhcPs
i
, let n :: SrcSpanLess (Located ModuleName)
n = Located ModuleName -> SrcSpanLess (Located ModuleName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc (Located ModuleName -> SrcSpanLess (Located ModuleName))
-> Located ModuleName -> SrcSpanLess (Located ModuleName)
forall a b. (a -> b) -> a -> b
$ ImportDecl GhcPs -> Located ModuleName
forall pass. ImportDecl pass -> Located ModuleName
ideclName ImportDecl GhcPs
i'
, let pkg :: Maybe String
pkg = FastString -> String
unpackFS (FastString -> String)
-> (StringLiteral -> FastString) -> StringLiteral -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. StringLiteral -> FastString
sl_fs (StringLiteral -> String) -> Maybe StringLiteral -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ImportDecl GhcPs -> Maybe StringLiteral
forall pass. ImportDecl pass -> Maybe StringLiteral
ideclPkgQual ImportDecl GhcPs
i']) [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++
(LImportDecl GhcPs -> [Idea]) -> [LImportDecl GhcPs] -> [Idea]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap LImportDecl GhcPs -> [Idea]
stripRedundantAlias [LImportDecl GhcPs]
ms [Idea] -> [Idea] -> [Idea]
forall a. [a] -> [a] -> [a]
++
(LImportDecl GhcPs -> [Idea]) -> [LImportDecl GhcPs] -> [Idea]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap LImportDecl GhcPs -> [Idea]
preferHierarchicalImports [LImportDecl GhcPs]
ms
reduceImports :: [LImportDecl GhcPs] -> [Idea]
reduceImports :: [LImportDecl GhcPs] -> [Idea]
reduceImports [] = []
reduceImports ms :: [LImportDecl GhcPs]
ms@(m :: LImportDecl GhcPs
m:_) =
[Severity
-> String
-> SrcSpan
-> String
-> Maybe String
-> [Note]
-> [Refactoring SrcSpan]
-> Idea
rawIdea' Severity
Hint.Type.Warning "Use fewer imports" (LImportDecl GhcPs -> SrcSpan
forall a. HasSrcSpan a => a -> SrcSpan
getLoc LImportDecl GhcPs
m) ([LImportDecl GhcPs] -> String
f [LImportDecl GhcPs]
ms) (String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ [LImportDecl GhcPs] -> String
f [LImportDecl GhcPs]
x) [] [Refactoring SrcSpan]
rs
| Just (x :: [LImportDecl GhcPs]
x, rs :: [Refactoring SrcSpan]
rs) <- [[LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
simplify [LImportDecl GhcPs]
ms]]
where f :: [LImportDecl GhcPs] -> String
f = [String] -> String
unlines ([String] -> String)
-> ([LImportDecl GhcPs] -> [String])
-> [LImportDecl GhcPs]
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (LImportDecl GhcPs -> String) -> [LImportDecl GhcPs] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map LImportDecl GhcPs -> String
forall a. Outputable a => a -> String
unsafePrettyPrint
simplify :: [LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring R.SrcSpan])
simplify :: [LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
simplify [] = Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall a. Maybe a
Nothing
simplify (x :: LImportDecl GhcPs
x : xs :: [LImportDecl GhcPs]
xs) = case LImportDecl GhcPs
-> [LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
simplifyHead LImportDecl GhcPs
x [LImportDecl GhcPs]
xs of
Nothing -> ([LImportDecl GhcPs] -> [LImportDecl GhcPs])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall a a' b. (a -> a') -> (a, b) -> (a', b)
first (LImportDecl GhcPs
xLImportDecl GhcPs -> [LImportDecl GhcPs] -> [LImportDecl GhcPs]
forall a. a -> [a] -> [a]
:) (([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan]))
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
simplify [LImportDecl GhcPs]
xs
Just (xs :: [LImportDecl GhcPs]
xs, rs :: [Refactoring SrcSpan]
rs) -> ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall a. a -> Maybe a
Just (([LImportDecl GhcPs], [Refactoring SrcSpan])
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan]))
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall a b. (a -> b) -> a -> b
$ ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> (([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan]))
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([LImportDecl GhcPs]
xs, [Refactoring SrcSpan]
rs) (([Refactoring SrcSpan] -> [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall b b' a. (b -> b') -> (a, b) -> (a, b')
second ([Refactoring SrcSpan]
-> [Refactoring SrcSpan] -> [Refactoring SrcSpan]
forall a. [a] -> [a] -> [a]
++ [Refactoring SrcSpan]
rs)) (Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan]))
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall a b. (a -> b) -> a -> b
$ [LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
simplify [LImportDecl GhcPs]
xs
simplifyHead :: LImportDecl GhcPs
-> [LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring R.SrcSpan])
simplifyHead :: LImportDecl GhcPs
-> [LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
simplifyHead x :: LImportDecl GhcPs
x (y :: LImportDecl GhcPs
y : ys :: [LImportDecl GhcPs]
ys) = case LImportDecl GhcPs
-> LImportDecl GhcPs
-> Maybe (LImportDecl GhcPs, [Refactoring SrcSpan])
combine LImportDecl GhcPs
x LImportDecl GhcPs
y of
Nothing -> ([LImportDecl GhcPs] -> [LImportDecl GhcPs])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall a a' b. (a -> a') -> (a, b) -> (a', b)
first (LImportDecl GhcPs
yLImportDecl GhcPs -> [LImportDecl GhcPs] -> [LImportDecl GhcPs]
forall a. a -> [a] -> [a]
:) (([LImportDecl GhcPs], [Refactoring SrcSpan])
-> ([LImportDecl GhcPs], [Refactoring SrcSpan]))
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> LImportDecl GhcPs
-> [LImportDecl GhcPs]
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
simplifyHead LImportDecl GhcPs
x [LImportDecl GhcPs]
ys
Just (xy :: LImportDecl GhcPs
xy, rs :: [Refactoring SrcSpan]
rs) -> ([LImportDecl GhcPs], [Refactoring SrcSpan])
-> Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall a. a -> Maybe a
Just (LImportDecl GhcPs
xy LImportDecl GhcPs -> [LImportDecl GhcPs] -> [LImportDecl GhcPs]
forall a. a -> [a] -> [a]
: [LImportDecl GhcPs]
ys, [Refactoring SrcSpan]
rs)
simplifyHead x :: LImportDecl GhcPs
x [] = Maybe ([LImportDecl GhcPs], [Refactoring SrcSpan])
forall a. Maybe a
Nothing
combine :: LImportDecl GhcPs
-> LImportDecl GhcPs
-> Maybe (LImportDecl GhcPs, [Refactoring R.SrcSpan])
combine :: LImportDecl GhcPs
-> LImportDecl GhcPs
-> Maybe (LImportDecl GhcPs, [Refactoring SrcSpan])
combine x :: LImportDecl GhcPs
x@(LL _ x' :: SrcSpanLess (LImportDecl GhcPs)
x') y :: LImportDecl GhcPs
y@(LL _ y' :: SrcSpanLess (LImportDecl GhcPs)
y')
| Bool
qual, Bool
as, Bool
specs = (LImportDecl GhcPs, [Refactoring SrcSpan])
-> Maybe (LImportDecl GhcPs, [Refactoring SrcSpan])
forall a. a -> Maybe a
Just (LImportDecl GhcPs
x, [RType -> SrcSpan -> Refactoring SrcSpan
forall a. RType -> a -> Refactoring a
Delete RType
Import (LImportDecl GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LImportDecl GhcPs
y)])
| Bool
qual, Bool
as
, Just (False, xs :: Located [LIE GhcPs]
xs) <- ImportDecl GhcPs -> Maybe (Bool, Located [LIE GhcPs])
forall pass. ImportDecl pass -> Maybe (Bool, Located [LIE pass])
ideclHiding SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x'
, Just (False, ys :: Located [LIE GhcPs]
ys) <- ImportDecl GhcPs -> Maybe (Bool, Located [LIE GhcPs])
forall pass. ImportDecl pass -> Maybe (Bool, Located [LIE pass])
ideclHiding SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
y' =
let newImp :: LImportDecl GhcPs
newImp = SrcSpanLess (LImportDecl GhcPs) -> LImportDecl GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x'{ideclHiding :: Maybe (Bool, Located [LIE GhcPs])
ideclHiding = (Bool, Located [LIE GhcPs]) -> Maybe (Bool, Located [LIE GhcPs])
forall a. a -> Maybe a
Just (Bool
False, SrcSpanLess (Located [LIE GhcPs]) -> Located [LIE GhcPs]
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (Located [LIE GhcPs] -> SrcSpanLess (Located [LIE GhcPs])
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located [LIE GhcPs]
xs [LIE GhcPs] -> [LIE GhcPs] -> [LIE GhcPs]
forall a. [a] -> [a] -> [a]
++ Located [LIE GhcPs] -> SrcSpanLess (Located [LIE GhcPs])
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located [LIE GhcPs]
ys))}
in (LImportDecl GhcPs, [Refactoring SrcSpan])
-> Maybe (LImportDecl GhcPs, [Refactoring SrcSpan])
forall a. a -> Maybe a
Just (LImportDecl GhcPs
newImp, [RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
Import (LImportDecl GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LImportDecl GhcPs
x) [] (ImportDecl GhcPs -> String
forall a. Outputable a => a -> String
unsafePrettyPrint (LImportDecl GhcPs -> SrcSpanLess (LImportDecl GhcPs)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc LImportDecl GhcPs
newImp))
, RType -> SrcSpan -> Refactoring SrcSpan
forall a. RType -> a -> Refactoring a
Delete RType
Import (LImportDecl GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LImportDecl GhcPs
y)])
| Bool
qual, Bool
as, Maybe (Bool, Located [LIE GhcPs]) -> Bool
forall a. Maybe a -> Bool
isNothing (ImportDecl GhcPs -> Maybe (Bool, Located [LIE GhcPs])
forall pass. ImportDecl pass -> Maybe (Bool, Located [LIE pass])
ideclHiding SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x') Bool -> Bool -> Bool
|| Maybe (Bool, Located [LIE GhcPs]) -> Bool
forall a. Maybe a -> Bool
isNothing (ImportDecl GhcPs -> Maybe (Bool, Located [LIE GhcPs])
forall pass. ImportDecl pass -> Maybe (Bool, Located [LIE pass])
ideclHiding SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
y') =
let (newImp :: LImportDecl GhcPs
newImp, toDelete :: LImportDecl GhcPs
toDelete) = if Maybe (Bool, Located [LIE GhcPs]) -> Bool
forall a. Maybe a -> Bool
isNothing (ImportDecl GhcPs -> Maybe (Bool, Located [LIE GhcPs])
forall pass. ImportDecl pass -> Maybe (Bool, Located [LIE pass])
ideclHiding SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x') then (LImportDecl GhcPs
x, LImportDecl GhcPs
y) else (LImportDecl GhcPs
y, LImportDecl GhcPs
x)
in (LImportDecl GhcPs, [Refactoring SrcSpan])
-> Maybe (LImportDecl GhcPs, [Refactoring SrcSpan])
forall a. a -> Maybe a
Just (LImportDecl GhcPs
newImp, [RType -> SrcSpan -> Refactoring SrcSpan
forall a. RType -> a -> Refactoring a
Delete RType
Import (LImportDecl GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LImportDecl GhcPs
toDelete)])
| Bool -> Bool
not (ImportDecl GhcPs -> Bool
forall pass. ImportDecl pass -> Bool
ideclQualified SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x'), Bool
qual, Bool
specs, [Located ModuleName] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Located ModuleName]
ass Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 1 =
let (newImp :: LImportDecl GhcPs
newImp, toDelete :: LImportDecl GhcPs
toDelete) = if Maybe (Located ModuleName) -> Bool
forall a. Maybe a -> Bool
isJust (ImportDecl GhcPs -> Maybe (Located ModuleName)
forall pass. ImportDecl pass -> Maybe (Located ModuleName)
ideclAs SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x') then (LImportDecl GhcPs
x, LImportDecl GhcPs
y) else (LImportDecl GhcPs
y, LImportDecl GhcPs
x)
in (LImportDecl GhcPs, [Refactoring SrcSpan])
-> Maybe (LImportDecl GhcPs, [Refactoring SrcSpan])
forall a. a -> Maybe a
Just (LImportDecl GhcPs
newImp, [RType -> SrcSpan -> Refactoring SrcSpan
forall a. RType -> a -> Refactoring a
Delete RType
Import (LImportDecl GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LImportDecl GhcPs
toDelete)])
| Bool
otherwise = Maybe (LImportDecl GhcPs, [Refactoring SrcSpan])
forall a. Maybe a
Nothing
where
eqMaybe:: Eq a => Maybe (Located a) -> Maybe (Located a) -> Bool
eqMaybe :: Maybe (Located a) -> Maybe (Located a) -> Bool
eqMaybe (Just x :: Located a
x) (Just y :: Located a
y) = Located a
x Located a -> Located a -> Bool
forall a. (HasSrcSpan a, Eq (SrcSpanLess a)) => a -> a -> Bool
`eqLocated` Located a
y
eqMaybe Nothing Nothing = Bool
True
eqMaybe _ _ = Bool
False
qual :: Bool
qual = ImportDecl GhcPs -> Bool
forall pass. ImportDecl pass -> Bool
ideclQualified SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x' Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== ImportDecl GhcPs -> Bool
forall pass. ImportDecl pass -> Bool
ideclQualified SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
y'
as :: Bool
as = ImportDecl GhcPs -> Maybe (Located ModuleName)
forall pass. ImportDecl pass -> Maybe (Located ModuleName)
ideclAs SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x' Maybe (Located ModuleName) -> Maybe (Located ModuleName) -> Bool
forall a. Eq a => Maybe (Located a) -> Maybe (Located a) -> Bool
`eqMaybe` ImportDecl GhcPs -> Maybe (Located ModuleName)
forall pass. ImportDecl pass -> Maybe (Located ModuleName)
ideclAs SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
y'
ass :: [Located ModuleName]
ass = (ImportDecl GhcPs -> Maybe (Located ModuleName))
-> [ImportDecl GhcPs] -> [Located ModuleName]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ImportDecl GhcPs -> Maybe (Located ModuleName)
forall pass. ImportDecl pass -> Maybe (Located ModuleName)
ideclAs [SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x', SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
y']
specs :: Bool
specs = (SrcSpan -> SrcSpan)
-> Maybe (Bool, Located [LIE GhcPs])
-> Maybe (Bool, Located [LIE GhcPs])
forall from to. Biplate from to => (to -> to) -> from -> from
transformBi (SrcSpan -> SrcSpan -> SrcSpan
forall a b. a -> b -> a
const SrcSpan
noSrcSpan) (ImportDecl GhcPs -> Maybe (Bool, Located [LIE GhcPs])
forall pass. ImportDecl pass -> Maybe (Bool, Located [LIE pass])
ideclHiding SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
x') Maybe (Bool, Located [LIE GhcPs])
-> Maybe (Bool, Located [LIE GhcPs]) -> Bool
forall a. Eq a => a -> a -> Bool
==
(SrcSpan -> SrcSpan)
-> Maybe (Bool, Located [LIE GhcPs])
-> Maybe (Bool, Located [LIE GhcPs])
forall from to. Biplate from to => (to -> to) -> from -> from
transformBi (SrcSpan -> SrcSpan -> SrcSpan
forall a b. a -> b -> a
const SrcSpan
noSrcSpan) (ImportDecl GhcPs -> Maybe (Bool, Located [LIE GhcPs])
forall pass. ImportDecl pass -> Maybe (Bool, Located [LIE pass])
ideclHiding SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
y')
combine _ _ = Maybe (LImportDecl GhcPs, [Refactoring SrcSpan])
forall a. Maybe a
Nothing
stripRedundantAlias :: LImportDecl GhcPs -> [Idea]
stripRedundantAlias :: LImportDecl GhcPs -> [Idea]
stripRedundantAlias x :: LImportDecl GhcPs
x@(LL loc :: SrcSpan
loc i :: SrcSpanLess (LImportDecl GhcPs)
i@ImportDecl {..})
| ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just (Located ModuleName -> SrcSpanLess (Located ModuleName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located ModuleName
ideclName) Maybe ModuleName -> Maybe ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== (Located ModuleName -> ModuleName)
-> Maybe (Located ModuleName) -> Maybe ModuleName
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Located ModuleName -> ModuleName
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Maybe (Located ModuleName)
ideclAs =
[String
-> LImportDecl GhcPs
-> LImportDecl GhcPs
-> [Refactoring SrcSpan]
-> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
suggest' "Redundant as" LImportDecl GhcPs
x (SrcSpan -> SrcSpanLess (LImportDecl GhcPs) -> LImportDecl GhcPs
forall a. HasSrcSpan a => SrcSpan -> SrcSpanLess a -> a
cL SrcSpan
loc SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
i{ideclAs :: Maybe (Located ModuleName)
ideclAs=Maybe (Located ModuleName)
forall a. Maybe a
Nothing} :: LImportDecl GhcPs) [SrcSpan -> Refactoring SrcSpan
forall a. a -> Refactoring a
RemoveAsKeyword (LImportDecl GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LImportDecl GhcPs
x)]]
stripRedundantAlias _ = []
preferHierarchicalImports :: LImportDecl GhcPs -> [Idea]
preferHierarchicalImports :: LImportDecl GhcPs -> [Idea]
preferHierarchicalImports x :: LImportDecl GhcPs
x@(LL loc :: SrcSpan
loc i :: SrcSpanLess (LImportDecl GhcPs)
i@ImportDecl{ideclName=L _ n,ideclPkgQual=Nothing})
| ModuleName
n ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> ModuleName
mkModuleName "IO" Bool -> Bool -> Bool
&& Maybe (Bool, Located [LIE GhcPs]) -> Bool
forall a. Maybe a -> Bool
isNothing (ImportDecl GhcPs -> Maybe (Bool, Located [LIE GhcPs])
forall pass. ImportDecl pass -> Maybe (Bool, Located [LIE pass])
ideclHiding SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
i) =
[Severity
-> String -> SrcSpan -> String -> Maybe String -> [Note] -> Idea
rawIdeaN' Severity
Suggestion "Use hierarchical imports" SrcSpan
loc
(String -> String
trimStart (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ ImportDecl GhcPs -> String
forall a. Outputable a => a -> String
unsafePrettyPrint SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
i) (
String -> Maybe String
forall a. a -> Maybe a
Just (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (ImportDecl GhcPs -> String) -> [ImportDecl GhcPs] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String -> String
trimStart (String -> String)
-> (ImportDecl GhcPs -> String) -> ImportDecl GhcPs -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ImportDecl GhcPs -> String
forall a. Outputable a => a -> String
unsafePrettyPrint)
[ String -> Maybe (Bool, Located [LIE GhcPs]) -> ImportDecl GhcPs
f "System.IO" Maybe (Bool, Located [LIE GhcPs])
forall a. Maybe a
Nothing, String -> Maybe (Bool, Located [LIE GhcPs]) -> ImportDecl GhcPs
f "System.IO.Error" Maybe (Bool, Located [LIE GhcPs])
forall a. Maybe a
Nothing
, String -> Maybe (Bool, Located [LIE GhcPs]) -> ImportDecl GhcPs
f "Control.Exception" (Maybe (Bool, Located [LIE GhcPs]) -> ImportDecl GhcPs)
-> Maybe (Bool, Located [LIE GhcPs]) -> ImportDecl GhcPs
forall a b. (a -> b) -> a -> b
$ (Bool, Located [LIE GhcPs]) -> Maybe (Bool, Located [LIE GhcPs])
forall a. a -> Maybe a
Just (Bool
False, SrcSpanLess (Located [LIE GhcPs]) -> Located [LIE GhcPs]
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc [String -> LIE GhcPs
mkLIE String
x | String
x <- ["bracket","bracket_"]])]) []]
| Just y :: String
y <- String -> [(String, String)] -> Maybe String
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (ModuleName -> String
moduleNameString ModuleName
n) [(String, String)]
newNames =
let newModuleName :: String
newModuleName = String
y String -> String -> String
forall a. [a] -> [a] -> [a]
++ "." String -> String -> String
forall a. [a] -> [a] -> [a]
++ ModuleName -> String
moduleNameString ModuleName
n
r :: [Refactoring SrcSpan]
r = [RType
-> SrcSpan -> [(String, SrcSpan)] -> String -> Refactoring SrcSpan
forall a. RType -> a -> [(String, a)] -> String -> Refactoring a
Replace RType
R.ModuleName (LImportDecl GhcPs -> SrcSpan
forall e. HasSrcSpan e => e -> SrcSpan
toSS' LImportDecl GhcPs
x) [] String
newModuleName] in
[String
-> LImportDecl GhcPs
-> LImportDecl GhcPs
-> [Refactoring SrcSpan]
-> Idea
forall a b.
(HasSrcSpan a, Outputable a, HasSrcSpan b, Outputable b) =>
String -> a -> b -> [Refactoring SrcSpan] -> Idea
suggest' "Use hierarchical imports"
LImportDecl GhcPs
x (SrcSpanLess (LImportDecl GhcPs) -> LImportDecl GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (ImportDecl GhcPs -> ImportDecl GhcPs
desugarQual SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
i){ideclName :: Located ModuleName
ideclName=SrcSpanLess (Located ModuleName) -> Located ModuleName
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (String -> ModuleName
mkModuleName String
newModuleName)} :: LImportDecl GhcPs) [Refactoring SrcSpan]
r]
where
f :: String -> Maybe (Bool, Located [LIE GhcPs]) -> ImportDecl GhcPs
f a :: String
a b :: Maybe (Bool, Located [LIE GhcPs])
b = (ImportDecl GhcPs -> ImportDecl GhcPs
desugarQual SrcSpanLess (LImportDecl GhcPs)
ImportDecl GhcPs
i){ideclName :: Located ModuleName
ideclName=SrcSpanLess (Located ModuleName) -> Located ModuleName
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (String -> ModuleName
mkModuleName String
a), ideclHiding :: Maybe (Bool, Located [LIE GhcPs])
ideclHiding=Maybe (Bool, Located [LIE GhcPs])
b}
mkLIE :: String -> LIE GhcPs
mkLIE :: String -> LIE GhcPs
mkLIE n :: String
n = SrcSpanLess (LIE GhcPs) -> LIE GhcPs
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (SrcSpanLess (LIE GhcPs) -> LIE GhcPs)
-> SrcSpanLess (LIE GhcPs) -> LIE GhcPs
forall a b. (a -> b) -> a -> b
$ XIEVar GhcPs -> LIEWrappedName (IdP GhcPs) -> IE GhcPs
forall pass. XIEVar pass -> LIEWrappedName (IdP pass) -> IE pass
IEVar NoExt
XIEVar GhcPs
noExt (SrcSpanLess (LIEWrappedName RdrName) -> LIEWrappedName RdrName
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (Located RdrName -> IEWrappedName RdrName
forall name. Located name -> IEWrappedName name
IEName (SrcSpanLess (Located RdrName) -> Located RdrName
forall a. HasSrcSpan a => SrcSpanLess a -> a
noLoc (FastString -> RdrName
mkVarUnqual (String -> FastString
fsLit String
n)))))
desugarQual :: ImportDecl GhcPs -> ImportDecl GhcPs
desugarQual :: ImportDecl GhcPs -> ImportDecl GhcPs
desugarQual i :: ImportDecl GhcPs
i
| ImportDecl GhcPs -> Bool
forall pass. ImportDecl pass -> Bool
ideclQualified ImportDecl GhcPs
i Bool -> Bool -> Bool
&& Maybe (Located ModuleName) -> Bool
forall a. Maybe a -> Bool
isNothing (ImportDecl GhcPs -> Maybe (Located ModuleName)
forall pass. ImportDecl pass -> Maybe (Located ModuleName)
ideclAs ImportDecl GhcPs
i) = ImportDecl GhcPs
i{ideclAs :: Maybe (Located ModuleName)
ideclAs = Located ModuleName -> Maybe (Located ModuleName)
forall a. a -> Maybe a
Just (ImportDecl GhcPs -> Located ModuleName
forall pass. ImportDecl pass -> Located ModuleName
ideclName ImportDecl GhcPs
i)}
| Bool
otherwise = ImportDecl GhcPs
i
preferHierarchicalImports _ = []
newNames :: [(String, String)]
newNames :: [(String, String)]
newNames = let * :: b -> a -> (a, b)
(*) = (a -> b -> (a, b)) -> b -> a -> (a, b)
forall a b c. (a -> b -> c) -> b -> a -> c
flip (,) in
["Control" String -> String -> (String, String)
forall b a. b -> a -> (a, b)
* "Monad"
,"Data" String -> String -> (String, String)
forall b a. b -> a -> (a, b)
* "Char"
,"Data" String -> String -> (String, String)
forall b a. b -> a -> (a, b)
* "List"
,"Data" String -> String -> (String, String)
forall b a. b -> a -> (a, b)
* "Maybe"
,"Data" String -> String -> (String, String)
forall b a. b -> a -> (a, b)
* "Ratio"
,"System" String -> String -> (String, String)
forall b a. b -> a -> (a, b)
* "Directory"
]