module Language.PureScript.CST
  ( parseFromFile
  , parseFromFiles
  , parseModuleFromFile
  , parseModulesFromFiles
  , unwrapParserError
  , toMultipleErrors
  , toMultipleWarnings
  , toPositionedError
  , toPositionedWarning
  , pureResult
  , module Language.PureScript.CST.Convert
  , module Language.PureScript.CST.Errors
  , module Language.PureScript.CST.Lexer
  , module Language.PureScript.CST.Monad
  , module Language.PureScript.CST.Parser
  , module Language.PureScript.CST.Print
  , module Language.PureScript.CST.Types
  ) where

import Prelude hiding (lex)

import Control.Monad.Error.Class (MonadError(..))
import Control.Parallel.Strategies (withStrategy, parList, evalTuple2, r0, rseq)
import Data.List.NonEmpty qualified as NE
import Data.Text (Text)
import Language.PureScript.AST qualified as AST
import Language.PureScript.Errors qualified as E
import Language.PureScript.CST.Convert
import Language.PureScript.CST.Errors
import Language.PureScript.CST.Lexer
import Language.PureScript.CST.Monad (Parser, ParserM(..), ParserState(..), LexResult, runParser, runTokenParser)
import Language.PureScript.CST.Parser
import Language.PureScript.CST.Print
import Language.PureScript.CST.Types

pureResult :: a -> PartialResult a
pureResult :: forall a. a -> PartialResult a
pureResult a
a = forall a.
a
-> ([ParserWarning], Either (NonEmpty ParserError) a)
-> PartialResult a
PartialResult a
a ([], forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a)

parseModulesFromFiles
  :: forall m k
   . MonadError E.MultipleErrors m
  => (k -> FilePath)
  -> [(k, Text)]
  -> m [(k, PartialResult AST.Module)]
parseModulesFromFiles :: forall (m :: * -> *) k.
MonadError MultipleErrors m =>
(k -> FilePath) -> [(k, Text)] -> m [(k, PartialResult Module)]
parseModulesFromFiles k -> FilePath
toFilePath [(k, Text)]
input =
  forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a b.
MonadError MultipleErrors m =>
[a] -> (a -> m b) -> m [b]
E.parU (forall (m :: * -> *) k a.
MonadError MultipleErrors m =>
(k -> FilePath) -> (k, Either (NonEmpty ParserError) a) -> m (k, a)
handleParserError k -> FilePath
toFilePath)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a.
[(k, Either (NonEmpty ParserError) a)]
-> [(k, Either (NonEmpty ParserError) a)]
inParallel
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(k, Text)]
input
    forall a b. (a -> b) -> a -> b
$ \(k
k, Text
a) -> (k
k, FilePath
-> Text -> Either (NonEmpty ParserError) (PartialResult Module)
parseModuleFromFile (k -> FilePath
toFilePath k
k) Text
a)

parseFromFiles
  :: forall m k
   . MonadError E.MultipleErrors m
  => (k -> FilePath)
  -> [(k, Text)]
  -> m [(k, ([ParserWarning], AST.Module))]
parseFromFiles :: forall (m :: * -> *) k.
MonadError MultipleErrors m =>
(k -> FilePath)
-> [(k, Text)] -> m [(k, ([ParserWarning], Module))]
parseFromFiles k -> FilePath
toFilePath [(k, Text)]
input =
  forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (m :: * -> *) a b.
MonadError MultipleErrors m =>
[a] -> (a -> m b) -> m [b]
E.parU (forall (m :: * -> *) k a.
MonadError MultipleErrors m =>
(k -> FilePath) -> (k, Either (NonEmpty ParserError) a) -> m (k, a)
handleParserError k -> FilePath
toFilePath)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a.
[(k, Either (NonEmpty ParserError) a)]
-> [(k, Either (NonEmpty ParserError) a)]
inParallel
    forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [(k, Text)]
input
    forall a b. (a -> b) -> a -> b
$ \(k
k, Text
a) -> (k
k, forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence forall a b. (a -> b) -> a -> b
$ FilePath
-> Text -> ([ParserWarning], Either (NonEmpty ParserError) Module)
parseFromFile (k -> FilePath
toFilePath k
k) Text
a)

parseModuleFromFile :: FilePath -> Text -> Either (NE.NonEmpty ParserError) (PartialResult AST.Module)
parseModuleFromFile :: FilePath
-> Text -> Either (NonEmpty ParserError) (PartialResult Module)
parseModuleFromFile FilePath
fp Text
content = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. FilePath -> Module a -> Module
convertModule FilePath
fp) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [LexResult]
-> Either (NonEmpty ParserError) (PartialResult (Module ()))
parseModule (Text -> [LexResult]
lexModule Text
content)

parseFromFile :: FilePath -> Text -> ([ParserWarning], Either (NE.NonEmpty ParserError) AST.Module)
parseFromFile :: FilePath
-> Text -> ([ParserWarning], Either (NonEmpty ParserError) Module)
parseFromFile FilePath
fp Text
content = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. FilePath -> Module a -> Module
convertModule FilePath
fp) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Text
-> ([ParserWarning], Either (NonEmpty ParserError) (Module ()))
parse Text
content

handleParserError
  :: forall m k a
   . MonadError E.MultipleErrors m
  => (k -> FilePath)
  -> (k, Either (NE.NonEmpty ParserError) a)
  -> m (k, a)
handleParserError :: forall (m :: * -> *) k a.
MonadError MultipleErrors m =>
(k -> FilePath) -> (k, Either (NonEmpty ParserError) a) -> m (k, a)
handleParserError k -> FilePath
toFilePath (k
k, Either (NonEmpty ParserError) a
res) =
  (k
k,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (m :: * -> *) a.
MonadError MultipleErrors m =>
FilePath -> Either (NonEmpty ParserError) a -> m a
unwrapParserError (k -> FilePath
toFilePath k
k) Either (NonEmpty ParserError) a
res

unwrapParserError
  :: forall m a
   . MonadError E.MultipleErrors m
  => FilePath
  -> Either (NE.NonEmpty ParserError) a
  -> m a
unwrapParserError :: forall (m :: * -> *) a.
MonadError MultipleErrors m =>
FilePath -> Either (NonEmpty ParserError) a -> m a
unwrapParserError FilePath
fp =
  forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> NonEmpty ParserError -> MultipleErrors
toMultipleErrors FilePath
fp) forall (f :: * -> *) a. Applicative f => a -> f a
pure

toMultipleErrors :: FilePath -> NE.NonEmpty ParserError -> E.MultipleErrors
toMultipleErrors :: FilePath -> NonEmpty ParserError -> MultipleErrors
toMultipleErrors FilePath
fp =
  [ErrorMessage] -> MultipleErrors
E.MultipleErrors forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NonEmpty a -> [a]
NE.toList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FilePath -> ParserError -> ErrorMessage
toPositionedError FilePath
fp)

toMultipleWarnings :: FilePath -> [ParserWarning] -> E.MultipleErrors
toMultipleWarnings :: FilePath -> [ParserWarning] -> MultipleErrors
toMultipleWarnings FilePath
fp =
  [ErrorMessage] -> MultipleErrors
E.MultipleErrors forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FilePath -> ParserWarning -> ErrorMessage
toPositionedWarning FilePath
fp)

toPositionedError :: FilePath -> ParserError -> E.ErrorMessage
toPositionedError :: FilePath -> ParserError -> ErrorMessage
toPositionedError FilePath
name ParserError
perr =
  [ErrorMessageHint] -> SimpleErrorMessage -> ErrorMessage
E.ErrorMessage [SourceSpan -> ErrorMessageHint
E.positionedError forall a b. (a -> b) -> a -> b
$ FilePath -> SourceRange -> SourceSpan
sourceSpan FilePath
name forall a b. (a -> b) -> a -> b
$ forall a. ParserErrorInfo a -> SourceRange
errRange ParserError
perr] (ParserError -> SimpleErrorMessage
E.ErrorParsingCSTModule ParserError
perr)

toPositionedWarning :: FilePath -> ParserWarning -> E.ErrorMessage
toPositionedWarning :: FilePath -> ParserWarning -> ErrorMessage
toPositionedWarning FilePath
name ParserWarning
perr =
  [ErrorMessageHint] -> SimpleErrorMessage -> ErrorMessage
E.ErrorMessage [SourceSpan -> ErrorMessageHint
E.positionedError forall a b. (a -> b) -> a -> b
$ FilePath -> SourceRange -> SourceSpan
sourceSpan FilePath
name forall a b. (a -> b) -> a -> b
$ forall a. ParserErrorInfo a -> SourceRange
errRange ParserWarning
perr] (ParserWarning -> SimpleErrorMessage
E.WarningParsingCSTModule ParserWarning
perr)

inParallel :: [(k, Either (NE.NonEmpty ParserError) a)] -> [(k, Either (NE.NonEmpty ParserError) a)]
inParallel :: forall k a.
[(k, Either (NonEmpty ParserError) a)]
-> [(k, Either (NonEmpty ParserError) a)]
inParallel = forall a. Strategy a -> a -> a
withStrategy (forall a. Strategy a -> Strategy [a]
parList (forall a b. Strategy a -> Strategy b -> Strategy (a, b)
evalTuple2 forall a. Strategy a
r0 forall a. Strategy a
rseq))