{-# LANGUAGE GADTs          #-}
{-# LANGUAGE NamedFieldPuns #-}

module GhcTags.ETag
  ( module X
  , compareTags
  ) where

import           Data.Function (on)

import           GhcTags.ETag.Formatter as X
import           GhcTags.ETag.Parser    as X

import           GhcTags.Tag ( Tag (..)
                             , ETag
                             , TagAddress (..)
                             , tagFilePath
                             )


-- | Order 'ETag's according to filename & byteOffset
--
compareTags :: ETag -> ETag -> Ordering
compareTags :: ETag -> ETag -> Ordering
compareTags ETag
t0 ETag
t1 =
       (TagFilePath -> TagFilePath -> Ordering)
-> (ETag -> TagFilePath) -> ETag -> ETag -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on TagFilePath -> TagFilePath -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ETag -> TagFilePath
forall (tk :: TAG_KIND). Tag tk -> TagFilePath
tagFilePath ETag
t0 ETag
t1
    Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (Int -> Int -> Ordering)
-> (ETag -> Int) -> ETag -> ETag -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (\Tag {TagAddress 'ETAG
tagAddr :: forall (tk :: TAG_KIND). Tag tk -> TagAddress tk
tagAddr :: TagAddress 'ETAG
tagAddr} ->
                    case TagAddress 'ETAG
tagAddr of
                      TagLineCol Int
line Int
_ -> Int
line
                      TagLine Int
line      -> Int
line
                      TagAddress 'ETAG
NoAddress         -> Int
0
                  ) ETag
t0 ETag
t1
    Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> (TagName -> TagName -> Ordering)
-> (ETag -> TagName) -> ETag -> ETag -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
on TagName -> TagName -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ETag -> TagName
forall (tk :: TAG_KIND). Tag tk -> TagName
tagName ETag
t0 ETag
t1