packages feed

ide-backend 0.9.0.1 → 0.9.0.2

raw patch · 24 files changed

+10/−3471 lines, 24 filesdep +ide-backend-commonPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: ide-backend-common

API changes (from Hackage documentation)

- IdeSession: IdInfo :: {-# UNPACK #-} !IdProp -> !IdScope -> IdInfo
+ IdeSession: IdInfo :: UnpkIdProp -> SrictNotUnpackedIdScope -> IdInfo
- IdeSession: IdProp :: !Name -> !IdNameSpace -> !(Maybe Type) -> {-# UNPACK #-} !ModuleId -> !EitherSpan -> !(Maybe ModuleId) -> IdProp
+ IdeSession: IdProp :: SrictNotUnpackedName -> SrictNotUnpackedIdNameSpace -> SrictNotUnpacked(Maybe Type) -> UnpkModuleId -> SrictNotUnpackedEitherSpan -> SrictNotUnpacked(Maybe ModuleId) -> IdProp
- IdeSession: Import :: !ModuleId -> !(Maybe Text) -> !Bool -> !Bool -> !(Maybe ModuleName) -> !ImportEntities -> Import
+ IdeSession: Import :: SrictNotUnpackedModuleId -> SrictNotUnpacked(Maybe Text) -> SrictNotUnpackedBool -> SrictNotUnpackedBool -> SrictNotUnpacked(Maybe ModuleName) -> SrictNotUnpackedImportEntities -> Import
- IdeSession: ImportHiding :: ![Text] -> ImportEntities
+ IdeSession: ImportHiding :: SrictNotUnpacked[Text] -> ImportEntities
- IdeSession: ImportOnly :: ![Text] -> ImportEntities
+ IdeSession: ImportOnly :: SrictNotUnpacked[Text] -> ImportEntities
- IdeSession: Imported :: {-# UNPACK #-} !ModuleId -> !EitherSpan -> !Text -> IdScope
+ IdeSession: Imported :: UnpkModuleId -> SrictNotUnpackedEitherSpan -> SrictNotUnpackedText -> IdScope
- IdeSession: ModuleId :: !ModuleName -> {-# UNPACK #-} !PackageId -> ModuleId
+ IdeSession: ModuleId :: SrictNotUnpackedModuleName -> UnpkPackageId -> ModuleId
- IdeSession: PackageId :: !Text -> !(Maybe Text) -> !Text -> PackageId
+ IdeSession: PackageId :: SrictNotUnpackedText -> SrictNotUnpacked(Maybe Text) -> SrictNotUnpackedText -> PackageId
- IdeSession: ProperSpan :: {-# UNPACK #-} !SourceSpan -> EitherSpan
+ IdeSession: ProperSpan :: UnpkSourceSpan -> EitherSpan
- IdeSession: SourceError :: !SourceErrorKind -> !EitherSpan -> !Text -> SourceError
+ IdeSession: SourceError :: SrictNotUnpackedSourceErrorKind -> SrictNotUnpackedEitherSpan -> SrictNotUnpackedText -> SourceError
- IdeSession: SourceSpan :: !FilePath -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> SourceSpan
+ IdeSession: SourceSpan :: SrictNotUnpackedFilePath -> UnpkInt -> UnpkInt -> UnpkInt -> UnpkInt -> SourceSpan
- IdeSession: TextSpan :: !Text -> EitherSpan
+ IdeSession: TextSpan :: SrictNotUnpackedText -> EitherSpan
- IdeSession: data BreakInfo
+ IdeSession: data BreakInfo :: *
- IdeSession: data EitherSpan
+ IdeSession: data EitherSpan :: *
- IdeSession: data ExternalException
+ IdeSession: data ExternalException :: *
- IdeSession: data GhcVersion
+ IdeSession: data GhcVersion :: *
- IdeSession: data IdInfo
+ IdeSession: data IdInfo :: *
- IdeSession: data IdNameSpace
+ IdeSession: data IdNameSpace :: *
- IdeSession: data IdProp
+ IdeSession: data IdProp :: *
- IdeSession: data IdScope
+ IdeSession: data IdScope :: *
- IdeSession: data Import
+ IdeSession: data Import :: *
- IdeSession: data ImportEntities
+ IdeSession: data ImportEntities :: *
- IdeSession: data ModuleId
+ IdeSession: data ModuleId :: *
- IdeSession: data PackageId
+ IdeSession: data PackageId :: *
- IdeSession: data Progress
+ IdeSession: data Progress :: *
- IdeSession: data RunBufferMode
+ IdeSession: data RunBufferMode :: *
- IdeSession: data RunResult
+ IdeSession: data RunResult :: *
- IdeSession: data SourceError
+ IdeSession: data SourceError :: *
- IdeSession: data SourceErrorKind
+ IdeSession: data SourceErrorKind :: *
- IdeSession: data SourceSpan
+ IdeSession: data SourceSpan :: *
- IdeSession: data SpanInfo
+ IdeSession: data SpanInfo :: *
- IdeSession: data Targets
+ IdeSession: data Targets :: *
- IdeSession: errorKind :: SourceError -> !SourceErrorKind
+ IdeSession: errorKind :: SourceError -> SrictNotUnpackedSourceErrorKind
- IdeSession: errorMsg :: SourceError -> !Text
+ IdeSession: errorMsg :: SourceError -> SrictNotUnpackedText
- IdeSession: errorSpan :: SourceError -> !EitherSpan
+ IdeSession: errorSpan :: SourceError -> SrictNotUnpackedEitherSpan
- IdeSession: idDefSpan :: IdProp -> !EitherSpan
+ IdeSession: idDefSpan :: IdProp -> SrictNotUnpackedEitherSpan
- IdeSession: idDefinedIn :: IdProp -> {-# UNPACK #-} !ModuleId
+ IdeSession: idDefinedIn :: IdProp -> UnpkModuleId
- IdeSession: idHomeModule :: IdProp -> !(Maybe ModuleId)
+ IdeSession: idHomeModule :: IdProp -> SrictNotUnpacked(Maybe ModuleId)
- IdeSession: idImportQual :: IdScope -> !Text
+ IdeSession: idImportQual :: IdScope -> SrictNotUnpackedText
- IdeSession: idImportSpan :: IdScope -> !EitherSpan
+ IdeSession: idImportSpan :: IdScope -> SrictNotUnpackedEitherSpan
- IdeSession: idImportedFrom :: IdScope -> {-# UNPACK #-} !ModuleId
+ IdeSession: idImportedFrom :: IdScope -> UnpkModuleId
- IdeSession: idName :: IdProp -> !Name
+ IdeSession: idName :: IdProp -> SrictNotUnpackedName
- IdeSession: idProp :: IdInfo -> {-# UNPACK #-} !IdProp
+ IdeSession: idProp :: IdInfo -> UnpkIdProp
- IdeSession: idScope :: IdInfo -> !IdScope
+ IdeSession: idScope :: IdInfo -> SrictNotUnpackedIdScope
- IdeSession: idSpace :: IdProp -> !IdNameSpace
+ IdeSession: idSpace :: IdProp -> SrictNotUnpackedIdNameSpace
- IdeSession: idType :: IdProp -> !(Maybe Type)
+ IdeSession: idType :: IdProp -> SrictNotUnpacked(Maybe Type)
- IdeSession: importAs :: Import -> !(Maybe ModuleName)
+ IdeSession: importAs :: Import -> SrictNotUnpacked(Maybe ModuleName)
- IdeSession: importEntities :: Import -> !ImportEntities
+ IdeSession: importEntities :: Import -> SrictNotUnpackedImportEntities
- IdeSession: importImplicit :: Import -> !Bool
+ IdeSession: importImplicit :: Import -> SrictNotUnpackedBool
- IdeSession: importModule :: Import -> !ModuleId
+ IdeSession: importModule :: Import -> SrictNotUnpackedModuleId
- IdeSession: importPackage :: Import -> !(Maybe Text)
+ IdeSession: importPackage :: Import -> SrictNotUnpacked(Maybe Text)
- IdeSession: importQualified :: Import -> !Bool
+ IdeSession: importQualified :: Import -> SrictNotUnpackedBool
- IdeSession: moduleName :: ModuleId -> !ModuleName
+ IdeSession: moduleName :: ModuleId -> SrictNotUnpackedModuleName
- IdeSession: modulePackage :: ModuleId -> {-# UNPACK #-} !PackageId
+ IdeSession: modulePackage :: ModuleId -> UnpkPackageId
- IdeSession: packageKey :: PackageId -> !Text
+ IdeSession: packageKey :: PackageId -> SrictNotUnpackedText
- IdeSession: packageName :: PackageId -> !Text
+ IdeSession: packageName :: PackageId -> SrictNotUnpackedText
- IdeSession: packageVersion :: PackageId -> !(Maybe Text)
+ IdeSession: packageVersion :: PackageId -> SrictNotUnpacked(Maybe Text)
- IdeSession: spanFilePath :: SourceSpan -> !FilePath
+ IdeSession: spanFilePath :: SourceSpan -> SrictNotUnpackedFilePath
- IdeSession: spanFromColumn :: SourceSpan -> {-# UNPACK #-} !Int
+ IdeSession: spanFromColumn :: SourceSpan -> UnpkInt
- IdeSession: spanFromLine :: SourceSpan -> {-# UNPACK #-} !Int
+ IdeSession: spanFromLine :: SourceSpan -> UnpkInt
- IdeSession: spanToColumn :: SourceSpan -> {-# UNPACK #-} !Int
+ IdeSession: spanToColumn :: SourceSpan -> UnpkInt
- IdeSession: spanToLine :: SourceSpan -> {-# UNPACK #-} !Int
+ IdeSession: spanToLine :: SourceSpan -> UnpkInt

Files

− IdeSession/GHC/API.hs
@@ -1,90 +0,0 @@--- | Types for the messages to and fro the GHC server------ It is important that none of the types here rely on the GHC library.-{-# LANGUAGE DeriveDataTypeable #-}-module IdeSession.GHC.API (-    -- * Requests-    module IdeSession.GHC.Requests-    -- * Responses-  , module IdeSession.GHC.Responses-    -- * Configuration-  , ideBackendApiVersion-  , hsExtensions-  , hsBootExtensions-  , cExtensions-  , cHeaderExtensions-  , sourceExtensions-  , cabalMacrosLocation-    -- * Paths-  , ideSessionSourceDir-  , ideSessionDataDir-  , ideSessionDistDir-  , ideSessionObjDir-  ) where--import System.FilePath ((</>))--import IdeSession.GHC.Requests-import IdeSession.GHC.Responses---- | For detecting runtime version mismatch between the server and the library------ We use a Unix timestamp for this so that these API versions have some--- semantics (http://www.epochconverter.com/, GMT).-ideBackendApiVersion :: Int-ideBackendApiVersion = 1426765899--{-------------------------------------------------------------------------------  Configuration-------------------------------------------------------------------------------}---- | Haskell source files-hsExtensions :: [FilePath]-hsExtensions = [".hs", ".lhs"]---- | Haskell @.boot@ files-hsBootExtensions :: [FilePath]-hsBootExtensions = [".hs-boot", ".lhs-boot"]---- | C source files-cExtensions :: [FilePath]-cExtensions = [".c"]---- | C header files-cHeaderExtensions :: [FilePath]-cHeaderExtensions = [".h"]---- | Extensions of all source files we keep in our source directory.-sourceExtensions :: [FilePath]-sourceExtensions = hsExtensions-                ++ hsBootExtensions-                ++ cExtensions-                ++ cHeaderExtensions---- TODO: perhaps create dist/build/autogen and put macros there so that--- Cabal.autogenModulesDir can use it for compilation of C files?-cabalMacrosLocation :: FilePath -> FilePath-cabalMacrosLocation ideDistDir = ideDistDir </> "cabal_macros.h"--{--------------------------------------------------------------------------------  Paths--  These are all meant to be relative to the session dir--------------------------------------------------------------------------------}---- | The directory to use for managing source files.-ideSessionSourceDir :: FilePath -> FilePath-ideSessionSourceDir sessionDir = sessionDir </> "src"---- | The directory to use for data files that may be accessed by the--- running program. The running program will have this as its CWD.-ideSessionDataDir :: FilePath -> FilePath-ideSessionDataDir sessionDir = sessionDir </> "data"---- | Cabal "dist" prefix.-ideSessionDistDir :: FilePath -> FilePath-ideSessionDistDir sessionDir = sessionDir </> "dist"---- | Directory where we store compiled C files (objects)-ideSessionObjDir :: FilePath -> FilePath-ideSessionObjDir sessionDir = sessionDir </> "ffi"
− IdeSession/GHC/Requests.hs
@@ -1,192 +0,0 @@--- | GHC requests------ GHC requests use "IdeSession.Types.Public" types.-{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}-module IdeSession.GHC.Requests (-    GhcInitRequest(..)-  , GhcRequest(..)-  , GhcRunRequest(..)-  , RunCmd(..)-  ) where--import Data.Binary-import Data.ByteString (ByteString)-import Data.Typeable (Typeable)-import Control.Applicative ((<$>), (<*>))--import Text.Show.Pretty (PrettyVal(..))-import GHC.Generics--import IdeSession.Types.Public---- | Initial handshake with the ghc server------ Ideally we'd send over the entire IdeStaticInfo but this includes some--- Cabal fields, and the ghc server does -not- compile against Cabal--- (although this isn't so important anymore now that we use Cabal-ide-backend)-data GhcInitRequest = GhcInitRequest {-    ghcInitClientApiVersion   :: Int-  , ghcInitGenerateModInfo    :: Bool-  , ghcInitOpts               :: [String]-  , ghcInitUserPackageDB      :: Bool-  , ghcInitSpecificPackageDBs :: [String]-  , ghcInitSessionDir         :: FilePath-  }-  deriving (Typeable, Generic)--data GhcRequest-  = ReqCompile {-        reqCompileGenCode   :: Bool-      , reqCompileTargets   :: Targets-      }-  | ReqRun {-        reqRunCmd :: RunCmd-      }-  | ReqSetEnv {-        reqSetEnv :: [(String, Maybe String)]-      }-  | ReqSetArgs {-        reqSetArgs :: [String]-      }-  | ReqBreakpoint {-        reqBreakpointModule :: ModuleName-      , reqBreakpointSpan   :: SourceSpan-      , reqBreakpointValue  :: Bool-      }-  | ReqPrint {-        reqPrintVars  :: Name-      , reqPrintBind  :: Bool-      , reqPrintForce :: Bool-      }-  | ReqLoad {-        reqLoad :: [FilePath]-      }-  | ReqUnload {-        reqUnload :: [FilePath]-      }-  | ReqSetGhcOpts {-        reqSetGhcOpts :: [String]-      }-    -- | For debugging only! :)-  | ReqCrash {-        reqCrashDelay :: Maybe Int-      }-  deriving (Typeable, Generic, Show)--data RunCmd =-    RunStmt {-        runCmdModule   :: String-      , runCmdFunction :: String-      , runCmdStdout   :: RunBufferMode-      , runCmdStderr   :: RunBufferMode-      }-  | Resume-  deriving (Typeable, Generic, Show)--instance PrettyVal GhcInitRequest-instance PrettyVal GhcRequest-instance PrettyVal RunCmd--data GhcRunRequest =-    GhcRunInput ByteString-  | GhcRunInterrupt-  deriving Typeable--instance Binary GhcInitRequest where-  put (GhcInitRequest{..}) = do-    -- Note: we intentionally write the API version first. This makes it-    -- possible (in theory at least) to have some form of backwards API-    -- compatibility.-    put ghcInitClientApiVersion-    put ghcInitGenerateModInfo-    put ghcInitOpts-    put ghcInitUserPackageDB-    put ghcInitSpecificPackageDBs-    put ghcInitSessionDir--  get = GhcInitRequest <$> get-                       <*> get-                       <*> get-                       <*> get-                       <*> get-                       <*> get--instance Binary GhcRequest where-  put ReqCompile{..} = do-    putWord8 0-    put reqCompileGenCode-    put reqCompileTargets-  put ReqRun{..} = do-    putWord8 1-    put reqRunCmd-  put ReqSetEnv{..} = do-    putWord8 2-    put reqSetEnv-  put ReqSetArgs{..} = do-    putWord8 3-    put reqSetArgs-  put ReqBreakpoint{..} = do-    putWord8 4-    put reqBreakpointModule-    put reqBreakpointSpan-    put reqBreakpointValue-  put ReqPrint{..} = do-    putWord8 5-    put reqPrintVars-    put reqPrintBind-    put reqPrintForce-  put ReqLoad{..} = do-    putWord8 6-    put reqLoad-  put ReqUnload{..} = do-    putWord8 7-    put reqUnload-  put ReqSetGhcOpts{..} = do-    putWord8 8-    put reqSetGhcOpts-  put ReqCrash{..} = do-    putWord8 255-    put reqCrashDelay--  get = do-    header <- getWord8-    case header of-      0   -> ReqCompile     <$> get <*> get-      1   -> ReqRun         <$> get-      2   -> ReqSetEnv      <$> get-      3   -> ReqSetArgs     <$> get-      4   -> ReqBreakpoint  <$> get <*> get <*> get-      5   -> ReqPrint       <$> get <*> get <*> get-      6   -> ReqLoad        <$> get-      7   -> ReqUnload      <$> get-      8   -> ReqSetGhcOpts  <$> get-      255 -> ReqCrash       <$> get-      _   -> fail "GhcRequest.get: invalid header"--instance Binary RunCmd where-  put (RunStmt {..}) = do-    putWord8 0-    put runCmdModule-    put runCmdFunction-    put runCmdStdout-    put runCmdStderr-  put Resume = do-    putWord8 1--  get = do-    header <- getWord8-    case header of-      0 -> RunStmt <$> get <*> get <*> get <*> get-      1 -> return Resume-      _ -> fail "RunCmd.get: invalid header"--instance Binary GhcRunRequest where-  put (GhcRunInput bs) = putWord8 0 >> put bs-  put GhcRunInterrupt  = putWord8 1--  get = do-    header <- getWord8-    case header of-      0 -> GhcRunInput <$> get-      1 -> return GhcRunInterrupt-      _ -> fail "GhcRunRequest.get: invalid header"
− IdeSession/GHC/Responses.hs
@@ -1,127 +0,0 @@--- | Responses from the GHC server------ The server responds with "IdeSession.Types.Private" types-{-# LANGUAGE DeriveDataTypeable, DeriveGeneric #-}-module IdeSession.GHC.Responses (-    GhcInitResponse(..)-  , GhcCompileResponse(..)-  , GhcCompileResult(..)-  , GhcRunResponse(..)-  , GhcVersion(..)-  ) where--import Data.Binary-import Data.ByteString (ByteString)-import Data.Text (Text)-import Data.Typeable (Typeable)-import Control.Applicative ((<$>), (<*>))--import IdeSession.Types.Private-import IdeSession.Types.Progress-import IdeSession.Strict.Container-import IdeSession.Util (Diff)--import Text.Show.Pretty-import GHC.Generics--data GhcInitResponse = GhcInitResponse {-    ghcInitVersion :: GhcVersion-  }-  deriving (Typeable, Generic)--data GhcCompileResponse =-    GhcCompileProgress Progress-  | GhcCompileDone GhcCompileResult-  deriving (Typeable, Generic)---- NOTE: These fields cannot be made strict (at least, not easily)-data GhcCompileResult = GhcCompileResult {-    ghcCompileErrors   :: Strict [] SourceError-  , ghcCompileLoaded   :: Strict [] ModuleName-  , ghcCompileCache    :: ExplicitSharingCache-  -- Computed from the GhcSummary (independent of the plugin, and hence-  -- available even when the plugin does not run)-  , ghcCompileFileMap  :: Strict (Map FilePath) ModuleId-  , ghcCompileImports  :: Strict (Map ModuleName) (Diff (Strict [] Import))-  , ghcCompileAuto     :: Strict (Map ModuleName) (Diff (Strict [] IdInfo))-  -- Computed by the plugin-  , ghcCompileSpanInfo :: Strict (Map ModuleName) (Diff IdList)-  , ghcCompilePkgDeps  :: Strict (Map ModuleName) (Diff (Strict [] PackageId))-  , ghcCompileExpTypes :: Strict (Map ModuleName) (Diff [(SourceSpan, Text)])-  , ghcCompileUseSites :: Strict (Map ModuleName) (Diff UseSites)-  }-  deriving (Typeable, Generic)--data GhcRunResponse =-    GhcRunOutp ByteString-  | GhcRunDone RunResult-  deriving (Typeable, Generic)---- | GHC version------ NOTE: Defined in such a way that the Ord instance makes sense.-data GhcVersion = GHC_7_4 | GHC_7_8 | GHC_7_10-  deriving (Typeable, Show, Eq, Ord, Generic)--instance PrettyVal GhcInitResponse-instance PrettyVal GhcCompileResponse-instance PrettyVal GhcCompileResult-instance PrettyVal GhcRunResponse-instance PrettyVal GhcVersion--instance Binary GhcInitResponse where-  put (GhcInitResponse{..}) = do-    put ghcInitVersion-  get = GhcInitResponse <$> get--instance Binary GhcCompileResponse where-  put (GhcCompileProgress progress) = putWord8 0 >> put progress-  put (GhcCompileDone result)       = putWord8 1 >> put result--  get = do-    header <- getWord8-    case header of-      0 -> GhcCompileProgress <$> get-      1 -> GhcCompileDone     <$> get-      _ -> fail "GhcCompileRespone.get: invalid header"--instance Binary GhcCompileResult where-  put GhcCompileResult{..} = do-    put ghcCompileErrors-    put ghcCompileLoaded-    put ghcCompileCache-    put ghcCompileFileMap-    put ghcCompileImports-    put ghcCompileAuto-    put ghcCompileSpanInfo-    put ghcCompilePkgDeps-    put ghcCompileExpTypes-    put ghcCompileUseSites--  get = GhcCompileResult <$> get <*> get <*> get-                         <*> get <*> get <*> get-                         <*> get <*> get <*> get <*> get--instance Binary GhcRunResponse where-  put (GhcRunOutp bs) = putWord8 0 >> put bs-  put (GhcRunDone r)  = putWord8 1 >> put r--  get = do-    header <- getWord8-    case header of-      0 -> GhcRunOutp <$> get-      1 -> GhcRunDone <$> get-      _ -> fail "GhcRunResponse.get: invalid header"--instance Binary GhcVersion where-  put GHC_7_4  = putWord8 0-  put GHC_7_8  = putWord8 1-  put GHC_7_10 = putWord8 2--  get = do-    header <- getWord8-    case header of-      0 -> return GHC_7_4-      1 -> return GHC_7_8-      2 -> return GHC_7_10-      _ -> fail "GhcVersion.get: invalid header"
− IdeSession/RPC/API.hs
@@ -1,188 +0,0 @@-{-# LANGUAGE DeriveDataTypeable, RankNTypes #-}-module IdeSession.RPC.API (-    -- * External exceptions-    ExternalException(..)-  , serverKilledException-    -- * Client-server communication-  , RpcConversation(..)-  , Request(..)-  , Response(..)-    -- * Lazy bytestring with incremental Binary instance-  , IncBS(..)-    -- * IO utils-  , hPutFlush-  , ignoreIOExceptions-  , openPipeForWriting-  , openPipeForReading-  ) where--import Prelude hiding (take)-import Control.Applicative ((<$>))-import Control.Concurrent (threadDelay)-import Data.Binary (Binary)-import Data.Typeable (Typeable)-import System.IO (Handle, hFlush, openFile, IOMode(..), hPutChar, hGetChar)-import qualified Control.Exception as Ex-import qualified Data.Binary as Binary-import qualified Data.ByteString as BSS-import qualified Data.ByteString.Lazy.Char8 as BSL-import qualified Data.ByteString.Lazy.Internal as BSL------------------------------------------------------------------------------------- Exceptions thrown by the RPC server are retrown locally as                 ----- 'ExternalException's                                                       --------------------------------------------------------------------------------------- | Exceptions thrown by the remote server-data ExternalException = ExternalException {-     -- | The output from the server on stderr-     externalStdErr    :: String-     -- | The local exception that was thrown and alerted us to the problem-   , externalException :: Maybe Ex.IOException-   }-  deriving (Eq, Typeable)--instance Show ExternalException where-  show (ExternalException err Nothing) =-    "External exception: " ++ err-  show (ExternalException err (Just ex)) =-    "External exception: " ++ err ++ ". Local exception: " ++ show ex--instance Ex.Exception ExternalException---- | Generic exception thrown if the server gets killed for unknown reason-serverKilledException :: Maybe Ex.IOException -> ExternalException-serverKilledException ex = ExternalException "Server killed" ex--{-------------------------------------------------------------------------------  Client-server communication-------------------------------------------------------------------------------}--data RpcConversation = RpcConversation {-    get :: forall a. (Typeable a, Binary a) => IO a-  , put :: forall a. (Typeable a, Binary a) => a -> IO ()-  }--data Request = Request IncBS | RequestShutdown-  deriving Show--newtype Response = Response IncBS--instance Binary Request where-  put (Request bs)         = Binary.putWord8 0 >> Binary.put bs-  put RequestShutdown      = Binary.putWord8 1--  get = do-    header <- Binary.getWord8-    case header of-      0 -> Request <$> Binary.get-      1 -> return RequestShutdown-      _ -> fail "Request.get: invalid header"--instance Binary Response where-  put (Response bs) = Binary.put bs-  get = Response <$> Binary.get--{-------------------------------------------------------------------------------  Lazy bytestring with an incremental Binary instance--  Note only does this avoid loading the entire ByteString into memory when-  serializing stuff, the standard Binary instance for Lazy bytestring is-  actually broken in 0.5 (http://hpaste.org/87401; fixed in 0.7, but even there-  still requires the length of the bytestring upfront).-------------------------------------------------------------------------------}--newtype IncBS = IncBS { unIncBS :: BSL.ByteString }--instance Binary IncBS where-  put (IncBS BSL.Empty)        = Binary.putWord8 0-  put (IncBS (BSL.Chunk b bs)) = do Binary.putWord8 1-                                    Binary.put b-                                    Binary.put (IncBS bs)--  get = go []-    where-      go :: [BSS.ByteString] -> Binary.Get IncBS-      go acc = do-        header <- Binary.getWord8-        case header of-          0 -> return . IncBS . BSL.fromChunks . reverse $ acc-          1 -> do b <- Binary.get ; go (b : acc)-          _ -> fail "IncBS.get: invalid header"--instance Show IncBS where-  show = show . unIncBS--{-------------------------------------------------------------------------------  Some IO utils-------------------------------------------------------------------------------}---- | Write a bytestring to a buffer and flush-hPutFlush :: Handle -> BSL.ByteString -> IO ()-hPutFlush h bs = BSL.hPut h bs >> ignoreIOExceptions (hFlush h)---- | Ignore IO exceptions-ignoreIOExceptions :: IO () -> IO ()-ignoreIOExceptions = Ex.handle ignore-  where-    ignore :: Ex.IOException -> IO ()-    ignore _ = return ()---- | Open a pipe for writing------ This is meant to be used together with 'openPipeForReading'-openPipeForWriting :: FilePath -> Int -> IO Handle-openPipeForWriting fp = go-  where-    go :: Int -> IO Handle-    go timeout = do-      -- We cannot open a pipe for writing without a corresponding reader-      mh <- Ex.try $ openFile fp WriteMode-      case mh of-        Left ex ->-          if timeout > delay-            then do threadDelay delay-                    go (timeout - delay)-            else Ex.throwIO (RPCPipeNotCreated ex)-        Right h -> do-          hPutChar h '!'-          hFlush h-          return h--    delay :: Int-    delay = 10000 -- 10 ms--data RPCPipeNotCreated = RPCPipeNotCreated Ex.IOException-    deriving Typeable-instance Ex.Exception RPCPipeNotCreated-instance Show RPCPipeNotCreated where-    show (RPCPipeNotCreated e) = "The bidirectional RPC pipe could not be opened. Exception was: " ++ show e---- | Open a pipe for reading------ This is meant to be used together with 'openPipeForWriting'-openPipeForReading :: FilePath -> Int -> IO Handle-openPipeForReading fp = \timeout -> do-    -- We _can_ open a pipe for reading without a corresponding writer-    h <- openFile fp ReadMode-    -- But if there is no corresponding writer, then trying to read from the-    -- pipe will report EOF. So we wait.-    go h timeout-    return h-  where-    go :: Handle -> Int -> IO ()-    go h timeout = do-      mc <- Ex.try $ hGetChar h-      case mc of-        Left ex ->-          if timeout > delay-            then do threadDelay delay-                    go h (timeout - delay)-            else Ex.throwIO (RPCPipeNotCreated ex)-        Right '!' ->-          return ()-        Right c ->-          Ex.throwIO (userError $ "openPipeForReading: Unexpected " ++ show c)--    delay :: Int-    delay = 10000 -- 10 ms
− IdeSession/RPC/Server.hs
@@ -1,230 +0,0 @@-{-# LANGUAGE ScopedTypeVariables, TemplateHaskell, DeriveDataTypeable, RankNTypes, GADTs #-}-{-# OPTIONS_GHC -Wall #-}-module IdeSession.RPC.Server-  ( rpcServer-  , concurrentConversation-  , RpcConversation(..)-  ) where--import Prelude hiding (take)-import System.IO-  ( Handle-  , hSetBinaryMode-  , hSetBuffering-  , BufferMode(BlockBuffering)-  )-import System.Posix.Types (Fd)-import System.Posix.IO (closeFd, fdToHandle)-import Control.Monad (void)-import qualified Control.Exception as Ex-import Control.Concurrent (threadDelay)-import Control.Concurrent.Chan (Chan, newChan, writeChan)-import qualified Data.ByteString.Lazy.Char8 as BSL-import Control.Concurrent.Async (Async, async)-import Data.Binary (encode, decode)--import IdeSession.Util.BlockingOps (readChan, wait, waitAny)-import IdeSession.RPC.API-import IdeSession.RPC.Stream------------------------------------------------------------------------------------- Server-side API                                                            --------------------------------------------------------------------------------------- Start the RPC server. For an explanation of the command line arguments, see--- 'forkRpcServer'. This function does not return until the client requests--- termination of the RPC conversation (or there is an error).------ The server is passed the RpcConversation to communicate with the client,--- as well as the path to the exception log (rarely needed -- only needed--- if the server thread kills the whole process unconditionally, without--- throwing an exception).-rpcServer :: (FilePath -> RpcConversation -> IO ()) -- ^ Request server-          -> [String]                               -- ^ Command line args-          -> IO ()-rpcServer handler args = do-  let readFd :: String -> Fd-      readFd fd = fromIntegral (read fd :: Int)--  let errorLog : fds = args-      [requestR, requestW, responseR, responseW] = map readFd fds--  closeFd requestW-  closeFd responseR-  requestR'  <- fdToHandle requestR-  responseW' <- fdToHandle responseW--  rpcServer' requestR' responseW' errorLog handler---- | Start a concurrent conversation.-concurrentConversation :: FilePath -- ^ stdin named pipe-                       -> FilePath -- ^ stdout named pipe-                       -> FilePath -- ^ log file for exceptions-                       -> (FilePath -> RpcConversation -> IO ())-                       -> IO ()-concurrentConversation requestR responseW errorLog server = do-    hin  <- openPipeForReading requestR  timeout-    hout <- openPipeForWriting responseW timeout-    rpcServer' hin hout errorLog server-  where-    timeout :: Int-    timeout = maxBound---- | Start the RPC server-rpcServer' :: Handle                     -- ^ Input-           -> Handle                     -- ^ Output-           -> FilePath                   -- ^ Log file for exceptions-           -> (FilePath -> RpcConversation -> IO ()) -- ^ The request server-           -> IO ()-rpcServer' hin hout errorLog server = do-    requests  <- newChan :: IO (Chan BSL.ByteString)-    responses <- newChan :: IO (Chan (Maybe BSL.ByteString))--    setBinaryBlockBuffered [hin, hout]--    -- Each thread installs it own exception handler before unmasking-    -- asynchronous exceptions. This way when an exception occurs we can-    -- identify it (by looking at which ServerEvent was returned).-    (reader, writer, handler) <- Ex.mask $ \restore -> do-      reader  <- async $ readRequests   restore hin requests-      writer  <- async $ writeResponses restore responses hout-      handler <- async $ channelHandler restore requests responses (server errorLog)-      return (reader, writer, handler)--    (_thread, ev) <- $waitAny [reader, writer, handler]-    case ev of-      -- If we lose connection with the client, just terminate.-      -- See #194 (in particular, https://github.com/fpco/ide-backend/issues/194#issuecomment-44210412)-      LostConnection ex ->-        tryShowException (Just ex)--      -- If the client requests termination, we simply terminate immediately.-      -- It is the client's responsibility to have a proper shutdown protocol-      -- with the server thread-      ReaderThreadTerminated ->-        return ()--      -- The writer thread should never terminate normally unless we request-      -- it; this is a logical impossibility :)-      WriterThreadTerminated ->-        error "The impossible happened"--      -- When the main server thread terminates we ask the writer thread to-      -- terminate so that we make sure to send any pending messages-      ServerThreadTerminated ->-        tryShowException =<< flushResponses responses writer--      -- When the main server thread aborts, we still attempt to flush any-      -- remaining messages, but the exception that we record is the one from-      -- the server (the writer thread might terminate with a further exception)-      ServerThreadAborted ex -> do-        tryShowException (Just ex)-        void $ flushResponses responses writer--    threadDelay 100000-  where-    tryShowException :: Maybe Ex.SomeException -> IO ()-    tryShowException (Just ex) =-      ignoreIOExceptions $ appendFile errorLog (show ex)-    tryShowException Nothing =-      return ()------------------------------------------------------------------------------------- Internal                                                                   --------------------------------------------------------------------------------------- | We record the reason why the various threads are terminating, so that we--- can take the appropriate action-data ServerEvent =-    -- | The reader thread terminates when the client sends a 'RequestShutdown'-    -- message-    ReaderThreadTerminated--    -- | After the main server thread terminates, we wait for the writer thread-    -- to terminate to make sure there are no pending unsent messages-  | WriterThreadTerminated--    -- | Termination of the main server thread-  | ServerThreadTerminated--    -- | Main server thread threw an exception-  | ServerThreadAborted Ex.SomeException--    -- | The reader thread and writer threads terminate with 'LostConnection'-    -- if an exception occurs-  | LostConnection Ex.SomeException-  deriving Show---- | Decode messages from a handle and forward them to a channel.--- The boolean result indicates whether the shutdown is forced.-readRequests :: Restore -> Handle -> Chan BSL.ByteString -> IO ServerEvent-readRequests restore h ch =-    Ex.handle (return . LostConnection)-              (restore (newStream h >>= go))-  where-    go :: Stream Request -> IO ServerEvent-    go input = do-      req <- nextInStream input-      case req of-        Request req'         -> writeChan ch (unIncBS req') >> go input-        RequestShutdown      -> return ReaderThreadTerminated---- | Encode messages from a channel and forward them on a handle------ Terminates on 'Nothing'.-writeResponses :: Restore -> Chan (Maybe BSL.ByteString) -> Handle -> IO ServerEvent-writeResponses restore ch h =-    Ex.handle (return . LostConnection)-              (restore go)-  where-    go :: IO ServerEvent-    go = do-      mbs <- $readChan ch-      case mbs of-        Just bs -> do hPutFlush h $ encode (Response (IncBS bs)) ; go-        Nothing -> return WriterThreadTerminated---- | Ask the writer thread to terminate and wait for all remaining messages to--- have been sent. Returns 'Nothing' if the writer thread terminated normally,--- or the exception if it didn't.-flushResponses :: Chan (Maybe BSL.ByteString) -> Async ServerEvent -> IO (Maybe Ex.SomeException)-flushResponses responses writer = do-  writeChan responses Nothing-  ev <- $wait writer-  case ev of-    WriterThreadTerminated ->-      return Nothing-    LostConnection ex ->-      return (Just ex)-    _ ->-      error "the impossible happened"---- | Run a handler repeatedly, given input and output channels-channelHandler :: Restore-               -> Chan BSL.ByteString-               -> Chan (Maybe BSL.ByteString)-               -> (RpcConversation -> IO ())-               -> IO ServerEvent-channelHandler restore requests responses server =-    Ex.handle (return . ServerThreadAborted)-              (restore go)-  where-    go :: IO ServerEvent-    go = do-      server RpcConversation {-          get = $readChan requests >>= Ex.evaluate . decode-        , put = writeChan responses . Just . encode-        }-      return ServerThreadTerminated------------------------------------------------------------------------------------- Auxiliary                                                                  -------------------------------------------------------------------------------------type Restore = forall a. IO a -> IO a---- | Set all the specified handles to binary mode and block buffering-setBinaryBlockBuffered :: [Handle] -> IO ()-setBinaryBlockBuffered =-  mapM_ $ \h -> do hSetBinaryMode h True-                   hSetBuffering  h (BlockBuffering Nothing)
− IdeSession/RPC/Stream.hs
@@ -1,47 +0,0 @@--- | Wrapper around binary-{-# LANGUAGE ScopedTypeVariables, GADTs #-}-module IdeSession.RPC.Stream (-    Stream-  , newStream-  , nextInStream-  ) where--import Prelude hiding (take)-import System.IO (Handle)-import qualified Control.Exception as Ex-import qualified Data.ByteString.Lazy.Internal as BSL-import qualified Data.ByteString as BSS-import Data.IORef (IORef, writeIORef, readIORef, newIORef)-import Data.Binary (Binary)-import qualified Data.Binary     as Binary-import qualified Data.Binary.Get as Binary--data Stream a where-  Stream :: Binary a => Handle -> IORef (Binary.Decoder a) -> Stream a--newStream :: Binary a => Handle -> IO (Stream a)-newStream h = do-  st <- newIORef $ Binary.runGetIncremental Binary.get-  return $ Stream h st--nextInStream :: forall a. Stream a -> IO a-nextInStream (Stream h st) = readIORef st >>= go-  where-    go :: Binary.Decoder a -> IO a-    go decoder = case decoder of-      Binary.Fail _ _ err -> do-        writeIORef st decoder-        Ex.throwIO (userError err)-      Binary.Partial k -> do-        mchunk <- Ex.try $ BSS.hGetSome h BSL.defaultChunkSize-        case mchunk of-          Left ex -> do writeIORef st decoder-                        Ex.throwIO (ex :: Ex.SomeException)-          Right chunk | BSS.null chunk -> go . k $ Nothing-                      | otherwise      -> go . k $ Just chunk-      Binary.Done unused _numConsumed a -> do-        writeIORef st $ contDecoder unused-        return a--    contDecoder :: BSS.ByteString -> Binary.Decoder a-    contDecoder = Binary.pushChunk (Binary.runGetIncremental Binary.get)
− IdeSession/Strict/Container.hs
@@ -1,130 +0,0 @@-{-# LANGUAGE TypeFamilies, FlexibleInstances, StandaloneDeriving #-}-module IdeSession.Strict.Container-  ( StrictContainer(..)-  , Strict(..)-    -- * For convenience, we export the names of the lazy types too-  , Maybe-  , Map-  , IntMap-  , Trie-  ) where--import Control.Applicative-import Data.IntMap (IntMap)-import qualified Data.IntMap as IntMap-import Data.Map (Map)-import qualified Data.Map as Map-import qualified Data.List as List-import Data.Trie (Trie)-import Data.Foldable as Foldable-import Data.Binary (Binary(..))-import IdeSession.Util.PrettyVal--class StrictContainer t where-  data Strict (t :: * -> *) :: * -> *-  force   :: t a -> Strict t a-  project :: Strict t a -> t a--{-------------------------------------------------------------------------------  IntMap-------------------------------------------------------------------------------}--instance StrictContainer IntMap where-  newtype Strict IntMap v = StrictIntMap { toLazyIntMap :: IntMap v }-    deriving Show--  force m = IntMap.foldl' (flip seq) () m `seq` StrictIntMap m-  project = toLazyIntMap--instance Binary v => Binary (Strict IntMap v) where-  put = put . IntMap.toList . toLazyIntMap-  get = (force . IntMap.fromList) <$> get--instance PrettyVal v => PrettyVal (Strict IntMap v) where-  prettyVal = prettyVal . toLazyIntMap--{-------------------------------------------------------------------------------  Lists-------------------------------------------------------------------------------}--instance StrictContainer [] where-  newtype Strict [] a = StrictList { toLazyList :: [a] }-    deriving (Show, Eq)--  force m = List.foldl' (flip seq) () m `seq` StrictList m-  project = toLazyList---- TODO: we can do better than this if we cache the length of the list-instance Binary a => Binary (Strict [] a) where-  put = put . toLazyList-  get = force <$> get--instance PrettyVal a => PrettyVal (Strict [] a) where-  prettyVal = prettyVal . toLazyList--{-------------------------------------------------------------------------------  Map-------------------------------------------------------------------------------}--instance StrictContainer (Map k) where-  newtype Strict (Map k) v = StrictMap { toLazyMap :: Map k v }-    deriving (Show)--  force m = Map.foldl' (flip seq) () m `seq` StrictMap m-  project = toLazyMap--instance (Ord k, Binary k, Binary v) => Binary (Strict (Map k) v) where-  put = put . Map.toList . toLazyMap-  get = (force . Map.fromList) <$> get--instance (PrettyVal k, PrettyVal v) => PrettyVal (Strict (Map k) v) where-  prettyVal = prettyVal . toLazyMap--{-------------------------------------------------------------------------------  Maybe-------------------------------------------------------------------------------}--instance StrictContainer Maybe where-  newtype Strict Maybe a = StrictMaybe { toLazyMaybe :: Maybe a }-    deriving (Show)--  force Nothing  = StrictMaybe Nothing-  force (Just x) = x `seq` StrictMaybe $ Just x-  project = toLazyMaybe--instance Binary a => Binary (Strict Maybe a) where-  put = put . toLazyMaybe-  get = force <$> get--deriving instance Eq  a => Eq  (Strict Maybe a)-deriving instance Ord a => Ord (Strict Maybe a)--instance Functor (Strict Maybe) where-  fmap f = force . fmap f . toLazyMaybe--instance PrettyVal a => PrettyVal (Strict Maybe a) where-  prettyVal = prettyVal . toLazyMaybe--instance Applicative (Strict Maybe) where-  pure    = force . pure-  -- We need 'force' here because we need to force the result of the-  -- function application-  f <*> a = force $ toLazyMaybe f <*> toLazyMaybe a--instance Alternative (Strict Maybe) where-  empty   = StrictMaybe Nothing-  a <|> b = StrictMaybe $ toLazyMaybe a <|> toLazyMaybe b--{-------------------------------------------------------------------------------  Trie-------------------------------------------------------------------------------}--instance StrictContainer Trie where-  newtype Strict Trie a = StrictTrie { toLazyTrie :: Trie a }-    deriving (Show)--  force m = Foldable.foldl (flip seq) () m `seq` StrictTrie m-  project = toLazyTrie--instance PrettyVal a => PrettyVal (Strict Trie a) where-  prettyVal = prettyVal . toLazyTrie
− IdeSession/Strict/IORef.hs
@@ -1,28 +0,0 @@--- IORefs that always evaluate their contents to WHNF-module IdeSession.Strict.IORef (-    StrictIORef -- Abstract-  , newIORef-  , readIORef-  , writeIORef-  , modifyIORef-  ) where--import Control.Applicative ((<$>))-import Control.Exception (evaluate)-import Data.IORef (IORef)-import qualified Data.IORef as IORef--newtype StrictIORef a = StrictIORef (IORef a)--newIORef :: a -> IO (StrictIORef a)-newIORef x = StrictIORef <$> (evaluate x >>= IORef.newIORef)--readIORef :: StrictIORef a -> IO a-readIORef (StrictIORef v) = IORef.readIORef v--writeIORef :: StrictIORef a -> a -> IO ()-writeIORef (StrictIORef v) x = evaluate x >>= IORef.writeIORef v---- base 4.6 exports modifyIORef' but 4.5 does not.-modifyIORef :: StrictIORef a -> (a -> a) -> IO ()-modifyIORef v f = readIORef v >>= writeIORef v . f
− IdeSession/Strict/IntMap.hs
@@ -1,68 +0,0 @@-{-# LANGUAGE TypeFamilies, FlexibleInstances #-}--- | Wrapper around Data.IntMap that guarantees elements are evaluated when--- the Map is. containers-0.5 provides this out of the box, but alas ghc 7.4--- is built against containers-0.4.-{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}-module IdeSession.Strict.IntMap (-    fromList-  , toList-  , lookup-  , findWithDefault-  , empty-  , adjust-  , insertWith-  , map-  , reverseLookup-  , filter-  , filterWithKey-  , union-  ) where--import Prelude hiding (map, filter, lookup)-import Data.Tuple (swap)-import qualified Data.IntMap as IntMap-import qualified Data.List as List--import IdeSession.Strict.Container--lookup :: Int -> Strict IntMap v -> Maybe v-lookup i = IntMap.lookup i . toLazyIntMap--findWithDefault :: v -> Int -> Strict IntMap v -> v-findWithDefault def i = IntMap.findWithDefault def i . toLazyIntMap--fromList :: [(Int, v)] -> Strict IntMap v-fromList = force . IntMap.fromList--toList :: Strict IntMap v -> [(Int, v)]-toList = IntMap.toList . toLazyIntMap--empty :: Strict IntMap v-empty = StrictIntMap $ IntMap.empty---- We use alter because it gives us something to anchor a seq to-adjust :: forall v. (v -> v) -> Int -> Strict IntMap v -> Strict IntMap v-adjust f i = StrictIntMap . IntMap.alter aux i . toLazyIntMap-  where-    aux :: Maybe v -> Maybe v-    aux Nothing  = Nothing-    aux (Just v) = let v' = f v in v' `seq` Just v'--insertWith :: (v -> v -> v) -> Int -> v -> Strict IntMap v -> Strict IntMap v-insertWith f i v = StrictIntMap . IntMap.insertWith' f i v . toLazyIntMap--map :: (a -> b) -> Strict IntMap a -> Strict IntMap b-map f = force . IntMap.map f . toLazyIntMap---- O(n)-reverseLookup :: Eq v => Strict IntMap v -> v -> Maybe Int-reverseLookup m v = List.lookup v $ List.map swap $ toList m--filter :: (v -> Bool) -> Strict IntMap v -> Strict IntMap v-filter p = StrictIntMap . IntMap.filter p . toLazyIntMap--filterWithKey :: (Int -> v -> Bool) -> Strict IntMap v -> Strict IntMap v-filterWithKey p = StrictIntMap . IntMap.filterWithKey p . toLazyIntMap--union :: Strict IntMap v -> Strict IntMap v -> Strict IntMap v-union a b = StrictIntMap $ IntMap.union (toLazyIntMap a) (toLazyIntMap b)
− IdeSession/Strict/IntervalMap.hs
@@ -1,62 +0,0 @@-module IdeSession.Strict.IntervalMap (-    StrictIntervalMap-  , dominators-  , fromList-  , toList-  , empty-  , insert-    -- * Re-exports-  , Interval(..)-  ) where--import Data.IntervalMap.FingerTree (Interval(..), IntervalMap)-import qualified Data.IntervalMap.FingerTree as IntervalMap-import Text.Show.Pretty--{--  We maintain an interval spanning the entire map, in order to support a toList-  operation.--}--data StrictIntervalMap v a = StrictIntervalMap {-    toLazyIntervalMap :: !(IntervalMap v a)-  , maxInterval       :: !(Maybe (Interval v))-  }--instance (Ord v, Show v, Show a) => Show (StrictIntervalMap v a) where-  show m = "fromList " ++ show (toList m)--instance (Ord v, PrettyVal v, PrettyVal a) => PrettyVal (StrictIntervalMap v a) where-  prettyVal m = Con "fromList" [prettyVal . map flattenIntervals . toList $ m]-    where-      flattenIntervals :: (Interval v, a) -> ((v, v), a)-      flattenIntervals (Interval lo hi, a) = ((lo, hi), a)--unionInterval :: Ord v => Interval v -> Maybe (Interval v) -> Maybe (Interval v)-unionInterval i@(Interval low high) Nothing =-  low `seq` high `seq` Just i-unionInterval (Interval low1 high1) (Just (Interval low2 high2)) =-  let low  = min low1  low2-      high = max high1 high2-  in low `seq` high `seq` Just (Interval low high)--dominators :: Ord v => Interval v -> StrictIntervalMap v a -> [(Interval v, a)]-dominators i = IntervalMap.dominators i . toLazyIntervalMap--empty :: Ord v => StrictIntervalMap v a-empty = StrictIntervalMap IntervalMap.empty Nothing--insert :: Ord v => Interval v -> a -> StrictIntervalMap v a -> StrictIntervalMap v a-insert i a m =-  a `seq` StrictIntervalMap {-      toLazyIntervalMap = IntervalMap.insert i a $ toLazyIntervalMap m-    , maxInterval       = unionInterval i        $ maxInterval m-    }--fromList :: Ord v => [(Interval v, a)] -> StrictIntervalMap v a-fromList = foldr (\(i, a) m -> insert i a m) empty--toList :: Ord v => StrictIntervalMap v a -> [(Interval v, a)]-toList m = case maxInterval m of-             Nothing -> []-             Just i  -> IntervalMap.intersections i (toLazyIntervalMap m)
− IdeSession/Strict/List.hs
@@ -1,49 +0,0 @@-{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}--- | Strict lists-module IdeSession.Strict.List (-    nil-  , cons-  , singleton-  , map-  , all-  , any-  , reverse-  , (++)-  , elem-  , (\\)-  ) where--import Prelude hiding (map, all, any, reverse, (++), elem)-import qualified Data.List as List--import IdeSession.Strict.Container--nil :: Strict [] a-nil = StrictList []--cons :: a -> Strict [] a -> Strict [] a-cons x xs = x `seq` StrictList (x : toLazyList xs)--singleton :: a -> Strict [] a-singleton x = x `seq` StrictList [x]--map :: (a -> b) -> Strict [] a -> Strict [] b-map f = force . List.map f . toLazyList--all :: (a -> Bool) -> Strict [] a -> Bool-all p = List.all p . toLazyList--any :: (a -> Bool) -> Strict [] a -> Bool-any p = List.any p . toLazyList--elem :: Eq a => a -> Strict [] a -> Bool-elem x = List.elem x . toLazyList--reverse :: Strict [] a -> Strict [] a-reverse = StrictList . List.reverse . toLazyList--(++) :: Strict [] a -> Strict [] a -> Strict [] a-xs ++ ys = StrictList $ toLazyList xs List.++ toLazyList ys--(\\) :: Eq a => Strict [] a -> Strict [] a -> Strict [] a-xs \\ ys = StrictList $ toLazyList xs List.\\ toLazyList ys
− IdeSession/Strict/MVar.hs
@@ -1,66 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}--- | MVar that always evaluates its argument to WHNF-module IdeSession.Strict.MVar (-    StrictMVar -- Abstract-  , newEmptyMVar-  , newMVar-  , takeMVar-  , putMVar-  , readMVar-  , swapMVar-  , tryTakeMVar-  , tryPutMVar-  , isEmptyMVar-  , withMVar-  , modifyMVar_-  , modifyMVar-  ) where--import Control.Concurrent.MVar (MVar)-import qualified Control.Concurrent.MVar as MVar-import Control.Applicative ((<$>))-import Control.Exception (evaluate)-import Control.Monad ((>=>))--newtype StrictMVar a = StrictMVar (MVar a)--newEmptyMVar :: IO (StrictMVar a)-newEmptyMVar = StrictMVar <$> MVar.newEmptyMVar--newMVar :: a -> IO (StrictMVar a)-newMVar x = StrictMVar <$> (evaluate x >>= MVar.newMVar)--takeMVar :: StrictMVar a -> IO a-takeMVar (StrictMVar v) = MVar.takeMVar v--putMVar :: StrictMVar a -> a -> IO ()-putMVar (StrictMVar v) x = evaluate x >>= MVar.putMVar v--readMVar :: StrictMVar a -> IO a-readMVar (StrictMVar v) = MVar.readMVar v--swapMVar :: StrictMVar a -> a -> IO a-swapMVar (StrictMVar v) x = evaluate x >>= MVar.swapMVar v--tryTakeMVar :: StrictMVar a -> IO (Maybe a)-tryTakeMVar (StrictMVar v) = MVar.tryTakeMVar v--tryPutMVar :: StrictMVar a -> a -> IO Bool-tryPutMVar (StrictMVar v) x = evaluate x >>= MVar.tryPutMVar v--isEmptyMVar :: StrictMVar a -> IO Bool-isEmptyMVar (StrictMVar v) = MVar.isEmptyMVar v--withMVar :: StrictMVar a -> (a -> IO b) -> IO b-withMVar (StrictMVar v) f = MVar.withMVar v f--modifyMVar_ :: StrictMVar a -> (a -> IO a) -> IO ()-modifyMVar_ (StrictMVar v) f = MVar.modifyMVar_ v (f >=> evaluate)--modifyMVar :: forall a b. StrictMVar a -> (a -> IO (a, b)) -> IO b-modifyMVar (StrictMVar v) f = MVar.modifyMVar v aux-  where-    aux :: a -> IO (a, b)-    aux x = do (a, b) <- f x-               a' <- evaluate a-               return (a', b)
− IdeSession/Strict/Map.hs
@@ -1,122 +0,0 @@-{-# LANGUAGE TemplateHaskell, ScopedTypeVariables #-}--- | Wrapper around Data.Map that guarantees elements are evaluated when--- the Map is. containers-0.5 provides this out of the box, but alas ghc 7.4--- is built against containers-0.4.-module IdeSession.Strict.Map (-    toList-  , fromList-  , map-  , mapWithKey-  , mapKeys-  , empty-  , insert-  , union-  , unions-  , filterWithKey-  , lookup-  , findWithDefault-  , keysSet-  , (\\)-  , alter-  , adjust-  , member-  , (!)-  , keys-  , elems-  , delete-  , accessor-  , accessorDefault-  ) where--import Prelude hiding (map, lookup)-import Data.Set (Set)-import qualified Data.Map as Map-import Data.Accessor (Accessor)-import qualified Data.Accessor as Acc-import qualified Data.List as List--import IdeSession.Strict.Container--toList :: Strict (Map k) v -> [(k, v)]-toList = Map.toList . toLazyMap--fromList :: Ord k => [(k, v)] -> Strict (Map k) v-fromList = force . Map.fromList--map :: (a -> b) -> Strict (Map k) a  -> Strict (Map k) b-map f = force . Map.map f . toLazyMap--mapWithKey :: (k -> a -> b) -> Strict (Map k) a  -> Strict (Map k) b-mapWithKey f = force . Map.mapWithKey f . toLazyMap--mapKeys :: Ord k' => (k -> k') -> Strict (Map k) v -> Strict (Map k') v--- Maps are already strict in keys-mapKeys f = StrictMap . Map.mapKeys f . toLazyMap--empty :: Strict (Map k) v-empty = StrictMap Map.empty--insert :: Ord k => k -> v -> Strict (Map k) v -> Strict (Map k) v-insert k v = StrictMap . Map.insertWith' const k v . toLazyMap---- | Left biased union-union :: Ord k => Strict (Map k) v -> Strict (Map k) v -> Strict (Map k) v-union a b = StrictMap $ Map.union (toLazyMap a) (toLazyMap b)--unions :: Ord k => [Strict (Map k) v] -> Strict (Map k) v-unions = StrictMap . Map.unions . List.map toLazyMap--filterWithKey :: Ord k => (k -> v -> Bool) -> Strict (Map k) v -> Strict (Map k) v-filterWithKey p = StrictMap . Map.filterWithKey p . toLazyMap--keysSet :: Strict (Map k) v -> Set k-keysSet = Map.keysSet . toLazyMap--lookup :: Ord k => k -> Strict (Map k) v -> Maybe v-lookup k = Map.lookup k . toLazyMap--findWithDefault :: Ord k => v -> k -> Strict (Map k) v -> v-findWithDefault d k = Map.findWithDefault d k . toLazyMap--(\\) :: Ord k => Strict (Map k) a -> Strict (Map k) b -> Strict (Map k) a-(\\) a b = StrictMap $ (Map.\\) (toLazyMap a) (toLazyMap b)--alter :: forall k a. Ord k-      => (Maybe a -> Maybe a) -> k -> Strict (Map k) a -> Strict (Map k) a-alter f k = StrictMap . Map.alter aux k . toLazyMap-  where-    aux :: Maybe a -> Maybe a-    aux ma = case f ma of-               Nothing -> Nothing-               Just a  -> a `seq` Just a---- We use alter because it gives us something to anchor a seq to-adjust :: forall k v. Ord k => (v -> v) -> k -> Strict (Map k) v -> Strict (Map k) v-adjust f i = StrictMap . Map.alter aux i . toLazyMap-  where-    aux :: Maybe v -> Maybe v-    aux Nothing  = Nothing-    aux (Just v) = let v' = f v in v' `seq` Just v'--member :: Ord k => k -> Strict (Map k) v -> Bool-member k = Map.member k . toLazyMap--(!) :: Ord k => Strict (Map k) v -> k -> v-(!) = (Map.!) . toLazyMap--keys :: Strict (Map k) a -> [k]-keys = Map.keys . toLazyMap--elems :: Strict (Map k) a -> [a]-elems = Map.elems . toLazyMap--delete :: Ord k => k -> Strict (Map k) a -> Strict (Map k) a-delete k = StrictMap . Map.delete k . toLazyMap--accessor :: Ord k => k -> Accessor (Strict (Map k) a) (Maybe a)-accessor key = Acc.accessor (lookup key) (\mval mp -> case mval of-                                            Just val -> insert key val mp-                                            Nothing  -> delete key mp)--accessorDefault :: Ord k => v -> k -> Accessor (Strict (Map k) v) v-accessorDefault d k = Acc.accessor (findWithDefault d k) (insert k)
− IdeSession/Strict/Maybe.hs
@@ -1,24 +0,0 @@-{-# LANGUAGE TemplateHaskell, DeriveFunctor #-}--- | Version of maybe that is strict in its argument-module IdeSession.Strict.Maybe (-    nothing-  , just-  , maybe-  , fromMaybe-  ) where--import Prelude hiding (maybe)-import IdeSession.Strict.Container-import qualified Data.Maybe as Maybe--nothing :: Strict Maybe a-nothing = force $ Nothing--just :: a -> Strict Maybe a-just = force . Just--maybe :: b -> (a -> b) -> Strict Maybe a -> b-maybe x f =  Maybe.maybe x f . toLazyMaybe--fromMaybe :: a -> Strict Maybe a -> a-fromMaybe def = Maybe.fromMaybe def . toLazyMaybe
− IdeSession/Strict/StateT.hs
@@ -1,65 +0,0 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}--- | Version on StateT which evaluates the state strictly at every step-module IdeSession.Strict.StateT (-    -- * Transformer-    StrictStateT(..)-  , modify-  , evalStateT-  , execStateT-    -- * As base monad-  , StrictState-  , runState-  , evalState-  , execState-  ) where--import Control.Applicative-import Control.Monad.State.Class-import Control.Monad.Trans.Class-import Data.Functor.Identity--newtype StrictStateT s m a = StrictStateT { runStateT :: s -> m (a, s) }--instance Monad m => Applicative (StrictStateT s m) where-  pure    = return-  f <*> x = do f' <- f ; x' <- x ; return (f' x')--instance Monad m => Monad (StrictStateT s m) where-  return a = StrictStateT $ \s -> return (a, s)-  x >>= f  = StrictStateT $ \s -> do (a, s')  <- runStateT x s-                                     (b, s'') <- runStateT (f a) s'-                                     return (b, s'')--instance Monad m => Functor (StrictStateT s m) where-  f `fmap` m = m >>= return . f--instance Monad m => MonadState s (StrictStateT s m) where-  get     = StrictStateT $ \s -> return (s, s)-  put s   = StrictStateT $ \_ -> s `seq` return ((), s)-  state f = StrictStateT $ \s -> do let (a, s') = f s-                                    s' `seq` return (a, s')--instance MonadTrans (StrictStateT s) where-  lift m = StrictStateT $ \s -> do a <- m-                                   return (a, s)--evalStateT :: Monad m => StrictStateT s m a -> s -> m a-evalStateT m s = do (a, _) <- runStateT m s ; return a--execStateT :: Monad m => StrictStateT s m a -> s -> m s-execStateT m s = do (_, s') <- runStateT m s ; return s'--{-------------------------------------------------------------------------------  As base monad-------------------------------------------------------------------------------}--type StrictState s = StrictStateT s Identity--runState :: StrictState s a -> s -> (a, s)-runState m s = runIdentity $ runStateT m s--evalState :: StrictState s a -> s -> a-evalState m = fst . runState m--execState :: StrictState s a -> s -> s-execState m = snd . runState m
− IdeSession/Strict/Trie.hs
@@ -1,27 +0,0 @@-module IdeSession.Strict.Trie (-    empty-  , submap-  , elems-  , fromListWith-  , toList-  ) where--import Data.ByteString (ByteString)-import qualified Data.Trie as Trie-import qualified Data.Trie.Convenience as Trie-import IdeSession.Strict.Container--empty :: Strict Trie a-empty = StrictTrie $ Trie.empty--submap :: ByteString -> Strict Trie a -> Strict Trie a-submap bs = StrictTrie . Trie.submap bs . toLazyTrie--elems :: Strict Trie a -> [a]-elems = Trie.elems . toLazyTrie--fromListWith :: (a -> a -> a) -> [(ByteString, a)] -> Strict Trie a-fromListWith f = force . Trie.fromListWith f--toList :: Strict Trie a -> [(ByteString, a)]-toList = Trie.toList . toLazyTrie
− IdeSession/Types/Private.hs
@@ -1,411 +0,0 @@-{-# LANGUAGE TemplateHaskell, GeneralizedNewtypeDeriving, DeriveDataTypeable, DeriveGeneric #-}--- | The private types-module IdeSession.Types.Private (-    -- * Types without a public counterpart-    FilePathPtr(..)-  , IdPropPtr(..)-  , UseSites-    -- * Types with a public counterpart-  , Public.IdNameSpace(..)-  , IdInfo(..)-  , IdProp(..)-  , IdScope(..)-  , SourceSpan(..)-  , EitherSpan(..)-  , SourceError(..)-  , Public.SourceErrorKind(..)-  , Public.ModuleName-  , ModuleId(..)-  , PackageId(..)-  , IdList-  , IdMap(..)-  , ExpMap(..)-  , SpanInfo(..)-  , ImportEntities(..)-  , Import(..)-  , RunResult(..)-  , BreakInfo(..)-    -- * Cache-  , ExplicitSharingCache(..)-  , unionCache-    -- * Util-  , mkIdMap-  , mkExpMap-  , dominators-  ) where--import Prelude hiding (span, mod)-import Data.Text (Text)-import Data.ByteString (ByteString)-import Control.Applicative ((<$>), (<*>))-import Control.Arrow (first)-import Data.Binary (Binary(..), getWord8, putWord8)-import Data.Typeable (Typeable)-import GHC.Generics (Generic)--import qualified IdeSession.Types.Public as Public-import IdeSession.Strict.Container-import IdeSession.Strict.IntervalMap (StrictIntervalMap, Interval(..))-import qualified IdeSession.Strict.IntervalMap as IntervalMap-import qualified IdeSession.Strict.IntMap      as IntMap-import IdeSession.Util.PrettyVal--newtype FilePathPtr = FilePathPtr { filePathPtr :: Int }-  deriving (Eq, Ord, Show, Generic)--newtype IdPropPtr = IdPropPtr { idPropPtr :: Int }-  deriving (Eq, Ord, Show, Generic)--data IdInfo = IdInfo {-    idProp  :: {-# UNPACK #-} !IdPropPtr-  , idScope :: !IdScope-  }-  deriving (Show, Typeable, Generic)--data IdProp = IdProp {-    idName       :: !Text-  , idSpace      :: !Public.IdNameSpace-  , idType       :: !(Strict Maybe Public.Type)-  , idDefinedIn  :: {-# UNPACK #-} !ModuleId-  , idDefSpan    :: !EitherSpan-  , idHomeModule :: !(Strict Maybe ModuleId)-  }-  deriving (Show, Generic)--data IdScope =-    -- | This is a binding occurrence (@f x = ..@, @\x -> ..@, etc.)-    Binder-    -- | Defined within this module-  | Local-    -- | Imported from a different module-  | Imported {-        idImportedFrom :: {-# UNPACK #-} !ModuleId-      , idImportSpan   :: !EitherSpan-        -- | Qualifier used for the import-        ---        -- > IMPORTED AS                       idImportQual-        -- > import Data.List                  ""-        -- > import qualified Data.List        "Data.List."-        -- > import qualified Data.List as L   "L."-      , idImportQual   :: !Text-      }-    -- | Wired into the compiler (@()@, @True@, etc.)-  | WiredIn-  deriving (Show, Generic)--data SourceSpan = SourceSpan-  { spanFilePath   :: {-# UNPACK #-} !FilePathPtr-  , spanFromLine   :: {-# UNPACK #-} !Int-  , spanFromColumn :: {-# UNPACK #-} !Int-  , spanToLine     :: {-# UNPACK #-} !Int-  , spanToColumn   :: {-# UNPACK #-} !Int-  }-  deriving (Eq, Ord, Show, Generic)--data EitherSpan =-    ProperSpan {-# UNPACK #-} !SourceSpan-  | TextSpan !Text-  deriving (Show, Generic)--data SourceError = SourceError-  { errorKind :: !Public.SourceErrorKind-  , errorSpan :: !EitherSpan-  , errorMsg  :: !Text-  }-  deriving (Show, Generic)--data ModuleId = ModuleId-  { moduleName    :: !Public.ModuleName-  , modulePackage :: {-# UNPACK #-} !PackageId-  }-  deriving (Show, Eq, Generic)--data PackageId = PackageId-  { packageName    :: !Text-  , packageVersion :: !(Strict Maybe Text)-  , packageKey     :: !Text-  }-  deriving (Show, Eq, Ord, Generic)---- | Used before we convert it to an IdMap-type IdList = [(SourceSpan, SpanInfo)]--data SpanInfo =-   SpanId IdInfo- | SpanQQ IdInfo-   -- We use 'SpanInSplice' for prioritization only (see 'internalGetSpanInfo').-   -- It gets translated to 'Public.SpanId'- | SpanInSplice IdInfo- deriving (Show, Generic)--newtype IdMap = IdMap { idMapToMap :: StrictIntervalMap (FilePathPtr, Int, Int) SpanInfo }-  deriving (Show, Generic)--newtype ExpMap = ExpMap { expMapToMap :: StrictIntervalMap (FilePathPtr, Int, Int) Text }-  deriving (Show, Generic)--type UseSites = Strict (Map IdPropPtr) [SourceSpan]--data ImportEntities =-    ImportOnly   !(Strict [] Text)-  | ImportHiding !(Strict [] Text)-  | ImportAll-  deriving (Show, Eq, Generic)--data Import = Import {-    importModule    :: !ModuleId-  -- | Used only for ghc's PackageImports extension-  , importPackage   :: !(Strict Maybe Text)-  , importQualified :: !Bool-  , importImplicit  :: !Bool-  , importAs        :: !(Strict Maybe Public.ModuleName)-  , importEntities  :: !ImportEntities-  }-  deriving (Show, Eq, Generic)---- | The outcome of running code-data RunResult =-    -- | The code terminated okay-    RunOk-    -- | The code threw an exception-  | RunProgException String-    -- | GHC itself threw an exception when we tried to run the code-  | RunGhcException String-    -- | Execution was paused because of a breakpoint-  | RunBreak BreakInfo-  deriving (Typeable, Show, Generic)---- | Information about a triggered breakpoint-data BreakInfo = BreakInfo {-    breakInfoModule      :: Public.ModuleName-  , breakInfoSpan        :: SourceSpan-  , breakInfoResultType  :: Public.Type-  , breakInfoVariableEnv :: Public.VariableEnv-  }-  deriving (Typeable, Show, Generic)--{-------------------------------------------------------------------------------  Cache-------------------------------------------------------------------------------}---- TODO: Since the ExplicitSharingCache contains internal types, resolving--- references to the cache means we lose implicit sharing because we need--- to translate on every lookup. To avoid this, we'd have to introduce two--- versions of the cache and translate the entire cache first.-data ExplicitSharingCache = ExplicitSharingCache {-    filePathCache :: !(Strict IntMap ByteString)-  , idPropCache   :: !(Strict IntMap IdProp)-  }-  deriving (Show, Generic)--unionCache :: ExplicitSharingCache -> ExplicitSharingCache -> ExplicitSharingCache-unionCache a b = ExplicitSharingCache {-    filePathCache = IntMap.union (filePathCache a) (filePathCache b)-  , idPropCache   = IntMap.union (idPropCache   a) (idPropCache   b)-  }--{-------------------------------------------------------------------------------  Binary instances-------------------------------------------------------------------------------}--instance Binary FilePathPtr where-  put = put . filePathPtr-  get = FilePathPtr <$> get--instance Binary SourceSpan where-  put SourceSpan{..} = do-    put spanFilePath-    put spanFromLine-    put spanFromColumn-    put spanToLine-    put spanToColumn-  get = SourceSpan <$> get <*> get <*> get <*> get <*> get--instance Binary EitherSpan where-  put (ProperSpan span) = putWord8 0 >> put span-  put (TextSpan text)   = putWord8 1 >> put text--  get = do-    header <- getWord8-    case header of-      0 -> ProperSpan <$> get-      1 -> TextSpan <$> get-      _ -> fail "EitherSpan.get: invalid header"--instance Binary SourceError where-  put SourceError{..} = do-    put errorKind-    put errorSpan-    put errorMsg--  get = SourceError <$> get <*> get <*> get--instance Binary IdInfo where-  put IdInfo{..} = put idProp >> put idScope-  get = IdInfo <$> get <*> get--instance Binary IdScope where-  put Binder       = putWord8 0-  put Local        = do putWord8 1-  put Imported{..} = do putWord8 2-                        put idImportedFrom-                        put idImportSpan-                        put idImportQual-  put WiredIn      = putWord8 3--  get = do-    header <- getWord8-    case header of-      0 -> return Binder-      1 -> return Local-      2 -> Imported <$> get <*> get <*> get-      3 -> return WiredIn-      _ -> fail "IdScope.get: invalid header"--instance Binary IdPropPtr where-  put = put . idPropPtr-  get = IdPropPtr <$> get--instance Binary ModuleId where-  put ModuleId{..} = put moduleName >> put modulePackage-  get = ModuleId <$> get <*> get--instance Binary PackageId where-  put PackageId{..} = do-    put packageName-    put packageVersion-    put packageKey-  get = PackageId <$> get <*> get <*> get--instance Binary IdProp where-  put IdProp{..} = do-    put idName-    put idSpace-    put idType-    put idDefinedIn-    put idDefSpan-    put idHomeModule--  get = IdProp <$> get <*> get <*> get <*> get <*> get <*> get--{--instance Binary IdMap where-  put = put . idMapToMap-  get = IdMap <$> get--}--instance Binary ImportEntities where-  put (ImportOnly names)   = putWord8 0 >> put names-  put (ImportHiding names) = putWord8 1 >> put names-  put ImportAll            = putWord8 2--  get = do-    header <- getWord8-    case header of-      0 -> ImportOnly   <$> get-      1 -> ImportHiding <$> get-      2 -> return ImportAll-      _ -> fail "ImportEntities.get: invalid header"--instance Binary Import where-  put Import{..} = do-    put importModule-    put importPackage-    put importQualified-    put importImplicit-    put importAs-    put importEntities--  get = Import <$> get <*> get <*> get <*> get <*> get <*> get--instance Binary ExplicitSharingCache where-  put ExplicitSharingCache{..} = do-    put filePathCache-    put idPropCache--  get = ExplicitSharingCache <$> get <*> get--instance Binary SpanInfo where-  put (SpanId idInfo)       = putWord8 0 >> put idInfo-  put (SpanQQ idInfo)       = putWord8 1 >> put idInfo-  put (SpanInSplice idInfo) = putWord8 2 >> put idInfo--  get = do-    header <- getWord8-    case header of-      0 -> SpanId       <$> get-      1 -> SpanQQ       <$> get-      2 -> SpanInSplice <$> get-      _ -> fail "SpanInfo.get: invalid header"--instance Binary RunResult where-  put RunOk                  = putWord8 0-  put (RunProgException str) = putWord8 1 >> put str-  put (RunGhcException str)  = putWord8 2 >> put str-  put (RunBreak info)        = putWord8 3 >> put info--  get = do-    header <- getWord8-    case header of-      0 -> return RunOk-      1 -> RunProgException <$> get-      2 -> RunGhcException <$> get-      3 -> RunBreak <$> get-      _ -> fail "RunResult.get: invalid header"--instance Binary BreakInfo where-  put (BreakInfo{..}) = do-    put breakInfoModule-    put breakInfoSpan-    put breakInfoResultType-    put breakInfoVariableEnv--  get = BreakInfo <$> get <*> get <*> get <*> get--{-------------------------------------------------------------------------------  PrettyVal instances (these rely on Generics)-------------------------------------------------------------------------------}--instance PrettyVal FilePathPtr-instance PrettyVal IdPropPtr-instance PrettyVal IdInfo-instance PrettyVal IdProp-instance PrettyVal IdScope-instance PrettyVal SourceSpan-instance PrettyVal EitherSpan-instance PrettyVal SourceError-instance PrettyVal ModuleId-instance PrettyVal PackageId-instance PrettyVal SpanInfo-instance PrettyVal IdMap-instance PrettyVal ExpMap-instance PrettyVal ImportEntities-instance PrettyVal Import-instance PrettyVal RunResult-instance PrettyVal BreakInfo-instance PrettyVal ExplicitSharingCache--{-------------------------------------------------------------------------------  Util-------------------------------------------------------------------------------}--mkIdMap :: IdList -> IdMap-mkIdMap = IdMap . IntervalMap.fromList . map (first spanToInterval)--mkExpMap :: [(SourceSpan, Text)] -> ExpMap-mkExpMap = ExpMap . IntervalMap.fromList . map (first spanToInterval)--dominators :: SourceSpan -> StrictIntervalMap (FilePathPtr, Int, Int) a -> [(SourceSpan, a)]-dominators span ivalmap =-    map (\(ival, idInfo) -> (intervalToSpan ival, idInfo))-        (IntervalMap.dominators (spanToInterval span) ivalmap)--spanToInterval :: SourceSpan -> Interval (FilePathPtr, Int, Int)-spanToInterval SourceSpan{..} =-  Interval (spanFilePath, spanFromLine, spanFromColumn)-           (spanFilePath, spanToLine, spanToColumn)--intervalToSpan :: Interval (FilePathPtr, Int, Int) -> SourceSpan-intervalToSpan (Interval (spanFilePath, spanFromLine, spanFromColumn)-                         (_,            spanToLine, spanToColumn)) =-  SourceSpan{..}
− IdeSession/Types/Progress.hs
@@ -1,61 +0,0 @@-{-# LANGUAGE DeriveGeneric #-}-module IdeSession.Types.Progress (-    Progress(..)-  ) where--import Control.Applicative ((<$>), (<*>), (<|>))-import Data.Binary (Binary(..))-import Data.Text (Text)-import Data.Maybe (fromJust)-import GHC.Generics (Generic)-import qualified Data.Text as Text-import Text.Show.Pretty (PrettyVal)--import IdeSession.Util () -- instance Binary Text---- | This type represents intermediate progress information during compilation.-data Progress = Progress {-    -- | The current step number-    ---    -- When these Progress messages are generated from progress updates from-    -- ghc, it is entirely possible that we might get step 4/26, 16/26, 3/26;-    -- the steps may not be continuous, might even be out of order, and may-    -- not finish at X/X.-    progressStep :: Int--    -- | The total number of steps-  , progressNumSteps :: Int--    -- | The parsed message. For instance, in the case of progress messages-    -- during compilation, 'progressOrigMsg' might be-    ---    -- > [1 of 2] Compiling M (some/path/to/file.hs, some/other/path/to/file.o)-    ---    -- while 'progressMsg' will just be 'Compiling M'-  , progressParsedMsg :: Maybe Text--    -- | The full original message (see 'progressMsg')-  , progressOrigMsg :: Maybe Text-  }-  deriving (Eq, Ord, Generic)--instance PrettyVal Progress--instance Binary Progress where-  put (Progress {..}) = do put progressStep-                           put progressNumSteps-                           put progressParsedMsg-                           put progressOrigMsg-  get = Progress <$> get <*> get <*> get <*> get--instance Show Progress where-  show (Progress{..}) =-         "["-      ++ show progressStep-      ++ " of "-      ++ show progressNumSteps-      ++ "]"-      ++ fromJust (pad progressParsedMsg <|> pad progressOrigMsg <|> Just "")-    where-      pad :: Maybe Text -> Maybe String-      pad = fmap $ \t -> " " ++ Text.unpack t
− IdeSession/Types/Public.hs
@@ -1,571 +0,0 @@-{-# LANGUAGE TemplateHaskell, DeriveDataTypeable, DeriveGeneric #-}--- | The public types-module IdeSession.Types.Public (-    -- * Types-    IdNameSpace(..)-  , Type-  , Name-  , IdInfo(..)-  , IdProp(..)-  , IdScope(..)-  , SourceSpan(..)-  , EitherSpan(..)-  , SourceError(..)-  , SourceErrorKind(..)-  , ModuleName-  , ModuleId(..)-  , PackageId(..)---  , IdMap(..)---  , LoadedModules-  , ImportEntities(..)-  , Import(..)-  , SpanInfo(..)-  , RunBufferMode(..)-  , RunResult(..)-  , BreakInfo(..)-  , Value-  , VariableEnv-  , Targets(..)-    -- * Util-  , idInfoQN---, idInfoAtLocation-  , haddockLink-  ) where--import Prelude hiding (span)-import Control.Applicative ((<$>), (<*>))-import Data.Text (Text)-import qualified Data.Text as Text-import Data.Binary (Binary(..), getWord8, putWord8)-import Data.Aeson.TH (deriveJSON, defaultOptions)-import Data.Typeable (Typeable)-import GHC.Generics (Generic)--import IdeSession.Util () -- Binary instance for Text-import IdeSession.Util.PrettyVal--{-------------------------------------------------------------------------------  Types-------------------------------------------------------------------------------}---- | Identifiers in Haskell are drawn from a number of different name spaces-data IdNameSpace =-    VarName    -- ^ Variables, including real data constructors-  | DataName   -- ^ Source data constructors-  | TvName     -- ^ Type variables-  | TcClsName  -- ^ Type constructors and classes-  deriving (Show, Eq, Generic)---- | Information about identifiers-data IdInfo = IdInfo {-    idProp  :: {-# UNPACK #-} !IdProp-  , idScope :: !IdScope-  }-  deriving (Eq, Generic)---- | Variable name-type Name = Text---- | For now we represent types in pretty-printed form-type Type = Text---- | Identifier info that is independent of the usage site-data IdProp = IdProp {-    -- | The base name of the identifer at this location. Module prefix-    -- is not included.-    idName  :: !Name-    -- | Namespace this identifier is drawn from-  , idSpace :: !IdNameSpace-    -- | The type-    -- We don't always know this; in particular, we don't know kinds because-    -- the type checker does not give us LSigs for top-level annotations)-  , idType  :: !(Maybe Type)-    -- | Module the identifier was defined in-  , idDefinedIn :: {-# UNPACK #-} !ModuleId-    -- | Where in the module was it defined (not always known)-  , idDefSpan :: !EitherSpan-    -- | Haddock home module-  , idHomeModule :: !(Maybe ModuleId)-  }-  deriving (Eq, Generic)---- TODO: Ideally, we would have--- 1. SourceSpan for Local rather than EitherSpan--- 2. SourceSpan for idImportSpan--- 3. Have a idImportedFromPackage, but unfortunately ghc doesn't give us---    this information (it's marked as a TODO in RdrName.lhs)-data IdScope =-    -- | This is a binding occurrence (@f x = ..@, @\x -> ..@, etc.)-    Binder-    -- | Defined within this module-  | Local-    -- | Imported from a different module-  | Imported {-        idImportedFrom :: {-# UNPACK #-} !ModuleId-      , idImportSpan   :: !EitherSpan-        -- | Qualifier used for the import-        ---        -- > IMPORTED AS                       idImportQual-        -- > import Data.List                  ""-        -- > import qualified Data.List        "Data.List."-        -- > import qualified Data.List as L   "L."-      , idImportQual   :: !Text-      }-    -- | Wired into the compiler (@()@, @True@, etc.)-  | WiredIn-  deriving (Eq, Generic)--data SourceSpan = SourceSpan-  { spanFilePath   :: !FilePath-  , spanFromLine   :: {-# UNPACK #-} !Int-  , spanFromColumn :: {-# UNPACK #-} !Int-  , spanToLine     :: {-# UNPACK #-} !Int-  , spanToColumn   :: {-# UNPACK #-} !Int-  }-  deriving (Eq, Ord, Generic)--data EitherSpan =-    ProperSpan {-# UNPACK #-} !SourceSpan-  | TextSpan !Text-  deriving (Eq, Generic)---- | An error or warning in a source module.------ Most errors are associated with a span of text, but some have only a--- location point.-data SourceError = SourceError-  { errorKind :: !SourceErrorKind-  , errorSpan :: !EitherSpan-  , errorMsg  :: !Text-  }-  deriving (Show, Eq, Generic)---- | Severity of an error.-data SourceErrorKind = KindError | KindWarning | KindServerDied-  deriving (Show, Eq, Generic)--type ModuleName = Text--data ModuleId = ModuleId-  { moduleName    :: !ModuleName-  , modulePackage :: {-# UNPACK #-} !PackageId-  }-  deriving (Eq, Ord, Generic)---- | A package ID in ide-backend consists of a human-readable package name--- and version (what Cabal calls a source ID) along with ghc's internal--- package key (primarily for internal use).-data PackageId = PackageId-  { packageName    :: !Text-  , packageVersion :: !(Maybe Text)-  , packageKey     :: !Text-  }-  deriving (Eq, Ord, Generic)--{--newtype IdMap = IdMap { idMapToMap :: Map SourceSpan IdInfo }--type LoadedModules = Map ModuleName IdMap--}--data ImportEntities =-    ImportOnly   ![Text]-  | ImportHiding ![Text]-  | ImportAll-  deriving (Show, Eq, Ord, Generic)--data Import = Import {-    importModule    :: !ModuleId-  -- | Used only for ghc's PackageImports extension-  , importPackage   :: !(Maybe Text)-  , importQualified :: !Bool-  , importImplicit  :: !Bool-  , importAs        :: !(Maybe ModuleName)-  , importEntities  :: !ImportEntities-  }-  deriving (Show, Eq, Ord, Generic)---- | Returned then the IDE asks "what's at this particular location?"-data SpanInfo =-    -- | Identifier-    SpanId IdInfo-    -- | Quasi-quote. The 'IdInfo' field gives the quasi-quoter-  | SpanQQ IdInfo-  deriving (Generic)---- | Buffer modes for running code------ Note that 'NoBuffering' means that something like 'putStrLn' will do a--- syscall per character, and each of these characters will be read and sent--- back to the client. This results in a large overhead.------ When using 'LineBuffering' or 'BlockBuffering', 'runWait' will not report--- any output from the snippet until it outputs a linebreak/fills the buffer,--- respectively (or does an explicit flush). However, you can specify a timeout--- in addition to the buffering mode; if you set this to @Just n@, the buffer--- will be flushed every @n@ microseconds.------ NOTE: This is duplicated in the IdeBackendRTS (defined in IdeSession)-data RunBufferMode =-    RunNoBuffering-  | RunLineBuffering  { runBufferTimeout   :: Maybe Int }-  | RunBlockBuffering { runBufferBlockSize :: Maybe Int-                      , runBufferTimeout   :: Maybe Int-                      }-  deriving (Typeable, Show, Generic, Eq)---- | The outcome of running code-data RunResult =-    -- | The code terminated okay-    RunOk-    -- | The code threw an exception-  | RunProgException String-    -- | GHC itself threw an exception when we tried to run the code-  | RunGhcException String-    -- | The session was restarted-  | RunForceCancelled-    -- | Execution was paused because of a breakpoint-  | RunBreak-  deriving (Typeable, Show, Eq, Generic)---- | Information about a triggered breakpoint-data BreakInfo = BreakInfo {-    -- | Module containing the breakpoint-    breakInfoModule :: ModuleName-    -- | Location of the breakpoint-  , breakInfoSpan :: SourceSpan-    -- | Type of the result-  , breakInfoResultType :: Type-    -- | Local variables and their values-  , breakInfoVariableEnv :: VariableEnv-  }-  deriving (Typeable, Show, Eq, Generic)---- | We present values only in pretty-printed form-type Value = Text---- | Variables during execution (in debugging mode)-type VariableEnv = [(Name, Type, Value)]--data Targets = TargetsInclude [FilePath] | TargetsExclude [FilePath]-  deriving (Typeable, Generic, Eq, Show)--{-------------------------------------------------------------------------------  Show instances-------------------------------------------------------------------------------}--instance Show SourceSpan where-  show (SourceSpan{..}) =-       spanFilePath ++ "@"-    ++ show spanFromLine ++ ":" ++ show spanFromColumn ++ "-"-    ++ show spanToLine   ++ ":" ++ show spanToColumn--instance Show IdProp where-  show (IdProp {..}) =-       Text.unpack idName ++ " "-    ++ "(" ++ show idSpace ++ ")"-    ++ (case idType of Just typ -> " :: " ++ Text.unpack typ; Nothing -> [])-    ++ " defined in "-    ++ show idDefinedIn-    ++ " at " ++ show idDefSpan-    ++ (case idHomeModule of Just home -> " (home " ++ show home ++ ")"-                             Nothing   -> "")--instance Show IdScope where-  show Binder          = "binding occurrence"-  show Local           = "defined locally"-  show WiredIn         = "wired in to the compiler"-  show (Imported {..}) =-           "imported from " ++ show idImportedFrom-        ++ (if Text.null idImportQual-              then []-              else " as '" ++ Text.unpack idImportQual ++ "'")-        ++ " at "++ show idImportSpan--instance Show EitherSpan where-  show (ProperSpan srcSpan) = show srcSpan-  show (TextSpan str)       = Text.unpack str--instance Show ModuleId where-  show (ModuleId mo pkg) = show pkg ++ ":" ++ Text.unpack mo--instance Show PackageId where-  show (PackageId name (Just version) _pkey) =-    Text.unpack name ++ "-" ++ Text.unpack version-  show (PackageId name Nothing _pkey) =-    Text.unpack name--instance Show IdInfo where-  show IdInfo{..} = show idProp ++ " (" ++ show idScope ++ ")"--instance Show SpanInfo where-  show (SpanId idInfo) = show idInfo-  show (SpanQQ idInfo) = "quasi-quote with quoter " ++ show idInfo--{--instance Show IdMap where-  show =-    let showIdInfo(span, idInfo) = "(" ++ show span ++ "," ++ show idInfo ++ ")"-    in unlines . map showIdInfo . Map.toList . idMapToMap--}--{-------------------------------------------------------------------------------  Binary instances--  We only have Binary instances for those types that are shared between-  the public and private types, and for the "small" types that are the result of-  IDE session queries. We don't want Binary instances for entire LoadedModules-  maps and other "large" types.-------------------------------------------------------------------------------}--instance Binary IdNameSpace where-  put VarName   = putWord8 0-  put DataName  = putWord8 1-  put TvName    = putWord8 2-  put TcClsName = putWord8 3--  get = do-    header <- getWord8-    case header of-      0 -> return VarName-      1 -> return DataName-      2 -> return TvName-      3 -> return TcClsName-      _ -> fail "IdNameSpace.get: invalid header"--instance Binary SourceErrorKind where-  put KindError      = putWord8 0-  put KindWarning    = putWord8 1-  put KindServerDied = putWord8 2--  get = do-    header <- getWord8-    case header of-      0 -> return KindError-      1 -> return KindWarning-      2 -> return KindServerDied-      _ -> fail "SourceErrorKind.get: invalid header"--instance Binary ImportEntities where-  put (ImportOnly names)   = putWord8 0 >> put names-  put (ImportHiding names) = putWord8 1 >> put names-  put ImportAll            = putWord8 2--  get = do-    header <- getWord8-    case header of-      0 -> ImportOnly   <$> get-      1 -> ImportHiding <$> get-      2 -> return ImportAll-      _ -> fail "ImportEntities.get: invalid header"--instance Binary Import where-  put Import{..} = do-    put importModule-    put importPackage-    put importQualified-    put importImplicit-    put importAs-    put importEntities--  get = Import <$> get <*> get <*> get <*> get <*> get <*> get--instance Binary SourceError where-  put SourceError{..} = do-    put errorKind-    put errorSpan-    put errorMsg--  get = SourceError <$> get <*> get <*> get--instance Binary IdProp where-  put IdProp{..} = do-    put idName-    put idSpace-    put idType-    put idDefinedIn-    put idDefSpan-    put idHomeModule--  get = IdProp <$> get <*> get <*> get <*> get <*> get <*> get--instance Binary IdScope where-  put Binder       = putWord8 0-  put Local        = putWord8 1-  put Imported{..} = do putWord8 2-                        put idImportedFrom-                        put idImportSpan-                        put idImportQual-  put WiredIn      = putWord8 3--  get = do-    header <- getWord8-    case header of-      0 -> return Binder-      1 -> return Local-      2 -> Imported <$> get <*> get <*> get-      3 -> return WiredIn-      _ -> fail "IdScope.get: invalid header"--instance Binary SourceSpan where-  put (SourceSpan{..}) = do-    put spanFilePath-    put spanFromLine-    put spanFromColumn-    put spanToLine-    put spanToColumn--  get = SourceSpan <$> get <*> get <*> get <*> get <*> get--instance Binary EitherSpan where-  put (ProperSpan span) = putWord8 0 >> put span-  put (TextSpan text)   = putWord8 1 >> put text--  get = do-    header <- getWord8-    case header of-      0 -> ProperSpan <$> get-      1 -> TextSpan <$> get-      _ -> fail "EitherSpan.get: invalid header"--instance Binary ModuleId where-  put ModuleId{..} = put moduleName >> put modulePackage-  get = ModuleId <$> get <*> get--instance Binary PackageId where-  put PackageId{..} = do-    put packageName-    put packageVersion-    put packageKey-  get = PackageId <$> get <*> get <*> get--instance Binary IdInfo where-  put IdInfo{..} = put idProp >> put idScope-  get = IdInfo <$> get <*> get--instance Binary RunBufferMode where-  put RunNoBuffering        = putWord8 0-  put RunLineBuffering{..}  = do putWord8 1-                                 put runBufferTimeout-  put RunBlockBuffering{..} = do putWord8 2-                                 put runBufferBlockSize-                                 put runBufferTimeout--  get = do-    header <- getWord8-    case header of-      0 -> return RunNoBuffering-      1 -> RunLineBuffering <$> get-      2 -> RunBlockBuffering <$> get <*> get-      _ -> fail "RunBufferMode.get: invalid header"--instance Binary Targets where-  put (TargetsInclude l) = do-    putWord8 0-    put l-  put (TargetsExclude l) = do-    putWord8 1-    put l--  get = do-    header <- getWord8-    case header of-      0 -> TargetsInclude <$> get-      1 -> TargetsExclude <$> get-      _ -> fail "Targets.get: invalid header"--{-------------------------------------------------------------------------------  JSON instances--  We provide these for the convenience of client code only; we don't use them-  internally.-------------------------------------------------------------------------------}--$(deriveJSON defaultOptions ''IdNameSpace)-$(deriveJSON defaultOptions ''SourceErrorKind)-$(deriveJSON defaultOptions ''ImportEntities)-$(deriveJSON defaultOptions ''Import)-$(deriveJSON defaultOptions ''SourceError)-$(deriveJSON defaultOptions ''IdProp)-$(deriveJSON defaultOptions ''IdScope)-$(deriveJSON defaultOptions ''SourceSpan)-$(deriveJSON defaultOptions ''EitherSpan)-$(deriveJSON defaultOptions ''ModuleId)-$(deriveJSON defaultOptions ''PackageId)-$(deriveJSON defaultOptions ''IdInfo)-$(deriveJSON defaultOptions ''SpanInfo)-$(deriveJSON defaultOptions ''BreakInfo)-$(deriveJSON defaultOptions ''RunResult)-$(deriveJSON defaultOptions ''RunBufferMode)--{-------------------------------------------------------------------------------  PrettyVal instances (these rely on Generics)-------------------------------------------------------------------------------}--instance PrettyVal IdNameSpace-instance PrettyVal IdInfo-instance PrettyVal IdProp-instance PrettyVal IdScope-instance PrettyVal SourceSpan-instance PrettyVal EitherSpan-instance PrettyVal SourceError-instance PrettyVal SourceErrorKind-instance PrettyVal ModuleId-instance PrettyVal PackageId-instance PrettyVal ImportEntities-instance PrettyVal Import-instance PrettyVal SpanInfo-instance PrettyVal RunBufferMode-instance PrettyVal RunResult-instance PrettyVal BreakInfo-instance PrettyVal Targets--{-------------------------------------------------------------------------------  Util-------------------------------------------------------------------------------}---- | Construct qualified name following Haskell's scoping rules-idInfoQN :: IdInfo -> String-idInfoQN IdInfo{idProp = IdProp{idName}, idScope} =-  case idScope of-    Binder                 -> Text.unpack idName-    Local{}                -> Text.unpack idName-    Imported{idImportQual} -> Text.unpack idImportQual ++ Text.unpack idName-    WiredIn                -> Text.unpack idName---- | Show approximately what Haddock adds to documentation URLs.-haddockSpaceMarks :: IdNameSpace -> String-haddockSpaceMarks VarName   = "v"-haddockSpaceMarks DataName  = "v"-haddockSpaceMarks TvName    = "t"-haddockSpaceMarks TcClsName = "t"---- | Show approximately a haddock link (without haddock root) for an id.--- This is an illustration and a test of the id info, but under ideal--- conditions could perhaps serve to link to documentation without--- going via Hoogle.-haddockLink :: IdProp -> IdScope -> String-haddockLink IdProp{..} idScope =-  case idScope of-    Imported{idImportedFrom} ->-         dashToSlash (modulePackage idImportedFrom)-      ++ "/doc/html/"-      ++ dotToDash (Text.unpack $ moduleName idImportedFrom) ++ ".html#"-      ++ haddockSpaceMarks idSpace ++ ":"-      ++ Text.unpack idName-    _ -> "<local identifier>"- where-   dotToDash = map (\c -> if c == '.' then '-' else c)-   dashToSlash p = case packageVersion p of-     Nothing      -> Text.unpack (packageName p) ++ "/latest"-     Just version -> Text.unpack (packageName p) ++ "/" ++ Text.unpack version--{--idInfoAtLocation :: Int -> Int -> IdMap -> [(SourceSpan, IdInfo)]-idInfoAtLocation line col = filter inRange . idMapToList-  where-    inRange :: (SourceSpan, a) -> Bool-    inRange (SourceSpan{..}, _) =-      (line   > spanFromLine || (line == spanFromLine && col >= spanFromColumn)) &&-      (line   < spanToLine   || (line == spanToLine   && col <= spanToColumn))--}
− IdeSession/Types/Translation.hs
@@ -1,255 +0,0 @@-{-# LANGUAGE TypeFamilies, ScopedTypeVariables, TypeSynonymInstances, FlexibleInstances, FlexibleContexts #-}--- | Translation from the private to the public types-module IdeSession.Types.Translation (-    XShared-  , ExplicitSharing(..)-  , IntroduceSharing(..)-  , showNormalized-  , dereferenceFilePathPtr-  ) where--import Prelude hiding (mod, span)-import qualified Data.ByteString.Char8 as BSSC-import qualified Data.Text as Text-import Data.Binary (Binary)--import IdeSession.Strict.Container-import qualified IdeSession.Types.Public  as Public-import qualified IdeSession.Types.Private as Private-import qualified IdeSession.Strict.IntMap as StrictIntMap-import qualified IdeSession.Strict.Maybe  as StrictMaybe---- | The associated type with explicit sharing-type family XShared a---- | The inverse of MShared, only for decidability of type checking-type family MShared a--type instance XShared Public.IdProp          = Private.IdProp-type instance XShared Public.IdInfo          = Private.IdInfo-type instance XShared Public.IdScope         = Private.IdScope-type instance XShared Public.SourceSpan      = Private.SourceSpan-type instance XShared Public.EitherSpan      = Private.EitherSpan-type instance XShared Public.SourceError     = Private.SourceError--- type instance XShared Public.IdMap           = Private.IdMap--- type instance XShared Public.LoadedModules   = Private.LoadedModules-type instance XShared Public.ModuleId        = Private.ModuleId-type instance XShared Public.PackageId       = Private.PackageId-type instance XShared Public.ImportEntities  = Private.ImportEntities-type instance XShared Public.Import          = Private.Import-type instance XShared Public.SpanInfo        = Private.SpanInfo-type instance XShared Public.RunResult       = Private.RunResult-type instance XShared Public.BreakInfo       = Private.BreakInfo--type instance MShared Private.IdProp         = Public.IdProp-type instance MShared Private.IdInfo         = Public.IdInfo-type instance MShared Private.IdScope        = Public.IdScope-type instance MShared Private.SourceSpan     = Public.SourceSpan-type instance MShared Private.EitherSpan     = Public.EitherSpan-type instance MShared Private.SourceError    = Public.SourceError--- type instance MShared Private.IdMap          = Public.IdMap--- type instance MShared Private.LoadedModules  = Public.LoadedModules-type instance MShared Private.ModuleId       = Public.ModuleId-type instance MShared Private.PackageId      = Public.PackageId-type instance MShared Private.ImportEntities = Public.ImportEntities-type instance MShared Private.Import         = Public.Import-type instance MShared Private.SpanInfo       = Public.SpanInfo-type instance MShared Private.RunResult      = Public.RunResult-type instance MShared Private.BreakInfo      = Public.BreakInfo--{-------------------------------------------------------------------------------  Removing explicit sharing-------------------------------------------------------------------------------}---- | Many of the public data types that we export in "IdeSession" have a--- corresponding private @XShared@ version. For instance, we have @IdProp@ and--- @XShared IdProp@, @SourceError@ and @XShared SourceError@, etc. These--- @XShared@ types are abstract; what's important is only that they can be--- serialized (support @FromJSON@ and @ToJSON@). The main difference between--- the public and the private data types is that the private data types use--- explicit sharing. This is important for serialization, because there is--- quite a bit of sharing in the type information that we collect and losing--- this would be a significant performance hit. (The other difference is that--- the private data types use specialized types that guarantee strictness.)------ The @MShared (XShared a) ~ a@ condition on the @ExplicitSharing@ type class--- is there for technical reasons only (it convinces GHC that the @XShared@--- type family is a bijection).-class (MShared (XShared a) ~ a, Binary (XShared a)) => ExplicitSharing a where-  removeExplicitSharing :: Private.ExplicitSharingCache -> XShared a -> a--showNormalized :: forall a. (Show a, ExplicitSharing a)-               => Private.ExplicitSharingCache -> XShared a -> String-showNormalized cache x = show (removeExplicitSharing cache x :: a)--instance ExplicitSharing Public.IdProp where-  removeExplicitSharing cache Private.IdProp{..} = Public.IdProp {-      Public.idName       = idName-    , Public.idSpace      = idSpace-    , Public.idType       = toLazyMaybe idType-    , Public.idDefSpan    = removeExplicitSharing cache idDefSpan-    , Public.idDefinedIn  = removeExplicitSharing cache idDefinedIn-    , Public.idHomeModule = StrictMaybe.maybe-                              Nothing-                              (Just . removeExplicitSharing cache)-                              idHomeModule-    }--instance ExplicitSharing Public.IdInfo where-  removeExplicitSharing cache Private.IdInfo{..} = Public.IdInfo {-      Public.idProp  = case StrictIntMap.lookup (Private.idPropPtr idProp)-                                                (Private.idPropCache cache)-                         of Just idProp' -> removeExplicitSharing cache idProp'-                            Nothing      -> unknownProp-    , Public.idScope = removeExplicitSharing cache idScope-    }-    where-      unknownProp = Public.IdProp {-          idName        = Text.pack "<<unknown id>>"-        , idSpace       = Public.VarName-        , idType        = Nothing-        , idDefinedIn   = unknownModule-        , idDefSpan     = Public.TextSpan (Text.pack "<<unknown span>>")-        , idHomeModule  = Nothing-        }--      unknownModule = Public.ModuleId {-          moduleName    = Text.pack "<<unknown module>>"-        , modulePackage = unknownPackage-        }--      unknownPackage = Public.PackageId {-         packageName    = Text.pack "<<unknown package>>"-       , packageVersion = Nothing-       , packageKey     = Text.pack "<<unknown package>>"-       }--instance ExplicitSharing Public.ModuleId where-  removeExplicitSharing cache Private.ModuleId{..} = Public.ModuleId {-      Public.moduleName    = moduleName-    , Public.modulePackage = removeExplicitSharing cache modulePackage-    }--instance ExplicitSharing Public.PackageId where-  removeExplicitSharing _cache Private.PackageId{..} = Public.PackageId {-      Public.packageName    = packageName-    , Public.packageVersion = toLazyMaybe packageVersion-    , Public.packageKey     = packageKey-    }--instance ExplicitSharing Public.IdScope where-  removeExplicitSharing cache idScope = case idScope of-    Private.Binder -> Public.Binder-    Private.Local  -> Public.Local-    Private.Imported {..} -> Public.Imported {-        Public.idImportedFrom = removeExplicitSharing cache idImportedFrom-      , Public.idImportSpan   = removeExplicitSharing cache idImportSpan-      , Public.idImportQual   = idImportQual-      }-    Private.WiredIn -> Public.WiredIn--instance ExplicitSharing Public.SourceSpan where-  removeExplicitSharing cache Private.SourceSpan{..} = Public.SourceSpan {-      Public.spanFilePath   = dereferenceFilePathPtr cache spanFilePath-    , Public.spanFromLine   = spanFromLine-    , Public.spanFromColumn = spanFromColumn-    , Public.spanToLine     = spanToLine-    , Public.spanToColumn   = spanToColumn-    }--instance ExplicitSharing Public.EitherSpan where-  removeExplicitSharing cache eitherSpan = case eitherSpan of-    Private.ProperSpan sourceSpan ->-      Public.ProperSpan (removeExplicitSharing cache sourceSpan)-    Private.TextSpan str ->-      Public.TextSpan str--instance ExplicitSharing Public.SourceError where-  removeExplicitSharing cache Private.SourceError{..} = Public.SourceError {-      Public.errorKind = errorKind-    , Public.errorSpan = removeExplicitSharing cache errorSpan-    , Public.errorMsg  = errorMsg-    }--{--instance ExplicitSharing Public.IdMap where-  removeExplicitSharing cache = Public.IdMap-                              . toLazyMap-                              . StrictMap.map (removeExplicitSharing cache)-                              . StrictMap.mapKeys (removeExplicitSharing cache)-                              . Private.idMapToMap--}--{--instance ExplicitSharing Public.LoadedModules where-  removeExplicitSharing cache = Map.map (removeExplicitSharing cache)-                              . toLazyMap--}--instance ExplicitSharing Public.ImportEntities where-  removeExplicitSharing _cache entities = case entities of-    Private.ImportAll          -> Public.ImportAll-    Private.ImportHiding names -> Public.ImportHiding (toLazyList names)-    Private.ImportOnly   names -> Public.ImportOnly (toLazyList names)--instance ExplicitSharing Public.Import where-  removeExplicitSharing cache Private.Import{..} = Public.Import {-      Public.importModule     = removeExplicitSharing cache $ importModule-    , Public.importPackage    = toLazyMaybe importPackage-    , Public.importQualified  = importQualified-    , Public.importImplicit   = importImplicit-    , Public.importAs         = toLazyMaybe importAs-    , Public.importEntities   = removeExplicitSharing cache $ importEntities-    }--instance ExplicitSharing Public.SpanInfo where-  removeExplicitSharing cache spanInfo = case spanInfo of-    Private.SpanId       idInfo -> Public.SpanId (removeExplicitSharing cache idInfo)-    Private.SpanQQ       idInfo -> Public.SpanQQ (removeExplicitSharing cache idInfo)-    Private.SpanInSplice idInfo -> Public.SpanId (removeExplicitSharing cache idInfo)--instance ExplicitSharing Public.BreakInfo where-  removeExplicitSharing cache Private.BreakInfo{..} = Public.BreakInfo {-      Public.breakInfoModule      = breakInfoModule-    , Public.breakInfoSpan        = removeExplicitSharing cache breakInfoSpan-    , Public.breakInfoResultType  = breakInfoResultType-    , Public.breakInfoVariableEnv = breakInfoVariableEnv-    }--{-------------------------------------------------------------------------------  Low-level API-------------------------------------------------------------------------------}--dereferenceFilePathPtr :: Private.ExplicitSharingCache-                       -> Private.FilePathPtr -> FilePath-dereferenceFilePathPtr cache ptr = BSSC.unpack $-    StrictIntMap.findWithDefault-      unknownFilePath-      (Private.filePathPtr ptr)-      (Private.filePathCache cache)-  where-    unknownFilePath = BSSC.pack "<<unknown filepath>>"--{-------------------------------------------------------------------------------  Introducing explicit sharing-------------------------------------------------------------------------------}---- | Introduce explicit sharing------ This provides the opposite translation to removeExplicitSharing. Note however--- that this is a partial function -- we never extend the cache, so if a--- required value is missing from the cache we return @Nothing@.-class IntroduceSharing a where-  introduceExplicitSharing :: Private.ExplicitSharingCache -> a -> Maybe (XShared a)--instance IntroduceSharing Public.SourceSpan where-  introduceExplicitSharing cache Public.SourceSpan{..} = do-    ptr <- StrictIntMap.reverseLookup (Private.filePathCache cache)-                                      (BSSC.pack spanFilePath)-    return Private.SourceSpan {-        Private.spanFilePath   = Private.FilePathPtr ptr-      , Private.spanFromLine   = spanFromLine-      , Private.spanFromColumn = spanFromColumn-      , Private.spanToLine     = spanToLine-      , Private.spanToColumn   = spanToColumn-      }
− IdeSession/Util.hs
@@ -1,325 +0,0 @@-{-# LANGUAGE TemplateHaskell, ScopedTypeVariables, DeriveFunctor, DeriveGeneric, StandaloneDeriving, GeneralizedNewtypeDeriving #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-module IdeSession.Util (-    -- * Misc util-    showExWithClass-  , accessorName-  , lookup'-  , envWithPathOverride-  , writeFileAtomic-  , setupEnv-  , relInclToOpts-  , parseProgressMessage-  , ignoreDoesNotExist-  , interruptible-    -- * Simple diffs-  , Diff(..)-  , applyMapDiff-    -- * Manipulating stdout and stderr-  , swizzleStdout-  , swizzleStderr-  , redirectStderr-  , captureOutput-  ) where--import Control.Applicative ((<$>))-import Control.Monad (void, forM_, mplus)-import Crypto.Classes (blockLength, initialCtx, updateCtx, finalize)-import Crypto.Types (BitLength)-import Data.Accessor (Accessor, accessor)-import Data.Binary (Binary(..))-import Data.Char (isSpace)-import Data.Digest.Pure.MD5 (MD5Digest, MD5Context)-import Data.List (intercalate)-import Data.Maybe (fromMaybe)-import Data.Tagged (Tagged, untag)-import Data.Text (Text)-import Data.Typeable (typeOf)-import Foreign.C.Types (CFile)-import Foreign.Ptr (Ptr, castPtr, nullPtr)-import GHC.Generics (Generic)-import GHC.IO (unsafeUnmask)-import System.Directory (createDirectoryIfMissing, removeFile, renameFile)-import System.Environment (getEnvironment)-import System.FilePath (splitFileName, (<.>), (</>))-import System.FilePath (splitSearchPath, searchPathSeparator)-import System.IO-import System.IO.Error (isDoesNotExistError)-import System.IO.Temp (withSystemTempFile)-import System.Posix (Fd)-import System.Posix.Env (setEnv, unsetEnv)-import System.Posix.IO-import System.Posix.Types (CPid(..))-import Text.Show.Pretty-import qualified Control.Exception            as Ex-import qualified Data.Attoparsec.Text         as Att-import qualified Data.Binary                  as Bin-import qualified Data.Binary.Builder.Internal as Bin (writeN)-import qualified Data.Binary.Get.Internal     as Bin (readNWith)-import qualified Data.Binary.Put              as Bin (putBuilder)-import qualified Data.ByteString              as BSS-import qualified Data.ByteString.Lazy         as BSL-import qualified Data.Text                    as Text-import qualified Data.Text.Foreign            as Text-import qualified System.Posix.Files           as Files--import IdeSession.Strict.Container-import qualified IdeSession.Strict.Map as StrictMap--foreign import ccall "fflush" fflush :: Ptr CFile -> IO ()--{-------------------------------------------------------------------------------  Util-------------------------------------------------------------------------------}---- | Show an exception together with its most precise type tag.-showExWithClass :: Ex.SomeException -> String-showExWithClass (Ex.SomeException ex) = show (typeOf ex) ++ ": " ++ show ex---- | Translate record field '_name' to the accessor 'name'-accessorName :: String -> Maybe String-accessorName ('_' : str) = Just str-accessorName _           = Nothing---- | Prelude.lookup as an accessor-lookup' :: Eq a => a -> Accessor [(a, b)] (Maybe b)-lookup' key =-    accessor (lookup key) $ \mVal list ->-      case mVal of-        Nothing  -> delete key list-        Just val -> override key val list-  where-    override :: Eq a => a -> b -> [(a, b)] -> [(a, b)]-    override a b [] = [(a, b)]-    override a b ((a', b') : xs)-      | a == a'   = (a, b) : xs-      | otherwise = (a', b') : override a b xs--    delete :: Eq a => a -> [(a, b)] -> [(a, b)]-    delete _ [] = []-    delete a ((a', b') : xs)-      | a == a'   = xs-      | otherwise = (a', b') : delete a xs--envWithPathOverride :: [FilePath] -> IO (Maybe [(String, String)])-envWithPathOverride []            = return Nothing-envWithPathOverride extraPathDirs = do-    env <- getEnvironment-    let path  = fromMaybe "" (lookup "PATH" env)-        path' = intercalate [searchPathSeparator]-                  (extraPathDirs ++ splitSearchPath path)-        env'  = ("PATH", path') : filter (\(var, _) -> var /= "PATH") env-    return (Just env')---- | Writes a file atomically.------ The file is either written successfully or an IO exception is raised and--- the original file is left unchanged.------ On windows it is not possible to delete a file that is open by a process.--- This case will give an IO exception but the atomic property is not affected.------ Returns the hash of the file; we are careful not to force the entire input--- bytestring into memory (we compute the hash as we write the file).-writeFileAtomic :: FilePath -> BSL.ByteString -> IO MD5Digest-writeFileAtomic targetPath content = do-  let (targetDir, targetFile) = splitFileName targetPath-  createDirectoryIfMissing True targetDir-  Ex.bracketOnError-    (openBinaryTempFile targetDir $ targetFile <.> "tmp")-    (\(tmpPath, handle) -> hClose handle >> removeFile tmpPath)-    (\(tmpPath, handle) -> do-        let bits :: Tagged MD5Digest BitLength ; bits = blockLength-        hash <- go handle initialCtx $ makeBlocks (untag bits `div` 8) content-        hClose handle-        renameFile tmpPath targetPath-        return hash)-  where-    go :: Handle -> MD5Context -> [BSS.ByteString] -> IO MD5Digest-    go _ _   []       = error "Bug in makeBlocks"-    go h ctx [bs]     = BSS.hPut h bs >> return (finalize ctx bs)-    go h ctx (bs:bss) = BSS.hPut h bs >> go h (updateCtx ctx bs) bss---- | @makeBlocks n@ splits a bytestring into blocks with a size that is a--- multiple of 'n', with one left-over smaller bytestring at the end.------ Based from the (unexported) 'makeBlocks' in the crypto-api package, but--- we are careful to be as lazy as possible (the first -- block can be returned--- before the entire input bytestring is forced)-makeBlocks :: Int -> BSL.ByteString -> [BSS.ByteString]-makeBlocks n = go . BSL.toChunks-  where-    go [] = [BSS.empty]-    go (bs:bss)-      | BSS.length bs >= n =-          let l = BSS.length bs - (BSS.length bs `rem` n)-              (bsInit, bsTail) = BSS.splitAt l bs-          in bsInit : go (bsTail : bss)-      | otherwise =-          case bss of-            []         -> [bs]-            (bs':bss') -> go (BSS.append bs bs' : bss')---- | First restore the environment to the specified initial environment, then--- apply the given overrides-setupEnv :: [(String, String)] -> [(String, Maybe String)] -> IO ()-setupEnv initEnv overrides = do-  -- Delete everything in the current environment-  curEnv <- getEnvironment-  forM_ curEnv $ \(var, _val) -> unsetEnv var--  -- Restore initial environment-  forM_ initEnv $ \(var, val) -> setEnv var val True--  -- Apply overrides-  forM_ overrides $ \(var, mVal) ->-    case mVal of-      Just val -> setEnv var val True-      Nothing  -> unsetEnv var--relInclToOpts :: FilePath -> [FilePath] -> [String]-relInclToOpts sourcesDir relIncl =-   ["-i"]  -- reset to empty-   ++ map (\path -> "-i" ++ sourcesDir </> path) relIncl--parseProgressMessage :: Text -> Either String (Int, Int, Text)-parseProgressMessage = Att.parseOnly parser-  where-    parser :: Att.Parser (Int, Int, Text)-    parser = do-      _    <- Att.char '['                ; Att.skipSpace-      step <- Att.decimal                 ; Att.skipSpace-      _    <- Att.string (Text.pack "of") ; Att.skipSpace-      numS <- Att.decimal                 ; Att.skipSpace-      _    <- Att.char ']'                ; Att.skipSpace-      rest <- parseCompiling `mplus` Att.takeText-      return (step, numS, rest)--    parseCompiling :: Att.Parser Text-    parseCompiling = do-      compiling <- Att.string (Text.pack "Compiling") ; Att.skipSpace-      _         <- parseTH                            ; Att.skipSpace-      modName   <- Att.takeTill isSpace-      return $ Text.concat [compiling, Text.pack " ", modName]--    parseTH :: Att.Parser ()-    parseTH = Att.option () $ void $ Att.string (Text.pack "[TH]")---- | Ignore "does not exist" exception-ignoreDoesNotExist :: IO () -> IO ()-ignoreDoesNotExist = Ex.handle $ \e ->-  if isDoesNotExistError e then return ()-                           else Ex.throwIO e---- | Define interruptiple operations------ (TODO: Stick in reference to blog post)-interruptible :: IO a -> IO a-interruptible act = do-  st <- Ex.getMaskingState-  case st of-    Ex.Unmasked              -> act-    Ex.MaskedInterruptible   -> unsafeUnmask act-    Ex.MaskedUninterruptible -> act--{-------------------------------------------------------------------------------  Simple diffs-------------------------------------------------------------------------------}--data Diff a = Keep | Remove | Insert a-  deriving (Show, Functor, Generic)--instance Binary a => Binary (Diff a) where-  put Keep       = Bin.putWord8 0-  put Remove     = Bin.putWord8 1-  put (Insert a) = Bin.putWord8 2 >> Bin.put a--  get = do-    header <- Bin.getWord8-    case header of-      0 -> return Keep-      1 -> return Remove-      2 -> Insert <$> Bin.get-      _ -> fail "Diff.get: invalid header"--instance PrettyVal a => PrettyVal (Diff a) -- relies on Generics--applyMapDiff :: forall k v. Ord k-             => Strict (Map k) (Diff v)-             -> Strict (Map k) v -> Strict (Map k) v-applyMapDiff diff = foldr (.) id (map aux $ StrictMap.toList diff)-  where-    aux :: (k, Diff v) -> Strict (Map k) v -> Strict (Map k) v-    aux (_, Keep)     = id-    aux (k, Remove)   = StrictMap.delete k-    aux (k, Insert x) = StrictMap.insert k x--{--------------------------------------------------------------------------------  Manipulations with stdout and stderr.--------------------------------------------------------------------------------}--swizzleStdout :: Fd -> IO a -> IO a-swizzleStdout = swizzleHandle (stdout, stdOutput)--swizzleStderr :: Fd -> IO a -> IO a-swizzleStderr = swizzleHandle (stderr, stdError)--swizzleHandle :: (Handle, Fd) -> Fd -> IO a -> IO a-swizzleHandle (targetHandle, targetFd) fd act =-    Ex.bracket swizzle unswizzle (\_ -> act)-  where-    swizzle :: IO Fd-    swizzle = do-      -- Flush existing handles-      hFlush targetHandle-      fflush nullPtr--      -- Backup stdout, then replace stdout with the given fd-      backup <- dup targetFd-      _ <- dupTo fd targetFd--      return backup--    unswizzle :: Fd -> IO ()-    unswizzle backup = do-      -- Flush handles again-      hFlush targetHandle-      fflush nullPtr--      -- Restore stdout-      _ <- dupTo backup targetFd-      closeFd backup--redirectStderr :: FilePath -> IO a -> IO a-redirectStderr fp act = do-  Ex.bracket (openFd fp WriteOnly (Just mode) defaultFileFlags)-             closeFd $ \errorLogFd ->-    swizzleStderr errorLogFd $-      act-  where-    mode = Files.unionFileModes Files.ownerReadMode Files.ownerWriteMode--captureOutput :: IO a -> IO (String, a)-captureOutput act = do-  withSystemTempFile "suppressed" $ \fp handle -> do-    fd <- handleToFd handle-    a  <- swizzleStdout fd . swizzleStderr fd $ act-    closeFd fd-    suppressed <- readFile fp-    return (suppressed, a)--{--------------------------------------------------------------------------------  Orphans--------------------------------------------------------------------------------}--instance Binary Text where-  get   = do units <- Bin.get-             Bin.readNWith (units * 2) $ \ptr ->-               Text.fromPtr (castPtr ptr) (fromIntegral units)--  put t = do put (Text.lengthWord16 t)-             Bin.putBuilder $-               Bin.writeN (Text.lengthWord16 t * 2)-                          (\p -> Text.unsafeCopyToPtr t (castPtr p))--deriving instance Binary CPid
− IdeSession/Util/BlockingOps.hs
@@ -1,253 +0,0 @@-{-# LANGUAGE CPP, TemplateHaskell, NamedFieldPuns #-}--- | Blocking operations such as------ > readMVar v------ may throw an exception such as------ > thread blocked indefinitely in an MVar operation------ Unfortunately, this exception does not give any information of _where_ in--- the code we are blocked indefinitely. Compiling with profiling info and--- running with +RTC -xc can address this to some extent, but (1) it requires--- that all profiling libraries are installed and (2) when we are running--- multithreaded code the resulting stack trace is often difficult to read--- (and still does not include line numbers). With this module you can replace--- the above code with------ > $readMVar v------ and the exception that will be thrown is------ > YourModule:lineNumber: thread blocked indefinitely in an MVar operation------ which is a lot more informative. When the CPP flag DEBUGGING is turned off--- then @$readMVar@ just turns into @readMVar@.------ NOTE: The type of the exception changes when using DEBUGGING mode -- in order--- to be able to add the line number, all exceptions are turned into--- IOExceptions.-module IdeSession.Util.BlockingOps (-    -- * Generic debugging utilities-    lineNumber-  , traceOnException-  , mapExceptionIO-  , mapExceptionShow-    -- * Blocking MVar ops-  , putMVar-  , takeMVar-  , modifyMVar-  , modifyMVar_-  , withMVar-  , readMVar-  , swapMVar-    -- * Same for strict MVars-  , putStrictMVar-  , takeStrictMVar-  , modifyStrictMVar-  , modifyStrictMVar_-  , withStrictMVar-  , readStrictMVar-  , swapStrictMVar-    -- * Blocking Chan ops-  , readChan-    -- * Blocking Async ops-  , wait-  , waitCatch-  , waitAny-  , waitAnyCatchCancel-  ) where--import Language.Haskell.TH-import qualified Control.Concurrent as C-import qualified Control.Concurrent.Async as Async-import System.IO (hPutStrLn, stderr)-import qualified Control.Exception as Ex--import qualified IdeSession.Strict.MVar as StrictMVar--lineNumber :: ExpQ-lineNumber = do-  Loc{loc_module, loc_start=(line, _)} <- location-  [| loc_module ++ ":" ++ show (line :: Int) |]--mapExceptionIO :: (Ex.Exception e1, Ex.Exception e2)-               => (e1 -> e2) -> IO a -> IO a-mapExceptionIO f io = Ex.catch io (Ex.throwIO . f)--mapExceptionShow :: (String -> String) -> IO a -> IO a-mapExceptionShow f = mapExceptionIO (userError . f . showSomeException)-  where-    showSomeException :: Ex.SomeException -> String-    showSomeException = show--traceOnException :: String -> IO a -> IO a-traceOnException str io = Ex.catch io $ \e -> do-  hPutStrLn stderr (str ++ ": " ++ show e)-  Ex.throwIO (e :: Ex.SomeException)--#define DEBUGGING 0--#if DEBUGGING == 1--rethrowWithLineNumber1 :: ExpQ -> ExpQ-rethrowWithLineNumber1 expr =-  [| \arg1 -> mapExceptionShow (\e -> $lineNumber ++ ": " ++ e)-                               ($expr arg1)-   |]--rethrowWithLineNumber2 :: ExpQ -> ExpQ-rethrowWithLineNumber2 expr =-  [| \arg1 arg2 -> mapExceptionShow (\e -> $lineNumber ++ ": " ++ e)-                                    ($expr arg1 arg2)-   |]--{--------------------------------------------------------------------------------  MVar--------------------------------------------------------------------------------}--takeMVar :: ExpQ-takeMVar = rethrowWithLineNumber1 [| C.takeMVar |]--putMVar :: ExpQ-putMVar = rethrowWithLineNumber2 [| C.putMVar |]--readMVar :: ExpQ-readMVar = rethrowWithLineNumber1 [| C.readMVar |]--modifyMVar :: ExpQ-modifyMVar = rethrowWithLineNumber2 [| C.modifyMVar |]--modifyMVar_ :: ExpQ-modifyMVar_ = rethrowWithLineNumber2 [| C.modifyMVar_ |]--withMVar :: ExpQ-withMVar = rethrowWithLineNumber2 [| C.withMVar |]--swapMVar :: ExpQ-swapMVar = rethrowWithLineNumber2 [| C.swapMVar |]--{--------------------------------------------------------------------------------  StrictMVar--------------------------------------------------------------------------------}--takeStrictMVar :: ExpQ-takeStrictMVar = rethrowWithLineNumber1 [| StrictMVar.takeMVar |]--putStrictMVar :: ExpQ-putStrictMVar = rethrowWithLineNumber2 [| StrictMVar.putMVar |]--readStrictMVar :: ExpQ-readStrictMVar = rethrowWithLineNumber1 [| StrictMVar.readMVar |]--modifyStrictMVar :: ExpQ-modifyStrictMVar = rethrowWithLineNumber2 [| StrictMVar.modifyMVar |]--modifyStrictMVar_ :: ExpQ-modifyStrictMVar_ = rethrowWithLineNumber2 [| StrictMVar.modifyMVar_ |]--withStrictMVar :: ExpQ-withStrictMVar = rethrowWithLineNumber2 [| StrictMVar.withMVar |]--swapStrictMVar :: ExpQ-swapStrictMVar = rethrowWithLineNumber2 [| StrictMVar.swapMVar |]--{--------------------------------------------------------------------------------  Chan--------------------------------------------------------------------------------}--readChan :: ExpQ-readChan = rethrowWithLineNumber1 [| C.readChan |]--{--------------------------------------------------------------------------------  Async--------------------------------------------------------------------------------}--wait :: ExpQ-wait = rethrowWithLineNumber1 [| Async.wait |]--waitCatch :: ExpQ-waitCatch = rethrowWithLineNumber1 [| Async.waitCatch |]--waitAny :: ExpQ-waitAny = rethrowWithLineNumber1 [| Async.waitAny |]--waitAnyCatchCancel :: ExpQ-waitAnyCatchCancel = rethrowWithLineNumber1 [| Async.waitAnyCatchCancel |]--#else--{--------------------------------------------------------------------------------  MVar--------------------------------------------------------------------------------}--takeMVar :: ExpQ-takeMVar = [| C.takeMVar |]--putMVar :: ExpQ-putMVar = [| C.putMVar |]--readMVar :: ExpQ-readMVar = [| C.readMVar |]--modifyMVar :: ExpQ-modifyMVar = [| C.modifyMVar |]--modifyMVar_ :: ExpQ-modifyMVar_ = [| C.modifyMVar_ |]--withMVar :: ExpQ-withMVar = [| C.withMVar |]--swapMVar :: ExpQ-swapMVar = [| C.swapMVar |]--{--------------------------------------------------------------------------------  StrictMVar--------------------------------------------------------------------------------}--takeStrictMVar :: ExpQ-takeStrictMVar = [| StrictMVar.takeMVar |]--putStrictMVar :: ExpQ-putStrictMVar = [| StrictMVar.putMVar |]--readStrictMVar :: ExpQ-readStrictMVar = [| StrictMVar.readMVar |]--modifyStrictMVar :: ExpQ-modifyStrictMVar = [| StrictMVar.modifyMVar |]--modifyStrictMVar_ :: ExpQ-modifyStrictMVar_ = [| StrictMVar.modifyMVar_ |]--withStrictMVar :: ExpQ-withStrictMVar = [| StrictMVar.withMVar |]--swapStrictMVar :: ExpQ-swapStrictMVar = [| StrictMVar.swapMVar |]--{--------------------------------------------------------------------------------  Chan--------------------------------------------------------------------------------}--readChan :: ExpQ-readChan = [| C.readChan |]--{--------------------------------------------------------------------------------  Async--------------------------------------------------------------------------------}--wait :: ExpQ-wait = [| Async.wait |]--waitCatch :: ExpQ-waitCatch = [| Async.waitCatch |]--waitAny :: ExpQ-waitAny = [| Async.waitAny |]--waitAnyCatchCancel :: ExpQ-waitAnyCatchCancel = [| Async.waitAnyCatchCancel |]--#endif
− IdeSession/Util/PrettyVal.hs
@@ -1,42 +0,0 @@--- | (Orphan) PrettyVal instances for various standard datatypes-{-# OPTIONS_GHC -fno-warn-orphans #-}-module IdeSession.Util.PrettyVal (-    -- * Re-exports-    PrettyVal(..)-  ) where--import Text.Show.Pretty-import Data.IntMap (IntMap)-import Data.Map (Map)-import Data.Trie (Trie)-import Data.ByteString (ByteString)-import Data.Text (Text)-import qualified Data.IntMap           as IntMap-import qualified Data.Map              as Map-import qualified Data.Trie             as Trie-import qualified Data.ByteString.Char8 as BSC-import qualified Data.Text             as Text--instance PrettyVal a => PrettyVal (Maybe a) where-  prettyVal Nothing  = Con "Nothing" []-  prettyVal (Just x) = Con "Just"    [prettyVal x]---- TODO: This has encoding issues-instance PrettyVal ByteString where-  prettyVal = prettyVal . BSC.unpack--instance PrettyVal a => PrettyVal (IntMap a) where-  prettyVal m = Con "fromList" [prettyVal . IntMap.toList $ m]--instance (PrettyVal k, PrettyVal a) => PrettyVal (Map k a) where-  prettyVal m = Con "fromList" [prettyVal . Map.toList $ m]--instance PrettyVal a => PrettyVal (Trie a) where-  prettyVal m = Con "fromList" [prettyVal . Trie.toList $ m]--instance PrettyVal Bool where-  prettyVal True  = Con "True"  []-  prettyVal False = Con "False" []--instance PrettyVal Text where-  prettyVal = prettyVal . Text.unpack
ide-backend.cabal view
@@ -1,7 +1,7 @@ name:                 ide-backend-version:              0.9.0.1+version:              0.9.0.2 synopsis:             An IDE backend library--- description:+description:          See README.md for more details license:              MIT license-file:         LICENSE author:               Duncan Coutts, Mikolaj Konarski, Edsko de Vries@@ -24,30 +24,8 @@                       IdeSession.Update,                       IdeSession.Update.IdeSessionUpdate,                       IdeSession.Update.ExecuteSessionUpdate,-                      IdeSession.RPC.Client,-                      IdeSession.RPC.API,-                      IdeSession.RPC.Stream,-                      IdeSession.Types.Public,-                      IdeSession.Types.Private,-                      IdeSession.Types.Translation,-                      IdeSession.Types.Progress,-                      IdeSession.GHC.API,-                      IdeSession.GHC.Requests,-                      IdeSession.GHC.Responses,-                      IdeSession.GHC.Client,-                      IdeSession.Util,-                      IdeSession.Util.BlockingOps,-                      IdeSession.Util.PrettyVal,-                      IdeSession.Strict.Container,-                      IdeSession.Strict.IntMap,-                      IdeSession.Strict.List,-                      IdeSession.Strict.Map,-                      IdeSession.Strict.Maybe,-                      IdeSession.Strict.Trie,-                      IdeSession.Strict.IntervalMap-                      IdeSession.Strict.MVar-                      IdeSession.Strict.IORef-                      IdeSession.Strict.StateT+                      IdeSession.GHC.Client+                      IdeSession.RPC.Client    build-depends:      base                 ==4.*,                       filemanip            >= 0.3.6.2 && < 0.4,@@ -55,28 +33,21 @@                       filepath             >= 1.3     && < 1.5,                       directory            >= 1.1     && < 1.3,                       containers           >= 0.4.1   && < 1,-                      random               >= 1.0.1   && < 2,                       bytestring           >= 0.9.2   && < 1,                       mtl                  >= 2.1     && < 2.3,                       async                >= 2.0     && < 2.1,-                      aeson                >= 0.6.2   && < 0.9,-                      executable-path      >= 0.0     && < 0.1,                       unix                 >= 2.5     && < 2.8,                       temporary            >= 1.1.2.4 && < 1.3,-                      bytestring-trie      >= 0.2     && < 0.3,-                      unordered-containers >= 0.2.3   && < 0.3,                       text                 >= 0.11    && < 1.3,-                      fingertree           >= 0.0.1   && < 0.2,                       binary               >= 0.7.1.0 && < 0.8,                       data-accessor        >= 0.2     && < 0.3,                       data-accessor-mtl    >= 0.2     && < 0.3,-                      crypto-api           >= 0.12    && < 0.14,                       pureMD5              >= 2.1     && < 2.2,-                      tagged               >= 0.4     && < 0.8,                       transformers         >= 0.3     && < 0.5,                       time                 >= 1.4     && < 1.6,                       attoparsec           >= 0.10    && < 0.13,                       utf8-string          >= 0.3     && < 1.1,+                      ide-backend-common   >= 0.9     && < 0.10,                       template-haskell,                       -- our own private fork:                       Cabal-ide-backend    >= 1.23,@@ -100,9 +71,9 @@   ghc-options:        -Wall -fno-warn-unused-do-bind  executable ide-backend-exe-cabal-  hs-source-dirs:     .   main-is:            ide-backend-exe-cabal.hs   build-depends:      ide-backend,+                      ide-backend-common,                       base                 ==4.*,                       filemanip            >= 0.3.6.2 && < 0.4,                       process              >= 1.1     && < 1.3,@@ -147,7 +118,7 @@   type:               exitcode-stdio-1.0   main-is:            typecheck-dir.hs   hs-source-dirs:     test-  build-depends:      base, ide-backend, temporary, filemanip, directory, time, text+  build-depends:      base, ide-backend, ide-backend-common, temporary, filemanip, directory, time, text    default-language:   Haskell2010   default-extensions: MonoLocalBinds,@@ -198,6 +169,7 @@                       TestTools   build-depends:      base,                       ide-backend,+                      ide-backend-common,                       tasty,                       HUnit,                       tagged,@@ -231,7 +203,7 @@ test-suite rpc-server   type:               exitcode-stdio-1.0   main-is:            rpc-server.hs-  hs-source-dirs:     . server test+  hs-source-dirs:     . test   build-depends:      base                 ==4.*,                       directory            ==1.*,                       filemanip            >= 0.3.6.2 && < 0.4,@@ -249,6 +221,7 @@                       executable-path      >= 0.0     && < 0.1,                       unix                 >= 2.5     && < 2.8,                       binary               >= 0.7.1.0 && < 0.8,+                      ide-backend-common,                       template-haskell    default-language:   Haskell2010@@ -257,4 +230,3 @@   other-extensions:   CPP, TemplateHaskell, ScopedTypeVariables,                       DeriveDataTypeable   ghc-options:        -Wall -fno-warn-unused-do-bind-  other-modules:      IdeSession.RPC.Server