-
-
Notifications
You must be signed in to change notification settings - Fork 389
Fix warnings in hls-graph, enable pedantic in CI #4047
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
79b4f4c
5a086fe
f03a6f2
c932d99
756b537
c5e2324
f926008
fca6e47
66f831d
a275fa1
36cb7d1
bf612f2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
{-# LANGUAGE DerivingStrategies #-} | ||
{-# LANGUAGE PatternSynonyms #-} | ||
{-# LANGUAGE ViewPatterns #-} | ||
|
||
module Development.IDE.Graph.Internal.Key | ||
( Key -- Opaque - don't expose constructor, use newKey to create | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Moved all the stuff that needs Key internals into this module with explicit import list, so that we don't expose the UnsafeMkKey constructor and all the unsafePerformIO stuff is hidden as impl. detail of this module. |
||
, KeyValue (..) | ||
, pattern Key | ||
, newKey | ||
, renderKey | ||
-- * KeyMap | ||
, KeyMap | ||
, mapKeyMap | ||
, insertKeyMap | ||
, lookupKeyMap | ||
, lookupDefaultKeyMap | ||
, fromListKeyMap | ||
, fromListWithKeyMap | ||
, toListKeyMap | ||
, elemsKeyMap | ||
, restrictKeysKeyMap | ||
-- * KeySet | ||
, KeySet | ||
, nullKeySet | ||
, insertKeySet | ||
, memberKeySet | ||
, toListKeySet | ||
, lengthKeySet | ||
, filterKeySet | ||
, singletonKeySet | ||
, fromListKeySet | ||
, deleteKeySet | ||
, differenceKeySet | ||
) where | ||
|
||
--import Control.Monad.IO.Class () | ||
import Data.Coerce | ||
import Data.Dynamic | ||
import qualified Data.HashMap.Strict as Map | ||
import Data.IntMap (IntMap) | ||
import qualified Data.IntMap.Strict as IM | ||
import Data.IntSet (IntSet) | ||
import qualified Data.IntSet as IS | ||
import Data.IORef | ||
import Data.Text (Text) | ||
import qualified Data.Text as T | ||
import Data.Typeable | ||
import Development.IDE.Graph.Classes | ||
import System.IO.Unsafe | ||
|
||
|
||
newtype Key = UnsafeMkKey Int | ||
|
||
pattern Key :: () => (Typeable a, Hashable a, Show a) => a -> Key | ||
pattern Key a <- (lookupKeyValue -> KeyValue a _) | ||
{-# COMPLETE Key #-} | ||
|
||
data KeyValue = forall a . (Typeable a, Hashable a, Show a) => KeyValue a Text | ||
|
||
instance Eq KeyValue where | ||
KeyValue a _ == KeyValue b _ = Just a == cast b | ||
instance Hashable KeyValue where | ||
hashWithSalt i (KeyValue x _) = hashWithSalt i (typeOf x, x) | ||
instance Show KeyValue where | ||
show (KeyValue _ t) = T.unpack t | ||
|
||
data GlobalKeyValueMap = GlobalKeyValueMap !(Map.HashMap KeyValue Key) !(IntMap KeyValue) {-# UNPACK #-} !Int | ||
|
||
keyMap :: IORef GlobalKeyValueMap | ||
keyMap = unsafePerformIO $ newIORef (GlobalKeyValueMap Map.empty IM.empty 0) | ||
|
||
{-# NOINLINE keyMap #-} | ||
|
||
newKey :: (Typeable a, Hashable a, Show a) => a -> Key | ||
newKey k = unsafePerformIO $ do | ||
let !newKey = KeyValue k (T.pack (show k)) | ||
atomicModifyIORef' keyMap $ \km@(GlobalKeyValueMap hm im n) -> | ||
let new_key = Map.lookup newKey hm | ||
in case new_key of | ||
Just v -> (km, v) | ||
Nothing -> | ||
let !new_index = UnsafeMkKey n | ||
in (GlobalKeyValueMap (Map.insert newKey new_index hm) (IM.insert n newKey im) (n+1), new_index) | ||
{-# NOINLINE newKey #-} | ||
|
||
lookupKeyValue :: Key -> KeyValue | ||
lookupKeyValue (UnsafeMkKey x) = unsafePerformIO $ do | ||
GlobalKeyValueMap _ im _ <- readIORef keyMap | ||
pure $! im IM.! x | ||
|
||
{-# NOINLINE lookupKeyValue #-} | ||
|
||
instance Eq Key where | ||
UnsafeMkKey a == UnsafeMkKey b = a == b | ||
instance Hashable Key where | ||
hashWithSalt i (UnsafeMkKey x) = hashWithSalt i x | ||
instance Show Key where | ||
show (Key x) = show x | ||
|
||
renderKey :: Key -> Text | ||
renderKey (lookupKeyValue -> KeyValue _ t) = t | ||
|
||
newtype KeySet = KeySet IntSet | ||
deriving newtype (Eq, Ord, Semigroup, Monoid) | ||
|
||
instance Show KeySet where | ||
showsPrec p (KeySet is)= showParen (p > 10) $ | ||
showString "fromList " . shows ks | ||
where ks = coerce (IS.toList is) :: [Key] | ||
|
||
insertKeySet :: Key -> KeySet -> KeySet | ||
insertKeySet = coerce IS.insert | ||
|
||
memberKeySet :: Key -> KeySet -> Bool | ||
memberKeySet = coerce IS.member | ||
|
||
toListKeySet :: KeySet -> [Key] | ||
toListKeySet = coerce IS.toList | ||
|
||
nullKeySet :: KeySet -> Bool | ||
nullKeySet = coerce IS.null | ||
|
||
differenceKeySet :: KeySet -> KeySet -> KeySet | ||
differenceKeySet = coerce IS.difference | ||
|
||
deleteKeySet :: Key -> KeySet -> KeySet | ||
deleteKeySet = coerce IS.delete | ||
|
||
fromListKeySet :: [Key] -> KeySet | ||
fromListKeySet = coerce IS.fromList | ||
|
||
singletonKeySet :: Key -> KeySet | ||
singletonKeySet = coerce IS.singleton | ||
|
||
filterKeySet :: (Key -> Bool) -> KeySet -> KeySet | ||
filterKeySet = coerce IS.filter | ||
|
||
lengthKeySet :: KeySet -> Int | ||
lengthKeySet = coerce IS.size | ||
|
||
newtype KeyMap a = KeyMap (IntMap a) | ||
deriving newtype (Eq, Ord, Semigroup, Monoid) | ||
|
||
instance Show a => Show (KeyMap a) where | ||
showsPrec p (KeyMap im)= showParen (p > 10) $ | ||
showString "fromList " . shows ks | ||
where ks = coerce (IM.toList im) :: [(Key,a)] | ||
|
||
mapKeyMap :: (a -> b) -> KeyMap a -> KeyMap b | ||
mapKeyMap f (KeyMap m) = KeyMap (IM.map f m) | ||
|
||
insertKeyMap :: Key -> a -> KeyMap a -> KeyMap a | ||
insertKeyMap (UnsafeMkKey k) v (KeyMap m) = KeyMap (IM.insert k v m) | ||
|
||
lookupKeyMap :: Key -> KeyMap a -> Maybe a | ||
lookupKeyMap (UnsafeMkKey k) (KeyMap m) = IM.lookup k m | ||
|
||
lookupDefaultKeyMap :: a -> Key -> KeyMap a -> a | ||
lookupDefaultKeyMap a (UnsafeMkKey k) (KeyMap m) = IM.findWithDefault a k m | ||
|
||
fromListKeyMap :: [(Key,a)] -> KeyMap a | ||
fromListKeyMap xs = KeyMap (IM.fromList (coerce xs)) | ||
|
||
fromListWithKeyMap :: (a -> a -> a) -> [(Key,a)] -> KeyMap a | ||
fromListWithKeyMap f xs = KeyMap (IM.fromListWith f (coerce xs)) | ||
|
||
toListKeyMap :: KeyMap a -> [(Key,a)] | ||
toListKeyMap (KeyMap m) = coerce (IM.toList m) | ||
|
||
elemsKeyMap :: KeyMap a -> [a] | ||
elemsKeyMap (KeyMap m) = IM.elems m | ||
|
||
restrictKeysKeyMap :: KeyMap a -> KeySet -> KeyMap a | ||
restrictKeysKeyMap (KeyMap m) (KeySet s) = KeyMap (IM.restrictKeys m s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ghc-patched-unboxed-bytecode and bench-exe flags seem to be some historic leftovers - they don't exist in ghcide.cabal anymore, so I just removed them from here.
The idea behind using cabal configure is that we do only single cabal build with pedantic flags enabled for everything - and don't skip pedantic when building hls-graph and ghcide.
Also I guessed what is the purpose of this flags job and added some comments - shout if you don't agree with any of this.