{-# LANGUAGE CPP #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}

-- | Manipulations on import lists.
module Ormolu.Imports
  ( normalizeImports,
  )
where

import Data.Bifunctor
import Data.Char (isAlphaNum)
import Data.Function (on)
import Data.List (nubBy, sortBy, sortOn)
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as M
import Data.Ord (comparing)
import Data.Set (Set)
import Distribution.ModuleName qualified as Cabal
import GHC.Data.FastString
import GHC.Hs
import GHC.Hs.ImpExp as GHC
import GHC.Types.Name.Reader
import GHC.Types.PkgQual
import GHC.Types.SourceText
import GHC.Types.SrcLoc
import Ormolu.Config (ImportGrouping)
import Ormolu.Imports.Grouping (Import (..), groupImports, prepareExistingGroups)
import Ormolu.Utils (notImplemented, showOutputable)
#if !MIN_VERSION_base(4,20,0)
import Data.List (foldl')
#endif

-- | Sort, group and normalize imports.
--
-- Assumes input list is sorted by source location. Output list is not necessarily
-- sorted by source location, so this function should be called at most once on a
-- given input list.
normalizeImports :: Bool -> Set Cabal.ModuleName -> ImportGrouping -> [LImportDecl GhcPs] -> [[LImportDecl GhcPs]]
normalizeImports :: Bool
-> Set ModuleName
-> ImportGrouping
-> [LImportDecl GhcPs]
-> [[LImportDecl GhcPs]]
normalizeImports Bool
respectful Set ModuleName
localModules ImportGrouping
importGrouping =
  ([(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
 -> [GenLocated SrcSpanAnnA (ImportDecl GhcPs)])
-> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]]
-> [[GenLocated SrcSpanAnnA (ImportDecl GhcPs)]]
forall a b. (a -> b) -> [a] -> [b]
map (((ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))
 -> GenLocated SrcSpanAnnA (ImportDecl GhcPs))
-> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
-> [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))
-> GenLocated SrcSpanAnnA (ImportDecl GhcPs)
forall a b. (a, b) -> b
snd)
    ([[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]]
 -> [[GenLocated SrcSpanAnnA (ImportDecl GhcPs)]])
-> ([GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
    -> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]])
-> [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
-> [[GenLocated SrcSpanAnnA (ImportDecl GhcPs)]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
 -> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]])
-> [[GenLocated SrcSpanAnnA (ImportDecl GhcPs)]]
-> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap
      ( ImportGrouping
-> Set ModuleName
-> ((ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))
    -> Import)
-> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
-> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]]
forall x.
ImportGrouping -> Set ModuleName -> (x -> Import) -> [x] -> [[x]]
groupImports ImportGrouping
importGrouping Set ModuleName
localModules (ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs)) -> Import
forall x. (ImportId, x) -> Import
toImport
          ([(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
 -> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]])
-> ([GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
    -> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))])
-> [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
-> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map ImportId (GenLocated SrcSpanAnnA (ImportDecl GhcPs))
-> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
forall k a. Map k a -> [(k, a)]
M.toAscList
          (Map ImportId (GenLocated SrcSpanAnnA (ImportDecl GhcPs))
 -> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))])
-> ([GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
    -> Map ImportId (GenLocated SrcSpanAnnA (ImportDecl GhcPs)))
-> [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
-> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenLocated SrcSpanAnnA (ImportDecl GhcPs)
 -> GenLocated SrcSpanAnnA (ImportDecl GhcPs)
 -> GenLocated SrcSpanAnnA (ImportDecl GhcPs))
-> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
-> Map ImportId (GenLocated SrcSpanAnnA (ImportDecl GhcPs))
forall k a. Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
M.fromListWith LImportDecl GhcPs -> LImportDecl GhcPs -> LImportDecl GhcPs
GenLocated SrcSpanAnnA (ImportDecl GhcPs)
-> GenLocated SrcSpanAnnA (ImportDecl GhcPs)
-> GenLocated SrcSpanAnnA (ImportDecl GhcPs)
combineImports
          ([(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
 -> Map ImportId (GenLocated SrcSpanAnnA (ImportDecl GhcPs)))
-> ([GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
    -> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))])
-> [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
-> Map ImportId (GenLocated SrcSpanAnnA (ImportDecl GhcPs))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenLocated SrcSpanAnnA (ImportDecl GhcPs)
 -> (ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs)))
-> [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
-> [(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\GenLocated SrcSpanAnnA (ImportDecl GhcPs)
x -> (LImportDecl GhcPs -> ImportId
importId LImportDecl GhcPs
GenLocated SrcSpanAnnA (ImportDecl GhcPs)
x, LImportDecl GhcPs -> LImportDecl GhcPs
g LImportDecl GhcPs
GenLocated SrcSpanAnnA (ImportDecl GhcPs)
x))
      )
    ([[GenLocated SrcSpanAnnA (ImportDecl GhcPs)]]
 -> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]])
-> ([GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
    -> [[GenLocated SrcSpanAnnA (ImportDecl GhcPs)]])
-> [GenLocated SrcSpanAnnA (ImportDecl GhcPs)]
-> [[(ImportId, GenLocated SrcSpanAnnA (ImportDecl GhcPs))]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ImportGrouping
-> Bool -> [LImportDecl GhcPs] -> [[LImportDecl GhcPs]]
prepareExistingGroups ImportGrouping
importGrouping Bool
respectful
  where
    toImport :: (ImportId, x) -> Import
    toImport :: forall x. (ImportId, x) -> Import
toImport (ImportId {Bool
Maybe ModuleName
Maybe ImportListInterpretationOrd
ModuleName
IsBootInterface
ImportPkgQual
importIsPrelude :: Bool
importPkgQual :: ImportPkgQual
importIdName :: ModuleName
importSource :: IsBootInterface
importSafe :: Bool
importQualified :: Bool
importAs :: Maybe ModuleName
importHiding :: Maybe ImportListInterpretationOrd
importHiding :: ImportId -> Maybe ImportListInterpretationOrd
importAs :: ImportId -> Maybe ModuleName
importQualified :: ImportId -> Bool
importSafe :: ImportId -> Bool
importSource :: ImportId -> IsBootInterface
importIdName :: ImportId -> ModuleName
importPkgQual :: ImportId -> ImportPkgQual
importIsPrelude :: ImportId -> Bool
..}, x
_) = Import {importName :: ModuleName
importName = ModuleName
importIdName, Bool
importQualified :: Bool
importQualified :: Bool
importQualified}

    g :: LImportDecl GhcPs -> LImportDecl GhcPs
    g :: LImportDecl GhcPs -> LImportDecl GhcPs
g (L SrcSpanAnnA
l ImportDecl {Bool
Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
Maybe (XRec GhcPs ModuleName)
ImportDeclPkgQual GhcPs
XCImportDecl GhcPs
XRec GhcPs ModuleName
IsBootInterface
ImportDeclQualifiedStyle
ideclExt :: XCImportDecl GhcPs
ideclName :: XRec GhcPs ModuleName
ideclPkgQual :: ImportDeclPkgQual GhcPs
ideclSource :: IsBootInterface
ideclSafe :: Bool
ideclQualified :: ImportDeclQualifiedStyle
ideclAs :: Maybe (XRec GhcPs ModuleName)
ideclImportList :: Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
ideclImportList :: forall pass.
ImportDecl pass
-> Maybe (ImportListInterpretation, XRec pass [LIE pass])
ideclAs :: forall pass. ImportDecl pass -> Maybe (XRec pass ModuleName)
ideclQualified :: forall pass. ImportDecl pass -> ImportDeclQualifiedStyle
ideclSafe :: forall pass. ImportDecl pass -> Bool
ideclSource :: forall pass. ImportDecl pass -> IsBootInterface
ideclPkgQual :: forall pass. ImportDecl pass -> ImportDeclPkgQual pass
ideclName :: forall pass. ImportDecl pass -> XRec pass ModuleName
ideclExt :: forall pass. ImportDecl pass -> XCImportDecl pass
..}) =
      SrcSpanAnnA
-> ImportDecl GhcPs -> GenLocated SrcSpanAnnA (ImportDecl GhcPs)
forall l e. l -> e -> GenLocated l e
L
        SrcSpanAnnA
l
        ImportDecl
          { ideclImportList :: Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
ideclImportList = (GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)]
 -> GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
-> (ImportListInterpretation,
    GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
-> (ImportListInterpretation,
    GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
forall b c a. (b -> c) -> (a, b) -> (a, c)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (([GenLocated SrcSpanAnnA (IE GhcPs)]
 -> [GenLocated SrcSpanAnnA (IE GhcPs)])
-> GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)]
-> GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)]
forall a b.
(a -> b) -> GenLocated SrcSpanAnnLI a -> GenLocated SrcSpanAnnLI b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [LIE GhcPs] -> [LIE GhcPs]
[GenLocated SrcSpanAnnA (IE GhcPs)]
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
normalizeLies) ((ImportListInterpretation,
  GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
 -> (ImportListInterpretation,
     GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)]))
-> Maybe
     (ImportListInterpretation,
      GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
-> Maybe
     (ImportListInterpretation,
      GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
Maybe
  (ImportListInterpretation,
   GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
ideclImportList,
            Bool
Maybe (XRec GhcPs ModuleName)
ImportDeclPkgQual GhcPs
XCImportDecl GhcPs
XRec GhcPs ModuleName
IsBootInterface
ImportDeclQualifiedStyle
ideclExt :: XCImportDecl GhcPs
ideclName :: XRec GhcPs ModuleName
ideclPkgQual :: ImportDeclPkgQual GhcPs
ideclSource :: IsBootInterface
ideclSafe :: Bool
ideclQualified :: ImportDeclQualifiedStyle
ideclAs :: Maybe (XRec GhcPs ModuleName)
ideclAs :: Maybe (XRec GhcPs ModuleName)
ideclQualified :: ImportDeclQualifiedStyle
ideclSafe :: Bool
ideclSource :: IsBootInterface
ideclPkgQual :: ImportDeclPkgQual GhcPs
ideclName :: XRec GhcPs ModuleName
ideclExt :: XCImportDecl GhcPs
..
          }

-- | Combine two import declarations. It should be assumed that 'ImportId's
-- are equal.
combineImports ::
  LImportDecl GhcPs ->
  LImportDecl GhcPs ->
  LImportDecl GhcPs
combineImports :: LImportDecl GhcPs -> LImportDecl GhcPs -> LImportDecl GhcPs
combineImports (L SrcSpanAnnA
lx ImportDecl {Bool
Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
Maybe (XRec GhcPs ModuleName)
ImportDeclPkgQual GhcPs
XCImportDecl GhcPs
XRec GhcPs ModuleName
IsBootInterface
ImportDeclQualifiedStyle
ideclImportList :: forall pass.
ImportDecl pass
-> Maybe (ImportListInterpretation, XRec pass [LIE pass])
ideclAs :: forall pass. ImportDecl pass -> Maybe (XRec pass ModuleName)
ideclQualified :: forall pass. ImportDecl pass -> ImportDeclQualifiedStyle
ideclSafe :: forall pass. ImportDecl pass -> Bool
ideclSource :: forall pass. ImportDecl pass -> IsBootInterface
ideclPkgQual :: forall pass. ImportDecl pass -> ImportDeclPkgQual pass
ideclName :: forall pass. ImportDecl pass -> XRec pass ModuleName
ideclExt :: forall pass. ImportDecl pass -> XCImportDecl pass
ideclExt :: XCImportDecl GhcPs
ideclName :: XRec GhcPs ModuleName
ideclPkgQual :: ImportDeclPkgQual GhcPs
ideclSource :: IsBootInterface
ideclSafe :: Bool
ideclQualified :: ImportDeclQualifiedStyle
ideclAs :: Maybe (XRec GhcPs ModuleName)
ideclImportList :: Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
..}) (L SrcSpanAnnA
_ ImportDecl GhcPs
y) =
  SrcSpanAnnA
-> ImportDecl GhcPs -> GenLocated SrcSpanAnnA (ImportDecl GhcPs)
forall l e. l -> e -> GenLocated l e
L
    SrcSpanAnnA
lx
    ImportDecl
      { ideclImportList :: Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
ideclImportList = case (Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
Maybe
  (ImportListInterpretation,
   GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
ideclImportList, ImportDecl GhcPs
-> Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
forall pass.
ImportDecl pass
-> Maybe (ImportListInterpretation, XRec pass [LIE pass])
GHC.ideclImportList ImportDecl GhcPs
y) of
          (Just (ImportListInterpretation
hiding, L SrcSpanAnnLI
l' [GenLocated SrcSpanAnnA (IE GhcPs)]
xs), Just (ImportListInterpretation
_, L SrcSpanAnnLI
_ [GenLocated SrcSpanAnnA (IE GhcPs)]
ys)) ->
            (ImportListInterpretation,
 GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
-> Maybe
     (ImportListInterpretation,
      GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
forall a. a -> Maybe a
Just (ImportListInterpretation
hiding, (SrcSpanAnnLI
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
-> GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)]
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnLI
l' ([LIE GhcPs] -> [LIE GhcPs]
normalizeLies ([GenLocated SrcSpanAnnA (IE GhcPs)]
xs [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
forall a. [a] -> [a] -> [a]
++ [GenLocated SrcSpanAnnA (IE GhcPs)]
ys))))
          (Maybe
   (ImportListInterpretation,
    GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)]),
 Maybe
   (ImportListInterpretation,
    GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)]))
_ -> Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
Maybe
  (ImportListInterpretation,
   GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
forall a. Maybe a
Nothing,
        Bool
Maybe (XRec GhcPs ModuleName)
ImportDeclPkgQual GhcPs
XCImportDecl GhcPs
XRec GhcPs ModuleName
IsBootInterface
ImportDeclQualifiedStyle
ideclAs :: Maybe (XRec GhcPs ModuleName)
ideclQualified :: ImportDeclQualifiedStyle
ideclSafe :: Bool
ideclSource :: IsBootInterface
ideclPkgQual :: ImportDeclPkgQual GhcPs
ideclName :: XRec GhcPs ModuleName
ideclExt :: XCImportDecl GhcPs
ideclExt :: XCImportDecl GhcPs
ideclName :: XRec GhcPs ModuleName
ideclPkgQual :: ImportDeclPkgQual GhcPs
ideclSource :: IsBootInterface
ideclSafe :: Bool
ideclQualified :: ImportDeclQualifiedStyle
ideclAs :: Maybe (XRec GhcPs ModuleName)
..
      }

-- | Import id, a collection of all things that justify having a separate
-- import entry. This is used for merging of imports. If two imports have
-- the same 'ImportId' they can be merged.
data ImportId = ImportId
  { ImportId -> Bool
importIsPrelude :: Bool,
    ImportId -> ImportPkgQual
importPkgQual :: ImportPkgQual,
    ImportId -> ModuleName
importIdName :: ModuleName,
    ImportId -> IsBootInterface
importSource :: IsBootInterface,
    ImportId -> Bool
importSafe :: Bool,
    ImportId -> Bool
importQualified :: Bool,
    ImportId -> Maybe ModuleName
importAs :: Maybe ModuleName,
    ImportId -> Maybe ImportListInterpretationOrd
importHiding :: Maybe ImportListInterpretationOrd
  }
  deriving (ImportId -> ImportId -> Bool
(ImportId -> ImportId -> Bool)
-> (ImportId -> ImportId -> Bool) -> Eq ImportId
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ImportId -> ImportId -> Bool
== :: ImportId -> ImportId -> Bool
$c/= :: ImportId -> ImportId -> Bool
/= :: ImportId -> ImportId -> Bool
Eq, Eq ImportId
Eq ImportId =>
(ImportId -> ImportId -> Ordering)
-> (ImportId -> ImportId -> Bool)
-> (ImportId -> ImportId -> Bool)
-> (ImportId -> ImportId -> Bool)
-> (ImportId -> ImportId -> Bool)
-> (ImportId -> ImportId -> ImportId)
-> (ImportId -> ImportId -> ImportId)
-> Ord ImportId
ImportId -> ImportId -> Bool
ImportId -> ImportId -> Ordering
ImportId -> ImportId -> ImportId
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
$ccompare :: ImportId -> ImportId -> Ordering
compare :: ImportId -> ImportId -> Ordering
$c< :: ImportId -> ImportId -> Bool
< :: ImportId -> ImportId -> Bool
$c<= :: ImportId -> ImportId -> Bool
<= :: ImportId -> ImportId -> Bool
$c> :: ImportId -> ImportId -> Bool
> :: ImportId -> ImportId -> Bool
$c>= :: ImportId -> ImportId -> Bool
>= :: ImportId -> ImportId -> Bool
$cmax :: ImportId -> ImportId -> ImportId
max :: ImportId -> ImportId -> ImportId
$cmin :: ImportId -> ImportId -> ImportId
min :: ImportId -> ImportId -> ImportId
Ord)

data ImportPkgQual
  = -- | The import is not qualified by a package name.
    NoImportPkgQual
  | -- | The import is qualified by an external package name.
    ImportPkgQual LexicalFastString
  | -- | The import is qualified by the current package being built, using the
    -- special @this@ package name.
    ImportPkgQualThis
  deriving stock (ImportPkgQual -> ImportPkgQual -> Bool
(ImportPkgQual -> ImportPkgQual -> Bool)
-> (ImportPkgQual -> ImportPkgQual -> Bool) -> Eq ImportPkgQual
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ImportPkgQual -> ImportPkgQual -> Bool
== :: ImportPkgQual -> ImportPkgQual -> Bool
$c/= :: ImportPkgQual -> ImportPkgQual -> Bool
/= :: ImportPkgQual -> ImportPkgQual -> Bool
Eq, Eq ImportPkgQual
Eq ImportPkgQual =>
(ImportPkgQual -> ImportPkgQual -> Ordering)
-> (ImportPkgQual -> ImportPkgQual -> Bool)
-> (ImportPkgQual -> ImportPkgQual -> Bool)
-> (ImportPkgQual -> ImportPkgQual -> Bool)
-> (ImportPkgQual -> ImportPkgQual -> Bool)
-> (ImportPkgQual -> ImportPkgQual -> ImportPkgQual)
-> (ImportPkgQual -> ImportPkgQual -> ImportPkgQual)
-> Ord ImportPkgQual
ImportPkgQual -> ImportPkgQual -> Bool
ImportPkgQual -> ImportPkgQual -> Ordering
ImportPkgQual -> ImportPkgQual -> ImportPkgQual
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
$ccompare :: ImportPkgQual -> ImportPkgQual -> Ordering
compare :: ImportPkgQual -> ImportPkgQual -> Ordering
$c< :: ImportPkgQual -> ImportPkgQual -> Bool
< :: ImportPkgQual -> ImportPkgQual -> Bool
$c<= :: ImportPkgQual -> ImportPkgQual -> Bool
<= :: ImportPkgQual -> ImportPkgQual -> Bool
$c> :: ImportPkgQual -> ImportPkgQual -> Bool
> :: ImportPkgQual -> ImportPkgQual -> Bool
$c>= :: ImportPkgQual -> ImportPkgQual -> Bool
>= :: ImportPkgQual -> ImportPkgQual -> Bool
$cmax :: ImportPkgQual -> ImportPkgQual -> ImportPkgQual
max :: ImportPkgQual -> ImportPkgQual -> ImportPkgQual
$cmin :: ImportPkgQual -> ImportPkgQual -> ImportPkgQual
min :: ImportPkgQual -> ImportPkgQual -> ImportPkgQual
Ord)

mkImportPkgQual :: RawPkgQual -> ImportPkgQual
mkImportPkgQual :: RawPkgQual -> ImportPkgQual
mkImportPkgQual = \case
  RawPkgQual
NoRawPkgQual -> ImportPkgQual
NoImportPkgQual
  RawPkgQual (StringLiteral -> FastString
sl_fs -> FastString
fs)
    | FastString
fs FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== String -> FastString
mkFastString String
"this" -> ImportPkgQual
ImportPkgQualThis
    | Bool
otherwise -> LexicalFastString -> ImportPkgQual
ImportPkgQual (FastString -> LexicalFastString
LexicalFastString FastString
fs)

-- | 'ImportListInterpretation' does not have an 'Ord' instance.
newtype ImportListInterpretationOrd = ImportListInterpretationOrd
  { ImportListInterpretationOrd -> ImportListInterpretation
unImportListInterpretationOrd :: ImportListInterpretation
  }
  deriving stock (ImportListInterpretationOrd -> ImportListInterpretationOrd -> Bool
(ImportListInterpretationOrd
 -> ImportListInterpretationOrd -> Bool)
-> (ImportListInterpretationOrd
    -> ImportListInterpretationOrd -> Bool)
-> Eq ImportListInterpretationOrd
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: ImportListInterpretationOrd -> ImportListInterpretationOrd -> Bool
== :: ImportListInterpretationOrd -> ImportListInterpretationOrd -> Bool
$c/= :: ImportListInterpretationOrd -> ImportListInterpretationOrd -> Bool
/= :: ImportListInterpretationOrd -> ImportListInterpretationOrd -> Bool
Eq)

instance Ord ImportListInterpretationOrd where
  compare :: ImportListInterpretationOrd
-> ImportListInterpretationOrd -> Ordering
compare = Bool -> Bool -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Bool -> Bool -> Ordering)
-> (ImportListInterpretationOrd -> Bool)
-> ImportListInterpretationOrd
-> ImportListInterpretationOrd
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` ImportListInterpretation -> Bool
toBool (ImportListInterpretation -> Bool)
-> (ImportListInterpretationOrd -> ImportListInterpretation)
-> ImportListInterpretationOrd
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ImportListInterpretationOrd -> ImportListInterpretation
unImportListInterpretationOrd
    where
      toBool :: ImportListInterpretation -> Bool
toBool ImportListInterpretation
Exactly = Bool
False
      toBool ImportListInterpretation
EverythingBut = Bool
True

-- | Obtain an 'ImportId' for a given import.
importId :: LImportDecl GhcPs -> ImportId
importId :: LImportDecl GhcPs -> ImportId
importId (L SrcSpanAnnA
_ ImportDecl {Bool
Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
Maybe (XRec GhcPs ModuleName)
ImportDeclPkgQual GhcPs
XCImportDecl GhcPs
XRec GhcPs ModuleName
IsBootInterface
ImportDeclQualifiedStyle
ideclImportList :: forall pass.
ImportDecl pass
-> Maybe (ImportListInterpretation, XRec pass [LIE pass])
ideclAs :: forall pass. ImportDecl pass -> Maybe (XRec pass ModuleName)
ideclQualified :: forall pass. ImportDecl pass -> ImportDeclQualifiedStyle
ideclSafe :: forall pass. ImportDecl pass -> Bool
ideclSource :: forall pass. ImportDecl pass -> IsBootInterface
ideclPkgQual :: forall pass. ImportDecl pass -> ImportDeclPkgQual pass
ideclName :: forall pass. ImportDecl pass -> XRec pass ModuleName
ideclExt :: forall pass. ImportDecl pass -> XCImportDecl pass
ideclExt :: XCImportDecl GhcPs
ideclName :: XRec GhcPs ModuleName
ideclPkgQual :: ImportDeclPkgQual GhcPs
ideclSource :: IsBootInterface
ideclSafe :: Bool
ideclQualified :: ImportDeclQualifiedStyle
ideclAs :: Maybe (XRec GhcPs ModuleName)
ideclImportList :: Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
..}) =
  ImportId
    { importIsPrelude :: Bool
importIsPrelude = Bool
isPrelude,
      importIdName :: ModuleName
importIdName = ModuleName
moduleName,
      importPkgQual :: ImportPkgQual
importPkgQual = RawPkgQual -> ImportPkgQual
mkImportPkgQual ImportDeclPkgQual GhcPs
RawPkgQual
ideclPkgQual,
      importSource :: IsBootInterface
importSource = IsBootInterface
ideclSource,
      importSafe :: Bool
importSafe = Bool
ideclSafe,
      importQualified :: Bool
importQualified = case ImportDeclQualifiedStyle
ideclQualified of
        ImportDeclQualifiedStyle
QualifiedPre -> Bool
True
        ImportDeclQualifiedStyle
QualifiedPost -> Bool
True
        ImportDeclQualifiedStyle
NotQualified -> Bool
False,
      importAs :: Maybe ModuleName
importAs = GenLocated SrcSpanAnnA ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc (GenLocated SrcSpanAnnA ModuleName -> ModuleName)
-> Maybe (GenLocated SrcSpanAnnA ModuleName) -> Maybe ModuleName
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (XRec GhcPs ModuleName)
Maybe (GenLocated SrcSpanAnnA ModuleName)
ideclAs,
      importHiding :: Maybe ImportListInterpretationOrd
importHiding = ImportListInterpretation -> ImportListInterpretationOrd
ImportListInterpretationOrd (ImportListInterpretation -> ImportListInterpretationOrd)
-> ((ImportListInterpretation,
     GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
    -> ImportListInterpretation)
-> (ImportListInterpretation,
    GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
-> ImportListInterpretationOrd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ImportListInterpretation,
 GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
-> ImportListInterpretation
forall a b. (a, b) -> a
fst ((ImportListInterpretation,
  GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
 -> ImportListInterpretationOrd)
-> Maybe
     (ImportListInterpretation,
      GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
-> Maybe ImportListInterpretationOrd
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (ImportListInterpretation, XRec GhcPs [LIE GhcPs])
Maybe
  (ImportListInterpretation,
   GenLocated SrcSpanAnnLI [GenLocated SrcSpanAnnA (IE GhcPs)])
ideclImportList
    }
  where
    isPrelude :: Bool
isPrelude = ModuleName -> String
moduleNameString ModuleName
moduleName String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"Prelude"
    moduleName :: ModuleName
moduleName = GenLocated SrcSpanAnnA ModuleName -> ModuleName
forall l e. GenLocated l e -> e
unLoc XRec GhcPs ModuleName
GenLocated SrcSpanAnnA ModuleName
ideclName

-- | Normalize a collection of import items.
normalizeLies :: [LIE GhcPs] -> [LIE GhcPs]
normalizeLies :: [LIE GhcPs] -> [LIE GhcPs]
normalizeLies = (GenLocated SrcSpanAnnA (IE GhcPs) -> IEWrappedNameOrd)
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (IE GhcPs -> IEWrappedNameOrd
getIewn (IE GhcPs -> IEWrappedNameOrd)
-> (GenLocated SrcSpanAnnA (IE GhcPs) -> IE GhcPs)
-> GenLocated SrcSpanAnnA (IE GhcPs)
-> IEWrappedNameOrd
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GenLocated SrcSpanAnnA (IE GhcPs) -> IE GhcPs
forall l e. GenLocated l e -> e
unLoc) ([GenLocated SrcSpanAnnA (IE GhcPs)]
 -> [GenLocated SrcSpanAnnA (IE GhcPs)])
-> ([GenLocated SrcSpanAnnA (IE GhcPs)]
    -> [GenLocated SrcSpanAnnA (IE GhcPs)])
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
forall k a. Map k a -> [a]
M.elems (Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
 -> [GenLocated SrcSpanAnnA (IE GhcPs)])
-> ([GenLocated SrcSpanAnnA (IE GhcPs)]
    -> Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs)))
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
 -> GenLocated SrcSpanAnnA (IE GhcPs)
 -> Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs)))
-> Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
-> [GenLocated SrcSpanAnnA (IE GhcPs)]
-> Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Map IEWrappedNameOrd (LIE GhcPs)
-> LIE GhcPs -> Map IEWrappedNameOrd (LIE GhcPs)
Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
-> GenLocated SrcSpanAnnA (IE GhcPs)
-> Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
combine Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
forall k a. Map k a
M.empty
  where
    combine ::
      Map IEWrappedNameOrd (LIE GhcPs) ->
      LIE GhcPs ->
      Map IEWrappedNameOrd (LIE GhcPs)
    combine :: Map IEWrappedNameOrd (LIE GhcPs)
-> LIE GhcPs -> Map IEWrappedNameOrd (LIE GhcPs)
combine Map IEWrappedNameOrd (LIE GhcPs)
m (L SrcSpanAnnA
new_l IE GhcPs
new) =
      let wname :: IEWrappedNameOrd
wname = IE GhcPs -> IEWrappedNameOrd
getIewn IE GhcPs
new
          normalizeWNames :: [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
normalizeWNames =
            (GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
 -> GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> Bool)
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy (\GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
x GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
y -> LIEWrappedName GhcPs -> LIEWrappedName GhcPs -> Ordering
compareLIewn LIEWrappedName GhcPs
GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
x LIEWrappedName GhcPs
GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
y Ordering -> Ordering -> Bool
forall a. Eq a => a -> a -> Bool
== Ordering
EQ) ([GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
 -> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)])
-> ([GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
    -> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)])
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
 -> GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> Ordering)
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
forall a. (a -> a -> Ordering) -> [a] -> [a]
sortBy LIEWrappedName GhcPs -> LIEWrappedName GhcPs -> Ordering
GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
-> GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> Ordering
compareLIewn
          alter :: Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
-> Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
alter = \case
            Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
Nothing -> GenLocated SrcSpanAnnA (IE GhcPs)
-> Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
forall a. a -> Maybe a
Just (GenLocated SrcSpanAnnA (IE GhcPs)
 -> Maybe (GenLocated SrcSpanAnnA (IE GhcPs)))
-> (IE GhcPs -> GenLocated SrcSpanAnnA (IE GhcPs))
-> IE GhcPs
-> Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SrcSpanAnnA -> IE GhcPs -> GenLocated SrcSpanAnnA (IE GhcPs)
forall l e. l -> e -> GenLocated l e
L SrcSpanAnnA
new_l (IE GhcPs -> Maybe (GenLocated SrcSpanAnnA (IE GhcPs)))
-> IE GhcPs -> Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
forall a b. (a -> b) -> a -> b
$
              case IE GhcPs
new of
                IEThingWith XIEThingWith GhcPs
x LIEWrappedName GhcPs
n IEWildcard
wildcard [LIEWrappedName GhcPs]
g Maybe (ExportDoc GhcPs)
_ ->
                  XIEThingWith GhcPs
-> LIEWrappedName GhcPs
-> IEWildcard
-> [LIEWrappedName GhcPs]
-> Maybe (ExportDoc GhcPs)
-> IE GhcPs
forall pass.
XIEThingWith pass
-> LIEWrappedName pass
-> IEWildcard
-> [LIEWrappedName pass]
-> Maybe (ExportDoc pass)
-> IE pass
IEThingWith XIEThingWith GhcPs
x LIEWrappedName GhcPs
n IEWildcard
wildcard ([GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
normalizeWNames [LIEWrappedName GhcPs]
[GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
g) Maybe (ExportDoc GhcPs)
forall a. Maybe a
Nothing
                IE GhcPs
other -> IE GhcPs
other
            Just GenLocated SrcSpanAnnA (IE GhcPs)
old ->
              let f :: IE GhcPs -> IE GhcPs
f = \case
                    IEVar XIEVar GhcPs
_ LIEWrappedName GhcPs
n Maybe (ExportDoc GhcPs)
_ -> XIEVar GhcPs
-> LIEWrappedName GhcPs -> Maybe (ExportDoc GhcPs) -> IE GhcPs
forall pass.
XIEVar pass
-> LIEWrappedName pass -> Maybe (ExportDoc pass) -> IE pass
IEVar Maybe (GenLocated SrcSpanAnnP (WarningTxt GhcPs))
XIEVar GhcPs
forall a. Maybe a
Nothing LIEWrappedName GhcPs
n Maybe (ExportDoc GhcPs)
forall a. Maybe a
Nothing
                    IEThingAbs XIEThingAbs GhcPs
_ LIEWrappedName GhcPs
_ Maybe (ExportDoc GhcPs)
_ -> IE GhcPs
new
                    IEThingAll XIEThingAll GhcPs
x LIEWrappedName GhcPs
n Maybe (ExportDoc GhcPs)
_ -> XIEThingAll GhcPs
-> LIEWrappedName GhcPs -> Maybe (ExportDoc GhcPs) -> IE GhcPs
forall pass.
XIEThingAll pass
-> LIEWrappedName pass -> Maybe (ExportDoc pass) -> IE pass
IEThingAll XIEThingAll GhcPs
x LIEWrappedName GhcPs
n Maybe (ExportDoc GhcPs)
forall a. Maybe a
Nothing
                    IEThingWith XIEThingWith GhcPs
_ LIEWrappedName GhcPs
n IEWildcard
wildcard [LIEWrappedName GhcPs]
g Maybe (ExportDoc GhcPs)
_ ->
                      case IE GhcPs
new of
                        IEVar XIEVar GhcPs
_ LIEWrappedName GhcPs
_ Maybe (ExportDoc GhcPs)
_ ->
                          String -> IE GhcPs
forall a. HasCallStack => String -> a
error String
"Ormolu.Imports broken presupposition"
                        IEThingAbs XIEThingAbs GhcPs
x LIEWrappedName GhcPs
_ Maybe (ExportDoc GhcPs)
_ ->
                          XIEThingWith GhcPs
-> LIEWrappedName GhcPs
-> IEWildcard
-> [LIEWrappedName GhcPs]
-> Maybe (ExportDoc GhcPs)
-> IE GhcPs
forall pass.
XIEThingWith pass
-> LIEWrappedName pass
-> IEWildcard
-> [LIEWrappedName pass]
-> Maybe (ExportDoc pass)
-> IE pass
IEThingWith (Maybe (GenLocated SrcSpanAnnP (WarningTxt GhcPs))
XIEThingAbs GhcPs
x, IEThingWithAnns
forall a. NoAnn a => a
noAnn) LIEWrappedName GhcPs
n IEWildcard
wildcard [LIEWrappedName GhcPs]
g Maybe (ExportDoc GhcPs)
forall a. Maybe a
Nothing
                        IEThingAll XIEThingAll GhcPs
x LIEWrappedName GhcPs
n' Maybe (ExportDoc GhcPs)
_ ->
                          XIEThingAll GhcPs
-> LIEWrappedName GhcPs -> Maybe (ExportDoc GhcPs) -> IE GhcPs
forall pass.
XIEThingAll pass
-> LIEWrappedName pass -> Maybe (ExportDoc pass) -> IE pass
IEThingAll XIEThingAll GhcPs
x LIEWrappedName GhcPs
n' Maybe (ExportDoc GhcPs)
forall a. Maybe a
Nothing
                        IEThingWith XIEThingWith GhcPs
x LIEWrappedName GhcPs
n' IEWildcard
wildcard' [LIEWrappedName GhcPs]
g' Maybe (ExportDoc GhcPs)
_ ->
                          let combinedWildcard :: IEWildcard
combinedWildcard =
                                case (IEWildcard
wildcard, IEWildcard
wildcard') of
                                  (IEWildcard Int
_, IEWildcard
_) -> Int -> IEWildcard
IEWildcard Int
0
                                  (IEWildcard
_, IEWildcard Int
_) -> Int -> IEWildcard
IEWildcard Int
0
                                  (IEWildcard, IEWildcard)
_ -> IEWildcard
NoIEWildcard
                           in XIEThingWith GhcPs
-> LIEWrappedName GhcPs
-> IEWildcard
-> [LIEWrappedName GhcPs]
-> Maybe (ExportDoc GhcPs)
-> IE GhcPs
forall pass.
XIEThingWith pass
-> LIEWrappedName pass
-> IEWildcard
-> [LIEWrappedName pass]
-> Maybe (ExportDoc pass)
-> IE pass
IEThingWith
                                XIEThingWith GhcPs
x
                                LIEWrappedName GhcPs
n'
                                IEWildcard
combinedWildcard
                                ([GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
normalizeWNames ([LIEWrappedName GhcPs]
[GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
g [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
-> [GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
forall a. Semigroup a => a -> a -> a
<> [LIEWrappedName GhcPs]
[GenLocated SrcSpanAnnA (IEWrappedName GhcPs)]
g'))
                                Maybe (ExportDoc GhcPs)
forall a. Maybe a
Nothing
                        IEModuleContents XIEModuleContents GhcPs
_ XRec GhcPs ModuleName
_ -> String -> IE GhcPs
forall a. String -> a
notImplemented String
"IEModuleContents"
                        IEGroup XIEGroup GhcPs
NoExtField
NoExtField Int
_ ExportDoc GhcPs
_ -> String -> IE GhcPs
forall a. String -> a
notImplemented String
"IEGroup"
                        IEDoc XIEDoc GhcPs
NoExtField
NoExtField ExportDoc GhcPs
_ -> String -> IE GhcPs
forall a. String -> a
notImplemented String
"IEDoc"
                        IEDocNamed XIEDocNamed GhcPs
NoExtField
NoExtField String
_ -> String -> IE GhcPs
forall a. String -> a
notImplemented String
"IEDocNamed"
                    IEModuleContents XIEModuleContents GhcPs
_ XRec GhcPs ModuleName
_ -> String -> IE GhcPs
forall a. String -> a
notImplemented String
"IEModuleContents"
                    IEGroup XIEGroup GhcPs
NoExtField
NoExtField Int
_ ExportDoc GhcPs
_ -> String -> IE GhcPs
forall a. String -> a
notImplemented String
"IEGroup"
                    IEDoc XIEDoc GhcPs
NoExtField
NoExtField ExportDoc GhcPs
_ -> String -> IE GhcPs
forall a. String -> a
notImplemented String
"IEDoc"
                    IEDocNamed XIEDocNamed GhcPs
NoExtField
NoExtField String
_ -> String -> IE GhcPs
forall a. String -> a
notImplemented String
"IEDocNamed"
               in GenLocated SrcSpanAnnA (IE GhcPs)
-> Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
forall a. a -> Maybe a
Just (IE GhcPs -> IE GhcPs
f (IE GhcPs -> IE GhcPs)
-> GenLocated SrcSpanAnnA (IE GhcPs)
-> GenLocated SrcSpanAnnA (IE GhcPs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenLocated SrcSpanAnnA (IE GhcPs)
old)
       in (Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
 -> Maybe (GenLocated SrcSpanAnnA (IE GhcPs)))
-> IEWrappedNameOrd
-> Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
-> Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
forall k a.
Ord k =>
(Maybe a -> Maybe a) -> k -> Map k a -> Map k a
M.alter Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
-> Maybe (GenLocated SrcSpanAnnA (IE GhcPs))
alter IEWrappedNameOrd
wname Map IEWrappedNameOrd (LIE GhcPs)
Map IEWrappedNameOrd (GenLocated SrcSpanAnnA (IE GhcPs))
m

-- | A wrapper for @'IEWrappedName' 'GhcPs'@ that allows us to define an
-- 'Ord' instance for it.
newtype IEWrappedNameOrd = IEWrappedNameOrd (IEWrappedName GhcPs)
  deriving (IEWrappedNameOrd -> IEWrappedNameOrd -> Bool
(IEWrappedNameOrd -> IEWrappedNameOrd -> Bool)
-> (IEWrappedNameOrd -> IEWrappedNameOrd -> Bool)
-> Eq IEWrappedNameOrd
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: IEWrappedNameOrd -> IEWrappedNameOrd -> Bool
== :: IEWrappedNameOrd -> IEWrappedNameOrd -> Bool
$c/= :: IEWrappedNameOrd -> IEWrappedNameOrd -> Bool
/= :: IEWrappedNameOrd -> IEWrappedNameOrd -> Bool
Eq)

instance Ord IEWrappedNameOrd where
  compare :: IEWrappedNameOrd -> IEWrappedNameOrd -> Ordering
compare (IEWrappedNameOrd IEWrappedName GhcPs
x) (IEWrappedNameOrd IEWrappedName GhcPs
y) = IEWrappedName GhcPs -> IEWrappedName GhcPs -> Ordering
compareIewn IEWrappedName GhcPs
x IEWrappedName GhcPs
y

-- | Project @'IEWrappedName' 'GhcPs'@ from @'IE' 'GhcPs'@.
getIewn :: IE GhcPs -> IEWrappedNameOrd
getIewn :: IE GhcPs -> IEWrappedNameOrd
getIewn = \case
  IEVar XIEVar GhcPs
_ LIEWrappedName GhcPs
x Maybe (ExportDoc GhcPs)
_ -> IEWrappedName GhcPs -> IEWrappedNameOrd
IEWrappedNameOrd (GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> IEWrappedName GhcPs
forall l e. GenLocated l e -> e
unLoc LIEWrappedName GhcPs
GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
x)
  IEThingAbs XIEThingAbs GhcPs
_ LIEWrappedName GhcPs
x Maybe (ExportDoc GhcPs)
_ -> IEWrappedName GhcPs -> IEWrappedNameOrd
IEWrappedNameOrd (GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> IEWrappedName GhcPs
forall l e. GenLocated l e -> e
unLoc LIEWrappedName GhcPs
GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
x)
  IEThingAll XIEThingAll GhcPs
_ LIEWrappedName GhcPs
x Maybe (ExportDoc GhcPs)
_ -> IEWrappedName GhcPs -> IEWrappedNameOrd
IEWrappedNameOrd (GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> IEWrappedName GhcPs
forall l e. GenLocated l e -> e
unLoc LIEWrappedName GhcPs
GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
x)
  IEThingWith XIEThingWith GhcPs
_ LIEWrappedName GhcPs
x IEWildcard
_ [LIEWrappedName GhcPs]
_ Maybe (ExportDoc GhcPs)
_ -> IEWrappedName GhcPs -> IEWrappedNameOrd
IEWrappedNameOrd (GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> IEWrappedName GhcPs
forall l e. GenLocated l e -> e
unLoc LIEWrappedName GhcPs
GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
x)
  IEModuleContents XIEModuleContents GhcPs
_ XRec GhcPs ModuleName
_ -> String -> IEWrappedNameOrd
forall a. String -> a
notImplemented String
"IEModuleContents"
  IEGroup XIEGroup GhcPs
NoExtField
NoExtField Int
_ ExportDoc GhcPs
_ -> String -> IEWrappedNameOrd
forall a. String -> a
notImplemented String
"IEGroup"
  IEDoc XIEDoc GhcPs
NoExtField
NoExtField ExportDoc GhcPs
_ -> String -> IEWrappedNameOrd
forall a. String -> a
notImplemented String
"IEDoc"
  IEDocNamed XIEDocNamed GhcPs
NoExtField
NoExtField String
_ -> String -> IEWrappedNameOrd
forall a. String -> a
notImplemented String
"IEDocNamed"

-- | Like 'compareIewn' for located wrapped names.
compareLIewn :: LIEWrappedName GhcPs -> LIEWrappedName GhcPs -> Ordering
compareLIewn :: LIEWrappedName GhcPs -> LIEWrappedName GhcPs -> Ordering
compareLIewn = IEWrappedName GhcPs -> IEWrappedName GhcPs -> Ordering
compareIewn (IEWrappedName GhcPs -> IEWrappedName GhcPs -> Ordering)
-> (GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
    -> IEWrappedName GhcPs)
-> GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
-> GenLocated SrcSpanAnnA (IEWrappedName GhcPs)
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` GenLocated SrcSpanAnnA (IEWrappedName GhcPs) -> IEWrappedName GhcPs
forall l e. GenLocated l e -> e
unLoc

-- | Compare two @'IEWrapppedName' 'GhcPs'@ things.
compareIewn :: IEWrappedName GhcPs -> IEWrappedName GhcPs -> Ordering
compareIewn :: IEWrappedName GhcPs -> IEWrappedName GhcPs -> Ordering
compareIewn = (((Int, GenLocated SrcSpanAnnN RdrName) -> Int)
-> (Int, GenLocated SrcSpanAnnN RdrName)
-> (Int, GenLocated SrcSpanAnnN RdrName)
-> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing (Int, GenLocated SrcSpanAnnN RdrName) -> Int
forall a b. (a, b) -> a
fst ((Int, GenLocated SrcSpanAnnN RdrName)
 -> (Int, GenLocated SrcSpanAnnN RdrName) -> Ordering)
-> ((Int, GenLocated SrcSpanAnnN RdrName)
    -> (Int, GenLocated SrcSpanAnnN RdrName) -> Ordering)
-> (Int, GenLocated SrcSpanAnnN RdrName)
-> (Int, GenLocated SrcSpanAnnN RdrName)
-> Ordering
forall a. Semigroup a => a -> a -> a
<> (RdrName -> RdrName -> Ordering
compareRdrName (RdrName -> RdrName -> Ordering)
-> ((Int, GenLocated SrcSpanAnnN RdrName) -> RdrName)
-> (Int, GenLocated SrcSpanAnnN RdrName)
-> (Int, GenLocated SrcSpanAnnN RdrName)
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` GenLocated SrcSpanAnnN RdrName -> RdrName
forall l e. GenLocated l e -> e
unLoc (GenLocated SrcSpanAnnN RdrName -> RdrName)
-> ((Int, GenLocated SrcSpanAnnN RdrName)
    -> GenLocated SrcSpanAnnN RdrName)
-> (Int, GenLocated SrcSpanAnnN RdrName)
-> RdrName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, GenLocated SrcSpanAnnN RdrName)
-> GenLocated SrcSpanAnnN RdrName
forall a b. (a, b) -> b
snd)) ((Int, GenLocated SrcSpanAnnN RdrName)
 -> (Int, GenLocated SrcSpanAnnN RdrName) -> Ordering)
-> (IEWrappedName GhcPs -> (Int, GenLocated SrcSpanAnnN RdrName))
-> IEWrappedName GhcPs
-> IEWrappedName GhcPs
-> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` IEWrappedName GhcPs -> (Int, GenLocated SrcSpanAnnN RdrName)
classify
  where
    classify :: IEWrappedName GhcPs -> (Int, LocatedN RdrName)
    classify :: IEWrappedName GhcPs -> (Int, GenLocated SrcSpanAnnN RdrName)
classify = \case
      IEName XIEName GhcPs
_ LIdP GhcPs
x -> (Int
0, LIdP GhcPs
GenLocated SrcSpanAnnN RdrName
x)
      IEDefault XIEDefault GhcPs
_ LIdP GhcPs
x -> (Int
1, LIdP GhcPs
GenLocated SrcSpanAnnN RdrName
x)
      IEPattern XIEPattern GhcPs
_ LIdP GhcPs
x -> (Int
2, LIdP GhcPs
GenLocated SrcSpanAnnN RdrName
x)
      IEType XIEType GhcPs
_ LIdP GhcPs
x -> (Int
3, LIdP GhcPs
GenLocated SrcSpanAnnN RdrName
x)

compareRdrName :: RdrName -> RdrName -> Ordering
compareRdrName :: RdrName -> RdrName -> Ordering
compareRdrName RdrName
x RdrName
y =
  case (RdrName -> String
getNameStr RdrName
x, RdrName -> String
getNameStr RdrName
y) of
    ([], []) -> Ordering
EQ
    ((Char
_ : String
_), []) -> Ordering
GT
    ([], (Char
_ : String
_)) -> Ordering
LT
    ((Char
x' : String
_), (Char
y' : String
_)) ->
      case (Char -> Bool
isAlphaNum Char
x', Char -> Bool
isAlphaNum Char
y') of
        (Bool
False, Bool
False) -> RdrName
x RdrName -> RdrName -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` RdrName
y
        (Bool
True, Bool
False) -> Ordering
LT
        (Bool
False, Bool
True) -> Ordering
GT
        (Bool
True, Bool
True) -> RdrName
x RdrName -> RdrName -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` RdrName
y
  where
    getNameStr :: RdrName -> String
getNameStr = OccName -> String
forall o. Outputable o => o -> String
showOutputable (OccName -> String) -> (RdrName -> OccName) -> RdrName -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RdrName -> OccName
rdrNameOcc