@@ -14,6 +14,7 @@
1414
1515{-# LANGUAGE PackageImports #-}
1616{-# LANGUAGE TemplateHaskell #-}
17+{-# LANGUAGE NamedFieldPuns #-}
1718
1819module Language.PureScript.Ide.State
1920 ( getLoadedModulenames
@@ -29,10 +30,12 @@ module Language.PureScript.Ide.State
2930 , populateStage3STM
3031 -- for tests
3132 , resolveOperatorsForModule
33+ , resolveInstances
3234 ) where
3335
3436import Protolude
3537
38+import Control.Arrow
3639import Control.Concurrent.STM
3740import Control.Lens hiding (op, (&))
3841import "monad-logger" Control.Monad.Logger
@@ -58,7 +61,7 @@ getLoadedModulenames :: Ide m => m [P.ModuleName]
5861getLoadedModulenames = Map.keys <$> getExternFiles
5962
6063-- | Gets all loaded ExternFiles
61−getExternFiles :: Ide m => m (Map P.ModuleName ExternsFile)
64+getExternFiles :: Ide m => m (ModuleMap ExternsFile)
6265getExternFiles = s1Externs <$> getStage1
6366
6467-- | Insert a Module into Stage1 of the State
@@ -121,7 +124,7 @@ setStage3STM ref s3 = do
121124-- | Checks if the given ModuleName matches the last rebuild cache and if it
122125-- does returns all loaded definitions + the definitions inside the rebuild
123126-- cache
124−getAllModules :: Ide m => Maybe P.ModuleName -> m [Module]
127+getAllModules :: Ide m => Maybe P.ModuleName -> m [(P.ModuleName, [IdeDeclarationAnn])]
125128getAllModules mmoduleName = do
126129 declarations <- s3Declarations <$> getStage3
127130 rebuild <- cachedRebuild
@@ -136,7 +139,7 @@ getAllModules mmoduleName = do
136139 ast =
137140 fromMaybe (Map.empty, Map.empty) (Map.lookup moduleName asts)
138141 cachedModule =
139− snd . annotateModule ast . fst . convertExterns $ ef
142+ annotateModule ast (fst (convertExterns ef))
140143 tmp =
141144 Map.insert moduleName cachedModule declarations
142145 resolved =
@@ -192,43 +195,84 @@ populateStage3 = do
192195 st <- ideStateVar <$> ask
193196 let message duration = "Finished populating Stage3 in " <> displayTimeSpec duration
194197 results <- logPerf message (liftIO (atomically (populateStage3STM st)))
195− traverse_
196− (logWarnN . prettyPrintReexportResult (P.runModuleName . fst))
197− (filter reexportHasFailures results)
198+ void $ Map.traverseWithKey
199+ (\mn -> logWarnN . prettyPrintReexportResult (const (P.runModuleName mn)))
200+ (Map.filter reexportHasFailures results)
198201
199202-- | STM version of populateStage3
200−populateStage3STM :: TVar IdeState -> STM [ReexportResult Module]
203+populateStage3STM
204+ :: TVar IdeState
205+ -> STM (ModuleMap (ReexportResult [IdeDeclarationAnn]))
201206populateStage3STM ref = do
202207 externs <- s1Externs <$> getStage1STM ref
203208 (AstData asts) <- s2AstData <$> getStage2STM ref
204− let modules = Map.map convertExterns externs
205− nModules :: Map P.ModuleName (Module, [(P.ModuleName, P.DeclarationRef)])
206− nModules = Map.mapWithKey
207− (\moduleName (m, refs) ->
208− (fromMaybe m $ annotateModule <$> Map.lookup moduleName asts <*> pure m, refs)) modules
209− -- resolves reexports and discards load failures for now
210− result = resolveReexports (map (snd . fst) nModules) <$> Map.elems nModules
211− resultP = resolveOperators (Map.fromList (reResolved <$> result))
212− setStage3STM ref (Stage3 resultP Nothing)
213− pure result
209+ let (modules, reexportRefs) = (map fst &&& map snd) (Map.map convertExterns externs)
210+ results =
211+ resolveLocations asts modules
212+ & resolveInstances externs
213+ & resolveOperators
214+ & resolveReexports reexportRefs
215+ setStage3STM ref (Stage3 (map reResolved results) Nothing)
216+ pure results
217+
218+
219+resolveLocations
220+ :: ModuleMap (DefinitionSites P.SourceSpan, TypeAnnotations)
221+ -> ModuleMap [IdeDeclarationAnn]
222+ -> ModuleMap [IdeDeclarationAnn]
223+resolveLocations asts =
224+ Map.mapWithKey (\mn decls ->
225+ maybe decls (flip annotateModule decls) (Map.lookup mn asts))
226+
227+resolveInstances
228+ :: ModuleMap P.ExternsFile
229+ -> ModuleMap [IdeDeclarationAnn]
230+ -> ModuleMap [IdeDeclarationAnn]
231+resolveInstances externs declarations =
232+ Map.foldr (flip (foldr go)) declarations
233+ . Map.mapWithKey (\mn ef -> mapMaybe (extractInstances mn) (efDeclarations ef))
234+ $ externs
235+ where
236+ extractInstances mn P.EDInstance{..} =
237+ case edInstanceClassName of
238+ P.Qualified (Just classModule) className ->
239+ Just (IdeInstance mn
240+ edInstanceName
241+ edInstanceTypes
242+ edInstanceConstraints, classModule, className)
243+ _ -> Nothing
244+ extractInstances _ _ = Nothing
245+
246+ go ::
247+ (IdeInstance, P.ModuleName, P.ProperName 'P.ClassName)
248+ -> ModuleMap [IdeDeclarationAnn]
249+ -> ModuleMap [IdeDeclarationAnn]
250+ go (ideInstance, classModule, className) acc' =
251+ let
252+ matchTC =
253+ lensSatisfies (idaDeclaration . _IdeDeclTypeClass . ideTCName) (== className)
254+ updateDeclaration =
255+ mapIf matchTC (idaDeclaration
256+ . _IdeDeclTypeClass
257+ . ideTCInstances
258+ %~ cons ideInstance)
259+ in
260+ acc' & ix classModule %~ updateDeclaration
214261
215262resolveOperators
216− :: Map P.ModuleName [IdeDeclarationAnn]
217− -> Map P.ModuleName [IdeDeclarationAnn]
263+ :: ModuleMap [IdeDeclarationAnn]
264+ -> ModuleMap [IdeDeclarationAnn]
218265resolveOperators modules =
219266 map (resolveOperatorsForModule modules) modules
220267
221268-- | Looks up the types and kinds for operators and assigns them to their
222269-- declarations
223270resolveOperatorsForModule
224− :: Map P.ModuleName [IdeDeclarationAnn]
271+ :: ModuleMap [IdeDeclarationAnn]
225272 -> [IdeDeclarationAnn]
226273 -> [IdeDeclarationAnn]
227−resolveOperatorsForModule modules = map ((over idaDeclaration) resolveOperator)
274+resolveOperatorsForModule modules = map (idaDeclaration %~ resolveOperator)
228275 where
229− hasName :: Eq b => Lens' a b -> b -> a -> Bool
230− hasName l a x = x ^. l == a
231−
232276 getDeclarations :: P.ModuleName -> [IdeDeclaration]
233277 getDeclarations moduleName =
234278 Map.lookup moduleName modules
@@ -239,14 +283,14 @@ resolveOperatorsForModule modules = map ((over idaDeclaration) resolveOperator)
239283 | (P.Qualified (Just mn) (Left ident)) <- op ^. ideValueOpAlias =
240284 let t = getDeclarations mn
241285 & mapMaybe (preview _IdeDeclValue)
242− & filter (hasName ideValueIdent ident)
286+ & filter (lensSatisfies ideValueIdent (== ident))
243287 & map (view ideValueType)
244288 & listToMaybe
245289 in IdeDeclValueOperator (op & ideValueOpType .~ t)
246290 | (P.Qualified (Just mn) (Right dtor)) <- op ^. ideValueOpAlias =
247291 let t = getDeclarations mn
248292 & mapMaybe (preview _IdeDeclDataConstructor)
249− & filter (hasName ideDtorName dtor)
293+ & filter (lensSatisfies ideDtorName (== dtor))
250294 & map (view ideDtorType)
251295 & listToMaybe
252296 in IdeDeclValueOperator (op & ideValueOpType .~ t)
@@ -254,9 +298,12 @@ resolveOperatorsForModule modules = map ((over idaDeclaration) resolveOperator)
254298 | P.Qualified (Just mn) properName <- op ^. ideTypeOpAlias =
255299 let k = getDeclarations mn
256300 & mapMaybe (preview _IdeDeclType)
257− & filter (hasName ideTypeName properName)
301+ & filter (lensSatisfies ideTypeName (== properName))
258302 & map (view ideTypeKind)
259303 & listToMaybe
260304 in IdeDeclTypeOperator (op & ideTypeOpKind .~ k)
261305 resolveOperator x = x
262306
307+
308+mapIf :: Functor f => (b -> Bool) -> (b -> b) -> f b -> f b
309+mapIf p f = map (\x -> if p x then f x else x)