module Language.PureScript.Ide.SourceFile
( parseModule
, parseModulesFromFiles
, extractAstInformation
, extractSpans
, extractTypeAnnotations
) where
import Protolude
import Control.Parallel.Strategies (withStrategy, parList, rseq)
import qualified Data.Map as Map
import qualified Language.PureScript as P
import Language.PureScript.Ide.Error
import Language.PureScript.Ide.Types
import Language.PureScript.Ide.Util
parseModule
:: (MonadIO m, MonadError IdeError m)
=> FilePath
-> m (Either FilePath (FilePath, P.Module))
parseModule path = do
(absPath, contents) <- ideReadFile path
pure (parseModule' absPath contents)
parseModule' :: FilePath -> Text -> Either FilePath (FilePath, P.Module)
parseModule' path file =
case P.parseModuleFromFile identity (path, file) of
Left _ -> Left path
Right m -> Right m
parseModulesFromFiles
:: (MonadIO m, MonadError IdeError m)
=> [FilePath]
-> m [Either FilePath (FilePath, P.Module)]
parseModulesFromFiles paths = do
files <- traverse ideReadFile paths
pure (inParallel (map (uncurry parseModule') files))
where
inParallel :: [Either e (k, a)] -> [Either e (k, a)]
inParallel = withStrategy (parList rseq)
extractAstInformation
:: P.Module
-> (DefinitionSites P.SourceSpan, TypeAnnotations)
extractAstInformation (P.Module _ _ _ decls _) =
let definitions = Map.fromList (concatMap extractSpans decls)
typeAnnotations = Map.fromList (extractTypeAnnotations decls)
in (definitions, typeAnnotations)
extractTypeAnnotations :: [P.Declaration] -> [(P.Ident, P.Type)]
extractTypeAnnotations = mapMaybe (map P.unwrapTypeDeclaration . P.getTypeDeclaration)
extractSpans
:: P.Declaration
-> [(IdeNamespaced, P.SourceSpan)]
extractSpans d = case d of
P.ValueDecl (ss, _) i _ _ _ ->
[(IdeNamespaced IdeNSValue (P.runIdent i), ss)]
P.TypeSynonymDeclaration (ss, _) name _ _ ->
[(IdeNamespaced IdeNSType (P.runProperName name), ss)]
P.TypeClassDeclaration (ss, _) name _ _ _ members ->
(IdeNamespaced IdeNSType (P.runProperName name), ss) : concatMap extractSpans' members
P.DataDeclaration (ss, _) _ name _ ctors ->
(IdeNamespaced IdeNSType (P.runProperName name), ss)
: map (\(cname, _) -> (IdeNamespaced IdeNSValue (P.runProperName cname), ss)) ctors
P.FixityDeclaration (ss, _) (Left (P.ValueFixity _ _ opName)) ->
[(IdeNamespaced IdeNSValue (P.runOpName opName), ss)]
P.FixityDeclaration (ss, _) (Right (P.TypeFixity _ _ opName)) ->
[(IdeNamespaced IdeNSType (P.runOpName opName), ss)]
P.ExternDeclaration (ss, _) ident _ ->
[(IdeNamespaced IdeNSValue (P.runIdent ident), ss)]
P.ExternDataDeclaration (ss, _) name _ ->
[(IdeNamespaced IdeNSType (P.runProperName name), ss)]
P.ExternKindDeclaration (ss, _) name ->
[(IdeNamespaced IdeNSKind (P.runProperName name), ss)]
_ -> []
where
extractSpans' dP = case dP of
P.TypeDeclaration (P.TypeDeclarationData (ss', _) ident _) ->
[(IdeNamespaced IdeNSValue (P.runIdent ident), ss')]
_ -> []