hsdev 0.3.0.0 → 0.3.0.1
raw patch · 23 files changed
+367/−223 lines, 23 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- HsDev.Display: instance HsDev.Display.Display HsDev.PackageDb.Types.PackageDb
- HsDev.Display: instance HsDev.Display.Display HsDev.PackageDb.Types.PackageDbStack
- HsDev.Display: instance HsDev.Display.Display HsDev.Project.Types.Project
- HsDev.Display: instance HsDev.Display.Display HsDev.Sandbox.Sandbox
- HsDev.Display: instance HsDev.Display.Display HsDev.Symbols.Location.ModuleLocation
- HsDev.Display: instance HsDev.Display.Display HsDev.Symbols.Types.ModuleTag
- HsDev.Display: instance Text.Format.Formattable HsDev.PackageDb.Types.PackageDb
- HsDev.Display: instance Text.Format.Formattable HsDev.PackageDb.Types.PackageDbStack
- HsDev.Display: instance Text.Format.Formattable HsDev.Project.Types.Project
- HsDev.Display: instance Text.Format.Formattable HsDev.Sandbox.Sandbox
- HsDev.Display: instance Text.Format.Formattable HsDev.Symbols.Location.ModuleLocation
- HsDev.Tools.Ghc.Check: recalcNotesTabs :: [Note OutputMessage] -> IO [Note OutputMessage]
- HsDev.Tools.Ghc.MGhc: instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance Control.Monad.IO.Class.MonadIO m => DynFlags.HasDynFlags (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance Data.Default.Class.Default (HsDev.Tools.Ghc.MGhc.SessionState s)
- HsDev.Tools.Ghc.MGhc: instance Exception.ExceptionMonad m => Exception.ExceptionMonad (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance Exception.ExceptionMonad m => GhcMonad.GhcMonad (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance GHC.Base.Functor m => GHC.Base.Functor (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (GHC.Base.Maybe GHC.IO.FilePath) (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (HsDev.Tools.Ghc.MGhc.SessionState s) (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance GHC.Base.Monad m => GHC.Base.Applicative (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance GHC.Base.Monad m => GHC.Base.Monad (HsDev.Tools.Ghc.MGhc.MGhcT s m)
- HsDev.Tools.Ghc.MGhc: instance System.Log.Simple.Monad.MonadLog m => System.Log.Simple.Monad.MonadLog (HsDev.Tools.Ghc.MGhc.MGhcT s m)
+ HsDev.PackageDb.Types: instance HsDev.Display.Display HsDev.PackageDb.Types.PackageDb
+ HsDev.PackageDb.Types: instance HsDev.Display.Display HsDev.PackageDb.Types.PackageDbStack
+ HsDev.PackageDb.Types: instance Text.Format.Formattable HsDev.PackageDb.Types.PackageDb
+ HsDev.PackageDb.Types: instance Text.Format.Formattable HsDev.PackageDb.Types.PackageDbStack
+ HsDev.Project.Types: instance HsDev.Display.Display HsDev.Project.Types.Project
+ HsDev.Project.Types: instance Text.Format.Formattable HsDev.Project.Types.Project
+ HsDev.Sandbox: instance HsDev.Display.Display HsDev.Sandbox.Sandbox
+ HsDev.Sandbox: instance Text.Format.Formattable HsDev.Sandbox.Sandbox
+ HsDev.Server.Types: postSessionUpdater :: SessionMonad m => ServerM IO a -> m (Async a)
+ HsDev.Symbols.Location: instance HsDev.Display.Display HsDev.Symbols.Location.ModuleLocation
+ HsDev.Symbols.Location: instance Text.Format.Formattable HsDev.Symbols.Location.ModuleLocation
+ HsDev.Symbols.Types: instance HsDev.Display.Display HsDev.Symbols.Types.ModuleTag
+ HsDev.Tools.Ghc.MGhc: Session :: s -> d -> Session s d
+ HsDev.Tools.Ghc.MGhc: [_sessionData] :: Session s d -> d
+ HsDev.Tools.Ghc.MGhc: [_sessionKey] :: Session s d -> s
+ HsDev.Tools.Ghc.MGhc: data Session s d
+ HsDev.Tools.Ghc.MGhc: getSessionData :: MonadIO m => MGhcT s d m (Maybe d)
+ HsDev.Tools.Ghc.MGhc: instance (GHC.Classes.Eq d, GHC.Classes.Eq s) => GHC.Classes.Eq (HsDev.Tools.Ghc.MGhc.Session s d)
+ HsDev.Tools.Ghc.MGhc: instance (GHC.Classes.Ord d, GHC.Classes.Ord s) => GHC.Classes.Ord (HsDev.Tools.Ghc.MGhc.Session s d)
+ HsDev.Tools.Ghc.MGhc: instance (GHC.Read.Read d, GHC.Read.Read s) => GHC.Read.Read (HsDev.Tools.Ghc.MGhc.Session s d)
+ HsDev.Tools.Ghc.MGhc: instance (GHC.Show.Show d, GHC.Show.Show s) => GHC.Show.Show (HsDev.Tools.Ghc.MGhc.Session s d)
+ HsDev.Tools.Ghc.MGhc: instance Control.Monad.Catch.MonadCatch m => Control.Monad.Catch.MonadCatch (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance Control.Monad.Catch.MonadMask m => Control.Monad.Catch.MonadMask (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance Control.Monad.Catch.MonadThrow m => Control.Monad.Catch.MonadThrow (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance Control.Monad.IO.Class.MonadIO m => DynFlags.HasDynFlags (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance Data.Default.Class.Default (HsDev.Tools.Ghc.MGhc.SessionState s d)
+ HsDev.Tools.Ghc.MGhc: instance Exception.ExceptionMonad m => Exception.ExceptionMonad (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance Exception.ExceptionMonad m => GhcMonad.GhcMonad (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance GHC.Base.Functor m => GHC.Base.Functor (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance GHC.Base.Monad m => Control.Monad.Reader.Class.MonadReader (GHC.Base.Maybe GHC.IO.FilePath) (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance GHC.Base.Monad m => Control.Monad.State.Class.MonadState (HsDev.Tools.Ghc.MGhc.SessionState s d) (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance GHC.Base.Monad m => GHC.Base.Applicative (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance GHC.Base.Monad m => GHC.Base.Monad (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: instance System.Log.Simple.Monad.MonadLog m => System.Log.Simple.Monad.MonadLog (HsDev.Tools.Ghc.MGhc.MGhcT s d m)
+ HsDev.Tools.Ghc.MGhc: sessionData :: Lens' (Session s d) d
+ HsDev.Tools.Ghc.MGhc: sessionKey :: Lens' (Session s d) s
+ HsDev.Tools.Ghc.MGhc: setSessionData :: MonadIO m => d -> MGhcT s d m ()
+ HsDev.Tools.Ghc.Worker: instance Text.Format.Formattable HsDev.Tools.Ghc.Worker.SessionType
+ HsDev.Tools.Tabs: recalcNotesTabs :: Map Path Text -> [Note a] -> IO [Note a]
- HsDev.Project.Types: entity :: forall a_a1hkw a_a1iMr. Lens (Extensions a_a1hkw) (Extensions a_a1iMr) a_a1hkw a_a1iMr
+ HsDev.Project.Types: entity :: forall a_a1j6X a_a1kyG. Lens (Extensions a_a1j6X) (Extensions a_a1kyG) a_a1j6X a_a1kyG
- HsDev.Project.Types: extensions :: forall a_a1hkw. Lens' (Extensions a_a1hkw) [Extension]
+ HsDev.Project.Types: extensions :: forall a_a1j6X. Lens' (Extensions a_a1j6X) [Extension]
- HsDev.Project.Types: ghcOptions :: forall a_a1hkw. Lens' (Extensions a_a1hkw) [Text]
+ HsDev.Project.Types: ghcOptions :: forall a_a1j6X. Lens' (Extensions a_a1j6X) [Text]
- HsDev.Sandbox: getModuleOpts :: [String] -> Module -> GhcM [String]
+ HsDev.Sandbox: getModuleOpts :: [String] -> Module -> GhcM (PackageDbStack, [String])
- HsDev.Sandbox: getProjectTargetOpts :: [String] -> Project -> Info -> GhcM [String]
+ HsDev.Sandbox: getProjectTargetOpts :: [String] -> Project -> Info -> GhcM (PackageDbStack, [String])
- HsDev.Server.Message: message :: forall a_a1IqJ a_a1Iw8. Lens (Message a_a1IqJ) (Message a_a1Iw8) a_a1IqJ a_a1Iw8
+ HsDev.Server.Message: message :: forall a_a1Ksl a_a1KxK. Lens (Message a_a1Ksl) (Message a_a1KxK) a_a1Ksl a_a1KxK
- HsDev.Server.Message: messageId :: forall a_a1IqJ. Lens' (Message a_a1IqJ) (Maybe String)
+ HsDev.Server.Message: messageId :: forall a_a1Ksl. Lens' (Message a_a1Ksl) (Maybe String)
- HsDev.Server.Types: FindUsages :: Text -> Command
+ HsDev.Server.Types: FindUsages :: Int -> Int -> Path -> Command
- HsDev.Symbols.Types: inspectedKey :: forall k_a22lU t_a22lV a_a22lW k_a24tX. Lens (Inspected k_a22lU t_a22lV a_a22lW) (Inspected k_a24tX t_a22lV a_a22lW) k_a22lU k_a24tX
+ HsDev.Symbols.Types: inspectedKey :: forall k_a2529 t_a252a a_a252b k_a279X. Lens (Inspected k_a2529 t_a252a a_a252b) (Inspected k_a279X t_a252a a_a252b) k_a2529 k_a279X
- HsDev.Symbols.Types: inspection :: forall k_a22lU t_a22lV a_a22lW. Lens' (Inspected k_a22lU t_a22lV a_a22lW) Inspection
+ HsDev.Symbols.Types: inspection :: forall k_a2529 t_a252a a_a252b. Lens' (Inspected k_a2529 t_a252a a_a252b) Inspection
- HsDev.Symbols.Types: inspectionResult :: forall k_a22lU t_a22lV a_a22lW a_a24tY. Lens (Inspected k_a22lU t_a22lV a_a22lW) (Inspected k_a22lU t_a22lV a_a24tY) (Either HsDevError a_a22lW) (Either HsDevError a_a24tY)
+ HsDev.Symbols.Types: inspectionResult :: forall k_a2529 t_a252a a_a252b a_a279Y. Lens (Inspected k_a2529 t_a252a a_a252b) (Inspected k_a2529 t_a252a a_a279Y) (Either HsDevError a_a252b) (Either HsDevError a_a279Y)
- HsDev.Symbols.Types: inspectionTags :: forall k_a22lU t_a22lV a_a22lW t_a24tZ. Lens (Inspected k_a22lU t_a22lV a_a22lW) (Inspected k_a22lU t_a24tZ a_a22lW) (Set t_a22lV) (Set t_a24tZ)
+ HsDev.Symbols.Types: inspectionTags :: forall k_a2529 t_a252a a_a252b t_a279Z. Lens (Inspected k_a2529 t_a252a a_a252b) (Inspected k_a2529 t_a279Z a_a252b) (Set t_a252a) (Set t_a279Z)
- HsDev.Tools.Ghc.MGhc: MGhcT :: GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s) m)) a -> MGhcT s m a
+ HsDev.Tools.Ghc.MGhc: MGhcT :: GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s d) m)) a -> MGhcT s d m a
- HsDev.Tools.Ghc.MGhc: SessionState :: Maybe s -> Map s HscEnv -> SessionState s
+ HsDev.Tools.Ghc.MGhc: SessionState :: Maybe (Session s d) -> Map s (HscEnv, d) -> SessionState s d
- HsDev.Tools.Ghc.MGhc: [_sessionActive] :: SessionState s -> Maybe s
+ HsDev.Tools.Ghc.MGhc: [_sessionActive] :: SessionState s d -> Maybe (Session s d)
- HsDev.Tools.Ghc.MGhc: [_sessionMap] :: SessionState s -> Map s HscEnv
+ HsDev.Tools.Ghc.MGhc: [_sessionMap] :: SessionState s d -> Map s (HscEnv, d)
- HsDev.Tools.Ghc.MGhc: [unMGhcT] :: MGhcT s m a -> GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s) m)) a
+ HsDev.Tools.Ghc.MGhc: [unMGhcT] :: MGhcT s d m a -> GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s d) m)) a
- HsDev.Tools.Ghc.MGhc: currentSession :: MonadIO m => MGhcT s m (Maybe s)
+ HsDev.Tools.Ghc.MGhc: currentSession :: MonadIO m => MGhcT s d m (Maybe (Session s d))
- HsDev.Tools.Ghc.MGhc: data SessionState s
+ HsDev.Tools.Ghc.MGhc: data SessionState s d
- HsDev.Tools.Ghc.MGhc: deleteSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m ()
+ HsDev.Tools.Ghc.MGhc: deleteSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m ()
- HsDev.Tools.Ghc.MGhc: findSession :: (MonadIO m, Ord s) => s -> MGhcT s m (Maybe s)
+ HsDev.Tools.Ghc.MGhc: findSession :: (MonadIO m, Ord s) => s -> MGhcT s d m (Maybe (Session s d))
- HsDev.Tools.Ghc.MGhc: findSessionBy :: MonadIO m => (s -> Bool) -> MGhcT s m [s]
+ HsDev.Tools.Ghc.MGhc: findSessionBy :: MonadIO m => (s -> Bool) -> MGhcT s d m [Session s d]
- HsDev.Tools.Ghc.MGhc: hasSession :: (MonadIO m, Ord s) => s -> MGhcT s m Bool
+ HsDev.Tools.Ghc.MGhc: hasSession :: (MonadIO m, Ord s) => s -> MGhcT s d m Bool
- HsDev.Tools.Ghc.MGhc: initSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s m ()
+ HsDev.Tools.Ghc.MGhc: initSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s d m ()
- HsDev.Tools.Ghc.MGhc: liftGhc :: MonadIO m => Ghc a -> MGhcT s m a
+ HsDev.Tools.Ghc.MGhc: liftGhc :: MonadIO m => Ghc a -> MGhcT s d m a
- HsDev.Tools.Ghc.MGhc: newSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m ()
+ HsDev.Tools.Ghc.MGhc: newSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m ()
- HsDev.Tools.Ghc.MGhc: newtype MGhcT s m a
+ HsDev.Tools.Ghc.MGhc: newtype MGhcT s d m a
- HsDev.Tools.Ghc.MGhc: restoreSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => MGhcT s m a -> MGhcT s m a
+ HsDev.Tools.Ghc.MGhc: restoreSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => MGhcT s d m a -> MGhcT s d m a
- HsDev.Tools.Ghc.MGhc: runMGhcT :: (MonadIO m, ExceptionMonad m, Ord s) => Maybe FilePath -> MGhcT s m a -> m a
+ HsDev.Tools.Ghc.MGhc: runMGhcT :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => Maybe FilePath -> MGhcT s d m a -> m a
- HsDev.Tools.Ghc.MGhc: saveSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s m (Maybe s)
+ HsDev.Tools.Ghc.MGhc: saveSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s d m (Maybe (Session s d))
- HsDev.Tools.Ghc.MGhc: sessionActive :: Lens' (SessionState s) (Maybe s)
+ HsDev.Tools.Ghc.MGhc: sessionActive :: Lens' (SessionState s d) (Maybe (Session s d))
- HsDev.Tools.Ghc.MGhc: sessionMap :: Lens' (SessionState s) (Map s HscEnv)
+ HsDev.Tools.Ghc.MGhc: sessionMap :: Lens' (SessionState s d) (Map s (HscEnv, d))
- HsDev.Tools.Ghc.MGhc: switchSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m Bool
+ HsDev.Tools.Ghc.MGhc: switchSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m Bool
- HsDev.Tools.Ghc.MGhc: switchSession_ :: (MonadIO m, ExceptionMonad m, Ord s) => s -> Maybe (MGhcT s m ()) -> MGhcT s m ()
+ HsDev.Tools.Ghc.MGhc: switchSession_ :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> Maybe (MGhcT s d m ()) -> MGhcT s d m ()
- HsDev.Tools.Ghc.MGhc: tempSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => s -> MGhcT s m a -> MGhcT s m a
+ HsDev.Tools.Ghc.MGhc: tempSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m a -> MGhcT s d m a
- HsDev.Tools.Ghc.MGhc: usingSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => s -> MGhcT s m a -> MGhcT s m a
+ HsDev.Tools.Ghc.MGhc: usingSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m a -> MGhcT s d m a
- HsDev.Tools.Ghc.Worker: MGhcT :: GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s) m)) a -> MGhcT s m a
+ HsDev.Tools.Ghc.Worker: MGhcT :: GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s d) m)) a -> MGhcT s d m a
- HsDev.Tools.Ghc.Worker: SessionConfig :: SessionType -> [String] -> SessionConfig
+ HsDev.Tools.Ghc.Worker: SessionConfig :: SessionType -> PackageDbStack -> SessionConfig
- HsDev.Tools.Ghc.Worker: [unMGhcT] :: MGhcT s m a -> GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s) m)) a
+ HsDev.Tools.Ghc.Worker: [unMGhcT] :: MGhcT s d m a -> GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s d) m)) a
- HsDev.Tools.Ghc.Worker: ghcSession :: [String] -> GhcM ()
+ HsDev.Tools.Ghc.Worker: ghcSession :: PackageDbStack -> [String] -> GhcM ()
- HsDev.Tools.Ghc.Worker: haddockSession :: [String] -> GhcM ()
+ HsDev.Tools.Ghc.Worker: haddockSession :: PackageDbStack -> [String] -> GhcM ()
- HsDev.Tools.Ghc.Worker: newtype MGhcT s m a
+ HsDev.Tools.Ghc.Worker: newtype MGhcT s d m a
- HsDev.Tools.Ghc.Worker: tmpSession :: [String] -> GhcM ()
+ HsDev.Tools.Ghc.Worker: tmpSession :: PackageDbStack -> [String] -> GhcM ()
- HsDev.Tools.Ghc.Worker: type GhcM a = MGhcT SessionConfig (LogT IO) a
+ HsDev.Tools.Ghc.Worker: type GhcM a = MGhcT SessionConfig (First DynFlags) (LogT IO) a
- HsDev.Tools.Ghc.Worker: type GhcWorker = Worker (MGhcT SessionConfig (LogT IO))
+ HsDev.Tools.Ghc.Worker: type GhcWorker = Worker (MGhcT SessionConfig (First DynFlags) (LogT IO))
- HsDev.Tools.Ghc.Worker: workerSession :: SessionType -> [String] -> GhcM ()
+ HsDev.Tools.Ghc.Worker: workerSession :: SessionType -> PackageDbStack -> [String] -> GhcM ()
- HsDev.Tools.HDocs: hdocs :: ModuleLocation -> [String] -> GhcM (Map String String)
+ HsDev.Tools.HDocs: hdocs :: PackageDbStack -> ModuleLocation -> [String] -> GhcM (Map String String)
- HsDev.Tools.HDocs: hdocsy :: [ModuleLocation] -> [String] -> GhcM [Map String String]
+ HsDev.Tools.HDocs: hdocsy :: PackageDbStack -> [ModuleLocation] -> [String] -> GhcM [Map String String]
- HsDev.Tools.Types: note :: forall a_a1Osq a_a1OEl. Lens (Note a_a1Osq) (Note a_a1OEl) a_a1Osq a_a1OEl
+ HsDev.Tools.Types: note :: forall a_a1Qu2 a_a1QFX. Lens (Note a_a1Qu2) (Note a_a1QFX) a_a1Qu2 a_a1QFX
- HsDev.Tools.Types: noteLevel :: forall a_a1Osq. Lens' (Note a_a1Osq) (Maybe Severity)
+ HsDev.Tools.Types: noteLevel :: forall a_a1Qu2. Lens' (Note a_a1Qu2) (Maybe Severity)
- HsDev.Tools.Types: noteRegion :: forall a_a1Osq. Lens' (Note a_a1Osq) Region
+ HsDev.Tools.Types: noteRegion :: forall a_a1Qu2. Lens' (Note a_a1Qu2) Region
- HsDev.Tools.Types: noteSource :: forall a_a1Osq. Lens' (Note a_a1Osq) ModuleLocation
+ HsDev.Tools.Types: noteSource :: forall a_a1Qu2. Lens' (Note a_a1Qu2) ModuleLocation
Files
- hsdev.cabal +2/−1
- src/HsDev/Client/Commands.hs +53/−19
- src/HsDev/Database/SQLite.hs +15/−7
- src/HsDev/Database/Update.hs +3/−4
- src/HsDev/Display.hs +0/−56
- src/HsDev/Inspect.hs +6/−1
- src/HsDev/PackageDb/Types.hs +19/−1
- src/HsDev/Project/Types.hs +14/−5
- src/HsDev/Sandbox.hs +17/−9
- src/HsDev/Scan.hs +2/−2
- src/HsDev/Scan/Browse.hs +4/−4
- src/HsDev/Server/Base.hs +11/−6
- src/HsDev/Server/Types.hs +15/−7
- src/HsDev/Stack.hs +1/−1
- src/HsDev/Symbols/Location.hs +13/−0
- src/HsDev/Symbols/Types.hs +7/−0
- src/HsDev/Tools/Ghc/Check.hs +8/−20
- src/HsDev/Tools/Ghc/MGhc.hs +72/−46
- src/HsDev/Tools/Ghc/Session.hs +2/−2
- src/HsDev/Tools/Ghc/Worker.hs +37/−21
- src/HsDev/Tools/HDocs.hs +7/−7
- src/HsDev/Tools/Tabs.hs +30/−0
- tests/Test.hs +29/−4
hsdev.cabal view
@@ -1,5 +1,5 @@ name: hsdev -version: 0.3.0.0 +version: 0.3.0.1 synopsis: Haskell development library description: Haskell development library and tool with support of autocompletion, symbol info, go to declaration, find references, hayoo search etc. @@ -96,6 +96,7 @@ HsDev.Tools.HDocs HsDev.Tools.HLint HsDev.Tools.Refact + HsDev.Tools.Tabs HsDev.Tools.Types HsDev.Types HsDev.Util
src/HsDev/Client/Commands.hs view
@@ -20,7 +20,7 @@ import Data.Maybe import qualified Data.Map.Strict as M import Data.Text (Text, pack, unpack) -import qualified Data.Text as T (append) +import qualified Data.Text as T (append, null) import System.Directory import System.FilePath import qualified System.Log.Simple as Log @@ -292,20 +292,46 @@ "s.name like ? escape '\\'"]) (fpath ^. path, likePattern sq) return [ScopeSymbol q s | (s :. Only q) <- rs] -runCommand (FindUsages nm) = toValue $ do - let - q = nameModule $ toName nm - ident = nameIdent $ toName nm - query @_ @SymbolUsage (toQuery $ qSymbol `mappend` qModuleId `mappend` select_ +runCommand (FindUsages l c fpath) = toValue $ do + us <- query @_ @SymbolUsage (toQuery $ qSymbol `mappend` qModuleId `mappend` select_ ["n.line", "n.column"] - ["names as n"] + ["names as n", "projects_modules_scope as ps", "names as defn", "modules as srcm"] [ - "m.name == n.resolved_module", - "s.name == n.resolved_name", - "mu.id == n.module_id", - "n.resolved_module == ? or ? is null", - "n.resolved_name == ?"]) - (q, q, ident) + "n.module_id = mu.id", + "n.resolved_module = defn.resolved_module", + "n.resolved_name = defn.resolved_name", + "s.name = defn.resolved_name", + -- "s.module_id = m.id", + "m.name = defn.resolved_module", + "(m.id = srcm.id or m.id = ps.module_id)", + "(((ps.cabal is null) and (srcm.cabal is null)) or (ps.cabal = srcm.cabal))", + "defn.module_id = srcm.id", + "(?, ?) between (defn.line, defn.column) and (defn.line_to, defn.column_to)", + "(mu.cabal = srcm.cabal or mu.id = srcm.cabal)", + "srcm.file = ?"]) + (l, c, fpath ^. path) + locals <- do + defs <- query @_ @(ModuleId :. Only Text :. Position :. Only (Maybe Text) :. Position) (toQuery $ qModuleId `mappend` select_ + ["n.name", "n.def_line", "n.def_column", "n.inferred_type", "n.line", "n.column"] + ["names as n", "names as defn"] + [ + "n.module_id = mu.id", + "n.def_line = defn.def_line", + "n.def_column = defn.def_column", + "defn.module_id = mu.id", + "(?, ?) between (defn.line, defn.column) and (defn.line_to, defn.column_to)", + "mu.file = ?"]) + (l, c, fpath ^. path) + return $ do + (mid :. Only nm :. defPos :. Only ftype :. usePos) <- defs + let + sym = Symbol { + _symbolId = SymbolId nm mid, + _symbolDocs = Nothing, + _symbolPosition = Just defPos, + _symbolInfo = Function ftype } + return $ SymbolUsage sym mid usePos + return $ us ++ locals runCommand (Complete input True fpath) = toValue $ query @_ @Symbol (toQuery $ qSymbol `mappend` select_ [] ["modules as srcm"] @@ -463,12 +489,10 @@ inSessionGhc $ do ms <- findSessionBy (const True) forM_ ms $ \s -> do - Log.sendLog Log.Trace $ "stopping session: {}" ~~ s - deleteSession s + Log.sendLog Log.Trace $ "stopping session: {}" ~~ view sessionKey s + deleteSession $ view sessionKey s runCommand Exit = toValue serverExit --- TODO: Implement `targetFilter` for sql - targetFilter :: Text -> Maybe Text -> TargetFilter -> (Text, [NamedParam]) targetFilter mtable _ (TargetProject proj) = ( "{t}.cabal in (select cabal from projects where name == :project or cabal == :project)" ~~ ("t" ~% mtable), @@ -480,7 +504,16 @@ ~~ ("t" ~% mtable) ~~ ("s" ~% stable), [":module_name" := nm]) -targetFilter mtable _ (TargetPackage nm) = ("{t}.package_name == :package_name" ~~ ("t" ~% mtable), [":package_name" := nm]) +targetFilter mtable _ (TargetPackage p) = (tpl ~~ ("t" ~% mtable), params) where + pkg = fromMaybe (mkPackage p) (readMaybe (unpack p)) + tpl + | T.null (pkg ^. packageVersion) = "{t}.package_name == :package_name" + | otherwise = "{t}.package_name == :package_name and {t}.package_version == :package_version" + params + | T.null (pkg ^. packageVersion) = [pname] + | otherwise = [pname, pver] + pname = ":package_name" := (pkg ^. packageName) + pver = ":package_version" := (pkg ^. packageVersion) targetFilter mtable _ TargetInstalled = ("{t}.package_name is not null" ~~ ("t" ~% mtable), []) targetFilter mtable _ TargetSourced = ("{t}.file is not null" ~~ ("t" ~% mtable), []) targetFilter mtable _ TargetStandalone = ("{t}.file is not null and {t}.cabal is null" ~~ ("t" ~% mtable), []) @@ -570,7 +603,8 @@ then return m else do defs <- askSession sessionDefines - p' <- liftIO $ preload (m ^. moduleId . moduleName) defs [] (m ^. moduleId . moduleLocation) Nothing + mcts <- fmap (fmap snd) $ getFileContents fpath' + p' <- liftIO $ preload (m ^. moduleId . moduleName) defs [] (m ^. moduleId . moduleLocation) mcts return $ set moduleImports (p' ^. asModule . moduleImports) m Just cabal' -> do proj' <- SQLite.loadProject cabal'
src/HsDev/Database/SQLite.hs view
@@ -45,6 +45,7 @@ import Distribution.Text (display) import Language.Haskell.Exts.Syntax hiding (Name, Module) import Language.Haskell.Extension () +import System.Directory import System.Log.Simple import Text.Format @@ -77,13 +78,20 @@ [Only equalVersion] <- SQL.query conn "select sum(json(value) == json(?)) > 0 from hsdev where option == 'version';" (Only $ toJSON version) return equalVersion else return True - unless goodVersion $ - -- TODO: Completely drop schema to reinitialize - hsdevError $ OtherError "Not implemented: dropping schema of db" - when (not hasTables || not goodVersion) $ SQL.withTransaction conn $ do - mapM_ (SQL.execute_ conn) commands - SQL.execute @(Text, Value) conn "insert into hsdev values (?, ?);" ("version", toJSON version) - return conn + let + start + | not goodVersion = do + close conn + removeFile p + conn' <- open p + initDb conn' + | not hasTables = initDb conn + | otherwise = return conn + initDb conn' = SQL.withTransaction conn' $ do + mapM_ (SQL.execute_ conn) commands + SQL.execute @(Text, Value) conn' "insert into hsdev values (?, ?);" ("version", toJSON version) + return conn' + start purge :: SessionMonad m => m () purge = do
src/HsDev/Database/Update.hs view
@@ -478,10 +478,10 @@ m' <- mapMOf (moduleId . moduleLocation . moduleProject . _Just) refineProjectInfo m Log.sendLog Log.Trace $ "Scanning docs for {}" ~~ view (moduleId . moduleLocation) m' docsMap <- inSessionGhc $ do - opts' <- getModuleOpts [] m' + (pdbs, opts') <- getModuleOpts [] m' currentSession >>= maybe (return ()) (const clearTargets) -- Calling haddock with targets set sometimes cause errors - haddockSession opts' + haddockSession pdbs opts' readModuleDocs opts' m' sendUpdateAction $ do SQLite.executeMany "update symbols set docs = ? where name == ? and module_id == ?;" @@ -512,8 +512,7 @@ mcts <- fmap (fmap snd) $ S.getFileContents (m' ^?! moduleId . moduleLocation . moduleFile) types' <- inSessionGhc $ do - opts' <- getModuleOpts [] m' - targetSession opts' m' + targetSession [] m' fileTypes m' mcts setModTypes (m' ^. moduleId) types'
src/HsDev/Display.hs view
@@ -6,54 +6,13 @@ ) where import Control.Lens (view) -import Data.List (intercalate) -import Data.Text.Lens (unpacked) -import Text.Format - import System.Directory.Paths -import HsDev.PackageDb -import HsDev.Project -import HsDev.Sandbox -import HsDev.Symbols.Location -import HsDev.Symbols.Types class Display a where display :: a -> String displayType :: a -> String -instance Display PackageDb where - display GlobalDb = "global-db" - display UserDb = "user-db" - display (PackageDb p) = "package-db " ++ display p - displayType _ = "package-db" - -instance Display PackageDbStack where - display = intercalate "/" . map display . packageDbs - displayType _ = "package-db-stack" - -instance Display ModuleLocation where - display (FileModule f _) = display f - display (InstalledModule _ _ n) = view unpacked n - display (OtherLocation s) = view unpacked s - display NoLocation = "<no-location>" - displayType _ = "module" - -instance Display ModuleTag where - display InferredTypesTag = "types" - display RefinedDocsTag = "docs" - display OnlyHeaderTag = "header" - displayType _ = "module-tag" - -instance Display Project where - display = view (projectName . unpacked) - displayType _ = "project" - -instance Display Sandbox where - display (Sandbox _ fpath) = display fpath - displayType (Sandbox CabalSandbox _) = "cabal-sandbox" - displayType (Sandbox StackWork _) = "stack-work" - instance Display FilePath where display = id displayType _ = "path" @@ -61,18 +20,3 @@ instance Display Path where display = view path displayType _ = "path" - -instance Formattable PackageDb where - formattable = formattable . display - -instance Formattable PackageDbStack where - formattable = formattable . display - -instance Formattable ModuleLocation where - formattable = formattable . display - -instance Formattable Project where - formattable = formattable . display - -instance Formattable Sandbox where - formattable = formattable . display
src/HsDev/Inspect.hs view
@@ -48,6 +48,7 @@ import HsDev.Display () import HsDev.Error +import HsDev.Sandbox (searchPackageDbStack) import HsDev.Symbols import HsDev.Symbols.Name (fromModuleName_) import HsDev.Symbols.Resolve (refineSymbol, refineTable, RefineTable, symbolUniqId) @@ -319,9 +320,13 @@ inspectDocs opts m = do let hdocsWorkaround = False + pdbs <- case view (moduleId . moduleLocation) m of + FileModule fpath _ -> searchPackageDbStack fpath + InstalledModule _ _ _ -> return userDb + _ -> return userDb docsMap <- if hdocsWorkaround then liftIO $ hdocsProcess (fromMaybe (T.unpack $ view (moduleId . moduleName) m) (preview (moduleId . moduleLocation . moduleFile . path) m)) opts - else liftM Just $ hdocs (view (moduleId . moduleLocation) m) opts + else liftM Just $ hdocs pdbs (view (moduleId . moduleLocation) m) opts return $ maybe id addDocs docsMap m -- | Like @inspectDocs@, but in @Ghc@ monad
src/HsDev/PackageDb/Types.hs view
@@ -14,11 +14,13 @@ import Control.Lens (makeLenses, each, (^.)) import Control.DeepSeq (NFData(..)) import Data.Aeson -import Data.List (tails, isSuffixOf) +import Data.List (tails, isSuffixOf, intercalate) import qualified Data.Text as T import Data.String +import Text.Format import System.Directory.Paths +import HsDev.Display data PackageDb = GlobalDb | UserDb | PackageDb { _packageDb :: Path } deriving (Eq, Ord) @@ -34,6 +36,15 @@ show UserDb = "user-db" show (PackageDb p) = "package-db:" ++ p ^. path +instance Display PackageDb where + display GlobalDb = "global-db" + display UserDb = "user-db" + display (PackageDb p) = "package-db " ++ display p + displayType _ = "package-db" + +instance Formattable PackageDb where + formattable = formattable . display + instance ToJSON PackageDb where toJSON GlobalDb = "global-db" toJSON UserDb = "user-db" @@ -59,6 +70,13 @@ instance NFData PackageDbStack where rnf (PackageDbStack ps) = rnf ps + +instance Display PackageDbStack where + display = intercalate "/" . map display . packageDbs + displayType _ = "package-db-stack" + +instance Formattable PackageDbStack where + formattable = formattable . display instance ToJSON PackageDbStack where toJSON (PackageDbStack ps) = toJSON ps
src/HsDev/Project/Types.hs view
@@ -20,11 +20,13 @@ import Data.Ord import Data.Text (Text) import qualified Data.Text as T -import Distribution.Text (display) +import qualified Distribution.Text as D (display) import Language.Haskell.Extension import System.FilePath +import Text.Format import System.Directory.Paths +import HsDev.Display import HsDev.Util -- | Cabal project @@ -50,6 +52,13 @@ "\tcabal: " ++ _projectCabal p ^. path, "\tdescription:"] ++ concatMap (map (tab 2) . lines . show) (maybeToList $ _projectDescription p) +instance Display Project where + display = T.unpack . _projectName + displayType _ = "project" + +instance Formattable Project where + formattable = formattable . display + instance ToJSON Project where toJSON p = object [ "name" .= _projectName p, @@ -249,10 +258,10 @@ instance Show Info where show i = unlines $ lang ++ exts ++ opts ++ sources ++ otherMods where - lang = maybe [] (\l -> ["default-language: " ++ display l]) $ _infoLanguage i + lang = maybe [] (\l -> ["default-language: " ++ D.display l]) $ _infoLanguage i exts | null (_infoExtensions i) = [] - | otherwise = "extensions:" : map (tab 1 . display) (_infoExtensions i) + | otherwise = "extensions:" : map (tab 1 . D.display) (_infoExtensions i) opts | null (_infoGHCOptions i) = [] | otherwise = "ghc-options:" : map (tab 1 . T.unpack) (_infoGHCOptions i) @@ -278,13 +287,13 @@ v .:: "other-modules" instance ToJSON Language where - toJSON = toJSON . display + toJSON = toJSON . D.display instance FromJSON Language where parseJSON = withText "language" $ \txt -> parseDT "Language" (T.unpack txt) instance ToJSON Extension where - toJSON = toJSON . display + toJSON = toJSON . D.display instance FromJSON Extension where parseJSON = withText "extension" $ \txt -> parseDT "Extension" (T.unpack txt)
src/HsDev/Sandbox.hs view
@@ -30,8 +30,10 @@ import qualified Distribution.Text as T (display) import System.FilePath import System.Log.Simple (MonadLog(..)) +import Text.Format import System.Directory.Paths +import HsDev.Display import HsDev.PackageDb import HsDev.Project.Types import HsDev.Scan.Browse (browsePackages) @@ -61,6 +63,14 @@ instance Show Sandbox where show (Sandbox _ p) = T.unpack p +instance Display Sandbox where + display (Sandbox _ fpath) = display fpath + displayType (Sandbox CabalSandbox _) = "cabal-sandbox" + displayType (Sandbox StackWork _) = "stack-work" + +instance Formattable Sandbox where + formattable = formattable . display + instance ToJSON Sandbox where toJSON (Sandbox _ p) = toJSON p @@ -138,7 +148,7 @@ -- | Get actual sandbox build path: <arch>-<platform>-<compiler>-<version> cabalSandboxLib :: GhcM FilePath cabalSandboxLib = do - tmpSession ["-no-user-package-db"] + tmpSession globalDb ["-no-user-package-db"] df <- GHC.getSessionDynFlags let res = @@ -154,27 +164,25 @@ cabalSandboxPackageDb = liftM (++ "-packages.conf.d") cabalSandboxLib -- | Options for GHC for module and project -getModuleOpts :: [String] -> Module -> GhcM [String] +getModuleOpts :: [String] -> Module -> GhcM (PackageDbStack, [String]) getModuleOpts opts m = do pdbs <- case view (moduleId . moduleLocation) m of FileModule fpath _ -> searchPackageDbStack fpath InstalledModule _ _ _ -> return userDb _ -> return userDb pkgs <- browsePackages opts pdbs - return $ concat [ - packageDbStackOpts pdbs, + return $ (pdbs, concat [ moduleOpts pkgs m, - opts] + opts]) -- | Options for GHC for project target -getProjectTargetOpts :: [String] -> Project -> Info -> GhcM [String] +getProjectTargetOpts :: [String] -> Project -> Info -> GhcM (PackageDbStack, [String]) getProjectTargetOpts opts proj t = do pdbs <- searchPackageDbStack $ view projectPath proj pkgs <- browsePackages opts pdbs - return $ concat [ - packageDbStackOpts pdbs, + return $ (pdbs, concat [ projectTargetOpts pkgs proj t, - opts] + opts]) -- | Get sandbox of project (if any) getProjectSandbox :: MonadLog m => Project -> m (Maybe Sandbox)
src/HsDev/Scan.hs view
@@ -40,7 +40,7 @@ import qualified HsDev.Database.SQLite as SQLite import HsDev.Database.SQLite.Select import HsDev.Scan.Browse (browsePackages) -import HsDev.Server.Types (FileSource(..), SessionMonad(..), CommandMonad(..), inSessionGhc) +import HsDev.Server.Types (FileSource(..), SessionMonad(..), CommandMonad(..), inSessionGhc, postSessionUpdater) import HsDev.Sandbox import HsDev.Symbols import HsDev.Symbols.Types @@ -247,5 +247,5 @@ if fmtime < tm' then return (Just (tm', cts)) else do - SQLite.execute "delete from file_contents where file = ?;" (SQLite.Only fpath) + void $ postSessionUpdater $ SQLite.execute "delete from file_contents where file = ?;" (SQLite.Only fpath) return Nothing
src/HsDev/Scan/Browse.hs view
@@ -55,13 +55,13 @@ -- | Browse packages browsePackages :: [String] -> PackageDbStack -> GhcM [PackageConfig] browsePackages opts dbs = do - tmpSession (packageDbStackOpts dbs ++ opts) + tmpSession dbs opts liftM (map readPackageConfig) packageConfigs -- | Get packages with deps browsePackagesDeps :: [String] -> PackageDbStack -> GhcM (Deps PackageConfig) browsePackagesDeps opts dbs = do - tmpSession (packageDbStackOpts dbs ++ opts) + tmpSession dbs opts df <- GHC.getSessionDynFlags cfgs <- packageConfigs return $ mapDeps (toPkg df) $ mconcat [deps (Compat.unitId cfg) (Compat.depends df cfg) | cfg <- cfgs] @@ -73,7 +73,7 @@ -- otherwise hidden packages won't be loaded listModules :: [String] -> PackageDbStack -> [ModulePackage] -> GhcM [ModuleLocation] listModules opts dbs pkgs = do - tmpSession (packageDbStackOpts dbs ++ opts ++ packagesOpts) + tmpSession dbs (opts ++ packagesOpts) ms <- packageDbModules return [ghcModuleLocation p m | (p, m) <- ms] where @@ -84,7 +84,7 @@ -- one of them can be lookuped and therefore modules from different version packages won't be actually inspected browseModules :: [String] -> PackageDbStack -> [ModuleLocation] -> GhcM [InspectedModule] browseModules opts dbs mlocs = do - tmpSession (packageDbStackOpts dbs ++ opts) + tmpSession dbs opts liftM concat . withEachPackage (const $ browseModules' opts) $ mlocs -- | Inspect installed modules, doesn't set session and package flags!
src/HsDev/Server/Base.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE CPP, OverloadedStrings, CPP, PatternGuards #-} +{-# LANGUAGE CPP, OverloadedStrings, CPP, PatternGuards, TypeApplications #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module HsDev.Server.Base ( @@ -54,7 +54,7 @@ import HsDev.Error import qualified HsDev.Database.Update as Update import HsDev.Inspect (getDefines) -import HsDev.Tools.Ghc.Worker +import HsDev.Tools.Ghc.Worker hiding (Session) import HsDev.Server.Types import HsDev.Server.Message import HsDev.Symbols.Location (ModuleLocation(..)) @@ -95,15 +95,20 @@ session <- liftIO $ fixIO $ \sess -> do let - setFileCts fpath Nothing = withSession sess $ do + setFileCts fpath Nothing = void $ withSession sess $ postSessionUpdater $ do Log.sendLog Log.Trace $ "dropping file contents for {}" ~~ fpath SQLite.execute "delete from file_contents where file = ?;" (SQLite.Only fpath) setFileCts fpath (Just cts) = do tm <- getPOSIXTime withSession sess $ do - Log.sendLog Log.Trace $ "setting file contents for {} with mtime = {}" ~~ fpath ~~ show tm - SQLite.execute "insert or replace into file_contents (file, contents, mtime) values (?, ?, ?);" (fpath, cts, (fromRational (toRational tm) :: Double)) - writeChan (W.watcherChan watcher) (W.WatchedModule, W.Event W.Modified (view path fpath) tm) + notChanged <- SQLite.query @_ @(SQLite.Only Bool) "select contents == ? from file_contents where file = ?;" (cts, fpath) + let + notChanged' = any SQLite.fromOnly notChanged + void $ postSessionUpdater $ do + Log.sendLog Log.Trace $ "setting file contents for {} with mtime = {}" ~~ fpath ~~ show tm + SQLite.execute "insert or replace into file_contents (file, contents, mtime) values (?, ?, ?);" (fpath, cts, (fromRational (toRational tm) :: Double)) + unless notChanged' $ liftIO $ + writeChan (W.watcherChan watcher) (W.WatchedModule, W.Event W.Modified (view path fpath) tm) uw <- startWorker (withSession sess . withSqlConnection) id logAll
src/HsDev/Server/Types.hs view
@@ -6,7 +6,8 @@ SessionLog(..), Session(..), SessionMonad(..), askSession, ServerM(..), CommandOptions(..), CommandMonad(..), askOptions, ClientM(..), withSession, serverListen, serverSetLogLevel, serverWait, serverWaitClients, - serverSqlDatabase, openSqlConnection, closeSqlConnection, withSqlConnection, withSqlTransaction, serverSetFileContents, inSessionGhc, inSessionUpdater, serverExit, commandRoot, commandNotify, commandLink, commandHold, + serverSqlDatabase, openSqlConnection, closeSqlConnection, withSqlConnection, withSqlTransaction, serverSetFileContents, + inSessionGhc, inSessionUpdater, postSessionUpdater, serverExit, commandRoot, commandNotify, commandLink, commandHold, ServerCommand(..), ConnectionPort(..), ServerOpts(..), silentOpts, ClientOpts(..), serverOptsArgs, Request(..), Command(..), @@ -15,6 +16,7 @@ ) where import Control.Applicative +import Control.Concurrent.Async (Async) import qualified Control.Concurrent.FiniteChan as F import Control.Lens (view, set) import Control.Monad.Base @@ -240,6 +242,12 @@ uw <- askSession sessionUpdater inWorkerWith (hsdevError . OtherError . displayException) uw act +-- | Post to updater and return +postSessionUpdater :: SessionMonad m => ServerM IO a -> m (Async a) +postSessionUpdater act = do + uw <- askSession sessionUpdater + liftIO $ sendTask uw act + -- | Exit session serverExit :: SessionMonad m => m () serverExit = join . liftM liftIO $ askSession sessionExit @@ -437,7 +445,7 @@ Whoat Int Int Path | ResolveScopeModules SearchQuery Path | ResolveScope SearchQuery Path | - FindUsages Text | + FindUsages Int Int Path | Complete Text Bool Path | Hayoo { hayooQuery :: String, @@ -508,7 +516,7 @@ paths f (Whoat l c fpath) = Whoat <$> pure l <*> pure c <*> paths f fpath paths f (ResolveScopeModules q fpath) = ResolveScopeModules q <$> paths f fpath paths f (ResolveScope q fpath) = ResolveScope q <$> paths f fpath - paths _ (FindUsages nm) = pure $ FindUsages nm + paths f (FindUsages l c fpath) = FindUsages <$> pure l <*> pure c <*> paths f fpath paths f (Complete n g fpath) = Complete n g <$> paths f fpath paths f (UnresolvedSymbols fs) = UnresolvedSymbols <$> traverse (paths f) fs paths f (Lint fs) = Lint <$> traverse (paths f) fs @@ -562,7 +570,7 @@ cmd "scope" "get declarations accessible from module or within a project" ( subparser (cmd "modules" "get modules accessible from module or within a project" (ResolveScopeModules <$> cmdP <*> ctx)) <|> ResolveScope <$> cmdP <*> ctx), - cmd "usages" "find usages of fully qualified symbol (qualified with module its defined in)" (FindUsages <$> textArgument idm), + cmd "usages" "find usages of symbol within project/module" (FindUsages <$> argument auto (metavar "line") <*> argument auto (metavar "column") <*> ctx), cmd "complete" "show completions for input" (Complete <$> textArgument idm <*> wideFlag <*> ctx), cmd "hayoo" "find declarations online via Hayoo" (Hayoo <$> strArgument idm <*> hayooPageArg <*> hayooPagesArg), cmd "cabal" "cabal commands" (subparser $ cmd "list" "list cabal packages" (CabalList <$> many (textArgument idm))), @@ -687,7 +695,7 @@ toJSON (Whoat l c f) = cmdJson "whoat" ["line" .= l, "column" .= c, "file" .= f] toJSON (ResolveScopeModules q f) = cmdJson "scope modules" ["query" .= q, "file" .= f] toJSON (ResolveScope q f) = cmdJson "scope" ["query" .= q, "file" .= f] - toJSON (FindUsages nm) = cmdJson "usages" ["name" .= nm] + toJSON (FindUsages l c f) = cmdJson "usages" ["line" .= l, "column" .= c, "file" .= f] toJSON (Complete q w f) = cmdJson "complete" ["prefix" .= q, "wide" .= w, "file" .= f] toJSON (Hayoo q p ps) = cmdJson "hayoo" ["query" .= q, "page" .= p, "pages" .= ps] toJSON (CabalList ps) = cmdJson "cabal list" ["packages" .= ps] @@ -741,7 +749,7 @@ guardCmd "whoat" v *> (Whoat <$> v .:: "line" <*> v .:: "column" <*> v .:: "file"), guardCmd "scope modules" v *> (ResolveScopeModules <$> v .:: "query" <*> v .:: "file"), guardCmd "scope" v *> (ResolveScope <$> v .:: "query" <*> v .:: "file"), - guardCmd "usages" v *> (FindUsages <$> v .:: "name"), + guardCmd "usages" v *> (FindUsages <$> v .:: "line" <*> v .:: "column" <*> v .:: "file"), guardCmd "complete" v *> (Complete <$> v .:: "prefix" <*> (v .:: "wide" <|> pure False) <*> v .:: "file"), guardCmd "hayoo" v *> (Hayoo <$> v .:: "query" <*> (v .:: "page" <|> pure 0) <*> (v .:: "pages" <|> pure 1)), guardCmd "cabal list" v *> (CabalList <$> v .::?! "packages"), @@ -770,7 +778,7 @@ toJSON (TargetProject pname) = object ["project" .= pname] toJSON (TargetFile fpath) = object ["file" .= fpath] toJSON (TargetModule mname) = object ["module" .= mname] - toJSON (TargetPackage pname) = object ["package" .= pname] + toJSON (TargetPackage pkg) = object ["package" .= pkg] toJSON TargetInstalled = toJSON ("installed" :: String) toJSON TargetSourced = toJSON ("sourced" :: String) toJSON TargetStandalone = toJSON ("standalone" :: String)
src/HsDev/Stack.hs view
@@ -43,7 +43,7 @@ -- | Get compiler version stackCompiler :: GhcM String stackCompiler = do - tmpSession ["-no-user-package-db"] + tmpSession globalDb ["-no-user-package-db"] df <- GHC.getSessionDynFlags let res =
src/HsDev/Symbols/Location.hs view
@@ -30,11 +30,14 @@ import Data.List (findIndex) import Data.Maybe import Data.Text (Text, pack, unpack) +import Data.Text.Lens (unpacked) import qualified Data.Text as T import System.FilePath import Text.Read (readMaybe) +import Text.Format import System.Directory.Paths +import HsDev.Display import HsDev.PackageDb.Types import HsDev.Project.Types import HsDev.Util ((.::), (.::?), (.::?!), objectUnion, noNulls) @@ -140,6 +143,16 @@ instance Show ModuleLocation where show = unpack . locationId + +instance Display ModuleLocation where + display (FileModule f _) = display f + display (InstalledModule _ _ n) = view unpacked n + display (OtherLocation s) = view unpacked s + display NoLocation = "<no-location>" + displayType _ = "module" + +instance Formattable ModuleLocation where + formattable = formattable . display instance ToJSON ModuleLocation where toJSON (FileModule f p) = object $ noNulls ["file" .= f, "project" .= fmap (view projectCabal) p]
src/HsDev/Symbols/Types.hs view
@@ -43,6 +43,7 @@ import Text.Format import Control.Apply.Util (chain) +import HsDev.Display import HsDev.PackageDb.Types import HsDev.Project import HsDev.Symbols.Name @@ -436,6 +437,12 @@ rnf InferredTypesTag = () rnf RefinedDocsTag = () rnf OnlyHeaderTag = () + +instance Display ModuleTag where + display InferredTypesTag = "types" + display RefinedDocsTag = "docs" + display OnlyHeaderTag = "header" + displayType _ = "module-tag" instance ToJSON ModuleTag where toJSON InferredTypesTag = toJSON ("types" :: String)
src/HsDev/Tools/Ghc/Check.hs view
@@ -8,18 +8,16 @@ module HsDev.Symbols.Types, PackageDb(..), PackageDbStack(..), Project(..), - recalcNotesTabs, - module Control.Monad.Except ) where -import Control.Lens (preview, view, each, (^..), (^.)) +import Control.Lens (view, (^.)) import Control.Monad.Except -import Data.Maybe (fromMaybe) +import qualified Data.Map as M import Data.Text (Text) import System.Log.Simple (MonadLog(..), scope, sendLog, Level(Trace)) -import GHC hiding (Warning, Module, moduleName) +import GHC hiding (Warning, Module) import Control.Concurrent.FiniteChan import HsDev.Error @@ -30,7 +28,7 @@ import HsDev.Tools.Ghc.Worker import HsDev.Tools.Ghc.Compat as C import HsDev.Tools.Types -import HsDev.Util (readFileUtf8, ordNub) +import HsDev.Tools.Tabs import System.Directory.Paths -- | Check module source @@ -40,6 +38,9 @@ ch <- liftIO newChan let dir = sourceRoot_ (m ^. moduleId) + -- FIXME: There can be dependent modules with modified file contents + -- Their contents should be set here too + srcs = maybe mempty (M.singleton file) msrc ex <- liftIO $ dirExists dir sendLog Trace "loading targets" withFlags $ (if ex then withCurrentDirectory (dir ^. path) else id) $ do @@ -48,18 +49,5 @@ loadTargets [target] notes <- liftIO $ stopChan ch sendLog Trace "targets checked" - liftIO $ recalcNotesTabs notes + liftIO $ recalcNotesTabs srcs notes _ -> scope "check" $ hsdevError $ ModuleNotSource (view (moduleId . moduleLocation) m) - --- Recalc tabs for notes -recalcNotesTabs :: [Note OutputMessage] -> IO [Note OutputMessage] -recalcNotesTabs notes = do - cts <- mapM (readFileUtf8 . view path) files - let - recalc' n = fromMaybe n $ do - fname <- preview (noteSource . moduleFile) n - cts' <- lookup fname (zip files cts) - return $ recalcTabs cts' 8 n - return $ map recalc' notes - where - files = ordNub $ notes ^.. each . noteSource . moduleFile
src/HsDev/Tools/Ghc/MGhc.hs view
@@ -2,9 +2,10 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} module HsDev.Tools.Ghc.MGhc ( + Session(..), sessionKey, sessionData, SessionState(..), sessionActive, sessionMap, MGhcT(..), runMGhcT, liftGhc, - currentSession, hasSession, findSession, findSessionBy, saveSession, + currentSession, getSessionData, setSessionData, hasSession, findSession, findSessionBy, saveSession, initSession, newSession, switchSession, switchSession_, deleteSession, restoreSession, usingSession, tempSession @@ -17,7 +18,6 @@ import Control.Monad.State import Data.Default import Data.IORef -import Data.List (find) import Data.Map.Strict (Map) import qualified Data.Map.Strict as M import Data.Maybe (fromMaybe, isJust) @@ -27,24 +27,40 @@ import Exception hiding (catch, mask, uninterruptibleMask, bracket, finally) import GHC import GHCi -import GhcMonad +import GhcMonad hiding (Session(..)) +import qualified GhcMonad (Session(..)) import HscTypes import Outputable import SysTools -data SessionState s = SessionState { - _sessionActive :: Maybe s, - _sessionMap :: Map s HscEnv } +data Session s d = Session { + _sessionKey :: s, + _sessionData :: d } + deriving (Eq, Ord, Read, Show) -instance Default (SessionState s) where +sessionKey :: Lens' (Session s d) s +sessionKey = lens g s where + g = _sessionKey + s sess k = sess { _sessionKey = k } + +sessionData :: Lens' (Session s d) d +sessionData = lens g s where + g = _sessionData + s sess dat = sess { _sessionData = dat } + +data SessionState s d = SessionState { + _sessionActive :: Maybe (Session s d), + _sessionMap :: Map s (HscEnv, d) } + +instance Default (SessionState s d) where def = SessionState Nothing M.empty -sessionActive :: Lens' (SessionState s) (Maybe s) +sessionActive :: Lens' (SessionState s d) (Maybe (Session s d)) sessionActive = lens g s where g = _sessionActive s st nm = st { _sessionActive = nm } -sessionMap :: Lens' (SessionState s) (Map s HscEnv) +sessionMap :: Lens' (SessionState s d) (Map s (HscEnv, d)) sessionMap = lens g s where g = _sessionMap s st m = st { _sessionMap = m } @@ -62,8 +78,8 @@ act v = ReaderT $ act' . runReaderT v -- | Multi-session ghc monad -newtype MGhcT s m a = MGhcT { unMGhcT :: GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s) m)) a } - deriving (Functor, Applicative, Monad, MonadIO, ExceptionMonad, HasDynFlags, GhcMonad, MonadState (SessionState s), MonadReader (Maybe FilePath), MonadThrow, MonadCatch, MonadMask, MonadLog) +newtype MGhcT s d m a = MGhcT { unMGhcT :: GhcT (ReaderT (Maybe FilePath) (StateT (SessionState s d) m)) a } + deriving (Functor, Applicative, Monad, MonadIO, ExceptionMonad, HasDynFlags, GhcMonad, MonadState (SessionState s d), MonadReader (Maybe FilePath), MonadThrow, MonadCatch, MonadMask, MonadLog) instance MonadTrans GhcT where lift = liftGhcT @@ -93,78 +109,88 @@ q g' act = GhcT $ g' . unGhcT act -- | Run multi-session ghc -runMGhcT :: (MonadIO m, ExceptionMonad m, Ord s) => Maybe FilePath -> MGhcT s m a -> m a +runMGhcT :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => Maybe FilePath -> MGhcT s d m a -> m a runMGhcT lib act = do ref <- liftIO $ newIORef (panic "empty session") let - session = Session ref + session = GhcMonad.Session ref flip evalStateT def $ flip runReaderT lib $ flip unGhcT session $ unMGhcT $ act `gfinally` cleanup where - cleanup :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s m () + cleanup :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => MGhcT s d m () cleanup = do void saveSession sessions <- gets (M.elems . view sessionMap) - liftIO $ mapM_ cleanupSession sessions + liftIO $ mapM_ (cleanupSession . view _1) sessions modify (set sessionMap M.empty) -- | Lift `Ghc` monad onto `MGhc` -liftGhc :: MonadIO m => Ghc a -> MGhcT s m a +liftGhc :: MonadIO m => Ghc a -> MGhcT s d m a liftGhc (Ghc act) = MGhcT $ GhcT $ liftIO . act -currentSession :: MonadIO m => MGhcT s m (Maybe s) +-- | Get current session +currentSession :: MonadIO m => MGhcT s d m (Maybe (Session s d)) currentSession = gets (view sessionActive) +-- | Get current session data +getSessionData :: MonadIO m => MGhcT s d m (Maybe d) +getSessionData = gets (preview (sessionActive . _Just . sessionData)) + +-- | Set current session data +setSessionData :: MonadIO m => d -> MGhcT s d m () +setSessionData sdata = modify (set (sessionActive . _Just . sessionData) sdata) + -- | Does session exist -hasSession :: (MonadIO m, Ord s) => s -> MGhcT s m Bool +hasSession :: (MonadIO m, Ord s) => s -> MGhcT s d m Bool hasSession key = do - msess <- gets (preview (sessionMap . ix key)) + msess <- findSession key return $ isJust msess -- | Find session -findSession :: (MonadIO m, Ord s) => s -> MGhcT s m (Maybe s) +findSession :: (MonadIO m, Ord s) => s -> MGhcT s d m (Maybe (Session s d)) findSession key = do - mkeys <- gets (M.keys . view sessionMap) - return $ find (== key) mkeys + sdata <- gets (preview (sessionMap . ix key . _2)) + return $ fmap (Session key) sdata -- | Find session by -findSessionBy :: MonadIO m => (s -> Bool) -> MGhcT s m [s] +findSessionBy :: MonadIO m => (s -> Bool) -> MGhcT s d m [Session s d] findSessionBy p = do - mkeys <- gets (M.keys . view sessionMap) - return $ filter p mkeys + sessions <- gets (M.toList . view sessionMap) + return [Session key sdata | (key, (_, sdata)) <- sessions, p key] -- | Save current session -saveSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s m (Maybe s) +saveSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s d m (Maybe (Session s d)) saveSession = do - key <- currentSession - case key of - Just key' -> do + msess <- currentSession + case msess of + Just (Session key' dat') -> do sess <- getSession - modify (set (sessionMap . at key') (Just sess)) + modify (set (sessionMap . at key') (Just (sess, dat'))) Nothing -> return () - return key + return msess -- | Initialize new session -initSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s m () +initSession :: (MonadIO m, ExceptionMonad m, Ord s) => MGhcT s d m () initSession = do lib <- ask initGhcMonad lib void saveSession -activateSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m (Maybe HscEnv) +activateSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m (Maybe HscEnv) activateSession key = do void saveSession - modify (set sessionActive $ Just key) - gets (view (sessionMap . at key)) + sdata <- gets (view (sessionMap . ix key . _2)) + modify (set sessionActive $ Just (Session key sdata)) + gets (preview (sessionMap . ix key . _1)) -- | Create new named session, deleting existing session -newSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m () +newSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m () newSession key = do msess <- activateSession key maybe (return ()) (liftIO . cleanupSession) msess initSession -- | Switch to session, creating if not exist, returns True if session was created -switchSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m Bool +switchSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m Bool switchSession key = do msess <- activateSession key case msess of @@ -172,38 +198,38 @@ Just sess -> setSession sess >> return False -- | Switch to session, creating if not exist and initializing with passed function -switchSession_ :: (MonadIO m, ExceptionMonad m, Ord s) => s -> Maybe (MGhcT s m ()) -> MGhcT s m () +switchSession_ :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> Maybe (MGhcT s d m ()) -> MGhcT s d m () switchSession_ key f = do new <- switchSession key when new $ fromMaybe (return ()) f -- | Delete existing session -deleteSession :: (MonadIO m, ExceptionMonad m, Ord s) => s -> MGhcT s m () +deleteSession :: (MonadIO m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m () deleteSession key = do cur <- saveSession - when (cur == Just key) $ + when (preview (_Just . sessionKey) cur == Just key) $ modify (set sessionActive Nothing) - msess <- gets (view (sessionMap . at key)) + msess <- gets (preview (sessionMap . ix key . _1)) modify (set (sessionMap . at key) Nothing) case msess of Nothing -> return () Just sess -> liftIO $ cleanupSession sess -- | Save and restore session -restoreSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => MGhcT s m a -> MGhcT s m a -restoreSession act = bracket saveSession (maybe (return ()) (void . switchSession)) $ const act +restoreSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => MGhcT s d m a -> MGhcT s d m a +restoreSession act = bracket saveSession (maybe (return ()) (void . switchSession . view sessionKey)) $ const act -- | Run action using session, restoring session back -usingSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => s -> MGhcT s m a -> MGhcT s m a +usingSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m a -> MGhcT s d m a usingSession key act = restoreSession $ do void $ switchSession key act -- | Run with temporary session, like @usingSession@, but deletes self session -tempSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s) => s -> MGhcT s m a -> MGhcT s m a +tempSession :: (MonadIO m, MonadMask m, ExceptionMonad m, Ord s, Monoid d) => s -> MGhcT s d m a -> MGhcT s d m a tempSession key act = do exist' <- hasSession key - usingSession key act `finally` when (not exist') (deleteSession key) + usingSession key act `finally` unless exist' (deleteSession key) -- | Cleanup session cleanupSession :: HscEnv -> IO ()
src/HsDev/Tools/Ghc/Session.hs view
@@ -23,8 +23,8 @@ -- | Session for module targetSession :: [String] -> Module -> GhcM () targetSession opts m = do - opts' <- getModuleOpts opts m - ghcSession ("-Wall" : opts') + (pdbs, opts') <- getModuleOpts opts m + ghcSession pdbs ("-Wall" : opts') -- | Interpret file interpretModule :: Module -> Maybe Text -> GhcM ()
src/HsDev/Tools/Ghc/Worker.hs view
@@ -33,6 +33,7 @@ import Control.Monad.Reader import Control.Monad.Catch import Data.Dynamic +import Data.Monoid import Data.Time.Clock (getCurrentTime) import Data.String (fromString) import Data.Text (Text) @@ -54,13 +55,14 @@ import Control.Concurrent.Worker import System.Directory.Paths import HsDev.Symbols.Location (Position(..), Region(..), region, ModuleLocation(..)) +import HsDev.PackageDb.Types import HsDev.Tools.Types import HsDev.Tools.Ghc.Compat import qualified HsDev.Tools.Ghc.Compat as C (setLogAction) import HsDev.Tools.Ghc.MGhc data SessionType = SessionGhci | SessionGhc | SessionHaddock | SessionTmp deriving (Eq, Ord) -data SessionConfig = SessionConfig SessionType [String] deriving (Eq, Ord) +data SessionConfig = SessionConfig SessionType PackageDbStack deriving (Eq, Ord) instance Show SessionType where show SessionGhci = "ghci" @@ -68,14 +70,16 @@ show SessionHaddock = "haddock" show SessionTmp = "tmp" +instance Formattable SessionType + instance Show SessionConfig where - show (SessionConfig t opts) = unwords (show t : opts) + show (SessionConfig t pdb) = "{} {}" ~~ t ~~ pdb instance Formattable SessionConfig -type GhcM a = MGhcT SessionConfig (LogT IO) a +type GhcM a = MGhcT SessionConfig (First DynFlags) (LogT IO) a -type GhcWorker = Worker (MGhcT SessionConfig (LogT IO)) +type GhcWorker = Worker (MGhcT SessionConfig (First DynFlags) (LogT IO)) instance (Monad m, GhcMonad m) => GhcMonad (ReaderT r m) where getSession = lift getSession @@ -104,38 +108,50 @@ logErr e = Log.sendLog Log.Warning ("exception in ghc worker task: {}" ~~ displayException e) -- | Create session with options -workerSession :: SessionType -> [String] -> GhcM () -workerSession ty opts = do +workerSession :: SessionType -> PackageDbStack -> [String] -> GhcM () +workerSession ty pdbs opts = do ms <- findSessionBy toKill forM_ ms $ \s' -> do - Log.sendLog Log.Trace $ "killing session: {}" ~~ s' - deleteSession s' - Log.sendLog Log.Trace $ "session: {}" ~~ SessionConfig ty opts - switchSession_ (SessionConfig ty opts) $ Just initialize + Log.sendLog Log.Trace $ "killing session: {}" ~~ view sessionKey s' + deleteSession $ view sessionKey s' + Log.sendLog Log.Trace $ "session: {}" ~~ SessionConfig ty pdbs + switchSession_ (SessionConfig ty pdbs) $ Just initialize + setSessionFlags where - toKill (SessionConfig ty' opts') = or [ - (ty == ty' && opts /= opts'), + toKill (SessionConfig ty' pdbs') = or [ + (ty == ty' && pdbs /= pdbs'), (ty /= ty' && ty' `elem` [SessionTmp, SessionHaddock] && ty /= SessionTmp)] - initialize = case ty of - SessionGhci -> ghcRun opts (importModules preludeModules) - SessionGhc -> ghcRun opts (return ()) - SessionTmp -> ghcRun opts (return ()) - SessionHaddock -> ghcRunWith noLinkFlags ("-haddock" : opts) (return ()) + initialize = do + run + dflags <- getSessionDynFlags + setSessionData (First $ Just dflags) + run = case ty of + SessionGhci -> ghcRun pdbsOpts (importModules preludeModules) + SessionGhc -> ghcRun pdbsOpts (return ()) + SessionTmp -> ghcRun pdbsOpts (return ()) + SessionHaddock -> ghcRunWith noLinkFlags ("-haddock" : pdbsOpts) (return ()) + setSessionFlags = do + Log.sendLog Log.Trace $ "setting flags: {}" ~~ unwords opts + mdflags <- fmap (join . fmap getFirst) getSessionData + dflags <- maybe getSessionDynFlags return mdflags + (df', _, _) <- parseDynamicFlags dflags (map noLoc opts) + void $ setSessionDynFlags df' + pdbsOpts = packageDbStackOpts pdbs -- | Get ghc session -ghcSession :: [String] -> GhcM () +ghcSession :: PackageDbStack -> [String] -> GhcM () ghcSession = workerSession SessionGhc -- | Get ghci session ghciSession :: GhcM () -ghciSession = workerSession SessionGhci [] +ghciSession = workerSession SessionGhci userDb [] -- | Get haddock session with flags -haddockSession :: [String] -> GhcM () +haddockSession :: PackageDbStack -> [String] -> GhcM () haddockSession = workerSession SessionHaddock -- | Get haddock session with flags -tmpSession :: [String] -> GhcM () +tmpSession :: PackageDbStack -> [String] -> GhcM () tmpSession = workerSession SessionTmp -- | Run ghc
src/HsDev/Tools/HDocs.hs view
@@ -50,12 +50,12 @@ import System.Directory.Paths -- | Get docs for modules -hdocsy :: [ModuleLocation] -> [String] -> GhcM [Map String String] +hdocsy :: PackageDbStack -> [ModuleLocation] -> [String] -> GhcM [Map String String] #ifndef NODOCS -hdocsy mlocs opts = (map $ force . HDocs.formatDocs) <$> docs' mlocs where +hdocsy pdbs mlocs opts = (map $ force . HDocs.formatDocs) <$> docs' mlocs where docs' :: [ModuleLocation] -> GhcM [HDocs.ModuleDocMap] docs' ms = do - haddockSession opts + haddockSession pdbs opts liftGhc $ hsdevLiftWith (ToolError "hdocs") $ liftM (map snd) $ HDocs.readSourcesGhc opts $ map (view (moduleFile . path)) ms #else @@ -63,12 +63,12 @@ #endif -- | Get docs for module -hdocs :: ModuleLocation -> [String] -> GhcM (Map String String) +hdocs :: PackageDbStack -> ModuleLocation -> [String] -> GhcM (Map String String) #ifndef NODOCS -hdocs mloc opts = (force . HDocs.formatDocs) <$> docs' mloc where +hdocs pdbs mloc opts = (force . HDocs.formatDocs) <$> docs' mloc where docs' :: ModuleLocation -> GhcM HDocs.ModuleDocMap docs' mloc' = do - haddockSession opts + haddockSession pdbs opts liftGhc $ case mloc' of (FileModule fpath _) -> hsdevLiftWith (ToolError "hdocs") $ liftM snd $ HDocs.readSourceGhc opts (view path fpath) (InstalledModule _ _ mname) -> do @@ -101,7 +101,7 @@ hdocsCabal :: PackageDbStack -> [String] -> GhcM [(ModulePackage, (Map Text (Map Text Text)))] #ifndef NODOCS hdocsCabal pdbs opts = do - haddockSession (packageDbStackOpts pdbs ++ opts) + haddockSession pdbs opts pkgs <- packageConfigs forM pkgs $ \pkg -> do pkgDocs' <- hdocsPackage pkg
+ src/HsDev/Tools/Tabs.hs view
@@ -0,0 +1,30 @@+module HsDev.Tools.Tabs ( + recalcNotesTabs + ) where + +import Control.Lens +import Data.Map (Map) +import qualified Data.Map as M +import Data.Maybe (fromMaybe) +import Data.Text (Text) + +import System.Directory.Paths +import HsDev.Symbols.Location +import HsDev.Tools.Types +import HsDev.Util + +-- | Some tools counts tab as 8 symbols and return such file positions; convert them (consider tab = one symbol) +recalcNotesTabs :: Map Path Text -> [Note a] -> IO [Note a] +recalcNotesTabs srcs notes = do + ctsMap <- fmap M.fromList $ mapM loadFileContents files + let + recalc' n = fromMaybe n $ do + fname <- preview (noteSource . moduleFile) n + cts' <- M.lookup fname ctsMap + return $ recalcTabs cts' 8 n + return $ map recalc' notes + where + files = ordNub $ notes ^.. each . noteSource . moduleFile + loadFileContents f = do + cts <- maybe (readFileUtf8 $ view path f) return $ M.lookup f srcs + return (f, cts)
tests/Test.hs view
@@ -34,10 +34,11 @@ exports v = mkSet (v ^.. traverseArray . key "exports" . traverseArray . key "id" . key "name" . _Just) rgn :: Maybe Value -> Maybe Region -rgn v = Region <$> (pos (v ^. key "from")) <*> (pos (v ^. key "to")) where - pos :: Maybe Value -> Maybe Position - pos v' = Position <$> (v' ^. key "line") <*> (v' ^. key "column") +rgn v = Region <$> (pos (v ^. key "from")) <*> (pos (v ^. key "to")) +pos :: Maybe Value -> Maybe Position +pos v = Position <$> (v ^. key "line") <*> (v ^. key "column") + mkSet :: [String] -> S.Set String mkSet = S.fromList @@ -47,7 +48,7 @@ dir <- runIO getCurrentDirectory s <- runIO $ startServer_ (def { serverSilent = True }) it "should load data" $ do - inserts <- liftM lines $ readFile (dir </> "tests/data/base.sql") + inserts <- fmap lines $ readFile (dir </> "tests/data/base.sql") inServer s $ mapM_ (execute_ . fromString) inserts it "should scan project" $ do void $ send s ["scan", "--project", dir </> "tests/test-package"] @@ -96,5 +97,29 @@ it "should use modified source in `check` command" $ do checks <- send s ["check", "--file", dir </> "tests/test-package/ModuleTwo.hs"] (checks ^.. traverseArray . key "note" . key "message" . _Just) `shouldSatisfy` (any ("Defined but not used" `isPrefixOf`)) + it "should get usages of symbol" $ do + -- Note, that source was modified + us <- send s ["usages", "2", "2", "--file", dir </> "tests/test-package/ModuleTwo.hs"] + let + locs :: [(String, Position)] + locs = do + n <- us ^.. traverseArray + nm <- maybeToList $ n ^. key "in" . key "name" + p <- maybeToList $ pos (n ^. key "at") + return (nm, p) + S.fromList locs `shouldBe` S.fromList [ + ("ModuleOne", Position 4 2), + ("ModuleTwo", Position 2 2), + ("ModuleTwo", Position 8 19), + ("ModuleTwo", Position 25 21), + ("ModuleTwo", Position 25 35)] + it "should get usages of local symbols" $ do + us <- send s ["usages", "14", "15", "--file", dir </> "tests/test-package/ModuleTwo.hs"] + let + locs :: [Position] + locs = do + n <- us ^.. traverseArray + maybeToList $ pos (n ^. key "at") + S.fromList locs `shouldBe` S.fromList [Position 14 7, Position 14 11, Position 14 15] _ <- runIO $ send s ["exit"] return ()