git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
[psc-ide] Switches to the Protolude

An alternative Prelude, that is meant to reduce boilerplate and enforce best practices with regards to String

commit8063c4d0498c9bdca74ffe165edcdd1ea1a4f15b authorChristoph Hegemann <christoph.hegemann1337@gmail.com> dateSat 11 Jun 2016, 04:09 (10 years ago) parenta07a714
27 files changed+263−374
psc-ide-server/Main.hs+17−25 purescript.cabal+3−1 src/Language/PureScript/Ide.hs+3−14 src/Language/PureScript/Ide/CaseSplit.hs+14−21 src/Language/PureScript/Ide/Command.hs+5−7 src/Language/PureScript/Ide/Completion.hs+6−8 src/Language/PureScript/Ide/Conversions.hs+7−8 src/Language/PureScript/Ide/Error.hs+9−12 src/Language/PureScript/Ide/Externs.hs+8−16 src/Language/PureScript/Ide/Filter.hs+4−8 src/Language/PureScript/Ide/Imports.hs+13−20 src/Language/PureScript/Ide/Matcher.hs+5−12 src/Language/PureScript/Ide/Pursuit.hs+5−11 src/Language/PureScript/Ide/Rebuild.hs+11−13 src/Language/PureScript/Ide/Reexports.hs+4−6 src/Language/PureScript/Ide/SourceFile.hs+34−44 src/Language/PureScript/Ide/State.hs+1−5 src/Language/PureScript/Ide/Types.hs+10−16 src/Language/PureScript/Ide/Util.hs+5−12 src/Language/PureScript/Ide/Watcher.hs+2−4 tests/Language/PureScript/Ide/FilterSpec.hs+13−11 tests/Language/PureScript/Ide/Imports/IntegrationSpec.hs+4−2 tests/Language/PureScript/Ide/ImportsSpec.hs+6−6 tests/Language/PureScript/Ide/Integration.hs+53−72 tests/Language/PureScript/Ide/MatcherSpec.hs+11−12 tests/Language/PureScript/Ide/RebuildSpec.hs+6−2 tests/Language/PureScript/Ide/ReexportsSpec.hs+4−6
psc-ide-server/Main.hs+17−25
@@ -17,21 +17,14 @@
1717{-# LANGUAGE OverloadedStrings #-}
1818{-# LANGUAGE PackageImports #-}
1919{-# LANGUAGE TemplateHaskell #-}
20+{-# LANGUAGE NoImplicitPrelude #-}
2021
2122module Main where
2223
23−import Prelude ()
24−import Prelude.Compat
24+import Protolude
2525
26−import Control.Concurrent (forkFinally)
2726import Control.Concurrent.STM
28−import Control.Exception (bracketOnError, catchJust)
29−import Control.Monad
30−import Control.Monad.Error.Class
3127import "monad-logger" Control.Monad.Logger
32−import Control.Monad.Reader
33−import Control.Monad.Trans.Except
34−import qualified Data.Text as T
3528import qualified Data.Text.IO as T
3629import Data.Version (showVersion)
3730import Language.PureScript.Ide
@@ -43,10 +36,10 @@ import Network hiding (socketPort, accept)
4336import Network.BSD (getProtocolNumber)
4437import Network.Socket hiding (PortNumber, Type,
4538 sClose)
46−import Options.Applicative
39+import Options.Applicative hiding ((<>))
4740import System.Directory
4841import System.FilePath
49−import System.IO
42+import System.IO hiding (putStrLn, print)
5043import System.IO.Error (isEOFError)
5144
5245import qualified Paths_purescript as Paths
@@ -54,8 +47,8 @@ import qualified Paths_purescript as Paths
5447-- "Borrowed" from the Idris Compiler
5548-- Copied from upstream impl of listenOn
5649-- bound to localhost interface instead of iNADDR_ANY
57−listenOnLocalhost :: PortID -> IO Socket
58−listenOnLocalhost (PortNumber port) = do
50+listenOnLocalhost :: PortNumber -> IO Socket
51+listenOnLocalhost port = do
5952 proto <- getProtocolNumber "tcp"
6053 localhost <- inet_addr "127.0.0.1"
6154 bracketOnError
@@ -66,12 +59,11 @@ listenOnLocalhost (PortNumber port) = do
6659 bindSocket sock (SockAddrInet port localhost)
6760 listen sock maxListenQueue
6861 pure sock)
69−listenOnLocalhost _ = error "Wrong Porttype"
7062
7163data Options = Options
7264 { optionsDirectory :: Maybe FilePath
7365 , optionsOutputPath :: FilePath
74− , optionsPort :: PortID
66+ , optionsPort :: PortNumber
7567 , optionsNoWatch :: Bool
7668 , optionsDebug :: Bool
7769 }
@@ -88,8 +80,8 @@ main = do
8880 unlessM (doesDirectoryExist fullOutputPath) $ do
8981 putStrLn ("Your output directory didn't exist. I'll create it at: " <> fullOutputPath)
9082 createDirectory fullOutputPath
91− putStrLn "This usually means you didn't compile your project yet."
92− putStrLn "psc-ide needs you to compile your project (for example by running pulp build)"
83+ putText "This usually means you didn't compile your project yet."
84+ putText "psc-ide needs you to compile your project (for example by running pulp build)"
9385
9486 unless noWatch $
9587 void (forkFinally (watcher ideState fullOutputPath) print)
@@ -100,18 +92,18 @@ main = do
10092 where
10193 parser =
10294 Options
103− <$> optional (strOption (long "directory" <> short 'd'))
104− <*> strOption (long "output-directory" <> value "output/")
105− <*> (PortNumber . fromIntegral <$>
106− option auto (long "port" <> short 'p' <> value (4242 :: Integer)))
95+ <$> optional (strOption (long "directory" `mappend` short 'd'))
96+ <*> strOption (long "output-directory" `mappend` value "output/")
97+ <*> (fromIntegral <$>
98+ option auto (long "port" `mappend` short 'p' `mappend` value (4242 :: Integer)))
10799 <*> switch (long "no-watch")
108100 <*> switch (long "debug")
109101 opts = info (version <*> helper <*> parser) mempty
110102 version = abortOption
111103 (InfoMsg (showVersion Paths.version))
112− (long "version" <> help "Show the version number")
104+ (long "version" `mappend` help "Show the version number")
113105
114−startServer :: PortID -> IdeEnvironment -> IO ()
106+startServer :: PortNumber -> IdeEnvironment -> IO ()
115107startServer port env = withSocketsDo $ do
116108 sock <- listenOnLocalhost port
117109 runLogger (runReaderT (forever (loop sock)) env)
@@ -141,8 +133,8 @@ startServer port env = withSocketsDo $ do
141133 liftIO (hClose h)
142134
143135
144−acceptCommand :: (MonadIO m, MonadLogger m, MonadError T.Text m)
145− => Socket -> m (T.Text, Handle)
136+acceptCommand :: (MonadIO m, MonadLogger m, MonadError Text m)
137+ => Socket -> m (Text, Handle)
146138acceptCommand sock = do
147139 h <- acceptConnection
148140 $(logDebug) "Accepted a connection"
purescript.cabal+3−1
@@ -101,7 +101,6 @@ library
101101 aeson >= 0.8 && < 0.12,
102102 aeson-better-errors >= 0.8,
103103 ansi-terminal >= 0.6.2 && < 0.7,
104− async,
105104 base-compat >=0.6.0,
106105 bower-json >= 0.8,
107106 boxes >= 0.1.4 && < 0.2.0,
@@ -126,6 +125,7 @@ library
126125 pipes >= 4.0.0 && < 4.2.0,
127126 pipes-http -any,
128127 process >= 1.2.0 && < 1.5,
128+ protolude >= 0.1.5,
129129 regex-tdfa -any,
130130 safe >= 0.3.9 && < 0.4,
131131 semigroups >= 0.16.2 && < 0.19,
@@ -435,6 +435,7 @@ executable psc-ide-server
435435 mtl -any,
436436 network -any,
437437 optparse-applicative >= 0.12.1,
438+ protolude >= 0.1.5,
438439 stm -any,
439440 text -any,
440441 transformers -any,
@@ -475,6 +476,7 @@ test-suite tests
475476 optparse-applicative -any,
476477 parsec -any,
477478 process -any,
479+ protolude >= 0.1.5,
478480 silently -any,
479481 stm -any,
480482 text -any,
src/Language/PureScript/Ide.hs+3−14
@@ -21,19 +21,9 @@ module Language.PureScript.Ide
2121 , printModules
2222 ) where
2323
24−import Prelude ()
25−import Prelude.Compat
24+import Protolude
2625
27−import Control.Concurrent.Async
28−import Control.Monad.Error.Class
29−import Control.Monad.IO.Class
3026import "monad-logger" Control.Monad.Logger
31−import Control.Monad.Reader
32−import Data.Foldable
33−import Data.Maybe (catMaybes)
34−import Data.Monoid
35−import Data.Text (Text)
36−import qualified Data.Text as T
3727import qualified Language.PureScript as P
3828import qualified Language.PureScript.Ide.CaseSplit as CS
3929import Language.PureScript.Ide.Command
@@ -50,7 +40,6 @@ import Language.PureScript.Ide.State
5040import Language.PureScript.Ide.Types
5141import Language.PureScript.Ide.Util
5242import System.Directory
53−import System.Exit
5443import System.FilePath
5544
5645handleCommand :: (Ide m, MonadLogger m, MonadError PscIdeError m) =>
@@ -86,7 +75,7 @@ handleCommand (Import fp outfp filters (AddImportForIdentifier ident)) = do
8675handleCommand (Rebuild file) =
8776 rebuildFile file
8877handleCommand Cwd =
89− TextResult . T.pack <$> liftIO getCurrentDirectory
78+ TextResult . toS <$> liftIO getCurrentDirectory
9079handleCommand Reset = resetIdeState *> pure (TextResult "State has been reset.")
9180handleCommand Quit = liftIO exitSuccess
9281
@@ -127,7 +116,7 @@ listAvailableModules = do
127116 liftIO $ do
128117 contents <- getDirectoryContents oDir
129118 let cleaned = filter (`notElem` [".", ".."]) contents
130− return (ModuleList (map T.pack cleaned))
119+ return (ModuleList (map toS cleaned))
131120
132121caseSplit :: (Ide m, MonadError PscIdeError m) =>
133122 Text -> Int -> Int -> CS.WildcardAnnotations -> Text -> m Success
src/Language/PureScript/Ide/CaseSplit.hs+14−21
@@ -23,14 +23,8 @@ module Language.PureScript.Ide.CaseSplit
2323 , caseSplit
2424 ) where
2525
26−import Prelude ()
27−import Prelude.Compat hiding (lex)
28−
29−import Control.Arrow (second)
30−import Control.Monad.Error.Class
31−import Data.List (find)
32−import Data.Monoid
33−import Data.Text (Text)
26+import Protolude hiding (Constructor)
27+
3428import qualified Data.Text as T
3529import qualified Language.PureScript as P
3630
@@ -56,7 +50,7 @@ noAnnotations = WildcardAnnotations False
5650caseSplit :: (Ide m, MonadError PscIdeError m) =>
5751 Text -> m [Constructor]
5852caseSplit q = do
59− type' <- parseType' (T.unpack q)
53+ type' <- parseType' q
6054 (tc, args) <- splitTypeConstructor type'
6155 (EDType _ _ (P.DataType typeVars ctors)) <- findTypeDeclaration tc
6256 let applyTypeVars = P.everywhereOnTypes (P.replaceAllTypeVars (zip (map fst typeVars) args))
@@ -115,26 +109,26 @@ makePattern t x y wsa = makePattern' (T.take x t) (T.drop y t)
115109
116110addClause :: (MonadError PscIdeError m) => Text -> WildcardAnnotations -> m [Text]
117111addClause s wca = do
118− (fName, fType) <- parseTypeDeclaration' (T.unpack s)
119− let (args, _) = splitFunctionType fType
112+ (fName, fType) <- parseTypeDeclaration' s
113+ let args = splitFunctionType fType
120114 template = runIdentT fName <> " " <>
121115 T.unwords (map (prettyPrintWildcard wca) args) <>
122116 " = ?" <> (T.strip . runIdentT $ fName)
123117 pure [s, template]
124118
125119parseType' :: (MonadError PscIdeError m) =>
126− String -> m P.Type
120+ Text -> m P.Type
127121parseType' s =
128− case P.lex "<psc-ide>" s >>= P.runTokenParser "<psc-ide>" (P.parseType <* Parsec.eof) of
122+ case P.lex "<psc-ide>" (toS s) >>= P.runTokenParser "<psc-ide>" (P.parseType <* Parsec.eof) of
129123 Right type' -> pure type'
130124 Left err ->
131125 throwError (GeneralError ("Parsing the splittype failed with:"
132− ++ show err))
126+ <> show err))
133127
134−parseTypeDeclaration' :: (MonadError PscIdeError m) => String -> m (P.Ident, P.Type)
128+parseTypeDeclaration' :: (MonadError PscIdeError m) => Text -> m (P.Ident, P.Type)
135129parseTypeDeclaration' s =
136130 let x = do
137− ts <- P.lex "" s
131+ ts <- P.lex "" (toS s)
138132 P.runTokenParser "" (P.parseDeclaration <* Parsec.eof) ts
139133 in
140134 case unwrapPositioned <$> x of
@@ -142,13 +136,12 @@ parseTypeDeclaration' s =
142136 Right _ -> throwError (GeneralError "Found a non-type-declaration")
143137 Left err ->
144138 throwError (GeneralError ("Parsing the typesignature failed with: "
145− ++ show err))
139+ <> show err))
146140
147−splitFunctionType :: P.Type -> ([P.Type], P.Type)
148−splitFunctionType t = (arguments, returns)
141+splitFunctionType :: P.Type -> [P.Type]
142+splitFunctionType t = fromMaybe [] arguments
149143 where
150− returns = last splitted
151− arguments = init splitted
144+ arguments = initMay splitted
152145 splitted = splitType' t
153146 splitType' (P.ForAll _ t' _) = splitType' t'
154147 splitType' (P.ConstrainedType _ t') = splitType' t'
src/Language/PureScript/Ide/Command.hs+5−7
@@ -16,17 +16,15 @@
1616
1717module Language.PureScript.Ide.Command where
1818
19−import Prelude ()
20−import Prelude.Compat
19+import Protolude
2120
22−import Control.Monad
2321import Data.Aeson
24−import Data.Text (Text)
2522import qualified Language.PureScript as P
2623import Language.PureScript.Ide.CaseSplit
2724import Language.PureScript.Ide.Filter
2825import Language.PureScript.Ide.Matcher
2926import Language.PureScript.Ide.Types
27+import System.FilePath
3028
3129data Command
3230 = Load [P.ModuleName]
@@ -70,7 +68,7 @@ data ImportCommand
7068
7169instance FromJSON ImportCommand where
7270 parseJSON = withObject "ImportCommand" $ \o -> do
73− (command :: String) <- o .: "importCommand"
71+ (command :: Text) <- o .: "importCommand"
7472 case command of
7573 "addImplicitImport" ->
7674 AddImplicitImport <$> (P.moduleNameFromString <$> o .: "module")
@@ -82,7 +80,7 @@ data ListType = LoadedModules | Imports FilePath | AvailableModules
8280
8381instance FromJSON ListType where
8482 parseJSON = withObject "ListType" $ \o -> do
85− (listType' :: String) <- o .: "type"
83+ (listType' :: Text) <- o .: "type"
8684 case listType' of
8785 "import" -> Imports <$> o .: "file"
8886 "loadedModules" -> pure LoadedModules
@@ -91,7 +89,7 @@ instance FromJSON ListType where
9189
9290instance FromJSON Command where
9391 parseJSON = withObject "command" $ \o -> do
94− (command :: String) <- o .: "command"
92+ (command :: Text) <- o .: "command"
9593 case command of
9694 "list" -> List <$> o .:? "params" .!= LoadedModules
9795 "cwd" -> pure Cwd
src/Language/PureScript/Ide/Completion.hs+6−8
@@ -1,12 +1,11 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Language.PureScript.Ide.Completion
3− (getCompletions, getExactMatches)
4− where
3+ ( getCompletions
4+ , getExactMatches
5+ ) where
56
6−import Prelude ()
7−import Prelude.Compat
7+import Protolude
88
9−import Data.Text (Text)
109import Language.PureScript.Ide.Filter
1110import Language.PureScript.Ide.Matcher
1211import Language.PureScript.Ide.Types
@@ -15,12 +14,11 @@ import Language.PureScript.Ide.Types
1514-- and sorts the found Completions according to the Matching Score
1615getCompletions :: [Filter] -> Matcher -> [Module] -> [Match]
1716getCompletions filters matcher modules =
18− runMatcher matcher $ completionsFromModules (applyFilters filters modules)
17+ runMatcher matcher (completionsFromModules (applyFilters filters modules))
1918
2019getExactMatches :: Text -> [Filter] -> [Module] -> [Match]
2120getExactMatches search filters modules =
22− completionsFromModules $
23− applyFilters (equalityFilter search : filters) modules
21+ completionsFromModules (applyFilters (equalityFilter search : filters) modules)
2422
2523completionsFromModules :: [Module] -> [Match]
2624completionsFromModules = foldMap completionFromModule
src/Language/PureScript/Ide/Conversions.hs+7−8
@@ -14,23 +14,22 @@
1414
1515module Language.PureScript.Ide.Conversions where
1616
17−import Prelude.Compat
18−import Data.Text (Text)
19−import qualified Data.Text as T
17+import Protolude
18+import Data.Text (unwords, lines, strip)
2019import qualified Language.PureScript as P
2120
2221runProperNameT :: P.ProperName a -> Text
23−runProperNameT = T.pack . P.runProperName
22+runProperNameT = toS . P.runProperName
2423
2524runIdentT :: P.Ident -> Text
26−runIdentT = T.pack . P.runIdent
25+runIdentT = toS . P.runIdent
2726
2827runOpNameT :: P.OpName a -> Text
29−runOpNameT = T.pack . P.runOpName
28+runOpNameT = toS . P.runOpName
3029
3130runModuleNameT :: P.ModuleName -> Text
32−runModuleNameT = T.pack . P.runModuleName
31+runModuleNameT = toS . P.runModuleName
3332
3433prettyTypeT :: P.Type -> Text
35−prettyTypeT = T.unwords . fmap T.strip . T.lines . T.pack . P.prettyPrintType
34+prettyTypeT = unwords . map strip . lines . toS . P.prettyPrintType
3635
src/Language/PureScript/Ide/Error.hs+9−12
@@ -14,25 +14,22 @@
1414
1515{-# LANGUAGE OverloadedStrings #-}
1616module Language.PureScript.Ide.Error
17− (ErrorMsg, PscIdeError(..), textError)
18− where
17+ ( PscIdeError(..)
18+ , textError
19+ ) where
1920
20−import Prelude.Compat
21+import Protolude
2122import Data.Aeson
22−import Data.Monoid
23−import Data.Text (Text, pack)
2423import Language.PureScript.Errors.JSON
2524import Language.PureScript.Ide.Types (ModuleIdent)
2625import qualified Text.Parsec.Error as P
2726
28−type ErrorMsg = String
29−
3027data PscIdeError
31− = GeneralError ErrorMsg
28+ = GeneralError Text
3229 | NotFound Text
3330 | ModuleNotFound ModuleIdent
3431 | ModuleFileNotFound ModuleIdent
35− | ParseError P.ParseError ErrorMsg
32+ | ParseError P.ParseError Text
3633 | RebuildError [JSONError]
3734
3835instance ToJSON PscIdeError where
@@ -46,7 +43,7 @@ instance ToJSON PscIdeError where
4643 ]
4744
4845textError :: PscIdeError -> Text
49−textError (GeneralError msg) = pack msg
46+textError (GeneralError msg) = msg
5047textError (NotFound ident) = "Symbol '" <> ident <> "' not found."
5148textError (ModuleNotFound ident) = "Module '" <> ident <> "' not found."
5249textError (ModuleFileNotFound ident) = "Extern file for module " <> ident <>" could not be found"
@@ -54,5 +51,5 @@ textError (ParseError parseError msg) = let escape = show
5451 -- escape newlines and other special
5552 -- chars so we can send the error
5653 -- over the socket as a single line
57− in pack $ msg <> ": " <> show (escape parseError)
58−textError (RebuildError err) = pack (show err)
54+ in msg <> ": " <> escape parseError
55+textError (RebuildError err) = show err
src/Language/PureScript/Ide/Externs.hs+8−16
@@ -26,17 +26,10 @@ module Language.PureScript.Ide.Externs
2626 unwrapPositionedRef
2727 ) where
2828
29−import Prelude ()
30−import Prelude.Compat
29+import Protolude
3130
32−import Control.Monad.Error.Class
33−import Control.Monad.IO.Class
3431import Data.Aeson (decodeStrict)
3532import Data.List (nub)
36−import Data.Maybe (mapMaybe)
37−import Data.Monoid
38−import Data.Text (Text)
39−import qualified Data.Text as T
4033import qualified Data.ByteString as BS
4134import Language.PureScript.Ide.Error (PscIdeError (..))
4235import Language.PureScript.Ide.Types
@@ -44,17 +37,16 @@ import Language.PureScript.Ide.Util
4437
4538import qualified Language.PureScript as P
4639
40+import System.FilePath
41+
4742readExternFile :: (MonadIO m, MonadError PscIdeError m) =>
4843 FilePath -> m P.ExternsFile
4944readExternFile fp = do
5045 parseResult <- liftIO (decodeStrict <$> BS.readFile fp)
5146 case parseResult of
52− Nothing -> throwError . GeneralError $ "Parsing the extern at: " ++ fp ++ " failed"
47+ Nothing -> throwError . GeneralError $ "Parsing the extern at: " <> toS fp <> " failed"
5348 Just externs -> pure externs
5449
55−identToText :: P.Ident -> Text
56−identToText = T.pack . P.runIdent
57−
5850convertExterns :: P.ExternsFile -> ModuleOld
5951convertExterns ef = (runModuleNameT moduleName, exportDecls ++ importDecls ++ decls ++ operatorDecls ++ tyOperatorDecls)
6052 where
@@ -96,7 +88,7 @@ convertDecl P.EDTypeSynonym{..} = Just $
9688convertDecl P.EDDataConstructor{..} = Just $
9789 DataConstructor (runProperNameT edDataCtorName) edDataCtorTypeCtor edDataCtorType
9890convertDecl P.EDValue{..} = Just $
99− ValueDeclaration (identToText edValueName) edValueType
91+ ValueDeclaration (runIdentT edValueName) edValueType
10092convertDecl P.EDClass{..} = Just $ TypeClassDeclaration edClassName
10193convertDecl P.EDInstance{} = Nothing
10294
@@ -104,7 +96,7 @@ convertOperator :: P.ExternsFixity -> ExternDecl
10496convertOperator P.ExternsFixity{..} =
10597 ValueOperator
10698 efOperator
107− (T.pack (P.showQualified (either P.runIdent P.runProperName) efAlias))
99+ (toS (P.showQualified (either P.runIdent P.runProperName) efAlias))
108100 efPrecedence
109101 efAssociativity
110102
@@ -112,7 +104,7 @@ convertTypeOperator :: P.ExternsTypeFixity -> ExternDecl
112104convertTypeOperator P.ExternsTypeFixity{..} =
113105 TypeOperator
114106 efTypeOperator
115− (T.pack (P.showQualified P.runProperName efTypeAlias))
107+ (toS (P.showQualified P.runProperName efTypeAlias))
116108 efTypePrecedence
117109 efTypeAssociativity
118110
@@ -125,7 +117,7 @@ unwrapPositionedRef (P.PositionedDeclarationRef _ _ x) = x
125117unwrapPositionedRef x = x
126118
127119convertModule :: ModuleOld -> Module
128−convertModule (mn, decls) = (P.moduleNameFromString (T.unpack mn), mapMaybe convertDeclaration decls)
120+convertModule (mn, decls) = (P.moduleNameFromString (toS mn), mapMaybe convertDeclaration decls)
129121 where convertDeclaration :: ExternDecl -> Maybe IdeDeclaration
130122 convertDeclaration d = case d of
131123 ValueDeclaration i t -> Just (IdeValue i t)
src/Language/PureScript/Ide/Filter.hs+4−8
@@ -24,14 +24,10 @@ module Language.PureScript.Ide.Filter
2424 , applyFilters
2525 ) where
2626
27−import Prelude ()
28−import Prelude.Compat
27+import Protolude hiding (isPrefixOf)
2928
30−import Control.Monad
3129import Data.Aeson
32−import Data.Foldable
33−import Data.Monoid
34−import Data.Text (Text, isPrefixOf)
30+import Data.Text (isPrefixOf)
3531import Language.PureScript.Ide.Types
3632import Language.PureScript.Ide.Util
3733import qualified Language.PureScript as P
@@ -51,7 +47,7 @@ moduleFilter' moduleIdents = filter (flip elem moduleIdents . fst)
5147
5248-- | Only keeps Identifiers that start with the given prefix
5349prefixFilter :: Text -> Filter
54−prefixFilter "" = mkFilter id
50+prefixFilter "" = mkFilter identity
5551prefixFilter t = mkFilter $ identFilter prefix t
5652 where
5753 prefix :: IdeDeclaration -> Text -> Bool
@@ -80,7 +76,7 @@ applyFilters = runFilter . fold
8076
8177instance FromJSON Filter where
8278 parseJSON = withObject "filter" $ \o -> do
83− (filter' :: String) <- o .: "filter"
79+ (filter' :: Text) <- o .: "filter"
8480 case filter' of
8581 "exact" -> do
8682 params <- o .: "params"
src/Language/PureScript/Ide/Imports.hs+13−20
@@ -29,17 +29,9 @@ module Language.PureScript.Ide.Imports
2929 )
3030 where
3131
32−import Prelude.Compat
33−import Control.Applicative ((<|>))
34−import Control.Monad.Error.Class
35−import Control.Monad.IO.Class
36−import Data.Bifunctor (first, second)
37−import Data.Function (on)
38−import qualified Data.List as List
39−import Data.Maybe (isNothing)
40−import Data.Monoid ((<>))
41−import Data.Text (Text)
32+import Protolude
4233import qualified Data.Text as T
34+import Data.List (nubBy, findIndex)
4335import qualified Data.Text.IO as TIO
4436import qualified Language.PureScript as P
4537import Language.PureScript.Ide.Completion
@@ -50,6 +42,7 @@ import Language.PureScript.Ide.Filter
5042import Language.PureScript.Ide.State
5143import Language.PureScript.Ide.Types
5244import Language.PureScript.Ide.Util
45+import System.FilePath
5346
5447data Import = Import P.ModuleName P.ImportDeclarationType (Maybe P.ModuleName)
5548 deriving (Eq, Show)
@@ -85,7 +78,7 @@ parseImportsFromFile fp = do
8578 Right res -> pure res
8679 Left err -> throwError (GeneralError err)
8780
88−parseImportsWithModuleName :: [Text] -> Either String (P.ModuleName, [Import])
81+parseImportsWithModuleName :: [Text] -> Either Text (P.ModuleName, [Import])
8982parseImportsWithModuleName ls = do
9083 (P.Module _ _ mn decls _) <- moduleParse ls
9184 pure (mn, concatMap mkImport (unwrapPositioned <$> decls))
@@ -95,13 +88,13 @@ parseImportsWithModuleName ls = do
9588 mkImport (P.ImportDeclaration mn it qual) = [Import mn it qual]
9689 mkImport _ = []
9790
98−sliceImportSection :: [Text] -> Either String (P.ModuleName, [Text], [Import], [Text])
91+sliceImportSection :: [Text] -> Either Text (P.ModuleName, [Text], [Import], [Text])
9992sliceImportSection ts =
10093 case foldl step (ModuleHeader 0) (zip [0..] ts) of
10194 Res start end ->
10295 let
10396 (moduleHeader, (importSection, remainingFile)) =
104− List.splitAt (succ (end - start)) `second` List.splitAt start ts
97+ splitAt (succ (end - start)) `second` splitAt start ts
10598 in
10699 (\(mn, is) -> (mn, moduleHeader, is, remainingFile)) <$>
107100 parseImportsWithModuleName (moduleHeader <> importSection)
@@ -109,7 +102,7 @@ sliceImportSection ts =
109102 -- If we don't find any imports, we insert a newline after the module
110103 -- declaration and begin a new importsection
111104 ModuleHeader ix ->
112− let (moduleHeader, remainingFile) = List.splitAt (succ ix) ts
105+ let (moduleHeader, remainingFile) = splitAt (succ ix) ts
113106 in
114107 (\(mn, is) -> (mn, moduleHeader ++ [""], is, remainingFile)) <$>
115108 parseImportsWithModuleName moduleHeader
@@ -151,7 +144,7 @@ step (ImportSection start lastImportLine) (ix, l)
151144 | otherwise = Res start lastImportLine
152145step (Res start end) _ = Res start end
153146
154−moduleParse :: [Text] -> Either String P.Module
147+moduleParse :: [Text] -> Either Text P.Module
155148moduleParse t = first show $ do
156149 tokens <- (P.lex "" . T.unpack . T.unlines) t
157150 P.runTokenParser "<psc-ide>" P.parseModule tokens
@@ -233,11 +226,11 @@ addExplicitImport' decl moduleName imports =
233226 dtor' = P.ProperName (T.unpack dtor)
234227 in
235228 updateAtFirstOrPrepend (matchType tn) (insertDtor dtor') (P.TypeRef tn (Just [dtor'])) refs
236− insertDeclIntoRefs dr refs = List.nubBy ((==) `on` P.prettyPrintRef) (refFromDeclaration dr : refs)
229+ insertDeclIntoRefs dr refs = nubBy ((==) `on` P.prettyPrintRef) (refFromDeclaration dr : refs)
237230
238231 insertDtor dtor (P.TypeRef tn' dtors) =
239232 case dtors of
240− Just dtors' -> P.TypeRef tn' (Just (List.nub (dtor : dtors')))
233+ Just dtors' -> P.TypeRef tn' (Just (ordNub (dtor : dtors')))
241234 -- This means the import was opened. We don't add anything in this case
242235 -- import Data.Maybe (Maybe(..)) -> import Data.Maybe (Maybe(Just))
243236 Nothing -> P.TypeRef tn' Nothing
@@ -249,10 +242,10 @@ addExplicitImport' decl moduleName imports =
249242
250243updateAtFirstOrPrepend :: (a -> Bool) -> (a -> a) -> a -> [a] -> [a]
251244updateAtFirstOrPrepend p t d l =
252− case List.findIndex p l of
245+ case findIndex p l of
253246 Nothing -> d : l
254247 Just ix ->
255− let (x, a : y) = List.splitAt ix l
248+ let (x, a : y) = splitAt ix l
256249 in x ++ [t a] ++ y
257250
258251-- | Looks up the given identifier in the currently loaded modules.
@@ -321,7 +314,7 @@ prettyPrintImport' (Import mn idt qual) =
321314 T.pack $ "import " ++ P.prettyPrintImport mn idt qual
322315
323316prettyPrintImportSection :: [Import] -> [Text]
324−prettyPrintImportSection imports = map prettyPrintImport' (List.sort imports)
317+prettyPrintImportSection imports = map prettyPrintImport' (sort imports)
325318
326319-- | Writes a list of lines to @Just filepath@ and responds with a @TextResult@,
327320-- or returns the lines as a @MultilineTextResult@ if @Nothing@ was given as the
src/Language/PureScript/Ide/Matcher.hs+5−12
@@ -21,16 +21,9 @@ module Language.PureScript.Ide.Matcher
2121 , runMatcher
2222 ) where
2323
24−import Prelude ()
25−import Prelude.Compat
24+import Protolude
2625
27−import Control.Monad
2826import Data.Aeson
29−import Data.Function (on)
30−import Data.List (sortBy)
31−import Data.Maybe (mapMaybe)
32−import Data.Monoid
33−import Data.Text (Text)
3427import qualified Data.Text as T
3528import qualified Data.Text.Encoding as TE
3629import Language.PureScript.Ide.Types
@@ -45,7 +38,7 @@ newtype Matcher = Matcher (Endo [Match]) deriving (Monoid)
4538
4639instance FromJSON Matcher where
4740 parseJSON = withObject "matcher" $ \o -> do
48− (matcher :: Maybe String) <- o .:? "matcher"
41+ (matcher :: Maybe Text) <- o .:? "matcher"
4942 case matcher of
5043 Just "flex" -> do
5144 params <- o .: "params"
@@ -109,7 +102,7 @@ flexScore :: Text -> Text -> Maybe Double
109102flexScore pat str =
110103 case T.uncons pat of
111104 Nothing -> Nothing
112− Just (first, p) ->
105+ Just (first', p) ->
113106 case TE.encodeUtf8 str =~ TE.encodeUtf8 pat' :: (Int, Int) of
114107 (-1,0) -> Nothing
115108 (start,len) -> Just $ calcScore start (start + len)
@@ -120,11 +113,11 @@ flexScore pat str =
120113 -- escape prepends a backslash to "regexy" characters to prevent the
121114 -- matcher from crashing when trying to build the regex
122115 escape :: Char -> Text
123− escape c = if c `elem` ("[\\^$.|?*+(){}" :: String)
116+ escape c = if c `elem` T.unpack "[\\^$.|?*+(){}"
124117 then T.pack ['\\', c]
125118 else T.singleton c
126119 -- This just interleaves the search pattern with .*
127120 -- abcd[*] -> a.*b.*c.*d.*[*]
128− pat' = escape first <> foldMap (<> ".*") escapedPattern
121+ pat' = escape first' <> foldMap (<> ".*") escapedPattern
129122 calcScore start end =
130123 100.0 / fromIntegral ((1 + start) * (end - start + 1))
src/Language/PureScript/Ide/Pursuit.hs+5−11
@@ -16,18 +16,12 @@
1616
1717module Language.PureScript.Ide.Pursuit where
1818
19−import Prelude ()
20−import Prelude.Compat
19+import Protolude
2120
2221import qualified Control.Exception as E
2322import Data.Aeson
24−import Data.ByteString (ByteString)
2523import Data.ByteString.Lazy (fromStrict)
26−import Data.Foldable (toList)
27−import Data.Maybe (mapMaybe)
28−import Data.Monoid ((<>))
2924import Data.String
30−import Data.Text (Text)
3125import qualified Data.Text as T
3226import Language.PureScript.Ide.Types
3327import Network.HTTP.Types.Header (hAccept)
@@ -41,12 +35,12 @@ queryPursuit q = do
4135 let qClean = T.dropWhileEnd (== '.') q
4236 req' <- parseUrl "http://pursuit.purescript.org/search"
4337 let req = req'
44− { queryString=("q=" <> (fromString . T.unpack) qClean)
38+ { queryString= "q=" <> (fromString . T.unpack) qClean
4539 , requestHeaders=[(hAccept, "application/json")]
4640 }
4741 m <- newManager tlsManagerSettings
4842 withHTTP req m $ \resp ->
49− P.fold (<>) "" id $ responseBody resp
43+ P.fold (<>) "" identity (responseBody resp)
5044
5145
5246handler :: HttpException -> IO [a]
@@ -59,7 +53,7 @@ searchPursuitForDeclarations query =
5953 let results' = decode (fromStrict r) :: Maybe Array
6054 case results' of
6155 Nothing -> pure []
62− Just results -> pure (mapMaybe isDeclarationResponse (map fromJSON (toList results)))) `E.catch`
56+ Just results -> pure (mapMaybe (isDeclarationResponse . fromJSON) (toList results))) `E.catch`
6357 handler
6458 where
6559 isDeclarationResponse (Success a@DeclarationResponse{}) = Just a
@@ -71,7 +65,7 @@ findPackagesForModuleIdent query =
7165 let results' = decode (fromStrict r) :: Maybe Array
7266 case results' of
7367 Nothing -> pure []
74− Just results -> pure (mapMaybe isModuleResponse (map fromJSON (toList results)))) `E.catch`
68+ Just results -> pure (mapMaybe (isModuleResponse . fromJSON) (toList results))) `E.catch`
7569 handler
7670 where
7771 isModuleResponse (Success a@ModuleResponse{}) = Just a
src/Language/PureScript/Ide/Rebuild.hs+11−13
@@ -8,14 +8,12 @@ module Language.PureScript.Ide.Rebuild
88 ( rebuildFile
99 ) where
1010
11−import Control.Monad.Error.Class
12−import Control.Monad.IO.Class
11+import Protolude
12+
1313import "monad-logger" Control.Monad.Logger
14−import Control.Monad.Reader
15−import Control.Monad.Trans.Except
14+import qualified Data.List as List
1615import qualified Data.Map.Lazy as M
17−import Data.Maybe (fromJust, mapMaybe)
18−import Data.Monoid ((<>))
16+import Data.Maybe (fromJust)
1917import qualified Data.Set as S
2018import qualified Language.PureScript as P
2119import Language.PureScript.Errors.JSON
@@ -23,8 +21,8 @@ import Language.PureScript.Ide.Error
2321import Language.PureScript.Ide.State
2422import Language.PureScript.Ide.Types
2523import Language.PureScript.Ide.Util
26−import Prelude.Compat
2724import System.IO.UTF8 (readUTF8File)
25+import System.FilePath
2826
2927-- | Given a filepath performs the following steps:
3028--
@@ -49,7 +47,7 @@ rebuildFile path = do
4947
5048 input <- liftIO (readUTF8File path)
5149
52− m <- case snd <$> P.parseModuleFromFile id (path, input) of
50+ m <- case snd <$> P.parseModuleFromFile identity (path, input) of
5351 Left parseError -> throwError
5452 . RebuildError
5553 . toJSONErrors False P.Error
@@ -106,8 +104,8 @@ rebuildModuleOpen makeEnv externs m = do
106104data MakeActionsEnv =
107105 MakeActionsEnv
108106 { maeOutputDirectory :: FilePath
109− , maeFilePathMap :: M.Map P.ModuleName (Either P.RebuildPolicy FilePath)
110− , maeForeignPathMap :: M.Map P.ModuleName FilePath
107+ , maeFilePathMap :: Map P.ModuleName (Either P.RebuildPolicy FilePath)
108+ , maeForeignPathMap :: Map P.ModuleName FilePath
111109 , maePrefixComment :: Bool
112110 }
113111
@@ -137,7 +135,7 @@ shushCodegen ma MakeActionsEnv{..} =
137135sortExterns
138136 :: (Ide m, MonadError PscIdeError m)
139137 => P.Module
140− -> M.Map P.ModuleName P.ExternsFile
138+ -> Map P.ModuleName P.ExternsFile
141139 -> m [P.ExternsFile]
142140sortExterns m ex = do
143141 sorted' <- runExceptT
@@ -149,11 +147,11 @@ sortExterns m ex = do
149147 case sorted' of
150148 Left _ -> throwError (GeneralError "There was a cycle in the dependencies")
151149 Right (sorted, graph) -> do
152− let deps = fromJust (lookup (P.getModuleName m) graph)
150+ let deps = fromJust (List.lookup (P.getModuleName m) graph)
153151 pure $ mapMaybe getExtern (deps `inOrderOf` map P.getModuleName sorted)
154152 where
155153 mkShallowModule P.ExternsFile{..} =
156− P.Module undefined [] efModuleName (map mkImport efImports) Nothing
154+ P.Module (P.internalModuleSourceSpan "<rebuild>") [] efModuleName (map mkImport efImports) Nothing
157155 mkImport (P.ExternsImport mn it iq) =
158156 P.ImportDeclaration mn it iq
159157 getExtern mn = M.lookup mn ex
src/Language/PureScript/Ide/Reexports.hs+4−6
@@ -24,16 +24,14 @@ module Language.PureScript.Ide.Reexports
2424 ) where
2525
2626
27−import Prelude ()
28−import Prelude.Compat
27+import Protolude
2928
3029import Data.List (union)
31−import Data.Map (Map)
3230import qualified Data.Map as Map
33−import Data.Maybe
3431import qualified Data.Text as T
3532import Language.PureScript.Ide.Types
3633import Language.PureScript.Ide.Externs
34+import qualified Language.PureScript as P
3735
3836getReexports :: ModuleOld -> [ExternDecl]
3937getReexports (mn, decls)= concatMap getExport decls
@@ -59,7 +57,7 @@ replaceExportWithAliases decls ident =
5957replaceReexport :: ExternDecl -> ModuleOld -> ModuleOld -> ModuleOld
6058replaceReexport e@(Export _) (m, decls) (_, newDecls) =
6159 (m, filter (/= e) decls `union` newDecls)
62−replaceReexport _ _ _ = error "Should only get Exports here."
60+replaceReexport _ _ _ = P.internalError "Should only get Exports here"
6361
6462emptyModule :: ModuleOld
6563emptyModule = ("Empty", [])
@@ -79,7 +77,7 @@ replaceReexports m db = result
7977
8078 go :: ModuleOld -> ExternDecl -> ModuleOld
8179 go m' re@(Export name) = replaceReexport re m' (getModule name)
82− go _ _ = error "partiality! woohoo"
80+ go _ _ = P.internalError "Should only get Exports here"
8381
8482 getModule :: ModuleIdent -> ModuleOld
8583 getModule name = clean res
src/Language/PureScript/Ide/SourceFile.hs+34−44
@@ -16,27 +16,20 @@
1616
1717module Language.PureScript.Ide.SourceFile where
1818
19−import Prelude
19+import Protolude
2020
21−import Control.Monad.Error.Class
22−import Control.Monad.IO.Class
23−import Control.Monad.Trans.Except
24−import Data.Maybe (mapMaybe)
25−import Data.Monoid
26−import qualified Data.Text as T
27−import qualified Language.PureScript.AST.Declarations as D
28−import qualified Language.PureScript.AST.SourcePos as SP
21+import qualified Language.PureScript as P
2922import Language.PureScript.Ide.Error
23+import Language.PureScript.Ide.Util
3024import Language.PureScript.Ide.Externs (unwrapPositioned,
3125 unwrapPositionedRef)
3226import Language.PureScript.Ide.Types
33−import qualified Language.PureScript.Names as N
34−import qualified Language.PureScript.Parser as P
3527import System.Directory
28+import System.FilePath
3629import System.IO.UTF8 (readUTF8File)
3730
3831parseModuleFromFile :: (MonadIO m, MonadError PscIdeError m) =>
39− FilePath -> m D.Module
32+ FilePath -> m P.Module
4033parseModuleFromFile fp = do
4134 exists <- liftIO (doesFileExist fp)
4235 if exists
@@ -49,14 +42,14 @@ parseModuleFromFile fp = do
4942
5043-- data Module = Module SourceSpan [Comment] ModuleName [Declaration] (Maybe [DeclarationRef])
5144
52−getDeclarations :: D.Module -> [D.Declaration]
53−getDeclarations (D.Module _ _ _ declarations _) = declarations
45+getDeclarations :: P.Module -> [P.Declaration]
46+getDeclarations (P.Module _ _ _ declarations _) = declarations
5447
55−getImports :: D.Module -> [D.Declaration]
56−getImports (D.Module _ _ _ declarations _) =
48+getImports :: P.Module -> [(P.ModuleName, P.ImportDeclarationType, Maybe P.ModuleName)]
49+getImports (P.Module _ _ _ declarations _) =
5750 mapMaybe isImport declarations
5851 where
59− isImport (D.PositionedDeclaration _ _ (i@D.ImportDeclaration{})) = Just i
52+ isImport (P.PositionedDeclaration _ _ (P.ImportDeclaration a b c)) = Just (a, b, c)
6053 isImport _ = Nothing
6154
6255getImportsForFile :: (MonadIO m, MonadError PscIdeError m) =>
@@ -66,53 +59,50 @@ getImportsForFile fp = do
6659 let imports = getImports module'
6760 pure (mkModuleImport . unwrapPositionedImport <$> imports)
6861 where
69− mkModuleImport (D.ImportDeclaration mn importType' qualifier) =
62+ mkModuleImport (mn, importType', qualifier) =
7063 ModuleImport
71− (T.pack (N.runModuleName mn))
64+ (runModuleNameT mn)
7265 importType'
73− (T.pack . N.runModuleName <$> qualifier)
74− mkModuleImport _ = error "Shouldn't have gotten anything but Imports here"
75− unwrapPositionedImport (D.ImportDeclaration mn importType' qualifier) =
76− D.ImportDeclaration mn (unwrapImportType importType') qualifier
77− unwrapPositionedImport x = x
78− unwrapImportType (D.Explicit decls) = D.Explicit (map unwrapPositionedRef decls)
79− unwrapImportType (D.Hiding decls) = D.Hiding (map unwrapPositionedRef decls)
80− unwrapImportType D.Implicit = D.Implicit
66+ (runModuleNameT <$> qualifier)
67+ unwrapPositionedImport (mn, it, q) = (mn, unwrapImportType it, q)
68+ unwrapImportType (P.Explicit decls) = P.Explicit (map unwrapPositionedRef decls)
69+ unwrapImportType (P.Hiding decls) = P.Hiding (map unwrapPositionedRef decls)
70+ unwrapImportType P.Implicit = P.Implicit
8171
82−getPositionedImports :: D.Module -> [D.Declaration]
83−getPositionedImports (D.Module _ _ _ declarations _) =
72+getPositionedImports :: P.Module -> [P.Declaration]
73+getPositionedImports (P.Module _ _ _ declarations _) =
8474 mapMaybe isImport declarations
8575 where
86− isImport i@(D.PositionedDeclaration _ _ D.ImportDeclaration{}) = Just i
76+ isImport i@(P.PositionedDeclaration _ _ P.ImportDeclaration{}) = Just i
8777 isImport _ = Nothing
8878
89−getDeclPosition :: D.Module -> String -> Maybe SP.SourceSpan
79+getDeclPosition :: P.Module -> Text -> Maybe P.SourceSpan
9080getDeclPosition m ident = getFirst (foldMap (match ident) decls)
9181 where
9282 decls = getDeclarations m
93− match q (D.PositionedDeclaration ss _ decl) = First (if go q decl
83+ match q (P.PositionedDeclaration ss _ decl) = First (if go q decl
9484 then Just ss
9585 else Nothing)
9686 match _ _ = First Nothing
9787
98− go q (D.DataDeclaration _ name _ constructors) =
88+ go q (P.DataDeclaration _ name _ constructors) =
9989 properEqual name q || any (\(x,_) -> properEqual x q) constructors
100− go q (D.DataBindingGroupDeclaration decls') = any (go q) decls'
101− go q (D.TypeSynonymDeclaration name _ _) = properEqual name q
102− go q (D.TypeDeclaration ident' _) = identEqual ident' q
103− go q (D.ValueDeclaration ident' _ _ _) = identEqual ident' q
104− go q (D.ExternDeclaration ident' _) = identEqual ident' q
105− go q (D.ExternDataDeclaration name _) = properEqual name q
106− go q (D.TypeClassDeclaration name _ _ members) =
90+ go q (P.DataBindingGroupDeclaration decls') = any (go q) decls'
91+ go q (P.TypeSynonymDeclaration name _ _) = properEqual name q
92+ go q (P.TypeDeclaration ident' _) = identEqual ident' q
93+ go q (P.ValueDeclaration ident' _ _ _) = identEqual ident' q
94+ go q (P.ExternDeclaration ident' _) = identEqual ident' q
95+ go q (P.ExternDataDeclaration name _) = properEqual name q
96+ go q (P.TypeClassDeclaration name _ _ members) =
10797 properEqual name q || any (go q . unwrapPositioned) members
108− go q (D.TypeInstanceDeclaration ident' _ _ _ _) =
98+ go q (P.TypeInstanceDeclaration ident' _ _ _ _) =
10999 identEqual ident' q
110100 go _ _ = False
111101
112− properEqual x q = N.runProperName x == q
113− identEqual x q = N.runIdent x == q
102+ properEqual x q = runProperNameT x == q
103+ identEqual x q = runIdentT x == q
114104
115−goToDefinition :: String -> FilePath -> IO (Maybe SP.SourceSpan)
105+goToDefinition :: Text -> FilePath -> IO (Maybe P.SourceSpan)
116106goToDefinition q fp = do
117107 m <- runExceptT (parseModuleFromFile fp)
118108 case m of
src/Language/PureScript/Ide/State.hs+1−5
@@ -33,15 +33,11 @@ module Language.PureScript.Ide.State
3333 , populateStage2STM
3434 ) where
3535
36−import Prelude ()
37−import Prelude.Compat
36+import Protolude
3837
3938import Control.Concurrent.STM
40−import Control.Monad.IO.Class
4139import "monad-logger" Control.Monad.Logger
42−import Control.Monad.Reader.Class
4340import qualified Data.Map.Lazy as M
44−import Data.Monoid
4541import qualified Data.Text as T
4642import Data.Time (getCurrentTime, diffUTCTime)
4743import Language.PureScript.Externs
src/Language/PureScript/Ide/Types.hs+10−16
@@ -16,22 +16,16 @@
1616
1717module Language.PureScript.Ide.Types where
1818
19−import Prelude ()
20−import Prelude.Compat
19+import Protolude
2120
2221import Control.Concurrent.STM
23−import Control.Monad
24−import Control.Monad.Reader.Class
25−import Control.Monad.Trans
2622import Data.Aeson
2723import Data.Map.Lazy as M
28−import Data.Maybe (maybeToList)
29−import Data.Text (Text, pack, unpack)
3024import qualified Language.PureScript.Errors.JSON as P
3125import qualified Language.PureScript as P
3226import Language.PureScript.Ide.Conversions
33−
34−import Text.Parsec
27+import System.FilePath
28+import Text.Parsec as Parsec
3529import Text.Parsec.Text
3630
3731type Ident = Text
@@ -219,7 +213,7 @@ instance FromJSON PursuitResponse where
219213 parseJSON (Object o) = do
220214 package <- o .: "package"
221215 info <- o .: "info"
222− (type' :: String) <- info .: "type"
216+ (type' :: Text) <- info .: "type"
223217 case type' of
224218 "module" -> do
225219 name <- info .: "module"
@@ -234,26 +228,26 @@ instance FromJSON PursuitResponse where
234228
235229typeParse :: Text -> Either Text (Text, Text)
236230typeParse t = case parse parseType "" t of
237− Right (x,y) -> Right (pack x, pack y)
238− Left err -> Left (pack (show err))
231+ Right (x,y) -> Right (x, y)
232+ Left err -> Left (show err)
239233 where
240− parseType :: Parser (String, String)
234+ parseType :: Parser (Text, Text)
241235 parseType = do
242236 name <- identifier
243237 _ <- string "::"
244238 spaces
245239 type' <- many1 anyChar
246− pure (unpack name, type')
240+ pure (name, toS type')
247241
248242 identifier :: Parser Text
249243 identifier = do
250244 spaces
251245 ident <-
252246 -- necessary for being able to parse the following ((++), concat)
253− between (char '(') (char ')') (many1 (noneOf ", )")) <|>
247+ between (char '(') (char ')') (many1 (noneOf ", )")) Parsec.<|>
254248 many1 (noneOf ", )")
255249 spaces
256− pure (pack ident)
250+ pure (toS ident)
257251
258252instance ToJSON PursuitResponse where
259253 toJSON (ModuleResponse name package) =
src/Language/PureScript/Ide/Util.hs+5−12
@@ -20,16 +20,12 @@ module Language.PureScript.Ide.Util
2020 , completionFromMatch
2121 , encodeT
2222 , decodeT
23− , unlessM
2423 , module Language.PureScript.Ide.Conversions
2524 ) where
2625
27−import Prelude.Compat
28−import Control.Monad (unless)
26+import Protolude
2927import Data.Aeson
30−import Data.Text (Text)
3128import qualified Data.Text as T
32−import Data.Text.Lazy (fromStrict, toStrict)
3329import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
3430import qualified Language.PureScript as P
3531import Language.PureScript.Ide.Types
@@ -51,7 +47,7 @@ identifierFromMatch (Match _ ed) = identifierFromIdeDeclaration ed
5147completionFromMatch :: Match -> Completion
5248completionFromMatch (Match m' d) = case d of
5349 IdeValue name type' -> Completion (m, name, prettyTypeT type')
54− IdeType name kind -> Completion (m, runProperNameT name, T.pack $ P.prettyPrintKind kind)
50+ IdeType name kind -> Completion (m, runProperNameT name, toS (P.prettyPrintKind kind))
5551 IdeTypeSynonym name kind -> Completion (m, runProperNameT name, prettyTypeT kind)
5652 IdeDataConstructor name _ type' -> Completion (m, name, prettyTypeT type')
5753 IdeTypeClass name -> Completion (m, runProperNameT name, "class")
@@ -64,13 +60,10 @@ completionFromMatch (Match m' d) = case d of
6460 P.Infix -> "infix"
6561 P.Infixl -> "infixl"
6662 P.Infixr -> "infixr"
67− in T.unwords [asso, T.pack (show p), r, "as", runOpNameT o]
63+ in T.unwords [asso, show p, r, "as", runOpNameT o]
6864
6965encodeT :: (ToJSON a) => a -> Text
70−encodeT = toStrict . decodeUtf8 . encode
66+encodeT = toS . decodeUtf8 . encode
7167
7268decodeT :: (FromJSON a) => Text -> Maybe a
73−decodeT = decode . encodeUtf8 . fromStrict
74−
75−unlessM :: Monad m => m Bool -> m () -> m ()
76−unlessM cond act = cond >>= flip unless act
69+decodeT = decode . encodeUtf8 . toS
src/Language/PureScript/Ide/Watcher.hs+2−4
@@ -14,14 +14,12 @@
1414
1515module Language.PureScript.Ide.Watcher where
1616
17−import Control.Concurrent (threadDelay)
17+import Protolude
18+
1819import Control.Concurrent.STM
19−import Control.Monad
20−import Control.Monad.Trans.Except
2120import Language.PureScript.Ide.Externs
2221import Language.PureScript.Ide.State
2322import Language.PureScript.Ide.Types
24−import Prelude
2523import System.FilePath
2624import System.FSNotify
2725
tests/Language/PureScript/Ide/FilterSpec.hs+13−11
@@ -1,7 +1,8 @@
11{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE NoImplicitPrelude #-}
23module Language.PureScript.Ide.FilterSpec where
34
4−import Data.Text (Text)
5+import Protolude
56import Language.PureScript.Ide.Filter
67import Language.PureScript.Ide.Types
78import qualified Language.PureScript as P
@@ -10,11 +11,12 @@ import Test.Hspec
1011value :: Text -> IdeDeclaration
1112value s = IdeValue s $ P.TypeWildcard $ P.SourceSpan "" (P.SourcePos 0 0) (P.SourcePos 0 0)
1213
14+moduleA, moduleB :: Module
15+moduleA = (P.moduleNameFromString "Module.A", [value "function1"])
16+moduleB = (P.moduleNameFromString "Module.B", [value "data1"])
17+
1318modules :: [Module]
14−modules =
15− [ (P.moduleNameFromString "Module.A", [value "function1"])
16− , (P.moduleNameFromString "Module.B", [value "data1"])
17− ]
19+modules = [moduleA, moduleB]
1820
1921runEq :: Text -> [Module]
2022runEq s = runFilter (equalityFilter s) modules
@@ -31,20 +33,20 @@ spec = do
3133 it "removes empty modules" $
3234 runEq "test" `shouldBe` []
3335 it "keeps function declarations that are equal" $
34− runEq "function1" `shouldBe` [head modules]
36+ runEq "function1" `shouldBe` [moduleA]
3537 it "keeps data declarations that are equal" $
36− runEq "data1" `shouldBe` [modules !! 1]
38+ runEq "data1" `shouldBe` [moduleB]
3739 describe "prefixFilter" $ do
3840 it "keeps everything on empty string" $
3941 runPrefix "" `shouldBe` modules
4042 it "keeps functionname prefix matches" $
41− runPrefix "fun" `shouldBe` [head modules]
43+ runPrefix "fun" `shouldBe` [moduleA]
4244 it "keeps data decls prefix matches" $
43− runPrefix "dat" `shouldBe` [modules !! 1]
45+ runPrefix "dat" `shouldBe` [moduleB]
4446 describe "moduleFilter" $ do
4547 it "removes everything on empty input" $
4648 runModule [] `shouldBe` []
4749 it "only keeps the specified modules" $
48− runModule [P.moduleNameFromString "Module.A"] `shouldBe` [head modules]
50+ runModule [P.moduleNameFromString "Module.A"] `shouldBe` [moduleA]
4951 it "ignores modules that are not in scope" $
50− runModule (P.moduleNameFromString <$> ["Module.A", "Unknown"]) `shouldBe` [head modules]
52+ runModule (P.moduleNameFromString <$> ["Module.A", "Unknown"]) `shouldBe` [moduleA]
tests/Language/PureScript/Ide/Imports/IntegrationSpec.hs+4−2
@@ -1,8 +1,10 @@
11{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE NoImplicitPrelude #-}
23module Language.PureScript.Ide.Imports.IntegrationSpec where
34
4−import Control.Monad (void)
5−import Data.Text (Text)
5+
6+import Protolude
7+
68import qualified Data.Text as T
79import qualified Data.Text.IO as TIO
810import qualified Language.PureScript.Ide.Integration as Integration
tests/Language/PureScript/Ide/ImportsSpec.hs+6−6
@@ -1,8 +1,10 @@
11{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE NoImplicitPrelude #-}
23module Language.PureScript.Ide.ImportsSpec where
34
4−import Data.Maybe (fromJust)
5−import Data.Text (Text)
5+import Protolude
6+import Unsafe (fromJust)
7+
68import qualified Language.PureScript as P
79import Language.PureScript.Ide.Imports
810import Language.PureScript.Ide.Types
@@ -17,11 +19,9 @@ simpleFile =
1719 ]
1820
1921splitSimpleFile :: (P.ModuleName, [Text], [Import], [Text])
20−splitSimpleFile = fromRight $ sliceImportSection simpleFile
22+splitSimpleFile = fromRight (sliceImportSection simpleFile)
2123 where
22− fromRight (Right r) = r
23− fromRight (Left _) = error "fromRight"
24−
24+ fromRight = fromJust . rightToMaybe
2525withImports :: [Text] -> [Text]
2626withImports is =
2727 take 2 simpleFile ++ is ++ drop 2 simpleFile
tests/Language/PureScript/Ide/Integration.hs+53−72
@@ -14,6 +14,7 @@
1414
1515{-# LANGUAGE OverloadedStrings #-}
1616{-# LANGUAGE ScopedTypeVariables #-}
17+{-# LANGUAGE NoImplicitPrelude #-}
1718module Language.PureScript.Ide.Integration
1819 (
1920 -- managing the server process
@@ -44,19 +45,15 @@ module Language.PureScript.Ide.Integration
4445 , parseTextResult
4546 ) where
4647
47−import Control.Concurrent (threadDelay)
48−import Control.Exception
49−import Control.Monad (join, when)
48+import Protolude
49+import Unsafe (fromJust)
50+
5051import Data.Aeson
5152import Data.Aeson.Types
52−import qualified Data.ByteString.Lazy.UTF8 as BSL
53−import Data.Either (isRight)
54−import Data.Maybe (fromJust, isNothing, fromMaybe)
5553import qualified Data.Text as T
5654import qualified Data.Vector as V
5755import Language.PureScript.Ide.Util
5856import System.Directory
59−import System.Exit
6057import System.FilePath
6158import System.IO.Error (mkIOError, userErrorType)
6259import System.Process
@@ -81,26 +78,23 @@ stopServer = terminateProcess
8178withServer :: IO a -> IO a
8279withServer s = do
8380 _ <- startServer
84− started <- tryNTimes 5 (shush <$> (try getCwd :: IO (Either SomeException String)))
81+ started <- tryNTimes 5 (rightToMaybe <$> (try getCwd :: IO (Either SomeException Text)))
8582 when (isNothing started) $
8683 throwIO (mkIOError userErrorType "psc-ide-server didn't start in time" Nothing Nothing)
8784 r <- s
8885 quitServer
8986 pure r
9087
91−shush :: Either a b -> Maybe b
92−shush = either (const Nothing) Just
93−
9488-- project management utils
9589
9690compileTestProject :: IO Bool
9791compileTestProject = do
9892 pdir <- projectDirectory
9993 (_, _, _, procHandle) <- createProcess $
100− (shell $ "psc " ++ fileGlob) { cwd = Just pdir
101− , std_out = CreatePipe
102− , std_err = CreatePipe
103− }
94+ (shell . toS $ "psc " <> fileGlob) { cwd = Just pdir
95+ , std_out = CreatePipe
96+ , std_err = CreatePipe
97+ }
10498 r <- tryNTimes 5 (getProcessExitCode procHandle)
10599 pure (fromMaybe False (isSuccess <$> r))
106100
@@ -122,24 +116,17 @@ deleteOutputFolder = do
122116deleteFileIfExists :: FilePath -> IO ()
123117deleteFileIfExists fp = whenM (doesFileExist fp) (removeFile fp)
124118
125−whenM :: Monad m => m Bool -> m () -> m ()
126−whenM p f = do
127− x <- p
128− when x f
129−
130119isSuccess :: ExitCode -> Bool
131120isSuccess ExitSuccess = True
132121isSuccess (ExitFailure _) = False
133122
134−fileGlob :: String
135−fileGlob = unwords
136− [ "\"src/**/*.purs\""
137− ]
123+fileGlob :: Text
124+fileGlob = "\"src/**/*.purs\""
138125
139126-- Integration Testing API
140127
141−sendCommand :: Value -> IO String
142−sendCommand v = readCreateProcess
128+sendCommand :: Value -> IO Text
129+sendCommand v = toS <$> readCreateProcess
143130 ((shell "psc-ide-client") { std_out=CreatePipe
144131 , std_err=CreatePipe
145132 })
@@ -147,68 +134,68 @@ sendCommand v = readCreateProcess
147134
148135quitServer :: IO ()
149136quitServer = do
150− let quitCommand = object ["command" .= ("quit" :: String)]
151− _ <- try $ sendCommand quitCommand :: IO (Either SomeException String)
137+ let quitCommand = object ["command" .= ("quit" :: Text)]
138+ _ <- try $ sendCommand quitCommand :: IO (Either SomeException Text)
152139 return ()
153140
154141reset :: IO ()
155142reset = do
156− let resetCommand = object ["command" .= ("reset" :: String)]
157− _ <- try $ sendCommand resetCommand :: IO (Either SomeException String)
143+ let resetCommand = object ["command" .= ("reset" :: Text)]
144+ _ <- try $ sendCommand resetCommand :: IO (Either SomeException Text)
158145 return ()
159146
160−getCwd :: IO String
147+getCwd :: IO Text
161148getCwd = do
162− let cwdCommand = object ["command" .= ("cwd" :: String)]
149+ let cwdCommand = object ["command" .= ("cwd" :: Text)]
163150 sendCommand cwdCommand
164151
165−loadModule :: String -> IO String
152+loadModule :: Text -> IO Text
166153loadModule m = loadModules [m]
167154
168−loadModules :: [String] -> IO String
155+loadModules :: [Text] -> IO Text
169156loadModules = sendCommand . load
170157
171−loadAll :: IO String
158+loadAll :: IO Text
172159loadAll = sendCommand (load [])
173160
174−getFlexCompletions :: String -> IO [(String, String, String)]
161+getFlexCompletions :: Text -> IO [(Text, Text, Text)]
175162getFlexCompletions q = parseCompletions <$> sendCommand (completion [] (Just (flexMatcher q)) Nothing)
176163
177−getFlexCompletionsInModule :: String -> String -> IO [(String, String, String)]
164+getFlexCompletionsInModule :: Text -> Text -> IO [(Text, Text, Text)]
178165getFlexCompletionsInModule q m = parseCompletions <$> sendCommand (completion [] (Just (flexMatcher q)) (Just m))
179166
180−getType :: String -> IO [(String, String, String)]
167+getType :: Text -> IO [(Text, Text, Text)]
181168getType q = parseCompletions <$> sendCommand (typeC q [])
182169
183−addImport :: String -> FilePath -> FilePath -> IO String
170+addImport :: Text -> FilePath -> FilePath -> IO Text
184171addImport identifier fp outfp = sendCommand (addImportC identifier fp outfp)
185172
186−addImplicitImport :: String -> FilePath -> FilePath -> IO String
173+addImplicitImport :: Text -> FilePath -> FilePath -> IO Text
187174addImplicitImport mn fp outfp = sendCommand (addImplicitImportC mn fp outfp)
188175
189−rebuildModule :: FilePath -> IO String
176+rebuildModule :: FilePath -> IO Text
190177rebuildModule m = sendCommand (rebuildC m Nothing)
191178
192179-- Command Encoding
193180
194−commandWrapper :: String -> Value -> Value
181+commandWrapper :: Text -> Value -> Value
195182commandWrapper c p = object ["command" .= c, "params" .= p]
196183
197−load :: [String] -> Value
184+load :: [Text] -> Value
198185load ms = commandWrapper "load" (object ["modules" .= ms])
199186
200−typeC :: String -> [Value] -> Value
187+typeC :: Text -> [Value] -> Value
201188typeC q filters = commandWrapper "type" (object ["search" .= q, "filters" .= filters])
202189
203−addImportC :: String -> FilePath -> FilePath -> Value
190+addImportC :: Text -> FilePath -> FilePath -> Value
204191addImportC identifier = addImportW $
205− object [ "importCommand" .= ("addImport" :: String)
192+ object [ "importCommand" .= ("addImport" :: Text)
206193 , "identifier" .= identifier
207194 ]
208195
209−addImplicitImportC :: String -> FilePath -> FilePath -> Value
196+addImplicitImportC :: Text -> FilePath -> FilePath -> Value
210197addImplicitImportC mn = addImportW $
211− object [ "importCommand" .= ("addImplicitImport" :: String)
198+ object [ "importCommand" .= ("addImplicitImport" :: Text)
212199 , "module" .= mn
213200 ]
214201
@@ -226,7 +213,7 @@ addImportW importCommand fp outfp =
226213 ])
227214
228215
229−completion :: [Value] -> Maybe Value -> Maybe String -> Value
216+completion :: [Value] -> Maybe Value -> Maybe Text -> Value
230217completion filters matcher currentModule =
231218 let
232219 matcher' = case matcher of
@@ -238,16 +225,16 @@ completion filters matcher currentModule =
238225 in
239226 commandWrapper "complete" (object $ "filters" .= filters : matcher' ++ currentModule' )
240227
241−flexMatcher :: String -> Value
242−flexMatcher q = object [ "matcher" .= ("flex" :: String)
228+flexMatcher :: Text -> Value
229+flexMatcher q = object [ "matcher" .= ("flex" :: Text)
243230 , "params" .= object ["search" .= q]
244231 ]
245232
246233-- Result parsing
247234
248−unwrapResult :: Value -> Parser (Either String Value)
235+unwrapResult :: Value -> Parser (Either Text Value)
249236unwrapResult = withObject "result" $ \o -> do
250− (rt :: String) <- o .: "resultType"
237+ (rt :: Text) <- o .: "resultType"
251238 case rt of
252239 "error" -> do
253240 res <- o .: "result"
@@ -255,16 +242,16 @@ unwrapResult = withObject "result" $ \o -> do
255242 "success" -> do
256243 res <- o .: "result"
257244 pure (Right res)
258− _ -> fail "lol"
245+ _ -> mzero
259246
260−withResult :: (Value -> Parser a) -> Value -> Parser (Either String a)
247+withResult :: (Value -> Parser a) -> Value -> Parser (Either Text a)
261248withResult p v = do
262249 r <- unwrapResult v
263250 case r of
264251 Left err -> pure (Left err)
265252 Right res -> Right <$> p res
266253
267−completionParser :: Value -> Parser [(String, String, String)]
254+completionParser :: Value -> Parser [(Text, Text, Text)]
268255completionParser = withArray "res" $ \cs ->
269256 mapM (withObject "completion" $ \o -> do
270257 ident <- o .: "identifier"
@@ -272,22 +259,16 @@ completionParser = withArray "res" $ \cs ->
272259 ty <- o .: "type"
273260 pure (module', ident, ty)) (V.toList cs)
274261
275−valueFromString :: String -> Value
276−valueFromString = fromJust . decode . BSL.fromString
262+valueFromText :: Text -> Value
263+valueFromText = fromJust . decode . toS
277264
278−resultIsSuccess :: String -> Bool
279−resultIsSuccess = isRight . join . parseEither unwrapResult . valueFromString
265+resultIsSuccess :: Text -> Bool
266+resultIsSuccess = isRight . join . first toS . parseEither unwrapResult . valueFromText
280267
281−parseCompletions :: String -> [(String, String, String)]
282−parseCompletions s = fromJust $ do
283− cs <- parseMaybe (withResult completionParser) (valueFromString s)
284− case cs of
285− Left _ -> error "Failed to parse completions"
286− Right cs' -> pure cs'
268+parseCompletions :: Text -> [(Text, Text, Text)]
269+parseCompletions s =
270+ fromJust $ join (rightToMaybe <$> parseMaybe (withResult completionParser) (valueFromText s))
287271
288−parseTextResult :: String -> String
289−parseTextResult s = fromJust $ do
290− r <- parseMaybe (withResult (withText "tr" pure)) (valueFromString s)
291− case r of
292− Left _ -> error "Failed to parse textResult"
293− Right r' -> pure (T.unpack r')
272+parseTextResult :: Text -> Text
273+parseTextResult s =
274+ fromJust $ join (rightToMaybe <$> parseMaybe (withResult (withText "tr" pure)) (valueFromText s))
tests/Language/PureScript/Ide/MatcherSpec.hs+11−12
@@ -1,9 +1,10 @@
11{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE NoImplicitPrelude #-}
23
34module Language.PureScript.Ide.MatcherSpec where
45
5−import Control.Monad (void)
6−import Data.Text (Text)
6+import Protolude
7+
78import qualified Language.PureScript as P
89import Language.PureScript.Ide.Integration
910import Language.PureScript.Ide.Matcher
@@ -13,15 +14,13 @@ import Test.Hspec
1314value :: Text -> IdeDeclaration
1415value s = IdeValue s $ P.TypeWildcard $ P.SourceSpan "" (P.SourcePos 0 0) (P.SourcePos 0 0)
1516
16−completions :: [Match]
17−completions =
18− [ Match (P.moduleNameFromString "Match") (value "firstResult")
19− , Match (P.moduleNameFromString "Match") (value "secondResult")
20− , Match (P.moduleNameFromString "Match") (value "fiult")
21− ]
17+firstResult, secondResult, fiult :: Match
18+firstResult = Match (P.moduleNameFromString "Match") (value "firstResult")
19+secondResult = Match (P.moduleNameFromString "Match") (value "secondResult")
20+fiult = Match (P.moduleNameFromString "Match") (value "fiult")
2221
23−mkResult :: [Int] -> [Match]
24−mkResult = map (completions !!)
22+completions :: [Match]
23+completions = [firstResult, secondResult, fiult]
2524
2625runFlex :: Text -> [Match]
2726runFlex s = runMatcher (flexMatcher s) completions
@@ -35,9 +34,9 @@ spec = do
3534 it "doesn't match on an empty string" $
3635 runFlex "" `shouldBe` []
3736 it "matches on equality" $
38− runFlex "firstResult" `shouldBe` mkResult [0]
37+ runFlex "firstResult" `shouldBe` [firstResult]
3938 it "scores short matches higher and sorts accordingly" $
40− runFlex "filt" `shouldBe` mkResult [2, 0]
39+ runFlex "filt" `shouldBe` [fiult, firstResult]
4140
4241 beforeAll_ setup . describe "Integration Tests: Flex Matcher" $ do
4342 it "doesn't match on an empty string" $ do
tests/Language/PureScript/Ide/RebuildSpec.hs+6−2
@@ -1,13 +1,17 @@
1+{-# LANGUAGE NoImplicitPrelude #-}
2+{-# LANGUAGE OverloadedStrings #-}
13module Language.PureScript.Ide.RebuildSpec where
24
5+import Protolude
6+
37import qualified Language.PureScript.Ide.Integration as Integration
48import System.FilePath
59import Test.Hspec
610
7−shouldBeSuccess :: String -> IO ()
11+shouldBeSuccess :: Text -> IO ()
812shouldBeSuccess = shouldBe True . Integration.resultIsSuccess
913
10−shouldBeFailure :: String -> IO ()
14+shouldBeFailure :: Text -> IO ()
1115shouldBeFailure = shouldBe False . Integration.resultIsSuccess
1216
1317spec :: Spec
tests/Language/PureScript/Ide/ReexportsSpec.hs+4−6
@@ -1,8 +1,9 @@
11{-# LANGUAGE OverloadedStrings #-}
2+{-# LANGUAGE NoImplicitPrelude #-}
23module Language.PureScript.Ide.ReexportsSpec where
34
4−import Control.Exception (evaluate)
5−import Data.List (sort)
5+import Protolude
6+
67import qualified Data.Map as Map
78import Language.PureScript.Ide.Reexports
89import Language.PureScript.Ide.Types
@@ -41,7 +42,7 @@ module4 = ("Module4", [Export "T", decl1, dep1, dep2])
4142result :: ModuleOld
4243result = ("Module1", [decl1, decl2, Export "Module3"])
4344
44−db :: Map.Map ModuleIdent [ExternDecl]
45+db :: Map ModuleIdent [ExternDecl]
4546db = Map.fromList [module1, module2, module3]
4647
4748shouldBeEqualSorted :: ModuleOld -> ModuleOld -> Expectation
@@ -64,9 +65,6 @@ spec =
6465 let replaced = replaceReexport (Export "Module2") module1 module2
6566 in replaceReexport (Export "Module2") replaced module2 `shouldBeEqualSorted` result
6667
67− it "should error when given a non-Export to replace" $
68− evaluate (replaceReexport decl1 module1 module2)
69− `shouldThrow` errorCall "Should only get Exports here."
7068 it "replaces all Exports with their corresponding declarations" $
7169 replaceReexports module1 db `shouldBe` ("Module1", [decl1, decl2, decl3])
7270