{-# LANGUAGE PatternSynonyms #-}
module GHC.Rename.Unbound
( mkUnboundName
, mkUnboundNameRdr
, isUnboundName
, reportUnboundName
, reportUnboundName'
, unknownNameSuggestions
, WhatLooking(..)
, WhereLooking(..)
, LookingFor(..)
, unboundName
, unboundNameX
, notInScopeErr
, nameSpacesRelated
)
where
import GHC.Prelude
import GHC.Driver.Session
import GHC.Driver.Ppr
import GHC.Tc.Errors.Types
import GHC.Tc.Utils.Monad
import GHC.Builtin.Names ( mkUnboundName, isUnboundName, getUnique)
import GHC.Utils.Misc
import GHC.Data.Maybe
import GHC.Data.FastString
import qualified GHC.LanguageExtensions as LangExt
import GHC.Types.Hint
( GhcHint (SuggestExtension, RemindFieldSelectorSuppressed, ImportSuggestion, SuggestSimilarNames)
, LanguageExtensionHint (SuggestSingleExtension)
, ImportSuggestion(..), SimilarName(..), HowInScope(..) )
import GHC.Types.SrcLoc as SrcLoc
import GHC.Types.Name
import GHC.Types.Name.Reader
import GHC.Types.Unique.DFM (udfmToList)
import GHC.Unit.Module
import GHC.Unit.Module.Imported
import GHC.Unit.Home.ModInfo
import GHC.Data.Bag
import GHC.Utils.Outputable (empty)
import Data.List (sortBy, partition, nub)
import Data.List.NonEmpty ( pattern (:|), NonEmpty )
import Data.Function ( on )
data WhatLooking = WL_Anything
| WL_Constructor
| WL_RecField
| WL_None
deriving WhatLooking -> WhatLooking -> Bool
(WhatLooking -> WhatLooking -> Bool)
-> (WhatLooking -> WhatLooking -> Bool) -> Eq WhatLooking
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: WhatLooking -> WhatLooking -> Bool
== :: WhatLooking -> WhatLooking -> Bool
$c/= :: WhatLooking -> WhatLooking -> Bool
/= :: WhatLooking -> WhatLooking -> Bool
Eq
data WhereLooking = WL_Anywhere
| WL_Global
| WL_LocalTop
| WL_LocalOnly
data LookingFor = LF { LookingFor -> WhatLooking
lf_which :: WhatLooking
, LookingFor -> WhereLooking
lf_where :: WhereLooking
}
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr :: RdrName -> Name
mkUnboundNameRdr RdrName
rdr = OccName -> Name
mkUnboundName (RdrName -> OccName
rdrNameOcc RdrName
rdr)
reportUnboundName' :: WhatLooking -> RdrName -> RnM Name
reportUnboundName' :: WhatLooking -> RdrName -> RnM Name
reportUnboundName' WhatLooking
what_look RdrName
rdr = LookingFor -> RdrName -> RnM Name
unboundName (WhatLooking -> WhereLooking -> LookingFor
LF WhatLooking
what_look WhereLooking
WL_Anywhere) RdrName
rdr
reportUnboundName :: RdrName -> RnM Name
reportUnboundName :: RdrName -> RnM Name
reportUnboundName = WhatLooking -> RdrName -> RnM Name
reportUnboundName' WhatLooking
WL_Anything
unboundName :: LookingFor -> RdrName -> RnM Name
unboundName :: LookingFor -> RdrName -> RnM Name
unboundName LookingFor
lf RdrName
rdr = LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameX LookingFor
lf RdrName
rdr []
unboundNameX :: LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameX :: LookingFor -> RdrName -> [GhcHint] -> RnM Name
unboundNameX LookingFor
looking_for RdrName
rdr_name [GhcHint]
hints
= do { DynFlags
dflags <- IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; let show_helpful_errors :: Bool
show_helpful_errors = GeneralFlag -> DynFlags -> Bool
gopt GeneralFlag
Opt_HelpfulErrors DynFlags
dflags
err :: NotInScopeError
err = WhereLooking -> RdrName -> NotInScopeError
notInScopeErr (LookingFor -> WhereLooking
lf_where LookingFor
looking_for) RdrName
rdr_name
; if Bool -> Bool
not Bool
show_helpful_errors
then TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ()
addErr (TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ())
-> TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ()
forall a b. (a -> b) -> a -> b
$ NotInScopeError
-> RdrName -> [ImportError] -> [GhcHint] -> TcRnMessage
TcRnNotInScope NotInScopeError
err RdrName
rdr_name [] [GhcHint]
hints
else do { LocalRdrEnv
local_env <- RnM LocalRdrEnv
getLocalRdrEnv
; GlobalRdrEnv
global_env <- TcRn GlobalRdrEnv
getGlobalRdrEnv
; ImportAvails
impInfo <- TcRn ImportAvails
getImports
; Module
currmod <- IOEnv (Env TcGblEnv TcLclEnv) Module
forall (m :: * -> *). HasModule m => m Module
getModule
; HomePackageTable
hpt <- TcRnIf TcGblEnv TcLclEnv HomePackageTable
forall gbl lcl. TcRnIf gbl lcl HomePackageTable
getHpt
; let ([ImportError]
imp_errs, [GhcHint]
suggs) =
LookingFor
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> ([ImportError], [GhcHint])
unknownNameSuggestions_ LookingFor
looking_for
DynFlags
dflags HomePackageTable
hpt Module
currmod GlobalRdrEnv
global_env LocalRdrEnv
local_env ImportAvails
impInfo
RdrName
rdr_name
; TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ()
addErr (TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ())
-> TcRnMessage -> IOEnv (Env TcGblEnv TcLclEnv) ()
forall a b. (a -> b) -> a -> b
$
NotInScopeError
-> RdrName -> [ImportError] -> [GhcHint] -> TcRnMessage
TcRnNotInScope NotInScopeError
err RdrName
rdr_name [ImportError]
imp_errs ([GhcHint]
hints [GhcHint] -> [GhcHint] -> [GhcHint]
forall a. [a] -> [a] -> [a]
++ [GhcHint]
suggs) }
; Name -> RnM Name
forall a. a -> IOEnv (Env TcGblEnv TcLclEnv) a
forall (m :: * -> *) a. Monad m => a -> m a
return (RdrName -> Name
mkUnboundNameRdr RdrName
rdr_name) }
notInScopeErr :: WhereLooking -> RdrName -> NotInScopeError
notInScopeErr :: WhereLooking -> RdrName -> NotInScopeError
notInScopeErr WhereLooking
where_look RdrName
rdr_name
| Just Name
name <- RdrName -> Maybe Name
isExact_maybe RdrName
rdr_name
= Name -> NotInScopeError
NoExactName Name
name
| WhereLooking
WL_LocalTop <- WhereLooking
where_look
= NotInScopeError
NoTopLevelBinding
| Bool
otherwise
= NotInScopeError
NotInScope
unknownNameSuggestions :: WhatLooking -> DynFlags
-> HomePackageTable -> Module
-> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails
-> RdrName -> ([ImportError], [GhcHint])
unknownNameSuggestions :: WhatLooking
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> ([ImportError], [GhcHint])
unknownNameSuggestions WhatLooking
what_look = LookingFor
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> ([ImportError], [GhcHint])
unknownNameSuggestions_ (WhatLooking -> WhereLooking -> LookingFor
LF WhatLooking
what_look WhereLooking
WL_Anywhere)
unknownNameSuggestions_ :: LookingFor -> DynFlags
-> HomePackageTable -> Module
-> GlobalRdrEnv -> LocalRdrEnv -> ImportAvails
-> RdrName -> ([ImportError], [GhcHint])
unknownNameSuggestions_ :: LookingFor
-> DynFlags
-> HomePackageTable
-> Module
-> GlobalRdrEnv
-> LocalRdrEnv
-> ImportAvails
-> RdrName
-> ([ImportError], [GhcHint])
unknownNameSuggestions_ LookingFor
looking_for DynFlags
dflags HomePackageTable
hpt Module
curr_mod GlobalRdrEnv
global_env LocalRdrEnv
local_env
ImportAvails
imports RdrName
tried_rdr_name = ([ImportError]
imp_errs, [GhcHint]
suggs)
where
suggs :: [GhcHint]
suggs = [[GhcHint]] -> [GhcHint]
forall a. Monoid a => [a] -> a
mconcat
[ (NonEmpty SimilarName -> GhcHint) -> [SimilarName] -> [GhcHint]
forall a b. (NonEmpty a -> b) -> [a] -> [b]
if_ne (RdrName -> NonEmpty SimilarName -> GhcHint
SuggestSimilarNames RdrName
tried_rdr_name) ([SimilarName] -> [GhcHint]) -> [SimilarName] -> [GhcHint]
forall a b. (a -> b) -> a -> b
$
LookingFor
-> DynFlags
-> GlobalRdrEnv
-> LocalRdrEnv
-> RdrName
-> [SimilarName]
similarNameSuggestions LookingFor
looking_for DynFlags
dflags GlobalRdrEnv
global_env LocalRdrEnv
local_env RdrName
tried_rdr_name
, (ImportSuggestion -> GhcHint) -> [ImportSuggestion] -> [GhcHint]
forall a b. (a -> b) -> [a] -> [b]
map ImportSuggestion -> GhcHint
ImportSuggestion [ImportSuggestion]
imp_suggs
, RdrName -> [GhcHint]
extensionSuggestions RdrName
tried_rdr_name
, GlobalRdrEnv -> RdrName -> [GhcHint]
fieldSelectorSuggestions GlobalRdrEnv
global_env RdrName
tried_rdr_name ]
([ImportError]
imp_errs, [ImportSuggestion]
imp_suggs) = LookingFor
-> GlobalRdrEnv
-> HomePackageTable
-> Module
-> ImportAvails
-> RdrName
-> ([ImportError], [ImportSuggestion])
importSuggestions LookingFor
looking_for GlobalRdrEnv
global_env HomePackageTable
hpt Module
curr_mod ImportAvails
imports RdrName
tried_rdr_name
if_ne :: (NonEmpty a -> b) -> [a] -> [b]
if_ne :: forall a b. (NonEmpty a -> b) -> [a] -> [b]
if_ne NonEmpty a -> b
_ [] = []
if_ne NonEmpty a -> b
f (a
a : [a]
as) = [NonEmpty a -> b
f (a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
:| [a]
as)]
fieldSelectorSuggestions :: GlobalRdrEnv -> RdrName -> [GhcHint]
fieldSelectorSuggestions :: GlobalRdrEnv -> RdrName -> [GhcHint]
fieldSelectorSuggestions GlobalRdrEnv
global_env RdrName
tried_rdr_name
| [GlobalRdrElt] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [GlobalRdrElt]
gres = []
| Bool
otherwise = [RdrName -> [Name] -> GhcHint
RemindFieldSelectorSuppressed RdrName
tried_rdr_name [Name]
parents]
where
gres :: [GlobalRdrElt]
gres = (GlobalRdrElt -> Bool) -> [GlobalRdrElt] -> [GlobalRdrElt]
forall a. (a -> Bool) -> [a] -> [a]
filter GlobalRdrElt -> Bool
isNoFieldSelectorGRE ([GlobalRdrElt] -> [GlobalRdrElt])
-> [GlobalRdrElt] -> [GlobalRdrElt]
forall a b. (a -> b) -> a -> b
$
RdrName -> GlobalRdrEnv -> [GlobalRdrElt]
lookupGRE_RdrName' RdrName
tried_rdr_name GlobalRdrEnv
global_env
parents :: [Name]
parents = [ Name
parent | ParentIs Name
parent <- (GlobalRdrElt -> Parent) -> [GlobalRdrElt] -> [Parent]
forall a b. (a -> b) -> [a] -> [b]
map GlobalRdrElt -> Parent
gre_par [GlobalRdrElt]
gres ]
similarNameSuggestions :: LookingFor -> DynFlags
-> GlobalRdrEnv -> LocalRdrEnv
-> RdrName -> [SimilarName]
similarNameSuggestions :: LookingFor
-> DynFlags
-> GlobalRdrEnv
-> LocalRdrEnv
-> RdrName
-> [SimilarName]
similarNameSuggestions looking_for :: LookingFor
looking_for@(LF WhatLooking
what_look WhereLooking
where_look) DynFlags
dflags GlobalRdrEnv
global_env
LocalRdrEnv
local_env RdrName
tried_rdr_name
= String -> [(String, SimilarName)] -> [SimilarName]
forall a. String -> [(String, a)] -> [a]
fuzzyLookup (DynFlags -> RdrName -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
tried_rdr_name) [(String, SimilarName)]
all_possibilities
where
all_possibilities :: [(String, SimilarName)]
all_possibilities :: [(String, SimilarName)]
all_possibilities = case WhatLooking
what_look of
WhatLooking
WL_None -> []
WhatLooking
_ -> [ (DynFlags -> RdrName -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
r, RdrName -> HowInScope -> SimilarName
SimilarRdrName RdrName
r (SrcSpan -> HowInScope
LocallyBoundAt SrcSpan
loc))
| (RdrName
r,SrcSpan
loc) <- LocalRdrEnv -> [(RdrName, SrcSpan)]
local_possibilities LocalRdrEnv
local_env ]
[(String, SimilarName)]
-> [(String, SimilarName)] -> [(String, SimilarName)]
forall a. [a] -> [a] -> [a]
++ [ (DynFlags -> RdrName -> String
forall a. Outputable a => DynFlags -> a -> String
showPpr DynFlags
dflags RdrName
r, SimilarName
rp) | (RdrName
r, SimilarName
rp) <- GlobalRdrEnv -> [(RdrName, SimilarName)]
global_possibilities GlobalRdrEnv
global_env ]
tried_occ :: OccName
tried_occ = RdrName -> OccName
rdrNameOcc RdrName
tried_rdr_name
tried_is_sym :: Bool
tried_is_sym = OccName -> Bool
isSymOcc OccName
tried_occ
tried_ns :: NameSpace
tried_ns = OccName -> NameSpace
occNameSpace OccName
tried_occ
tried_is_qual :: Bool
tried_is_qual = RdrName -> Bool
isQual RdrName
tried_rdr_name
correct_name_space :: OccName -> Bool
correct_name_space OccName
occ =
(DynFlags -> WhatLooking -> NameSpace -> NameSpace -> Bool
nameSpacesRelated DynFlags
dflags WhatLooking
what_look NameSpace
tried_ns (OccName -> NameSpace
occNameSpace OccName
occ))
Bool -> Bool -> Bool
&& OccName -> Bool
isSymOcc OccName
occ Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
tried_is_sym
local_ok :: Bool
local_ok = case WhereLooking
where_look of { WhereLooking
WL_Anywhere -> Bool
True
; WhereLooking
WL_LocalOnly -> Bool
True
; WhereLooking
_ -> Bool
False }
local_possibilities :: LocalRdrEnv -> [(RdrName, SrcSpan)]
local_possibilities :: LocalRdrEnv -> [(RdrName, SrcSpan)]
local_possibilities LocalRdrEnv
env
| Bool
tried_is_qual = []
| Bool -> Bool
not Bool
local_ok = []
| Bool
otherwise = [ (OccName -> RdrName
mkRdrUnqual OccName
occ, Name -> SrcSpan
nameSrcSpan Name
name)
| Name
name <- LocalRdrEnv -> [Name]
localRdrEnvElts LocalRdrEnv
env
, let occ :: OccName
occ = Name -> OccName
nameOccName Name
name
, OccName -> Bool
correct_name_space OccName
occ]
global_possibilities :: GlobalRdrEnv -> [(RdrName, SimilarName)]
global_possibilities :: GlobalRdrEnv -> [(RdrName, SimilarName)]
global_possibilities GlobalRdrEnv
global_env
| Bool
tried_is_qual = [ (RdrName
rdr_qual, RdrName -> HowInScope -> SimilarName
SimilarRdrName RdrName
rdr_qual HowInScope
how)
| GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
, LookingFor -> GlobalRdrElt -> Bool
isGreOk LookingFor
looking_for GlobalRdrElt
gre
, let occ :: OccName
occ = GlobalRdrElt -> OccName
greOccName GlobalRdrElt
gre
, OccName -> Bool
correct_name_space OccName
occ
, (ModuleName
mod, HowInScope
how) <- GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope GlobalRdrElt
gre
, let rdr_qual :: RdrName
rdr_qual = ModuleName -> OccName -> RdrName
mkRdrQual ModuleName
mod OccName
occ ]
| Bool
otherwise = [ (RdrName
rdr_unqual, SimilarName
sim)
| GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
, LookingFor -> GlobalRdrElt -> Bool
isGreOk LookingFor
looking_for GlobalRdrElt
gre
, let occ :: OccName
occ = GlobalRdrElt -> OccName
greOccName GlobalRdrElt
gre
rdr_unqual :: RdrName
rdr_unqual = OccName -> RdrName
mkRdrUnqual OccName
occ
, OccName -> Bool
correct_name_space OccName
occ
, SimilarName
sim <- case (GlobalRdrElt -> [HowInScope]
unquals_in_scope GlobalRdrElt
gre, GlobalRdrElt -> [SimilarName]
quals_only GlobalRdrElt
gre) of
(HowInScope
how:[HowInScope]
_, [SimilarName]
_) -> [ RdrName -> HowInScope -> SimilarName
SimilarRdrName RdrName
rdr_unqual HowInScope
how ]
([], SimilarName
pr:[SimilarName]
_) -> [ SimilarName
pr ]
([], []) -> [] ]
unquals_in_scope :: GlobalRdrElt -> [HowInScope]
unquals_in_scope :: GlobalRdrElt -> [HowInScope]
unquals_in_scope (gre :: GlobalRdrElt
gre@GRE { gre_lcl :: GlobalRdrElt -> Bool
gre_lcl = Bool
lcl, gre_imp :: GlobalRdrElt -> Bag ImportSpec
gre_imp = Bag ImportSpec
is })
| Bool
lcl = [ SrcSpan -> HowInScope
LocallyBoundAt (GlobalRdrElt -> SrcSpan
greDefinitionSrcSpan GlobalRdrElt
gre) ]
| Bool
otherwise = [ ImpDeclSpec -> HowInScope
ImportedBy ImpDeclSpec
ispec
| ImportSpec
i <- Bag ImportSpec -> [ImportSpec]
forall a. Bag a -> [a]
bagToList Bag ImportSpec
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i
, Bool -> Bool
not (ImpDeclSpec -> Bool
is_qual ImpDeclSpec
ispec) ]
quals_only :: GlobalRdrElt -> [SimilarName]
quals_only :: GlobalRdrElt -> [SimilarName]
quals_only (gre :: GlobalRdrElt
gre@GRE { gre_imp :: GlobalRdrElt -> Bag ImportSpec
gre_imp = Bag ImportSpec
is })
= [ (RdrName -> HowInScope -> SimilarName
SimilarRdrName (ModuleName -> OccName -> RdrName
mkRdrQual (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec) (GlobalRdrElt -> OccName
greOccName GlobalRdrElt
gre)) (ImpDeclSpec -> HowInScope
ImportedBy ImpDeclSpec
ispec))
| ImportSpec
i <- Bag ImportSpec -> [ImportSpec]
forall a. Bag a -> [a]
bagToList Bag ImportSpec
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i, ImpDeclSpec -> Bool
is_qual ImpDeclSpec
ispec ]
importSuggestions :: LookingFor
-> GlobalRdrEnv
-> HomePackageTable -> Module
-> ImportAvails -> RdrName -> ([ImportError], [ImportSuggestion])
importSuggestions :: LookingFor
-> GlobalRdrEnv
-> HomePackageTable
-> Module
-> ImportAvails
-> RdrName
-> ([ImportError], [ImportSuggestion])
importSuggestions LookingFor
looking_for GlobalRdrEnv
global_env HomePackageTable
hpt Module
currMod ImportAvails
imports RdrName
rdr_name
| WhereLooking
WL_LocalOnly <- LookingFor -> WhereLooking
lf_where LookingFor
looking_for = ([], [])
| WhereLooking
WL_LocalTop <- LookingFor -> WhereLooking
lf_where LookingFor
looking_for = ([], [])
| Bool -> Bool
not (RdrName -> Bool
isQual RdrName
rdr_name Bool -> Bool -> Bool
|| RdrName -> Bool
isUnqual RdrName
rdr_name) = ([], [])
| [(Module, ImportedModsVal)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
interesting_imports
, Just ModuleName
name <- Maybe ModuleName
mod_name
, ModuleName -> Bool
show_not_imported_line ModuleName
name
= ([ModuleName -> ImportError
MissingModule ModuleName
name], [])
| Bool
is_qualified
, [(Module, ImportedModsVal)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Module, ImportedModsVal)]
helpful_imports
, (Module
mod : [Module]
mods) <- ((Module, ImportedModsVal) -> Module)
-> [(Module, ImportedModsVal)] -> [Module]
forall a b. (a -> b) -> [a] -> [b]
map (Module, ImportedModsVal) -> Module
forall a b. (a, b) -> a
fst [(Module, ImportedModsVal)]
interesting_imports
= ([NonEmpty Module -> OccName -> ImportError
ModulesDoNotExport (Module
mod Module -> [Module] -> NonEmpty Module
forall a. a -> [a] -> NonEmpty a
:| [Module]
mods) OccName
occ_name], [])
| (Module, ImportedModsVal)
mod : [(Module, ImportedModsVal)]
mods <- [(Module, ImportedModsVal)]
helpful_imports_non_hiding
= ([], [NonEmpty (Module, ImportedModsVal) -> OccName -> ImportSuggestion
CouldImportFrom ((Module, ImportedModsVal)
mod (Module, ImportedModsVal)
-> [(Module, ImportedModsVal)]
-> NonEmpty (Module, ImportedModsVal)
forall a. a -> [a] -> NonEmpty a
:| [(Module, ImportedModsVal)]
mods) OccName
occ_name])
| (Module, ImportedModsVal)
mod : [(Module, ImportedModsVal)]
mods <- [(Module, ImportedModsVal)]
helpful_imports_hiding
= ([], [NonEmpty (Module, ImportedModsVal) -> OccName -> ImportSuggestion
CouldUnhideFrom ((Module, ImportedModsVal)
mod (Module, ImportedModsVal)
-> [(Module, ImportedModsVal)]
-> NonEmpty (Module, ImportedModsVal)
forall a. a -> [a] -> NonEmpty a
:| [(Module, ImportedModsVal)]
mods) OccName
occ_name])
| Bool
otherwise
= ([], [])
where
is_qualified :: Bool
is_qualified = RdrName -> Bool
isQual RdrName
rdr_name
(Maybe ModuleName
mod_name, OccName
occ_name) = case RdrName
rdr_name of
Unqual OccName
occ_name -> (Maybe ModuleName
forall a. Maybe a
Nothing, OccName
occ_name)
Qual ModuleName
mod_name OccName
occ_name -> (ModuleName -> Maybe ModuleName
forall a. a -> Maybe a
Just ModuleName
mod_name, OccName
occ_name)
RdrName
_ -> String -> (Maybe ModuleName, OccName)
forall a. HasCallStack => String -> a
error String
"importSuggestions: dead code"
interesting_imports :: [(Module, ImportedModsVal)]
interesting_imports = [ (Module
mod, ImportedModsVal
imp)
| (Module
mod, [ImportedBy]
mod_imports) <- ModuleEnv [ImportedBy] -> [(Module, [ImportedBy])]
forall a. ModuleEnv a -> [(Module, a)]
moduleEnvToList (ImportAvails -> ModuleEnv [ImportedBy]
imp_mods ImportAvails
imports)
, Just ImportedModsVal
imp <- Maybe ImportedModsVal -> [Maybe ImportedModsVal]
forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ImportedModsVal -> [Maybe ImportedModsVal])
-> Maybe ImportedModsVal -> [Maybe ImportedModsVal]
forall a b. (a -> b) -> a -> b
$ [ImportedModsVal] -> Maybe ImportedModsVal
pick ([ImportedBy] -> [ImportedModsVal]
importedByUser [ImportedBy]
mod_imports)
]
pick :: [ImportedModsVal] -> Maybe ImportedModsVal
pick :: [ImportedModsVal] -> Maybe ImportedModsVal
pick = [ImportedModsVal] -> Maybe ImportedModsVal
forall a. [a] -> Maybe a
listToMaybe ([ImportedModsVal] -> Maybe ImportedModsVal)
-> ([ImportedModsVal] -> [ImportedModsVal])
-> [ImportedModsVal]
-> Maybe ImportedModsVal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ImportedModsVal -> ImportedModsVal -> Ordering)
-> [ImportedModsVal] -> [ImportedModsVal]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy ImportedModsVal -> ImportedModsVal -> Ordering
cmp ([ImportedModsVal] -> [ImportedModsVal])
-> ([ImportedModsVal] -> [ImportedModsVal])
-> [ImportedModsVal]
-> [ImportedModsVal]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ImportedModsVal -> Bool) -> [ImportedModsVal] -> [ImportedModsVal]
forall a. (a -> Bool) -> [a] -> [a]
filter ImportedModsVal -> Bool
select
where select :: ImportedModsVal -> Bool
select ImportedModsVal
imv = case Maybe ModuleName
mod_name of Just ModuleName
name -> ImportedModsVal -> ModuleName
imv_name ImportedModsVal
imv ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleName
name
Maybe ModuleName
Nothing -> Bool -> Bool
not (ImportedModsVal -> Bool
imv_qualified ImportedModsVal
imv)
cmp :: ImportedModsVal -> ImportedModsVal -> Ordering
cmp ImportedModsVal
a ImportedModsVal
b =
(Bool -> Bool -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Bool -> Bool -> Ordering)
-> (ImportedModsVal -> Bool)
-> ImportedModsVal
-> ImportedModsVal
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` ImportedModsVal -> Bool
imv_is_hiding) ImportedModsVal
a ImportedModsVal
b
Ordering -> Ordering -> Ordering
`thenCmp`
(SrcSpan -> SrcSpan -> Ordering
SrcLoc.leftmost_smallest (SrcSpan -> SrcSpan -> Ordering)
-> (ImportedModsVal -> SrcSpan)
-> ImportedModsVal
-> ImportedModsVal
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` ImportedModsVal -> SrcSpan
imv_span) ImportedModsVal
a ImportedModsVal
b
helpful_imports :: [(Module, ImportedModsVal)]
helpful_imports = ((Module, ImportedModsVal) -> Bool)
-> [(Module, ImportedModsVal)] -> [(Module, ImportedModsVal)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Module, ImportedModsVal) -> Bool
helpful [(Module, ImportedModsVal)]
interesting_imports
where helpful :: (Module, ImportedModsVal) -> Bool
helpful (Module
_,ImportedModsVal
imv)
= (GlobalRdrElt -> Bool) -> [GlobalRdrElt] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (LookingFor -> GlobalRdrElt -> Bool
isGreOk LookingFor
looking_for) ([GlobalRdrElt] -> Bool) -> [GlobalRdrElt] -> Bool
forall a b. (a -> b) -> a -> b
$
GlobalRdrEnv -> OccName -> [GlobalRdrElt]
lookupGlobalRdrEnv (ImportedModsVal -> GlobalRdrEnv
imv_all_exports ImportedModsVal
imv) OccName
occ_name
([(Module, ImportedModsVal)]
helpful_imports_hiding, [(Module, ImportedModsVal)]
helpful_imports_non_hiding)
= ((Module, ImportedModsVal) -> Bool)
-> [(Module, ImportedModsVal)]
-> ([(Module, ImportedModsVal)], [(Module, ImportedModsVal)])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition (ImportedModsVal -> Bool
imv_is_hiding (ImportedModsVal -> Bool)
-> ((Module, ImportedModsVal) -> ImportedModsVal)
-> (Module, ImportedModsVal)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Module, ImportedModsVal) -> ImportedModsVal
forall a b. (a, b) -> b
snd) [(Module, ImportedModsVal)]
helpful_imports
show_not_imported_line :: ModuleName -> Bool
show_not_imported_line :: ModuleName -> Bool
show_not_imported_line ModuleName
modnam
| ModuleName
modnam ModuleName -> [ModuleName] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [ModuleName]
glob_mods = Bool
False
| Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
currMod ModuleName -> ModuleName -> Bool
forall a. Eq a => a -> a -> Bool
== ModuleName
modnam = Bool
False
| ModuleName -> [Unique] -> Bool
forall {a}. Uniquable a => a -> [Unique] -> Bool
is_last_loaded_mod ModuleName
modnam [Unique]
hpt_uniques = Bool
False
| Bool
otherwise = Bool
True
where
hpt_uniques :: [Unique]
hpt_uniques = ((Unique, HomeModInfo) -> Unique)
-> [(Unique, HomeModInfo)] -> [Unique]
forall a b. (a -> b) -> [a] -> [b]
map (Unique, HomeModInfo) -> Unique
forall a b. (a, b) -> a
fst (HomePackageTable -> [(Unique, HomeModInfo)]
forall key elt. UniqDFM key elt -> [(Unique, elt)]
udfmToList HomePackageTable
hpt)
is_last_loaded_mod :: a -> [Unique] -> Bool
is_last_loaded_mod a
_ [] = Bool
False
is_last_loaded_mod a
modnam [Unique]
uniqs = [Unique] -> Unique
forall a. HasCallStack => [a] -> a
last [Unique]
uniqs Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
== a -> Unique
forall a. Uniquable a => a -> Unique
getUnique a
modnam
glob_mods :: [ModuleName]
glob_mods = [ModuleName] -> [ModuleName]
forall a. Eq a => [a] -> [a]
nub [ ModuleName
mod
| GlobalRdrElt
gre <- GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
global_env
, (ModuleName
mod, HowInScope
_) <- GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope GlobalRdrElt
gre
]
extensionSuggestions :: RdrName -> [GhcHint]
extensionSuggestions :: RdrName -> [GhcHint]
extensionSuggestions RdrName
rdrName
| RdrName
rdrName RdrName -> RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace -> FastString -> RdrName
mkUnqual NameSpace
varName (String -> FastString
fsLit String
"mdo") Bool -> Bool -> Bool
||
RdrName
rdrName RdrName -> RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace -> FastString -> RdrName
mkUnqual NameSpace
varName (String -> FastString
fsLit String
"rec")
= [LanguageExtensionHint -> GhcHint
SuggestExtension (LanguageExtensionHint -> GhcHint)
-> LanguageExtensionHint -> GhcHint
forall a b. (a -> b) -> a -> b
$ SDoc -> Extension -> LanguageExtensionHint
SuggestSingleExtension SDoc
empty Extension
LangExt.RecursiveDo]
| Bool
otherwise
= []
qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope :: GlobalRdrElt -> [(ModuleName, HowInScope)]
qualsInScope gre :: GlobalRdrElt
gre@GRE { gre_lcl :: GlobalRdrElt -> Bool
gre_lcl = Bool
lcl, gre_imp :: GlobalRdrElt -> Bag ImportSpec
gre_imp = Bag ImportSpec
is }
| Bool
lcl = case GlobalRdrElt -> Maybe Module
greDefinitionModule GlobalRdrElt
gre of
Maybe Module
Nothing -> []
Just Module
m -> [(Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
m, SrcSpan -> HowInScope
LocallyBoundAt (GlobalRdrElt -> SrcSpan
greDefinitionSrcSpan GlobalRdrElt
gre))]
| Bool
otherwise = [ (ImpDeclSpec -> ModuleName
is_as ImpDeclSpec
ispec, ImpDeclSpec -> HowInScope
ImportedBy ImpDeclSpec
ispec)
| ImportSpec
i <- Bag ImportSpec -> [ImportSpec]
forall a. Bag a -> [a]
bagToList Bag ImportSpec
is, let ispec :: ImpDeclSpec
ispec = ImportSpec -> ImpDeclSpec
is_decl ImportSpec
i ]
isGreOk :: LookingFor -> GlobalRdrElt -> Bool
isGreOk :: LookingFor -> GlobalRdrElt -> Bool
isGreOk (LF WhatLooking
what_look WhereLooking
where_look) GlobalRdrElt
gre = Bool
what_ok Bool -> Bool -> Bool
&& Bool
where_ok
where
what_ok :: Bool
what_ok = case WhatLooking
what_look of
WhatLooking
WL_RecField -> GlobalRdrElt -> Bool
isRecFldGRE GlobalRdrElt
gre
WhatLooking
_ -> Bool -> Bool
not (GlobalRdrElt -> Bool
isNoFieldSelectorGRE GlobalRdrElt
gre)
where_ok :: Bool
where_ok = case WhereLooking
where_look of
WhereLooking
WL_LocalTop -> GlobalRdrElt -> Bool
isLocalGRE GlobalRdrElt
gre
WhereLooking
WL_LocalOnly -> Bool
False
WhereLooking
_ -> Bool
True
nameSpacesRelated :: DynFlags
-> WhatLooking
-> NameSpace
-> NameSpace
-> Bool
nameSpacesRelated :: DynFlags -> WhatLooking -> NameSpace -> NameSpace -> Bool
nameSpacesRelated DynFlags
dflags WhatLooking
what_looking NameSpace
ns NameSpace
ns'
= NameSpace
ns' NameSpace -> [NameSpace] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` NameSpace
ns NameSpace -> [NameSpace] -> [NameSpace]
forall a. a -> [a] -> [a]
: [ NameSpace
other_ns
| (NameSpace
orig_ns, [(NameSpace, [WhatLooking])]
others) <- [(NameSpace, [(NameSpace, [WhatLooking])])]
other_namespaces
, NameSpace
ns NameSpace -> NameSpace -> Bool
forall a. Eq a => a -> a -> Bool
== NameSpace
orig_ns
, (NameSpace
other_ns, [WhatLooking]
wls) <- [(NameSpace, [WhatLooking])]
others
, WhatLooking
what_looking WhatLooking -> [WhatLooking] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` WhatLooking
WL_Anything WhatLooking -> [WhatLooking] -> [WhatLooking]
forall a. a -> [a] -> [a]
: [WhatLooking]
wls
]
where
other_namespaces :: [(NameSpace, [(NameSpace, [WhatLooking])])]
other_namespaces =
[ (NameSpace
varName , [(NameSpace
dataName, [WhatLooking
WL_Constructor])])
, (NameSpace
dataName , [(NameSpace
varName , [WhatLooking
WL_RecField])])
, (NameSpace
tvName , (NameSpace
tcClsName, [WhatLooking
WL_Constructor]) (NameSpace, [WhatLooking])
-> [(NameSpace, [WhatLooking])] -> [(NameSpace, [WhatLooking])]
forall a. a -> [a] -> [a]
: [(NameSpace, [WhatLooking])]
promoted_datacons)
, (NameSpace
tcClsName, (NameSpace
tvName , []) (NameSpace, [WhatLooking])
-> [(NameSpace, [WhatLooking])] -> [(NameSpace, [WhatLooking])]
forall a. a -> [a] -> [a]
: [(NameSpace, [WhatLooking])]
promoted_datacons)
]
data_kinds :: Bool
data_kinds = Extension -> DynFlags -> Bool
xopt Extension
LangExt.DataKinds DynFlags
dflags
promoted_datacons :: [(NameSpace, [WhatLooking])]
promoted_datacons = [(NameSpace
dataName, [WhatLooking
WL_Constructor]) | Bool
data_kinds]