on master help sign in
Begin to consolidate Elm.Project.* into Elm.Outline and Elm.Details
commitf31fd4ab0ba937f704646546bcd19dcfb0f32725 authorEvan Czaplicki <evancz@users.noreply.github.com> dateTue 12 Feb 2019, 18:43 (8 years ago) parent8df5596
5 files changed+237−404
builder/src/Elm/Details.hs+104 builder/src/Elm/Project/Json.hs → builder/src/Elm/Outline.hs+133−121 builder/src/Elm/Project.hs−80 builder/src/Elm/Project/Root.hs−95 builder/src/Elm/Project/Summary.hs−108
builder/src/Elm/Details.hsnew file+104
@@ -0,0 +1,104 @@
1+{-# OPTIONS_GHC -Wall #-}
2+module Elm.Details
3+ ( Details(..)
4+ , ValidOutline(..)
5+ , Local(..)
6+ , Foreign(..)
7+ )
8+ where
9+
10+
11+import Control.Concurrent (forkIO)
12+import Control.Concurrent.MVar (MVar, newEmptyMVar, putMVar, readMVar)
13+import Control.Monad (liftM, liftM2, liftM3, liftM4)
14+import Data.Binary (Binary, get, put, getWord8, putWord8)
15+import qualified Data.Map as Map
16+import qualified Data.Map.Merge.Strict as Map
17+import qualified Data.Set as Set
18+import qualified Data.Utf8 as Utf8
19+import System.Directory (doesDirectoryExist)
20+import System.FilePath ((</>))
21+
22+import qualified Deps.Registry as Registry
23+import qualified Deps.Solver as Solver
24+import qualified Elm.Constraint as Con
25+import qualified Elm.Interface as I
26+import qualified Elm.ModuleName as ModuleName
27+import qualified Elm.Outline as Outline
28+import qualified Elm.Package as Pkg
29+import qualified Elm.Version as V
30+import qualified File
31+import qualified Http
32+import qualified Json.Decode as D
33+import qualified Reporting.Exit as Exit
34+import qualified Reporting.Progress as Progress
35+import qualified Reporting.Task as Task
36+import qualified Stuff
37+
38+
39+
40+-- DETAILS
41+
42+
43+data Details =
44+ Details
45+ { _outlineTime :: File.Time
46+ , _outline :: ValidOutline
47+ , _locals :: Map.Map ModuleName.Raw Local
48+ , _foreigns :: Map.Map ModuleName.Raw Foreign
49+ }
50+
51+
52+data ValidOutline
53+ = ValidApp Outline.AppOutline
54+ | ValidPkg Outline.PkgOutline (Map.Map Pkg.Name V.Version)
55+
56+
57+data Local =
58+ Local
59+ { _path :: FilePath
60+ , _time :: File.Time
61+ , _deps :: [ModuleName.Raw]
62+ }
63+
64+
65+data Foreign =
66+ Foreign Pkg.Name [Pkg.Name]
67+
68+
69+
70+-- BINARY
71+
72+
73+instance Binary Details where
74+ get = liftM4 Details get get get get
75+ put (Details a b c d) = put a >> put b >> put c >> put d
76+
77+
78+instance Binary ValidOutline where
79+ put outline =
80+ case outline of
81+ ValidApp a -> putWord8 0 >> put a
82+ ValidPkg a b -> putWord8 1 >> put a >> put b
83+
84+ get =
85+ do n <- getWord8
86+ case n of
87+ 0 -> liftM ValidApp get
88+ 1 -> liftM2 ValidPkg get get
89+ _ -> error "binary encoding of ValidOutline was corrupted"
90+
91+
92+instance Binary Local where
93+ get = liftM3 Local get get get
94+ put (Local a b c) = put a >> put b >> put c
95+
96+
97+instance Binary Foreign where
98+ get = liftM2 Foreign get get
99+ put (Foreign a b) = put a >> put b
100+
101+
102+instance Binary Artifacts where
103+ get = liftM3 Artifacts get get get
104+ put (Artifacts a b c) = put a >> put b >> put c
builder/src/Elm/Project/Json.hs → builder/src/Elm/Outline.hsrenamed+133−121
@@ -1,27 +1,25 @@
11{-# OPTIONS_GHC -Wall #-}
22{-# LANGUAGE OverloadedStrings #-}
3−module Elm.Project.Json
4− ( Project(..)
5− , AppInfo(..)
6− , PkgInfo(..)
3+module Elm.Outline
4+ ( Outline(..)
5+ , AppOutline(..)
6+ , PkgOutline(..)
77 , Exposed(..)
8− , defaultSummary
9− -- json
8+ , read
109 , write
1110 , encode
12− , read
13− , pkgDecoder
14− -- queries
11+ , decoder
12+ , defaultSummary
1513 , isPlatformPackage
1614 , getName
1715 , getExposed
18− , check
1916 )
2017 where
2118
2219
2320import Prelude hiding (read)
24−import Control.Monad.Trans (liftIO)
21+import Control.Monad (filterM, liftM)
22+import Data.Binary (Binary, get, put, getWord8, putWord8)
2523import Data.Foldable (traverse_)
2624import qualified Data.Map as Map
2725import qualified Data.Utf8 as Utf8
@@ -37,39 +35,30 @@ import qualified Json.Decode as D
3735import qualified Json.Encode as E
3836import qualified Reporting.Exit as Exit
3937import qualified Reporting.Exit.Assets as E
40−import qualified Reporting.Task as Task
41−
42−
43−
44−-- PROJECT
4538
4639
47−data Project
48− = App AppInfo
49− | Pkg PkgInfo
5040
41+-- OUTLINE
5142
5243
53−-- APPLICATION
44+data Outline
45+ = App AppOutline
46+ | Pkg PkgOutline
5447
5548
56−data AppInfo =
57− AppInfo
49+data AppOutline =
50+ AppOutline
5851 { _app_elm_version :: V.Version
5952 , _app_source_dirs :: [FilePath]
6053 , _app_deps_direct :: Map.Map Pkg.Name V.Version
61− , _app_deps_trans :: Map.Map Pkg.Name V.Version
54+ , _app_deps_indirect :: Map.Map Pkg.Name V.Version
6255 , _app_test_direct :: Map.Map Pkg.Name V.Version
63− , _app_test_trans :: Map.Map Pkg.Name V.Version
56+ , _app_test_indirect :: Map.Map Pkg.Name V.Version
6457 }
6558
6659
67−
68−-- PACKAGE
69−
70−
71−data PkgInfo =
72− PkgInfo
60+data PkgOutline =
61+ PkgOutline
7362 { _pkg_name :: Pkg.Name
7463 , _pkg_summary :: Utf8.String
7564 , _pkg_license :: Licenses.License
@@ -99,76 +88,54 @@ defaultSummary =
9988-- QUERIES
10089
10190
102−isPlatformPackage :: Project -> Bool
103−isPlatformPackage project =
104− case project of
91+isPlatformPackage :: Outline -> Bool
92+isPlatformPackage outline =
93+ case outline of
10594 App _ ->
10695 False
10796
108− Pkg info ->
109− let
110− (Pkg.Name author _) =
111− _pkg_name info
112− in
97+ Pkg pkgOutline ->
98+ let author = Pkg._author (_pkg_name pkgOutline) in
11399 author == "elm" || author == "elm-explorations"
114100
115101
116−getName :: Project -> Pkg.Name
117−getName project =
118− case project of
102+getName :: Outline -> Pkg.Name
103+getName outline =
104+ case outline of
119105 App _ ->
120106 Pkg.dummyName
121107
122− Pkg info ->
123− _pkg_name info
124−
125−
126−getExposed :: PkgInfo -> [ModuleName.Raw]
127−getExposed info =
128− case _pkg_exposed info of
129− ExposedList modules ->
130− modules
131−
132− ExposedDict chunks ->
133− concatMap snd chunks
134−
135−
136−check :: Project -> Task.Task ()
137−check project =
138− case project of
139− Pkg (PkgInfo name _ _ _ _ deps _ _) ->
140− if name == Pkg.core || Map.member Pkg.core deps
141− then return ()
142− else throwBadJson E.NoPkgCore
108+ Pkg (PkgOutline name _ _ _ _ _ _ _) ->
109+ name
143110
144− App (AppInfo _ _ direct indirect _ _) ->
145− if Map.member Pkg.core direct then
146111
147− if Map.member Pkg.json direct || Map.member Pkg.json indirect
148− then return ()
149− else throwBadJson E.NoAppJson
112+getExposed :: PkgOutline -> [ModuleName.Raw]
113+getExposed (PkgOutline _ _ _ _ exposed _ _ _) =
114+ case exposed of
115+ ExposedList names ->
116+ names
150117
151− else
152− throwBadJson E.NoAppCore
118+ ExposedDict sections ->
119+ concatMap snd sections
153120
154121
155122
156123-- WRITE
157124
158125
159−write :: FilePath -> Project -> IO ()
160−write root project =
161− E.write (root </> "elm.json") (encode project)
126+write :: FilePath -> Outline -> IO ()
127+write root outline =
128+ E.write (root </> "elm.json") (encode outline)
162129
163130
164131
165132-- JSON ENCODE
166133
167134
168−encode :: Project -> E.Value
169−encode project =
170− case project of
171− App (AppInfo elm srcDirs depsDirect depsTrans testDirect testTrans) ->
135+encode :: Outline -> E.Value
136+encode outline =
137+ case outline of
138+ App (AppOutline elm srcDirs depsDirect depsTrans testDirect testTrans) ->
172139 E.object
173140 [ "type" ==> E.string "application"
174141 , "source-directories" ==> E.list (E.string . Utf8.fromChars) srcDirs
@@ -185,10 +152,10 @@ encode project =
185152 ]
186153 ]
187154
188− Pkg (PkgInfo name summary license version exposed deps tests elm) ->
155+ Pkg (PkgOutline name summary license version exposed deps tests elm) ->
189156 E.object
190157 [ "type" ==> E.string "package"
191− , "name" ==> E.string (Pkg.toString name)
158+ , "name" ==> Pkg.encode name
192159 , "summary" ==> E.string summary
193160 , "license" ==> Licenses.encode license
194161 , "version" ==> V.encode version
@@ -228,34 +195,28 @@ encodeDeps encodeValue deps =
228195-- PARSE AND VERIFY
229196
230197
231−read :: FilePath -> Task.Task Project
232−read path =
233− do result <- liftIO $ D.fromFile decoder path
198+read :: FilePath -> IO (Either Exit.OutlineProblem Outline)
199+read root =
200+ do result <- D.fromFile decoder (root </> "elm.json")
234201 case result of
235− Right project ->
236− case project of
237− Pkg _ ->
238− do return project
239−
240− App (AppInfo _ srcDirs _ _ _ _) ->
241− do mapM_ doesDirectoryExist srcDirs
242− return project
243−
244202 Left err ->
245− throwBadJson (error "TODO bad json" err)
203+ return $ Left (Exit.BadOutlineStructure err)
246204
205+ Right outline ->
206+ case outline of
207+ Pkg _ ->
208+ return $ Right outline
247209
248−throwBadJson :: E.ElmJsonProblem -> Task.Task a
249−throwBadJson problem =
250− Task.throw (Exit.Assets (E.BadElmJson problem))
210+ App (AppOutline _ srcDirs _ _ _ _) ->
211+ do badDirs <- filterM (isBadSrcDir root) srcDirs
212+ case badDirs of
213+ [] -> return $ Right outline
214+ d:ds -> return $ Left (Exit.BadOutlineSrcDirs d ds)
251215
252216
253−doesDirectoryExist :: FilePath -> Task.Task ()
254−doesDirectoryExist dir =
255− do exists <- liftIO $ Dir.doesDirectoryExist dir
256− if exists
257− then return ()
258− else throwBadJson (E.BadSrcDir dir)
217+isBadSrcDir :: FilePath -> FilePath -> IO Bool
218+isBadSrcDir root dir =
219+ not <$> Dir.doesDirectoryExist (root </> dir)
259220
260221
261222
@@ -266,7 +227,7 @@ type Decoder a =
266227 D.Decoder E.BadElmJsonContent a
267228
268229
269−decoder :: Decoder Project
230+decoder :: Decoder Outline
270231decoder =
271232 do tipe <- D.field "type" D.string
272233 case tipe of
@@ -280,9 +241,9 @@ decoder =
280241 D.failure (E.BadType other)
281242
282243
283−appDecoder :: Decoder AppInfo
244+appDecoder :: Decoder AppOutline
284245appDecoder =
285− AppInfo
246+ AppOutline
286247 <$> D.field "elm-version" versionDecoder
287248 <*> D.field "source-directories" (D.list dirDecoder)
288249 <*> D.field "dependencies" (D.field "direct" (depsDecoder versionDecoder))
@@ -291,12 +252,12 @@ appDecoder =
291252 <*> D.field "test-dependencies" (D.field "indirect" (depsDecoder versionDecoder))
292253
293254
294−pkgDecoder :: Decoder PkgInfo
255+pkgDecoder :: Decoder PkgOutline
295256pkgDecoder =
296− PkgInfo
297− <$> D.field "name" pkgNameDecoder
257+ PkgOutline
258+ <$> D.field "name" (D.mapError E.BadPkgName Pkg.decoder)
298259 <*> D.field "summary" summaryDecoder
299− <*> D.field "license" licenseDecoder
260+ <*> D.field "license" (Licenses.decoder E.BadLicense)
300261 <*> D.field "version" versionDecoder
301262 <*> D.field "exposed-modules" exposedDecoder
302263 <*> D.field "dependencies" (depsDecoder constraintDecoder)
@@ -308,11 +269,6 @@ pkgDecoder =
308269-- JSON DECODE HELPERS
309270
310271
311−pkgNameDecoder :: Decoder Pkg.Name
312−pkgNameDecoder =
313− D.mapError E.BadPkgName Pkg.decoder
314−
315−
316272summaryDecoder :: Decoder Utf8.String
317273summaryDecoder =
318274 do summary <- D.string
@@ -321,11 +277,6 @@ summaryDecoder =
321277 else D.failure E.BadSummaryTooLong
322278
323279
324−licenseDecoder :: Decoder Licenses.License
325−licenseDecoder =
326− Licenses.decoder E.BadLicense
327−
328−
329280versionDecoder :: Decoder V.Version
330281versionDecoder =
331282 D.mapError E.BadVersion V.decoder
@@ -379,7 +330,68 @@ moduleDecoder =
379330
380331checkHeader :: Utf8.String -> Decoder ()
381332checkHeader header =
382− if Utf8.size header < 20 then
383− return ()
384− else
385− D.failure (E.BadModuleHeaderTooLong header)
333+ if Utf8.size header < 20
334+ then return ()
335+ else D.failure (E.BadModuleHeaderTooLong header)
336+
337+
338+
339+-- BINARY
340+
341+
342+instance Binary Outline where
343+ put outline =
344+ case outline of
345+ App a -> putWord8 0 >> put a
346+ Pkg a -> putWord8 1 >> put a
347+
348+ get =
349+ do n <- getWord8
350+ case n of
351+ 0 -> liftM App get
352+ 1 -> liftM Pkg get
353+ _ -> error "binary encoding of Outline was corrupted"
354+
355+
356+instance Binary AppOutline where
357+ put (AppOutline a b c d e f) =
358+ put a >> put b >> put c >> put d >> put e >> put f
359+
360+ get =
361+ do a <- get
362+ b <- get
363+ c <- get
364+ d <- get
365+ e <- get
366+ f <- get
367+ return (AppOutline a b c d e f)
368+
369+
370+instance Binary PkgOutline where
371+ put (PkgOutline a b c d e f g h) =
372+ put a >> put b >> put c >> put d >> put e >> put f >> put g >> put h
373+
374+ get =
375+ do a <- get
376+ b <- get
377+ c <- get
378+ d <- get
379+ e <- get
380+ f <- get
381+ g <- get
382+ h <- get
383+ return (PkgOutline a b c d e f g h)
384+
385+
386+instance Binary Exposed where
387+ put exposed =
388+ case exposed of
389+ ExposedList a -> putWord8 0 >> put a
390+ ExposedDict a -> putWord8 1 >> put a
391+
392+ get =
393+ do n <- getWord8
394+ case n of
395+ 0 -> liftM ExposedList get
396+ 1 -> liftM ExposedDict get
397+ _ -> error "binary encoding of ProjectDeps was corrupted"
builder/src/Elm/Project.hsdeleted−80
@@ -1,80 +0,0 @@
1−{-# OPTIONS_GHC -Wall #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−module Elm.Project
4− ( getRoot
5− , getRootWithReplFallback
6− , compile
7− , compileForRepl
8− )
9− where
10−
11−
12−import qualified Data.ByteString as BS
13−import Data.Map ((!))
14−import qualified Data.Name as Name
15−
16−import qualified Elm.Compiler as Compiler
17−import qualified Elm.Project.Json as Project
18−import qualified Elm.Project.Root as Root
19−import qualified Elm.Project.Summary as Summary
20−import Elm.Project.Summary (Summary)
21−import qualified File.Args as Args
22−import qualified File.Compile as Compile
23−import qualified File.Crawl as Crawl
24−import qualified File.Plan as Plan
25−import qualified Generate.Artifacts as Artifacts
26−import qualified Generate.Output as Output
27−import qualified Reporting.Render.Type.Localizer as L
28−import qualified Reporting.Task as Task
29−
30−
31−
32−-- GET ROOT
33−
34−
35−getRoot :: Task.Task Summary
36−getRoot =
37− Root.get
38−
39−
40−getRootWithReplFallback :: IO FilePath
41−getRootWithReplFallback =
42− Root.getWithReplFallback
43−
44−
45−
46−-- COMPILE
47−
48−
49−compile
50− :: Output.Mode
51− -> Output.Target
52− -> Maybe Output.Output
53− -> Summary
54− -> [FilePath]
55− -> Task.Task ()
56−compile mode target maybeOutput summary@(Summary.Summary root project _ _ _) paths =
57− do Project.check project
58− args <- Args.fromPaths summary paths
59− graph <- Crawl.crawl summary args
60− (dirty, ifaces) <- Plan.plan summary graph
61− answers <- Compile.compile project ifaces dirty
62− results <- Artifacts.write root answers
63− -- _ <- traverse (Artifacts.writeDocs results) docs
64− Output.generate mode target maybeOutput summary graph results
65−
66−
67−
68−-- COMPILE FOR REPL
69−
70−
71−compileForRepl :: Bool -> L.Localizer -> BS.ByteString -> Maybe Name.Name -> Task.Task (Maybe FilePath)
72−compileForRepl noColors localizer source maybeName =
73− do summary@(Summary.Summary root project _ _ _) <- getRoot
74− Project.check project
75− graph <- Crawl.crawlFromSource summary source
76− (dirty, ifaces) <- Plan.plan summary graph
77− answers <- Compile.compile project ifaces dirty
78− results <- Artifacts.write root answers
79− let (Compiler.Artifacts elmi _) = results ! Name.replModule
80− traverse (Output.generateReplFile noColors localizer summary graph elmi) maybeName
builder/src/Elm/Project/Root.hsdeleted−95
@@ -1,95 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−module Elm.Project.Root
3− ( get
4− , unsafeGet
5− , getWithReplFallback
6− )
7− where
8−
9−
10−import Control.Monad.Trans (liftIO)
11−import qualified Data.Map as Map
12−import qualified System.Directory as Dir
13−import System.FilePath ((</>))
14−
15−import qualified Elm.Constraint as Con
16−import qualified Elm.Licenses as Licenses
17−import qualified Elm.Package as Pkg
18−import qualified Elm.Project.Json as Project
19−import qualified Elm.Project.Summary as Summary
20−import qualified Elm.PerUserCache as PerUserCache
21−import qualified Elm.Version as V
22−import qualified File.IO as IO
23−import qualified Reporting.Exit as Exit
24−import qualified Reporting.Task as Task
25−import qualified Stuff.Verify as Verify
26−import qualified Json.Encode as Encode
27−
28−
29−
30−-- GET
31−
32−
33−get :: Task.Task Summary.Summary
34−get =
35− do root <- moveToRoot
36− project <- Project.read "elm.json"
37− Verify.verify root project
38−
39−
40−unsafeGet :: Task.Task (FilePath, Project.Project)
41−unsafeGet =
42− (,) <$> moveToRoot <*> Project.read "elm.json"
43−
44−
45−
46−-- MOVE TO ROOT
47−
48−
49−moveToRoot :: Task.Task FilePath
50−moveToRoot =
51− do maybeRoot <- liftIO $ IO.find "elm.json"
52− case maybeRoot of
53− Just root ->
54− do liftIO $ Dir.setCurrentDirectory root
55− return root
56−
57− Nothing ->
58− Task.throw Exit.NoElmJson
59−
60−
61−
62−-- GET WITH FALLBACK
63−
64−
65−getWithReplFallback :: IO FilePath
66−getWithReplFallback =
67− do maybeRoot <- IO.find "elm.json"
68−
69− case maybeRoot of
70− Just root ->
71− do Dir.setCurrentDirectory root
72− return root
73−
74− Nothing ->
75− do cache <- PerUserCache.getReplRoot
76− let root = cache </> "tmp"
77− Dir.createDirectoryIfMissing True root
78− Dir.setCurrentDirectory root
79− IO.removeDir "elm-stuff"
80− Encode.write "elm.json" (Project.encode (Project.Pkg replInfo))
81− return root
82−
83−
84−replInfo :: Project.PkgInfo
85−replInfo =
86− Project.PkgInfo
87− { Project._pkg_name = Pkg.dummyName
88− , Project._pkg_summary = "dummy code for the REPL"
89− , Project._pkg_license = Licenses.bsd3
90− , Project._pkg_version = V.one
91− , Project._pkg_exposed = Project.ExposedList []
92− , Project._pkg_deps = Map.singleton Pkg.core Con.anything
93− , Project._pkg_test_deps = Map.empty
94− , Project._pkg_elm_version = Con.defaultElm
95− }
builder/src/Elm/Project/Summary.hsdeleted−108
@@ -1,108 +0,0 @@
1−{-# OPTIONS_GHC -Wall #-}
2−module Elm.Project.Summary
3− ( Summary(..)
4− , ExposedModules
5− , DepsGraph
6− , init
7− , cheapInit
8− )
9− where
10−
11−
12−import Prelude hiding (init)
13−import qualified Data.List as List
14−import qualified Data.Map as Map
15−
16−import qualified Elm.Interface as I
17−import qualified Elm.ModuleName as ModuleName
18−import qualified Elm.Package as Pkg
19−import qualified Elm.Version as V
20−import Elm.Project.Json (Project(..), AppInfo(..), PkgInfo(..))
21−import qualified Elm.Project.Json as Project
22−
23−
24−
25−-- SUMMARY
26−
27−
28−data Summary =
29− Summary
30− { _root :: FilePath
31− , _project :: Project
32− , _exposed :: ExposedModules
33− , _ifaces :: I.Interfaces
34− , _depsGraph :: DepsGraph
35− }
36−
37−
38−type ExposedModules =
39− Map.Map ModuleName.Raw [Pkg.Canonical]
40−
41−
42−type DepsGraph =
43− Map.Map Pkg.Name ( V.Version, [Pkg.Name] )
44−
45−
46−
47−-- MAKE SUMMARY
48−
49−
50−init :: FilePath -> Project -> Map.Map Pkg.Name PkgInfo -> I.Interfaces -> Summary
51−init root project deps ifaces =
52− let
53− exposed =
54− case project of
55− Project.App info ->
56− getExposed deps (_app_deps_direct info)
57−
58− Project.Pkg info ->
59− getExposed deps (_pkg_deps info)
60−
61− privatizedInterfaces =
62− Map.mapMaybeWithKey (privatize exposed) ifaces
63−
64− depsGraph =
65− Map.foldr toNode Map.empty deps
66− in
67− Summary root project exposed privatizedInterfaces depsGraph
68−
69−
70−privatize :: ExposedModules -> ModuleName.Canonical -> I.Interface -> Maybe I.Interface
71−privatize exposed (ModuleName.Canonical _ name) iface =
72− case Map.lookup name exposed of
73− Just [_] ->
74− Just iface
75−
76− _ ->
77− Nothing
78−
79−
80−toNode :: PkgInfo -> DepsGraph -> DepsGraph
81−toNode (PkgInfo name _ _ version _ deps _ _) graph =
82− Map.insert name (version, Map.keys deps) graph
83−
84−
85−
86−-- MAKE CHEAP SUMMARY
87−
88−
89−cheapInit :: FilePath -> PkgInfo -> Map.Map Pkg.Name PkgInfo -> I.Interfaces -> Summary
90−cheapInit root info deps ifaces =
91− Summary root (Pkg info) (getExposed deps (_pkg_deps info)) ifaces Map.empty
92−
93−
94−getExposed :: Map.Map Pkg.Name PkgInfo -> Map.Map Pkg.Name a -> ExposedModules
95−getExposed deps directs =
96− Map.foldl insertExposed Map.empty (Map.intersection deps directs)
97−
98−
99−insertExposed :: ExposedModules -> PkgInfo -> ExposedModules
100−insertExposed exposed info =
101− let
102− home =
103− Pkg.Canonical (_pkg_name info) (_pkg_version info)
104−
105− insertModule dict modul =
106− Map.insertWith (++) modul [home] dict
107− in
108− List.foldl' insertModule exposed (Project.getExposed info)