@@ -18,17 +18,23 @@ import Control.DeepSeq (force)
18
18
import Control.Exception (evaluate , mask , throwIO )
19
19
import Control.Monad.Extra (eitherM , join , mapMaybeM )
20
20
import Data.Either (fromRight )
21
+ import qualified Data.Map as Map
21
22
import Data.Set (Set )
22
23
import qualified Data.Set as Set
24
+ import qualified Data.Text as T
23
25
import Data.Unique (Unique )
24
26
import qualified Data.Unique as Unique
25
- import Development.IDE.Core.Shake (ShakeExtras )
27
+ import Development.IDE.Core.Compile (indexHieFile , loadHieFile )
28
+ import Development.IDE.Core.Shake (ShakeExtras (ideNc , logger ), mkUpdater )
26
29
import Development.IDE.GHC.Compat
27
30
import qualified Development.IDE.GHC.Compat.Util as Maybes
28
31
import Development.IDE.GHC.Error (catchSrcErrors )
29
32
import Development.IDE.GHC.Util (lookupPackageConfig )
30
33
import Development.IDE.Graph.Classes
31
34
import Development.IDE.Types.Exports (ExportsMap , createExportsMap )
35
+ import Development.IDE.Types.Location (toNormalizedFilePath' )
36
+ import qualified Development.IDE.Types.Logger as Logger
37
+ import HieDb (SourceFile (FakeFile ))
32
38
import OpenTelemetry.Eventlog (withSpan )
33
39
import System.Directory (makeAbsolute )
34
40
import System.FilePath
@@ -71,6 +77,10 @@ newHscEnvEq cradlePath se hscEnv0 deps = do
71
77
72
78
newHscEnvEqWithImportPaths (Just $ Set. fromList importPathsCanon) se hscEnv deps
73
79
80
+ newtype UnitInfoOrd = UnitInfoOrd UnitInfo deriving Eq
81
+ instance Ord UnitInfoOrd where
82
+ compare (UnitInfoOrd u1) (UnitInfoOrd u2) = compare (unitId u1) (unitId u2)
83
+
74
84
newHscEnvEqWithImportPaths :: Maybe (Set FilePath ) -> ShakeExtras -> HscEnv -> [(UnitId , DynFlags )] -> IO HscEnvEq
75
85
newHscEnvEqWithImportPaths envImportPaths se hscEnv deps = do
76
86
@@ -83,25 +93,70 @@ newHscEnvEqWithImportPaths envImportPaths se hscEnv deps = do
83
93
-- compute the package imports
84
94
let pkgst = unitState hscEnv
85
95
depends = explicitUnits pkgst
86
- modules =
87
- [ m
88
- | d <- depends
89
- , Just pkg <- [lookupPackageConfig d hscEnv]
90
- , (modName, maybeOtherPkgMod) <- unitExposedModules pkg
91
- , let m = case maybeOtherPkgMod of
92
- -- When module is re-exported from another package,
93
- -- the origin module is represented by value in Just
94
- Just otherPkgMod -> otherPkgMod
95
- Nothing -> mkModule (unitInfoId pkg) modName
96
- ]
97
-
98
- doOne m = do
96
+ packages = [ pkg
97
+ | d <- depends
98
+ , Just pkg <- [lookupPackageConfig d hscEnv]
99
+ ]
100
+ modules = Map. fromSet
101
+ (\ (UnitInfoOrd pkg) ->
102
+ [ m
103
+ | (modName, maybeOtherPkgMod) <- unitExposedModules pkg
104
+ , let m = case maybeOtherPkgMod of
105
+ -- When module is re-exported from another package,
106
+ -- the origin module is represented by value in Just
107
+ Just otherPkgMod -> otherPkgMod
108
+ Nothing -> mkModule (unitInfoId pkg) modName
109
+ ]
110
+ )
111
+ (Set. fromList $ map UnitInfoOrd packages)
112
+
113
+ logPackage :: UnitInfo -> IO ()
114
+ logPackage pkg = Logger. logDebug (logger se) $ " \n\n\n !!!!!!!!!!!! hscEnvEq :\n "
115
+ <> T. pack (concatMap show $ unitLibraryDirs pkg)
116
+ <> " \n !!!!!!!!!!!!!!!!!!!!!!\n\n\n "
117
+ doOnePackage :: UnitInfoOrd -> [Module ] -> IO [ModIface ]
118
+ doOnePackage (UnitInfoOrd pkg) ms = do
119
+ let pkgLibDir :: FilePath
120
+ pkgLibDir = case unitLibraryDirs pkg of
121
+ [] -> " "
122
+ (libraryDir : _) -> libraryDir
123
+ hieDir :: FilePath
124
+ hieDir = pkgLibDir </> " extra-compliation-artifacts"
125
+ logPackage pkg
126
+ mapMaybeM (doOne hieDir) ms
127
+
128
+ doOne :: FilePath -> Module -> IO (Maybe ModIface )
129
+ doOne hieDir m = do
130
+ let toFilePath :: ModuleName -> FilePath
131
+ toFilePath = separateDirectories . prettyModuleName
132
+ where
133
+ separateDirectories :: FilePath -> FilePath
134
+ separateDirectories moduleNameString =
135
+ case breakOnDot moduleNameString of
136
+ [] -> " "
137
+ ms -> foldr1 (</>) ms
138
+ breakOnDot :: FilePath -> [FilePath ]
139
+ breakOnDot = words . map replaceDotWithSpace
140
+ replaceDotWithSpace :: Char -> Char
141
+ replaceDotWithSpace ' .' = ' '
142
+ replaceDotWithSpace c = c
143
+ prettyModuleName :: ModuleName -> String
144
+ prettyModuleName = filter (/= ' "' )
145
+ . concat
146
+ . drop 1
147
+ . words
148
+ . show
149
+ hiePath :: FilePath
150
+ hiePath = hieDir </> toFilePath (moduleName m) ++ " .hie"
99
151
modIface <- initIfaceLoad hscEnv $
100
152
loadInterface " " m (ImportByUser NotBoot )
101
- return $ case modIface of
102
- Maybes. Failed _r -> Nothing
103
- Maybes. Succeeded mi -> Just mi
104
- modIfaces <- mapMaybeM doOne modules
153
+ case modIface of
154
+ Maybes. Failed _r -> return Nothing
155
+ Maybes. Succeeded mi -> do
156
+ hie <- loadHieFile (mkUpdater $ ideNc se) hiePath
157
+ indexHieFile se (toNormalizedFilePath' hiePath) (FakeFile Nothing ) (mi_src_hash mi) hie
158
+ return $ Just mi
159
+ modIfaces <- concat . Map. elems <$> Map. traverseWithKey doOnePackage modules
105
160
return $ createExportsMap modIfaces
106
161
107
162
-- similar to envPackageExports, evaluated lazily
0 commit comments