ide-backend-0.10.0: An IDE backend library

Safe HaskellNone
LanguageHaskell2010

IdeSession.Update

Contents

Description

IDE session updates

We should only be using internal types here (explicit strictness/sharing)

Synopsis

Starting and stopping

initSession :: SessionInitParams -> SessionConfig -> IO IdeSession Source

Create a fresh session, using some initial configuration.

Throws an exception if the configuration is invalid, or if GHC_PACKAGE_PATH is set.

data SessionInitParams Source

How should the session be initialized?

Client code should use defaultSessionInitParams to protect itself against future extensions of this record.

Constructors

SessionInitParams 

Fields

sessionInitCabalMacros :: Maybe ByteString

Previously computed cabal macros, or Nothing to compute them on startup

sessionInitGhcOptions :: [String]

Initial ghc options

sessionInitRelativeIncludes :: [FilePath]

Include paths (equivalent of GHC's -i parameter) relative to the temporary directory where we store the session's source files.

By default this is the singleton list [""] -- i.e., we include the sources dir but nothing else.

sessionInitTargets :: Targets

Targets for compilation

Defaults to TargetsExclude [] -- i.e., compile all modules in the project.

sessionInitRtsOpts :: [String]

RTS options

Defaults to -K8M

sessionInitDistDir :: !(Maybe FilePath)

dist/ directory.

shutdownSession :: IdeSession -> IO () Source

Close a session down, releasing the resources.

This operation is the only one that can be run after a shutdown was already performed. This lets the API user execute an early shutdown, e.g., before the shutdownSession placed inside bracket is triggered by a normal program control flow.

If code is still running, it will be interrupted.

forceShutdownSession :: IdeSession -> IO () Source

Like shutdownSession, but don't be nice about it (SIGKILL)

restartSession :: IdeSession -> IO () Source

Restart a session

This puts the session in a "dead" state; it won't _actually_ be restarted until the next call to updateSession.

Session updates

data IdeSessionUpdate Source

Declarative description of session updates

IdeSessionUpdate forms a monoid, which is right-biased: "later" calls override "earlier" ones:

updateTargets targets1 <> updateTargets2

is equivalent to

updateTargets2

However, updates of a different nature are not necessarily executed in order; for instance,

updateDynamicOpts opts <> updateSourceFile fp bs

is equivalent to

updateSourceFile fp bs <> updateDynamicOpts opts

In both cases options are set before new source files are compiled.

File commands are updated in order, so that

updateSourceFile fp bs <> updateSourceFile fp bs'

is equivalent to

updateSourceFile fp bs'

which is consistent with "later updates override earlier ones".

updateSession :: IdeSession -> IdeSessionUpdate -> (UpdateStatus -> IO ()) -> IO () Source

Given the current IDE session state, go ahead and update the session, eventually resulting in a new session state, with fully updated computed information (typing, etc.).

The update can be a long running operation, so we support a callback which can be used to monitor progress of the operation.

updateSourceFile :: FilePath -> ByteString -> IdeSessionUpdate Source

A session update that changes a source file by providing some contents. This can be used to add a new module or update an existing one. The FilePath argument determines the directory and file where the module is located within the project. In case of Haskell source files, the actual internal compiler module name, such as the one given by the getLoadedModules query, comes from within module ... end. Usually the two names are equal, but they needn't be.

updateSourceFileFromFile :: FilePath -> IdeSessionUpdate Source

Like updateSourceFile except that instead of passing the source by value, it's given by reference to an existing file, which will be copied.

updateSourceFileDelete :: FilePath -> IdeSessionUpdate Source

A session update that deletes an existing source file.

updateGhcOpts :: [String] -> IdeSessionUpdate Source

Set ghc options

This function is stateless: the set of actions options is the set provided by the last call to updateGhcOptions.

updateRtsOpts :: [String] -> IdeSessionUpdate Source

Set RTS options for the ghc session (this does not affect executables)

This will cause a session restart.

NOTE: Limiting stack size does not seem to work for ghc 7.4 (https:/github.comfpcoide-backendissues/258).

updateRelativeIncludes :: [FilePath] -> IdeSessionUpdate Source

Set include paths (equivalent of GHC's -i parameter). In general, this requires session restart, because GHC doesn't revise module dependencies when targets or include paths change, but only when files change.

This function is stateless: semantically, the set of currently active include paths are those set in the last call to updateRelativeIncludes. Any paths set earlier (including those from configRelativeIncludes) are wiped out and overwritten in each call to updateRelativeIncludes.

updateCodeGeneration :: Bool -> IdeSessionUpdate Source

Enable or disable code generation in addition to type-checking. Required by runStmt.

updateDataFile :: FilePath -> ByteString -> IdeSessionUpdate Source

A session update that changes a data file by giving a new value for the file. This can be used to add a new file or update an existing one.

updateDataFileFromFile :: FilePath -> FilePath -> IdeSessionUpdate Source

Like updateDataFile except that instead of passing the file content by value, it's given by reference to an existing file (the second argument), which will be copied.

updateDataFileDelete :: FilePath -> IdeSessionUpdate Source

Deletes an existing data file.

updateDeleteManagedFiles :: IdeSessionUpdate Source

Delete all files currently managed in this session

updateEnv :: [(String, Maybe String)] -> IdeSessionUpdate Source

Set environment variables

Use updateEnv [(var, Nothing)] to unset var.

Note that this is intended to be stateless:

updateEnv []

will reset the environment to the server's original environment.

updateArgs :: [String] -> IdeSessionUpdate Source

Set command line arguments for snippets (i.e., the expected value of getArgs)

updateStdoutBufferMode :: RunBufferMode -> IdeSessionUpdate Source

Set buffering mode for snippets' stdout

updateStderrBufferMode :: RunBufferMode -> IdeSessionUpdate Source

Set buffering mode for snippets' stderr

updateTargets :: Targets -> IdeSessionUpdate Source

Set compilation targets. In general, this requires session restart, because GHC doesn't revise module dependencies when targets or include paths change, but only when files change.

buildExe :: [String] -> [(ModuleName, FilePath)] -> IdeSessionUpdate Source

Build an exe from sources added previously via the ide-backend updateSourceFile* mechanism. The modules that contains the main code are indicated in second argument to buildExe. The function can be called multiple times with different arguments. Additional GHC options, applied only when building executables, are supplied in the first argument.

We assume any indicated module is already successfully processed by GHC API in a compilation mode that makes computedImports available (but no code needs to be generated). The environment (package dependencies, ghc options, preprocessor program options, etc.) for building the exe is the same as when previously compiling the code via GHC API. The module does not have to be called Main, but we assume the main function is always main (we don't check this and related conditions, but GHC does when eventually called to build the exe).

The executable files are placed in the filesystem inside the build subdirectory of getDistDir, in subdirectories corresponding to the given module names. The build directory does not overlap with any of the other used directories and with its path.

Logs from the building process are saved in files build/ide-backend-exe.stdout and build/ide-backend-exe.stderr in the getDistDir directory.

Note: currently it requires configGenerateModInfo to be set (see #86). Also, after session restart, one has to call updateSession at least once (even with empty updates list) before calling it for buildExe. This ensures the code is compiled again and the results made accessible.

buildDoc :: IdeSessionUpdate Source

Build haddock documentation from sources added previously via the ide-backend updateSourceFile* mechanism. Similarly to buildExe, it needs the project modules to be already loaded within the session and the generated docs can be found in the doc subdirectory of getDistDir.

Logs from the documentation building process are saved in files doc/ide-backend-doc.stdout and doc/ide-backend-doc.stderr in the getDistDir directory.

Note: currently it requires configGenerateModInfo to be set (see #86).

buildLicenses :: FilePath -> IdeSessionUpdate Source

Build a file containing licenses of all used packages. Similarly to buildExe, the function needs the project modules to be already loaded within the session. The concatenated licenses can be found in file licenses.txt inside the getDistDir directory.

The function expects .cabal files of all used packages, except those mentioned in configLicenseExc, to be gathered in the directory given as the first argument (which needs to be an absolute path or a path relative to the data dir). The code then expects to find those packages installed and their license files in the usual place that Cabal puts them (or the in-place packages should be correctly embedded in the GHC tree).

We guess the installed locations of the license files on the basis of the haddock interfaces path. If the default setting does not work properly, the haddock interfaces path should be set manually. E.g., cabal configure --docdir=the_same_path --htmldir=the_same_path affects the haddock interfaces path (because it is by default based on htmldir) and is reported to work for some values of the_same_path.

Logs from the license search and catenation process are saved in files licenses.stdout and licenses.stderr in the getDistDir directory.

Note: currently configGenerateModInfo needs to be set for this function to work (see #86).

Note: if the executable uses TH and its module is named Main (and so it's not compiled as a part of a temporary library) configDynLink needs to be set. See #162.

Running code

runStmt :: IdeSession -> String -> String -> IO (RunActions RunResult) Source

Run a given function in a given module (the name of the module is the one between module ... end, which may differ from the file name). The function resembles a query, but it's not instantaneous and the running code can be interrupted or interacted with.

runStmt will throw an exception if the code has not been compiled yet, or when the server is in a dead state (i.e., when ghc has crashed). In the latter case getSourceErrors will report the ghc exception; it is the responsibility of the client code to check for this.

runStmtPty :: IdeSession -> String -> String -> IO (RunActions RunResult) Source

Like runStmt, but runs the statement in a pseudoterminal.

runExe :: IdeSession -> String -> IO (RunActions ExitCode) Source

Run the main function from the last compiled executable.

runExe will throw an exception if there were no executables compiled since session init, or if the last compilation was not successful (checked as in getBuildExeStatus) or if none of the executables last compiled have the supplied name or when the server is in a dead state (i.e., when ghc has crashed). In the last case getSourceErrors will report the ghc exception; it is the responsibility of the client code to check for this.

resume :: IdeSession -> IO (RunActions RunResult) Source

Resume a previously interrupted statement

setBreakpoint Source

Arguments

:: IdeSession 
-> ModuleName

Module where the breakshould should be set

-> SourceSpan

Location of the breakpoint

-> Bool

New value for the breakpoint

-> IO (Maybe Bool)

Old value of the breakpoint (if valid)

Breakpoint

Set a breakpoint at the specified location. Returns Just the old value of the breakpoint if successful, or Nothing otherwise.

printVar Source

Arguments

:: IdeSession 
-> Name

Variable to print

-> Bool

Should printing bind new vars? (:print vs. :sprint)

-> Bool

Should the value be forced? (:print vs. :force)

-> IO VariableEnv 

Print and/or force values during debugging

Only valid in breakpoint state.

Debugging

crashGhcServer :: IdeSession -> Maybe Int -> IO () Source

Crash the GHC server. For debugging only. If the specified delay is Nothing, crash immediately; otherwise, set up a thread that throws an exception to the main thread after the delay.

buildLicsFromPkgs :: Bool -> LicenseArgs -> IO ExitCode Source

Build the concatenation of all license files from a given list of packages. See buildLicenses.

data LicenseArgs Source

Constructors

LicenseArgs 

Fields

liPackageDBStack :: PackageDBStack

3 fields from session configuration

liExtraPathDirs :: [FilePath]
 
liLicenseExc :: [String]
 
liDistDir :: FilePath

the working directory; the resulting file is written there

liStdoutLog :: FilePath
 
liStderrLog :: FilePath
 
licenseFixed :: [(String, (Maybe License, Maybe FilePath, Maybe String))]

see configLicenseFixed

liCabalsDir :: FilePath

the directory with all the .cabal files

liPkgs :: [PackageId]

the list of packages to process

Instances