git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
[psc-ide] Collect type class instances (#2592)
a1a37e6Christoph Hegemann
purescript.cabal+1
@@ -542,6 +542,7 @@ test-suite tests
542 hspec -any,
542 hspec -any,
543 hspec-discover -any,
543 hspec-discover -any,
544 HUnit -any,
544 HUnit -any,
545+ lens -any,
545 mtl -any,
546 mtl -any,
546 optparse-applicative -any,
547 optparse-applicative -any,
547 parsec -any,
548 parsec -any,
src/Language/PureScript/Ide/Completion.hs+3
@@ -8,6 +8,9 @@ import Protolude
8import Language.PureScript.Ide.Filter
8import Language.PureScript.Ide.Filter
9import Language.PureScript.Ide.Matcher
9import Language.PureScript.Ide.Matcher
10import Language.PureScript.Ide.Types
10import Language.PureScript.Ide.Types
11+import qualified Language.PureScript as P
12+
13+type Module = (P.ModuleName, [IdeDeclarationAnn])
11
14
12-- | Applies the CompletionFilters and the Matcher to the given Modules
15-- | Applies the CompletionFilters and the Matcher to the given Modules
13-- and sorts the found Completions according to the Matching Score
16-- and sorts the found Completions according to the Matching Score
src/Language/PureScript/Ide/Externs.hs+14−11
@@ -54,9 +54,9 @@ readExternFile fp = do
54 where
54 where
55 version = toS (showVersion P.version)
55 version = toS (showVersion P.version)
56
56
57−convertExterns :: P.ExternsFile -> (Module, [(P.ModuleName, P.DeclarationRef)])
57+convertExterns :: P.ExternsFile -> ([IdeDeclarationAnn], [(P.ModuleName, P.DeclarationRef)])
58convertExterns ef =
58convertExterns ef =
59− ((P.efModuleName ef, decls), exportDecls)
59+ (decls, exportDecls)
60 where
60 where
61 decls = map
61 decls = map
62 (IdeDeclarationAnn emptyAnn)
62 (IdeDeclarationAnn emptyAnn)
@@ -71,8 +71,10 @@ convertExterns ef =
71
71
72removeTypeDeclarationsForClass :: IdeDeclaration -> Endo [IdeDeclaration]
72removeTypeDeclarationsForClass :: IdeDeclaration -> Endo [IdeDeclaration]
73removeTypeDeclarationsForClass (IdeDeclTypeClass n) = Endo (filter notDuplicate)
73removeTypeDeclarationsForClass (IdeDeclTypeClass n) = Endo (filter notDuplicate)
74+ where notDuplicate (IdeDeclType t) =
74− where notDuplicate (IdeDeclType t) = n ^. properNameT /= t ^. ideTypeName . properNameT
75+ n ^. ideTCName . properNameT /= t ^. ideTypeName . properNameT
76+ notDuplicate (IdeDeclTypeSynonym s) =
75− notDuplicate (IdeDeclTypeSynonym s) = n ^. properNameT /= s ^. ideSynonymName . properNameT
77+ n ^. ideTCName . properNameT /= s ^. ideSynonymName . properNameT
76 notDuplicate _ = True
78 notDuplicate _ = True
77removeTypeDeclarationsForClass _ = mempty
79removeTypeDeclarationsForClass _ = mempty
78
80
@@ -93,7 +95,8 @@ convertDecl P.EDDataConstructor{..} = Just $ IdeDeclDataConstructor $
93 IdeDataConstructor edDataCtorName edDataCtorTypeCtor edDataCtorType
95 IdeDataConstructor edDataCtorName edDataCtorTypeCtor edDataCtorType
94convertDecl P.EDValue{..} = Just $ IdeDeclValue $
96convertDecl P.EDValue{..} = Just $ IdeDeclValue $
95 IdeValue edValueName edValueType
97 IdeValue edValueName edValueType
96−convertDecl P.EDClass{..} = Just (IdeDeclTypeClass edClassName)
98+convertDecl P.EDClass{..} = Just $ IdeDeclTypeClass $
99+ IdeTypeClass edClassName []
97convertDecl P.EDKind{..} = Just (IdeDeclKind edKindName)
100convertDecl P.EDKind{..} = Just (IdeDeclKind edKindName)
98convertDecl P.EDInstance{} = Nothing
101convertDecl P.EDInstance{} = Nothing
99
102
@@ -117,10 +120,10 @@ convertTypeOperator P.ExternsTypeFixity{..} =
117
120
118annotateModule
121annotateModule
119 :: (DefinitionSites P.SourceSpan, TypeAnnotations)
122 :: (DefinitionSites P.SourceSpan, TypeAnnotations)
120− -> Module
123+ -> [IdeDeclarationAnn]
121− -> Module
124+ -> [IdeDeclarationAnn]
122−annotateModule (defs, types) (moduleName, decls) =
125+annotateModule (defs, types) decls =
123− (moduleName, map convertDeclaration decls)
126+ map convertDeclaration decls
124 where
127 where
125 convertDeclaration :: IdeDeclarationAnn -> IdeDeclarationAnn
128 convertDeclaration :: IdeDeclarationAnn -> IdeDeclarationAnn
126 convertDeclaration (IdeDeclarationAnn ann d) = case d of
129 convertDeclaration (IdeDeclarationAnn ann d) = case d of
@@ -132,8 +135,8 @@ annotateModule (defs, types) (moduleName, decls) =
132 annotateType (s ^. ideSynonymName . properNameT) (IdeDeclTypeSynonym s)
135 annotateType (s ^. ideSynonymName . properNameT) (IdeDeclTypeSynonym s)
133 IdeDeclDataConstructor dtor ->
136 IdeDeclDataConstructor dtor ->
134 annotateValue (dtor ^. ideDtorName . properNameT) (IdeDeclDataConstructor dtor)
137 annotateValue (dtor ^. ideDtorName . properNameT) (IdeDeclDataConstructor dtor)
135− IdeDeclTypeClass i ->
138+ IdeDeclTypeClass tc ->
136− annotateType (i ^. properNameT) (IdeDeclTypeClass i)
139+ annotateType (tc ^. ideTCName . properNameT) (IdeDeclTypeClass tc)
137 IdeDeclValueOperator op ->
140 IdeDeclValueOperator op ->
138 annotateValue (op ^. ideValueOpAlias & valueOperatorAliasT) (IdeDeclValueOperator op)
141 annotateValue (op ^. ideValueOpAlias & valueOperatorAliasT) (IdeDeclValueOperator op)
139 IdeDeclTypeOperator op ->
142 IdeDeclTypeOperator op ->
src/Language/PureScript/Ide/Filter.hs+2
@@ -32,6 +32,8 @@ import Language.PureScript.Ide.Util
32
32
33newtype Filter = Filter (Endo [Module]) deriving(Monoid)
33newtype Filter = Filter (Endo [Module]) deriving(Monoid)
34
34
35+type Module = (P.ModuleName, [IdeDeclarationAnn])
36+
35mkFilter :: ([Module] -> [Module]) -> Filter
37mkFilter :: ([Module] -> [Module]) -> Filter
36mkFilter = Filter . Endo
38mkFilter = Filter . Endo
37
39
src/Language/PureScript/Ide/Imports.hs+2−2
@@ -197,8 +197,8 @@ addExplicitImport' decl moduleName imports =
197 then imports
197 then imports
198 else updateAtFirstOrPrepend matches (insertDeclIntoImport decl) freshImport imports
198 else updateAtFirstOrPrepend matches (insertDeclIntoImport decl) freshImport imports
199 where
199 where
200− refFromDeclaration (IdeDeclTypeClass n) =
200+ refFromDeclaration (IdeDeclTypeClass tc) =
201− P.TypeClassRef n
201+ P.TypeClassRef (tc ^. ideTCName)
202 refFromDeclaration (IdeDeclDataConstructor dtor) =
202 refFromDeclaration (IdeDeclDataConstructor dtor) =
203 P.TypeRef (dtor ^. ideDtorTypeName) Nothing
203 P.TypeRef (dtor ^. ideDtorTypeName) Nothing
204 refFromDeclaration (IdeDeclType t) =
204 refFromDeclaration (IdeDeclType t) =
src/Language/PureScript/Ide/Rebuild.hs+3−3
@@ -103,8 +103,8 @@ rebuildModuleOpen makeEnv externs m = void $ runExceptT $ do
103data MakeActionsEnv =
103data MakeActionsEnv =
104 MakeActionsEnv
104 MakeActionsEnv
105 { maeOutputDirectory :: FilePath
105 { maeOutputDirectory :: FilePath
106− , maeFilePathMap :: Map P.ModuleName (Either P.RebuildPolicy FilePath)
106+ , maeFilePathMap :: ModuleMap (Either P.RebuildPolicy FilePath)
107− , maeForeignPathMap :: Map P.ModuleName FilePath
107+ , maeForeignPathMap :: ModuleMap FilePath
108 , maePrefixComment :: Bool
108 , maePrefixComment :: Bool
109 }
109 }
110
110
@@ -134,7 +134,7 @@ shushCodegen ma MakeActionsEnv{..} =
134sortExterns
134sortExterns
135 :: (Ide m, MonadError PscIdeError m)
135 :: (Ide m, MonadError PscIdeError m)
136 => P.Module
136 => P.Module
137− -> Map P.ModuleName P.ExternsFile
137+ -> ModuleMap P.ExternsFile
138 -> m [P.ExternsFile]
138 -> m [P.ExternsFile]
139sortExterns m ex = do
139sortExterns m ex = do
140 sorted' <- runExceptT
140 sorted' <- runExceptT
src/Language/PureScript/Ide/Reexports.hs+33−22
@@ -18,25 +18,25 @@ module Language.PureScript.Ide.Reexports
18 , prettyPrintReexportResult
18 , prettyPrintReexportResult
19 , reexportHasFailures
19 , reexportHasFailures
20 , ReexportResult(..)
20 , ReexportResult(..)
21+ -- for tests
22+ , resolveReexports'
21 ) where
23 ) where
22
24
23import Protolude
25import Protolude
24
26
25−import Control.Lens hiding ((&))
26−
27import qualified Data.Map as Map
27import qualified Data.Map as Map
28import qualified Language.PureScript as P
28import qualified Language.PureScript as P
29import Language.PureScript.Ide.Types
29import Language.PureScript.Ide.Types
30import Language.PureScript.Ide.Util
30import Language.PureScript.Ide.Util
31
31
32−-- | Contains the module with resolved reexports, and eventual failures
32+-- | Contains the module with resolved reexports, and possible failures
33data ReexportResult a
33data ReexportResult a
34 = ReexportResult
34 = ReexportResult
35 { reResolved :: a
35 { reResolved :: a
36 , reFailed :: [(P.ModuleName, P.DeclarationRef)]
36 , reFailed :: [(P.ModuleName, P.DeclarationRef)]
37 } deriving (Show, Eq, Functor)
37 } deriving (Show, Eq, Functor)
38
38
39−-- | Uses the passed formatter to format the resolved module, and adds eventual
39+-- | Uses the passed formatter to format the resolved module, and adds possible
40-- failures
40-- failures
41prettyPrintReexportResult
41prettyPrintReexportResult
42 :: (a -> Text)
42 :: (a -> Text)
@@ -56,16 +56,27 @@ prettyPrintReexportResult f ReexportResult{..}
56reexportHasFailures :: ReexportResult a -> Bool
56reexportHasFailures :: ReexportResult a -> Bool
57reexportHasFailures = not . null . reFailed
57reexportHasFailures = not . null . reFailed
58
58
59−-- | Resolves Reexports for a given Module, by looking up the reexported values
59+-- | Resolves Reexports for the given Modules, by looking up the reexported
60−-- from the passed in Map
60+-- values from the passed in DeclarationRefs
61resolveReexports
61resolveReexports
62+ :: ModuleMap [(P.ModuleName, P.DeclarationRef)]
63+ -- ^ the references to resolve
62− :: Map P.ModuleName [IdeDeclarationAnn]
64+ -> ModuleMap [IdeDeclarationAnn]
63 -- ^ Modules to search for the reexported declarations
65 -- ^ Modules to search for the reexported declarations
66+ -> ModuleMap (ReexportResult [IdeDeclarationAnn])
67+resolveReexports reexportRefs modules =
68+ Map.mapWithKey (\moduleName decls ->
69+ maybe (ReexportResult decls [])
70+ (resolveReexports' modules decls)
71+ (Map.lookup moduleName reexportRefs)) modules
72+
73+resolveReexports'
74+ :: ModuleMap [IdeDeclarationAnn]
75+ -> [IdeDeclarationAnn]
64− -> (Module, [(P.ModuleName, P.DeclarationRef)])
76+ -> [(P.ModuleName, P.DeclarationRef)]
65− -- ^ The module to resolve reexports for, aswell as the references to resolve
66− -> ReexportResult Module
77+ -> ReexportResult [IdeDeclarationAnn]
67−resolveReexports modules ((moduleName, decls), refs) =
78+resolveReexports' modules decls refs =
68− ReexportResult (moduleName, decls <> concat resolvedRefs) failedRefs
79+ ReexportResult (decls <> concat resolvedRefs) failedRefs
69 where
80 where
70 (failedRefs, resolvedRefs) = partitionEithers (resolveRef' <$> refs)
81 (failedRefs, resolvedRefs) = partitionEithers (resolveRef' <$> refs)
71 resolveRef' x@(mn, r) = case Map.lookup mn modules of
82 resolveRef' x@(mn, r) = case Map.lookup mn modules of
@@ -78,7 +89,7 @@ resolveRef
78 -> Either P.DeclarationRef [IdeDeclarationAnn]
89 -> Either P.DeclarationRef [IdeDeclarationAnn]
79resolveRef decls ref = case ref of
90resolveRef decls ref = case ref of
80 P.TypeRef tn mdtors ->
91 P.TypeRef tn mdtors ->
81− case findRef (\x -> x ^? _IdeDeclType . ideTypeName <&> (== tn) & fromMaybe False) of
92+ case findRef (lensSatisfies (_IdeDeclType . ideTypeName) (== tn)) of
82 Nothing -> Left ref
93 Nothing -> Left ref
83 Just d -> Right $ d : case mdtors of
94 Just d -> Right $ d : case mdtors of
84 Nothing ->
95 Nothing ->
@@ -88,13 +99,13 @@ resolveRef decls ref = case ref of
88 findDtors tn
99 findDtors tn
89 Just dtors -> mapMaybe lookupDtor dtors
100 Just dtors -> mapMaybe lookupDtor dtors
90 P.ValueRef i ->
101 P.ValueRef i ->
91− findWrapped (\x -> x ^? _IdeDeclValue . ideValueIdent <&> (== i) & fromMaybe False)
102+ findWrapped (lensSatisfies (_IdeDeclValue . ideValueIdent) (== i))
92 P.ValueOpRef name ->
103 P.ValueOpRef name ->
93− findWrapped (\x -> x ^? _IdeDeclValueOperator . ideValueOpName <&> (== name) & fromMaybe False)
104+ findWrapped (lensSatisfies (_IdeDeclValueOperator . ideValueOpName) (== name))
94 P.TypeOpRef name ->
105 P.TypeOpRef name ->
95− findWrapped (\x -> x ^? _IdeDeclTypeOperator . ideTypeOpName <&> (== name) & fromMaybe False)
106+ findWrapped (lensSatisfies (_IdeDeclTypeOperator . ideTypeOpName) (== name))
96 P.TypeClassRef name ->
107 P.TypeClassRef name ->
97− findWrapped (\case IdeDeclTypeClass n -> n == name; _ -> False)
108+ findWrapped (lensSatisfies (_IdeDeclTypeClass . ideTCName) (== name))
98 _ ->
109 _ ->
99 Left ref
110 Left ref
100 where
111 where
@@ -102,9 +113,9 @@ resolveRef decls ref = case ref of
102 findRef f = find (f . discardAnn) decls
113 findRef f = find (f . discardAnn) decls
103
114
104 lookupDtor name =
115 lookupDtor name =
105− findRef (\x -> x ^? _IdeDeclDataConstructor . ideDtorName <&> (== name) & fromMaybe False)
116+ findRef (lensSatisfies (_IdeDeclDataConstructor . ideDtorName) (== name))
106
117
107− findDtors tn = filter (f . discardAnn) decls
118+ findDtors tn = filter (lensSatisfies
108− where
119+ (idaDeclaration
109− f :: IdeDeclaration -> Bool
110− f decl = decl ^? _IdeDeclDataConstructor . ideDtorTypeName <&> (== tn) & fromMaybe False
120+ . _IdeDeclDataConstructor
121+ . ideDtorTypeName) (== tn)) decls
src/Language/PureScript/Ide/State.hs+74−27
@@ -14,6 +14,7 @@
14
14
15{-# LANGUAGE PackageImports #-}
15{-# LANGUAGE PackageImports #-}
16{-# LANGUAGE TemplateHaskell #-}
16{-# LANGUAGE TemplateHaskell #-}
17+{-# LANGUAGE NamedFieldPuns #-}
17
18
18module Language.PureScript.Ide.State
19module Language.PureScript.Ide.State
19 ( getLoadedModulenames
20 ( getLoadedModulenames
@@ -29,10 +30,12 @@ module Language.PureScript.Ide.State
29 , populateStage3STM
30 , populateStage3STM
30 -- for tests
31 -- for tests
31 , resolveOperatorsForModule
32 , resolveOperatorsForModule
33+ , resolveInstances
32 ) where
34 ) where
33
35
34import Protolude
36import Protolude
35
37
38+import Control.Arrow
36import Control.Concurrent.STM
39import Control.Concurrent.STM
37import Control.Lens hiding (op, (&))
40import Control.Lens hiding (op, (&))
38import "monad-logger" Control.Monad.Logger
41import "monad-logger" Control.Monad.Logger
@@ -58,7 +61,7 @@ getLoadedModulenames :: Ide m => m [P.ModuleName]
58getLoadedModulenames = Map.keys <$> getExternFiles
61getLoadedModulenames = Map.keys <$> getExternFiles
59
62
60-- | Gets all loaded ExternFiles
63-- | Gets all loaded ExternFiles
61−getExternFiles :: Ide m => m (Map P.ModuleName ExternsFile)
64+getExternFiles :: Ide m => m (ModuleMap ExternsFile)
62getExternFiles = s1Externs <$> getStage1
65getExternFiles = s1Externs <$> getStage1
63
66
64-- | Insert a Module into Stage1 of the State
67-- | Insert a Module into Stage1 of the State
@@ -121,7 +124,7 @@ setStage3STM ref s3 = do
121-- | Checks if the given ModuleName matches the last rebuild cache and if it
124-- | Checks if the given ModuleName matches the last rebuild cache and if it
122-- does returns all loaded definitions + the definitions inside the rebuild
125-- does returns all loaded definitions + the definitions inside the rebuild
123-- cache
126-- cache
124−getAllModules :: Ide m => Maybe P.ModuleName -> m [Module]
127+getAllModules :: Ide m => Maybe P.ModuleName -> m [(P.ModuleName, [IdeDeclarationAnn])]
125getAllModules mmoduleName = do
128getAllModules mmoduleName = do
126 declarations <- s3Declarations <$> getStage3
129 declarations <- s3Declarations <$> getStage3
127 rebuild <- cachedRebuild
130 rebuild <- cachedRebuild
@@ -136,7 +139,7 @@ getAllModules mmoduleName = do
136 ast =
139 ast =
137 fromMaybe (Map.empty, Map.empty) (Map.lookup moduleName asts)
140 fromMaybe (Map.empty, Map.empty) (Map.lookup moduleName asts)
138 cachedModule =
141 cachedModule =
139− snd . annotateModule ast . fst . convertExterns $ ef
142+ annotateModule ast (fst (convertExterns ef))
140 tmp =
143 tmp =
141 Map.insert moduleName cachedModule declarations
144 Map.insert moduleName cachedModule declarations
142 resolved =
145 resolved =
@@ -192,43 +195,84 @@ populateStage3 = do
192 st <- ideStateVar <$> ask
195 st <- ideStateVar <$> ask
193 let message duration = "Finished populating Stage3 in " <> displayTimeSpec duration
196 let message duration = "Finished populating Stage3 in " <> displayTimeSpec duration
194 results <- logPerf message (liftIO (atomically (populateStage3STM st)))
197 results <- logPerf message (liftIO (atomically (populateStage3STM st)))
195− traverse_
198+ void $ Map.traverseWithKey
196− (logWarnN . prettyPrintReexportResult (P.runModuleName . fst))
199+ (\mn -> logWarnN . prettyPrintReexportResult (const (P.runModuleName mn)))
197− (filter reexportHasFailures results)
200+ (Map.filter reexportHasFailures results)
198
201
199-- | STM version of populateStage3
202-- | STM version of populateStage3
200−populateStage3STM :: TVar IdeState -> STM [ReexportResult Module]
203+populateStage3STM
204+ :: TVar IdeState
205+ -> STM (ModuleMap (ReexportResult [IdeDeclarationAnn]))
201populateStage3STM ref = do
206populateStage3STM ref = do
202 externs <- s1Externs <$> getStage1STM ref
207 externs <- s1Externs <$> getStage1STM ref
203 (AstData asts) <- s2AstData <$> getStage2STM ref
208 (AstData asts) <- s2AstData <$> getStage2STM ref
204− let modules = Map.map convertExterns externs
209+ let (modules, reexportRefs) = (map fst &&& map snd) (Map.map convertExterns externs)
205− nModules :: Map P.ModuleName (Module, [(P.ModuleName, P.DeclarationRef)])
210+ results =
206− nModules = Map.mapWithKey
211+ resolveLocations asts modules
207− (\moduleName (m, refs) ->
212+ & resolveInstances externs
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))
213+ & resolveOperators
214+ & resolveReexports reexportRefs
212− setStage3STM ref (Stage3 resultP Nothing)
215+ setStage3STM ref (Stage3 (map reResolved results) Nothing)
213− pure result
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
214
261
215resolveOperators
262resolveOperators
216− :: Map P.ModuleName [IdeDeclarationAnn]
263+ :: ModuleMap [IdeDeclarationAnn]
217− -> Map P.ModuleName [IdeDeclarationAnn]
264+ -> ModuleMap [IdeDeclarationAnn]
218resolveOperators modules =
265resolveOperators modules =
219 map (resolveOperatorsForModule modules) modules
266 map (resolveOperatorsForModule modules) modules
220
267
221-- | Looks up the types and kinds for operators and assigns them to their
268-- | Looks up the types and kinds for operators and assigns them to their
222-- declarations
269-- declarations
223resolveOperatorsForModule
270resolveOperatorsForModule
224− :: Map P.ModuleName [IdeDeclarationAnn]
271+ :: ModuleMap [IdeDeclarationAnn]
225 -> [IdeDeclarationAnn]
272 -> [IdeDeclarationAnn]
226 -> [IdeDeclarationAnn]
273 -> [IdeDeclarationAnn]
227−resolveOperatorsForModule modules = map ((over idaDeclaration) resolveOperator)
274+resolveOperatorsForModule modules = map (idaDeclaration %~ resolveOperator)
228 where
275 where
229− hasName :: Eq b => Lens' a b -> b -> a -> Bool
230− hasName l a x = x ^. l == a
231−
232 getDeclarations :: P.ModuleName -> [IdeDeclaration]
276 getDeclarations :: P.ModuleName -> [IdeDeclaration]
233 getDeclarations moduleName =
277 getDeclarations moduleName =
234 Map.lookup moduleName modules
278 Map.lookup moduleName modules
@@ -239,14 +283,14 @@ resolveOperatorsForModule modules = map ((over idaDeclaration) resolveOperator)
239 | (P.Qualified (Just mn) (Left ident)) <- op ^. ideValueOpAlias =
283 | (P.Qualified (Just mn) (Left ident)) <- op ^. ideValueOpAlias =
240 let t = getDeclarations mn
284 let t = getDeclarations mn
241 & mapMaybe (preview _IdeDeclValue)
285 & mapMaybe (preview _IdeDeclValue)
242− & filter (hasName ideValueIdent ident)
286+ & filter (lensSatisfies ideValueIdent (== ident))
243 & map (view ideValueType)
287 & map (view ideValueType)
244 & listToMaybe
288 & listToMaybe
245 in IdeDeclValueOperator (op & ideValueOpType .~ t)
289 in IdeDeclValueOperator (op & ideValueOpType .~ t)
246 | (P.Qualified (Just mn) (Right dtor)) <- op ^. ideValueOpAlias =
290 | (P.Qualified (Just mn) (Right dtor)) <- op ^. ideValueOpAlias =
247 let t = getDeclarations mn
291 let t = getDeclarations mn
248 & mapMaybe (preview _IdeDeclDataConstructor)
292 & mapMaybe (preview _IdeDeclDataConstructor)
249− & filter (hasName ideDtorName dtor)
293+ & filter (lensSatisfies ideDtorName (== dtor))
250 & map (view ideDtorType)
294 & map (view ideDtorType)
251 & listToMaybe
295 & listToMaybe
252 in IdeDeclValueOperator (op & ideValueOpType .~ t)
296 in IdeDeclValueOperator (op & ideValueOpType .~ t)
@@ -254,9 +298,12 @@ resolveOperatorsForModule modules = map ((over idaDeclaration) resolveOperator)
254 | P.Qualified (Just mn) properName <- op ^. ideTypeOpAlias =
298 | P.Qualified (Just mn) properName <- op ^. ideTypeOpAlias =
255 let k = getDeclarations mn
299 let k = getDeclarations mn
256 & mapMaybe (preview _IdeDeclType)
300 & mapMaybe (preview _IdeDeclType)
257− & filter (hasName ideTypeName properName)
301+ & filter (lensSatisfies ideTypeName (== properName))
258 & map (view ideTypeKind)
302 & map (view ideTypeKind)
259 & listToMaybe
303 & listToMaybe
260 in IdeDeclTypeOperator (op & ideTypeOpKind .~ k)
304 in IdeDeclTypeOperator (op & ideTypeOpKind .~ k)
261 resolveOperator x = x
305 resolveOperator x = x
262
306
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)
src/Language/PureScript/Ide/Types.hs+20−7
@@ -27,13 +27,14 @@ import qualified Language.PureScript as P
27import qualified Language.PureScript.Errors.JSON as P
27import qualified Language.PureScript.Errors.JSON as P
28
28
29type ModuleIdent = Text
29type ModuleIdent = Text
30+type ModuleMap a = Map P.ModuleName a
30
31
31data IdeDeclaration
32data IdeDeclaration
32 = IdeDeclValue IdeValue
33 = IdeDeclValue IdeValue
33 | IdeDeclType IdeType
34 | IdeDeclType IdeType
34 | IdeDeclTypeSynonym IdeSynonym
35 | IdeDeclTypeSynonym IdeSynonym
35 | IdeDeclDataConstructor IdeDataConstructor
36 | IdeDeclDataConstructor IdeDataConstructor
36− | IdeDeclTypeClass (P.ProperName 'P.ClassName)
37+ | IdeDeclTypeClass IdeTypeClass
37 | IdeDeclValueOperator IdeValueOperator
38 | IdeDeclValueOperator IdeValueOperator
38 | IdeDeclTypeOperator IdeTypeOperator
39 | IdeDeclTypeOperator IdeTypeOperator
39 | IdeDeclKind (P.ProperName 'P.KindName)
40 | IdeDeclKind (P.ProperName 'P.KindName)
@@ -60,6 +61,18 @@ data IdeDataConstructor = IdeDataConstructor
60 , _ideDtorType :: P.Type
61 , _ideDtorType :: P.Type
61 } deriving (Show, Eq, Ord)
62 } deriving (Show, Eq, Ord)
62
63
64+data IdeTypeClass = IdeTypeClass
65+ { _ideTCName :: P.ProperName 'P.ClassName
66+ , _ideTCInstances :: [IdeInstance]
67+ } deriving (Show, Eq, Ord)
68+
69+data IdeInstance = IdeInstance
70+ { _ideInstanceModule :: P.ModuleName
71+ , _ideInstanceName :: P.Ident
72+ , _ideInstanceTypes :: [P.Type]
73+ , _ideInstanceConstraints :: Maybe [P.Constraint]
74+ } deriving (Show, Eq, Ord)
75+
63data IdeValueOperator = IdeValueOperator
76data IdeValueOperator = IdeValueOperator
64 { _ideValueOpName :: P.OpName 'P.ValueOpName
77 { _ideValueOpName :: P.OpName 'P.ValueOpName
65 , _ideValueOpAlias :: P.Qualified (Either P.Ident (P.ProperName 'P.ConstructorName))
78 , _ideValueOpAlias :: P.Qualified (Either P.Ident (P.ProperName 'P.ConstructorName))
@@ -81,6 +94,8 @@ makeLenses ''IdeValue
81makeLenses ''IdeType
94makeLenses ''IdeType
82makeLenses ''IdeSynonym
95makeLenses ''IdeSynonym
83makeLenses ''IdeDataConstructor
96makeLenses ''IdeDataConstructor
97+makeLenses ''IdeTypeClass
98+makeLenses ''IdeInstance
84makeLenses ''IdeValueOperator
99makeLenses ''IdeValueOperator
85makeLenses ''IdeTypeOperator
100makeLenses ''IdeTypeOperator
86
101
@@ -101,11 +116,9 @@ makeLenses ''IdeDeclarationAnn
101emptyAnn :: Annotation
116emptyAnn :: Annotation
102emptyAnn = Annotation Nothing Nothing Nothing
117emptyAnn = Annotation Nothing Nothing Nothing
103
118
104−type Module = (P.ModuleName, [IdeDeclarationAnn])
105−
106type DefinitionSites a = Map IdeDeclNamespace a
119type DefinitionSites a = Map IdeDeclNamespace a
107type TypeAnnotations = Map P.Ident P.Type
120type TypeAnnotations = Map P.Ident P.Type
108−newtype AstData a = AstData (Map P.ModuleName (DefinitionSites a, TypeAnnotations))
121+newtype AstData a = AstData (ModuleMap (DefinitionSites a, TypeAnnotations))
109 -- ^ SourceSpans for the definition sites of Values and Types aswell as type
122 -- ^ SourceSpans for the definition sites of Values and Types aswell as type
110 -- annotations found in a module
123 -- annotations found in a module
111 deriving (Show, Eq, Ord, Functor, Foldable)
124 deriving (Show, Eq, Ord, Functor, Foldable)
@@ -147,8 +160,8 @@ emptyStage3 :: Stage3
147emptyStage3 = Stage3 M.empty Nothing
160emptyStage3 = Stage3 M.empty Nothing
148
161
149data Stage1 = Stage1
162data Stage1 = Stage1
150− { s1Externs :: M.Map P.ModuleName P.ExternsFile
163+ { s1Externs :: ModuleMap P.ExternsFile
151− , s1Modules :: M.Map P.ModuleName (P.Module, FilePath)
164+ , s1Modules :: ModuleMap (P.Module, FilePath)
152 }
165 }
153
166
154data Stage2 = Stage2
167data Stage2 = Stage2
@@ -156,7 +169,7 @@ data Stage2 = Stage2
156 }
169 }
157
170
158data Stage3 = Stage3
171data Stage3 = Stage3
159− { s3Declarations :: M.Map P.ModuleName [IdeDeclarationAnn]
172+ { s3Declarations :: ModuleMap [IdeDeclarationAnn]
160 , s3CachedRebuild :: Maybe (P.ModuleName, P.ExternsFile)
173 , s3CachedRebuild :: Maybe (P.ModuleName, P.ExternsFile)
161 }
174 }
162
175
src/Language/PureScript/Ide/Util.hs+12−7
@@ -27,15 +27,17 @@ module Language.PureScript.Ide.Util
27 , prettyTypeT
27 , prettyTypeT
28 , properNameT
28 , properNameT
29 , identT
29 , identT
30+ , lensSatisfies
30 , module Language.PureScript.Ide.Logging
31 , module Language.PureScript.Ide.Logging
31 ) where
32 ) where
32
33
33import Protolude hiding (decodeUtf8,
34import Protolude hiding (decodeUtf8,
34 encodeUtf8)
35 encodeUtf8)
35
36
36−import Control.Lens ((^.), Iso', iso)
37+import Control.Lens ((^.), (^?), Iso', iso, Getting, (<&>))
37import Data.Aeson
38import Data.Aeson
38import qualified Data.Text as T
39import qualified Data.Text as T
40+import qualified Data.Text.Lazy as TL
39import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
41import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
40import qualified Language.PureScript as P
42import qualified Language.PureScript as P
41import Language.PureScript.Ide.Logging
43import Language.PureScript.Ide.Logging
@@ -47,7 +49,7 @@ identifierFromIdeDeclaration d = case d of
47 IdeDeclType t -> t ^. ideTypeName . properNameT
49 IdeDeclType t -> t ^. ideTypeName . properNameT
48 IdeDeclTypeSynonym s -> s ^. ideSynonymName . properNameT
50 IdeDeclTypeSynonym s -> s ^. ideSynonymName . properNameT
49 IdeDeclDataConstructor dtor -> dtor ^. ideDtorName . properNameT
51 IdeDeclDataConstructor dtor -> dtor ^. ideDtorName . properNameT
50− IdeDeclTypeClass name -> P.runProperName name
52+ IdeDeclTypeClass tc -> tc ^. ideTCName . properNameT
51 IdeDeclValueOperator op -> op ^. ideValueOpName & P.runOpName
53 IdeDeclValueOperator op -> op ^. ideValueOpName & P.runOpName
52 IdeDeclTypeOperator op -> op ^. ideTypeOpName & P.runOpName
54 IdeDeclTypeOperator op -> op ^. ideTypeOpName & P.runOpName
53 IdeDeclKind name -> P.runProperName name
55 IdeDeclKind name -> P.runProperName name
@@ -67,14 +69,14 @@ completionFromMatch (Match (m, IdeDeclarationAnn ann decl)) =
67 where
69 where
68 (complIdentifier, complExpandedType) = case decl of
70 (complIdentifier, complExpandedType) = case decl of
69 IdeDeclValue v -> (v ^. ideValueIdent . identT, v ^. ideValueType & prettyTypeT)
71 IdeDeclValue v -> (v ^. ideValueIdent . identT, v ^. ideValueType & prettyTypeT)
70− IdeDeclType t -> (t ^. ideTypeName . properNameT, t ^. ideTypeKind & P.prettyPrintKind & toS )
72+ IdeDeclType t -> (t ^. ideTypeName . properNameT, t ^. ideTypeKind & P.prettyPrintKind)
71 IdeDeclTypeSynonym s -> (s ^. ideSynonymName . properNameT, s ^. ideSynonymType & prettyTypeT)
73 IdeDeclTypeSynonym s -> (s ^. ideSynonymName . properNameT, s ^. ideSynonymType & prettyTypeT)
72 IdeDeclDataConstructor d -> (d ^. ideDtorName . properNameT, d ^. ideDtorType & prettyTypeT)
74 IdeDeclDataConstructor d -> (d ^. ideDtorName . properNameT, d ^. ideDtorType & prettyTypeT)
73− IdeDeclTypeClass name -> (P.runProperName name, "class")
75+ IdeDeclTypeClass d -> (d ^. ideTCName . properNameT, "type class")
74 IdeDeclValueOperator (IdeValueOperator op ref precedence associativity typeP) ->
76 IdeDeclValueOperator (IdeValueOperator op ref precedence associativity typeP) ->
75 (P.runOpName op, maybe (showFixity precedence associativity (valueOperatorAliasT ref) op) prettyTypeT typeP)
77 (P.runOpName op, maybe (showFixity precedence associativity (valueOperatorAliasT ref) op) prettyTypeT typeP)
76 IdeDeclTypeOperator (IdeTypeOperator op ref precedence associativity kind) ->
78 IdeDeclTypeOperator (IdeTypeOperator op ref precedence associativity kind) ->
77− (P.runOpName op, maybe (showFixity precedence associativity (typeOperatorAliasT ref) op) (toS . P.prettyPrintKind) kind)
79+ (P.runOpName op, maybe (showFixity precedence associativity (typeOperatorAliasT ref) op) P.prettyPrintKind kind)
78 IdeDeclKind k -> (P.runProperName k, "kind")
80 IdeDeclKind k -> (P.runProperName k, "kind")
79
81
80 complModule = P.runModuleName m
82 complModule = P.runModuleName m
@@ -103,10 +105,10 @@ typeOperatorAliasT i =
103 P.showQualified P.runProperName i
105 P.showQualified P.runProperName i
104
106
105encodeT :: (ToJSON a) => a -> Text
107encodeT :: (ToJSON a) => a -> Text
106−encodeT = toS . decodeUtf8 . encode
108+encodeT = TL.toStrict . decodeUtf8 . encode
107
109
108decodeT :: (FromJSON a) => Text -> Maybe a
110decodeT :: (FromJSON a) => Text -> Maybe a
109−decodeT = decode . encodeUtf8 . toS
111+decodeT = decode . encodeUtf8 . TL.fromStrict
110
112
111unwrapPositioned :: P.Declaration -> P.Declaration
113unwrapPositioned :: P.Declaration -> P.Declaration
112unwrapPositioned (P.PositionedDeclaration _ _ x) = unwrapPositioned x
114unwrapPositioned (P.PositionedDeclaration _ _ x) = unwrapPositioned x
@@ -129,3 +131,6 @@ prettyTypeT =
129 . T.lines
131 . T.lines
130 . T.pack
132 . T.pack
131 . P.prettyPrintTypeWithUnicode
133 . P.prettyPrintTypeWithUnicode
134+
135+lensSatisfies :: forall a s. Getting (First a) s a -> (a -> Bool) -> s -> Bool
136+lensSatisfies getter predicate value = value ^? getter <&> predicate & fromMaybe False
tests/Language/PureScript/Ide/FilterSpec.hs+2
@@ -8,6 +8,8 @@ import Language.PureScript.Ide.Types
8import qualified Language.PureScript as P
8import qualified Language.PureScript as P
9import Test.Hspec
9import Test.Hspec
10
10
11+type Module = (P.ModuleName, [IdeDeclarationAnn])
12+
11value :: Text -> IdeDeclarationAnn
13value :: Text -> IdeDeclarationAnn
12value s = IdeDeclarationAnn emptyAnn (IdeDeclValue (IdeValue (P.Ident (toS s)) P.REmpty))
14value s = IdeDeclarationAnn emptyAnn (IdeDeclValue (IdeValue (P.Ident (toS s)) P.REmpty))
13
15
tests/Language/PureScript/Ide/ImportsSpec.hs+1−1
@@ -144,7 +144,7 @@ spec = do
144 addImport imports import' = addExplicitImport' import' moduleName imports
144 addImport imports import' = addExplicitImport' import' moduleName imports
145 valueImport ident = (IdeDeclValue (IdeValue (P.Ident ident) wildcard))
145 valueImport ident = (IdeDeclValue (IdeValue (P.Ident ident) wildcard))
146 typeImport name = (IdeDeclType (IdeType (P.ProperName name) P.kindType))
146 typeImport name = (IdeDeclType (IdeType (P.ProperName name) P.kindType))
147− classImport name = (IdeDeclTypeClass (P.ProperName name))
147+ classImport name = (IdeDeclTypeClass (IdeTypeClass (P.ProperName name) []))
148 dtorImport name typeName = (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName name) (P.ProperName typeName) wildcard))
148 dtorImport name typeName = (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName name) (P.ProperName typeName) wildcard))
149 -- expect any list of provided identifiers, when imported, to come out as specified
149 -- expect any list of provided identifiers, when imported, to come out as specified
150 expectSorted imports expected = shouldBe
150 expectSorted imports expected = shouldBe
tests/Language/PureScript/Ide/ReexportsSpec.hs+15−13
@@ -10,6 +10,8 @@ import Language.PureScript.Ide.Types
10import qualified Language.PureScript as P
10import qualified Language.PureScript as P
11import Test.Hspec
11import Test.Hspec
12
12
13+type Module = (P.ModuleName, [IdeDeclarationAnn])
14+
13m :: Text -> P.ModuleName
15m :: Text -> P.ModuleName
14m = P.moduleNameFromString
16m = P.moduleNameFromString
15
17
@@ -19,32 +21,32 @@ d = IdeDeclarationAnn emptyAnn
19valueA, typeA, classA, dtorA1, dtorA2 :: IdeDeclarationAnn
21valueA, typeA, classA, dtorA1, dtorA2 :: IdeDeclarationAnn
20valueA = d (IdeDeclValue (IdeValue (P.Ident "valueA") P.REmpty))
22valueA = d (IdeDeclValue (IdeValue (P.Ident "valueA") P.REmpty))
21typeA = d (IdeDeclType (IdeType(P.ProperName "TypeA") P.kindType))
23typeA = d (IdeDeclType (IdeType(P.ProperName "TypeA") P.kindType))
22−classA = d (IdeDeclTypeClass (P.ProperName "ClassA"))
24+classA = d (IdeDeclTypeClass (IdeTypeClass (P.ProperName "ClassA") []))
23dtorA1 = d (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName "DtorA1") (P.ProperName "TypeA") P.REmpty))
25dtorA1 = d (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName "DtorA1") (P.ProperName "TypeA") P.REmpty))
24dtorA2 = d (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName "DtorA2") (P.ProperName "TypeA") P.REmpty))
26dtorA2 = d (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName "DtorA2") (P.ProperName "TypeA") P.REmpty))
25
27
26−env :: Map P.ModuleName [IdeDeclarationAnn]
28+env :: ModuleMap [IdeDeclarationAnn]
27env = Map.fromList
29env = Map.fromList
28 [ (m "A", [valueA, typeA, classA, dtorA1, dtorA2])
30 [ (m "A", [valueA, typeA, classA, dtorA1, dtorA2])
29 ]
31 ]
30
32
31type Refs = [(P.ModuleName, P.DeclarationRef)]
33type Refs = [(P.ModuleName, P.DeclarationRef)]
32
34
33−succTestCases :: [(Text, Module, Refs, Module)]
35+succTestCases :: [(Text, [IdeDeclarationAnn], Refs, [IdeDeclarationAnn])]
34succTestCases =
36succTestCases =
35− [ ("resolves a value reexport", (m "C", []), [(m "A", P.ValueRef (P.Ident "valueA"))], (m "C", [valueA]))
37+ [ ("resolves a value reexport", [], [(m "A", P.ValueRef (P.Ident "valueA"))], [valueA])
36 , ("resolves a type reexport with explicit data constructors"
38 , ("resolves a type reexport with explicit data constructors"
37− , (m "C", []), [(m "A", P.TypeRef (P.ProperName "TypeA") (Just [P.ProperName "DtorA1"]))], (m "C", [typeA, dtorA1]))
39+ , [], [(m "A", P.TypeRef (P.ProperName "TypeA") (Just [P.ProperName "DtorA1"]))], [typeA, dtorA1])
38 , ("resolves a type reexport with implicit data constructors"
40 , ("resolves a type reexport with implicit data constructors"
39− , (m "C", []), [(m "A", P.TypeRef (P.ProperName "TypeA") Nothing)], (m "C", [typeA, dtorA1, dtorA2]))
41+ , [], [(m "A", P.TypeRef (P.ProperName "TypeA") Nothing)], [typeA, dtorA1, dtorA2])
40− , ("resolves a class reexport", (m "C", []), [(m "A", P.TypeClassRef (P.ProperName "ClassA"))], (m "C", [classA]))
42+ , ("resolves a class reexport", [], [(m "A", P.TypeClassRef (P.ProperName "ClassA"))], [classA])
41 ]
43 ]
42
44
43−failTestCases :: [(Text, Module, Refs)]
45+failTestCases :: [(Text, [IdeDeclarationAnn], Refs)]
44failTestCases =
46failTestCases =
45− [ ("fails to resolve a non existing value", (m "C", []), [(m "A", P.ValueRef (P.Ident "valueB"))])
47+ [ ("fails to resolve a non existing value", [], [(m "A", P.ValueRef (P.Ident "valueB"))])
46− , ("fails to resolve a non existing type reexport" , (m "C", []), [(m "A", P.TypeRef (P.ProperName "TypeB") Nothing)])
48+ , ("fails to resolve a non existing type reexport" , [], [(m "A", P.TypeRef (P.ProperName "TypeB") Nothing)])
47− , ("fails to resolve a non existing class reexport", (m "C", []), [(m "A", P.TypeClassRef (P.ProperName "ClassB"))])
49+ , ("fails to resolve a non existing class reexport", [], [(m "A", P.TypeClassRef (P.ProperName "ClassB"))])
48 ]
50 ]
49
51
50spec :: Spec
52spec :: Spec
@@ -52,12 +54,12 @@ spec = do
52 describe "Successful Reexports" $
54 describe "Successful Reexports" $
53 for_ succTestCases $ \(desc, initial, refs, result) ->
55 for_ succTestCases $ \(desc, initial, refs, result) ->
54 it (toS desc) $ do
56 it (toS desc) $ do
55− let reResult = resolveReexports env (initial, refs)
57+ let reResult = resolveReexports' env initial refs
56 reResolved reResult `shouldBe` result
58 reResolved reResult `shouldBe` result
57 reResult `shouldSatisfy` not . reexportHasFailures
59 reResult `shouldSatisfy` not . reexportHasFailures
58 describe "Failed Reexports" $
60 describe "Failed Reexports" $
59 for_ failTestCases $ \(desc, initial, refs) ->
61 for_ failTestCases $ \(desc, initial, refs) ->
60 it (toS desc) $ do
62 it (toS desc) $ do
61− let reResult = resolveReexports env (initial, refs)
63+ let reResult = resolveReexports' env initial refs
62 reFailed reResult `shouldBe` refs
64 reFailed reResult `shouldBe` refs
63 reResult `shouldSatisfy` reexportHasFailures
65 reResult `shouldSatisfy` reexportHasFailures
tests/Language/PureScript/Ide/StateSpec.hs+53−13
@@ -3,6 +3,7 @@
3module Language.PureScript.Ide.StateSpec where
3module Language.PureScript.Ide.StateSpec where
4
4
5import Protolude
5import Protolude
6+import Control.Lens hiding ((&))
6import Language.PureScript.Ide.Types
7import Language.PureScript.Ide.Types
7import Language.PureScript.Ide.State
8import Language.PureScript.Ide.State
8import qualified Language.PureScript as P
9import qualified Language.PureScript as P
@@ -21,7 +22,7 @@ typeOperator :: Maybe P.Kind -> IdeDeclarationAnn
21typeOperator =
22typeOperator =
22 d . IdeDeclTypeOperator . IdeTypeOperator (P.OpName ":") (P.Qualified (Just (mn "Test")) (P.ProperName "List")) 2 P.Infix
23 d . IdeDeclTypeOperator . IdeTypeOperator (P.OpName ":") (P.Qualified (Just (mn "Test")) (P.ProperName "List")) 2 P.Infix
23
24
24−testModule :: Module
25+testModule :: (P.ModuleName, [IdeDeclarationAnn])
25testModule = (mn "Test", [ d (IdeDeclValue (IdeValue (P.Ident "function") P.REmpty))
26testModule = (mn "Test", [ d (IdeDeclValue (IdeValue (P.Ident "function") P.REmpty))
26 , d (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName "Cons") (P.ProperName "List") (P.REmpty)))
27 , d (IdeDeclDataConstructor (IdeDataConstructor (P.ProperName "Cons") (P.ProperName "List") (P.REmpty)))
27 , d (IdeDeclType (IdeType (P.ProperName "List") P.kindType))
28 , d (IdeDeclType (IdeType (P.ProperName "List") P.kindType))
@@ -34,18 +35,57 @@ d :: IdeDeclaration -> IdeDeclarationAnn
34d = IdeDeclarationAnn emptyAnn
35d = IdeDeclarationAnn emptyAnn
35
36
36mn :: Text -> P.ModuleName
37mn :: Text -> P.ModuleName
37−mn = P.moduleNameFromString . toS
38+mn = P.moduleNameFromString
38
39
39−testState :: Map P.ModuleName [IdeDeclarationAnn]
40+testState :: ModuleMap [IdeDeclarationAnn]
40−testState = Map.fromList
41+testState = Map.fromList [testModule]
41− [ testModule
42+
43+-- The accessor fields for these data types are not exposed unfortunately
44+ef :: P.ExternsFile
45+ef = P.ExternsFile
46+ -- { efVersion =
47+ mempty
48+ -- , efModuleName =
49+ (mn "InstanceModule")
50+ -- , efExports =
51+ mempty
52+ -- , efImports =
53+ mempty
54+ -- , efFixities =
55+ mempty
56+ -- , efTypeFixities =
57+ mempty
58+ --, efDeclarations =
59+ [ P.EDInstance
60+ -- { edInstanceClassName =
61+ (P.Qualified (Just (mn "ClassModule")) (P.ProperName "MyClass"))
62+ -- , edInstanceName =
63+ (P.Ident "myClassInstance")
64+ -- , edInstanceTypes =
65+ mempty
66+ -- , edInstanceConstraints =
67+ mempty
68+ -- }
42− ]
69+ ]
70+ -- }
71+
72+moduleMap :: ModuleMap [IdeDeclarationAnn]
73+moduleMap = Map.singleton (mn "ClassModule") [d (IdeDeclTypeClass (IdeTypeClass (P.ProperName "MyClass") []))]
74+
75+ideInstance :: IdeInstance
76+ideInstance = IdeInstance (mn "InstanceModule") (P.Ident "myClassInstance") mempty mempty
43
77
44spec :: Spec
78spec :: Spec
79+spec = do
45−spec = describe "resolving operators" $ do
80+ describe "resolving operators" $ do
46− it "resolves the type for a value operator" $
81+ it "resolves the type for a value operator" $
47− resolveOperatorsForModule testState (snd testModule) `shouldSatisfy` elem (valueOperator (Just P.REmpty))
82+ resolveOperatorsForModule testState (snd testModule) `shouldSatisfy` elem (valueOperator (Just P.REmpty))
48− it "resolves the type for a constructor operator" $
83+ it "resolves the type for a constructor operator" $
49− resolveOperatorsForModule testState (snd testModule) `shouldSatisfy` elem (ctorOperator (Just P.REmpty))
84+ resolveOperatorsForModule testState (snd testModule) `shouldSatisfy` elem (ctorOperator (Just P.REmpty))
50− it "resolves the kind for a type operator" $
85+ it "resolves the kind for a type operator" $
51− resolveOperatorsForModule testState (snd testModule) `shouldSatisfy` elem (typeOperator (Just P.kindType))
86+ resolveOperatorsForModule testState (snd testModule) `shouldSatisfy` elem (typeOperator (Just P.kindType))
87+ describe "resolving instances for type classes" $ do
88+ it "resolves an instance for an existing type class" $ do
89+ resolveInstances (Map.singleton (mn "InstanceModule") ef) moduleMap
90+ `shouldSatisfy`
91+ elemOf (ix (mn "ClassModule") . ix 0 . idaDeclaration . _IdeDeclTypeClass . ideTCInstances . folded) ideInstance