{-# LANGUAGE DerivingVia    #-}
{-# LANGUAGE GADTs          #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes     #-}

module Development.IDE.Core.UseStale
  ( Age(..)
  , Tracked
  , unTrack
  , PositionMap
  , TrackedStale (..)
  , untrackedStaleValue
  , unsafeMkStale
  , unsafeMkCurrent
  , unsafeCopyAge
  , MapAge (..)
  , dualPositionMap
  , useWithStale
  , useWithStale_
  ) where

import           Control.Arrow
import           Control.Category                     (Category)
import qualified Control.Category                     as C
import           Control.DeepSeq                      (NFData)
import           Data.Aeson
import           Data.Coerce                          (coerce)
import           Data.Functor                         ((<&>))
import           Data.Functor.Identity                (Identity (Identity))
import           Data.Kind                            (Type)
import           Data.String                          (fromString)
import           Development.IDE                      (Action, IdeRule,
                                                       NormalizedFilePath,
                                                       Range,
                                                       rangeToRealSrcSpan,
                                                       realSrcSpanToRange)
import qualified Development.IDE.Core.PositionMapping as P
import qualified Development.IDE.Core.Shake           as IDE
import           Development.IDE.GHC.Compat           (RealSrcSpan, srcSpanFile)
import           Development.IDE.GHC.Compat.Util      (unpackFS)


------------------------------------------------------------------------------
-- | A data kind for 'Tracked'.
data Age = Current | Stale Type


------------------------------------------------------------------------------
-- | Some value, tagged with its age. All 'Current' ages are considered to be
-- the same thing, but 'Stale' values are protected by an untouchable variable
-- to ensure they can't be unified.
newtype Tracked (age :: Age) a  = UnsafeTracked
  { forall (age :: Age) a. Tracked age a -> a
unTrack :: a
  }
  deriving stock (forall a b. a -> Tracked age b -> Tracked age a
forall a b. (a -> b) -> Tracked age a -> Tracked age b
forall (age :: Age) a b. a -> Tracked age b -> Tracked age a
forall (age :: Age) a b. (a -> b) -> Tracked age a -> Tracked age b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> Tracked age b -> Tracked age a
$c<$ :: forall (age :: Age) a b. a -> Tracked age b -> Tracked age a
fmap :: forall a b. (a -> b) -> Tracked age a -> Tracked age b
$cfmap :: forall (age :: Age) a b. (a -> b) -> Tracked age a -> Tracked age b
Functor, forall a. Tracked age a -> Bool
forall m a. Monoid m => (a -> m) -> Tracked age a -> m
forall a b. (a -> b -> b) -> b -> Tracked age a -> b
forall (age :: Age) a. Eq a => a -> Tracked age a -> Bool
forall (age :: Age) a. Num a => Tracked age a -> a
forall (age :: Age) a. Ord a => Tracked age a -> a
forall (age :: Age) m. Monoid m => Tracked age m -> m
forall (age :: Age) a. Tracked age a -> Bool
forall (age :: Age) a. Tracked age a -> Int
forall (age :: Age) a. Tracked age a -> [a]
forall (age :: Age) a. (a -> a -> a) -> Tracked age a -> a
forall (age :: Age) m a. Monoid m => (a -> m) -> Tracked age a -> m
forall (age :: Age) b a. (b -> a -> b) -> b -> Tracked age a -> b
forall (age :: Age) a b. (a -> b -> b) -> b -> Tracked age a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => Tracked age a -> a
$cproduct :: forall (age :: Age) a. Num a => Tracked age a -> a
sum :: forall a. Num a => Tracked age a -> a
$csum :: forall (age :: Age) a. Num a => Tracked age a -> a
minimum :: forall a. Ord a => Tracked age a -> a
$cminimum :: forall (age :: Age) a. Ord a => Tracked age a -> a
maximum :: forall a. Ord a => Tracked age a -> a
$cmaximum :: forall (age :: Age) a. Ord a => Tracked age a -> a
elem :: forall a. Eq a => a -> Tracked age a -> Bool
$celem :: forall (age :: Age) a. Eq a => a -> Tracked age a -> Bool
length :: forall a. Tracked age a -> Int
$clength :: forall (age :: Age) a. Tracked age a -> Int
null :: forall a. Tracked age a -> Bool
$cnull :: forall (age :: Age) a. Tracked age a -> Bool
toList :: forall a. Tracked age a -> [a]
$ctoList :: forall (age :: Age) a. Tracked age a -> [a]
foldl1 :: forall a. (a -> a -> a) -> Tracked age a -> a
$cfoldl1 :: forall (age :: Age) a. (a -> a -> a) -> Tracked age a -> a
foldr1 :: forall a. (a -> a -> a) -> Tracked age a -> a
$cfoldr1 :: forall (age :: Age) a. (a -> a -> a) -> Tracked age a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> Tracked age a -> b
$cfoldl' :: forall (age :: Age) b a. (b -> a -> b) -> b -> Tracked age a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Tracked age a -> b
$cfoldl :: forall (age :: Age) b a. (b -> a -> b) -> b -> Tracked age a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Tracked age a -> b
$cfoldr' :: forall (age :: Age) a b. (a -> b -> b) -> b -> Tracked age a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Tracked age a -> b
$cfoldr :: forall (age :: Age) a b. (a -> b -> b) -> b -> Tracked age a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> Tracked age a -> m
$cfoldMap' :: forall (age :: Age) m a. Monoid m => (a -> m) -> Tracked age a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Tracked age a -> m
$cfoldMap :: forall (age :: Age) m a. Monoid m => (a -> m) -> Tracked age a -> m
fold :: forall m. Monoid m => Tracked age m -> m
$cfold :: forall (age :: Age) m. Monoid m => Tracked age m -> m
Foldable, forall (age :: Age). Functor (Tracked age)
forall (age :: Age). Foldable (Tracked age)
forall (age :: Age) (m :: * -> *) a.
Monad m =>
Tracked age (m a) -> m (Tracked age a)
forall (age :: Age) (f :: * -> *) a.
Applicative f =>
Tracked age (f a) -> f (Tracked age a)
forall (age :: Age) (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Tracked age a -> m (Tracked age b)
forall (age :: Age) (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tracked age a -> f (Tracked age b)
forall (t :: * -> *).
Functor t
-> Foldable t
-> (forall (f :: * -> *) a b.
    Applicative f =>
    (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tracked age a -> f (Tracked age b)
sequence :: forall (m :: * -> *) a.
Monad m =>
Tracked age (m a) -> m (Tracked age a)
$csequence :: forall (age :: Age) (m :: * -> *) a.
Monad m =>
Tracked age (m a) -> m (Tracked age a)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Tracked age a -> m (Tracked age b)
$cmapM :: forall (age :: Age) (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Tracked age a -> m (Tracked age b)
sequenceA :: forall (f :: * -> *) a.
Applicative f =>
Tracked age (f a) -> f (Tracked age a)
$csequenceA :: forall (age :: Age) (f :: * -> *) a.
Applicative f =>
Tracked age (f a) -> f (Tracked age a)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tracked age a -> f (Tracked age b)
$ctraverse :: forall (age :: Age) (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tracked age a -> f (Tracked age b)
Traversable)
  deriving newtype (Tracked age a -> Tracked age a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (age :: Age) a.
Eq a =>
Tracked age a -> Tracked age a -> Bool
/= :: Tracked age a -> Tracked age a -> Bool
$c/= :: forall (age :: Age) a.
Eq a =>
Tracked age a -> Tracked age a -> Bool
== :: Tracked age a -> Tracked age a -> Bool
$c== :: forall (age :: Age) a.
Eq a =>
Tracked age a -> Tracked age a -> Bool
Eq, Tracked age a -> Tracked age a -> Bool
Tracked age a -> Tracked age a -> Ordering
Tracked age a -> Tracked age a -> Tracked age a
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
forall {age :: Age} {a}. Ord a => Eq (Tracked age a)
forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Bool
forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Ordering
forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Tracked age a
min :: Tracked age a -> Tracked age a -> Tracked age a
$cmin :: forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Tracked age a
max :: Tracked age a -> Tracked age a -> Tracked age a
$cmax :: forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Tracked age a
>= :: Tracked age a -> Tracked age a -> Bool
$c>= :: forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Bool
> :: Tracked age a -> Tracked age a -> Bool
$c> :: forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Bool
<= :: Tracked age a -> Tracked age a -> Bool
$c<= :: forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Bool
< :: Tracked age a -> Tracked age a -> Bool
$c< :: forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Bool
compare :: Tracked age a -> Tracked age a -> Ordering
$ccompare :: forall (age :: Age) a.
Ord a =>
Tracked age a -> Tracked age a -> Ordering
Ord, Int -> Tracked age a -> ShowS
[Tracked age a] -> ShowS
Tracked age a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (age :: Age) a. Show a => Int -> Tracked age a -> ShowS
forall (age :: Age) a. Show a => [Tracked age a] -> ShowS
forall (age :: Age) a. Show a => Tracked age a -> String
showList :: [Tracked age a] -> ShowS
$cshowList :: forall (age :: Age) a. Show a => [Tracked age a] -> ShowS
show :: Tracked age a -> String
$cshow :: forall (age :: Age) a. Show a => Tracked age a -> String
showsPrec :: Int -> Tracked age a -> ShowS
$cshowsPrec :: forall (age :: Age) a. Show a => Int -> Tracked age a -> ShowS
Show, ReadPrec [Tracked age a]
ReadPrec (Tracked age a)
Int -> ReadS (Tracked age a)
ReadS [Tracked age a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall (age :: Age) a. Read a => ReadPrec [Tracked age a]
forall (age :: Age) a. Read a => ReadPrec (Tracked age a)
forall (age :: Age) a. Read a => Int -> ReadS (Tracked age a)
forall (age :: Age) a. Read a => ReadS [Tracked age a]
readListPrec :: ReadPrec [Tracked age a]
$creadListPrec :: forall (age :: Age) a. Read a => ReadPrec [Tracked age a]
readPrec :: ReadPrec (Tracked age a)
$creadPrec :: forall (age :: Age) a. Read a => ReadPrec (Tracked age a)
readList :: ReadS [Tracked age a]
$creadList :: forall (age :: Age) a. Read a => ReadS [Tracked age a]
readsPrec :: Int -> ReadS (Tracked age a)
$creadsPrec :: forall (age :: Age) a. Read a => Int -> ReadS (Tracked age a)
Read, [Tracked age a] -> Encoding
[Tracked age a] -> Value
Tracked age a -> Encoding
Tracked age a -> Value
forall a.
(a -> Value)
-> (a -> Encoding)
-> ([a] -> Value)
-> ([a] -> Encoding)
-> ToJSON a
forall (age :: Age) a. ToJSON a => [Tracked age a] -> Encoding
forall (age :: Age) a. ToJSON a => [Tracked age a] -> Value
forall (age :: Age) a. ToJSON a => Tracked age a -> Encoding
forall (age :: Age) a. ToJSON a => Tracked age a -> Value
toEncodingList :: [Tracked age a] -> Encoding
$ctoEncodingList :: forall (age :: Age) a. ToJSON a => [Tracked age a] -> Encoding
toJSONList :: [Tracked age a] -> Value
$ctoJSONList :: forall (age :: Age) a. ToJSON a => [Tracked age a] -> Value
toEncoding :: Tracked age a -> Encoding
$ctoEncoding :: forall (age :: Age) a. ToJSON a => Tracked age a -> Encoding
toJSON :: Tracked age a -> Value
$ctoJSON :: forall (age :: Age) a. ToJSON a => Tracked age a -> Value
ToJSON, Value -> Parser [Tracked age a]
Value -> Parser (Tracked age a)
forall a.
(Value -> Parser a) -> (Value -> Parser [a]) -> FromJSON a
forall (age :: Age) a.
FromJSON a =>
Value -> Parser [Tracked age a]
forall (age :: Age) a.
FromJSON a =>
Value -> Parser (Tracked age a)
parseJSONList :: Value -> Parser [Tracked age a]
$cparseJSONList :: forall (age :: Age) a.
FromJSON a =>
Value -> Parser [Tracked age a]
parseJSON :: Value -> Parser (Tracked age a)
$cparseJSON :: forall (age :: Age) a.
FromJSON a =>
Value -> Parser (Tracked age a)
FromJSON, Tracked age a -> ()
forall a. (a -> ()) -> NFData a
forall (age :: Age) a. NFData a => Tracked age a -> ()
rnf :: Tracked age a -> ()
$crnf :: forall (age :: Age) a. NFData a => Tracked age a -> ()
NFData)
  deriving (forall a. a -> Tracked age a
forall a b. Tracked age a -> Tracked age b -> Tracked age a
forall a b. Tracked age a -> Tracked age b -> Tracked age b
forall a b. Tracked age (a -> b) -> Tracked age a -> Tracked age b
forall a b c.
(a -> b -> c) -> Tracked age a -> Tracked age b -> Tracked age c
forall (age :: Age). Functor (Tracked age)
forall (age :: Age) a. a -> Tracked age a
forall (age :: Age) a b.
Tracked age a -> Tracked age b -> Tracked age a
forall (age :: Age) a b.
Tracked age a -> Tracked age b -> Tracked age b
forall (age :: Age) a b.
Tracked age (a -> b) -> Tracked age a -> Tracked age b
forall (age :: Age) a b c.
(a -> b -> c) -> Tracked age a -> Tracked age b -> Tracked age c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. Tracked age a -> Tracked age b -> Tracked age a
$c<* :: forall (age :: Age) a b.
Tracked age a -> Tracked age b -> Tracked age a
*> :: forall a b. Tracked age a -> Tracked age b -> Tracked age b
$c*> :: forall (age :: Age) a b.
Tracked age a -> Tracked age b -> Tracked age b
liftA2 :: forall a b c.
(a -> b -> c) -> Tracked age a -> Tracked age b -> Tracked age c
$cliftA2 :: forall (age :: Age) a b c.
(a -> b -> c) -> Tracked age a -> Tracked age b -> Tracked age c
<*> :: forall a b. Tracked age (a -> b) -> Tracked age a -> Tracked age b
$c<*> :: forall (age :: Age) a b.
Tracked age (a -> b) -> Tracked age a -> Tracked age b
pure :: forall a. a -> Tracked age a
$cpure :: forall (age :: Age) a. a -> Tracked age a
Applicative, forall a. a -> Tracked age a
forall a b. Tracked age a -> Tracked age b -> Tracked age b
forall a b. Tracked age a -> (a -> Tracked age b) -> Tracked age b
forall (age :: Age). Applicative (Tracked age)
forall (age :: Age) a. a -> Tracked age a
forall (age :: Age) a b.
Tracked age a -> Tracked age b -> Tracked age b
forall (age :: Age) a b.
Tracked age a -> (a -> Tracked age b) -> Tracked age b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> Tracked age a
$creturn :: forall (age :: Age) a. a -> Tracked age a
>> :: forall a b. Tracked age a -> Tracked age b -> Tracked age b
$c>> :: forall (age :: Age) a b.
Tracked age a -> Tracked age b -> Tracked age b
>>= :: forall a b. Tracked age a -> (a -> Tracked age b) -> Tracked age b
$c>>= :: forall (age :: Age) a b.
Tracked age a -> (a -> Tracked age b) -> Tracked age b
Monad) via Identity


------------------------------------------------------------------------------
-- | Like 'P.PositionMapping', but with annotated ages for how 'Tracked' values
-- change. Use the 'Category' instance to compose 'PositionMapping's in order
-- to transform between values of different stale ages.
newtype PositionMap (from :: Age) (to :: Age) = PositionMap
  { forall (from :: Age) (to :: Age).
PositionMap from to -> PositionMapping
_getPositionMapping :: P.PositionMapping
  }

instance Category PositionMap where
  id :: forall (a :: Age). PositionMap a a
id  = coerce :: forall a b. Coercible a b => a -> b
coerce PositionMapping
P.zeroMapping
  . :: forall (b :: Age) (c :: Age) (a :: Age).
PositionMap b c -> PositionMap a b -> PositionMap a c
(.) = coerce :: forall a b. Coercible a b => a -> b
coerce PositionDelta -> PositionDelta -> PositionDelta
P.composeDelta


------------------------------------------------------------------------------
-- | Get a 'PositionMap' that runs in the opposite direction.
dualPositionMap :: PositionMap from to -> PositionMap to from
dualPositionMap :: forall (from :: Age) (to :: Age).
PositionMap from to -> PositionMap to from
dualPositionMap (PositionMap (P.PositionMapping (P.PositionDelta Position -> PositionResult Position
from Position -> PositionResult Position
to))) =
  forall (from :: Age) (to :: Age).
PositionMapping -> PositionMap from to
PositionMap forall a b. (a -> b) -> a -> b
$ PositionDelta -> PositionMapping
P.PositionMapping forall a b. (a -> b) -> a -> b
$ (Position -> PositionResult Position)
-> (Position -> PositionResult Position) -> PositionDelta
P.PositionDelta Position -> PositionResult Position
to Position -> PositionResult Position
from


------------------------------------------------------------------------------
-- | A pair containing a @'Tracked' 'Stale'@ value, as well as
-- a 'PositionMapping' that will fast-forward values to the current age.
data TrackedStale a where
  TrackedStale
      :: Tracked (Stale s) a
      -> PositionMap (Stale s) Current
      -> TrackedStale a

instance Functor TrackedStale where
  fmap :: forall a b. (a -> b) -> TrackedStale a -> TrackedStale b
fmap a -> b
f (TrackedStale Tracked ('Stale s) a
t PositionMap ('Stale s) 'Current
pm) = forall s a.
Tracked ('Stale s) a
-> PositionMap ('Stale s) 'Current -> TrackedStale a
TrackedStale (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Tracked ('Stale s) a
t) PositionMap ('Stale s) 'Current
pm


untrackedStaleValue :: TrackedStale a -> a
untrackedStaleValue :: forall a. TrackedStale a -> a
untrackedStaleValue (TrackedStale Tracked ('Stale s) a
ta PositionMap ('Stale s) 'Current
_) = coerce :: forall a b. Coercible a b => a -> b
coerce Tracked ('Stale s) a
ta


------------------------------------------------------------------------------
-- | A class for which 'Tracked' values can be run across a 'PositionMapping'
-- to change their ages.
class MapAge a where
  {-# MINIMAL mapAgeFrom | mapAgeTo #-}
  mapAgeFrom :: PositionMap from to -> Tracked to   a -> Maybe (Tracked from a)
  mapAgeFrom = forall a (from :: Age) (to :: Age).
MapAge a =>
PositionMap from to -> Tracked from a -> Maybe (Tracked to a)
mapAgeTo forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (from :: Age) (to :: Age).
PositionMap from to -> PositionMap to from
dualPositionMap

  mapAgeTo   :: PositionMap from to -> Tracked from a -> Maybe (Tracked to   a)
  mapAgeTo = forall a (from :: Age) (to :: Age).
MapAge a =>
PositionMap from to -> Tracked to a -> Maybe (Tracked from a)
mapAgeFrom forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (from :: Age) (to :: Age).
PositionMap from to -> PositionMap to from
dualPositionMap


instance MapAge Range where
  mapAgeFrom :: forall (from :: Age) (to :: Age).
PositionMap from to
-> Tracked to Range -> Maybe (Tracked from Range)
mapAgeFrom = coerce :: forall a b. Coercible a b => a -> b
coerce PositionMapping -> Range -> Maybe Range
P.fromCurrentRange
  mapAgeTo :: forall (from :: Age) (to :: Age).
PositionMap from to
-> Tracked from Range -> Maybe (Tracked to Range)
mapAgeTo   = coerce :: forall a b. Coercible a b => a -> b
coerce PositionMapping -> Range -> Maybe Range
P.toCurrentRange


instance MapAge RealSrcSpan where
  mapAgeFrom :: forall (from :: Age) (to :: Age).
PositionMap from to
-> Tracked to RealSrcSpan -> Maybe (Tracked from RealSrcSpan)
mapAgeFrom =
    forall c a b (from :: Age) (to :: Age).
(c -> a -> b)
-> (b -> (c, a))
-> (Tracked from a -> Maybe (Tracked to a))
-> Tracked from b
-> Maybe (Tracked to b)
invMapAge (\FastString
fs -> NormalizedFilePath -> Range -> RealSrcSpan
rangeToRealSrcSpan (forall a. IsString a => String -> a
fromString forall a b. (a -> b) -> a -> b
$ FastString -> String
unpackFS FastString
fs))
              (RealSrcSpan -> FastString
srcSpanFile forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& RealSrcSpan -> Range
realSrcSpanToRange)
      forall b c a. (b -> c) -> (a -> b) -> a -> c
.  forall a (from :: Age) (to :: Age).
MapAge a =>
PositionMap from to -> Tracked to a -> Maybe (Tracked from a)
mapAgeFrom


------------------------------------------------------------------------------
-- | Helper function for deriving 'MapAge' for values in terms of other
-- instances.
invMapAge
    :: (c -> a -> b)
    -> (b -> (c, a))
    -> (Tracked from a -> Maybe (Tracked to a))
    -> Tracked from b
    -> Maybe (Tracked to b)
invMapAge :: forall c a b (from :: Age) (to :: Age).
(c -> a -> b)
-> (b -> (c, a))
-> (Tracked from a -> Maybe (Tracked to a))
-> Tracked from b
-> Maybe (Tracked to b)
invMapAge c -> a -> b
to b -> (c, a)
from Tracked from a -> Maybe (Tracked to a)
f Tracked from b
t =
  let (c
c, a
t') = forall (age :: Age) a. Tracked age a -> a
unTrack forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap b -> (c, a)
from Tracked from b
t
   in forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a -> b) -> a -> b
$ c -> a -> b
to c
c) forall a b. (a -> b) -> a -> b
$ Tracked from a -> Maybe (Tracked to a)
f forall a b. (a -> b) -> a -> b
$ forall (age :: Age) a. a -> Tracked age a
UnsafeTracked a
t'


unsafeMkCurrent :: age ->  Tracked 'Current age
unsafeMkCurrent :: forall age. age -> Tracked 'Current age
unsafeMkCurrent = coerce :: forall a b. Coercible a b => a -> b
coerce


unsafeMkStale :: age -> Tracked (Stale s) age
unsafeMkStale :: forall age s. age -> Tracked ('Stale s) age
unsafeMkStale = coerce :: forall a b. Coercible a b => a -> b
coerce


unsafeCopyAge :: Tracked age a -> b -> Tracked age b
unsafeCopyAge :: forall (age :: Age) a b. Tracked age a -> b -> Tracked age b
unsafeCopyAge Tracked age a
_ = coerce :: forall a b. Coercible a b => a -> b
coerce


-- | Request a Rule result, it not available return the last computed result, if any, which may be stale
useWithStale :: IdeRule k v
    => k -> NormalizedFilePath -> Action (Maybe (TrackedStale v))
useWithStale :: forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> Action (Maybe (TrackedStale v))
useWithStale k
key NormalizedFilePath
file = do
  Maybe (v, PositionMapping)
x <- forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> Action (Maybe (v, PositionMapping))
IDE.useWithStale k
key NormalizedFilePath
file
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Maybe (v, PositionMapping)
x forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(v
v, PositionMapping
pm) ->
    forall s a.
Tracked ('Stale s) a
-> PositionMap ('Stale s) 'Current -> TrackedStale a
TrackedStale (coerce :: forall a b. Coercible a b => a -> b
coerce v
v) (coerce :: forall a b. Coercible a b => a -> b
coerce PositionMapping
pm)

-- | Request a Rule result, it not available return the last computed result which may be stale.
--   Errors out if none available.
useWithStale_ :: IdeRule k v
    => k -> NormalizedFilePath -> Action (TrackedStale v)
useWithStale_ :: forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> Action (TrackedStale v)
useWithStale_ k
key NormalizedFilePath
file = do
  (v
v, PositionMapping
pm) <- forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> Action (v, PositionMapping)
IDE.useWithStale_ k
key NormalizedFilePath
file
  forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall s a.
Tracked ('Stale s) a
-> PositionMap ('Stale s) 'Current -> TrackedStale a
TrackedStale (coerce :: forall a b. Coercible a b => a -> b
coerce v
v) (coerce :: forall a b. Coercible a b => a -> b
coerce PositionMapping
pm)