1-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2-- SPDX-License-Identifier: Apache-2.0
4{-# OPTIONS_GHC -Wno-missing-fields #-} -- to enable prettyPrint
6-- | GHC utility functions. Importantly, code using our GHC should never:
8-- * Call runGhc, use runGhcFast instead. It's faster and doesn't require config we don't have.
10-- * Call setSessionDynFlags, use modifyDynFlags instead. It's faster and avoids loading packages.
11module Development.IDE.UtilGHC(
12 PackageDynFlags(..), setPackageDynFlags, getPackageDynFlags,
24import GHC hiding (convertLit)
26import GhcPlugins as GHC hiding (fst3, (<>))
28import qualified Packages
30import qualified EnumSet
32import GHC.Generics (Generic)
34----------------------------------------------------------------------
37setPackageDbs :: [FilePath] -> DynFlags -> DynFlags
38setPackageDbs paths dflags =
41 [PackageDB $ PkgConfFile path | path <- paths] ++ [NoGlobalPackageDB, ClearPackageDBs]
42 , pkgDatabase = if null paths then Just [] else Nothing
43 -- if we don't load any packages set the package database to empty and loaded.
44 , settings = (settings dflags)
45 {sTopDir = case paths of p:_ -> p; _ -> error "No package db path available but used $topdir"
46 , sSystemPackageConfig = case paths of p:_ -> p; _ -> error "No package db path available but used system package config"
50setPackageImports :: Bool -> [(String, ModRenaming)] -> DynFlags -> DynFlags
51setPackageImports hideAllPkgs pkgImports dflags = dflags {
52 packageFlags = packageFlags dflags ++
53 [ExposePackage pkgName (UnitIdArg $ stringToUnitId pkgName) renaming
54 | (pkgName, renaming) <- pkgImports
56 , generalFlags = if hideAllPkgs
57 then Opt_HideAllPackages `EnumSet.insert` generalFlags dflags
58 else generalFlags dflags
61modifyDynFlags :: GhcMonad m => (DynFlags -> DynFlags) -> m ()
63 newFlags <- f <$> getSessionDynFlags
64 -- We do not use setSessionDynFlags here since we handle package
65 -- initialization separately.
67 h { hsc_dflags = newFlags, hsc_IC = (hsc_IC h) {ic_dflags = newFlags} }
69-- | The subset of @DynFlags@ computed by package initialization.
70data PackageDynFlags = PackageDynFlags
71 { pdfPkgDatabase :: !(Maybe [(FilePath, [Packages.PackageConfig])])
72 , pdfPkgState :: !Packages.PackageState
73 , pdfThisUnitIdInsts :: !(Maybe [(ModuleName, Module)])
76setPackageDynFlags :: PackageDynFlags -> DynFlags -> DynFlags
77setPackageDynFlags PackageDynFlags{..} dflags = dflags
78 { pkgDatabase = pdfPkgDatabase
79 , pkgState = pdfPkgState
80 , thisUnitIdInsts_ = pdfThisUnitIdInsts
83getPackageDynFlags :: DynFlags -> PackageDynFlags
84getPackageDynFlags DynFlags{..} = PackageDynFlags
85 { pdfPkgDatabase = pkgDatabase
86 , pdfPkgState = pkgState
87 , pdfThisUnitIdInsts = thisUnitIdInsts_
90lookupPackageConfig :: UnitId -> PackageDynFlags -> Maybe PackageConfig
91lookupPackageConfig unitId PackageDynFlags {..} =
92 lookupPackage' False pkgConfigMap unitId
95 -- For some weird reason, the GHC API does not provide a way to get the PackageConfigMap
96 -- from PackageState so we have to wrap it in DynFlags first.
97 getPackageConfigMap fakeDynFlags { pkgState = pdfPkgState }
101prettyPrint :: Outputable a => a -> String
102prettyPrint = showSDoc fakeDynFlags . ppr
104-- | Like 'runGhc' but much faster (400x), with less IO and no file dependency
105runGhcFast :: Ghc a -> IO a
106-- copied from GHC with the nasty bits dropped
108 ref <- newIORef (error "empty session")
109 let session = Session ref
110 flip unGhc session $ do
111 dflags <- liftIO $ initDynFlags fakeDynFlags
112 liftIO $ setUnsafeGlobalDynFlags dflags
113 env <- liftIO $ newHscEnv dflags
115 withCleanupSession act
117-- Fake DynFlags which are mostly undefined, but define enough to do a little bit
118fakeDynFlags :: DynFlags
119fakeDynFlags = defaultDynFlags settings ([], [])
122 {sTargetPlatform = Platform
123 {platformWordSize = 8
124 ,platformOS = OSUnknown
125 ,platformUnregisterised = True
127 ,sPlatformConstants = PlatformConstants
128 {pc_DYNAMIC_BY_DEFAULT = False
131 ,sProjectVersion = cProjectVersion
132 ,sProgramName = "ghc"
133 ,sOpt_P_fingerprint = fingerprint0
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list