@@ -19,20 +19,15 @@
19module Language.PureScript.Ide.State
19module Language.PureScript.Ide.State
20 ( getLoadedModulenames
20 ( getLoadedModulenames
21 , getExternFiles
21 , getExternFiles
23 , resetIdeState
22 , resetIdeState
24 , cacheRebuild
23 , cacheRebuild
25 , insertExterns
24 , insertExterns
26 , insertModule
25 , insertModule
28 , insertExternsSTM
26 , insertExternsSTM
29− , getAllModules2
27+ , getAllModules
34 , populateStage2
28 , populateStage2
35− , populateStage2STM
29+ , populateStage3
38import Protolude
33import Protolude
@@ -44,6 +39,7 @@ import qualified Data.Map.Lazy as M
44import Language.PureScript.Externs
39import Language.PureScript.Externs
45import Language.PureScript.Ide.Externs
40import Language.PureScript.Ide.Externs
46import Language.PureScript.Ide.Reexports
41import Language.PureScript.Ide.Reexports
42+import Language.PureScript.Ide.SourceFile
47import Language.PureScript.Ide.Types
43import Language.PureScript.Ide.Types
48import Language.PureScript.Ide.Util
44import Language.PureScript.Ide.Util
49import qualified Language.PureScript as P
45import qualified Language.PureScript as P
@@ -53,12 +49,10 @@ import System.FilePath
53-- | Resets all State inside psc-ide
49-- | Resets all State inside psc-ide
54resetIdeState :: Ide m => m ()
50resetIdeState :: Ide m => m ()
55resetIdeState = do
51resetIdeState = do
56− stateVar <- envStateVar <$> ask
57 ideVar <- ideStateVar <$> ask
52 ideVar <- ideStateVar <$> ask
58 liftIO . atomically $ do
53 liftIO . atomically $ do
59− writeTVar stateVar emptyPscIdeState
60 writeTVar ideVar emptyIdeState
54 writeTVar ideVar emptyIdeState
61− setStage2STM ideVar emptyStage2
55+ setStage3STM ideVar emptyStage3
63-- | Gets the loaded Modulenames
57-- | Gets the loaded Modulenames
64getLoadedModulenames :: Ide m => m [P.ModuleName]
58getLoadedModulenames :: Ide m => m [P.ModuleName]
@@ -68,26 +62,6 @@ getLoadedModulenames = M.keys <$> getExternFiles
68getExternFiles :: Ide m => m (M.Map P.ModuleName ExternsFile)
62getExternFiles :: Ide m => m (M.Map P.ModuleName ExternsFile)
69getExternFiles = s1Externs <$> getStage1
63getExternFiles = s1Externs <$> getStage1
71−-- | Inserts an @ExternsFile@ into the PscIdeState. Also converts the
72−-- ExternsFile into psc-ide's internal Declaration format
73−-- TODO: should be removed when the "old" Declaration format gets removed
74−insertModuleOld :: Ide m => ExternsFile -> m ()
75−insertModuleOld externsFile = do
76− stateVar <- envStateVar <$> ask
77− liftIO . atomically $ insertModuleOldSTM stateVar externsFile
79−-- | STM version of insertModuleOld
80−insertModuleOldSTM :: TVar PscIdeState -> ExternsFile -> STM ()
81−insertModuleOldSTM st ef = modifyTVar st (insertModule' ef)
83−-- | Pure version of insertModuleOld
84−insertModule' :: ExternsFile -> PscIdeState -> PscIdeState
85−insertModule' ef state =
87− { pscIdeStateModules = let (mn, decls) = convertExterns ef
88− in M.insert mn decls (pscIdeStateModules state)
91-- | Insert a Module into Stage1 of the State
65-- | Insert a Module into Stage1 of the State
92insertModule :: Ide m => (FilePath, P.Module) -> m ()
66insertModule :: Ide m => (FilePath, P.Module) -> m ()
93insertModule module' = do
67insertModule module' = do
@@ -106,7 +80,6 @@ insertModuleSTM ref (fp, module') =
107-- | Retrieves Stage1 from the State.
81-- | Retrieves Stage1 from the State.
108-- This includes loaded Externfiles
82-- This includes loaded Externfiles
109−-- (TODO: as soon as we actually parse the modules) aswell as the parsed modules
110getStage1 :: Ide m => m Stage1
83getStage1 :: Ide m => m Stage1
111getStage1 = do
84getStage1 = do
112 st <- ideStateVar <$> ask
85 st <- ideStateVar <$> ask
@@ -116,27 +89,14 @@ getStage1 = do
116getStage1STM :: TVar IdeState -> STM Stage1
89getStage1STM :: TVar IdeState -> STM Stage1
117getStage1STM ref = ideStage1 <$> readTVar ref
90getStage1STM ref = ideStage1 <$> readTVar ref
119−-- | Sets Stage1 inside the compiler
120−setStage1 :: Ide m => Stage1 -> m ()
122− st <- ideStateVar <$> ask
123− liftIO . atomically . modifyTVar st $ \x ->
127−-- TODO: Soon to be Stage3
128-- | Retrieves Stage2 from the State.
92-- | Retrieves Stage2 from the State.
129−-- This includes the denormalized Declarations and cached rebuilds
130getStage2 :: Ide m => m Stage2
93getStage2 :: Ide m => m Stage2
131getStage2 = do
94getStage2 = do
132 st <- ideStateVar <$> ask
95 st <- ideStateVar <$> ask
133− fmap ideStage2 . liftIO . readTVarIO $ st
96+ liftIO (atomically (getStage2STM st))
135−-- | Sets Stage2 inside the compiler
98+getStage2STM :: TVar IdeState -> STM Stage2
136−setStage2 :: Ide m => Stage2 -> m ()
99+getStage2STM ref = ideStage2 <$> readTVar ref
138− st <- ideStateVar <$> ask
139− liftIO . atomically $ setStage2STM st s2
141-- | STM version of setStage2
101-- | STM version of setStage2
142setStage2STM :: TVar IdeState -> Stage2 -> STM ()
102setStage2STM :: TVar IdeState -> Stage2 -> STM ()
@@ -145,21 +105,38 @@ setStage2STM ref s2 = do
145 x {ideStage2 = s2}
105 x {ideStage2 = s2}
108+-- | Retrieves Stage3 from the State.
109+-- This includes the denormalized Declarations and cached rebuilds
110+getStage3 :: Ide m => m Stage3
112+ st <- ideStateVar <$> ask
113+ fmap ideStage3 . liftIO . readTVarIO $ st
115+-- | Sets Stage3 inside the compiler
116+setStage3STM :: TVar IdeState -> Stage3 -> STM ()
117+setStage3STM ref s3 = do
118+ modifyTVar ref $ \x ->
148-- | Checks if the given ModuleName matches the last rebuild cache and if it
122-- | Checks if the given ModuleName matches the last rebuild cache and if it
149-- does returns all loaded definitions + the definitions inside the rebuild
123-- does returns all loaded definitions + the definitions inside the rebuild
151−getAllModules2 :: Ide m => Maybe P.ModuleName -> m [(P.ModuleName, [IdeDeclaration])]
125+getAllModules :: Ide m => Maybe P.ModuleName -> m [Module]
152−getAllModules2 mmoduleName = do
126+getAllModules mmoduleName = do
153− declarations <- s2Declarations <$> getStage2
127+ declarations <- s3Declarations <$> getStage3
154 rebuild <- cachedRebuild
128 rebuild <- cachedRebuild
155 case mmoduleName of
129 case mmoduleName of
156 Nothing -> pure (M.toList declarations)
130 Nothing -> pure (M.toList declarations)
157 Just moduleName ->
131 Just moduleName ->
158 case rebuild of
132 case rebuild of
159 Just (cachedModulename, ef)
133 Just (cachedModulename, ef)
160− | cachedModulename == moduleName ->
134+ | cachedModulename == moduleName -> do
135+ (AstData asts) <- s2AstData <$> getStage2
136+ let ast = fromMaybe M.empty (M.lookup moduleName asts)
161− pure . M.toList $
137+ pure . M.toList $
162− M.insert moduleName (snd . convertModule . convertExterns $ ef) declarations
139+ (snd . annotateLocations ast . fst . convertExterns $ ef) declarations
163 _ -> pure (M.toList declarations)
140 _ -> pure (M.toList declarations)
165-- | Adds an ExternsFile into psc-ide's State Stage1. This does not populate the
142-- | Adds an ExternsFile into psc-ide's State Stage1. This does not populate the
@@ -182,14 +159,14 @@ cacheRebuild :: Ide m => ExternsFile -> m ()
182cacheRebuild ef = do
159cacheRebuild ef = do
183 st <- ideStateVar <$> ask
160 st <- ideStateVar <$> ask
184 liftIO . atomically . modifyTVar st $ \x ->
161 liftIO . atomically . modifyTVar st $ \x ->
185− x { ideStage2 = (ideStage2 x) {
162+ x { ideStage3 = (ideStage3 x) {
186− s2CachedRebuild = Just (efModuleName ef, ef)}}
163+ s3CachedRebuild = Just (efModuleName ef, ef)}}
188-- | Retrieves the rebuild cache
165-- | Retrieves the rebuild cache
189cachedRebuild :: Ide m => m (Maybe (P.ModuleName, ExternsFile))
166cachedRebuild :: Ide m => m (Maybe (P.ModuleName, ExternsFile))
190−cachedRebuild = s2CachedRebuild <$> getStage2
167+cachedRebuild = s3CachedRebuild <$> getStage3
192−-- | Resolves reexports and populates Stage2 with data to be used in queries.
169+-- | Extracts source spans from the parsed ASTs
193populateStage2 :: (Ide m, MonadLogger m) => m ()
170populateStage2 :: (Ide m, MonadLogger m) => m ()
194populateStage2 = do
171populateStage2 = do
195 st <- ideStateVar <$> ask
172 st <- ideStateVar <$> ask
@@ -203,9 +180,35 @@ populateStage2 = do
203-- | STM version of populateStage2
180-- | STM version of populateStage2
204populateStage2STM :: TVar IdeState -> STM ()
181populateStage2STM :: TVar IdeState -> STM ()
205populateStage2STM ref = do
182populateStage2STM ref = do
183+ modules <- s1Modules <$> getStage1STM ref
184+ let spans = map (\((P.Module ss _ _ decls _), _) -> M.fromList (concatMap (extractSpans ss) decls)) modules
185+ setStage2STM ref (Stage2 (AstData spans))
187+-- | Resolves reexports and populates Stage3 with data to be used in queries.
188+populateStage3 :: (Ide m, MonadLogger m) => m ()
190+ st <- ideStateVar <$> ask
191+ (duration, results) <- liftIO $ do
192+ start <- getTime Monotonic
193+ results <- atomically (populateStage3STM st)
194+ end <- getTime Monotonic
195+ pure (Prelude.show (diffTimeSpec start end), results)
197+ (logWarnN . prettyPrintReexportResult (runModuleNameT . fst))
198+ (filter reexportHasFailures results)
199+ $(logDebug) $ "Finished populating Stage3 in " <> toS duration
201+-- | STM version of populateStage3
202+populateStage3STM :: TVar IdeState -> STM [ReexportResult Module]
203+populateStage3STM ref = do
206 externs <- s1Externs <$> getStage1STM ref
204 externs <- s1Externs <$> getStage1STM ref
207− -- Build the "old" ExternDecl format
205+ (AstData asts) <- s2AstData <$> getStage2STM ref
208− let modules = M.mapKeys runModuleNameT (M.map (snd . convertExterns) externs)
206+ let modules = M.map convertExterns externs
209− -- Convert ExternDecl into IdeDeclaration
207+ nModules :: Map P.ModuleName (Module, [(P.ModuleName, P.DeclarationRef)])
210− declarations = resolveReexports2 modules <$> M.toList modules
208+ nModules = M.mapWithKey
211− setStage2STM ref (Stage2 (M.fromList declarations) Nothing)
209+ (\moduleName (m, refs) ->
210+ (fromMaybe m $ annotateLocations <$> M.lookup moduleName asts <*> pure m, refs)) modules
211+ -- resolves reexports and discards load failures for now
212+ result = resolveReexports (M.map (snd . fst) nModules) <$> M.elems nModules
213+ setStage3STM ref (Stage3 (M.fromList (map reResolved result)) Nothing)