{-# LANGUAGE ExistentialQuantification #-}
module Development.IDE.Types.Shake (Value(..), Values, Key(..), currentValue) where

import Control.DeepSeq
import Data.Dynamic
import Data.Hashable
import Data.HashMap.Strict
import Data.Typeable
import GHC.Generics
import Language.Haskell.LSP.Types

data Value v
    = Succeeded TextDocumentVersion v
    | Stale TextDocumentVersion v
    | Failed
    deriving (a -> Value b -> Value a
(a -> b) -> Value a -> Value b
(forall a b. (a -> b) -> Value a -> Value b)
-> (forall a b. a -> Value b -> Value a) -> Functor Value
forall a b. a -> Value b -> Value a
forall a b. (a -> b) -> Value a -> Value b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> Value b -> Value a
$c<$ :: forall a b. a -> Value b -> Value a
fmap :: (a -> b) -> Value a -> Value b
$cfmap :: forall a b. (a -> b) -> Value a -> Value b
Functor, (forall x. Value v -> Rep (Value v) x)
-> (forall x. Rep (Value v) x -> Value v) -> Generic (Value v)
forall x. Rep (Value v) x -> Value v
forall x. Value v -> Rep (Value v) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall v x. Rep (Value v) x -> Value v
forall v x. Value v -> Rep (Value v) x
$cto :: forall v x. Rep (Value v) x -> Value v
$cfrom :: forall v x. Value v -> Rep (Value v) x
Generic, Int -> Value v -> ShowS
[Value v] -> ShowS
Value v -> String
(Int -> Value v -> ShowS)
-> (Value v -> String) -> ([Value v] -> ShowS) -> Show (Value v)
forall v. Show v => Int -> Value v -> ShowS
forall v. Show v => [Value v] -> ShowS
forall v. Show v => Value v -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Value v] -> ShowS
$cshowList :: forall v. Show v => [Value v] -> ShowS
show :: Value v -> String
$cshow :: forall v. Show v => Value v -> String
showsPrec :: Int -> Value v -> ShowS
$cshowsPrec :: forall v. Show v => Int -> Value v -> ShowS
Show)

instance NFData v => NFData (Value v)

-- | Convert a Value to a Maybe. This will only return `Just` for

-- up2date results not for stale values.

currentValue :: Value v -> Maybe v
currentValue :: Value v -> Maybe v
currentValue (Succeeded TextDocumentVersion
_ v
v) = v -> Maybe v
forall a. a -> Maybe a
Just v
v
currentValue (Stale TextDocumentVersion
_ v
_) = Maybe v
forall a. Maybe a
Nothing
currentValue Value v
Failed = Maybe v
forall a. Maybe a
Nothing

-- | The state of the all values.

type Values = HashMap (NormalizedFilePath, Key) (Value Dynamic)

-- | Key type

data Key = forall k . (Typeable k, Hashable k, Eq k, Show k) => Key k

instance Show Key where
  show :: Key -> String
show (Key k
k) = k -> String
forall a. Show a => a -> String
show k
k

instance Eq Key where
    Key k
k1 == :: Key -> Key -> Bool
== Key k
k2 | Just k
k2' <- k -> Maybe k
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast k
k2 = k
k1 k -> k -> Bool
forall a. Eq a => a -> a -> Bool
== k
k2'
                     | Bool
otherwise = Bool
False

instance Hashable Key where
    hashWithSalt :: Int -> Key -> Int
hashWithSalt Int
salt (Key k
key) = Int -> (TypeRep, k) -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt (k -> TypeRep
forall a. Typeable a => a -> TypeRep
typeOf k
key, k
key)