packages feed

purescript 0.11.4 → 0.11.5

raw patch · 60 files changed

+1037/−547 lines, 60 filesdep +stringsearchdep ~directoryPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: stringsearch

Dependency ranges changed: directory

API changes (from Hackage documentation)

- Language.PureScript.Ide.Imports: instance GHC.Classes.Ord Language.PureScript.Ide.Imports.Import
- Language.PureScript.Ide.State: populateStage2 :: (Ide m, MonadLogger m) => m ()
- Language.PureScript.Ide.State: populateStage3 :: (Ide m, MonadLogger m) => m ()
- Language.PureScript.Ide.State: populateStage3STM :: TVar IdeState -> STM (ModuleMap (ReexportResult [IdeDeclarationAnn]))
- Language.PureScript.Ide.Types: Configuration :: FilePath -> IdeLogLevel -> [FilePath] -> Configuration
- Language.PureScript.Ide.Types: Stage1 :: ModuleMap ExternsFile -> ModuleMap (Module, FilePath) -> Stage1
- Language.PureScript.Ide.Types: Stage2 :: AstData SourceSpan -> Stage2
- Language.PureScript.Ide.Types: Stage3 :: ModuleMap [IdeDeclarationAnn] -> Maybe (ModuleName, ExternsFile) -> Stage3
- Language.PureScript.Ide.Types: [ideStage1] :: IdeState -> Stage1
- Language.PureScript.Ide.Types: [ideStage2] :: IdeState -> Stage2
- Language.PureScript.Ide.Types: [ideStage3] :: IdeState -> Stage3
- Language.PureScript.Ide.Types: [s1Externs] :: Stage1 -> ModuleMap ExternsFile
- Language.PureScript.Ide.Types: [s1Modules] :: Stage1 -> ModuleMap (Module, FilePath)
- Language.PureScript.Ide.Types: [s2AstData] :: Stage2 -> AstData SourceSpan
- Language.PureScript.Ide.Types: [s3CachedRebuild] :: Stage3 -> Maybe (ModuleName, ExternsFile)
- Language.PureScript.Ide.Types: [s3Declarations] :: Stage3 -> ModuleMap [IdeDeclarationAnn]
- Language.PureScript.Ide.Types: data Configuration
- Language.PureScript.Ide.Types: data IdeDeclNamespace
- Language.PureScript.Ide.Types: data Stage1
- Language.PureScript.Ide.Types: data Stage2
- Language.PureScript.Ide.Types: data Stage3
- Language.PureScript.Ide.Types: emptyStage1 :: Stage1
- Language.PureScript.Ide.Types: emptyStage2 :: Stage2
- Language.PureScript.Ide.Types: emptyStage3 :: Stage3
- Language.PureScript.Ide.Types: instance GHC.Classes.Eq Language.PureScript.Ide.Types.IdeDeclNamespace
- Language.PureScript.Ide.Types: instance GHC.Classes.Eq Language.PureScript.Ide.Types.Stage2
- Language.PureScript.Ide.Types: instance GHC.Classes.Ord Language.PureScript.Ide.Types.IdeDeclNamespace
- Language.PureScript.Ide.Types: instance GHC.Show.Show Language.PureScript.Ide.Types.IdeDeclNamespace
- Language.PureScript.Ide.Types: instance GHC.Show.Show Language.PureScript.Ide.Types.Stage1
- Language.PureScript.Ide.Types: instance GHC.Show.Show Language.PureScript.Ide.Types.Stage2
- Language.PureScript.Ide.Types: instance GHC.Show.Show Language.PureScript.Ide.Types.Stage3
- Language.PureScript.Ide.Util: completionFromMatch :: Match IdeDeclarationAnn -> Completion
- Language.PureScript.Ide.Util: ideReadTextFile :: (MonadIO m, MonadError IdeError m) => FilePath -> m Text
+ Language.PureScript.AST.Declarations: MissingNewtypeSuperclassInstance :: (Qualified (ProperName ClassName)) -> (Qualified (ProperName ClassName)) -> [Type] -> SimpleErrorMessage
+ Language.PureScript.AST.Declarations: UnverifiableSuperclassInstance :: (Qualified (ProperName ClassName)) -> (Qualified (ProperName ClassName)) -> [Type] -> SimpleErrorMessage
+ Language.PureScript.Errors: [ppeRelativeDirectory] :: PPEOptions -> FilePath
+ Language.PureScript.Ide.Command: AddQualifiedImport :: ModuleName -> ModuleName -> ImportCommand
+ Language.PureScript.Ide.Command: [completeOptions] :: Command -> CompletionOptions
+ Language.PureScript.Ide.Completion: CompletionOptions :: Maybe Int -> Bool -> CompletionOptions
+ Language.PureScript.Ide.Completion: [coGroupReexports] :: CompletionOptions -> Bool
+ Language.PureScript.Ide.Completion: [coMaxResults] :: CompletionOptions -> Maybe Int
+ Language.PureScript.Ide.Completion: applyCompletionOptions :: CompletionOptions -> [Match IdeDeclarationAnn] -> [(Match IdeDeclarationAnn, [ModuleName])]
+ Language.PureScript.Ide.Completion: completionFromMatch :: (Match IdeDeclarationAnn, [ModuleName]) -> Completion
+ Language.PureScript.Ide.Completion: data CompletionOptions
+ Language.PureScript.Ide.Completion: defaultCompletionOptions :: CompletionOptions
+ Language.PureScript.Ide.Completion: getExactCompletions :: Text -> [Filter] -> [Module] -> [Completion]
+ Language.PureScript.Ide.Completion: instance Data.Aeson.Types.FromJSON.FromJSON Language.PureScript.Ide.Completion.CompletionOptions
+ Language.PureScript.Ide.Completion: instance GHC.Classes.Eq a => GHC.Classes.Eq (Language.PureScript.Ide.Completion.Namespaced a)
+ Language.PureScript.Ide.Completion: instance GHC.Classes.Ord a => GHC.Classes.Ord (Language.PureScript.Ide.Completion.Namespaced a)
+ Language.PureScript.Ide.Completion: instance GHC.Show.Show a => GHC.Show.Show (Language.PureScript.Ide.Completion.Namespaced a)
+ Language.PureScript.Ide.Completion: simpleExport :: Match a -> (Match a, [ModuleName])
+ Language.PureScript.Ide.Filter: namespaceFilter :: NonEmpty IdeNamespace -> Filter
+ Language.PureScript.Ide.Imports: addQualifiedImport :: (MonadIO m, MonadError IdeError m) => FilePath -> ModuleName -> ModuleName -> m [Text]
+ Language.PureScript.Ide.Imports: addQualifiedImport' :: [Import] -> ModuleName -> ModuleName -> [Text]
+ Language.PureScript.Ide.SourceFile: parseModulesFromFiles :: (MonadIO m, MonadError IdeError m) => [FilePath] -> m [Either FilePath (FilePath, Module)]
+ Language.PureScript.Ide.State: populateVolatileState :: (Ide m, MonadLogger m) => m ()
+ Language.PureScript.Ide.State: populateVolatileStateSTM :: TVar IdeState -> STM (ModuleMap (ReexportResult [IdeDeclarationAnn]))
+ Language.PureScript.Ide.Types: IdeConfiguration :: FilePath -> IdeLogLevel -> [FilePath] -> IdeConfiguration
+ Language.PureScript.Ide.Types: IdeFileState :: ModuleMap ExternsFile -> ModuleMap (Module, FilePath) -> IdeFileState
+ Language.PureScript.Ide.Types: IdeNamespaced :: IdeNamespace -> Text -> IdeNamespaced
+ Language.PureScript.Ide.Types: IdeVolatileState :: AstData SourceSpan -> ModuleMap [IdeDeclarationAnn] -> Maybe (ModuleName, ExternsFile) -> IdeVolatileState
+ Language.PureScript.Ide.Types: [complExportedFrom] :: Completion -> [ModuleName]
+ Language.PureScript.Ide.Types: [fsExterns] :: IdeFileState -> ModuleMap ExternsFile
+ Language.PureScript.Ide.Types: [fsModules] :: IdeFileState -> ModuleMap (Module, FilePath)
+ Language.PureScript.Ide.Types: [ideFileState] :: IdeState -> IdeFileState
+ Language.PureScript.Ide.Types: [ideVolatileState] :: IdeState -> IdeVolatileState
+ Language.PureScript.Ide.Types: [vsAstData] :: IdeVolatileState -> AstData SourceSpan
+ Language.PureScript.Ide.Types: [vsCachedRebuild] :: IdeVolatileState -> Maybe (ModuleName, ExternsFile)
+ Language.PureScript.Ide.Types: [vsDeclarations] :: IdeVolatileState -> ModuleMap [IdeDeclarationAnn]
+ Language.PureScript.Ide.Types: data IdeConfiguration
+ Language.PureScript.Ide.Types: data IdeFileState
+ Language.PureScript.Ide.Types: data IdeNamespace
+ Language.PureScript.Ide.Types: data IdeNamespaced
+ Language.PureScript.Ide.Types: data IdeVolatileState
+ Language.PureScript.Ide.Types: emptyFileState :: IdeFileState
+ Language.PureScript.Ide.Types: emptyVolatileState :: IdeVolatileState
+ Language.PureScript.Ide.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.PureScript.Ide.Types.IdeNamespace
+ Language.PureScript.Ide.Types: instance GHC.Classes.Eq Language.PureScript.Ide.Types.IdeNamespace
+ Language.PureScript.Ide.Types: instance GHC.Classes.Eq Language.PureScript.Ide.Types.IdeNamespaced
+ Language.PureScript.Ide.Types: instance GHC.Classes.Ord Language.PureScript.Ide.Types.IdeNamespace
+ Language.PureScript.Ide.Types: instance GHC.Classes.Ord Language.PureScript.Ide.Types.IdeNamespaced
+ Language.PureScript.Ide.Types: instance GHC.Show.Show Language.PureScript.Ide.Types.IdeFileState
+ Language.PureScript.Ide.Types: instance GHC.Show.Show Language.PureScript.Ide.Types.IdeNamespace
+ Language.PureScript.Ide.Types: instance GHC.Show.Show Language.PureScript.Ide.Types.IdeNamespaced
+ Language.PureScript.Ide.Types: instance GHC.Show.Show Language.PureScript.Ide.Types.IdeVolatileState
+ Language.PureScript.Ide.Util: namespaceForDeclaration :: IdeDeclaration -> IdeNamespace
+ Language.PureScript.Parser.Types: noForAll :: TokenParser Type -> TokenParser Type
+ Language.PureScript.Sugar.TypeClasses.Deriving: instance GHC.Base.Monoid Language.PureScript.Sugar.TypeClasses.Deriving.NewtypeDerivedInstances
+ Language.PureScript.Sugar.TypeClasses.Deriving: instance GHC.Show.Show Language.PureScript.Sugar.TypeClasses.Deriving.NewtypeDerivedInstances
+ Language.PureScript.Types: containsForAll :: Type -> Bool
+ System.IO.UTF8: fixCRLF :: ByteString -> ByteString
- Language.PureScript.AST.SourcePos: displaySourceSpan :: SourceSpan -> Text
+ Language.PureScript.AST.SourcePos: displaySourceSpan :: FilePath -> SourceSpan -> Text
- Language.PureScript.Errors: PPEOptions :: Maybe (ColorIntensity, Color) -> Bool -> Level -> Bool -> PPEOptions
+ Language.PureScript.Errors: PPEOptions :: Maybe (ColorIntensity, Color) -> Bool -> Level -> Bool -> FilePath -> PPEOptions
- Language.PureScript.Ide.Command: Complete :: [Filter] -> Matcher IdeDeclarationAnn -> Maybe ModuleName -> Command
+ Language.PureScript.Ide.Command: Complete :: [Filter] -> Matcher IdeDeclarationAnn -> Maybe ModuleName -> CompletionOptions -> Command
- Language.PureScript.Ide.Completion: getCompletions :: [Filter] -> Matcher IdeDeclarationAnn -> [Module] -> [Match IdeDeclarationAnn]
+ Language.PureScript.Ide.Completion: getCompletions :: [Filter] -> Matcher IdeDeclarationAnn -> CompletionOptions -> [Module] -> [Completion]
- Language.PureScript.Ide.SourceFile: extractSpans :: SourceSpan -> Declaration -> [(IdeDeclNamespace, SourceSpan)]
+ Language.PureScript.Ide.SourceFile: extractSpans :: SourceSpan -> Declaration -> [(IdeNamespaced, SourceSpan)]
- Language.PureScript.Ide.Types: Completion :: Text -> Text -> Text -> Text -> Maybe SourceSpan -> Maybe Text -> Completion
+ Language.PureScript.Ide.Types: Completion :: Text -> Text -> Text -> Text -> Maybe SourceSpan -> Maybe Text -> [ModuleName] -> Completion
- Language.PureScript.Ide.Types: IdeEnvironment :: TVar IdeState -> Configuration -> IdeEnvironment
+ Language.PureScript.Ide.Types: IdeEnvironment :: TVar IdeState -> IdeConfiguration -> IdeEnvironment
- Language.PureScript.Ide.Types: IdeNSKind :: Text -> IdeDeclNamespace
+ Language.PureScript.Ide.Types: IdeNSKind :: IdeNamespace
- Language.PureScript.Ide.Types: IdeNSType :: Text -> IdeDeclNamespace
+ Language.PureScript.Ide.Types: IdeNSType :: IdeNamespace
- Language.PureScript.Ide.Types: IdeNSValue :: Text -> IdeDeclNamespace
+ Language.PureScript.Ide.Types: IdeNSValue :: IdeNamespace
- Language.PureScript.Ide.Types: IdeState :: Stage1 -> Stage2 -> Stage3 -> IdeState
+ Language.PureScript.Ide.Types: IdeState :: IdeFileState -> IdeVolatileState -> IdeState
- Language.PureScript.Ide.Types: [confGlobs] :: Configuration -> [FilePath]
+ Language.PureScript.Ide.Types: [confGlobs] :: IdeConfiguration -> [FilePath]
- Language.PureScript.Ide.Types: [confLogLevel] :: Configuration -> IdeLogLevel
+ Language.PureScript.Ide.Types: [confLogLevel] :: IdeConfiguration -> IdeLogLevel
- Language.PureScript.Ide.Types: [confOutputPath] :: Configuration -> FilePath
+ Language.PureScript.Ide.Types: [confOutputPath] :: IdeConfiguration -> FilePath
- Language.PureScript.Ide.Types: [ideConfiguration] :: IdeEnvironment -> Configuration
+ Language.PureScript.Ide.Types: [ideConfiguration] :: IdeEnvironment -> IdeConfiguration
- Language.PureScript.Ide.Types: type DefinitionSites a = Map IdeDeclNamespace a
+ Language.PureScript.Ide.Types: type DefinitionSites a = Map IdeNamespaced a
- Language.PureScript.Sugar.TypeClasses.Deriving: deriveInstances :: forall m. (MonadError MultipleErrors m, MonadSupply m) => [ExternsFile] -> Module -> m Module
+ Language.PureScript.Sugar.TypeClasses.Deriving: deriveInstances :: forall m. (MonadError MultipleErrors m, MonadWriter MultipleErrors m, MonadSupply m) => [ExternsFile] -> Module -> m Module

Files

CONTRIBUTING.md view
@@ -23,7 +23,7 @@  ``` bash # Build-stack exec psc -- 'tests/support/bower_components/purescript-*/src/**/*.purs' examples/blah/Blah.purs+stack exec purs -- compile 'tests/support/bower_components/purescript-*/src/**/*.purs' examples/blah/Blah.purs  # Run node -e "require('./output/Main/').main()"
CONTRIBUTORS.md view
@@ -36,6 +36,7 @@ | [@davidchambers](https://github.com/davidchambers) | David Chambers | [MIT license](http://opensource.org/licenses/MIT) | | [@DavidLindbom](https://github.com/DavidLindbom) | David Lindbom | [MIT license](http://opensource.org/licenses/MIT) | | [@dckc](https://github.com/dckc) | Dan Connolly | [MIT license](http://opensource.org/licenses/MIT) |+| [@kleeneplus](https://github.com/dgendill) | Dominick Gendill | [MIT license](http://opensource.org/licenses/MIT) | | [@eamelink](https://github.com/eamelink) | Erik Bakker | MIT license | | [@epost](https://github.com/epost) | Erik Post | MIT license | | [@erdeszt](https://github.com/erdeszt) | Tibor Erdesz | [MIT license](http://opensource.org/licenses/MIT) |@@ -45,6 +46,7 @@ | [@FrigoEU](https://github.com/FrigoEU) | Simon Van Casteren | [MIT license](http://opensource.org/licenses/MIT) | | [@garyb](https://github.com/garyb) | Gary Burgess | [MIT license](http://opensource.org/licenses/MIT) | | [@hdgarrood](https://github.com/hdgarrood) | Harry Garrood | [MIT license](http://opensource.org/licenses/MIT) |+| [@houli](https://github.com/houli) | Eoin Houlihan | [MIT license](http://opensource.org/licenses/MIT) | | [@ianbollinger](https://github.com/ianbollinger) | Ian D. Bollinger | [MIT license](http://opensource.org/licenses/MIT) | | [@ilovezfs](https://github.com/ilovezfs) | ilovezfs | MIT license | | [@izgzhen](https://github.com/izgzhen) | Zhen Zhang | [MIT license](http://opensource.org/licenses/MIT) |@@ -86,11 +88,13 @@ | [@rvion](https://github.com/rvion) | Rémi Vion | [MIT license](http://opensource.org/licenses/MIT) | | [@RyanGlScott](https://github.com/RyanGlScott) | Ryan Scott | [MIT license](http://opensource.org/licenses/MIT) | | [@sebastiaanvisser](https://github.com/sebastiaanvisser) | Sebastiaan Visser | MIT license |+| [@sectore](https://github.com/sectore) | Jens Krause | [MIT license](http://opensource.org/licenses/MIT) | | [@senju](https://github.com/senju) | senju | [MIT license](http://opensource.org/licenses/MIT) | | [@seungha-kim](https://github.com/seungha-kim) | Seungha Kim | [MIT license](http://opensource.org/licenses/MIT) | | [@simonyangme](https://github.com/simonyangme) | Simon Yang | [MIT license](http://opensource.org/licenses/MIT) | | [@sharkdp](https://github.com/sharkdp) | David Peter | [MIT license](http://opensource.org/licenses/MIT) | | [@soupi](https://github.com/soupi) | Gil Mizrahi | [MIT license](http://opensource.org/licenses/MIT) |+| [@stefanholzmueller](https://github.com/stefanholzmueller) | Stefan Holzmüller | [MIT license](http://opensource.org/licenses/MIT) | | [@sztupi](https://github.com/sztupi) | Attila Sztupak | [MIT license](http://opensource.org/licenses/MIT) | | [@taktoa](https://github.com/taktoa) | Remy Goldschmidt | [MIT license](http://opensource.org/licenses/MIT) | | [@taku0](https://github.com/taku0) | taku0 | [MIT license](http://opensource.org/licenses/MIT) |
app/Command/Compile.hs view
@@ -22,7 +22,6 @@ import qualified System.Console.ANSI as ANSI import           System.Exit (exitSuccess, exitFailure) import           System.Directory (getCurrentDirectory)-import           System.FilePath (makeRelative) import           System.FilePath.Glob (glob) import           System.IO (hPutStr, hPutStrLn, stderr) import           System.IO.UTF8 (readUTF8FileT)@@ -38,8 +37,9 @@ -- | Argumnets: verbose, use JSON, warnings, errors printWarningsAndErrors :: Bool -> Bool -> P.MultipleErrors -> Either P.MultipleErrors a -> IO () printWarningsAndErrors verbose False warnings errors = do+  pwd <- getCurrentDirectory   cc <- bool Nothing (Just P.defaultCodeColor) <$> ANSI.hSupportsANSI stderr-  let ppeOpts = P.defaultPPEOptions { P.ppeCodeColor = cc, P.ppeFull = verbose }+  let ppeOpts = P.defaultPPEOptions { P.ppeCodeColor = cc, P.ppeFull = verbose, P.ppeRelativeDirectory = pwd }   when (P.nonEmpty warnings) $     hPutStrLn stderr (P.prettyPrintMultipleWarnings ppeOpts warnings)   case errors of@@ -55,7 +55,6 @@  compile :: PSCMakeOptions -> IO () compile PSCMakeOptions{..} = do-  pwd <- getCurrentDirectory   input <- globWarningOnMisses (unless pscmJSONErrors . warnFileTypeNotFound) pscmInput   when (null input && not pscmJSONErrors) $ do     hPutStr stderr $ unlines [ "purs compile: No input files."@@ -64,7 +63,7 @@     exitFailure   moduleFiles <- readInput input   (makeErrors, makeWarnings) <- runMake pscmOpts $ do-    ms <- P.parseModulesFromFiles (makeRelative pwd) moduleFiles+    ms <- P.parseModulesFromFiles id moduleFiles     let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, Right fp)) ms     foreigns <- inferForeignModules filePathMap     let makeActions = buildMakeActions pscmOutputDir filePathMap foreigns pscmUsePrefix
app/Command/Ide.hs view
@@ -120,7 +120,7 @@      unless noWatch $       void (forkFinally (watcher polling logLevel ideState fullOutputPath) print)-    let conf = Configuration {confLogLevel = logLevel, confOutputPath = outputPath, confGlobs = globs}+    let conf = IdeConfiguration {confLogLevel = logLevel, confOutputPath = outputPath, confGlobs = globs}         env = IdeEnvironment {ideStateVar = ideState, ideConfiguration = conf}     startServer port env @@ -164,15 +164,16 @@           case decodeT cmd of             Just cmd' -> do               let message duration =-                    "Command " <> commandName cmd'-                    <> " took "-                    <> displayTimeSpec duration-              result <- logPerf message (runExceptT (handleCommand cmd'))-              -- $(logDebug) ("Answer was: " <> T.pack (show result))+                    "Command "+                      <> commandName cmd'+                      <> " took "+                      <> displayTimeSpec duration+              logPerf message $ do+                result <- runExceptT (handleCommand cmd')+                liftIO $ catchGoneHandle $ BSL8.hPutStrLn h $ case result of+                  Right r  -> Aeson.encode r+                  Left err -> Aeson.encode err               liftIO (hFlush stdout)-              case result of-                Right r  -> liftIO $ catchGoneHandle (BSL8.hPutStrLn h (Aeson.encode r))-                Left err -> liftIO $ catchGoneHandle (BSL8.hPutStrLn h (Aeson.encode err))             Nothing -> do               $(logError) ("Parsing the command failed. Command: " <> cmd)               liftIO $ do
app/Command/REPL.hs view
@@ -53,6 +53,7 @@ import           System.FilePath ((</>)) import           System.FilePath.Glob (glob) import           System.Process (readProcessWithExitCode)+import qualified Data.ByteString.Lazy.UTF8 as U  -- | Command line options data PSCiOptions = PSCiOptions@@ -206,12 +207,12 @@           case Wai.pathInfo req of             [] ->               respond $ Wai.responseLBS status200-                                        [(hContentType, "text/html")]-                                        indexPage+                                        [(hContentType, "text/html; charset=UTF-8")]+                                        (U.fromString indexPage)             ["js", "index.js"] ->               respond $ Wai.responseLBS status200                                         [(hContentType, "application/javascript")]-                                        indexJS+                                        (U.fromString indexJS)             ["js", "latest.js"] -> do               may <- readTVarIO indexJs               case may of@@ -224,7 +225,7 @@                                             , (hPragma, "no-cache")                                             , (hExpires, "0")                                             ]-                                            (fromString js)+                                            (U.fromString js)             ["js", "bundle.js"] -> do               may <- readTVarIO bundleJs               case may of@@ -233,7 +234,7 @@                 Just js ->                   respond $ Wai.responseLBS status200                                             [ (hContentType, "application/javascript")]-                                            (fromString js)+                                            (U.fromString js)             _ -> respond $ Wai.responseLBS status404 [] "Not found"        let browserState = BrowserState cmdChan shutdownVar indexJs bundleJs@@ -323,7 +324,9 @@         case psciBackend of           Backend setup eval reload (shutdown :: state -> IO ()) ->             case e of-              Left errs -> putStrLn (P.prettyPrintMultipleErrors P.defaultPPEOptions errs) >> exitFailure+              Left errs -> do+                pwd <- getCurrentDirectory+                putStrLn (P.prettyPrintMultipleErrors P.defaultPPEOptions {P.ppeRelativeDirectory = pwd} errs) >> exitFailure               Right (modules, externs, env) -> do                 historyFilename <- getHistoryFilename                 let settings = defaultSettings { historyFile = Just historyFilename }
+ examples/docs/src/Desugar.purs view
@@ -0,0 +1,8 @@+module Desugar where++data X a b = X a b++test :: forall a b. X (a -> b) a -> b+test x =+  let X a b = x+  in a b
+ examples/failing/2874-forall.purs view
@@ -0,0 +1,8 @@+-- @shouldFailWith ErrorParsingModule+module Main where++class T a b | a -> b+instance tT :: (T Int (forall a. a)) => T Int String++ddd :: Int+ddd = 0 :: forall t. T Int t => Int
+ examples/failing/2874-forall2.purs view
@@ -0,0 +1,10 @@+-- @shouldFailWith ErrorParsingModule+module Main where++class X a b | a -> b+class X a (forall t. t) <= Y a b | a -> b+instance tX :: X Int String+instance tY :: Y Int Boolean++ggg :: Int+ggg = 0 :: forall t. Y Int t => Int
+ examples/failing/2874-wildcard.purs view
@@ -0,0 +1,11 @@+-- @shouldFailWith ErrorParsingModule+module Main where++class Foo a where+  foo :: a++class Baz b where+  baz :: b++instance bazFoo :: (Baz _) => Foo b where+  foo = baz
+ examples/failing/InstanceSigsBodyIncorrect.purs view
@@ -0,0 +1,10 @@+-- @shouldFailWith TypesDoNotUnify++module Main where++class Foo a where+  foo :: a++instance fooNumber :: Foo Number where+  foo :: Number+  foo = true
+ examples/failing/InstanceSigsDifferentTypes.purs view
@@ -0,0 +1,10 @@+-- @shouldFailWith TypesDoNotUnify++module Main where++class Foo a where+  foo :: a++instance fooNumber :: Foo Number where+  foo :: Int+  foo = 0.0
+ examples/failing/InstanceSigsIncorrectType.purs view
@@ -0,0 +1,10 @@+-- @shouldFailWith TypesDoNotUnify++module Main where++class Foo a where+  foo :: a++instance fooNumber :: Foo Number where+  foo :: Boolean+  foo = true
+ examples/failing/InstanceSigsOrphanTypeDeclaration.purs view
@@ -0,0 +1,10 @@+-- @shouldFailWith OrphanTypeDeclaration++module Main where++class Foo a where+  foo :: a++instance fooNumber :: Foo Number where+  bar :: Int+  foo = 0.0
+ examples/passing/InstanceSigs.purs view
@@ -0,0 +1,12 @@+module Main where++import Control.Monad.Eff.Console (log)++class Foo a where+  foo :: a++instance fooNumber :: Foo Number where+  foo :: Number+  foo = 0.0++main = log "Done"
+ examples/passing/InstanceSigsGeneral.purs view
@@ -0,0 +1,12 @@+module Main where++import Control.Monad.Eff.Console (log)++class Eq a where+  eq :: a -> a -> Boolean++instance eqNumber :: Eq Number where+  eq :: forall x y. x -> y -> Boolean+  eq _ _ = true++main = log "Done"
examples/passing/NewtypeInstance.purs view
@@ -3,15 +3,15 @@ import Prelude import Control.Monad.Eff import Control.Monad.Eff.Console+import Data.Monoid+import Data.Tuple  type MyString = String   newtype X = X MyString  derive newtype instance showX :: Show X- derive newtype instance eqX :: Eq X- derive newtype instance ordX :: Ord X  newtype Y a = Y (Array a)@@ -29,12 +29,26 @@ newtype MyArray a = MyArray (Array a)  derive newtype instance showMyArray :: Show a => Show (MyArray a)- derive newtype instance functorMyArray :: Functor MyArray  newtype ProxyArray x a = ProxyArray (Array a)  derive newtype instance functorProxyArray :: Functor (ProxyArray x)++class (Monad m, Monoid w) <= MonadWriter w m | m -> w where+  tell :: w -> m Unit++instance monadWriterTuple :: Monoid w => MonadWriter w (Tuple w) where+  tell w = Tuple w unit++newtype MyWriter w a = MyWriter (Tuple w a)++derive newtype instance functorMyWriter :: Functor (MyWriter w)+derive newtype instance applyMyWriter :: Semigroup w => Apply (MyWriter w)+derive newtype instance applicativeMyWriter :: Monoid w => Applicative (MyWriter w)+derive newtype instance bindMyWriter :: Semigroup w => Bind (MyWriter w)+derive newtype instance monadMyWriter :: Monoid w => Monad (MyWriter w)+derive newtype instance monadWriterMyWriter :: Monoid w => MonadWriter w (MyWriter w)  main = do   logShow (X "test")
+ examples/warning/NewtypeInstance.purs view
@@ -0,0 +1,8 @@+-- @shouldWarnWith MissingNewtypeSuperclassInstance+module Main where++import Prelude++newtype X = X String++derive newtype instance ordX :: Ord X
+ examples/warning/NewtypeInstance2.purs view
@@ -0,0 +1,16 @@+-- @shouldWarnWith MissingNewtypeSuperclassInstance+module Main where++import Prelude+import Data.Monoid (class Monoid)+import Data.Tuple (Tuple(..))++class (Monad m, Monoid w) <= MonadWriter w m | m -> w where+  tell :: w -> m Unit++instance monadWriterTuple :: Monoid w => MonadWriter w (Tuple w) where+  tell w = Tuple w unit++newtype MyWriter w a = MyWriter (Tuple w a)++derive newtype instance monadWriterMyWriter :: Monoid w => MonadWriter w (MyWriter w)
+ examples/warning/NewtypeInstance3.purs view
@@ -0,0 +1,22 @@+-- @shouldWarnWith MissingNewtypeSuperclassInstance+module Main where++import Prelude+import Data.Monoid (class Monoid)+import Data.Tuple (Tuple(..))++class (Monad m, Monoid w) <= MonadTell w m | m -> w where+  tell :: w -> m Unit++class (MonadTell w m) <= MonadWriter w m | m -> w where+  listen :: forall a. m a -> m (Tuple w a)++instance monadTellTuple :: Monoid w => MonadTell w (Tuple w) where+  tell w = Tuple w unit++instance monadWriterTuple :: Monoid w => MonadWriter w (Tuple w) where+  listen (Tuple w a) = Tuple w (Tuple w a)++newtype MyWriter w a = MyWriter (Tuple w a)++derive newtype instance monadWriterMyWriter :: Monoid w => MonadWriter w (MyWriter w)
+ examples/warning/NewtypeInstance4.purs view
@@ -0,0 +1,24 @@+-- @shouldWarnWith UnverifiableSuperclassInstance+module Main where++import Prelude+import Data.Monoid (class Monoid)+import Data.Tuple (Tuple(..))++class Monoid w <= MonadTell w m where+  tell :: w -> m Unit++class (MonadTell w m) <= MonadWriter w m where+  listen :: forall a. m a -> m (Tuple w a)++instance monadTellTuple :: Monoid w => MonadTell w (Tuple w) where+  tell w = Tuple w unit++instance monadWriterTuple :: Monoid w => MonadWriter w (Tuple w) where+  listen (Tuple w a) = Tuple w (Tuple w a)++newtype MyWriter w a = MyWriter (Tuple w a)++-- No fundep means this is unverifiable+derive newtype instance monadTellMyWriter :: Monoid w => MonadTell w (MyWriter w)+derive newtype instance monadWriterMyWriter :: Monoid w => MonadWriter w (MyWriter w)
purescript.cabal view
@@ -3,16 +3,16 @@ -- see: https://github.com/sol/hpack  name:           purescript-version:        0.11.4+version:        0.11.5 cabal-version:  >= 1.10 build-type:     Simple license:        BSD3 license-file:   LICENSE-copyright:      (c) 2013-16 Phil Freeman, (c) 2014-16 Gary Burgess+copyright:      (c) 2013-17 Phil Freeman, (c) 2014-17 Gary Burgess maintainer:     Phil Freeman <paf31@cantab.net> stability:      experimental homepage:       http://www.purescript.org/-bug-reports:    https://github.com/purescript/purescript.git/issues+bug-reports:    https://github.com/purescript/purescript/issues synopsis:       PureScript Programming Language Compiler description:    A small strongly, statically typed programming language with expressive types, inspired by Haskell and compiling to JavaScript. category:       Language@@ -35,6 +35,7 @@       examples/docs/src/Clash2.purs       examples/docs/src/Clash2a.purs       examples/docs/src/ConstrainedArgument.purs+      examples/docs/src/Desugar.purs       examples/docs/src/DocComments.purs       examples/docs/src/DuplicateNames.purs       examples/docs/src/Example.purs@@ -85,6 +86,9 @@       examples/failing/2601.purs       examples/failing/2616.purs       examples/failing/2806.purs+      examples/failing/2874-forall.purs+      examples/failing/2874-forall2.purs+      examples/failing/2874-wildcard.purs       examples/failing/365.purs       examples/failing/438.purs       examples/failing/881.purs@@ -184,6 +188,10 @@       examples/failing/InfiniteType.purs       examples/failing/InstanceExport.purs       examples/failing/InstanceExport/InstanceExport.purs+      examples/failing/InstanceSigsBodyIncorrect.purs+      examples/failing/InstanceSigsDifferentTypes.purs+      examples/failing/InstanceSigsIncorrectType.purs+      examples/failing/InstanceSigsOrphanTypeDeclaration.purs       examples/failing/IntOutOfRange.purs       examples/failing/InvalidDerivedInstance.purs       examples/failing/InvalidDerivedInstance2.purs@@ -398,6 +406,8 @@       examples/passing/ImportQualified/M1.purs       examples/passing/InferRecFunWithConstrainedArgument.purs       examples/passing/InstanceBeforeClass.purs+      examples/passing/InstanceSigs.purs+      examples/passing/InstanceSigsGeneral.purs       examples/passing/IntAndChar.purs       examples/passing/iota.purs       examples/passing/JSReserved.purs@@ -596,6 +606,10 @@       examples/warning/ImplicitImport.purs       examples/warning/ImplicitQualifiedImport.purs       examples/warning/MissingTypeDeclaration.purs+      examples/warning/NewtypeInstance.purs+      examples/warning/NewtypeInstance2.purs+      examples/warning/NewtypeInstance3.purs+      examples/warning/NewtypeInstance4.purs       examples/warning/OverlappingInstances.purs       examples/warning/OverlappingPattern.purs       examples/warning/ScopeShadowing.purs@@ -638,7 +652,7 @@  source-repository head     type: git-    location: https://github.com/purescript/purescript.git+    location: https://github.com/purescript/purescript  flag release     description: Mark this build as a release build: prevents inclusion of extra info e.g. commit SHA in --version output)@@ -662,7 +676,7 @@         , containers         , data-ordlist >=0.4.7.0         , deepseq-        , directory >=1.2+        , directory >=1.2.3         , dlist         , edit-distance         , filepath@@ -692,6 +706,7 @@         , spdx ==0.2.*         , split         , stm >=0.2.4.0+        , stringsearch         , syb         , text         , time@@ -870,7 +885,7 @@         , containers         , data-ordlist >=0.4.7.0         , deepseq-        , directory >=1.2+        , directory >=1.2.3         , dlist         , edit-distance         , filepath@@ -900,6 +915,7 @@         , spdx ==0.2.*         , split         , stm >=0.2.4.0+        , stringsearch         , syb         , text         , time@@ -958,7 +974,7 @@         , containers         , data-ordlist >=0.4.7.0         , deepseq-        , directory >=1.2+        , directory >=1.2.3         , dlist         , edit-distance         , filepath@@ -988,6 +1004,7 @@         , spdx ==0.2.*         , split         , stm >=0.2.4.0+        , stringsearch         , syb         , text         , time@@ -1006,6 +1023,7 @@     type: exitcode-stdio-1.0     main-is: Main.hs     other-modules:+          Language.PureScript.Ide.CompletionSpec           Language.PureScript.Ide.FilterSpec           Language.PureScript.Ide.ImportsSpec           Language.PureScript.Ide.MatcherSpec
src/Language/PureScript/AST/Declarations.hs view
@@ -109,6 +109,8 @@   | InvalidDerivedInstance (Qualified (ProperName 'ClassName)) [Type] Int   | ExpectedTypeConstructor (Qualified (ProperName 'ClassName)) [Type] Type   | InvalidNewtypeInstance (Qualified (ProperName 'ClassName)) [Type]+  | MissingNewtypeSuperclassInstance (Qualified (ProperName 'ClassName)) (Qualified (ProperName 'ClassName)) [Type]+  | UnverifiableSuperclassInstance (Qualified (ProperName 'ClassName)) (Qualified (ProperName 'ClassName)) [Type]   | CannotFindDerivingType (ProperName 'TypeName)   | DuplicateLabel Label (Maybe Expr)   | DuplicateValueDeclaration Ident
src/Language/PureScript/AST/SourcePos.hs view
@@ -13,6 +13,7 @@ import Data.Monoid import qualified Data.Text as T import Data.Text (Text)+import System.FilePath (makeRelative)  -- | -- Source position information@@ -65,9 +66,9 @@   displaySourcePos (spanStart sp) <> " - " <>   displaySourcePos (spanEnd sp) -displaySourceSpan :: SourceSpan -> Text-displaySourceSpan sp =-  T.pack (spanName sp) <> " " <>+displaySourceSpan :: FilePath -> SourceSpan -> Text+displaySourceSpan relPath sp =+  T.pack (makeRelative relPath (spanName sp)) <> " " <>     displayStartEndPos sp  instance A.ToJSON SourceSpan where
src/Language/PureScript/CoreImp/Optimizer/TCO.hs view
@@ -13,19 +13,19 @@ tco :: AST -> AST tco = everywhere convert where   tcoVar :: Text -> Text-  tcoVar arg = "__tco_" <> arg+  tcoVar arg = "$tco_var_" <> arg    copyVar :: Text -> Text-  copyVar arg = "__copy_" <> arg+  copyVar arg = "$copy_" <> arg    tcoDone :: Text-  tcoDone = tcoVar "done"+  tcoDone = "$tco_done"    tcoLoop :: Text-  tcoLoop = tcoVar "loop"+  tcoLoop = "$tco_loop"    tcoResult :: Text-  tcoResult = tcoVar "result"+  tcoResult = "$tco_result"    convert :: AST -> AST   convert (VariableIntroduction ss name (Just fn@Function {}))
src/Language/PureScript/Docs/Convert.hs view
@@ -58,7 +58,7 @@       Nothing -> Local mn    isLocal :: P.ModuleName -> Bool-  isLocal = not . flip Map.member modulesDeps +  isLocal = not . flip Map.member modulesDeps  -- | -- Convert a group of modules to the intermediate format, designed for@@ -208,7 +208,8 @@   where   desugar' =     traverse P.desugarDoModule-      >=> traverse P.desugarCasesModule+      >=> map P.desugarLetPatternModule+      >>> traverse P.desugarCasesModule       >=> traverse P.desugarTypeDeclarationsModule       >=> ignoreWarnings . P.desugarImportsWithEnv [] 
src/Language/PureScript/Environment.hs view
@@ -377,9 +377,9 @@     -- class RowCons (l :: Symbol) (a :: Type) (i :: # Type) (o :: # Type) | l i a -> o, l o -> a i     , (primName "RowCons", (makeTypeClassData                              [ ("l", Just kindSymbol)-                             , ("a", Just (Row kindType))-                             , ("i", Just kindType)-                             , ("o", Just kindType)+                             , ("a", Just kindType)+                             , ("i", Just (Row kindType))+                             , ("o", Just (Row kindType))                              ] [] []                              [ FunctionalDependency [0, 1, 2] [3]                              , FunctionalDependency [0, 3] [1, 2]
src/Language/PureScript/Errors.hs view
@@ -121,6 +121,8 @@   PossiblyInfiniteInstance{} -> "PossiblyInfiniteInstance"   CannotDerive{} -> "CannotDerive"   InvalidNewtypeInstance{} -> "InvalidNewtypeInstance"+  MissingNewtypeSuperclassInstance{} -> "MissingNewtypeSuperclassInstance"+  UnverifiableSuperclassInstance{} -> "UnverifiableSuperclassInstance"   InvalidDerivedInstance{} -> "InvalidDerivedInstance"   ExpectedTypeConstructor{} -> "ExpectedTypeConstructor"   CannotFindDerivingType{} -> "CannotFindDerivingType"@@ -262,6 +264,8 @@   gSimple (PossiblyInfiniteInstance cl ts) = PossiblyInfiniteInstance cl <$> traverse f ts   gSimple (CannotDerive cl ts) = CannotDerive cl <$> traverse f ts   gSimple (InvalidNewtypeInstance cl ts) = InvalidNewtypeInstance cl <$> traverse f ts+  gSimple (MissingNewtypeSuperclassInstance cl1 cl2 ts) = MissingNewtypeSuperclassInstance cl1 cl2 <$> traverse f ts+  gSimple (UnverifiableSuperclassInstance cl1 cl2 ts) = UnverifiableSuperclassInstance cl1 cl2 <$> traverse f ts   gSimple (InvalidDerivedInstance cl ts n) = InvalidDerivedInstance cl <$> traverse f ts <*> pure n   gSimple (ExpectedTypeConstructor cl ts ty) = ExpectedTypeConstructor cl <$> traverse f ts <*> f ty   gSimple (ExpectedType ty k) = ExpectedType <$> f ty <*> pure k@@ -362,24 +366,26 @@  -- | `prettyPrintSingleError` Options data PPEOptions = PPEOptions-  { ppeCodeColor :: Maybe (ANSI.ColorIntensity, ANSI.Color) -- ^ Color code with this color... or not-  , ppeFull      :: Bool -- ^ Should write a full error message?-  , ppeLevel     :: Level -- ^ Should this report an error or a warning?-  , ppeShowDocs  :: Bool -- ^ Should show a link to error message's doc page?+  { ppeCodeColor         :: Maybe (ANSI.ColorIntensity, ANSI.Color) -- ^ Color code with this color... or not+  , ppeFull              :: Bool -- ^ Should write a full error message?+  , ppeLevel             :: Level -- ^ Should this report an error or a warning?+  , ppeShowDocs          :: Bool -- ^ Should show a link to error message's doc page?+  , ppeRelativeDirectory :: FilePath -- ^ FilePath to which the errors are relative   }  -- | Default options for PPEOptions defaultPPEOptions :: PPEOptions defaultPPEOptions = PPEOptions-  { ppeCodeColor = Just defaultCodeColor-  , ppeFull      = False-  , ppeLevel     = Error-  , ppeShowDocs  = True+  { ppeCodeColor         = Just defaultCodeColor+  , ppeFull              = False+  , ppeLevel             = Error+  , ppeShowDocs          = True+  , ppeRelativeDirectory = mempty   }  -- | Pretty print a single error, simplifying if necessary prettyPrintSingleError :: PPEOptions -> ErrorMessage -> Box.Box-prettyPrintSingleError (PPEOptions codeColor full level showDocs) e = flip evalState defaultUnknownMap $ do+prettyPrintSingleError (PPEOptions codeColor full level showDocs relPath) e = flip evalState defaultUnknownMap $ do   em <- onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e)   um <- get   return (prettyPrintErrorMessage um em)@@ -522,7 +528,7 @@       line $ "Export for " <> printName new <> " conflicts with " <> runName existing     renderSimpleErrorMessage (DuplicateModule mn ss) =       paras [ line ("Module " <> markCode (runModuleName mn) <> " has been defined multiple times:")-            , indent . paras $ map (line . displaySourceSpan) ss+            , indent . paras $ map (line . displaySourceSpan relPath) ss             ]     renderSimpleErrorMessage (CycleInDeclaration nm) =       line $ "The value of " <> markCode (showIdent nm) <> " is undefined here, so this reference is not allowed."@@ -551,7 +557,7 @@             ]     renderSimpleErrorMessage (EscapedSkolem name (Just srcSpan) ty) =       paras [ line $ "The type variable " <> markCode name <> ", bound at"-            , indent $ line $ displaySourceSpan srcSpan+            , indent $ line $ displaySourceSpan relPath srcSpan             , line "has escaped its scope, appearing in the type"             , markCodeBox $ indent $ typeAsBox ty             ]@@ -671,6 +677,22 @@                 ]             , line "Make sure this is a newtype."             ]+    renderSimpleErrorMessage (MissingNewtypeSuperclassInstance su cl ts) =+      paras [ line "The derived newtype instance for"+            , markCodeBox $ indent $ Box.hsep 1 Box.left+                [ line (showQualified runProperName cl)+                , Box.vcat Box.left (map typeAtomAsBox ts)+                ]+            , line $ "does not include a derived superclass instance for " <> markCode (showQualified runProperName su) <> "."+            ]+    renderSimpleErrorMessage (UnverifiableSuperclassInstance su cl ts) =+      paras [ line "The derived newtype instance for"+            , markCodeBox $ indent $ Box.hsep 1 Box.left+                [ line (showQualified runProperName cl)+                , Box.vcat Box.left (map typeAtomAsBox ts)+                ]+            , line $ "implies an superclass instance for " <> markCode (showQualified runProperName su) <> " which could not be verified."+            ]     renderSimpleErrorMessage (InvalidDerivedInstance nm ts argCount) =       paras [ line "Cannot derive the type class instance"             , markCodeBox $ indent $ Box.hsep 1 Box.left@@ -1053,7 +1075,7 @@                 ]             ]     renderHint (PositionedError srcSpan) detail =-      paras [ line $ "at " <> displaySourceSpan srcSpan+      paras [ line $ "at " <> displaySourceSpan relPath srcSpan             , detail             ] 
src/Language/PureScript/Errors/JSON.hs view
@@ -50,7 +50,7 @@ toJSONError :: Bool -> P.Level -> P.ErrorMessage -> JSONError toJSONError verbose level e =   JSONError (toErrorPosition <$> sspan)-            (P.renderBox (P.prettyPrintSingleError (P.PPEOptions Nothing verbose level False) (P.stripModuleAndSpan e)))+            (P.renderBox (P.prettyPrintSingleError (P.PPEOptions Nothing verbose level False mempty) (P.stripModuleAndSpan e)))             (P.errorCode e)             (P.errorDocUri e)             (P.spanName <$> sspan)
src/Language/PureScript/Ide.hs view
@@ -56,8 +56,8 @@     loadModulesSync modules   Type search filters currentModule ->     findType search filters currentModule-  Complete filters matcher currentModule ->-    findCompletions filters matcher currentModule+  Complete filters matcher currentModule complOptions ->+    findCompletions filters matcher currentModule complOptions   Pursuit query Package ->     findPursuitPackages query   Pursuit query Identifier ->@@ -75,12 +75,15 @@   Import fp outfp _ (AddImplicitImport mn) -> do     rs <- addImplicitImport fp mn     answerRequest outfp rs+  Import fp outfp _ (AddQualifiedImport mn qual) -> do+    rs <- addQualifiedImport fp mn qual+    answerRequest outfp rs   Import fp outfp filters (AddImportForIdentifier ident) -> do     rs <- addImportForIdentifier fp ident filters     case rs of       Right rs' -> answerRequest outfp rs'       Left question ->-        pure (CompletionResult (map (completionFromMatch . map withEmptyAnn) question))+        pure (CompletionResult (map (completionFromMatch . simpleExport . map withEmptyAnn) question))   Rebuild file ->     rebuildFileAsync file   RebuildSync file ->@@ -92,17 +95,22 @@   Quit ->     liftIO exitSuccess -findCompletions :: Ide m =>-                   [Filter] -> Matcher IdeDeclarationAnn -> Maybe P.ModuleName -> m Success-findCompletions filters matcher currentModule = do+findCompletions+  :: Ide m+  => [Filter]+  -> Matcher IdeDeclarationAnn+  -> Maybe P.ModuleName+  -> CompletionOptions+  -> m Success+findCompletions filters matcher currentModule complOptions = do   modules <- getAllModules currentModule-  pure . CompletionResult . map completionFromMatch . getCompletions filters matcher $ modules+  pure (CompletionResult (getCompletions filters matcher complOptions modules))  findType :: Ide m =>             Text -> [Filter] -> Maybe P.ModuleName -> m Success findType search filters currentModule = do   modules <- getAllModules currentModule-  pure . CompletionResult . map completionFromMatch . getExactMatches search filters $ modules+  pure (CompletionResult (getExactCompletions search filters modules))  findPursuitCompletions :: MonadIO m =>                           PursuitQuery -> m Success@@ -167,7 +175,7 @@ -- | Looks up the ExternsFiles for the given Modulenames and loads them into the -- server state. Then proceeds to parse all the specified sourcefiles and -- inserts their ASTs into the state. Finally kicks off an async worker, which--- populates Stage 2 and 3 of the state.+-- populates the VolatileState. loadModulesAsync   :: (Ide m, MonadError IdeError m, MonadLogger m)   => [P.ModuleName]@@ -179,9 +187,9 @@   -- successfully parsed modules.   env <- ask   let ll = confLogLevel (ideConfiguration env)-  -- populateStage2 and 3 return Unit for now, so it's fine to discard this+  -- populateVolatileState return Unit for now, so it's fine to discard this   -- result. We might want to block on this in a benchmarking situation.-  _ <- liftIO (async (runLogger ll (runReaderT (populateStage2 *> populateStage3) env)))+  _ <- liftIO (async (runLogger ll (runReaderT populateVolatileState env)))   pure tr  loadModulesSync@@ -190,7 +198,7 @@   -> m Success loadModulesSync moduleNames = do   tr <- loadModules moduleNames-  populateStage2 *> populateStage3+  populateVolatileState   pure tr  loadModules@@ -208,7 +216,7 @@   -- We parse all source files, log eventual parse failures and insert the   -- successful parses into the state.   (failures, allModules) <--    partitionEithers <$> (traverse parseModule =<< findAllSourceFiles)+    partitionEithers <$> (parseModulesFromFiles =<< findAllSourceFiles)   unless (null failures) $     $(logWarn) ("Failed to parse: " <> show failures)   traverse_ insertModule allModules
src/Language/PureScript/Ide/Command.hs view
@@ -19,6 +19,7 @@ import           Data.Aeson import qualified Language.PureScript               as P import           Language.PureScript.Ide.CaseSplit+import           Language.PureScript.Ide.Completion import           Language.PureScript.Ide.Filter import           Language.PureScript.Ide.Matcher import           Language.PureScript.Ide.Types@@ -35,6 +36,7 @@       { completeFilters       :: [Filter]       , completeMatcher       :: Matcher IdeDeclarationAnn       , completeCurrentModule :: Maybe P.ModuleName+      , completeOptions       :: CompletionOptions       }     | Pursuit       { pursuitQuery      :: PursuitQuery@@ -79,6 +81,7 @@  data ImportCommand   = AddImplicitImport P.ModuleName+  | AddQualifiedImport P.ModuleName P.ModuleName   | AddImportForIdentifier Text   deriving (Show, Eq) @@ -88,6 +91,10 @@     case command of       "addImplicitImport" ->         AddImplicitImport <$> (P.moduleNameFromString <$> o .: "module")+      "addQualifiedImport" ->+        AddQualifiedImport+          <$> (P.moduleNameFromString <$> o .: "module")+          <*> (P.moduleNameFromString <$> o .: "qualifier")       "addImport" ->         AddImportForIdentifier <$> o .: "identifier"       _ -> mzero@@ -129,6 +136,7 @@           <$> params .:? "filters" .!= []           <*> params .:? "matcher" .!= mempty           <*> (fmap P.moduleNameFromString <$> params .:? "currentModule")+          <*> params .:? "options" .!= defaultCompletionOptions       "pursuit" -> do         params <- o .: "params"         Pursuit
src/Language/PureScript/Ide/Completion.hs view
@@ -1,14 +1,26 @@ module Language.PureScript.Ide.Completion        ( getCompletions        , getExactMatches+       , getExactCompletions+       , simpleExport+       , completionFromMatch+       , CompletionOptions(..)+       , defaultCompletionOptions+       , applyCompletionOptions        ) where  import           Protolude +import           Control.Lens hiding ((&), op)+import           Data.Aeson+import qualified Data.Map as Map+import qualified Data.Text as T+import qualified Language.PureScript as P+import           Language.PureScript.Ide.Error (prettyPrintTypeSingleLine) import           Language.PureScript.Ide.Filter import           Language.PureScript.Ide.Matcher import           Language.PureScript.Ide.Types-import qualified Language.PureScript as P+import           Language.PureScript.Ide.Util  type Module = (P.ModuleName, [IdeDeclarationAnn]) @@ -17,17 +29,113 @@ getCompletions   :: [Filter]   -> Matcher IdeDeclarationAnn+  -> CompletionOptions   -> [Module]-  -> [Match IdeDeclarationAnn]-getCompletions filters matcher modules =-  runMatcher matcher (completionsFromModules (applyFilters filters modules))+  -> [Completion]+getCompletions filters matcher options modules =+  modules+  & applyFilters filters+  & matchesFromModules+  & runMatcher matcher+  & applyCompletionOptions options+  <&> completionFromMatch  getExactMatches :: Text -> [Filter] -> [Module] -> [Match IdeDeclarationAnn] getExactMatches search filters modules =-  completionsFromModules (applyFilters (equalityFilter search : filters) modules)+  modules+  & applyFilters (equalityFilter search : filters)+  & matchesFromModules -completionsFromModules :: [Module] -> [Match IdeDeclarationAnn]-completionsFromModules = foldMap completionFromModule+getExactCompletions :: Text -> [Filter] -> [Module] -> [Completion]+getExactCompletions search filters modules =+  modules+  & getExactMatches search filters+  <&> simpleExport+  <&> completionFromMatch++matchesFromModules :: [Module] -> [Match IdeDeclarationAnn]+matchesFromModules = foldMap completionFromModule   where     completionFromModule (moduleName, decls) =       map (\x -> Match (moduleName, x)) decls++data CompletionOptions = CompletionOptions+  { coMaxResults :: Maybe Int+  , coGroupReexports :: Bool+  }++instance FromJSON CompletionOptions where+  parseJSON = withObject "CompletionOptions" $ \o -> do+    maxResults <- o .:? "maxResults"+    groupReexports <- o .:? "groupReexports" .!= False+    pure (CompletionOptions { coMaxResults = maxResults+                            , coGroupReexports = groupReexports+                            })++defaultCompletionOptions :: CompletionOptions+defaultCompletionOptions = CompletionOptions { coMaxResults = Nothing, coGroupReexports = False }++applyCompletionOptions :: CompletionOptions -> [Match IdeDeclarationAnn] -> [(Match IdeDeclarationAnn, [P.ModuleName])]+applyCompletionOptions co decls =+  maybe identity take (coMaxResults co) decls+  & if coGroupReexports co+    then groupCompletionReexports+    else map simpleExport++simpleExport :: Match a -> (Match a, [P.ModuleName])+simpleExport match@(Match (moduleName, _)) = (match, [moduleName])++groupCompletionReexports :: [Match IdeDeclarationAnn] -> [(Match IdeDeclarationAnn, [P.ModuleName])]+groupCompletionReexports initial =+  Map.elems (foldr go Map.empty initial)+  where+    go (Match (moduleName, d@(IdeDeclarationAnn ann decl))) =+      let+        origin = fromMaybe moduleName (ann^.annExportedFrom)+      in+        Map.alter+        (insertDeclaration moduleName origin d)+        (Namespaced (namespaceForDeclaration decl)+         (P.runModuleName origin <> "." <> identifierFromIdeDeclaration decl))+    insertDeclaration moduleName origin d old = case old of+      Nothing -> Just ( Match (origin, d & idaAnnotation.annExportedFrom .~ Nothing)+                      , [moduleName]+                      )+      Just x -> Just (second (moduleName :) x)++data Namespaced a = Namespaced IdeNamespace a+  deriving (Show, Eq, Ord)++completionFromMatch :: (Match IdeDeclarationAnn, [P.ModuleName]) -> Completion+completionFromMatch (Match (m, IdeDeclarationAnn ann decl), mns) =+  Completion {..}+  where+    (complIdentifier, complExpandedType) = case decl of+      IdeDeclValue v -> (v ^. ideValueIdent . identT, v ^. ideValueType & prettyPrintTypeSingleLine)+      IdeDeclType t -> (t ^. ideTypeName . properNameT, t ^. ideTypeKind & P.prettyPrintKind)+      IdeDeclTypeSynonym s -> (s ^. ideSynonymName . properNameT, s ^. ideSynonymType & prettyPrintTypeSingleLine)+      IdeDeclDataConstructor d -> (d ^. ideDtorName . properNameT, d ^. ideDtorType & prettyPrintTypeSingleLine)+      IdeDeclTypeClass d -> (d ^. ideTCName . properNameT, d ^. ideTCKind & P.prettyPrintKind)+      IdeDeclValueOperator (IdeValueOperator op ref precedence associativity typeP) ->+        (P.runOpName op, maybe (showFixity precedence associativity (valueOperatorAliasT ref) op) prettyPrintTypeSingleLine typeP)+      IdeDeclTypeOperator (IdeTypeOperator op ref precedence associativity kind) ->+        (P.runOpName op, maybe (showFixity precedence associativity (typeOperatorAliasT ref) op) P.prettyPrintKind kind)+      IdeDeclKind k -> (P.runProperName k, "kind")++    complExportedFrom = mns++    complModule = P.runModuleName m++    complType = maybe complExpandedType prettyPrintTypeSingleLine (_annTypeAnnotation ann)++    complLocation = _annLocation ann++    complDocumentation = Nothing++    showFixity p a r o =+      let asso = case a of+            P.Infix -> "infix"+            P.Infixl -> "infixl"+            P.Infixr -> "infixr"+      in T.unwords [asso, show p, r, "as", P.runOpName o]+
src/Language/PureScript/Ide/Error.hs view
@@ -66,9 +66,9 @@     insertTSCompletions _ _ _ v = v      identCompletion (P.Qualified mn i, ty) =-      Completion (maybe "" P.runModuleName mn) i (prettyPrintTypeSingleLine ty) (prettyPrintTypeSingleLine ty) Nothing Nothing+      Completion (maybe "" P.runModuleName mn) i (prettyPrintTypeSingleLine ty) (prettyPrintTypeSingleLine ty) Nothing Nothing (maybe [] (\x -> [x]) mn)     fieldCompletion (label, ty) =-      Completion "" ("_." <> P.prettyPrintLabel label) (prettyPrintTypeSingleLine ty) (prettyPrintTypeSingleLine ty) Nothing Nothing+      Completion "" ("_." <> P.prettyPrintLabel label) (prettyPrintTypeSingleLine ty) (prettyPrintTypeSingleLine ty) Nothing Nothing []  textError :: IdeError -> Text textError (GeneralError msg)          = msg
src/Language/PureScript/Ide/Filter.hs view
@@ -16,6 +16,7 @@  module Language.PureScript.Ide.Filter        ( Filter+       , namespaceFilter        , moduleFilter        , prefixFilter        , equalityFilter@@ -25,18 +26,28 @@ import           Protolude                     hiding (isPrefixOf)  import           Data.Aeson+import           Data.List.NonEmpty            (NonEmpty) import           Data.Text                     (isPrefixOf)-import qualified Language.PureScript           as P import           Language.PureScript.Ide.Types import           Language.PureScript.Ide.Util+import qualified Language.PureScript           as P -newtype Filter = Filter (Endo [Module]) deriving(Monoid)+newtype Filter = Filter (Endo [Module])+  deriving (Monoid)  type Module = (P.ModuleName, [IdeDeclarationAnn])  mkFilter :: ([Module] -> [Module]) -> Filter mkFilter = Filter . Endo +-- | Only keeps Identifiers in the given Namespaces+namespaceFilter :: NonEmpty IdeNamespace -> Filter+namespaceFilter namespaces =+  mkFilter (filterModuleDecls filterNamespaces)+  where+    filterNamespaces :: IdeDeclaration -> Bool+    filterNamespaces decl = elem (namespaceForDeclaration decl) namespaces+ -- | Only keeps the given Modules moduleFilter :: [P.ModuleName] -> Filter moduleFilter =@@ -48,25 +59,29 @@ -- | Only keeps Identifiers that start with the given prefix prefixFilter :: Text -> Filter prefixFilter "" = mkFilter identity-prefixFilter t = mkFilter $ identFilter prefix t+prefixFilter t =+  mkFilter $ declarationFilter prefix t   where     prefix :: IdeDeclaration -> Text -> Bool     prefix ed search = search `isPrefixOf` identifierFromIdeDeclaration ed  -- | Only keeps Identifiers that are equal to the search string equalityFilter :: Text -> Filter-equalityFilter = mkFilter . identFilter equality+equalityFilter =+  mkFilter . declarationFilter equality   where     equality :: IdeDeclaration -> Text -> Bool     equality ed search = identifierFromIdeDeclaration ed == search -identFilter :: (IdeDeclaration -> Text -> Bool) -> Text -> [Module] -> [Module]-identFilter predicate search =-    filter (not . null . snd) . fmap filterModuleDecls+declarationFilter :: (IdeDeclaration -> Text -> Bool) -> Text -> [Module] -> [Module]+declarationFilter predicate search =+  filterModuleDecls (flip predicate search)++filterModuleDecls :: (IdeDeclaration -> Bool) -> [Module] -> [Module]+filterModuleDecls predicate =+  filter (not . null . snd) . fmap filterDecls   where-    filterModuleDecls :: Module -> Module-    filterModuleDecls (moduleIdent, decls) =-        (moduleIdent, filter (flip predicate search . discardAnn) decls)+    filterDecls (moduleIdent, decls) = (moduleIdent, filter (predicate . discardAnn) decls)  runFilter :: Filter -> [Module] -> [Module] runFilter (Filter f) = appEndo f@@ -90,4 +105,8 @@         params <- o .: "params"         modules <- map P.moduleNameFromString <$> params .: "modules"         return $ moduleFilter modules+      "namespace" -> do+        params <- o .: "params"+        namespaces <- params .: "namespaces"+        return $ namespaceFilter namespaces       _ -> mzero
src/Language/PureScript/Ide/Imports.hs view
@@ -14,6 +14,7 @@  module Language.PureScript.Ide.Imports        ( addImplicitImport+       , addQualifiedImport        , addImportForIdentifier        , answerRequest        , parseImportsFromFile@@ -21,6 +22,7 @@        , parseImport        , prettyPrintImportSection        , addImplicitImport'+       , addQualifiedImport'        , addExplicitImport'        , sliceImportSection        , prettyPrintImport'@@ -31,7 +33,7 @@ import           Protolude  import           Control.Lens                       ((^.), (%~), ix)-import           Data.List                          (findIndex, nubBy)+import           Data.List                          (findIndex, nubBy, partition) import qualified Data.Text                          as T import qualified Language.PureScript                as P import           Language.PureScript.Ide.Completion@@ -46,27 +48,6 @@ data Import = Import P.ModuleName P.ImportDeclarationType (Maybe P.ModuleName)               deriving (Eq, Show) -instance Ord Import where-  compare = compImport--compImportType :: P.ImportDeclarationType -> P.ImportDeclarationType -> Ordering-compImportType P.Implicit P.Implicit = EQ-compImportType P.Implicit _ = LT-compImportType (P.Explicit _) (P.Hiding _) = LT-compImportType (P.Explicit _) (P.Explicit _) = EQ-compImportType (P.Explicit _) P.Implicit = GT-compImportType (P.Hiding _) (P.Hiding _) = EQ-compImportType (P.Hiding _) _ = GT--compImport :: Import -> Import -> Ordering-compImport (Import n i q) (Import n' i' q')-  | compImportType i i' /= EQ = compImportType i i'-    -- This means that for a stable sort, the first implicit import will stay-    -- the first implicit import-  | not (P.isExplicit i) && isNothing q = LT-  | not (P.isExplicit i) && isNothing q' = GT-  | otherwise = compare n n'- -- | Reads a file and returns the parsed modulename as well as the parsed -- imports, while ignoring eventual parse errors that aren't relevant to the -- import section@@ -85,7 +66,7 @@ parseImportsFromFile' :: (MonadIO m, MonadError IdeError m) =>                         FilePath -> m (P.ModuleName, [Text], [Import], [Text]) parseImportsFromFile' fp = do-  file <- ideReadTextFile fp+  file <- ideReadFile fp   case sliceImportSection (T.lines file) of     Right res -> pure res     Left err -> throwError (GeneralError err)@@ -143,10 +124,11 @@       & ix (l2 - l1) %~ T.take c2  -- | Adds an implicit import like @import Prelude@ to a Sourcefile.-addImplicitImport :: (MonadIO m, MonadError IdeError m)-                     => FilePath     -- ^ The Sourcefile read from-                     -> P.ModuleName -- ^ The module to import-                     -> m [Text]+addImplicitImport+  :: (MonadIO m, MonadError IdeError m)+  => FilePath     -- ^ The source file read from+  -> P.ModuleName -- ^ The module to import+  -> m [Text] addImplicitImport fp mn = do   (_, pre, imports, post) <- parseImportsFromFile' fp   let newImportSection = addImplicitImport' imports mn@@ -154,11 +136,27 @@  addImplicitImport' :: [Import] -> P.ModuleName -> [Text] addImplicitImport' imports mn =-  -- We need to append the new import, because there could already be implicit-  -- imports and we need to preserve the order on these, as the first implicit-  -- import is the one that doesn't generate warnings.-  prettyPrintImportSection ( imports ++ [Import mn P.Implicit Nothing])+  prettyPrintImportSection (Import mn P.Implicit Nothing : imports) +-- | Adds a qualified import like @import Data.Map as Map@ to a source file.+addQualifiedImport+  :: (MonadIO m, MonadError IdeError m)+  => FilePath+  -- ^ The sourcefile read from+  -> P.ModuleName+  -- ^ The module to import+  -> P.ModuleName+  -- ^ The qualifier under which to import+  -> m [Text]+addQualifiedImport fp mn qualifier = do+  (_, pre, imports, post) <- parseImportsFromFile' fp+  let newImportSection = addQualifiedImport' imports mn qualifier+  pure (pre ++ newImportSection ++ post)++addQualifiedImport' :: [Import] -> P.ModuleName -> P.ModuleName -> [Text]+addQualifiedImport' imports mn qualifier =+  prettyPrintImportSection (Import mn P.Implicit (Just qualifier) : imports)+ -- | Adds an explicit import like @import Prelude (unit)@ to a Sourcefile. If an -- explicit import already exists for the given module, it adds the identifier -- to that imports list.@@ -203,6 +201,8 @@       P.ValueOpRef (op ^. ideValueOpName)     refFromDeclaration (IdeDeclTypeOperator op) =       P.TypeOpRef (op ^. ideTypeOpName)+    refFromDeclaration (IdeDeclKind kn) =+      P.KindRef kn     refFromDeclaration d =       P.ValueRef (P.Ident (identifierFromIdeDeclaration d)) @@ -272,7 +272,7 @@       if m1 /= m2          -- If the modules don't line up we just ask the user to specify the          -- module-      then pure $ Left ms+      then pure (Left ms)       else case decideRedundantCase d1 d2 <|> decideRedundantCase d2 d1 of         -- If dataconstructor and type line up we just import the         -- dataconstructor as that will give us an unnecessary import warning at@@ -281,13 +281,16 @@           Right <$> addExplicitImport fp decl m1         -- Here we need the user to specify whether he wanted a dataconstructor         -- or a type++        -- TODO: With the new namespace filter, this can actually be a+        -- request for the user to specify which of the two was wanted.         Nothing ->           throwError (GeneralError "Undecidable between type and dataconstructor")      -- Multiple matches were found so we need to ask the user to clarify which     -- module he meant     xs ->-      pure $ Left xs+      pure (Left xs)     where       decideRedundantCase d@(IdeDeclDataConstructor dtor) (IdeDeclType t) =         if dtor ^. ideDtorTypeName == t ^. ideTypeName then Just d else Nothing@@ -300,7 +303,21 @@   "import " <> P.prettyPrintImport mn idt qual  prettyPrintImportSection :: [Import] -> [Text]-prettyPrintImportSection imports = map prettyPrintImport' (sort imports)+prettyPrintImportSection imports =+  let+    (implicitImports, explicitImports) = partition isImplicitImport imports+  in+    sort (map prettyPrintImport' implicitImports)+      -- Only add the extra spacing if both implicit as well as+      -- explicit/qualified imports exist+      <> (guard (not (null explicitImports || null implicitImports)) $> "")+      <> sort (map prettyPrintImport' explicitImports)+  where+    isImplicitImport :: Import -> Bool+    isImplicitImport i = case i of+      Import _ P.Implicit Nothing -> True+      _ -> False+  -- | Writes a list of lines to @Just filepath@ and responds with a @TextResult@, -- or returns the lines as a @MultilineTextResult@ if @Nothing@ was given as the
src/Language/PureScript/Ide/Rebuild.hs view
@@ -20,8 +20,6 @@ import           Language.PureScript.Ide.State import           Language.PureScript.Ide.Types import           Language.PureScript.Ide.Util-import           System.Directory (getCurrentDirectory)-import           System.FilePath (makeRelative)  -- | Given a filepath performs the following steps: --@@ -48,15 +46,14 @@ rebuildFile path runOpenBuild = do    input <- ideReadFile path-  pwd <- liftIO getCurrentDirectory -  m <- case snd <$> P.parseModuleFromFile (makeRelative pwd) (path, input) of+  m <- case snd <$> P.parseModuleFromFile identity (path, input) of     Left parseError ->       throwError (RebuildError (P.MultipleErrors [P.toPositionedError parseError]))     Right m -> pure m    -- Externs files must be sorted ahead of time, so that they get applied-  -- correctly to the 'Environment'.+  -- in the right order (bottom up) to the 'Environment'.   externs <- logPerf (labelTimespec "Sorting externs") (sortExterns m =<< getExternFiles)    outputDirectory <- confOutputPath . ideConfiguration <$> ask
src/Language/PureScript/Ide/Reexports.hs view
@@ -93,8 +93,10 @@   -> Either P.DeclarationRef [IdeDeclarationAnn] resolveRef decls ref = case ref of   P.TypeRef tn mdtors ->-    case findRef (anyOf (_IdeDeclType . ideTypeName) (== tn)) of-      Nothing -> Left ref+    case findRef (anyOf (_IdeDeclType . ideTypeName) (== tn))+         <|> findRef (anyOf (_IdeDeclTypeSynonym . ideSynonymName) (== tn)) of+      Nothing ->+        Left ref       Just d -> Right $ d : case mdtors of           Nothing ->             -- If the dataconstructor field inside the TypeRef is Nothing, that@@ -110,6 +112,8 @@     findWrapped (anyOf (_IdeDeclTypeOperator . ideTypeOpName) (== name))   P.TypeClassRef name ->     findWrapped (anyOf (_IdeDeclTypeClass . ideTCName) (== name))+  P.KindRef name ->+    findWrapped (anyOf _IdeDeclKind (== name))   _ ->     Left ref   where
src/Language/PureScript/Ide/SourceFile.hs view
@@ -14,6 +14,7 @@  module Language.PureScript.Ide.SourceFile   ( parseModule+  , parseModulesFromFiles   , extractAstInformation   -- for tests   , extractSpans@@ -22,25 +23,38 @@  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-import           System.Directory (getCurrentDirectory)-import           System.FilePath (makeRelative)  parseModule   :: (MonadIO m, MonadError IdeError m)   => FilePath   -> m (Either FilePath (FilePath, P.Module)) parseModule path = do-  pwd <- liftIO getCurrentDirectory   contents <- ideReadFile path-  case P.parseModuleFromFile (makeRelative pwd) (path, contents) of-    Left _ -> pure (Left path)-    Right m -> pure (Right m)+  pure (parseModule' path 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 (\p -> (p,) <$> ideReadFile p) paths+  pure (inParallel (map (uncurry parseModule') files))+  where+    inParallel :: [Either e (k, a)] -> [Either e (k, a)]+    inParallel = withStrategy (parList rseq)+ -- | Extracts AST information from a parsed module extractAstInformation   :: P.Module@@ -67,30 +81,30 @@   -- ^ The surrounding span   -> P.Declaration   -- ^ The declaration to extract spans from-  -> [(IdeDeclNamespace, P.SourceSpan)]+  -> [(IdeNamespaced, P.SourceSpan)]   -- ^ Declarations and their source locations extractSpans ss d = case d of   P.PositionedDeclaration ss' _ d' ->     extractSpans ss' d'   P.ValueDeclaration i _ _ _ ->-    [(IdeNSValue (P.runIdent i), ss)]+    [(IdeNamespaced IdeNSValue (P.runIdent i), ss)]   P.TypeSynonymDeclaration name _ _ ->-    [(IdeNSType (P.runProperName name), ss)]+    [(IdeNamespaced IdeNSType (P.runProperName name), ss)]   P.TypeClassDeclaration name _ _ _ members ->-    (IdeNSType (P.runProperName name), ss) : concatMap (extractSpans' ss) members+    (IdeNamespaced IdeNSType (P.runProperName name), ss) : concatMap (extractSpans' ss) members   P.DataDeclaration _ name _ ctors ->-    (IdeNSType (P.runProperName name), ss)-    : map (\(cname, _) -> (IdeNSValue (P.runProperName cname), ss)) ctors+    (IdeNamespaced IdeNSType (P.runProperName name), ss)+    : map (\(cname, _) -> (IdeNamespaced IdeNSValue (P.runProperName cname), ss)) ctors   P.FixityDeclaration (Left (P.ValueFixity _ _ opName)) ->-    [(IdeNSValue (P.runOpName opName), ss)]+    [(IdeNamespaced IdeNSValue (P.runOpName opName), ss)]   P.FixityDeclaration (Right (P.TypeFixity _ _ opName)) ->-    [(IdeNSType (P.runOpName opName), ss)]+    [(IdeNamespaced IdeNSType (P.runOpName opName), ss)]   P.ExternDeclaration ident _ ->-    [(IdeNSValue (P.runIdent ident), ss)]+    [(IdeNamespaced IdeNSValue (P.runIdent ident), ss)]   P.ExternDataDeclaration name _ ->-    [(IdeNSType (P.runProperName name), ss)]+    [(IdeNamespaced IdeNSType (P.runProperName name), ss)]   P.ExternKindDeclaration name ->-    [(IdeNSKind (P.runProperName name), ss)]+    [(IdeNamespaced IdeNSKind (P.runProperName name), ss)]   _ -> []   where     -- We need this special case to be able to also get the position info for@@ -101,5 +115,5 @@       P.PositionedDeclaration ssP' _ dP' ->         extractSpans' ssP' dP'       P.TypeDeclaration ident _ ->-        [(IdeNSValue (P.runIdent ident), ssP)]+        [(IdeNamespaced IdeNSValue (P.runIdent ident), ssP)]       _ -> []
src/Language/PureScript/Ide/State.hs view
@@ -25,9 +25,8 @@   , insertModule   , insertExternsSTM   , getAllModules-  , populateStage2-  , populateStage3-  , populateStage3STM+  , populateVolatileState+  , populateVolatileStateSTM   -- for tests   , resolveOperatorsForModule   , resolveInstances@@ -52,9 +51,7 @@ resetIdeState :: Ide m => m () resetIdeState = do   ideVar <- ideStateVar <$> ask-  liftIO . atomically $ do-    writeTVar ideVar emptyIdeState-    setStage3STM ideVar emptyStage3+  liftIO (atomically (writeTVar ideVar emptyIdeState))  -- | Gets the loaded Modulenames getLoadedModulenames :: Ide m => m [P.ModuleName]@@ -62,7 +59,7 @@  -- | Gets all loaded ExternFiles getExternFiles :: Ide m => m (ModuleMap ExternsFile)-getExternFiles = s1Externs <$> getStage1+getExternFiles = fsExterns <$> getFileState  -- | Insert a Module into Stage1 of the State insertModule :: Ide m => (FilePath, P.Module) -> m ()@@ -74,51 +71,35 @@ insertModuleSTM :: TVar IdeState -> (FilePath, P.Module) -> STM () insertModuleSTM ref (fp, module') =   modifyTVar ref $ \x ->-    x { ideStage1 = (ideStage1 x) {-          s1Modules = Map.insert+    x { ideFileState = (ideFileState x) {+          fsModules = Map.insert             (P.getModuleName module')             (module', fp)-            (s1Modules (ideStage1 x))}}---- | Retrieves Stage1 from the State.---  This includes loaded Externfiles-getStage1 :: Ide m => m Stage1-getStage1 = do-  st <- ideStateVar <$> ask-  fmap ideStage1 . liftIO . readTVarIO $ st---- | STM version of getStage1-getStage1STM :: TVar IdeState -> STM Stage1-getStage1STM ref = ideStage1 <$> readTVar ref+            (fsModules (ideFileState x))}} --- | Retrieves Stage2 from the State.-getStage2 :: Ide m => m Stage2-getStage2 = do+-- | Retrieves the FileState from the State. This includes loaded Externfiles+-- and parsed Modules+getFileState :: Ide m => m IdeFileState+getFileState = do   st <- ideStateVar <$> ask-  liftIO (atomically (getStage2STM st))--getStage2STM ::  TVar IdeState -> STM Stage2-getStage2STM ref = ideStage2 <$> readTVar ref+  fmap ideFileState . liftIO . readTVarIO $ st --- | STM version of setStage2-setStage2STM :: TVar IdeState -> Stage2 -> STM ()-setStage2STM ref s2 = do-  modifyTVar ref $ \x ->-    x {ideStage2 = s2}-  pure ()+-- | STM version of getFileState+getFileStateSTM :: TVar IdeState -> STM IdeFileState+getFileStateSTM ref = ideFileState <$> readTVar ref --- | Retrieves Stage3 from the State.+-- | Retrieves VolatileState from the State. -- This includes the denormalized Declarations and cached rebuilds-getStage3 :: Ide m => m Stage3-getStage3 = do+getVolatileState :: Ide m => m IdeVolatileState+getVolatileState = do   st <- ideStateVar <$> ask-  fmap ideStage3 . liftIO . readTVarIO $ st+  fmap ideVolatileState . liftIO . readTVarIO $ st --- | Sets Stage3 inside the compiler-setStage3STM :: TVar IdeState -> Stage3 -> STM ()-setStage3STM ref s3 = do+-- | Sets the VolatileState inside Ide's state+setVolatileStateSTM :: TVar IdeState -> IdeVolatileState -> STM ()+setVolatileStateSTM ref vs = do   modifyTVar ref $ \x ->-    x {ideStage3 = s3}+    x {ideVolatileState = vs}   pure ()  -- | Checks if the given ModuleName matches the last rebuild cache and if it@@ -126,7 +107,7 @@ -- cache getAllModules :: Ide m => Maybe P.ModuleName -> m [(P.ModuleName, [IdeDeclarationAnn])] getAllModules mmoduleName = do-  declarations <- s3Declarations <$> getStage3+  declarations <- vsDeclarations <$> getVolatileState   rebuild <- cachedRebuild   case mmoduleName of     Nothing -> pure (Map.toList declarations)@@ -134,7 +115,7 @@       case rebuild of         Just (cachedModulename, ef)           | cachedModulename == moduleName -> do-              (AstData asts) <- s2AstData <$> getStage2+              AstData asts <- vsAstData <$> getVolatileState               let                 ast =                   fromMaybe (Map.empty, Map.empty) (Map.lookup moduleName asts)@@ -148,9 +129,9 @@               pure (Map.toList resolved)         _ -> pure (Map.toList declarations) --- | Adds an ExternsFile into psc-ide's State Stage1. This does not populate the--- following Stages, which needs to be done after all the necessary Exterms have--- been loaded.+-- | Adds an ExternsFile into psc-ide's FileState. This does not populate the+-- VolatileState, which needs to be done after all the necessary Externs and+-- SourceFiles have been loaded. insertExterns :: Ide m => ExternsFile -> m () insertExterns ef = do   st <- ideStateVar <$> ask@@ -160,62 +141,47 @@ insertExternsSTM :: TVar IdeState -> ExternsFile -> STM () insertExternsSTM ref ef =   modifyTVar ref $ \x ->-    x { ideStage1 = (ideStage1 x) {-          s1Externs = Map.insert (efModuleName ef) ef (s1Externs (ideStage1 x))}}+    x { ideFileState = (ideFileState x) {+          fsExterns = Map.insert (efModuleName ef) ef (fsExterns (ideFileState x))}}  -- | Sets rebuild cache to the given ExternsFile cacheRebuild :: Ide m => ExternsFile -> m () cacheRebuild ef = do   st <- ideStateVar <$> ask   liftIO . atomically . modifyTVar st $ \x ->-    x { ideStage3 = (ideStage3 x) {-          s3CachedRebuild = Just (efModuleName ef, ef)}}+    x { ideVolatileState = (ideVolatileState x) {+          vsCachedRebuild = Just (efModuleName ef, ef)}}  -- | Retrieves the rebuild cache cachedRebuild :: Ide m => m (Maybe (P.ModuleName, ExternsFile))-cachedRebuild = s3CachedRebuild <$> getStage3---- | Extracts source spans from the parsed ASTs-populateStage2 :: (Ide m, MonadLogger m) => m ()-populateStage2 = do-  st <- ideStateVar <$> ask-  let message duration = "Finished populating Stage2 in " <> displayTimeSpec duration-  logPerf message (liftIO (atomically (populateStage2STM st)))---- | STM version of populateStage2-populateStage2STM :: TVar IdeState -> STM ()-populateStage2STM ref = do-  modules <- s1Modules <$> getStage1STM ref-  let astData = map (extractAstInformation . fst) modules-  setStage2STM ref (Stage2 (AstData astData))+cachedRebuild = vsCachedRebuild <$> getVolatileState --- | Resolves reexports and populates Stage3 with data to be used in queries.-populateStage3 :: (Ide m, MonadLogger m) => m ()-populateStage3 = do+-- | Resolves reexports and populates VolatileState with data to be used in queries.+populateVolatileState :: (Ide m, MonadLogger m) => m ()+populateVolatileState = do   st <- ideStateVar <$> ask   let message duration = "Finished populating Stage3 in " <> displayTimeSpec duration-  results <- logPerf message (liftIO (atomically (populateStage3STM st)))+  results <- logPerf message (liftIO (atomically (populateVolatileStateSTM st)))   void $ Map.traverseWithKey     (\mn -> logWarnN . prettyPrintReexportResult (const (P.runModuleName mn)))     (Map.filter reexportHasFailures results) --- | STM version of populateStage3-populateStage3STM+-- | STM version of populateVolatileState+populateVolatileStateSTM   :: TVar IdeState   -> STM (ModuleMap (ReexportResult [IdeDeclarationAnn]))-populateStage3STM ref = do-  externs <- s1Externs <$> getStage1STM ref-  (AstData asts) <- s2AstData <$> getStage2STM ref-  let (modules, reexportRefs) = (map fst &&& map snd) (Map.map convertExterns externs)+populateVolatileStateSTM ref = do+  IdeFileState{fsExterns = externs, fsModules = modules} <- getFileStateSTM ref+  let asts = map (extractAstInformation . fst) modules+  let (moduleDeclarations, reexportRefs) = (map fst &&& map snd) (Map.map convertExterns externs)       results =-        resolveLocations asts modules+        resolveLocations asts moduleDeclarations         & resolveInstances externs         & resolveOperators         & resolveReexports reexportRefs-  setStage3STM ref (Stage3 (map reResolved results) Nothing)+  setVolatileStateSTM ref (IdeVolatileState (AstData asts) (map reResolved results) Nothing)   pure results - resolveLocations   :: ModuleMap (DefinitionSites P.SourceSpan, TypeAnnotations)   -> ModuleMap [IdeDeclarationAnn]@@ -250,12 +216,12 @@       IdeDeclKind i ->         annotateKind (i ^. properNameT) (IdeDeclKind i)       where-        annotateFunction x = IdeDeclarationAnn (ann { _annLocation = Map.lookup (IdeNSValue (P.runIdent x)) defs+        annotateFunction x = IdeDeclarationAnn (ann { _annLocation = Map.lookup (IdeNamespaced IdeNSValue (P.runIdent x)) defs                                                     , _annTypeAnnotation = Map.lookup x types                                                     })-        annotateValue x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSValue x) defs})-        annotateType x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSType x) defs})-        annotateKind x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNSKind x) defs})+        annotateValue x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNamespaced IdeNSValue x) defs})+        annotateType x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNamespaced IdeNSType x) defs})+        annotateKind x = IdeDeclarationAnn (ann {_annLocation = Map.lookup (IdeNamespaced IdeNSKind x) defs})  resolveInstances   :: ModuleMap P.ExternsFile@@ -276,8 +242,8 @@           _ -> Nothing     extractInstances _ _ = Nothing -    go ::-      (IdeInstance, P.ModuleName, P.ProperName 'P.ClassName)+    go+      :: (IdeInstance, P.ModuleName, P.ProperName 'P.ClassName)       -> ModuleMap [IdeDeclarationAnn]       -> ModuleMap [IdeDeclarationAnn]     go (ideInstance, classModule, className) acc' =
src/Language/PureScript/Ide/Types.hs view
@@ -22,9 +22,9 @@ import           Control.Concurrent.STM import           Control.Lens.TH import           Data.Aeson-import qualified Data.Map.Lazy                       as M-import qualified Language.PureScript                 as P-import qualified Language.PureScript.Errors.JSON     as P+import qualified Data.Map.Lazy as M+import qualified Language.PureScript as P+import qualified Language.PureScript.Errors.JSON as P  type ModuleIdent = Text type ModuleMap a = Map P.ModuleName a@@ -119,18 +119,18 @@ emptyAnn :: Annotation emptyAnn = Annotation Nothing Nothing Nothing -type DefinitionSites a = Map IdeDeclNamespace a+type DefinitionSites a = Map IdeNamespaced a type TypeAnnotations = Map P.Ident P.Type newtype AstData a = AstData (ModuleMap (DefinitionSites a, TypeAnnotations))-  -- ^ SourceSpans for the definition sites of Values and Types aswell as type+  -- ^ SourceSpans for the definition sites of values and types as well as type   -- annotations found in a module   deriving (Show, Eq, Ord, Functor, Foldable)  data IdeLogLevel = LogDebug | LogPerf | LogAll | LogDefault | LogNone   deriving (Show, Eq) -data Configuration =-  Configuration+data IdeConfiguration =+  IdeConfiguration   { confOutputPath :: FilePath   , confLogLevel   :: IdeLogLevel   , confGlobs      :: [FilePath]@@ -139,41 +139,47 @@ data IdeEnvironment =   IdeEnvironment   { ideStateVar      :: TVar IdeState-  , ideConfiguration :: Configuration+  , ideConfiguration :: IdeConfiguration   }  type Ide m = (MonadIO m, MonadReader IdeEnvironment m)  data IdeState = IdeState-  { ideStage1 :: Stage1-  , ideStage2 :: Stage2-  , ideStage3 :: Stage3+  { ideFileState     :: IdeFileState+  , ideVolatileState :: IdeVolatileState   } deriving (Show)  emptyIdeState :: IdeState-emptyIdeState = IdeState emptyStage1 emptyStage2 emptyStage3+emptyIdeState = IdeState emptyFileState emptyVolatileState -emptyStage1 :: Stage1-emptyStage1 = Stage1 M.empty M.empty+emptyFileState :: IdeFileState+emptyFileState = IdeFileState M.empty M.empty -emptyStage2 :: Stage2-emptyStage2 = Stage2 (AstData M.empty)+emptyVolatileState :: IdeVolatileState+emptyVolatileState = IdeVolatileState (AstData M.empty) M.empty Nothing -emptyStage3 :: Stage3-emptyStage3 = Stage3 M.empty Nothing -data Stage1 = Stage1-  { s1Externs :: ModuleMap P.ExternsFile-  , s1Modules :: ModuleMap (P.Module, FilePath)+-- | @IdeFileState@ holds data that corresponds 1-to-1 to an entity on the+-- filesystem. Externs correspond to the ExternsFiles the compiler emits into+-- the output folder, and modules are parsed ASTs from source files. This means,+-- that we can update single modules or ExternsFiles inside this state whenever+-- the corresponding entity changes on the file system.+data IdeFileState = IdeFileState+  { fsExterns :: ModuleMap P.ExternsFile+  , fsModules :: ModuleMap (P.Module, FilePath)   } deriving (Show) -data Stage2 = Stage2-  { s2AstData :: AstData P.SourceSpan-  } deriving (Show, Eq)--data Stage3 = Stage3-  { s3Declarations  :: ModuleMap [IdeDeclarationAnn]-  , s3CachedRebuild :: Maybe (P.ModuleName, P.ExternsFile)+-- | @IdeVolatileState@ is derived from the @IdeFileState@ and needs to be+-- invalidated and refreshed carefully. It holds @AstData@, which is the data we+-- extract from the parsed ASTs, as well as the IdeDeclarations, which contain+-- lots of denormalized data, so they need to fully rebuilt whenever+-- @IdeFileState@ changes. The vsCachedRebuild field can hold a rebuild result+-- with open imports which is used to provide completions for module private+-- declarations+data IdeVolatileState = IdeVolatileState+  { vsAstData       :: AstData P.SourceSpan+  , vsDeclarations  :: ModuleMap [IdeDeclarationAnn]+  , vsCachedRebuild :: Maybe (P.ModuleName, P.ExternsFile)   } deriving (Show)  newtype Match a = Match (P.ModuleName, a)@@ -187,6 +193,7 @@   , complExpandedType  :: Text   , complLocation      :: Maybe P.SourceSpan   , complDocumentation :: Maybe Text+  , complExportedFrom  :: [P.ModuleName]   } deriving (Show, Eq, Ord)  instance ToJSON Completion where@@ -197,6 +204,7 @@            , "expandedType" .= complExpandedType            , "definedAt" .= complLocation            , "documentation" .= complDocumentation+           , "exportedFrom" .= complExportedFrom            ]  identifierFromDeclarationRef :: P.DeclarationRef -> Text@@ -305,11 +313,18 @@       , "text"    .= text       ] -data IdeDeclNamespace =-  -- | An identifier in the value namespace-  IdeNSValue Text-  -- | An identifier in the type namespace-  | IdeNSType Text-  -- | An identifier in the kind namespace-  | IdeNSKind Text+-- | Denotes the different namespaces a name in PureScript can reside in.+data IdeNamespace = IdeNSValue | IdeNSType | IdeNSKind+  deriving (Show, Eq, Ord)++instance FromJSON IdeNamespace where+  parseJSON (String s) = case s of+    "value" -> pure IdeNSValue+    "type"  -> pure IdeNSType+    "kind"  -> pure IdeNSKind+    _       -> mzero+  parseJSON _ = mzero++-- | A name tagged with a namespace+data IdeNamespaced = IdeNamespaced IdeNamespace Text   deriving (Show, Eq, Ord)
src/Language/PureScript/Ide/Util.hs view
@@ -17,7 +17,7 @@   , unwrapMatch   , unwrapPositioned   , unwrapPositionedRef-  , completionFromMatch+  , namespaceForDeclaration   , encodeT   , decodeT   , discardAnn@@ -28,7 +28,6 @@   , identT   , opNameT   , ideReadFile-  , ideReadTextFile   , module Language.PureScript.Ide.Logging   ) where @@ -38,11 +37,10 @@ import           Control.Lens                        hiding ((&), op) import           Data.Aeson import qualified Data.Text                           as T-import qualified Data.Text.IO                        as TIO import qualified Data.Text.Lazy                      as TL-import           Data.Text.Lazy.Encoding             (decodeUtf8, encodeUtf8)+import           Data.Text.Lazy.Encoding             as TLE import qualified Language.PureScript                 as P-import           Language.PureScript.Ide.Error       (prettyPrintTypeSingleLine, IdeError(..))+import           Language.PureScript.Ide.Error       (IdeError(..)) import           Language.PureScript.Ide.Logging import           Language.PureScript.Ide.Types import           System.IO.UTF8                      (readUTF8FileT)@@ -58,6 +56,17 @@   IdeDeclTypeOperator op -> op ^. ideTypeOpName & P.runOpName   IdeDeclKind name -> P.runProperName name +namespaceForDeclaration :: IdeDeclaration -> IdeNamespace+namespaceForDeclaration d = case d of+  IdeDeclValue _ -> IdeNSValue+  IdeDeclType _ -> IdeNSType+  IdeDeclTypeSynonym _ -> IdeNSType+  IdeDeclDataConstructor _ -> IdeNSValue+  IdeDeclTypeClass _ -> IdeNSType+  IdeDeclValueOperator _ -> IdeNSValue+  IdeDeclTypeOperator _ -> IdeNSType+  IdeDeclKind _ -> IdeNSKind+ discardAnn :: IdeDeclarationAnn -> IdeDeclaration discardAnn (IdeDeclarationAnn _ d) = d @@ -67,37 +76,6 @@ unwrapMatch :: Match a -> a unwrapMatch (Match (_, ed)) = ed -completionFromMatch :: Match IdeDeclarationAnn -> Completion-completionFromMatch (Match (m, IdeDeclarationAnn ann decl)) =-  Completion {..}-  where-    (complIdentifier, complExpandedType) = case decl of-      IdeDeclValue v -> (v ^. ideValueIdent . identT, v ^. ideValueType & prettyPrintTypeSingleLine)-      IdeDeclType t -> (t ^. ideTypeName . properNameT, t ^. ideTypeKind & P.prettyPrintKind)-      IdeDeclTypeSynonym s -> (s ^. ideSynonymName . properNameT, s ^. ideSynonymType & prettyPrintTypeSingleLine)-      IdeDeclDataConstructor d -> (d ^. ideDtorName . properNameT, d ^. ideDtorType & prettyPrintTypeSingleLine)-      IdeDeclTypeClass d -> (d ^. ideTCName . properNameT, d ^. ideTCKind & P.prettyPrintKind)-      IdeDeclValueOperator (IdeValueOperator op ref precedence associativity typeP) ->-        (P.runOpName op, maybe (showFixity precedence associativity (valueOperatorAliasT ref) op) prettyPrintTypeSingleLine typeP)-      IdeDeclTypeOperator (IdeTypeOperator op ref precedence associativity kind) ->-        (P.runOpName op, maybe (showFixity precedence associativity (typeOperatorAliasT ref) op) P.prettyPrintKind kind)-      IdeDeclKind k -> (P.runProperName k, "kind")--    complModule = P.runModuleName m--    complType = maybe complExpandedType prettyPrintTypeSingleLine (_annTypeAnnotation ann)--    complLocation = _annLocation ann--    complDocumentation = Nothing--    showFixity p a r o =-      let asso = case a of-            P.Infix -> "infix"-            P.Infixl -> "infixl"-            P.Infixr -> "infixr"-      in T.unwords [asso, show p, r, "as", P.runOpName o]- valueOperatorAliasT   :: P.Qualified (Either P.Ident (P.ProperName 'P.ConstructorName)) -> Text valueOperatorAliasT i =@@ -109,10 +87,10 @@   P.showQualified P.runProperName i  encodeT :: (ToJSON a) => a -> Text-encodeT = TL.toStrict . decodeUtf8 . encode+encodeT = TL.toStrict . TLE.decodeUtf8 . encode  decodeT :: (FromJSON a) => Text -> Maybe a-decodeT = decode . encodeUtf8 . TL.fromStrict+decodeT = decode . TLE.encodeUtf8 . TL.fromStrict  unwrapPositioned :: P.Declaration -> P.Declaration unwrapPositioned (P.PositionedDeclaration _ _ x) = unwrapPositioned x@@ -145,11 +123,3 @@  ideReadFile :: (MonadIO m, MonadError IdeError m) => FilePath -> m Text ideReadFile = ideReadFile' readUTF8FileT---- | This function is to be used over @ideReadFile@ when the result is not just--- passed on to the PureScript parser, but also needs to be treated as lines of--- text. Because @ideReadFile@ reads the file as ByteString in @BinaryMode@--- rather than @TextMode@ line endings get mangled on Windows otherwise. This is--- irrelevant for parsing, because the Lexer strips these additional @\r@'s.-ideReadTextFile :: (MonadIO m, MonadError IdeError m) => FilePath -> m Text-ideReadTextFile = ideReadFile' TIO.readFile
src/Language/PureScript/Ide/Watcher.hs view
@@ -39,7 +39,7 @@     Left err ->       logErrorN ("Failed to reload file at: " <> toS fp <> " with error: " <> show err)     Right ef -> do-      lift $ void $ atomically (insertExternsSTM ref ef *> populateStage3STM ref)+      lift $ void $ atomically (insertExternsSTM ref ef *> populateVolatileStateSTM ref)       logDebugN ("Reloaded File at: " <> toS fp)  -- | Installs filewatchers for the given directory and reloads ExternsFiles when
src/Language/PureScript/Interactive.hs view
@@ -38,11 +38,14 @@ import           Language.PureScript.Interactive.Printer      as Interactive import           Language.PureScript.Interactive.Types        as Interactive +import           System.Directory (getCurrentDirectory) import           System.FilePath ((</>))  -- | Pretty-print errors printErrors :: MonadIO m => P.MultipleErrors -> m ()-printErrors = liftIO . putStrLn . P.prettyPrintMultipleErrors P.defaultPPEOptions+printErrors errs = liftIO $ do+  pwd <- getCurrentDirectory+  putStrLn $ P.prettyPrintMultipleErrors P.defaultPPEOptions {P.ppeRelativeDirectory = pwd} errs  -- | This is different than the runMake in 'Language.PureScript.Make' in that it specifies the -- options and ignores the warning messages.
src/Language/PureScript/Interactive/Module.hs view
@@ -27,8 +27,8 @@   pwd <- getCurrentDirectory   content <- readUTF8FileT filename   return $-    either (Left . P.prettyPrintMultipleErrors P.defaultPPEOptions) (Right . map snd) $-      P.parseModulesFromFiles (makeRelative pwd) [(filename, content)]+    either (Left . P.prettyPrintMultipleErrors P.defaultPPEOptions {P.ppeRelativeDirectory = pwd}) (Right . map snd) $+      P.parseModulesFromFiles id [(filename, content)]  -- | Load all modules. loadAllModules :: [FilePath] -> IO (Either P.MultipleErrors [(FilePath, P.Module)])
src/Language/PureScript/Parser/Declarations.hs view
@@ -195,7 +195,7 @@  parseConstraint :: TokenParser Constraint parseConstraint = Constraint <$> parseQualified properName-                             <*> P.many (noWildcards parseTypeAtom)+                             <*> P.many (noWildcards $ noForAll parseTypeAtom)                              <*> pure Nothing  parseInstanceDeclaration :: TokenParser (TypeInstanceBody -> Declaration)@@ -216,8 +216,14 @@   instanceDecl <- parseInstanceDeclaration   members <- P.option [] $ do     indented *> reserved "where"-    mark (P.many (same *> positioned parseValueDeclaration))+    mark (P.many (same *> positioned declsInInstance))   return $ instanceDecl (ExplicitInstance members)+  where+    declsInInstance :: TokenParser Declaration+    declsInInstance = P.choice+      [ parseTypeDeclaration+      , parseValueDeclaration+      ] P.<?> "type declaration or value declaration in instance"  parseDerivingInstanceDeclaration :: TokenParser Declaration parseDerivingInstanceDeclaration = do
src/Language/PureScript/Parser/Types.hs view
@@ -1,6 +1,7 @@ module Language.PureScript.Parser.Types   ( parseType   , parsePolyType+  , noForAll   , noWildcards   , parseTypeAtom   ) where@@ -51,6 +52,16 @@ parseForAll :: TokenParser Type parseForAll = mkForAll <$> ((reserved "forall" <|> reserved "∀") *> P.many1 (indented *> identifier) <* indented <* dot)                        <*> parseType+++-- |+-- Parse an atomic type with no `forall`+--+noForAll :: TokenParser Type -> TokenParser Type+noForAll p = do+ ty <- p+ when (containsForAll ty) $ P.unexpected "forall"+ return ty  -- | -- Parse a type as it appears in e.g. a data constructor
src/Language/PureScript/Sugar/TypeClasses/Deriving.hs view
@@ -1,19 +1,21 @@--- |--- This module implements the generic deriving elaboration that takes place during desugaring.---+-- | This module implements the generic deriving elaboration that takes place during desugaring. module Language.PureScript.Sugar.TypeClasses.Deriving (deriveInstances) where  import           Prelude.Compat+import           Protolude (ordNub)  import           Control.Arrow (second)-import           Control.Monad (replicateM, zipWithM)+import           Control.Monad (replicateM, zipWithM, unless, when) import           Control.Monad.Error.Class (MonadError(..))+import           Control.Monad.Writer.Class (MonadWriter(..)) import           Control.Monad.Supply.Class (MonadSupply)+import           Data.Foldable (for_) import           Data.List (foldl', find, sortBy, unzip5) import qualified Data.Map as M import           Data.Monoid ((<>)) import           Data.Maybe (fromMaybe, mapMaybe) import           Data.Ord (comparing)+import qualified Data.Set as S import           Data.Text (Text) import qualified Data.Text as T import           Language.PureScript.AST@@ -30,15 +32,47 @@ import           Language.PureScript.TypeChecker (checkNewtype) import           Language.PureScript.TypeChecker.Synonyms (SynonymMap, replaceAllTypeSynonymsM) +-- | When deriving an instance for a newtype, we must ensure that all superclass+-- instances were derived in the same way. This data structure is used to ensure+-- this property.+data NewtypeDerivedInstances = NewtypeDerivedInstances+  { ndiClasses :: M.Map (ModuleName, ProperName 'ClassName) ([Text], [Constraint], [FunctionalDependency])+  -- ^ A list of superclass constraints for each type class. Since type classes+  -- have not been desugared here, we need to track this.+  , ndiDerivedInstances :: S.Set ((ModuleName, ProperName 'ClassName), (ModuleName, ProperName 'TypeName))+  -- ^ A list of newtype instances which were derived in this module.+  } deriving Show++instance Monoid NewtypeDerivedInstances where+  mempty = NewtypeDerivedInstances mempty mempty+  mappend x y =+    NewtypeDerivedInstances { ndiClasses          = ndiClasses          x <> ndiClasses          y+                            , ndiDerivedInstances = ndiDerivedInstances x <> ndiDerivedInstances y+                            }++-- | Extract the name of the newtype appearing in the last type argument of+-- a derived newtype instance.+--+-- Note: since newtypes in newtype instances can only be applied to type arguments+-- (no flexible instances allowed), we don't need to bother with unification when+-- looking for matching superclass instances, which saves us a lot of work. Instead,+-- we just match the newtype name.+extractNewtypeName :: ModuleName -> [Type] -> Maybe (ModuleName, ProperName 'TypeName)+extractNewtypeName _ [] = Nothing+extractNewtypeName mn xs = go (last xs) where+  go (TypeApp ty (TypeVar _)) = go ty+  go (TypeConstructor name) = Just (qualify mn name)+  go _ = Nothing+ -- | Elaborates deriving instance declarations by code generation. deriveInstances   :: forall m-   . (MonadError MultipleErrors m, MonadSupply m)+   . (MonadError MultipleErrors m, MonadWriter MultipleErrors m, MonadSupply m)   => [ExternsFile]   -> Module   -> m Module deriveInstances externs (Module ss coms mn ds exts) =-    Module ss coms mn <$> mapM (deriveInstance mn synonyms ds) ds <*> pure exts+    Module ss coms mn <$> mapM (deriveInstance mn synonyms instanceData ds) ds <*> pure exts   where     -- We need to collect type synonym information, since synonyms will not be     -- removed until later, during type checking.@@ -55,16 +89,34 @@         fromLocalDecl (PositionedDeclaration _ _ d) = fromLocalDecl d         fromLocalDecl _ = Nothing +    instanceData :: NewtypeDerivedInstances+    instanceData =+        foldMap (\ExternsFile{..} -> foldMap (fromExternsDecl efModuleName) efDeclarations) externs <> foldMap fromLocalDecl ds+      where+        fromExternsDecl mn' EDClass{..} =+          NewtypeDerivedInstances (M.singleton (mn', edClassName) (map fst edClassTypeArguments, edClassConstraints, edFunctionalDependencies)) mempty+        fromExternsDecl mn' EDInstance{..} =+          foldMap (\nm -> NewtypeDerivedInstances mempty (S.singleton (qualify mn' edInstanceClassName, nm))) (extractNewtypeName mn' edInstanceTypes)+        fromExternsDecl _ _ = mempty++        fromLocalDecl (TypeClassDeclaration cl args cons deps _) =+          NewtypeDerivedInstances (M.singleton (mn, cl) (map fst args, cons, deps)) mempty+        fromLocalDecl (TypeInstanceDeclaration _ _ cl tys _) =+          foldMap (\nm -> NewtypeDerivedInstances mempty (S.singleton (qualify mn cl, nm))) (extractNewtypeName mn tys)+        fromLocalDecl (PositionedDeclaration _ _ d) = fromLocalDecl d+        fromLocalDecl _ = mempty+ -- | Takes a declaration, and if the declaration is a deriving TypeInstanceDeclaration, -- elaborates that into an instance declaration via code generation. deriveInstance-  :: (MonadError MultipleErrors m, MonadSupply m)+  :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m, MonadSupply m)   => ModuleName   -> SynonymMap+  -> NewtypeDerivedInstances   -> [Declaration]   -> Declaration   -> m Declaration-deriveInstance mn syns ds (TypeInstanceDeclaration nm deps className tys DerivedInstance)+deriveInstance mn syns _ ds (TypeInstanceDeclaration nm deps className tys DerivedInstance)   | className == Qualified (Just dataGeneric) (ProperName C.generic)   = case tys of       [ty] | Just (Qualified mn' tyCon, args) <- unwrapTypeConstructor ty@@ -112,15 +164,15 @@         | otherwise -> throwError . errorMessage $ ExpectedTypeConstructor className tys actualTy       _ -> throwError . errorMessage $ InvalidDerivedInstance className tys 2   | otherwise = throwError . errorMessage $ CannotDerive className tys-deriveInstance mn syns ds (TypeInstanceDeclaration nm deps className tys NewtypeInstance) =+deriveInstance mn syns ndis ds (TypeInstanceDeclaration nm deps className tys NewtypeInstance) =   case tys of     _ : _ | Just (Qualified mn' tyCon, args) <- unwrapTypeConstructor (last tys)           , mn == fromMaybe mn mn'-          -> TypeInstanceDeclaration nm deps className tys . NewtypeInstanceWithDictionary <$> deriveNewtypeInstance syns className ds tys tyCon args+          -> TypeInstanceDeclaration nm deps className tys . NewtypeInstanceWithDictionary <$> deriveNewtypeInstance mn syns ndis className ds tys tyCon args           | otherwise -> throwError . errorMessage $ ExpectedTypeConstructor className tys (last tys)     _ -> throwError . errorMessage $ InvalidNewtypeInstance className tys-deriveInstance mn syns ds (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> deriveInstance mn syns ds d-deriveInstance _ _ _ e = return e+deriveInstance mn syns ndis ds (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> deriveInstance mn syns ndis ds d+deriveInstance _ _ _ _ e = return e  unwrapTypeConstructor :: Type -> Maybe (Qualified (ProperName 'TypeName), [Type]) unwrapTypeConstructor = fmap (second reverse) . go@@ -133,15 +185,18 @@  deriveNewtypeInstance   :: forall m-   . MonadError MultipleErrors m-  => SynonymMap+   . (MonadError MultipleErrors m, MonadWriter MultipleErrors m)+  => ModuleName+  -> SynonymMap+  -> NewtypeDerivedInstances   -> Qualified (ProperName 'ClassName)   -> [Declaration]   -> [Type]   -> ProperName 'TypeName   -> [Type]   -> m Expr-deriveNewtypeInstance syns className ds tys tyConNm dargs = do+deriveNewtypeInstance mn syns ndis className ds tys tyConNm dargs = do+    verifySuperclasses     tyCon <- findTypeDecl tyConNm ds     go tyCon   where@@ -170,6 +225,31 @@     stripRight ((arg, _) : args) (TypeApp t (TypeVar arg'))       | arg == arg' = stripRight args t     stripRight _ _ = Nothing++    verifySuperclasses :: m ()+    verifySuperclasses =+      for_ (M.lookup (qualify mn className) (ndiClasses ndis)) $ \(args, superclasses, _) ->+        for_ superclasses $ \Constraint{..} -> do+          let constraintClass' = qualify (error "verifySuperclasses: unknown class module") constraintClass+          for_ (M.lookup constraintClass' (ndiClasses ndis)) $ \(_, _, deps) ->+            -- We need to check whether the newtype is mentioned, because of classes like MonadWriter+            -- with its Monoid superclass constraint.+            when (not (null args) && any ((last args `elem`) . usedTypeVariables) constraintArgs) $ do+              -- For now, we only verify superclasses where the newtype is the only argument,+              -- or for which all other arguments are determined by functional dependencies.+              -- Everything else raises a UnverifiableSuperclassInstance warning.+              -- This covers pretty much all cases we're interested in, but later we might want to do+              -- more work to extend this to other superclass relationships.+              let determined = map (TypeVar . (args !!)) . ordNub . concatMap fdDetermined . filter ((== [length args - 1]) . fdDeterminers) $ deps+              if last constraintArgs == TypeVar (last args) && all (`elem` determined) (init constraintArgs)+                then do+                  -- Now make sure that a superclass instance was derived. Again, this is not a complete+                  -- check, since the superclass might have multiple type arguments, so overlaps might still+                  -- be possible, so we warn again.+                  for_ (extractNewtypeName mn tys) $ \nm ->+                    unless ((constraintClass', nm) `S.member` ndiDerivedInstances ndis) $+                      tell . errorMessage $ MissingNewtypeSuperclassInstance constraintClass className tys+                else tell . errorMessage $ UnverifiableSuperclassInstance constraintClass className tys  dataGeneric :: ModuleName dataGeneric = ModuleName [ ProperName "Data", ProperName "Generic" ]
src/Language/PureScript/Types.hs view
@@ -216,6 +216,13 @@   go TypeWildcard{} = True   go _ = False +-- | Check if a type contains `forall`+containsForAll :: Type -> Bool+containsForAll = everythingOnTypes (||) go where+  go :: Type -> Bool+  go ForAll{} = True+  go _ = False+ everywhereOnTypes :: (Type -> Type) -> Type -> Type everywhereOnTypes f = go where   go (TypeApp t1 t2) = f (TypeApp (go t1) (go t2))
src/System/IO/UTF8.hs view
@@ -3,13 +3,20 @@ import Prelude.Compat  import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BSL+import qualified Data.ByteString.Search as BSS import qualified Data.ByteString.UTF8 as UTF8 import           Data.Text (Text) import qualified Data.Text.Encoding as TE +-- | Unfortunately ByteString's readFile does not convert line endings on+-- Windows, so we have to do it ourselves+fixCRLF :: BS.ByteString -> BS.ByteString+fixCRLF = BSL.toStrict . BSS.replace "\r\n" ("\n" :: BS.ByteString)+ readUTF8FileT :: FilePath -> IO Text readUTF8FileT inFile =-  fmap TE.decodeUtf8 (BS.readFile inFile)+  fmap (TE.decodeUtf8 . fixCRLF) (BS.readFile inFile)  writeUTF8FileT :: FilePath -> Text -> IO () writeUTF8FileT inFile text =@@ -17,7 +24,7 @@  readUTF8File :: FilePath -> IO String readUTF8File inFile =-  fmap UTF8.toString (BS.readFile inFile)+  fmap (UTF8.toString . fixCRLF) (BS.readFile inFile)  writeUTF8File :: FilePath -> String -> IO () writeUTF8File inFile text =
+ tests/Language/PureScript/Ide/CompletionSpec.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE NoImplicitPrelude #-}+module Language.PureScript.Ide.CompletionSpec where++import Protolude++import Language.PureScript as P+import Language.PureScript.Ide.Completion+import Language.PureScript.Ide.Test+import Language.PureScript.Ide.Types+import Test.Hspec++reexportMatches :: [Match IdeDeclarationAnn]+reexportMatches =+  map (\d -> Match (mn "A", d)) moduleA+  ++ map (\d -> Match (mn "B", d)) moduleB+  where+    moduleA = [ideKind "Kind"]+    moduleB = [ideKind "Kind" `annExp` "A"]++matches :: [(Match IdeDeclarationAnn, [P.ModuleName])]+matches = map (\d -> (Match (mn "Main", d), [mn "Main"])) [ ideKind "Kind", ideType "Type" Nothing ]++spec :: Spec+spec = describe "Applying completion options" $ do+  it "keeps all matches if maxResults is not specified" $ do+    applyCompletionOptions (defaultCompletionOptions { coMaxResults = Nothing })+      (map fst matches) `shouldMatchList` matches+  it "keeps only the specified amount of maxResults" $ do+    applyCompletionOptions (defaultCompletionOptions { coMaxResults = Just 1 })+      (map fst matches) `shouldMatchList` take 1 matches+  it "groups reexports for a single identifier" $ do+    applyCompletionOptions (defaultCompletionOptions { coGroupReexports = True })+      reexportMatches `shouldBe` [(Match (mn "A", ideKind "Kind"), [mn "A", mn "B"])]
tests/Language/PureScript/Ide/FilterSpec.hs view
@@ -3,19 +3,20 @@ module Language.PureScript.Ide.FilterSpec where  import           Protolude+import           Data.List.NonEmpty import           Language.PureScript.Ide.Filter import           Language.PureScript.Ide.Types+import           Language.PureScript.Ide.Test as T import qualified Language.PureScript as P import           Test.Hspec  type Module = (P.ModuleName, [IdeDeclarationAnn]) -value :: Text -> IdeDeclarationAnn-value s = IdeDeclarationAnn emptyAnn (IdeDeclValue (IdeValue (P.Ident (toS s)) P.REmpty))--moduleA, moduleB :: Module-moduleA = (P.moduleNameFromString "Module.A", [value "function1"])-moduleB = (P.moduleNameFromString "Module.B", [value "data1"])+moduleA, moduleB, moduleC, moduleD :: Module+moduleA = (P.moduleNameFromString "Module.A", [T.ideValue "function1" Nothing])+moduleB = (P.moduleNameFromString "Module.B", [T.ideValue "data1" Nothing])+moduleC = (P.moduleNameFromString "Module.C", [T.ideType "List" Nothing])+moduleD = (P.moduleNameFromString "Module.D", [T.ideKind "kind1"])  modules :: [Module] modules = [moduleA, moduleB]@@ -29,6 +30,9 @@ runModule :: [P.ModuleName] -> [Module] runModule ms = applyFilters [moduleFilter ms] modules +runNamespace :: NonEmpty IdeNamespace -> [Module] -> [Module]+runNamespace namespaces = applyFilters [namespaceFilter namespaces]+ spec :: Spec spec = do   describe "equality Filter" $ do@@ -52,3 +56,38 @@       runModule [P.moduleNameFromString "Module.A"] `shouldBe` [moduleA]     it "ignores modules that are not in scope" $       runModule (P.moduleNameFromString <$> ["Module.A", "Unknown"]) `shouldBe` [moduleA]+  describe "namespaceFilter" $ do+    it "extracts modules by filtering `value` namespaces" $+      runNamespace (fromList [IdeNSValue])+        [moduleA, moduleB, moduleD] `shouldBe` [moduleA, moduleB]+    it "extracts no modules by filtering `value` namespaces" $+      runNamespace (fromList [IdeNSValue])+        [moduleD] `shouldBe` []+    it "extracts modules by filtering `type` namespaces" $+      runNamespace (fromList [IdeNSType])+        [moduleA, moduleB, moduleC] `shouldBe` [moduleC]+    it "extracts no modules by filtering `type` namespaces" $+      runNamespace (fromList [IdeNSType])+        [moduleA, moduleB] `shouldBe` []+    it "extracts modules by filtering `kind` namespaces" $+      runNamespace (fromList [IdeNSKind])+        [moduleA, moduleB, moduleD] `shouldBe` [moduleD]+    it "extracts no modules by filtering `kind` namespaces" $+      runNamespace (fromList [IdeNSKind])+        [moduleA, moduleB] `shouldBe` []+    it "extracts modules by filtering `value` and `type` namespaces" $+      runNamespace (fromList [ IdeNSValue, IdeNSType])+        [moduleA, moduleB, moduleC, moduleD]+        `shouldBe` [moduleA, moduleB, moduleC]+    it "extracts modules by filtering `value` and `kind` namespaces" $+      runNamespace (fromList [ IdeNSValue, IdeNSKind])+        [moduleA, moduleB, moduleC, moduleD]+        `shouldBe` [moduleA, moduleB, moduleD]+    it "extracts modules by filtering `type` and `kind` namespaces" $+      runNamespace (fromList [ IdeNSType, IdeNSKind])+        [moduleA, moduleB, moduleC, moduleD]+        `shouldBe` [moduleC, moduleD]+    it "extracts modules by filtering `value`, `type` and `kind` namespaces" $+      runNamespace (fromList [ IdeNSValue, IdeNSType, IdeNSKind])+        [moduleA, moduleB, moduleC, moduleD]+        `shouldBe` [moduleA, moduleB, moduleC, moduleD]
tests/Language/PureScript/Ide/ImportsSpec.hs view
@@ -44,7 +44,7 @@  withImports :: [Text] -> [Text] withImports is =-  take 2 simpleFile ++ is ++ drop 2 simpleFile+  take 2 simpleFile ++ [""] ++ is ++ drop 2 simpleFile  testParseImport :: Text -> Import testParseImport = fromJust . parseImport@@ -108,6 +108,8 @@           prettyPrintImportSection (addExplicitImport' (_idaDeclaration (Test.ideDtor i t Nothing)) mn is)         addTypeImport i mn is =           prettyPrintImportSection (addExplicitImport' (_idaDeclaration (Test.ideType i Nothing)) mn is)+        addKindImport i mn is =+          prettyPrintImportSection (addExplicitImport' (_idaDeclaration (Test.ideKind i)) mn is)     it "adds an implicit unqualified import to a file without any imports" $       shouldBe         (addImplicitImport' [] (P.moduleNameFromString "Data.Map"))@@ -115,8 +117,15 @@     it "adds an implicit unqualified import" $       shouldBe         (addImplicitImport' simpleFileImports (P.moduleNameFromString "Data.Map"))+        [ "import Data.Map"+        , "import Prelude"+        ]+    it "adds a qualified import" $+      shouldBe+        (addQualifiedImport' simpleFileImports (Test.mn "Data.Map") (Test.mn "Map"))         [ "import Prelude"-        , "import Data.Map"+        , ""+        , "import Data.Map as Map"         ]     it "adds an explicit unqualified import to a file without any imports" $       shouldBe@@ -126,6 +135,7 @@       shouldBe         (addValueImport "head" (P.moduleNameFromString "Data.Array") simpleFileImports)         [ "import Prelude"+        , ""         , "import Data.Array (head)"         ]     it "doesn't add an import if the containing module is imported implicitly" $@@ -137,24 +147,35 @@       shouldBe         (addValueImport "head" (P.moduleNameFromString "Data.Array") explicitImports)         [ "import Prelude"+        , ""         , "import Data.Array (head, tail)"         ]+    it "adds a kind to an explicit import list" $+      shouldBe+        (addKindImport "Effect" (P.moduleNameFromString "Control.Monad.Eff") simpleFileImports)+        [ "import Prelude"+        , ""+        , "import Control.Monad.Eff (kind Effect)"+        ]     it "adds an operator to an explicit import list" $       shouldBe         (addOpImport "<~>" (P.moduleNameFromString "Data.Array") explicitImports)         [ "import Prelude"+        , ""         , "import Data.Array (tail, (<~>))"         ]     it "adds a type with constructors without automatically adding an open import of said constructors " $         shouldBe           (addTypeImport "Maybe" (P.moduleNameFromString "Data.Maybe") simpleFileImports)           [ "import Prelude"+          , ""           , "import Data.Maybe (Maybe)"           ]     it "adds the type for a given DataConstructor" $         shouldBe           (addDtorImport "Just" "Maybe" (P.moduleNameFromString "Data.Maybe") simpleFileImports)           [ "import Prelude"+          , ""           , "import Data.Maybe (Maybe(..))"           ]     it "adds a dataconstructor to an existing type import" $ do@@ -162,6 +183,7 @@       shouldBe         (addDtorImport "Just" "Maybe" (P.moduleNameFromString "Data.Maybe") typeImports)         [ "import Prelude"+        , ""         , "import Data.Maybe (Maybe(..))"         ]     it "doesn't add a dataconstructor to an existing type import with open dtors" $ do@@ -169,12 +191,14 @@       shouldBe         (addDtorImport "Just" "Maybe" (P.moduleNameFromString "Data.Maybe") typeImports)         [ "import Prelude"+        , ""         , "import Data.Maybe (Maybe(..))"         ]     it "doesn't add an identifier to an explicit import list if it's already imported" $       shouldBe       (addValueImport "tail" (P.moduleNameFromString "Data.Array") explicitImports)       [ "import Prelude"+      , ""       , "import Data.Array (tail)"       ] @@ -195,23 +219,23 @@           [expected]     it "sorts class" $       expectSorted (map classImport ["Applicative", "Bind"])-        ["import Prelude", "import Control.Monad (class Applicative, class Bind, ap)"]+        ["import Prelude", "", "import Control.Monad (class Applicative, class Bind, ap)"]     it "sorts value" $       expectSorted (map valueImport ["unless", "where"])-        ["import Prelude", "import Control.Monad (ap, unless, where)"]+        ["import Prelude", "", "import Control.Monad (ap, unless, where)"]     it "sorts type, value" $       expectSorted         ((map valueImport ["unless", "where"]) ++ (map typeImport ["Foo", "Bar"]))-        ["import Prelude", "import Control.Monad (Bar, Foo, ap, unless, where)"]+        ["import Prelude", "", "import Control.Monad (Bar, Foo, ap, unless, where)"]     it "sorts class, type, value" $       expectSorted         ((map valueImport ["unless", "where"]) ++ (map typeImport ["Foo", "Bar"]) ++ (map classImport ["Applicative", "Bind"]))-        ["import Prelude", "import Control.Monad (class Applicative, class Bind, Bar, Foo, ap, unless, where)"]+        ["import Prelude", "", "import Control.Monad (class Applicative, class Bind, Bar, Foo, ap, unless, where)"]     it "sorts types with constructors, using open imports for the constructors" $       expectSorted         -- the imported names don't actually have to exist!         (map (uncurry dtorImport) [("Just", "Maybe"), ("Nothing", "Maybe"), ("SomeOtherConstructor", "SomeDataType")])-        ["import Prelude", "import Control.Monad (Maybe(..), SomeDataType(..), ap)"]+        ["import Prelude", "", "import Control.Monad (Maybe(..), SomeDataType(..), ap)"]   describe "importing from a loaded IdeState" importFromIdeState  implImport :: Text -> Command
tests/Language/PureScript/Ide/RebuildSpec.hs view
@@ -5,6 +5,7 @@ import           Protolude  import           Language.PureScript.Ide.Command+import           Language.PureScript.Ide.Completion import           Language.PureScript.Ide.Matcher import           Language.PureScript.Ide.Types import qualified Language.PureScript.Ide.Test as Test@@ -57,5 +58,5 @@     it "completes a hidden identifier after rebuilding" $ do       ([_, (Right (CompletionResult [ result ]))], _) <- Test.inProject $         Test.runIde [ rebuildSync "RebuildSpecWithHiddenIdent.purs"-                    , Complete [] (flexMatcher "hid") (Just (Test.mn "RebuildSpecWithHiddenIdent"))]+                    , Complete [] (flexMatcher "hid") (Just (Test.mn "RebuildSpecWithHiddenIdent")) defaultCompletionOptions]       complIdentifier result `shouldBe` "hidden"
tests/Language/PureScript/Ide/ReexportsSpec.hs view
@@ -11,16 +11,18 @@ import qualified Language.PureScript as P import           Test.Hspec -valueA, typeA, classA, dtorA1, dtorA2 :: IdeDeclarationAnn+valueA, typeA, synonymA, classA, dtorA1, dtorA2, kindA :: IdeDeclarationAnn valueA = ideValue "valueA" Nothing typeA = ideType "TypeA" Nothing+synonymA = ideSynonym "SynonymA" Nothing Nothing classA = ideTypeClass "ClassA" P.kindType [] dtorA1 = ideDtor "DtorA1" "TypeA" Nothing dtorA2 = ideDtor "DtorA2" "TypeA" Nothing+kindA = ideKind "KindA"  env :: ModuleMap [IdeDeclarationAnn] env = Map.fromList-  [ (mn "A", [valueA, typeA, classA, dtorA1, dtorA2])+  [ (mn "A", [valueA, typeA, synonymA, classA, dtorA1, dtorA2, kindA])   ]  type Refs = [(P.ModuleName, P.DeclarationRef)]@@ -32,7 +34,10 @@     , [(mn "A", P.TypeRef (P.ProperName "TypeA") (Just [P.ProperName "DtorA1"]))], [typeA `annExp` "A", dtorA1 `annExp` "A"])   , ("resolves a type reexport with implicit data constructors"     , [(mn "A", P.TypeRef (P.ProperName "TypeA") Nothing)], map (`annExp` "A") [typeA, dtorA1, dtorA2])+  , ("resolves a synonym reexport"+    , [(mn "A", P.TypeRef (P.ProperName "SynonymA") Nothing)], [synonymA `annExp` "A"])   , ("resolves a class reexport", [(mn "A", P.TypeClassRef (P.ProperName "ClassA"))], [classA `annExp` "A"])+  , ("resolves a kind reexport", [(mn "A", P.KindRef (P.ProperName "KindA"))], [kindA `annExp` "A"])   ]  failTestCases :: [(Text, Refs)]
tests/Language/PureScript/Ide/SourceFileSpec.hs view
@@ -44,27 +44,27 @@ spec = do   describe "Extracting Spans" $ do     it "extracts a span for a value declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] value1) `shouldBe` [(IdeNSValue "value1", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] value1) `shouldBe` [(IdeNamespaced IdeNSValue "value1", span1)]     it "extracts a span for a type synonym declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] synonym1) `shouldBe` [(IdeNSType "Synonym1", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] synonym1) `shouldBe` [(IdeNamespaced IdeNSType "Synonym1", span1)]     it "extracts a span for a typeclass declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] class1) `shouldBe` [(IdeNSType "Class1", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] class1) `shouldBe` [(IdeNamespaced IdeNSType "Class1", span1)]     it "extracts spans for a typeclass declaration and its members" $-      extractSpans span0 (P.PositionedDeclaration span1 [] class2) `shouldBe` [(IdeNSType "Class2", span1), (IdeNSValue "member1", span2)]+      extractSpans span0 (P.PositionedDeclaration span1 [] class2) `shouldBe` [(IdeNamespaced IdeNSType "Class2", span1), (IdeNamespaced IdeNSValue "member1", span2)]     it "extracts a span for a data declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] data1) `shouldBe` [(IdeNSType "Data1", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] data1) `shouldBe` [(IdeNamespaced IdeNSType "Data1", span1)]     it "extracts spans for a data declaration and its constructors" $-      extractSpans span0 (P.PositionedDeclaration span1 [] data2) `shouldBe` [(IdeNSType "Data2", span1), (IdeNSValue "Cons1", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] data2) `shouldBe` [(IdeNamespaced IdeNSType "Data2", span1), (IdeNamespaced IdeNSValue "Cons1", span1)]     it "extracts a span for a value operator fixity declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] valueFixity) `shouldBe` [(IdeNSValue "<$>", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] valueFixity) `shouldBe` [(IdeNamespaced IdeNSValue "<$>", span1)]     it "extracts a span for a type operator fixity declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] typeFixity) `shouldBe` [(IdeNSType "~>", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] typeFixity) `shouldBe` [(IdeNamespaced IdeNSType "~>", span1)]     it "extracts a span for a foreign declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] foreign1) `shouldBe` [(IdeNSValue "foreign1", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] foreign1) `shouldBe` [(IdeNamespaced IdeNSValue "foreign1", span1)]     it "extracts a span for a data foreign declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] foreign2) `shouldBe` [(IdeNSType "Foreign2", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] foreign2) `shouldBe` [(IdeNamespaced IdeNSType "Foreign2", span1)]     it "extracts a span for a foreign kind declaration" $-      extractSpans span0 (P.PositionedDeclaration span1 [] foreign3) `shouldBe` [(IdeNSKind "Foreign3", span1)]+      extractSpans span0 (P.PositionedDeclaration span1 [] foreign3) `shouldBe` [(IdeNamespaced IdeNSKind "Foreign3", span1)]   describe "Type annotations" $ do     it "extracts a type annotation" $       extractTypeAnnotations [typeAnnotation1] `shouldBe` [(P.Ident "value1", P.REmpty)]@@ -94,10 +94,10 @@     runIde' defConfig ideState [Type s [] Nothing]   pure (complLocation c)   where-    ideState = emptyIdeState `s3`+    ideState = emptyIdeState `volatileState`       [ ("Test",          [ ideValue "sfValue" Nothing `annLoc` valueSS-         , ideSynonym "SFType" P.tyString P.kindType `annLoc` synonymSS+         , ideSynonym "SFType" Nothing Nothing `annLoc` synonymSS          , ideType "SFData" Nothing `annLoc` typeSS          , ideDtor "SFOne" "SFData" Nothing `annLoc` typeSS          , ideDtor "SFTwo" "SFData" Nothing `annLoc` typeSS
tests/Language/PureScript/Ide/Test.hs view
@@ -17,14 +17,14 @@  import qualified Language.PureScript             as P -defConfig :: Configuration+defConfig :: IdeConfiguration defConfig =-  Configuration { confLogLevel = LogNone+  IdeConfiguration { confLogLevel = LogNone                 , confOutputPath = "output/"                 , confGlobs = ["src/*.purs"]                 } -runIde' :: Configuration -> IdeState -> [Command] -> IO ([Either IdeError Success], IdeState)+runIde' :: IdeConfiguration -> IdeState -> [Command] -> IO ([Either IdeError Success], IdeState) runIde' conf s cs = do   stateVar <- newTVarIO s   let env' = IdeEnvironment {ideStateVar = stateVar, ideConfiguration = conf}@@ -35,11 +35,11 @@ runIde :: [Command] -> IO ([Either IdeError Success], IdeState) runIde = runIde' defConfig emptyIdeState -s3 :: IdeState -> [(Text, [IdeDeclarationAnn])] -> IdeState-s3 s ds =-  s {ideStage3 = stage3}+volatileState :: IdeState -> [(Text, [IdeDeclarationAnn])] -> IdeState+volatileState s ds =+  s {ideVolatileState = vs}   where-    stage3 = Stage3 (Map.fromList decls) Nothing+    vs = IdeVolatileState (AstData Map.empty) (Map.fromList decls) Nothing     decls = map (first P.moduleNameFromString) ds  -- | Adding Annotations to IdeDeclarations@@ -66,8 +66,8 @@ ideType :: Text -> Maybe P.Kind -> IdeDeclarationAnn ideType pn ki = ida (IdeDeclType (IdeType (P.ProperName pn) (fromMaybe P.kindType ki))) -ideSynonym :: Text -> P.Type -> P.Kind -> IdeDeclarationAnn-ideSynonym pn ty kind = ida (IdeDeclTypeSynonym (IdeTypeSynonym (P.ProperName pn) ty kind))+ideSynonym :: Text -> Maybe P.Type -> Maybe P.Kind -> IdeDeclarationAnn+ideSynonym pn ty kind = ida (IdeDeclTypeSynonym (IdeTypeSynonym (P.ProperName pn) (fromMaybe P.tyString ty) (fromMaybe P.kindType kind)))  ideTypeClass :: Text -> P.Kind -> [IdeInstance] -> IdeDeclarationAnn ideTypeClass pn kind instances = ida (IdeDeclTypeClass (IdeTypeClass (P.ProperName pn) kind instances))
tests/TestCompiler.hs view
@@ -61,26 +61,23 @@ spec :: Spec spec = do -  (supportExterns, supportForeigns, passingTestCases, warningTestCases, failingTestCases) <- runIO $ do+  (supportModules, supportExterns, supportForeigns, passingTestCases, warningTestCases, failingTestCases) <- runIO $ do     cwd <- getCurrentDirectory     let passing = cwd </> "examples" </> "passing"     let warning = cwd </> "examples" </> "warning"     let failing = cwd </> "examples" </> "failing"-    let supportDir = cwd </> "tests" </> "support" </> "bower_components"-    let supportFiles ext = Glob.globDir1 (Glob.compile ("purescript-*/src/**/*." ++ ext)) supportDir     passingFiles <- getTestFiles passing <$> testGlob passing     warningFiles <- getTestFiles warning <$> testGlob warning     failingFiles <- getTestFiles failing <$> testGlob failing-    supportPurs <- supportFiles "purs"-    supportPursFiles <- readInput supportPurs+    ms <- getSupportModuleTuples+    let modules = map snd ms     supportExterns <- runExceptT $ do-      modules <- ExceptT . return $ P.parseModulesFromFiles id supportPursFiles-      foreigns <- inferForeignModules modules-      externs <- ExceptT . fmap fst . runTest $ P.make (makeActions foreigns) (map snd modules)-      return (zip (map snd modules) externs, foreigns)+      foreigns <- inferForeignModules ms+      externs <- ExceptT . fmap fst . runTest $ P.make (makeActions modules foreigns) modules+      return (externs, foreigns)     case supportExterns of       Left errs -> fail (P.prettyPrintMultipleErrors P.defaultPPEOptions errs)-      Right (externs, foreigns) -> return (externs, foreigns, passingFiles, warningFiles, failingFiles)+      Right (externs, foreigns) -> return (modules, externs, foreigns, passingFiles, warningFiles, failingFiles)    outputFile <- runIO $ do     tmp <- getTemporaryDirectory@@ -90,21 +87,21 @@   context "Passing examples" $     forM_ passingTestCases $ \testPurs ->       it ("'" <> takeFileName (getTestMain testPurs) <> "' should compile and run without error") $-        assertCompiles supportExterns supportForeigns testPurs outputFile+        assertCompiles supportModules supportExterns supportForeigns testPurs outputFile    context "Warning examples" $     forM_ warningTestCases $ \testPurs -> do       let mainPath = getTestMain testPurs       expectedWarnings <- runIO $ getShouldWarnWith mainPath       it ("'" <> takeFileName mainPath <> "' should compile with warning(s) '" <> intercalate "', '" expectedWarnings <> "'") $-        assertCompilesWithWarnings supportExterns supportForeigns testPurs expectedWarnings+        assertCompilesWithWarnings supportModules supportExterns supportForeigns testPurs expectedWarnings    context "Failing examples" $     forM_ failingTestCases $ \testPurs -> do       let mainPath = getTestMain testPurs       expectedFailures <- runIO $ getShouldFailWith mainPath       it ("'" <> takeFileName mainPath <> "' should fail with '" <> intercalate "', '" expectedFailures <> "'") $-        assertDoesNotCompile supportExterns supportForeigns testPurs expectedFailures+        assertDoesNotCompile supportModules supportExterns supportForeigns testPurs expectedFailures    where @@ -168,18 +165,18 @@ modulesDir :: FilePath modulesDir = ".test_modules" </> "node_modules" -makeActions :: M.Map P.ModuleName FilePath -> P.MakeActions P.Make-makeActions foreigns = (P.buildMakeActions modulesDir (P.internalError "makeActions: input file map was read.") foreigns False)-                         { P.getInputTimestamp = getInputTimestamp-                         , P.getOutputTimestamp = getOutputTimestamp-                         }+makeActions :: [P.Module] -> M.Map P.ModuleName FilePath -> P.MakeActions P.Make+makeActions modules foreigns = (P.buildMakeActions modulesDir (P.internalError "makeActions: input file map was read.") foreigns False)+                               { P.getInputTimestamp = getInputTimestamp+                               , P.getOutputTimestamp = getOutputTimestamp+                               }   where   getInputTimestamp :: P.ModuleName -> P.Make (Either P.RebuildPolicy (Maybe UTCTime))   getInputTimestamp mn-    | isSupportModule (T.unpack (P.runModuleName mn)) = return (Left P.RebuildNever)+    | isSupportModule (P.runModuleName mn) = return (Left P.RebuildNever)     | otherwise = return (Left P.RebuildAlways)     where-    isSupportModule = flip elem supportModules+    isSupportModule = flip elem (map (P.runModuleName . P.getModuleName) modules)    getOutputTimestamp :: P.ModuleName -> P.Make (Maybe UTCTime)   getOutputTimestamp mn = do@@ -187,39 +184,36 @@     exists <- liftIO $ doesDirectoryExist filePath     return (if exists then Just (P.internalError "getOutputTimestamp: read timestamp") else Nothing) -readInput :: [FilePath] -> IO [(FilePath, T.Text)]-readInput inputFiles = forM inputFiles $ \inputFile -> do-  text <- readUTF8FileT inputFile-  return (inputFile, text)- runTest :: P.Make a -> IO (Either P.MultipleErrors a, P.MultipleErrors) runTest = P.runMake P.defaultOptions  compile-  :: [(P.Module, P.ExternsFile)]+  :: [P.Module]+  -> [P.ExternsFile]   -> M.Map P.ModuleName FilePath   -> [FilePath]   -> ([P.Module] -> IO ())   -> IO (Either P.MultipleErrors [P.ExternsFile], P.MultipleErrors)-compile supportExterns supportForeigns inputFiles check = silence $ runTest $ do+compile supportModules supportExterns supportForeigns inputFiles check = silence $ runTest $ do   fs <- liftIO $ readInput inputFiles   ms <- P.parseModulesFromFiles id fs   foreigns <- inferForeignModules ms   liftIO (check (map snd ms))-  let actions = makeActions (foreigns `M.union` supportForeigns)+  let actions = makeActions supportModules (foreigns `M.union` supportForeigns)   case ms of-    [singleModule] -> pure <$> P.rebuildModule actions (map snd supportExterns) (snd singleModule)-    _ -> P.make actions (map fst supportExterns ++ map snd ms)+    [singleModule] -> pure <$> P.rebuildModule actions supportExterns (snd singleModule)+    _ -> P.make actions (supportModules ++ map snd ms)  assert-  :: [(P.Module, P.ExternsFile)]+  :: [P.Module]+  -> [P.ExternsFile]   -> M.Map P.ModuleName FilePath   -> [FilePath]   -> ([P.Module] -> IO ())   -> (Either P.MultipleErrors P.MultipleErrors -> IO (Maybe String))   -> Expectation-assert supportExterns supportForeigns inputFiles check f = do-  (e, w) <- compile supportExterns supportForeigns inputFiles check+assert supportModules supportExterns supportForeigns inputFiles check f = do+  (e, w) <- compile supportModules supportExterns supportForeigns inputFiles check   maybeErr <- f (const w <$> e)   maybe (return ()) expectationFailure maybeErr @@ -236,13 +230,14 @@     else Just $ "Expected these errors: " ++ show expected ++ ", but got these: " ++ show actual  assertCompiles-  :: [(P.Module, P.ExternsFile)]+  :: [P.Module]+  -> [P.ExternsFile]   -> M.Map P.ModuleName FilePath   -> [FilePath]   -> Handle   -> Expectation-assertCompiles supportExterns supportForeigns inputFiles outputFile =-  assert supportExterns supportForeigns inputFiles checkMain $ \e ->+assertCompiles supportModules supportExterns supportForeigns inputFiles outputFile =+  assert supportModules supportExterns supportForeigns inputFiles checkMain $ \e ->     case e of       Left errs -> return . Just . P.prettyPrintMultipleErrors P.defaultPPEOptions $ errs       Right _ -> do@@ -262,13 +257,14 @@           Nothing -> return $ Just "Couldn't find node.js executable"  assertCompilesWithWarnings-  :: [(P.Module, P.ExternsFile)]+  :: [P.Module]+  -> [P.ExternsFile]   -> M.Map P.ModuleName FilePath   -> [FilePath]   -> [String]   -> Expectation-assertCompilesWithWarnings supportExterns supportForeigns inputFiles shouldWarnWith =-  assert supportExterns supportForeigns inputFiles checkMain $ \e ->+assertCompilesWithWarnings supportModules supportExterns supportForeigns inputFiles shouldWarnWith =+  assert supportModules supportExterns supportForeigns inputFiles checkMain $ \e ->     case e of       Left errs ->         return . Just . P.prettyPrintMultipleErrors P.defaultPPEOptions $ errs@@ -282,13 +278,14 @@     (<> "\n\n" <> P.prettyPrintMultipleErrors P.defaultPPEOptions warnings)  assertDoesNotCompile-  :: [(P.Module, P.ExternsFile)]+  :: [P.Module]+  -> [P.ExternsFile]   -> M.Map P.ModuleName FilePath   -> [FilePath]   -> [String]   -> Expectation-assertDoesNotCompile supportExterns supportForeigns inputFiles shouldFailWith =-  assert supportExterns supportForeigns inputFiles noPreCheck $ \e ->+assertDoesNotCompile supportModules supportExterns supportForeigns inputFiles shouldFailWith =+  assert supportModules supportExterns supportForeigns inputFiles noPreCheck $ \e ->     case e of       Left errs ->         return $ if null shouldFailWith
tests/TestDocs.hs view
@@ -402,6 +402,10 @@   , ("TypeLevelString",       [ ShouldBeDocumented (n "TypeLevelString") "Foo" ["fooBar"]       ])++  , ("Desugar",+      [ ValueShouldHaveTypeSignature (n "Desugar") "test" (renderedType "forall a b. X (a -> b) a -> b")+      ])   ]    where
tests/TestPsci/CompletionTest.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE OverloadedStrings #-} module TestPsci.CompletionTest where  import Prelude ()@@ -13,17 +14,18 @@ import           Language.PureScript.Interactive import           System.Console.Haskeline import           TestPsci.TestEnv (initTestPSCiEnv)-import           TestUtils (supportModules)+import           TestUtils (getSupportModuleNames)  completionTests :: Spec-completionTests = context "completionTests" $-  mapM_ assertCompletedOk completionTestData+completionTests = context "completionTests" $ do+  mns <- runIO $ getSupportModuleNames+  mapM_ assertCompletedOk (completionTestData mns)  -- If the cursor is at the right end of the line, with the 1st element of the -- pair as the text in the line, then pressing tab should offer all the -- elements of the list (which is the 2nd element) as completions.-completionTestData :: [(String, [String])]-completionTestData =+completionTestData :: [T.Text] -> [(String, [String])]+completionTestData supportModuleNames =   -- basic directives   [ (":h",  [":help"])   , (":r",  [":reload"])@@ -32,12 +34,12 @@   , (":b",  [":browse"])    -- :browse should complete module names-  , (":b Control.Monad.E",    map (":b Control.Monad.Eff" ++) ["", ".Unsafe", ".Class", ".Console"])-  , (":b Control.Monad.Eff.", map (":b Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console"])+  , (":b Control.Monad.E",    map (":b Control.Monad.Eff" ++) ["", ".Unsafe", ".Class", ".Console", ".Uncurried"])+  , (":b Control.Monad.Eff.", map (":b Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console", ".Uncurried"])    -- import should complete module names-  , ("import Control.Monad.E",    map ("import Control.Monad.Eff" ++) ["", ".Unsafe", ".Class", ".Console"])-  , ("import Control.Monad.Eff.", map ("import Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console"])+  , ("import Control.Monad.E",    map ("import Control.Monad.Eff" ++) ["", ".Unsafe", ".Class", ".Console", ".Uncurried"])+  , ("import Control.Monad.Eff.", map ("import Control.Monad.Eff" ++) [".Unsafe", ".Class", ".Console", ".Uncurried"])    -- :quit, :help, :reload, :clear should not complete   , (":help ", [])@@ -65,7 +67,7 @@    -- a few other import tests   , ("impor", ["import"])-  , ("import ", map ("import " ++) supportModules)+  , ("import ", map (T.unpack . mappend "import ") supportModuleNames)   , ("import Prelude ", [])    -- String and number literals should not be completed@@ -99,10 +101,10 @@ getPSCiStateForCompletion :: IO PSCiState getPSCiStateForCompletion = do   (PSCiState _ bs es, _) <- initTestPSCiEnv-  let imports = [controlMonadSTasST, (P.ModuleName [P.ProperName (T.pack "Prelude")], P.Implicit, Nothing)]+  let imports = [controlMonadSTasST, (P.ModuleName [P.ProperName "Prelude"], P.Implicit, Nothing)]   return $ PSCiState imports bs es  controlMonadSTasST :: ImportedModule controlMonadSTasST = (s "Control.Monad.ST", P.Implicit, Just (s "ST"))   where-  s = P.moduleNameFromString . T.pack+  s = P.moduleNameFromString
tests/TestUtils.hs view
@@ -5,14 +5,21 @@ import Prelude () import Prelude.Compat +import qualified Language.PureScript as P+ import Control.Monad+import Control.Monad.Trans.Except import Control.Monad.Trans.Maybe import Control.Exception-+import Data.List (sort)+import qualified Data.Text as T import System.Process import System.Directory import System.Info+import System.IO.UTF8 (readUTF8FileT) import System.Exit (exitFailure)+import System.FilePath ((</>))+import qualified System.FilePath.Glob as Glob import System.IO (stderr, hPutStrLn)  findNodeProcess :: IO (Maybe String)@@ -47,127 +54,28 @@     hPutStrLn stderr "Cannot find node (or nodejs) executable"     exitFailure +readInput :: [FilePath] -> IO [(FilePath, T.Text)]+readInput inputFiles = forM inputFiles $ \inputFile -> do+  text <- readUTF8FileT inputFile+  return (inputFile, text)+ -- | -- The support modules that should be cached between test cases, to avoid -- excessive rebuilding. ---supportModules :: [String]-supportModules =-  [ "Control.Alt"-  , "Control.Alternative"-  , "Control.Applicative"-  , "Control.Apply"-  , "Control.Biapplicative"-  , "Control.Biapply"-  , "Control.Bind"-  , "Control.Category"-  , "Control.Comonad"-  , "Control.Extend"-  , "Control.Lazy"-  , "Control.Monad"-  , "Control.Monad.Eff"-  , "Control.Monad.Eff.Class"-  , "Control.Monad.Eff.Console"-  , "Control.Monad.Eff.Unsafe"-  , "Control.Monad.Rec.Class"-  , "Control.Monad.ST"-  , "Control.MonadPlus"-  , "Control.MonadZero"-  , "Control.Plus"-  , "Control.Semigroupoid"-  , "Data.Array"-  , "Data.Array.Partial"-  , "Data.Array.ST"-  , "Data.Array.ST.Iterator"-  , "Data.Bifoldable"-  , "Data.Bifunctor"-  , "Data.Bifunctor.Clown"-  , "Data.Bifunctor.Flip"-  , "Data.Bifunctor.Join"-  , "Data.Bifunctor.Joker"-  , "Data.Bifunctor.Product"-  , "Data.Bifunctor.Wrap"-  , "Data.Bitraversable"-  , "Data.Boolean"-  , "Data.BooleanAlgebra"-  , "Data.Bounded"-  , "Data.Char"-  , "Data.CommutativeRing"-  , "Data.Either"-  , "Data.Either.Nested"-  , "Data.Eq"-  , "Data.EuclideanRing"-  , "Data.Field"-  , "Data.Foldable"-  , "Data.Function"-  , "Data.Function.Uncurried"-  , "Data.Functor"-  , "Data.Functor.Invariant"-  , "Data.Generic"-  , "Data.Generic.Rep"-  , "Data.Generic.Rep.Bounded"-  , "Data.Generic.Rep.Eq"-  , "Data.Generic.Rep.Monoid"-  , "Data.Generic.Rep.Ord"-  , "Data.Generic.Rep.Semigroup"-  , "Data.Generic.Rep.Show"-  , "Data.HeytingAlgebra"-  , "Data.Identity"-  , "Data.Lazy"-  , "Data.List"-  , "Data.List.Lazy"-  , "Data.List.Lazy.NonEmpty"-  , "Data.List.Lazy.Types"-  , "Data.List.NonEmpty"-  , "Data.List.Partial"-  , "Data.List.Types"-  , "Data.List.ZipList"-  , "Data.Maybe"-  , "Data.Maybe.First"-  , "Data.Maybe.Last"-  , "Data.Monoid"-  , "Data.Monoid.Additive"-  , "Data.Monoid.Alternate"-  , "Data.Monoid.Conj"-  , "Data.Monoid.Disj"-  , "Data.Monoid.Dual"-  , "Data.Monoid.Endo"-  , "Data.Monoid.Multiplicative"-  , "Data.NaturalTransformation"-  , "Data.Newtype"-  , "Data.NonEmpty"-  , "Data.Ord"-  , "Data.Ord.Unsafe"-  , "Data.Ordering"-  , "Data.Ring"-  , "Data.Semigroup"-  , "Data.Semiring"-  , "Data.Show"-  , "Data.String"-  , "Data.String.CaseInsensitive"-  , "Data.String.Regex"-  , "Data.String.Regex.Flags"-  , "Data.String.Regex.Unsafe"-  , "Data.String.Unsafe"-  , "Data.Symbol"-  , "Data.Traversable"-  , "Data.Tuple"-  , "Data.Tuple.Nested"-  , "Data.Unfoldable"-  , "Data.Unit"-  , "Data.Void"-  , "PSCI.Support"-  , "Partial"-  , "Partial.Unsafe"-  , "Prelude"-  , "Test.Assert"-  , "Type.Data.Ordering"-  , "Type.Data.Symbol"-  , "Type.Equality"-  , "Type.Prelude"-  , "Type.Proxy"-  , "Unsafe.Coerce"-  ]+getSupportModuleTuples :: IO [(FilePath, P.Module)]+getSupportModuleTuples = do+  cd <- getCurrentDirectory+  let supportDir = cd </> "tests" </> "support" </> "bower_components"+  supportPurs <- Glob.globDir1 (Glob.compile "purescript-*/src/**/*.purs") supportDir+  supportPursFiles <- readInput supportPurs+  modules <- runExceptT $ ExceptT . return $ P.parseModulesFromFiles id supportPursFiles+  case modules of+    Right ms -> return ms+    Left errs -> fail (P.prettyPrintMultipleErrors P.defaultPPEOptions errs)++getSupportModuleNames :: IO [T.Text]+getSupportModuleNames = sort . map (P.runModuleName . P.getModuleName . snd) <$> getSupportModuleTuples  pushd :: forall a. FilePath -> IO a -> IO a pushd dir act = do
tests/support/bower.json view
@@ -4,7 +4,7 @@     "purescript-arrays": "4.0.0",     "purescript-assert": "3.0.0",     "purescript-console": "3.0.0",-    "purescript-eff": "3.0.0",+    "purescript-eff": "3.1.0",     "purescript-functions": "3.0.0",     "purescript-generics": "4.0.0",     "purescript-generics-rep": "5.0.0",