packages feed

purescript 0.7.3.0 → 0.7.4.1

raw patch · 85 files changed

+1728/−1072 lines, 85 files

Files

examples/failing/438.purs view
@@ -1,4 +1,4 @@--- @shouldFailWith NoInstanceFound+-- @shouldFailWith PossiblyInfiniteInstance  -- See issue 438 for details: this test is mainly here to test that code like -- this doesn't cause the compiler to loop.
+ examples/failing/EmptyDo.purs view
@@ -0,0 +1,6 @@+-- @shouldFailWith ErrorParsingModule++module Main where++main = do+
+ examples/failing/ImportHidingModule.purs view
@@ -0,0 +1,10 @@+-- @shouldFailWith ImportHidingModule+module A where+  x = 1++module B (module B, module A) where+  import A+  y = 1++module C where+  import B hiding (module A)
− examples/failing/OverlappingInstances.purs
@@ -1,14 +0,0 @@--- @shouldFailWith OverlappingInstances-module OverlappingInstances where--import Prelude--data A = A--instance showA1 :: Show A where-  show A = "Instance 1"--instance showA2 :: Show A where-  show A = "Instance 2"--main = Control.Monad.Eff.Console.log $ show A
− examples/failing/OverlappingInstances2.purs
@@ -1,24 +0,0 @@--- @shouldFailWith OverlappingInstances-module OverlappingInstances where--import Prelude--data A = A | B--instance eqA1 :: Eq A where-  eq A A = true-  eq B B = true-  eq _ _ = false--instance eqA2 :: Eq A where-  eq _ _ = true--instance ordA :: Ord A where-  compare A B = LT-  compare B A = GT-  compare _ _ = EQ--test :: forall a. (Ord a) => a -> a -> String-test x y = show $ x == y--main = Control.Monad.Eff.Console.log $ test A B
+ examples/failing/OverlappingReExport.purs view
@@ -0,0 +1,10 @@+-- @shouldFailWith DuplicateValueExport+module A where+  x = true++module B where+  x = false++module C (module A, module M2) where+  import A+  import qualified B as M2
− examples/failing/Superclasses4.purs
@@ -1,15 +0,0 @@--- @shouldFailWith OverlappingInstances-module OverlappingInstances where--import Prelude--class Foo a--instance foo1 :: Foo Number--instance foo2 :: Foo Number--test :: forall a. (Foo a) => a -> a-test a = a--test1 = test 0.0
+ examples/failing/Superclasses5.purs view
@@ -0,0 +1,25 @@+-- @shouldFailWith NoInstanceFound++module Main where++import Prelude++class Su a where+  su :: a -> a++class (Su (Array a)) <= Cl a where+  cl :: a -> a -> a++instance suNumber :: Su Number where+  su n = n + 1.0++instance suArray :: (Su a) => Su (Array a) where+  su [x] = [su x]++instance clNumber :: Cl Number where+  cl n m = n + m++test :: forall a. (Cl a) => a -> Array a+test x = su [cl x x]++main = Control.Monad.Eff.Console.print $ test 10.0
+ examples/passing/ExplicitImportReExport.purs view
@@ -0,0 +1,16 @@+-- from #1244+module Foo where++  foo :: Int+  foo = 3++module Bar (module Foo) where++  import Foo++module Baz where++  import Bar (foo)++  baz :: Int+  baz = foo
− examples/passing/ModuleExportHiding.purs
@@ -1,11 +0,0 @@-module A (module Prelude) where-  import Prelude--module Main where-  import Control.Monad.Eff.Console-  import A hiding (module Prelude)--  otherwise = false--  main = do-    print "1.0"
+ examples/passing/OverlappingInstances.purs view
@@ -0,0 +1,13 @@+module Main where++import Prelude++data A = A++instance showA1 :: Show A where+  show A = "Instance 1"++instance showA2 :: Show A where+  show A = "Instance 2"++main = Test.Assert.assert $ show A == "Instance 1"
+ examples/passing/OverlappingInstances2.purs view
@@ -0,0 +1,23 @@+module Main where++import Prelude++data A = A | B++instance eqA1 :: Eq A where+  eq A A = true+  eq B B = true+  eq _ _ = false++instance eqA2 :: Eq A where+  eq _ _ = true++instance ordA :: Ord A where+  compare A B = LT+  compare B A = GT+  compare _ _ = EQ++test :: forall a. (Ord a) => a -> a -> String+test x y = show $ x == y++main = Test.Assert.assert $ test A B == "false"
+ examples/passing/OverlappingInstances3.purs view
@@ -0,0 +1,16 @@+module Main where++import Prelude++class Foo a++instance foo1 :: Foo Number++instance foo2 :: Foo Number++test :: forall a. (Foo a) => a -> a+test a = a++test1 = test 0.0++main = Test.Assert.assert (test1 == 0.0)
+ examples/passing/ReExportQualified.purs view
@@ -0,0 +1,16 @@+module A where+  x = "Do"++module B where+  y = "ne"++module C (module A, module M2) where+  import A+  import qualified B as M2++module Main where++  import Prelude+  import C++  main = Control.Monad.Eff.Console.log (x ++ y)
− examples/passing/Superclasses2.purs
@@ -1,23 +0,0 @@-module Main where--import Prelude--class Su a where-  su :: a -> a--class (Su (Array a)) <= Cl a where-  cl :: a -> a -> a--instance suNumber :: Su Number where-  su n = n + 1.0--instance suArray :: (Su a) => Su (Array a) where-  su [x] = [su x]--instance clNumber :: Cl Number where-  cl n m = n + m--test :: forall a. (Cl a) => a -> Array a-test x = su [cl x x]--main = Control.Monad.Eff.Console.print $ test 10.0
hierarchy/Main.hs view
@@ -2,7 +2,7 @@ -- -- Module      :  Main -- Copyright   :  (c) Hardy Jones 2014--- License     :  MIT+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Hardy Jones <jones3.hardy@gmail.com> -- Stability   :  experimental@@ -65,7 +65,7 @@   case modules of     Left errs -> hPutStr stderr (P.prettyPrintMultipleErrors False errs) >> exitFailure     Right ms -> do-      for_ ms $ \(P.Module _ moduleName decls _) ->+      for_ ms $ \(P.Module _ _ moduleName decls _) ->         let name = runModuleName moduleName             tcs = filter P.isTypeClassDeclaration decls             supers = sort . nub . filter (not . null) $ fmap superClasses tcs
psc/Main.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Main--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -22,8 +22,9 @@ import Control.Applicative import Control.Monad import Control.Monad.Error.Class (MonadError(..))-import Control.Monad.Writer+import Control.Monad.Writer.Strict +import Data.List (isSuffixOf, partition) import Data.Version (showVersion) import qualified Data.Map as M @@ -56,9 +57,10 @@   when (null input) $ do     hPutStrLn stderr "psc: No input files."     exitFailure-  moduleFiles <- readInput (InputOptions input)+  let (jsFiles, pursFiles) = partition (isSuffixOf ".js") input+  moduleFiles <- readInput (InputOptions pursFiles)   inputForeign <- globWarningOnMisses warnFileTypeNotFound inputForeignGlob-  foreignFiles <- forM inputForeign (\inFile -> (inFile,) <$> readFile inFile)+  foreignFiles <- forM (inputForeign ++ jsFiles) (\inFile -> (inFile,) <$> readFile inFile)   case runWriterT (parseInputs moduleFiles foreignFiles) of     Left errs -> do       hPutStrLn stderr (P.prettyPrintMultipleErrors (P.optionsVerboseErrors opts) errs)@@ -66,7 +68,7 @@     Right ((ms, foreigns), warnings) -> do       when (P.nonEmpty warnings) $         hPutStrLn stderr (P.prettyPrintMultipleWarnings (P.optionsVerboseErrors opts) warnings)-      let filePathMap = M.fromList $ map (\(fp, P.Module _ mn _ _) -> (mn, fp)) ms+      let filePathMap = M.fromList $ map (\(fp, P.Module _ _ mn _ _) -> (mn, fp)) ms           makeActions = buildMakeActions outputDir filePathMap foreigns usePrefix       e <- runMake opts $ P.make makeActions (map snd ms)       case e of@@ -79,7 +81,7 @@           exitSuccess  warnFileTypeNotFound :: String -> IO ()-warnFileTypeNotFound = hPutStrLn stderr . ((++) "psc: No files found using pattern: ")+warnFileTypeNotFound = hPutStrLn stderr . ("psc: No files found using pattern: " ++)  globWarningOnMisses :: (String -> IO ()) -> [FilePath] -> IO [FilePath] globWarningOnMisses warn = concatMapM globWithWarning@@ -168,7 +170,7 @@                     <*> verboseErrors                     <*> (not <$> comments)                     <*> requirePath-                    + pscMakeOptions :: Parser PSCMakeOptions pscMakeOptions = PSCMakeOptions <$> many inputFile                                 <*> many inputForeignFile
psci/Completion.hs view
@@ -1,13 +1,19 @@+{-# LANGUAGE CPP #-}+ module Completion where  import Data.Maybe (mapMaybe) import Data.List (nub, nubBy, sortBy, isPrefixOf, stripPrefix) import Data.Char (isUpper) import Data.Function (on)+#if __GLASGOW_HASKELL__ < 710 import Data.Traversable (traverse)+#endif  import Control.Arrow (second)+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>), (<*>))+#endif import Control.Monad.Trans.Reader (asks, runReaderT, ReaderT) import Control.Monad.Trans.State.Strict @@ -216,7 +222,7 @@   go _ = []  moduleNames :: [P.Module] -> [String]-moduleNames ms = nub [show moduleName | P.Module _ moduleName _ _ <- ms]+moduleNames ms = nub [show moduleName | P.Module _ _ moduleName _ _ <- ms]  directivesFirst :: Completion -> Completion -> Ordering directivesFirst (Completion _ d1 _) (Completion _ d2 _) = go d1 d2
psci/PSCi.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  PSCi--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -17,12 +17,15 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-}+{-# LANGUAGE CPP #-}  module PSCi where  import Data.Foldable (traverse_) import Data.List (intercalate, nub, sort)+#if __GLASGOW_HASKELL__ < 710 import Data.Traversable (traverse)+#endif import Data.Tuple (swap) import Data.Version (showVersion) import qualified Data.Map as M@@ -36,7 +39,7 @@ import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT) import Control.Monad.Trans.State.Strict import Control.Monad.IO.Class (liftIO)-import Control.Monad.Writer (runWriter)+import Control.Monad.Writer.Strict (runWriter) import qualified Control.Monad.Trans.State.Lazy as L  import Options.Applicative as Opts@@ -67,7 +70,7 @@ supportModule :: P.Module supportModule =   case P.parseModulesFromFiles id [("", code)] of-    Right [(_, P.Module cs _ ds exps)] -> P.Module cs supportModuleName ds exps+    Right [(_, P.Module ss cs _ ds exps)] -> P.Module ss cs supportModuleName ds exps     _ -> error "Support module could not be parsed"   where   code :: String@@ -215,7 +218,7 @@     mainDecl = P.ValueDeclaration (P.Ident "main") P.Public [] $ Right mainValue     decls = if exec then [itDecl, mainDecl] else [itDecl]   in-    P.Module [] moduleName ((importDecl `map` imports) ++ lets ++ decls) Nothing+    P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ decls) Nothing   -- |@@ -227,7 +230,7 @@     moduleName = P.ModuleName [P.ProperName "$PSCI"]     itDecl = P.TypeSynonymDeclaration (P.ProperName "IT") [] typ   in-    P.Module [] moduleName ((importDecl `map` imports) ++ lets ++ [itDecl]) Nothing+    P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName ((importDecl `map` imports) ++ lets ++ [itDecl]) Nothing  -- | -- Makes a volatile module to execute the current imports.@@ -237,7 +240,7 @@   let     moduleName = P.ModuleName [P.ProperName "$PSCI"]   in-    P.Module [] moduleName (importDecl `map` imports) Nothing+    P.Module (P.internalModuleSourceSpan "<internal>") [] moduleName (importDecl `map` imports) Nothing  importDecl :: ImportedModule -> P.Declaration importDecl (mn, declType, asQ) = P.ImportDeclaration mn declType asQ@@ -308,7 +311,7 @@   psciIO $ readModules loadedModules >>= putStrLn   return ()   where readModules = return . unlines . sort . nub . map toModuleName-        toModuleName =  N.runModuleName . (\ (P.Module _ mdName _ _) -> mdName) . snd+        toModuleName =  N.runModuleName . (\ (P.Module _ _ mdName _ _) -> mdName) . snd  -- | -- Show the imported modules in psci.@@ -399,7 +402,7 @@   case env of     Left errs -> printErrors errs     Right env' ->-      if moduleName `notElem` (nub . map ((\ (P.Module _ modName _ _ ) -> modName) . snd)) (psciLoadedModules st)+      if moduleName `notElem` (nub . map ((\ (P.Module _ _ modName _ _ ) -> modName) . snd)) (psciLoadedModules st)         then PSCI $ outputStrLn $ "Module '" ++ N.runModuleName moduleName ++ "' is not valid."         else printModuleSignatures moduleName env' @@ -485,7 +488,7 @@ whenFileExists filePath f = do   absPath <- psciIO $ expandTilde filePath   exists <- psciIO $ doesFileExist absPath-  if exists +  if exists     then f absPath     else PSCI . outputStrLn $ "Couldn't locate: " ++ filePath 
psci/Parser.hs view
@@ -13,6 +13,8 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-}+ module Parser   ( parseCommand   ) where@@ -22,7 +24,9 @@ import Data.Char (isSpace) import Data.List (intercalate) +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative hiding (many)+#endif  import Text.Parsec hiding ((<|>)) 
psci/tests/Main.hs view
@@ -1,11 +1,15 @@-{-# LANGUAGE RecordWildCards, TupleSections #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE CPP #-}  module Main where  import Control.Monad.Trans.State.Strict (runStateT) import Control.Monad (when, forM)+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative-import Control.Monad.Writer (runWriterT)+#endif+import Control.Monad.Writer.Strict (runWriterT) import Control.Monad.Trans.Except (runExceptT)  import Data.List (sort)@@ -24,8 +28,11 @@ import Completion import Types +import TestsSetup+ main :: IO () main = do+  fetchSupportCode   Counts{..} <- runTestTT allTests   when (errors + failures > 0) exitFailure 
purescript.cabal view
@@ -1,5 +1,5 @@ name: purescript-version: 0.7.3.0+version: 0.7.4.1 cabal-version: >=1.8 build-type: Simple license: MIT@@ -23,6 +23,7 @@                   , tests/support/setup.js                   , tests/support/package.json                   , tests/support/bower.json+                  , tests/support/setup-win.cmd                   , psci/tests/data/Sample.purs  source-repository head@@ -119,10 +120,13 @@                      Language.PureScript.Sugar.CaseDeclarations                      Language.PureScript.Sugar.DoNotation                      Language.PureScript.Sugar.Names+                     Language.PureScript.Sugar.Names.Env+                     Language.PureScript.Sugar.Names.Imports+                     Language.PureScript.Sugar.Names.Exports                      Language.PureScript.Sugar.ObjectWildcards                      Language.PureScript.Sugar.Operators                      Language.PureScript.Sugar.TypeClasses-                     Language.PureScript.Sugar.TypeClasses.Deriving +                     Language.PureScript.Sugar.TypeClasses.Deriving                      Language.PureScript.Sugar.TypeDeclarations                      Language.PureScript.Traversals                      Language.PureScript.TypeChecker@@ -243,8 +247,9 @@                    Glob -any     type: exitcode-stdio-1.0     main-is: Main.hs+    other-modules: TestsSetup     buildable: True-    hs-source-dirs: tests+    hs-source-dirs: tests tests/common  test-suite psci-tests     build-depends: base >=4 && <5, containers -any, directory -any, filepath -any,@@ -254,6 +259,7 @@                    Glob -any     type: exitcode-stdio-1.0     main-is: Main.hs+    other-modules: TestsSetup     buildable: True-    hs-source-dirs: psci psci/tests+    hs-source-dirs: psci psci/tests tests/common     ghc-options: -Wall
src/Control/Monad/Supply.hs view
@@ -14,12 +14,15 @@ -----------------------------------------------------------------------------  {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE CPP #-}  module Control.Monad.Supply where  import Data.Functor.Identity +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.State import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Reader
src/Control/Monad/Unify.hs view
@@ -28,6 +28,7 @@ import Control.Applicative import Control.Monad.State import Control.Monad.Error.Class (MonadError(..))+import Control.Monad.Writer.Class (MonadWriter(..))  import Data.HashMap.Strict as M @@ -92,7 +93,7 @@ -- The type checking monad, which provides the state of the type checker, and error reporting capabilities -- newtype UnifyT t m a = UnifyT { unUnify :: StateT (UnifyState t) m a }-  deriving (Functor, Monad, Applicative, Alternative, MonadPlus)+  deriving (Functor, Monad, Applicative, Alternative, MonadPlus, MonadWriter w)  instance (MonadState s m) => MonadState s (UnifyT t m) where   get = UnifyT . lift $ get
src/Language/PureScript.hs view
@@ -28,7 +28,7 @@ import Language.PureScript.AST as P import Language.PureScript.Comments as P import Language.PureScript.Environment as P-import Language.PureScript.Errors as P+import Language.PureScript.Errors as P hiding (indent) import Language.PureScript.Kinds as P import Language.PureScript.Linter as P import Language.PureScript.Make as P
src/Language/PureScript/AST/Declarations.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.AST.Declarations--- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -12,7 +12,9 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.AST.Declarations where @@ -21,7 +23,9 @@  import Control.Monad.Identity +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif  import Language.PureScript.AST.Binders import Language.PureScript.AST.Operators@@ -38,11 +42,11 @@ -- a list of declarations, and a list of the declarations that are -- explicitly exported. If the export list is Nothing, everything is exported. ---data Module = Module [Comment] ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)+data Module = Module SourceSpan [Comment] ModuleName [Declaration] (Maybe [DeclarationRef]) deriving (Show, D.Data, D.Typeable)  -- | Return a module's name. getModuleName :: Module -> ModuleName-getModuleName (Module _ name _ _) = name+getModuleName (Module _ _ name _ _) = name  -- | -- An item in a list of explicit imports or exports@@ -84,6 +88,10 @@   r == (PositionedDeclarationRef _ _ r') = r == r'   _ == _ = False +isModuleRef :: DeclarationRef -> Bool+isModuleRef (ModuleRef _) = True+isModuleRef _ = False+ -- | -- The data type which specifies type of import declaration --@@ -172,10 +180,10 @@   -- | This is a regular (explicit) instance   | ExplicitInstance [Declaration]   deriving (Show, D.Data, D.Typeable)- + mapTypeInstanceBody :: ([Declaration] -> [Declaration]) -> TypeInstanceBody -> TypeInstanceBody mapTypeInstanceBody f = runIdentity . traverseTypeInstanceBody (Identity . f)- + -- | A traversal for TypeInstanceBody traverseTypeInstanceBody :: (Applicative f) => ([Declaration] -> f [Declaration]) -> TypeInstanceBody -> f TypeInstanceBody traverseTypeInstanceBody _ DerivedInstance = pure DerivedInstance@@ -386,7 +394,7 @@   -- at superclass implementations when searching for a dictionary, the type class name and   -- instance type, and the type class dictionaries in scope.   ---  | TypeClassDictionary Bool Constraint (M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)))+  | TypeClassDictionary Constraint (M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)))   -- |   -- A typeclass dictionary accessor, the implementation is left unspecified until CoreFn desugaring.   --
src/Language/PureScript/AST/Exported.hs view
@@ -23,7 +23,7 @@ -- instances will be incorrectly removed in some cases. -- exportedDeclarations :: Module -> [Declaration]-exportedDeclarations (Module _ _ decls exps) = go decls+exportedDeclarations (Module _ _ _ decls exps) = go decls   where   go = flattenDecls         >>> filter (isExported exps)
src/Language/PureScript/AST/SourcePos.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.AST.SourcePos--- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -12,7 +12,10 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE DeriveDataTypeable, ScopedTypeVariables, RecordWildCards, OverloadedStrings #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE OverloadedStrings #-}  module Language.PureScript.AST.SourcePos where @@ -65,7 +68,7 @@ displaySourceSpan :: SourceSpan -> String displaySourceSpan sp =   spanName sp ++ " " ++-    displayStartEndPos sp +    displayStartEndPos sp  instance A.ToJSON SourceSpan where   toJSON SourceSpan{..} =@@ -73,3 +76,6 @@              , "start" .= spanStart              , "end"   .= spanEnd              ]++internalModuleSourceSpan :: String -> SourceSpan+internalModuleSourceSpan name = SourceSpan name (SourcePos 0 0) (SourcePos 0 0)
src/Language/PureScript/AST/Traversals.hs view
@@ -12,13 +12,21 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-}+ module Language.PureScript.AST.Traversals where +#if __GLASGOW_HASKELL__ < 710 import Data.Monoid (Monoid(..), mconcat)+#endif import Data.Maybe (mapMaybe)+#if __GLASGOW_HASKELL__ < 710 import Data.Traversable (traverse)+#endif +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad import Control.Arrow ((***), (+++), second) @@ -396,7 +404,7 @@   forDecls (TypeDeclaration _ ty) = f ty   forDecls _ = mempty -  forValues (TypeClassDictionary _ (_, cs) _) = mconcat (map f cs)+  forValues (TypeClassDictionary (_, cs) _) = mconcat (map f cs)   forValues (SuperClassDictionary _ tys) = mconcat (map f tys)   forValues (TypedValue _ _ ty) = f ty   forValues _ = mempty
src/Language/PureScript/Bundle.hs view
@@ -20,6 +20,7 @@ {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Bundle (      bundle@@ -38,7 +39,9 @@  import qualified Data.Set as S +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad import Control.Monad.Error.Class import Language.JavaScript.Parser
src/Language/PureScript/CodeGen/Externs.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.CodeGen.Externs--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -36,28 +36,31 @@ -- Generate foreign imports for all declarations in a module -- moduleToPs :: Module -> Environment -> String-moduleToPs (Module _ _ _ Nothing) _ = error "Module exports were not elaborated in moduleToPs"-moduleToPs (Module _ moduleName ds (Just exts)) env = intercalate "\n" . execWriter $ do-  let exps = listExports exts+moduleToPs (Module _ _ _ _ Nothing) _ = error "Module exports were not elaborated in moduleToPs"+moduleToPs (Module _ _ moduleName ds (Just exts)) env = intercalate "\n" . execWriter $ do+  let exps = listRefs exts   tell ["module " ++ runModuleName moduleName ++ (if null exps then "" else " (" ++ exps ++ ")") ++ " where"]   mapM_ declToPs ds   mapM_ exportToPs exts   where -    listExports :: [DeclarationRef] -> String-    listExports = intercalate ", " . mapMaybe listExport+    listRefs :: [DeclarationRef] -> String+    listRefs = intercalate ", " . mapMaybe listRef -    listExport :: DeclarationRef -> Maybe String-    listExport (PositionedDeclarationRef _ _ d) = listExport d-    listExport (TypeRef name Nothing) = Just $ show name ++ "()"-    listExport (TypeRef name (Just dctors)) = Just $ show name ++ "(" ++ intercalate ", " (map show dctors) ++ ")"-    listExport (ValueRef name) = Just $ show name-    listExport (TypeClassRef name) = Just $ show name-    listExport (ModuleRef name) = Just $ "module " ++ show name-    listExport _ = Nothing+    listRef :: DeclarationRef -> Maybe String+    listRef (PositionedDeclarationRef _ _ d) = listRef d+    listRef (TypeRef name Nothing) = Just $ show name ++ "()"+    listRef (TypeRef name (Just dctors)) = Just $ show name ++ "(" ++ intercalate ", " (map show dctors) ++ ")"+    listRef (ValueRef name) = Just $ show name+    listRef (TypeClassRef name) = Just $ show name+    listRef (ModuleRef name) = Just $ "module " ++ show name+    listRef _ = Nothing      declToPs :: Declaration -> Writer [String] ()-    declToPs (ImportDeclaration mn _ _) = tell ["import " ++ show mn ++ " ()"]+    declToPs (ImportDeclaration mn imp Nothing) =+      tell ["import " ++ show mn ++ importToPs imp]+    declToPs (ImportDeclaration mn imp (Just qual)) =+      tell ["import qualified " ++ show mn ++ importToPs imp ++ " as " ++ show qual]     declToPs (FixityDeclaration (Fixity assoc prec) op) =       case find exportsOp exts of         Nothing -> return ()@@ -69,6 +72,11 @@       exportsOp _ = False     declToPs (PositionedDeclaration _ com d) = mapM_ commentToPs com >> declToPs d     declToPs _ = return ()++    importToPs :: ImportDeclarationType -> String+    importToPs Implicit = ""+    importToPs (Explicit refs) = " (" ++ listRefs refs ++ ")"+    importToPs (Hiding refs) = " hiding (" ++ listRefs refs ++ ")"      commentToPs :: Comment -> Writer [String] ()     commentToPs (LineComment s) = tell ["-- " ++ s]
src/Language/PureScript/CodeGen/JS.hs view
@@ -17,6 +17,7 @@ {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.CodeGen.JS   ( module AST@@ -28,7 +29,9 @@ import Data.List ((\\), delete, intersect) import qualified Data.Traversable as T (traverse) +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Arrow ((&&&)) import Control.Monad (replicateM, forM) import Control.Monad.Reader (MonadReader, asks)
src/Language/PureScript/CodeGen/JS/AST.hs view
@@ -14,13 +14,18 @@ -----------------------------------------------------------------------------  {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.CodeGen.JS.AST where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative (Applicative, (<$>), (<*>))+#endif import Control.Monad.Identity import Data.Data+#if __GLASGOW_HASKELL__ < 710 import Data.Traversable (traverse)+#endif  import Language.PureScript.Comments import Language.PureScript.Traversals
src/Language/PureScript/CodeGen/JS/Optimizer.hs view
@@ -32,12 +32,15 @@ -----------------------------------------------------------------------------  {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.CodeGen.JS.Optimizer (     optimize ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative (Applicative)+#endif import Control.Monad.Reader (MonadReader, ask, asks) import Control.Monad.Supply.Class (MonadSupply) @@ -63,7 +66,7 @@ optimize' :: (Monad m, MonadReader Options m, Applicative m, MonadSupply m) => JS -> m JS optimize' js = do   opts <- ask-  untilFixedPoint (inlineArrComposition . applyAll+  untilFixedPoint (inlineFnComposition . applyAll     [ collapseNestedBlocks     , collapseNestedIfs     , tco opts
src/Language/PureScript/CodeGen/JS/Optimizer/Inliner.hs view
@@ -13,18 +13,22 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-}+ module Language.PureScript.CodeGen.JS.Optimizer.Inliner (   inlineVariables,   inlineValues,   inlineOperator,   inlineCommonOperators,-  inlineArrComposition,+  inlineFnComposition,   etaConvert,   unThunk,   evaluateIifes ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative (Applicative)+#endif import Control.Monad.Supply.Class (MonadSupply, freshName) import Data.Maybe (fromMaybe) @@ -240,18 +244,18 @@  -- (f <<< g $ x) = f (g x) -- (f <<< g)     = \x -> f (g x)-inlineArrComposition :: (Applicative m, MonadSupply m) => JS -> m JS-inlineArrComposition = everywhereOnJSTopDownM convert+inlineFnComposition :: (Applicative m, MonadSupply m) => JS -> m JS+inlineFnComposition = everywhereOnJSTopDownM convert   where   convert :: (MonadSupply m) => JS -> m JS-  convert (JSApp (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) [z]) | isArrCompose dict' fn =+  convert (JSApp (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) [z]) | isFnCompose dict' fn =     return $ JSApp x [JSApp y [z]]-  convert (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) | isArrCompose dict' fn = do+  convert (JSApp (JSApp (JSApp fn [dict']) [x]) [y]) | isFnCompose dict' fn = do     arg <- freshName     return $ JSFunction Nothing [arg] (JSBlock [JSReturn $ JSApp x [JSApp y [JSVar arg]]])   convert other = return other-  isArrCompose :: JS -> JS -> Bool-  isArrCompose dict' fn = isDict semigroupoidArr dict' && isPreludeFn (C.<<<) fn+  isFnCompose :: JS -> JS -> Bool+  isFnCompose dict' fn = isDict semigroupoidFn dict' && (isPreludeFn (C.<<<) fn || isPreludeFn (C.compose) fn)  isDict :: (String, String) -> JS -> Bool isDict (moduleName, dictName) (JSAccessor x (JSVar y)) = x == dictName && y == moduleName@@ -310,5 +314,5 @@ booleanAlgebraBoolean :: (String, String) booleanAlgebraBoolean = (C.prelude, C.booleanAlgebraBoolean) -semigroupoidArr :: (String, String)-semigroupoidArr = (C.prelude, C.semigroupoidArr)+semigroupoidFn :: (String, String)+semigroupoidFn = (C.prelude, C.semigroupoidFn)
src/Language/PureScript/Constants.hs view
@@ -89,6 +89,9 @@ (<<<) :: String (<<<) = "<<<" +compose :: String+compose = "compose"+ -- Functions  negate :: String@@ -235,8 +238,8 @@ semigroupString :: String semigroupString = "semigroupString" -semigroupoidArr :: String-semigroupoidArr = "semigroupoidArr"+semigroupoidFn :: String+semigroupoidFn = "semigroupoidFn"  -- Generic Deriving 
src/Language/PureScript/CoreFn/Desugar.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.CoreFn.Desugar--- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com> -- Stability   :  experimental@@ -40,9 +40,9 @@ -- Desugars a module from AST to CoreFn representation. -- moduleToCoreFn :: Environment -> A.Module -> Module Ann-moduleToCoreFn _ (A.Module _ _ _ Nothing) =+moduleToCoreFn _ (A.Module _ _ _ _ Nothing) =   error "Module exports were not elaborated before moduleToCoreFn"-moduleToCoreFn env (A.Module coms mn decls (Just exps)) =+moduleToCoreFn env (A.Module _ coms mn decls (Just exps)) =   let imports = nub $ mapMaybe importToCoreFn decls ++ findQualModules decls       exps' = nub $ concatMap exportToCoreFn exps       externs = nub $ mapMaybe externToCoreFn decls
src/Language/PureScript/Docs/Convert.hs view
@@ -25,7 +25,7 @@ -- Convert a single Module. -- convertModule :: P.Module -> Module-convertModule m@(P.Module coms moduleName  _ _) =+convertModule m@(P.Module _ coms moduleName  _ _) =   Module (show moduleName) comments (declarations m)   where   comments = convertComments coms
src/Language/PureScript/Docs/ParseAndDesugar.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE TupleSections #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Docs.ParseAndDesugar   ( parseAndDesugar@@ -8,9 +9,12 @@ import qualified Data.Map as M import Control.Arrow (first) import Control.Monad+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif  import Control.Monad.Trans.Except+import Control.Monad.Writer.Strict (runWriterT) import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.IO.Class (MonadIO(..)) @@ -103,9 +107,9 @@ fileInfoToString (FromDep _ fn) = fn  addDefaultImport :: P.ModuleName -> P.Module -> P.Module-addDefaultImport toImport m@(P.Module coms mn decls exps)  =+addDefaultImport toImport m@(P.Module ss coms mn decls exps)  =   if isExistingImport `any` decls || mn == toImport then m-  else P.Module coms mn (P.ImportDeclaration toImport P.Implicit Nothing : decls) exps+  else P.Module ss coms mn (P.ImportDeclaration toImport P.Implicit Nothing : decls) exps   where   isExistingImport (P.ImportDeclaration mn' _ _) | mn' == toImport = True   isExistingImport (P.PositionedDeclaration _ _ d) = isExistingImport d@@ -118,7 +122,8 @@ desugar = P.evalSupplyT 0 . desugar'   where   desugar' :: [P.Module] -> P.SupplyT (Either P.MultipleErrors) [P.Module]-  desugar' = mapM P.desugarDoModule >=> P.desugarCasesModule >=> P.desugarImports+  desugar' = mapM P.desugarDoModule >=> P.desugarCasesModule >=> ignoreWarnings . P.desugarImports+  ignoreWarnings m = liftM fst (runWriterT m)  parseFile :: FilePath -> IO (FilePath, String) parseFile input' = (,) input' <$> readFile input'
src/Language/PureScript/Docs/RenderedCode/Render.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-}  -- | Functions for producing RenderedCode values from PureScript Type values. @@ -11,7 +12,11 @@     renderTypeWithOptions ) where +#if __GLASGOW_HASKELL__ < 710 import Data.Monoid ((<>), mconcat, mempty)+#else+import Data.Monoid ((<>))+#endif import Data.Maybe (fromMaybe)  import Control.Arrow ((<+>))
src/Language/PureScript/Docs/RenderedCode/Types.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-}  -- | Data types and functions for representing a simplified form of PureScript -- code, intended for use in e.g. HTML documentation.@@ -30,9 +31,11 @@  , keywordWhere  ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>), (<*>), (*>), pure) import Data.Foldable import Data.Monoid+#endif import qualified Data.Aeson as A import Data.Aeson.BetterErrors import Control.Monad.Error.Class (MonadError(..))
src/Language/PureScript/Docs/Types.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Docs.Types   ( module Language.PureScript.Docs.Types@@ -10,9 +11,10 @@   where  import Control.Arrow (first, (***))-import Control.Applicative ((<$>), (<*>), pure)+#if __GLASGOW_HASKELL__ < 710+import Control.Applicative ((<$>), (<$), (<*>), pure)+#endif import Control.Monad (when)-import Data.Functor ((<$)) import Data.Maybe (mapMaybe) import Data.Version import Data.Aeson ((.=))
src/Language/PureScript/Errors.hs view
@@ -15,14 +15,18 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Errors where  import Data.Either (lefts, rights) import Data.List (intercalate, transpose) import Data.Function (on)-import Data.Monoid+#if __GLASGOW_HASKELL__ < 710 import Data.Foldable (fold, foldMap)+#else+import Data.Foldable (fold)+#endif  import qualified Data.Map as M @@ -30,7 +34,9 @@ import Control.Monad.Unify import Control.Monad.Writer import Control.Monad.Error.Class (MonadError(..))+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>), (<*>), Applicative, pure)+#endif import Control.Monad.Trans.State.Lazy import Control.Arrow(first) @@ -40,11 +46,13 @@ import Language.PureScript.Types import Language.PureScript.Names import Language.PureScript.Kinds-import Language.PureScript.TypeClassDictionaries  import qualified Text.PrettyPrint.Boxes as Box  import qualified Text.Parsec as P+import qualified Text.Parsec.Error as PE+import Text.Parsec.Error (Message(..))+import Data.List (nub)  -- | -- A type of error messages@@ -66,7 +74,7 @@   | MultipleFixities Ident   | OrphanTypeDeclaration Ident   | OrphanFixityDeclaration String-  | RedefinedModule ModuleName+  | RedefinedModule ModuleName [SourceSpan]   | RedefinedIdent Ident   | OverlappingNamesInLet   | UnknownModule ModuleName@@ -75,6 +83,15 @@   | UnknownValue (Qualified Ident)   | UnknownDataConstructor (Qualified ProperName) (Maybe (Qualified ProperName))   | UnknownTypeConstructor (Qualified ProperName)+  | UnknownImportType ModuleName ProperName+  | UnknownExportType ProperName+  | UnknownImportTypeClass ModuleName ProperName+  | UnknownExportTypeClass ProperName+  | UnknownImportValue ModuleName Ident+  | UnknownExportValue Ident+  | UnknownExportModule ModuleName+  | UnknownImportDataConstructor ModuleName ProperName ProperName+  | UnknownExportDataConstructor ProperName ProperName   | ConflictingImport String ModuleName   | ConflictingImports String ModuleName ModuleName   | ConflictingTypeDecls ProperName@@ -100,8 +117,9 @@   | TypesDoNotUnify Type Type   | KindsDoNotUnify Kind Kind   | ConstrainedTypeUnified Type Type-  | OverlappingInstances (Qualified ProperName) [Type] [DictionaryValue]+  | OverlappingInstances (Qualified ProperName) [Type] [Qualified Ident]   | NoInstanceFound (Qualified ProperName) [Type]+  | PossiblyInfiniteInstance (Qualified ProperName) [Type]   | CannotDerive (Qualified ProperName) [Type]   | CannotFindDerivingType ProperName   | DuplicateLabel String (Maybe Expr)@@ -126,6 +144,8 @@   | NotExhaustivePattern [[Binder]] Bool   | OverlappingPattern [[Binder]] Bool   | ClassOperator ProperName Ident+  | MisleadingEmptyTypeImport ModuleName ProperName+  | ImportHidingModule ModuleName   deriving (Show)  -- |@@ -164,82 +184,94 @@ -- errorCode :: ErrorMessage -> String errorCode em = case unwrapErrorMessage em of-  (ErrorParsingExterns _)       -> "ErrorParsingExterns"-  (ErrorParsingFFIModule _)     -> "ErrorParsingFFIModule"-  (ErrorParsingModule _)        -> "ErrorParsingModule"-  MissingFFIModule{}            -> "MissingFFIModule"-  MultipleFFIModules{}          -> "MultipleFFIModules"-  UnnecessaryFFIModule{}        -> "UnnecessaryFFIModule"-  (InvalidExternsFile _)        -> "InvalidExternsFile"-  (CannotGetFileInfo _)         -> "CannotGetFileInfo"-  (CannotReadFile _)            -> "CannotReadFile"-  (CannotWriteFile _)           -> "CannotWriteFile"-  (InfiniteType _)              -> "InfiniteType"-  (InfiniteKind _)              -> "InfiniteKind"-  CannotReorderOperators        -> "CannotReorderOperators"-  (MultipleFixities _)          -> "MultipleFixities"-  (OrphanTypeDeclaration _)     -> "OrphanTypeDeclaration"-  (OrphanFixityDeclaration _)   -> "OrphanFixityDeclaration"-  (RedefinedModule _)           -> "RedefinedModule"-  (RedefinedIdent _)            -> "RedefinedIdent"-  OverlappingNamesInLet         -> "OverlappingNamesInLet"-  (UnknownModule _)             -> "UnknownModule"-  (UnknownType _)               -> "UnknownType"-  (UnknownTypeClass _)          -> "UnknownTypeClass"-  (UnknownValue _)              -> "UnknownValue"-  (UnknownDataConstructor _ _)  -> "UnknownDataConstructor"-  (UnknownTypeConstructor _)    -> "UnknownTypeConstructor"-  (ConflictingImport _ _)       -> "ConflictingImport"-  (ConflictingImports _ _ _)    -> "ConflictingImports"-  (ConflictingTypeDecls _)      -> "ConflictingTypeDecls"-  (ConflictingCtorDecls _)      -> "ConflictingCtorDecls"-  (TypeConflictsWithClass _)    -> "TypeConflictsWithClass"-  (CtorConflictsWithClass _)    -> "CtorConflictsWithClass"-  (ClassConflictsWithType _)    -> "ClassConflictsWithType"-  (ClassConflictsWithCtor _)    -> "ClassConflictsWithCtor"-  (DuplicateClassExport _)      -> "DuplicateClassExport"-  (DuplicateValueExport _)      -> "DuplicateValueExport"-  (DuplicateTypeArgument _)     -> "DuplicateTypeArgument"-  InvalidDoBind                 -> "InvalidDoBind"-  InvalidDoLet                  -> "InvalidDoLet"-  (CycleInDeclaration _)        -> "CycleInDeclaration"-  (CycleInTypeSynonym _)        -> "CycleInTypeSynonym"-  (CycleInModules _)            -> "CycleInModules"-  (NameIsUndefined _)           -> "NameIsUndefined"-  (NameNotInScope _)            -> "NameNotInScope"-  (UndefinedTypeVariable _)     -> "UndefinedTypeVariable"-  (PartiallyAppliedSynonym _)   -> "PartiallyAppliedSynonym"-  (EscapedSkolem _)             -> "EscapedSkolem"-  UnspecifiedSkolemScope        -> "UnspecifiedSkolemScope"-  (TypesDoNotUnify _ _)         -> "TypesDoNotUnify"-  (KindsDoNotUnify _ _)         -> "KindsDoNotUnify"-  (ConstrainedTypeUnified _ _)  -> "ConstrainedTypeUnified"-  (OverlappingInstances _ _ _)  -> "OverlappingInstances"-  (NoInstanceFound _ _)         -> "NoInstanceFound"-  (CannotDerive _ _)            -> "CannotDerive"-  (CannotFindDerivingType _)    -> "CannotFindDerivingType"-  (DuplicateLabel _ _)          -> "DuplicateLabel"-  (DuplicateValueDeclaration _) -> "DuplicateValueDeclaration"-  (ArgListLengthsDiffer _)      -> "ArgListLengthsDiffer"-  (OverlappingArgNames _)       -> "OverlappingArgNames"-  (MissingClassMember _)        -> "MissingClassMember"-  (ExtraneousClassMember _)     -> "ExtraneousClassMember"-  (ExpectedType _)              -> "ExpectedType"-  (IncorrectConstructorArity _) -> "IncorrectConstructorArity"-  SubsumptionCheckFailed        -> "SubsumptionCheckFailed"-  (ExprDoesNotHaveType _ _)     -> "ExprDoesNotHaveType"-  (PropertyIsMissing _ _)       -> "PropertyIsMissing"-  (CannotApplyFunction _ _)     -> "CannotApplyFunction"-  TypeSynonymInstance           -> "TypeSynonymInstance"-  (OrphanInstance _ _ _)        -> "OrphanInstance"-  InvalidNewtype                -> "InvalidNewtype"-  (InvalidInstanceHead _)       -> "InvalidInstanceHead"-  (TransitiveExportError _ _)   -> "TransitiveExportError"-  (ShadowedName _)              -> "ShadowedName"-  (WildcardInferredType _)      -> "WildcardInferredType"-  (NotExhaustivePattern _ _)    -> "NotExhaustivePattern"-  (OverlappingPattern _ _)      -> "OverlappingPattern"-  (ClassOperator _ _)           -> "ClassOperator"+  ErrorParsingExterns{} -> "ErrorParsingExterns"+  ErrorParsingFFIModule{} -> "ErrorParsingFFIModule"+  ErrorParsingModule{} -> "ErrorParsingModule"+  MissingFFIModule{} -> "MissingFFIModule"+  MultipleFFIModules{} -> "MultipleFFIModules"+  UnnecessaryFFIModule{} -> "UnnecessaryFFIModule"+  InvalidExternsFile{} -> "InvalidExternsFile"+  CannotGetFileInfo{} -> "CannotGetFileInfo"+  CannotReadFile{} -> "CannotReadFile"+  CannotWriteFile{} -> "CannotWriteFile"+  InfiniteType{} -> "InfiniteType"+  InfiniteKind{} -> "InfiniteKind"+  CannotReorderOperators -> "CannotReorderOperators"+  MultipleFixities{} -> "MultipleFixities"+  OrphanTypeDeclaration{} -> "OrphanTypeDeclaration"+  OrphanFixityDeclaration{} -> "OrphanFixityDeclaration"+  RedefinedModule{} -> "RedefinedModule"+  RedefinedIdent{} -> "RedefinedIdent"+  OverlappingNamesInLet -> "OverlappingNamesInLet"+  UnknownModule{} -> "UnknownModule"+  UnknownType{} -> "UnknownType"+  UnknownTypeClass{} -> "UnknownTypeClass"+  UnknownValue{} -> "UnknownValue"+  UnknownDataConstructor{} -> "UnknownDataConstructor"+  UnknownTypeConstructor{} -> "UnknownTypeConstructor"+  UnknownImportType{} -> "UnknownImportType"+  UnknownExportType{} -> "UnknownExportType"+  UnknownImportTypeClass{} -> "UnknownImportTypeClass"+  UnknownExportTypeClass{} -> "UnknownExportTypeClass"+  UnknownImportValue{} -> "UnknownImportValue"+  UnknownExportValue{} -> "UnknownExportValue"+  UnknownExportModule{} -> "UnknownExportModule"+  UnknownImportDataConstructor{} -> "UnknownImportDataConstructor"+  UnknownExportDataConstructor{} -> "UnknownExportDataConstructor"+  ConflictingImport{} -> "ConflictingImport"+  ConflictingImports{} -> "ConflictingImports"+  ConflictingTypeDecls{} -> "ConflictingTypeDecls"+  ConflictingCtorDecls{} -> "ConflictingCtorDecls"+  TypeConflictsWithClass{} -> "TypeConflictsWithClass"+  CtorConflictsWithClass{} -> "CtorConflictsWithClass"+  ClassConflictsWithType{} -> "ClassConflictsWithType"+  ClassConflictsWithCtor{} -> "ClassConflictsWithCtor"+  DuplicateClassExport{} -> "DuplicateClassExport"+  DuplicateValueExport{} -> "DuplicateValueExport"+  DuplicateTypeArgument{} -> "DuplicateTypeArgument"+  InvalidDoBind -> "InvalidDoBind"+  InvalidDoLet -> "InvalidDoLet"+  CycleInDeclaration{} -> "CycleInDeclaration"+  CycleInTypeSynonym{} -> "CycleInTypeSynonym"+  CycleInModules{} -> "CycleInModules"+  NameIsUndefined{} -> "NameIsUndefined"+  NameNotInScope{} -> "NameNotInScope"+  UndefinedTypeVariable{} -> "UndefinedTypeVariable"+  PartiallyAppliedSynonym{} -> "PartiallyAppliedSynonym"+  EscapedSkolem{} -> "EscapedSkolem"+  UnspecifiedSkolemScope -> "UnspecifiedSkolemScope"+  TypesDoNotUnify{} -> "TypesDoNotUnify"+  KindsDoNotUnify{} -> "KindsDoNotUnify"+  ConstrainedTypeUnified{} -> "ConstrainedTypeUnified"+  OverlappingInstances{} -> "OverlappingInstances"+  NoInstanceFound{} -> "NoInstanceFound"+  PossiblyInfiniteInstance{} -> "PossiblyInfiniteInstance"+  CannotDerive{} -> "CannotDerive"+  CannotFindDerivingType{} -> "CannotFindDerivingType"+  DuplicateLabel{} -> "DuplicateLabel"+  DuplicateValueDeclaration{} -> "DuplicateValueDeclaration"+  ArgListLengthsDiffer{} -> "ArgListLengthsDiffer"+  OverlappingArgNames{} -> "OverlappingArgNames"+  MissingClassMember{} -> "MissingClassMember"+  ExtraneousClassMember{} -> "ExtraneousClassMember"+  ExpectedType{} -> "ExpectedType"+  IncorrectConstructorArity{} -> "IncorrectConstructorArity"+  SubsumptionCheckFailed -> "SubsumptionCheckFailed"+  ExprDoesNotHaveType{} -> "ExprDoesNotHaveType"+  PropertyIsMissing{} -> "PropertyIsMissing"+  CannotApplyFunction{} -> "CannotApplyFunction"+  TypeSynonymInstance -> "TypeSynonymInstance"+  OrphanInstance{} -> "OrphanInstance"+  InvalidNewtype -> "InvalidNewtype"+  InvalidInstanceHead{} -> "InvalidInstanceHead"+  TransitiveExportError{} -> "TransitiveExportError"+  ShadowedName{} -> "ShadowedName"+  WildcardInferredType{} -> "WildcardInferredType"+  NotExhaustivePattern{} -> "NotExhaustivePattern"+  OverlappingPattern{} -> "OverlappingPattern"+  ClassOperator{} -> "ClassOperator"+  MisleadingEmptyTypeImport{} -> "MisleadingEmptyTypeImport"+  ImportHidingModule{} -> "ImportHidingModule"  -- | -- A stack trace for an error@@ -367,7 +399,7 @@   prettyPrintErrorMessage em =     paras $       go em:suggestions em ++-      [line $ "See " ++ wikiUri ++ " for more information, or to contribute content related to this error."]+      [line $ "See " ++ wikiUri ++ " for more information, or to contribute content related to this " ++ levelText ++ "."]     where     wikiUri :: String     wikiUri = "https://github.com/purescript/purescript/wiki/Error-Code-" ++ errorCode e@@ -387,7 +419,7 @@             ]     goSimple (ErrorParsingExterns err) =       paras [ lineWithLevel "parsing externs files: "-            , indent . line . show $ err+            , indent . prettyPrintParseError $ err             ]     goSimple (ErrorParsingFFIModule path) =       paras [ line "Unable to parse module from FFI file: "@@ -395,7 +427,7 @@             ]     goSimple (ErrorParsingModule err) =       paras [ line "Unable to parse module: "-            , indent . line . show $ err+            , indent . prettyPrintParseError $ err             ]     goSimple (MissingFFIModule mn) =       line $ "Missing FFI implementations for module " ++ show mn@@ -434,8 +466,9 @@       line $ "Orphan type declaration for " ++ show nm     goSimple (OrphanFixityDeclaration op) =       line $ "Orphan fixity declaration for " ++ show op-    goSimple (RedefinedModule name) =-      line $ "Module " ++ show name ++ " has been defined multiple times"+    goSimple (RedefinedModule name filenames) =+      paras $ [ line $ "Module " ++ show name ++ " has been defined multiple times:"+              ] ++ map (indent . line . displaySourceSpan) filenames     goSimple (RedefinedIdent name) =       line $ "Name " ++ show name ++ " has been defined multiple times"     goSimple (UnknownModule mn) =@@ -450,10 +483,28 @@       line $ "Unknown type constructor " ++ show name     goSimple (UnknownDataConstructor dc tc) =       line $ "Unknown data constructor " ++ show dc ++ foldMap ((" for type constructor " ++) . show) tc+    goSimple (UnknownImportType mn name) =+      line $ "Module " ++ show mn ++ " does not export type " ++ show name+    goSimple (UnknownExportType name) =+      line $ "Cannot export unknown type " ++ show name+    goSimple (UnknownImportTypeClass mn name) =+      line $ "Module " ++ show mn ++ " does not export type class " ++ show name+    goSimple (UnknownExportTypeClass name) =+      line $ "Cannot export unknown type class " ++ show name+    goSimple (UnknownImportValue mn name) =+      line $ "Module " ++ show mn ++ " does not export value " ++ show name+    goSimple (UnknownExportValue name) =+      line $ "Cannot export unknown value " ++ show name+    goSimple (UnknownExportModule name) =+      line $ "Cannot export unknown module " ++ show name ++ ", it either does not exist or has not been imported by the current module"+    goSimple (UnknownImportDataConstructor mn tcon dcon) =+      line $ "Module " ++ show mn ++ " does not export data constructor " ++ show dcon ++ " for type " ++ show tcon+    goSimple (UnknownExportDataConstructor tcon dcon) =+      line $ "Cannot export data constructor " ++ show dcon ++ " for type " ++ show tcon ++ " as it has not been declared"     goSimple (ConflictingImport nm mn) =       line $ "Cannot declare " ++ show nm ++ " since another declaration of that name was imported from " ++ show mn     goSimple (ConflictingImports nm m1 m2) =-      line $ "Conflicting imports for " ++ show nm ++ " from modules " ++ show m1 ++ " and " ++ show m2+      line $ "Conflicting imports for " ++ nm ++ " from modules " ++ show m1 ++ " and " ++ show m2     goSimple (ConflictingTypeDecls nm) =       line $ "Conflicting type declarations for " ++ show nm     goSimple (ConflictingCtorDecls nm) =@@ -507,12 +558,15 @@             , line "with type"             , indent $ line $ prettyPrintType t2             ]-    goSimple (OverlappingInstances nm ts ds) =+    goSimple (OverlappingInstances nm ts (d : ds)) =       paras [ line $ "Overlapping instances found for " ++ show nm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ ":"-            , paras $ map prettyPrintDictionaryValue ds+            , indent $ paras (line (show d ++ " (chosen)") : map (line . show) ds)             ]+    goSimple OverlappingInstances{} = error "OverlappingInstances: empty instance list"     goSimple (NoInstanceFound nm ts) =       line $ "No instance found for " ++ show nm ++ " " ++ unwords (map prettyPrintTypeAtom ts)+    goSimple (PossiblyInfiniteInstance nm ts) =+      line $ "Instance for " ++ show nm ++ " " ++ unwords (map prettyPrintTypeAtom ts) ++ " is possibly infinite."     goSimple (CannotDerive nm ts) =       line $ "Cannot derive " ++ show nm ++ " instance for " ++ unwords (map prettyPrintTypeAtom ts)     goSimple (CannotFindDerivingType nm) =@@ -573,6 +627,10 @@             , indent $ line $ "This may be disallowed in the future - consider declaring a named member in the class and making the operator an alias:"             , indent $ line $ show opName ++ " = someMember"             ]+    goSimple (MisleadingEmptyTypeImport mn name) =+      line $ "Importing type " ++ show name ++ "(..) from " ++ show mn ++ " is misleading as it has no exported data constructors"+    goSimple (ImportHidingModule name) =+      line $ "Attempted to hide module " ++ show name ++ " in import expression, this is not permitted"     goSimple (WildcardInferredType ty) =       line $ "The wildcard type definition has the inferred type " ++ prettyPrintType ty     goSimple (NotExhaustivePattern bs b) =@@ -676,12 +734,14 @@             ]     go (SimpleErrorWrapper sem) = goSimple sem -  line :: String -> Box.Box-  line = Box.text-   lineWithLevel :: String -> Box.Box   lineWithLevel text = line $ show level ++ " " ++ text +  levelText :: String+  levelText = case level of+    Error -> "error"+    Warning -> "warning"+   suggestions :: ErrorMessage -> [Box.Box]   suggestions = suggestions' . unwrapErrorMessage     where@@ -696,23 +756,7 @@   paras :: [Box.Box] -> Box.Box   paras = Box.vcat Box.left -  indent :: Box.Box -> Box.Box-  indent = Box.moveRight 2-   -- |-  -- Render a DictionaryValue fit for human consumption in error messages-  ---  prettyPrintDictionaryValue :: DictionaryValue -> Box.Box-  prettyPrintDictionaryValue (LocalDictionaryValue _)           = line "Dictionary in scope"-  prettyPrintDictionaryValue (GlobalDictionaryValue nm)         = line (show nm)-  prettyPrintDictionaryValue (DependentDictionaryValue nm args) = paras [ line $ (show nm) ++ " via"-                                                                        , indent $ paras $ map prettyPrintDictionaryValue args-                                                                        ]-  prettyPrintDictionaryValue (SubclassDictionaryValue sup nm _) = paras [ line $ (show nm) ++ " via superclass"-                                                                        , indent $ prettyPrintDictionaryValue sup-                                                                        ]--  -- |   -- Pretty print and export declaration   --   prettyPrintExport :: DeclarationRef -> String@@ -789,6 +833,60 @@                       , Box.vsep 1 Box.left result                       ] +-- | Pretty print a Parsec ParseError as a Box+prettyPrintParseError :: P.ParseError -> Box.Box+prettyPrintParseError = (prettyPrintParseErrorMessages "or" "unknown parse error" "expecting" "unexpected" "end of input") . PE.errorMessages++-- |+-- Pretty print ParseError detail messages.+--+-- Adapted from 'Text.Parsec.Error.showErrorMessages', see <https://github.com/aslatter/parsec/blob/v3.1.9/Text/Parsec/Error.hs#L173>.+--+prettyPrintParseErrorMessages :: String -> String -> String -> String -> String -> [Message] -> Box.Box+prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEndOfInput msgs+  | null msgs = Box.text msgUnknown+  | otherwise = Box.vcat Box.left $ map Box.text $ clean [showSysUnExpect,showUnExpect,showExpect,showMessages]++  where+  (sysUnExpect,msgs1) = span ((SysUnExpect "") ==) msgs+  (unExpect,msgs2)    = span ((UnExpect    "") ==) msgs1+  (expect,messages)   = span ((Expect      "") ==) msgs2++  showExpect      = showMany msgExpecting expect+  showUnExpect    = showMany msgUnExpected unExpect+  showSysUnExpect | not (null unExpect) ||+                    null sysUnExpect = ""+                  | null firstMsg    = msgUnExpected ++ " " ++ msgEndOfInput+                  | otherwise        = msgUnExpected ++ " " ++ firstMsg+    where+    firstMsg  = PE.messageString (head sysUnExpect)++  showMessages      = showMany "" messages++  -- helpers+  showMany pre msgs' = case clean (map PE.messageString msgs') of+                         [] -> ""+                         ms | null pre  -> commasOr ms+                            | otherwise -> pre ++ " " ++ commasOr ms++  commasOr []       = ""+  commasOr [m]      = m+  commasOr ms       = commaSep (init ms) ++ " " ++ msgOr ++ " " ++ last ms++  commaSep          = separate ", " . clean++  separate   _ []     = ""+  separate   _ [m]    = m+  separate sep (m:ms) = m ++ sep ++ separate sep ms++  clean             = nub . filter (not . null)++indent :: Box.Box -> Box.Box+indent = Box.moveRight 2++line :: String -> Box.Box+line = Box.text+ renderBox :: Box.Box -> String renderBox = unlines . map trimEnd . lines . Box.render   where@@ -808,15 +906,24 @@ rethrow :: (MonadError e m) => (e -> e) -> m a -> m a rethrow f = flip catchError $ \e -> throwError (f e) +warnAndRethrow :: (MonadError e m, MonadWriter e m) => (e -> e) -> m a -> m a+warnAndRethrow f = rethrow f . censor f+ -- | -- Rethrow an error with source position information -- rethrowWithPosition :: (MonadError MultipleErrors m) => SourceSpan -> m a -> m a-rethrowWithPosition pos = rethrow (onErrorMessages withPosition)-  where-  withPosition :: ErrorMessage -> ErrorMessage-  withPosition (PositionedError _ err) = withPosition err-  withPosition err = PositionedError pos err+rethrowWithPosition pos = rethrow (onErrorMessages (withPosition pos))++warnWithPosition :: (MonadWriter MultipleErrors m) => SourceSpan -> m a -> m a+warnWithPosition pos = censor (onErrorMessages (withPosition pos))++warnAndRethrowWithPosition :: (MonadError MultipleErrors m, MonadWriter MultipleErrors m) => SourceSpan -> m a -> m a+warnAndRethrowWithPosition pos = rethrowWithPosition pos . warnWithPosition pos++withPosition :: SourceSpan -> ErrorMessage -> ErrorMessage+withPosition _ (PositionedError pos err) = withPosition pos err+withPosition pos err = PositionedError pos err  -- | -- Collect errors in in parallel
src/Language/PureScript/Kinds.hs view
@@ -14,13 +14,16 @@  {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Kinds where  import Data.Data import qualified Data.Aeson.TH as A +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.Unify (Unknown)  -- |
src/Language/PureScript/Linter.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Linter--- Copyright   :  (c) Copyright 2015 PureScript--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -15,6 +15,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Linter (lint, module L) where @@ -24,7 +25,9 @@  import qualified Data.Set as S +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.Writer.Class  import Language.PureScript.AST@@ -36,7 +39,7 @@ -- | -- | Right now, this pass only performs a shadowing check. lint :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Module -> m ()-lint (Module _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_ lintDeclaration ds+lint (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ mapM_ lintDeclaration ds   where   moduleNames :: S.Set Ident   moduleNames = S.fromList (nub (mapMaybe getDeclIdent ds))
src/Language/PureScript/Linter/Exhaustive.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Exhaustive--- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -13,13 +13,14 @@ -- | The algorithm analyses the clauses of a definition one by one from top -- | to bottom, where in each step it has the cases already missing (uncovered), -- | and it generates the new set of missing cases.--- +-- -----------------------------------------------------------------------------  {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-} -module Language.PureScript.Linter.Exhaustive +module Language.PureScript.Linter.Exhaustive   ( checkExhaustive   , checkExhaustiveModule   ) where@@ -207,7 +208,7 @@   isOtherwise (TypedValue _ (BooleanLiteral True) _) = True   isOtherwise (TypedValue _ (Var (Qualified (Just (ModuleName [ProperName "Prelude"])) (Ident "otherwise"))) _) = True   isOtherwise _ = False-isExhaustiveGuard (Right _) = True +isExhaustiveGuard (Right _) = True  -- | -- Returns the uncovered set of case alternatives@@ -217,7 +218,7 @@  missingAlternative :: Environment -> ModuleName -> CaseAlternative -> [Binder] -> ([[Binder]], Maybe Bool) missingAlternative env mn ca uncovered-  | isExhaustiveGuard (caseAlternativeResult ca) = mcases +  | isExhaustiveGuard (caseAlternativeResult ca) = mcases   | otherwise = ([uncovered], snd mcases)   where   mcases = missingCases env mn uncovered ca@@ -227,9 +228,9 @@ -- Starting with the set `uncovered = { _ }` (nothing covered, one `_` for each function argument), -- it partitions that set with the new uncovered cases, until it consumes the whole set of clauses. -- Then, returns the uncovered set of case alternatives.--- -checkExhaustive :: forall m. (MonadWriter MultipleErrors m) => Environment -> ModuleName -> [CaseAlternative] -> m ()-checkExhaustive env mn cas = makeResult . first nub $ foldl' step ([initial], (pure True, [])) cas+--+checkExhaustive :: forall m. (MonadWriter MultipleErrors m) => Environment -> ModuleName -> Int -> [CaseAlternative] -> m ()+checkExhaustive env mn numArgs cas = makeResult . first nub $ foldl' step ([initialize numArgs], (pure True, [])) cas   where   step :: ([[Binder]], (Maybe Bool, [[Binder]])) -> CaseAlternative -> ([[Binder]], (Maybe Bool, [[Binder]]))   step (uncovered, (nec, redundant)) ca =@@ -237,13 +238,10 @@         cond = or <$> sequenceA pr     in (concat missed, (liftA2 (&&) cond nec,                          if fromMaybe True cond then redundant else caseAlternativeBinders ca : redundant))+#if __GLASGOW_HASKELL__ < 710     where     sequenceA = foldr (liftA2 (:)) (pure [])--  initial :: [Binder]-  initial = initialize numArgs-    where-    numArgs = length . caseAlternativeBinders . head $ cas +#endif    makeResult :: ([[Binder]], (Maybe Bool, [[Binder]])) -> m ()   makeResult (bss, (_, bss')) =@@ -255,7 +253,7 @@  -- | -- Exhaustivity checking over a list of declarations--- +-- checkExhaustiveDecls :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> ModuleName -> [Declaration] -> m () checkExhaustiveDecls env mn ds =   let (f, _, _) = everywhereOnValuesTopDownM return checkExpr return@@ -274,12 +272,12 @@   in mapM_ f' ds   where   checkExpr :: Expr -> m Expr-  checkExpr c@(Case _ cas)  = checkExhaustive env mn cas >> return c+  checkExpr c@(Case expr cas)  = checkExhaustive env mn (length expr) cas >> return c   checkExpr other = return other  -- | -- Exhaustivity checking over a single module--- +-- checkExhaustiveModule :: forall m. (Applicative m, MonadWriter MultipleErrors m) => Environment -> Module -> m ()-checkExhaustiveModule env (Module _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds+checkExhaustiveModule env (Module _ _ mn ds _) = censor (onErrorMessages (ErrorInModule mn)) $ checkExhaustiveDecls env mn ds 
src/Language/PureScript/Make.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Make--- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -19,6 +19,7 @@ {-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Make   (@@ -28,20 +29,22 @@   , MakeActions(..)   , Externs()   , make-  +   -- * Implementation of Make API using files on disk   , Make(..)   , runMake   , buildMakeActions   ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Arrow ((&&&)) import Control.Monad import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Trans.Except import Control.Monad.Reader-import Control.Monad.Writer+import Control.Monad.Writer.Strict import Control.Monad.Supply  import Data.Function (on)@@ -49,7 +52,9 @@ import Data.Maybe (fromMaybe) import Data.Time.Clock import Data.Foldable (for_)+#if __GLASGOW_HASKELL__ < 710 import Data.Traversable (traverse)+#endif import Data.Version (showVersion) import qualified Data.Map as M import qualified Data.Set as S@@ -92,7 +97,7 @@ -- This type exists to make two things abstract: -- -- * The particular backend being used (Javascript, C++11, etc.)--- +-- -- * The details of how files are read/written etc. -- data MakeActions m = MakeActions {@@ -148,7 +153,7 @@      -> m Environment make MakeActions{..} ms = do   (sorted, graph) <- sortModules $ map importPrim ms-  toRebuild <- foldM (\s (Module _ moduleName' _ _) -> do+  toRebuild <- foldM (\s (Module _ _ moduleName' _ _) -> do     inputTimestamp <- getInputTimestamp moduleName'     outputTimestamp <- getOutputTimestamp moduleName'     return $ case (inputTimestamp, outputTimestamp) of@@ -167,12 +172,12 @@   go env ((False, m) : ms') = do     (_, env') <- lift . runCheck' env $ typeCheckModule Nothing m     go env' ms'-  go env ((True, m@(Module coms moduleName' _ exps)) : ms') = do-    lift . progress $ CompilingModule moduleName' -    (checked@(Module _ _ elaborated _), env') <- lift . runCheck' env $ typeCheckModule Nothing m+  go env ((True, m@(Module ss coms moduleName' _ exps)) : ms') = do+    lift . progress $ CompilingModule moduleName'+    (checked@(Module _ _ _ elaborated _), env') <- lift . runCheck' env $ typeCheckModule Nothing m     checkExhaustiveModule env' checked     regrouped <- createBindingGroups moduleName' . collapseBindingGroups $ elaborated-    let mod' = Module coms moduleName' regrouped exps+    let mod' = Module ss coms moduleName' regrouped exps         corefn = CF.moduleToCoreFn env' mod'         [renamed] = renameInModules [corefn]         exts = moduleToPs mod' env'@@ -181,15 +186,15 @@    rebuildIfNecessary :: M.Map ModuleName [ModuleName] -> S.Set ModuleName -> [Module] -> m [(Bool, Module)]   rebuildIfNecessary _ _ [] = return []-  rebuildIfNecessary graph toRebuild (m@(Module _ moduleName' _ _) : ms') | moduleName' `S.member` toRebuild = do+  rebuildIfNecessary graph toRebuild (m@(Module _ _ moduleName' _ _) : ms') | moduleName' `S.member` toRebuild = do     let deps = fromMaybe [] $ moduleName' `M.lookup` graph         toRebuild' = toRebuild `S.union` S.fromList deps     (:) (True, m) <$> rebuildIfNecessary graph toRebuild' ms'-  rebuildIfNecessary graph toRebuild (Module _ moduleName' _ _ : ms') = do+  rebuildIfNecessary graph toRebuild (Module _ _ moduleName' _ _ : ms') = do     (path, externs) <- readExterns moduleName'     externsModules <- fmap (map snd) . alterErrors $ parseModulesFromFiles id [(path, externs)]     case externsModules of-      [m'@(Module _ moduleName'' _ _)] | moduleName'' == moduleName' -> (:) (False, m') <$> rebuildIfNecessary graph toRebuild ms'+      [m'@(Module _ _ moduleName'' _ _)] | moduleName'' == moduleName' -> (:) (False, m') <$> rebuildIfNecessary graph toRebuild ms'       _ -> throwError . errorMessage . InvalidExternsFile $ path     where     alterErrors = flip catchError $ \(MultipleErrors errs) ->@@ -207,9 +212,9 @@ -- Add an import declaration for a module if it does not already explicitly import it. -- addDefaultImport :: ModuleName -> Module -> Module-addDefaultImport toImport m@(Module coms mn decls exps)  =+addDefaultImport toImport m@(Module ss coms mn decls exps)  =   if isExistingImport `any` decls || mn == toImport then m-  else Module coms mn (ImportDeclaration toImport Implicit Nothing : decls) exps+  else Module ss coms mn (ImportDeclaration toImport Implicit Nothing : decls) exps   where   isExistingImport (ImportDeclaration mn' _ _) | mn' == toImport = True   isExistingImport (PositionedDeclaration _ _ d) = isExistingImport d
src/Language/PureScript/ModuleDependencies.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.ModuleDependencies--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -42,7 +42,7 @@ -- sortModules :: (MonadError MultipleErrors m) => [Module] -> m ([Module], ModuleGraph) sortModules ms = do-  let verts = map (\m@(Module _ _ ds _) -> (m, getModuleName m, nub (concatMap usedModules ds))) ms+  let verts = map (\m@(Module _ _ _ ds _) -> (m, getModuleName m, nub (concatMap usedModules ds))) ms   ms' <- mapM toModule $ stronglyConnComp verts   let moduleGraph = map (\(_, mn, deps) -> (mn, deps)) verts   return (ms', moduleGraph)
src/Language/PureScript/Names.hs view
@@ -13,7 +13,9 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE DeriveDataTypeable, DeriveFunctor, GADTs #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveFunctor #-}+{-# LANGUAGE GADTs #-}  module Language.PureScript.Names where @@ -100,3 +102,16 @@ qualify :: ModuleName -> Qualified a -> (ModuleName, a) qualify m (Qualified Nothing a) = (m, a) qualify _ (Qualified (Just m) a) = (m, a)++-- |+-- Makes a qualified value from a name and module name.+--+mkQualified :: a -> ModuleName -> Qualified a+mkQualified name mn = Qualified (Just mn) name++-- |+-- Checks whether a qualified value is actually qualified with a module reference+--+isUnqualified :: Qualified a -> Bool+isUnqualified (Qualified Nothing _) = True+isUnqualified _ = False
src/Language/PureScript/Parser/Declarations.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Parser.Declarations--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -64,8 +64,6 @@   end <- P.getPosition   let sp = SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end)   return $ f sp comments x-  where-  toSourcePos pos = SourcePos (P.sourceLine pos) (P.sourceColumn pos)  kindedIdent :: TokenParser (String, Maybe Kind) kindedIdent = (, Nothing) <$> identifier@@ -230,7 +228,7 @@     indented *> reserved "where"     mark (P.many (same *> positioned parseValueDeclaration))   return $ TypeInstanceDeclaration name (fromMaybe [] deps) className ty (ExplicitInstance members)-  + parseDerivingInstanceDeclaration :: TokenParser Declaration parseDerivingInstanceDeclaration = do   reserved "derive"@@ -277,19 +275,22 @@ parseModule :: TokenParser Module parseModule = do   comments <- C.readComments+  start <- P.getPosition   reserved "module"   indented   name <- moduleName   exports <- P.optionMaybe $ parens $ commaSep1 parseDeclarationRef   reserved "where"   decls <- mark (P.many (same *> parseDeclaration))-  return $ Module comments name decls exports+  end <- P.getPosition+  let ss = SourceSpan (P.sourceName start) (toSourcePos start) (toSourcePos end)+  return $ Module ss comments name decls exports  -- | -- Parse a collection of modules -- parseModulesFromFiles :: forall m k. (MonadError MultipleErrors m, Functor m) =>-                                     (k -> String) -> [(k, String)] -> m [(k, Module)]+                                     (k -> FilePath) -> [(k, String)] -> m [(k, Module)] parseModulesFromFiles toFilePath input = do   modules <- parU input $ \(k, content) -> do     let filename = toFilePath k@@ -299,10 +300,20 @@   return $ collect modules   where   wrapError :: Either P.ParseError a -> m a-  wrapError = either (throwError . errorMessage . ErrorParsingModule) return+  wrapError = either (throwError . MultipleErrors . pure . toPositionedError) return   collect :: [(k, [v])] -> [(k, v)]   collect vss = [ (k, v) | (k, vs) <- vss, v <- vs ] +toPositionedError :: P.ParseError -> ErrorMessage+toPositionedError perr = PositionedError (SourceSpan name start end) (SimpleErrorWrapper (ErrorParsingModule perr))+  where+  name   = (P.sourceName . P.errorPos) perr+  start  = (toSourcePos  . P.errorPos) perr+  end    = start++toSourcePos :: P.SourcePos -> SourcePos+toSourcePos pos = SourcePos (P.sourceLine pos) (P.sourceColumn pos)+ -- | -- Parse a collection of modules --@@ -429,7 +440,7 @@ parseDo = do   reserved "do"   C.indented-  Do <$> C.mark (P.many (C.same *> C.mark parseDoNotationElement))+  Do <$> C.mark (P.many1 (C.same *> C.mark parseDoNotationElement))  parseDoNotationLet :: TokenParser DoNotationElement parseDoNotationLet = DoNotationLet <$> (reserved "let" *> C.indented *> C.mark (P.many1 (C.same *> parseLocalDeclaration)))
src/Language/PureScript/Parser/JS.hs view
@@ -13,13 +13,16 @@ -----------------------------------------------------------------------------  {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Parser.JS   ( ForeignJS()   , parseForeignModulesFromFiles   ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((*>), (<*))+#endif import Control.Monad (forM_, when, msum) import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Writer.Class (MonadWriter(..))
src/Language/PureScript/Parser/Kinds.hs view
@@ -13,6 +13,8 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-}+ module Language.PureScript.Parser.Kinds (     parseKind ) where@@ -20,7 +22,9 @@ import Language.PureScript.Kinds import Language.PureScript.Parser.Common import Language.PureScript.Parser.Lexer+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import qualified Text.Parsec as P import qualified Text.Parsec.Expr as P 
src/Language/PureScript/Pretty/JS.hs view
@@ -13,6 +13,8 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-}+ module Language.PureScript.Pretty.JS (     prettyPrintJS ) where@@ -20,7 +22,9 @@ import Data.List import Data.Maybe (fromMaybe) +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Arrow ((<+>)) import Control.Monad.State import Control.PatternArrows
src/Language/PureScript/Pretty/Values.hs view
@@ -13,6 +13,8 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-}+ module Language.PureScript.Pretty.Values (     prettyPrintValue,     prettyPrintBinder,@@ -25,7 +27,9 @@ import Control.Arrow ((<+>), runKleisli, second) import Control.PatternArrows import Control.Monad.State+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif  import Language.PureScript.AST import Language.PureScript.Names@@ -74,7 +78,7 @@     ]   match (OperatorSection op (Right val)) = return $ "(" ++ prettyPrintValue op ++ " " ++ prettyPrintValue val ++ ")"   match (OperatorSection op (Left val)) = return $ "(" ++ prettyPrintValue val ++ " " ++ prettyPrintValue op ++ ")"-  match (TypeClassDictionary _ (name, tys) _) = return $ "<<dict " ++ show name ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ">>"+  match (TypeClassDictionary (name, tys) _) = return $ "<<dict " ++ show name ++ " " ++ unwords (map prettyPrintTypeAtom tys) ++ ">>"   match (SuperClassDictionary name _) = return $ "<<superclass dict " ++ show name ++ ">>"   match (TypedValue _ val _) = prettyPrintValue' val   match (PositionedValue _ _ val) = prettyPrintValue' val
src/Language/PureScript/Publish.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Publish   ( preparePackage@@ -32,14 +33,16 @@ import Data.Aeson.BetterErrors import qualified Data.Text as T +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Category ((>>>)) import Control.Arrow ((***)) import Control.Exception (catch, try) import Control.Monad.Trans.Maybe (MaybeT(..), runMaybeT) import Control.Monad.Trans.Except import Control.Monad.Error.Class (MonadError(..))-import Control.Monad.Writer+import Control.Monad.Writer.Strict  import System.Directory (doesFileExist, findExecutable) import System.Process (readProcess)
src/Language/PureScript/Publish/ErrorsWarnings.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Publish.ErrorsWarnings   ( PackageError(..)@@ -15,12 +16,16 @@   , renderWarnings   ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>))+#endif import Data.Aeson.BetterErrors import Data.Version import Data.Maybe import Data.Monoid+#if __GLASGOW_HASKELL__ < 710 import Data.Foldable (foldMap)+#endif import Data.List (intersperse, intercalate) import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.List.NonEmpty as NonEmpty
src/Language/PureScript/Renamer.hs view
@@ -14,11 +14,15 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Renamer (renameInModules) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.State  import Data.List (find)
src/Language/PureScript/Sugar.hs view
@@ -14,13 +14,17 @@ -----------------------------------------------------------------------------  {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Sugar (desugar, module S) where  import Control.Monad import Control.Category ((>>>))+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative-import Control.Monad.Error.Class (MonadError(..))+#endif+import Control.Monad.Error.Class (MonadError())+import Control.Monad.Writer.Class (MonadWriter()) import Control.Monad.Supply.Class  import Language.PureScript.AST@@ -59,7 +63,7 @@ -- --  * Group mutually recursive value and data declarations into binding groups. ---desugar :: (Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Module] -> m [Module]+desugar :: (Applicative m, MonadSupply m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => [Module] -> m [Module] desugar = map removeSignedLiterals           >>> mapM desugarObjectConstructors           >=> mapM desugarOperatorSections
src/Language/PureScript/Sugar/BindingGroups.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.BindingGroups--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -15,6 +15,7 @@ -----------------------------------------------------------------------------  {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Sugar.BindingGroups (     createBindingGroups,@@ -26,7 +27,9 @@ import Data.Graph import Data.List (nub, intersect) import Data.Maybe (isJust, mapMaybe)+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad ((<=<)) import Control.Monad.Error.Class (MonadError(..)) @@ -42,13 +45,13 @@ -- Replace all sets of mutually-recursive declarations in a module with binding groups -- createBindingGroupsModule :: (Functor m, Applicative m, MonadError MultipleErrors m) => [Module] -> m [Module]-createBindingGroupsModule = mapM $ \(Module coms name ds exps) -> Module coms name <$> createBindingGroups name ds <*> pure exps+createBindingGroupsModule = mapM $ \(Module ss coms name ds exps) -> Module ss coms name <$> createBindingGroups name ds <*> pure exps  -- | -- Collapse all binding groups in a module to individual declarations -- collapseBindingGroupsModule :: [Module] -> [Module]-collapseBindingGroupsModule = map $ \(Module coms name ds exps) -> Module coms name (collapseBindingGroups ds) exps+collapseBindingGroupsModule = map $ \(Module ss coms name ds exps) -> Module ss coms name (collapseBindingGroups ds) exps  createBindingGroups :: (Functor m, Applicative m, MonadError MultipleErrors m) => ModuleName -> [Declaration] -> m [Declaration] createBindingGroups moduleName = mapM f <=< handleDecls
src/Language/PureScript/Sugar/CaseDeclarations.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.CaseDeclarations--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -14,7 +14,9 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE FlexibleContexts, ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Sugar.CaseDeclarations (     desugarCases,@@ -24,7 +26,9 @@ import Data.Maybe (catMaybes) import Data.List (nub, groupBy) +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad ((<=<), forM, replicateM, join, unless) import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Supply.Class@@ -45,9 +49,9 @@ -- Replace all top-level binders in a module with case expressions. -- desugarCasesModule :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Module] -> m [Module]-desugarCasesModule ms = forM ms $ \(Module coms name ds exps) ->+desugarCasesModule ms = forM ms $ \(Module ss coms name ds exps) ->   rethrow (onErrorMessages (ErrorInModule name)) $-    Module coms name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps+    Module ss coms name <$> (desugarCases <=< desugarAbs $ ds) <*> pure exps  desugarAbs :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => [Declaration] -> m [Declaration] desugarAbs = flip parU f
src/Language/PureScript/Sugar/DoNotation.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Sugar.DoNotation--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -16,6 +16,7 @@  {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Sugar.DoNotation (     desugarDoModule@@ -27,7 +28,9 @@  import qualified Language.PureScript.Constants as C +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Supply.Class @@ -36,7 +39,7 @@ -- and all @DoNotationLet@ constructors with let expressions. -- desugarDoModule :: forall m. (Applicative m, MonadSupply m, MonadError MultipleErrors m) => Module -> m Module-desugarDoModule (Module coms mn ds exts) = Module coms mn <$> parU ds desugarDo <*> pure exts+desugarDoModule (Module ss coms mn ds exts) = Module ss coms mn <$> parU ds desugarDo <*> pure exts  desugarDo :: forall m. (Applicative m, MonadSupply m, MonadError MultipleErrors m) => Declaration -> m Declaration desugarDo (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> (rethrowWithPosition pos $ desugarDo d)
src/Language/PureScript/Sugar/Names.hs view
@@ -1,8 +1,7 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Sugar.Names--- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors--- License     :  MIT+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com> -- Stability   :  experimental@@ -12,250 +11,90 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE PatternGuards #-} -module Language.PureScript.Sugar.Names (-  desugarImports-) where+module Language.PureScript.Sugar.Names (desugarImports) where -import Data.List (find, nub, (\\))-import Data.Maybe (catMaybes, fromMaybe, isJust, mapMaybe)+import Data.List (find, nub)+import Data.Maybe (fromMaybe, mapMaybe) +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative (Applicative(..), (<$>), (<*>))+#endif import Control.Monad import Control.Monad.Error.Class (MonadError(..))+import Control.Monad.Writer (MonadWriter(..))  import qualified Data.Map as M  import Language.PureScript.AST import Language.PureScript.Names import Language.PureScript.Types-import Language.PureScript.Environment import Language.PureScript.Errors import Language.PureScript.Traversals--import qualified Language.PureScript.Constants as C---- |--- The global export environment - every declaration exported from every module.----type ExportEnvironment = M.Map ModuleName Exports---- |--- The exported declarations from a module.----data Exports = Exports-  {-  -- |-  -- The types exported from each module-  ---    exportedTypes :: [(ProperName, [ProperName])]-  -- |-  -- The classes exported from each module-  ---  , exportedTypeClasses :: [ProperName]-  -- |-  -- The values exported from each module-  ---  , exportedValues :: [Ident]-  -- |-  -- The modules exported from each module-  ---  , exportedModules :: [ModuleName]-  } deriving (Show)---- |--- An imported environment for a particular module. This also contains the module's own members.----data ImportEnvironment = ImportEnvironment-  {-  -- |-  -- Local names for types within a module mapped to to their qualified names-  ---    importedTypes :: M.Map (Qualified ProperName) (Qualified ProperName)-  -- |-  -- Local names for data constructors within a module mapped to to their qualified names-  ---  , importedDataConstructors :: M.Map (Qualified ProperName) (Qualified ProperName)-  -- |-  -- Local names for classes within a module mapped to to their qualified names-  ---  , importedTypeClasses :: M.Map (Qualified ProperName) (Qualified ProperName)-  -- |-  -- Local names for values within a module mapped to to their qualified names-  ---  , importedValues :: M.Map (Qualified Ident) (Qualified Ident)-  } deriving (Show)---- |--- Updates the exports for a module from the global environment. If the module was not previously--- present in the global environment, it is created.----updateExportedModule :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> (Exports -> m Exports) -> m ExportEnvironment-updateExportedModule env mn update = do-  let exports = fromMaybe (error "Module was undefined in updateExportedModule") $ mn `M.lookup` env-  exports' <- update exports-  return $ M.insert mn exports' env---- |--- Adds an empty module to an ExportEnvironment.----addEmptyModule :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> m ExportEnvironment-addEmptyModule env name =-  if name `M.member` env-    then throwError . errorMessage $ RedefinedModule name-    else return $ M.insert name (Exports [] [] [] []) env---- |--- Adds a type belonging to a module to the export environment.----addType :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> ProperName -> [ProperName] -> m ExportEnvironment-addType env mn name dctors = updateExportedModule env mn $ \m -> do-  let exTypes = exportedTypes m-  let exDctors = snd `concatMap` exTypes-  let exClasses = exportedTypeClasses m-  when (any ((== name) . fst) exTypes) $ throwConflictError ConflictingTypeDecls name-  when (name `elem` exClasses) $ throwConflictError TypeConflictsWithClass name-  forM_ dctors $ \dctor -> do-    when (dctor `elem` exDctors) $ throwConflictError ConflictingCtorDecls dctor-    when (dctor `elem` exClasses) $ throwConflictError CtorConflictsWithClass dctor-  return $ m { exportedTypes = (name, dctors) : exTypes }---- |--- Adds a class to the export environment.----addTypeClass :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> ProperName -> m ExportEnvironment-addTypeClass env mn name = updateExportedModule env mn $ \m -> do-  let exTypes = exportedTypes m-  let exDctors = snd `concatMap` exTypes-  when (any ((== name) . fst) exTypes) $ throwConflictError ClassConflictsWithType name-  when (name `elem` exDctors) $ throwConflictError ClassConflictsWithCtor name-  classes <- addExport DuplicateClassExport (exportedTypeClasses m) name-  return $ m { exportedTypeClasses = classes }---- |--- Adds a class to the export environment.----addValue :: (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> ModuleName -> Ident -> m ExportEnvironment-addValue env mn name = updateExportedModule env mn $ \m -> do-  values <- addExport DuplicateValueExport (exportedValues m) name-  return $ m { exportedValues = values }---- |--- Adds an entry to a list of exports unless it is already present, in which case an error is--- returned.----addExport :: (Applicative m, MonadError MultipleErrors m, Eq a, Show a) => (a -> SimpleErrorMessage) -> [a] -> a -> m [a]-addExport what exports name =-  if name `elem` exports-  then throwConflictError what name-  else return $ name : exports+import Language.PureScript.Sugar.Names.Env+import Language.PureScript.Sugar.Names.Imports+import Language.PureScript.Sugar.Names.Exports  -- |--- Replaces all local names with qualified names within a set of modules.+-- Replaces all local names with qualified names within a list of modules. The+-- modules should be topologically sorted beforehand. ---desugarImports :: forall m. (Applicative m, MonadError MultipleErrors m) => [Module] -> m [Module]+desugarImports :: forall m. (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => [Module] -> m [Module] desugarImports modules = do-  unfilteredExports <- findExports modules-  exports <- foldM filterModuleExports unfilteredExports modules-  let modules' = moduleReexports <$> modules-  mapM (renameInModule' unfilteredExports exports) modules'+  env <- foldM updateEnv initEnv modules+  mapM (renameInModule' env) modules   where-  moduleReexports :: Module -> Module-  moduleReexports (Module coms mn decls exps) =-    let importedMods = catMaybes findImports'-    in (Module coms mn (decls ++ (concatMap reexports importedMods)) exps)-    where-    imports :: [Declaration]-    imports = filter isImportDecl decls-    findImports' :: [Maybe (Declaration, Module)]-    findImports' = go <$> modules-      where-      go :: Module -> Maybe (Declaration, Module)-      go m@(Module _ mn' _ (Just exps'))-        | any isModExport exps', Just d <- find ((== mn') . importedModName) imports = Just (d, m)-        where-        importedModName :: Declaration -> ModuleName-        importedModName (ImportDeclaration imn _ _) = imn-        importedModName (PositionedDeclaration _ _ d) = importedModName d-        importedModName _ = error "Not an import decl"-      go _ = Nothing-    reexports :: (Declaration, Module) -> [Declaration]-    reexports (ImportDeclaration _ (Hiding refs) _, (Module coms' mn' ds' (Just exps'))) =-      case nonHiddenRefs of-        [] -> []-        _ -> reexports (ImportDeclaration mn' Implicit Nothing, Module coms' mn' ds' (Just nonHiddenRefs))-      where-      nonHiddenRefs :: [DeclarationRef]-      nonHiddenRefs = filter isModExport exps' \\ filter isModExport refs-    reexports (ImportDeclaration _ ty qual, Module _ _ _ (Just exps')) =-      let ty' = case ty of-                  Explicit _ -> Explicit []-                  _ -> ty-      in (\m -> ImportDeclaration m ty' qual) <$> (catMaybes $ go <$> exps')-      where-      go :: DeclarationRef -> Maybe ModuleName-      go (ModuleRef mn') = Just mn'-      go _ = Nothing-    reexports (PositionedDeclaration _ _ d, m@(Module _ _ _ (Just _))) = reexports (d, m)-    reexports _ = []--  isModExport :: DeclarationRef -> Bool-  isModExport (ModuleRef _) = True-  isModExport _ = False--  -- Filters the exports for a module in the global exports environment so that only explicitly-  -- exported members remain. If the module does not explicitly export anything, everything is-  -- exported.-  filterModuleExports :: ExportEnvironment -> Module -> m ExportEnvironment-  filterModuleExports env (Module _ mn _ (Just exps))-    | any isSelfModuleExport exps, Just exps' <- M.lookup mn env =-        let moduleNames = filter (/= mn) $ (\(ModuleRef mn') -> mn') <$> filter isModExport exps-        in return $ M.insert mn (exps' {exportedModules = moduleNames}) env-    where-    isSelfModuleExport :: DeclarationRef -> Bool-    isSelfModuleExport (ModuleRef mn') | mn' == mn = True-    isSelfModuleExport (PositionedDeclarationRef _ _ ref) = isSelfModuleExport ref-    isSelfModuleExport _ = False-  filterModuleExports env (Module _ mn _ (Just exps)) = filterExports mn exps env-  filterModuleExports env _ = return env+  updateEnv :: Env -> Module -> m Env+  updateEnv env m@(Module ss _ mn _ refs) =+    case mn `M.lookup` env of+      Just m' -> throwError . errorMessage $ RedefinedModule mn [envModuleSourceSpan m', ss]+      Nothing -> do+        members <- findExportable m+        let env' = M.insert mn (ss, nullImports, members) env+        imps <- resolveImports env' m+        exps <- maybe (return members) (resolveExports env' mn imps members) refs+        return $ M.insert mn (ss, imps, exps) env -  -- Rename and check all the names within a module. We tweak the global exports environment so-  -- the module has access to an unfiltered list of its own members.-  renameInModule' :: ExportEnvironment -> ExportEnvironment -> Module -> m Module-  renameInModule' unfilteredExports exports m@(Module _ mn _ _) =+  renameInModule' :: Env -> Module -> m Module+  renameInModule' env m@(Module _ _ mn _ _) =     rethrow (onErrorMessages (ErrorInModule mn)) $ do-      let env = M.update (\_ -> M.lookup mn unfilteredExports) mn exports-      let exps = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn exports-      imports <- resolveImports env m-      elaborateImports <$> renameInModule imports env (elaborateExports exps m)+      let (_, imps, exps) = fromMaybe (error "Module is missing in renameInModule'") $ M.lookup mn env+      elaborateImports imps <$> renameInModule env imps (elaborateExports exps m)  -- |--- Make all exports for a module explicit. This may still effect modules that have an exports list,--- as it will also make all data constructor exports explicit.+-- Make all exports for a module explicit. This may still effect modules that+-- have an exports list, as it will also make all data constructor exports+-- explicit. -- elaborateExports :: Exports -> Module -> Module-elaborateExports exps (Module coms mn decls _) = Module coms mn decls (Just $-  map (\(ctor, dctors) -> TypeRef ctor (Just dctors)) (exportedTypes exps) ++-  map TypeClassRef (exportedTypeClasses exps) ++-  map ValueRef (exportedValues exps) ++-  map ModuleRef (exportedModules exps))+elaborateExports exps (Module ss coms mn decls refs) =+  Module ss coms mn decls $+    Just $ map (\(ctor, dctors) -> TypeRef ctor (Just dctors)) (my exportedTypes) +++           map TypeClassRef (my exportedTypeClasses) +++           map ValueRef (my exportedValues) +++           maybe [] (filter isModuleRef) refs+  where+  -- Extracts a list of values from the exports and filters out any values that+  -- are re-exports from other modules.+  my :: (Exports -> [(a, ModuleName)]) -> [a]+  my f = fst `map` filter ((== mn) . snd) (f exps)  -- | -- Add `import X ()` for any modules where there are only fully qualified references to members. -- This ensures transitive instances are included when using a member from a module. ---elaborateImports :: Module -> Module-elaborateImports (Module coms mn decls exps) = Module coms mn decls' exps+elaborateImports :: Imports -> Module -> Module+elaborateImports imps (Module ss coms mn decls exps) = Module ss coms mn decls' exps   where   decls' :: [Declaration]   decls' =     let (f, _, _, _, _) = everythingOnValues (++) (const []) fqValues (const []) (const []) (const [])     in mkImport `map` nub (f `concatMap` decls) ++ decls   fqValues :: Expr -> [ModuleName]-  fqValues (Var (Qualified (Just mn') _)) = [mn']+  fqValues (Var (Qualified (Just mn') _)) | notElem mn' (importedModules imps) = [mn']   fqValues _ = []   mkImport :: ModuleName -> Declaration   mkImport mn' = ImportDeclaration mn' (Explicit []) Nothing@@ -264,14 +103,15 @@ -- Replaces all local names with qualified names within a module and checks that all existing -- qualified names are valid. ---renameInModule :: forall m. (Applicative m, MonadError MultipleErrors m) => ImportEnvironment -> ExportEnvironment -> Module -> m Module-renameInModule imports exports (Module coms mn decls exps) =-  Module coms mn <$> parU decls go <*> pure exps+renameInModule :: forall m. (Applicative m, MonadError MultipleErrors m) => Env -> Imports -> Module -> m Module+renameInModule env imports (Module ss coms mn decls exps) =+  Module ss coms mn <$> parU decls go <*> pure exps   where   (go, _, _, _, _) = everywhereWithContextOnValuesM (Nothing, []) updateDecl updateValue updateBinder updateCase defS    updateDecl :: (Maybe SourceSpan, [Ident]) -> Declaration -> m ((Maybe SourceSpan, [Ident]), Declaration)-  updateDecl (_, bound) d@(PositionedDeclaration pos _ _) = return ((Just pos, bound), d)+  updateDecl (_, bound) d@(PositionedDeclaration pos _ _) =+    return ((Just pos, bound), d)   updateDecl (pos, bound) (DataDeclaration dtype name args dctors) =     (,) (pos, bound) <$> (DataDeclaration dtype name args <$> mapM (sndM (mapM (updateTypesEverywhere pos))) dctors)   updateDecl (pos, bound) (TypeSynonymDeclaration name ps ty) =@@ -289,30 +129,37 @@   updateDecl s d = return (s, d)    updateValue :: (Maybe SourceSpan, [Ident]) -> Expr -> m ((Maybe SourceSpan, [Ident]), Expr)-  updateValue (_, bound) v@(PositionedValue pos' _ _) = return ((Just pos', bound), v)-  updateValue (pos, bound) (Abs (Left arg) val') = return ((pos, arg : bound), Abs (Left arg) val')+  updateValue (_, bound) v@(PositionedValue pos' _ _) =+    return ((Just pos', bound), v)+  updateValue (pos, bound) (Abs (Left arg) val') =+    return ((pos, arg : bound), Abs (Left arg) val')   updateValue (pos, bound) (Let ds val') = do-      let args = mapMaybe letBoundVariable ds-      unless (length (nub args) == length args) $-        maybe id rethrowWithPosition pos $-          throwError . errorMessage $ OverlappingNamesInLet-      return ((pos, args ++ bound), Let ds val')-      where+    let args = mapMaybe letBoundVariable ds+    unless (length (nub args) == length args) $+      maybe id rethrowWithPosition pos $+        throwError . errorMessage $ OverlappingNamesInLet+    return ((pos, args ++ bound), Let ds val')   updateValue (pos, bound) (Var name'@(Qualified Nothing ident)) | ident `notElem` bound =     (,) (pos, bound) <$> (Var <$> updateValueName name' pos)   updateValue (pos, bound) (Var name'@(Qualified (Just _) _)) =     (,) (pos, bound) <$> (Var <$> updateValueName name' pos)-  updateValue s@(pos, _) (Constructor name) = (,) s <$> (Constructor <$> updateDataConstructorName name pos)-  updateValue s@(pos, _) (TypedValue check val ty) = (,) s <$> (TypedValue check val <$> updateTypesEverywhere pos ty)+  updateValue s@(pos, _) (Constructor name) =+    (,) s <$> (Constructor <$> updateDataConstructorName name pos)+  updateValue s@(pos, _) (TypedValue check val ty) =+    (,) s <$> (TypedValue check val <$> updateTypesEverywhere pos ty)   updateValue s v = return (s, v)    updateBinder :: (Maybe SourceSpan, [Ident]) -> Binder -> m ((Maybe SourceSpan, [Ident]), Binder)-  updateBinder (_, bound) v@(PositionedBinder pos _ _) = return ((Just pos, bound), v)-  updateBinder s@(pos, _) (ConstructorBinder name b) = (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)-  updateBinder s v = return (s, v)+  updateBinder (_, bound) v@(PositionedBinder pos _ _) =+    return ((Just pos, bound), v)+  updateBinder s@(pos, _) (ConstructorBinder name b) =+    (,) s <$> (ConstructorBinder <$> updateDataConstructorName name pos <*> pure b)+  updateBinder s v =+    return (s, v)    updateCase :: (Maybe SourceSpan, [Ident]) -> CaseAlternative -> m ((Maybe SourceSpan, [Ident]), CaseAlternative)-  updateCase (pos, bound) c@(CaseAlternative bs _) = return ((pos, concatMap binderNames bs ++ bound), c)+  updateCase (pos, bound) c@(CaseAlternative bs _) =+    return ((pos, concatMap binderNames bs ++ bound), c)    letBoundVariable :: Declaration -> Maybe Ident   letBoundVariable (ValueDeclaration ident _ _ _) = Just ident@@ -320,290 +167,78 @@   letBoundVariable _ = Nothing    updateTypesEverywhere :: Maybe SourceSpan -> Type -> m Type-  updateTypesEverywhere pos0 = everywhereOnTypesM (updateType pos0)+  updateTypesEverywhere pos = everywhereOnTypesM updateType     where-    updateType :: Maybe SourceSpan -> Type -> m Type-    updateType pos (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos-    updateType pos (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym <$> updateTypeName name pos <*> pure tys-    updateType pos (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t-    updateType _ t = return t+    updateType :: Type -> m Type+    updateType (TypeConstructor name) = TypeConstructor <$> updateTypeName name pos+    updateType (SaturatedTypeSynonym name tys) = SaturatedTypeSynonym <$> updateTypeName name pos <*> pure tys+    updateType (ConstrainedType cs t) = ConstrainedType <$> updateConstraints pos cs <*> pure t+    updateType t = return t +  updateConstraints :: Maybe SourceSpan -> [Constraint] -> m [Constraint]   updateConstraints pos = mapM (\(name, ts) -> (,) <$> updateClassName name pos <*> mapM (updateTypesEverywhere pos) ts) -  updateTypeName = update UnknownType importedTypes (\mes -> isJust . (`lookup` exportedTypes mes))-  updateClassName = update UnknownTypeClass importedTypeClasses (flip elem . exportedTypeClasses)-  updateValueName = update UnknownValue importedValues (flip elem . exportedValues)-  updateDataConstructorName = update (flip UnknownDataConstructor Nothing) importedDataConstructors (\mes -> flip elem (join $ snd `map` exportedTypes mes))+  updateTypeName :: Qualified ProperName -> Maybe SourceSpan -> m (Qualified ProperName)+  updateTypeName = update UnknownType (importedTypes imports) (resolveType . exportedTypes) -  -- Update names so unqualified references become qualified, and locally qualified references-  -- are replaced with their canoncial qualified names (e.g. M.Map -> Data.Map.Map)+  updateDataConstructorName :: Qualified ProperName -> Maybe SourceSpan -> m (Qualified ProperName)+  updateDataConstructorName = update (flip UnknownDataConstructor Nothing) (importedDataConstructors imports) (resolveDctor . exportedTypes)++  updateClassName  :: Qualified ProperName -> Maybe SourceSpan -> m (Qualified ProperName)+  updateClassName = update UnknownTypeClass (importedTypeClasses imports) (resolve . exportedTypeClasses)++  updateValueName  :: Qualified Ident -> Maybe SourceSpan -> m (Qualified Ident)+  updateValueName = update UnknownValue (importedValues imports) (resolve . exportedValues)++  -- Used when performing an update to qualify values and classes with their+  -- module of original definition.+  resolve :: (Eq a) => [(a, ModuleName)] -> a -> Maybe (Qualified a)+  resolve as name = mkQualified name <$> name `lookup` as++  -- Used when performing an update to qualify types with their module of+  -- original definition.+  resolveType :: [((ProperName, [ProperName]), ModuleName)] -> ProperName -> Maybe (Qualified ProperName)+  resolveType tys name = mkQualified name . snd <$> find ((== name) . fst . fst) tys++  -- Used when performing an update to qualify data constructors with their+  -- module of original definition.+  resolveDctor :: [((ProperName, [ProperName]), ModuleName)] -> ProperName -> Maybe (Qualified ProperName)+  resolveDctor tys name = mkQualified name . snd <$> find (elem name . snd . fst) tys++  -- Update names so unqualified references become qualified, and locally+  -- qualified references are replaced with their canoncial qualified names+  -- (e.g. M.Map -> Data.Map.Map).   update :: (Ord a, Show a) => (Qualified a -> SimpleErrorMessage)-                            -> (ImportEnvironment -> M.Map (Qualified a) (Qualified a))-                            -> (Exports -> a -> Bool)+                            -> M.Map (Qualified a) (Qualified a, ModuleName)+                            -> (Exports -> a -> Maybe (Qualified a))                             -> Qualified a                             -> Maybe SourceSpan                             -> m (Qualified a)-  update unknown getI checkE qname@(Qualified mn' name) pos = positioned $ case (M.lookup qname imports', mn') of-    (Just qname', _) -> return qname'-    (Nothing, Just mn'') -> do-      when (isExplicitQualModule mn'') . throwError . errorMessage $ unknown qname-      modExports <- getExports mn''-      if checkE modExports name-        then return qname-        else throwError . errorMessage $ unknown qname-    _ -> throwError . errorMessage $ unknown qname+  update unknown imps getE qname@(Qualified mn' name) pos = positioned $+    case (M.lookup qname imps, mn') of+      -- We found the name in our imports, so we return the name for it,+      -- qualifying with the name of the module it was originally defined in+      -- rather than the module we're importing from, to handle the case of+      -- re-exports.+      (Just (_, mnOrig), _) -> return $ Qualified (Just mnOrig) name+      -- If the name wasn't found in our imports but was qualified then we need+      -- to check whether it's a failed import from a "pseudo" module (created+      -- by qualified importing). If that's not the case, then we just need to+      -- check it refers to a symbol in another module.+      (Nothing, Just mn'') -> do+        when (isExplicitQualModule mn'') . throwError . errorMessage $ unknown qname+        modExports <- getExports mn''+        maybe (throwError . errorMessage $ unknown qname) return (getE modExports name)+      -- If neither of the above cases are true then it's an undefined or+      -- unimported symbol.+      _ -> throwError . errorMessage $ unknown qname     where     isExplicitQualModule :: ModuleName -> Bool-    isExplicitQualModule = flip elem $ mapMaybe (\(Qualified q _) -> q) (M.keys imports')-    imports' = getI imports+    isExplicitQualModule = flip elem $ mapMaybe (\(Qualified q _) -> q) (M.keys imps)     positioned err = case pos of       Nothing -> err       Just pos' -> rethrowWithPosition pos' err    -- Gets the exports for a module, or an error message if the module doesn't exist   getExports :: ModuleName -> m Exports-  getExports mn' = maybe (throwError . errorMessage $ UnknownModule mn') return $ M.lookup mn' exports---- |--- Finds all exported declarations in a set of modules.----findExports :: forall m. (Applicative m, MonadError MultipleErrors m) => [Module] -> m ExportEnvironment-findExports = foldM addModule $ M.singleton (ModuleName [ProperName C.prim]) primExports-  where--  -- The exported types from the Prim module-  primExports = Exports (mkTypeEntry `map` M.keys primTypes) [] [] []-    where-    mkTypeEntry (Qualified _ name) = (name, [])--  -- Add all of the exported declarations from a module to the global export environment-  addModule :: ExportEnvironment -> Module -> m ExportEnvironment-  addModule env (Module _ mn ds _) = do-    env' <- addEmptyModule env mn-    rethrow (onErrorMessages (ErrorInModule mn)) $ foldM (addDecl mn) env' ds--  -- Add a declaration from a module to the global export environment-  addDecl :: ModuleName -> ExportEnvironment -> Declaration -> m ExportEnvironment-  addDecl mn env (TypeClassDeclaration tcn _ _ ds) = do-    env' <- addTypeClass env mn tcn-    foldM go env' ds-    where-    go env'' (TypeDeclaration name _) = addValue env'' mn name-    go env'' (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ go env'' d-    go _ _ = error "Invalid declaration in TypeClassDeclaration"-  addDecl mn env (DataDeclaration _ tn _ dcs) = addType env mn tn (map fst dcs)-  addDecl mn env (TypeSynonymDeclaration tn _ _) = addType env mn tn []-  addDecl mn env (ExternDataDeclaration tn _) = addType env mn tn []-  addDecl mn env (ValueDeclaration name _ _ _) = addValue env mn name-  addDecl mn env (ExternDeclaration name _) = addValue env mn name-  addDecl mn env (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ addDecl mn env d-  addDecl _  env _ = return env---- |--- Filters the exports for a module to ensure only explicit exports are kept in the global exports--- environment.----filterExports :: forall m. (Applicative m, MonadError MultipleErrors m) => ModuleName -> [DeclarationRef] -> ExportEnvironment -> m ExportEnvironment-filterExports mn exps env = do-  let moduleExports = fromMaybe (error "Module is missing") (mn `M.lookup` env)-  moduleExports' <- rethrow (onErrorMessages (ErrorInModule mn)) $ filterModule moduleExports-  return $ M.insert mn moduleExports' env-  where--  -- Filter the exports for the specific module-  filterModule :: Exports -> m Exports-  filterModule exported = do-    types' <- foldM (filterTypes $ exportedTypes exported) [] exps-    values <- foldM (filterValues $ exportedValues exported) [] exps-    classes <- foldM (filterClasses $ exportedTypeClasses exported) [] exps-    modules <- foldM (filterModules $ exportedModules exported) [] exps-    return exported { exportedTypes = types', exportedTypeClasses = classes, exportedValues = values, exportedModules = modules }--  -- Ensure the exported types and data constructors exist in the module and add them to the set of-  -- exports-  filterTypes :: [(ProperName, [ProperName])] -> [(ProperName, [ProperName])] -> DeclarationRef -> m [(ProperName, [ProperName])]-  filterTypes expTys result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterTypes expTys result r-  filterTypes expTys result (TypeRef name expDcons) = do-    dcons <- maybe (throwError . errorMessage . UnknownType $ Qualified (Just mn) name) return $ name `lookup` expTys-    dcons' <- maybe (return dcons) (foldM (filterDcons name dcons) []) expDcons-    return $ (name, dcons') : result-  filterTypes _ result _ = return result--  -- Ensure the exported data constructors exists for a type and add them to the list of exports-  filterDcons :: ProperName -> [ProperName] -> [ProperName] -> ProperName -> m [ProperName]-  filterDcons tcon exps' result name =-    if name `elem` exps'-    then return $ name : result-    else throwError . errorMessage $ UnknownDataConstructor (Qualified (Just mn) name) (Just (Qualified (Just mn) tcon))--  -- Ensure the exported classes exist in the module and add them to the set of exports-  filterClasses :: [ProperName] -> [ProperName] -> DeclarationRef -> m [ProperName]-  filterClasses exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterClasses exps' result r-  filterClasses exps' result (TypeClassRef name) =-    if name `elem` exps'-    then return $ name : result-    else throwError . errorMessage . UnknownTypeClass $ Qualified (Just mn) name-  filterClasses _ result _ = return result--  -- Ensure the exported values exist in the module and add them to the set of exports-  filterValues :: [Ident] -> [Ident] -> DeclarationRef -> m [Ident]-  filterValues exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterValues exps' result r-  filterValues exps' result (ValueRef name) =-    if name `elem` exps'-    then return $ name : result-    else throwError . errorMessage . UnknownValue $ Qualified (Just mn) name-  filterValues _ result _ = return result--  -- Add the exported modules to the set of exports-  filterModules :: [ModuleName] -> [ModuleName] -> DeclarationRef -> m [ModuleName]-  filterModules exps' result (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ filterModules exps' result r-  filterModules _ result (ModuleRef name) = return $ name : result-  filterModules _ result _ = return result---- |--- Finds the imports within a module, mapping the imported module name to an optional set of--- explicitly imported declarations.----findImports :: [Declaration] -> M.Map ModuleName (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)-findImports = foldl (findImports' Nothing) M.empty-  where-  findImports' pos result (ImportDeclaration mn typ qual) = M.insert mn (pos, typ, qual) result-  findImports' _ result (PositionedDeclaration pos _ d) = findImports' (Just pos) result d-  findImports' _ result _ = result---- |--- Constructs a local environment for a module.----resolveImports :: forall m. (Applicative m, MonadError MultipleErrors m) => ExportEnvironment -> Module -> m ImportEnvironment-resolveImports env (Module _ currentModule decls _) =-  foldM resolveImport' (ImportEnvironment M.empty M.empty M.empty M.empty) (M.toList scope)-  where--  -- A Map from module name to the source position for the import, the list of imports from that-  -- module (where Nothing indicates everything is to be imported), and optionally a qualified name-  -- for the module-  scope :: M.Map ModuleName (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)-  scope = M.insert currentModule (Nothing, Implicit, Nothing) (findImports decls)--  resolveImport' :: ImportEnvironment -> (ModuleName, (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)) -> m ImportEnvironment-  resolveImport' imp (mn, (pos, typ, impQual)) = do-    modExports <- positioned $ maybe (throwError . errorMessage $ UnknownModule mn) return $ mn `M.lookup` env-    positioned $ resolveImport currentModule mn modExports imp impQual typ-    where-    positioned err = case pos of-      Nothing -> err-      Just pos' -> rethrowWithPosition pos' err---- |--- Extends the local environment for a module by resolving an import of another module.----resolveImport :: forall m. (Applicative m, MonadError MultipleErrors m) => ModuleName -> ModuleName -> Exports -> ImportEnvironment -> Maybe ModuleName -> ImportDeclarationType -> m ImportEnvironment-resolveImport currentModule importModule exps imps impQual =-  resolveByType-  where--  resolveByType :: ImportDeclarationType -> m ImportEnvironment-  resolveByType Implicit = importAll importExplicit-  resolveByType (Explicit explImports) = (checkedRefs >=> foldM importExplicit imps) explImports-  resolveByType (Hiding hiddenImports) = do-    hiddenImports' <- checkedRefs hiddenImports-    importAll (importNonHidden hiddenImports')--  importNonHidden :: [DeclarationRef] -> ImportEnvironment -> DeclarationRef -> m ImportEnvironment-  importNonHidden hidden m ref =-    if isHidden hidden ref-    then return m-    else importExplicit m ref--  isHidden :: [DeclarationRef] -> DeclarationRef -> Bool-  isHidden hidden ref@(TypeRef _ _) =-    let-      checkTypeRef _ True _ = True-      checkTypeRef (TypeRef _ Nothing) acc (TypeRef _ (Just _)) = acc-      checkTypeRef (TypeRef name (Just dctor)) _ (TypeRef name' (Just dctor')) = name == name' && dctor == dctor'-      checkTypeRef (TypeRef name _) _ (TypeRef name' Nothing) = name == name'-      checkTypeRef (PositionedDeclarationRef _ _ r) acc hiddenRef = checkTypeRef r acc hiddenRef-      checkTypeRef _ acc _ = acc-    in foldl (checkTypeRef ref) False hidden-  isHidden hidden ref = ref `elem` hidden--  -- Import all symbols-  importAll :: (ImportEnvironment -> DeclarationRef -> m ImportEnvironment) -> m ImportEnvironment-  importAll importer = do-    imp' <- foldM (\m (name, dctors) -> importer m (TypeRef name (Just dctors))) imps (exportedTypes exps)-    imp'' <- foldM (\m name -> importer m (ValueRef name)) imp' (exportedValues exps)-    foldM (\m name -> importer m (TypeClassRef name)) imp'' (exportedTypeClasses exps)--  -- Import something explicitly-  importExplicit :: ImportEnvironment -> DeclarationRef -> m ImportEnvironment-  importExplicit imp (PositionedDeclarationRef pos _ r) = rethrowWithPosition pos $ importExplicit imp r-  importExplicit imp (ValueRef name) = do-    values' <- updateImports (importedValues imp) name-    return $ imp { importedValues = values' }-  importExplicit imp (TypeRef name dctors) = do-    types' <- updateImports (importedTypes imp) name-    let allDctors = allExportedDataConstructors name-    dctors' <- maybe (return allDctors) (mapM $ checkDctorExists allDctors) dctors-    dctors'' <- foldM updateImports (importedDataConstructors imp) dctors'-    return $ imp { importedTypes = types', importedDataConstructors = dctors'' }-  importExplicit imp (TypeClassRef name) = do-    typeClasses' <- updateImports (importedTypeClasses imp) name-    return $ imp { importedTypeClasses = typeClasses' }-  importExplicit _ _ = error "Invalid argument to importExplicit"--  -- Check if DeclarationRef points to an existent symbol-  checkedRefs :: [DeclarationRef] -> m [DeclarationRef]-  checkedRefs = mapM check-    where-    check (PositionedDeclarationRef pos _ r) =-      rethrowWithPosition pos $ check r-    check ref@(ValueRef name) =-      checkImportExists UnknownValue values name >> return ref-    check ref@(TypeRef name dctors) = do-      _ <- checkImportExists UnknownType availableTypes name-      let allDctors = allExportedDataConstructors name-      _ <- maybe (return allDctors) (mapM $ checkDctorExists allDctors) dctors-      return ref-    check ref@(TypeClassRef name) =-      checkImportExists UnknownTypeClass classes name >> return ref-    check ref@(ModuleRef name) =-      checkImportExists (UnknownModule . (\(Qualified _ m) -> m)) (exportedModules exps) name >> return ref-    check _ = error "Invalid argument to checkRefIsValid"--  -- Find all exported data constructors for a given type-  allExportedDataConstructors :: ProperName -> [ProperName]-  allExportedDataConstructors name = fromMaybe [] $ name `lookup` exportedTypes exps--  -- Add something to the ImportEnvironment if it does not already exist there-  updateImports :: (Ord a, Show a) => M.Map (Qualified a) (Qualified a) -> a -> m (M.Map (Qualified a) (Qualified a))-  updateImports m name = case M.lookup (Qualified impQual name) m of-    Nothing -> return $ M.insert (Qualified impQual name) (Qualified (Just importModule) name) m-    Just (Qualified Nothing _) -> error "Invalid state in updateImports"-    Just (Qualified (Just mn) _) -> throwError . errorMessage $ err-      where-      err = if currentModule `elem` [mn, importModule]-            then ConflictingImport (show name) importModule-            else ConflictingImports (show name) mn importModule--  -- The available values, types, and classes in the module being imported-  values = exportedValues exps-  availableTypes = fst `map` exportedTypes exps-  classes = exportedTypeClasses exps--  -- Ensure that an explicitly imported data constructor exists for the type it is being imported-  -- from-  checkDctorExists :: [ProperName] -> ProperName -> m ProperName-  checkDctorExists = checkImportExists (flip UnknownDataConstructor Nothing)--  -- Check that an explicitly imported item exists in the module it is being imported from-  checkImportExists :: (Eq a, Show a) => (Qualified a -> SimpleErrorMessage) -> [a] -> a -> m a-  checkImportExists unknown exports item =-      if item `elem` exports-      then return item-      else throwError . errorMessage . unknown $ Qualified (Just importModule) item---- |--- Raises an error for when there is more than one definition for something.----throwConflictError :: (Applicative m, MonadError MultipleErrors m, Show a) => (a -> SimpleErrorMessage) -> a -> m b-throwConflictError conflict = throwError . errorMessage . conflict+  getExports mn' = maybe (throwError . errorMessage $ UnknownModule mn') (return . envModuleExports) $ M.lookup mn' env
+ src/Language/PureScript/Sugar/Names/Env.hs view
@@ -0,0 +1,197 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.Sugar.Names.Env+-- License     :  MIT (http://opensource.org/licenses/MIT)+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>+-- Stability   :  experimental+-- Portability :+--+-- |+--+-----------------------------------------------------------------------------++{-# LANGUAGE FlexibleContexts #-}+--{-# LANGUAGE ScopedTypeVariables #-}+--{-# LANGUAGE PatternGuards #-}+--{-# LANGUAGE RankNTypes #-}+--{-# LANGUAGE TupleSections #-}++module Language.PureScript.Sugar.Names.Env+  ( Imports(..)+  , nullImports+  , Exports(..)+  , nullExports+  , Env+  , initEnv+  , envModuleSourceSpan+  , envModuleImports+  , envModuleExports+  , exportType+  , exportTypeClass+  , exportValue+  ) where++import Control.Monad+import Control.Monad.Error.Class (MonadError(..))++import qualified Data.Map as M++import Language.PureScript.AST+import Language.PureScript.Names+import Language.PureScript.Environment+import Language.PureScript.Errors++-- |+-- The imported declarations for a module, including the module's own members.+--+data Imports = Imports+  {+  -- |+  -- Local names for types within a module mapped to to their qualified names+  --+    importedTypes :: M.Map (Qualified ProperName) (Qualified ProperName, ModuleName)+  -- |+  -- Local names for data constructors within a module mapped to to their qualified names+  --+  , importedDataConstructors :: M.Map (Qualified ProperName) (Qualified ProperName, ModuleName)+  -- |+  -- Local names for classes within a module mapped to to their qualified names+  --+  , importedTypeClasses :: M.Map (Qualified ProperName) (Qualified ProperName, ModuleName)+  -- |+  -- Local names for values within a module mapped to to their qualified names+  --+  , importedValues :: M.Map (Qualified Ident) (Qualified Ident, ModuleName)+  -- |+  -- The list of modules that have been imported into the current scope.+  --+  , importedModules :: [ModuleName]+  } deriving (Show)++-- |+-- An empty 'Imports' value.+--+nullImports :: Imports+nullImports = Imports M.empty M.empty M.empty M.empty []++-- |+-- The exported declarations from a module.+--+data Exports = Exports+  {+  -- |+  -- The types exported from each module along with the module they originally+  -- came from.+  --+    exportedTypes :: [((ProperName, [ProperName]), ModuleName)]+  -- |+  -- The classes exported from each module along with the module they originally+  -- came from.+  --+  , exportedTypeClasses :: [(ProperName, ModuleName)]+  -- |+  -- The values exported from each module along with the module they originally+  -- came from.+  --+  , exportedValues :: [(Ident, ModuleName)]+  } deriving (Show)++-- |+-- An empty 'Exports' value.+--+nullExports :: Exports+nullExports = Exports [] [] []++-- |+-- The imports and exports for a collection of modules. The 'SourceSpan' is used+-- to store the source location of the module with a given name, used to provide+-- useful information when there is a duplicate module definition.+--+type Env = M.Map ModuleName (SourceSpan, Imports, Exports)++-- |+-- Extracts the 'SourceSpan' from an 'Env' value.+--+envModuleSourceSpan :: (SourceSpan, a, b) -> SourceSpan+envModuleSourceSpan (ss, _, _) = ss++-- |+-- Extracts the 'Imports' from an 'Env' value.+--+envModuleImports :: (a, Imports, b) -> Imports+envModuleImports (_, imps, _) = imps++-- |+-- Extracts the 'Exports' from an 'Env' value.+--+envModuleExports :: (a, b, Exports) -> Exports+envModuleExports (_, _, exps) = exps++-- |+-- The exported types from the @Prim@ module+--+primExports :: Exports+primExports = Exports (mkTypeEntry `map` M.keys primTypes) [] []+  where+  mkTypeEntry (Qualified _ name) = ((name, []), ModuleName [ProperName "Prim"])++-- |+-- The initial global import/export environment containing the @Prim@ module.+--+initEnv :: Env+initEnv = M.singleton+  (ModuleName [ProperName "Prim"])+  (internalModuleSourceSpan "<Prim>", nullImports, primExports)++-- |+-- Safely adds a type and its data constructors to some exports, returning an+-- error if a conflict occurs.+--+exportType :: (MonadError MultipleErrors m) => Exports -> ProperName -> [ProperName] -> ModuleName -> m Exports+exportType exps name dctors mn = do+  let exTypes = exportedTypes exps+  let exDctors = (snd . fst) `concatMap` exTypes+  let exClasses = exportedTypeClasses exps+  when (any (\((name', _), _) -> name == name') exTypes) $ throwConflictError ConflictingTypeDecls name+  when (any ((== name) . fst) exClasses) $ throwConflictError TypeConflictsWithClass name+  forM_ dctors $ \dctor -> do+    when (dctor `elem` exDctors) $ throwConflictError ConflictingCtorDecls dctor+    when (any ((== dctor) . fst) exClasses) $ throwConflictError CtorConflictsWithClass dctor+  return $ exps { exportedTypes = ((name, dctors), mn) : exTypes }++-- |+-- Safely adds a class to some exports, returning an error if a conflict occurs.+--+exportTypeClass :: (MonadError MultipleErrors m) => Exports -> ProperName -> ModuleName -> m Exports+exportTypeClass exps name mn = do+  let exTypes = exportedTypes exps+  let exDctors = (snd . fst) `concatMap` exTypes+  when (any (\((name', _), _) -> name == name') exTypes) $ throwConflictError ClassConflictsWithType name+  when (name `elem` exDctors) $ throwConflictError ClassConflictsWithCtor name+  classes <- addExport DuplicateClassExport name mn (exportedTypeClasses exps)+  return $ exps { exportedTypeClasses = classes }++-- |+-- Safely adds a value to some exports, returning an error if a conflict occurs.+--+exportValue :: (MonadError MultipleErrors m) => Exports -> Ident -> ModuleName -> m Exports+exportValue exps name mn = do+  values <- addExport DuplicateValueExport name mn (exportedValues exps)+  return $ exps { exportedValues = values }++-- |+-- Adds an entry to a list of exports unless it is already present, in which case an error is+-- returned.+--+addExport :: (MonadError MultipleErrors m, Eq a, Show a) => (a -> SimpleErrorMessage) -> a -> ModuleName -> [(a, ModuleName)] -> m [(a, ModuleName)]+addExport what name mn exports =+  if any ((== name) . fst) exports+  then throwConflictError what name+  else return $ (name, mn) : exports++-- |+-- Raises an error for when there is more than one definition for something.+--+throwConflictError :: (MonadError MultipleErrors m, Show a) => (a -> SimpleErrorMessage) -> a -> m b+throwConflictError conflict = throwError . errorMessage . conflict
+ src/Language/PureScript/Sugar/Names/Exports.hs view
@@ -0,0 +1,236 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.Sugar.Names.Exports+-- License     :  MIT (http://opensource.org/licenses/MIT)+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>+-- Stability   :  experimental+-- Portability :+--+-- |+--+-----------------------------------------------------------------------------++{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections #-}++module Language.PureScript.Sugar.Names.Exports+  ( findExportable+  , resolveExports+  ) where++import Data.List (find, intersect)+import Data.Maybe (fromMaybe, mapMaybe)++#if __GLASGOW_HASKELL__ < 710+import Control.Applicative (Applicative(..), (<$>))+#endif+import Control.Monad+import Control.Monad.Error.Class (MonadError(..))++import qualified Data.Map as M++import Language.PureScript.AST+import Language.PureScript.Names+import Language.PureScript.Errors+import Language.PureScript.Sugar.Names.Env++-- |+-- Finds all exportable members of a module, disregarding any explicit exports.+--+findExportable :: forall m. (Applicative m, MonadError MultipleErrors m) => Module -> m Exports+findExportable (Module _ _ mn ds _) =+  rethrow (onErrorMessages (ErrorInModule mn)) $ foldM updateExports nullExports ds+  where+  updateExports :: Exports -> Declaration -> m Exports+  updateExports exps (TypeClassDeclaration tcn _ _ ds') = do+    exps' <- exportTypeClass exps tcn mn+    foldM go exps' ds'+    where+    go exps'' (TypeDeclaration name _) = exportValue exps'' name mn+    go exps'' (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ go exps'' d+    go _ _ = error "Invalid declaration in TypeClassDeclaration"+  updateExports exps (DataDeclaration _ tn _ dcs) = exportType exps tn (map fst dcs) mn+  updateExports exps (TypeSynonymDeclaration tn _ _) = exportType exps tn [] mn+  updateExports exps (ExternDataDeclaration tn _) = exportType exps tn [] mn+  updateExports exps (ValueDeclaration name _ _ _) = exportValue exps name mn+  updateExports exps (ExternDeclaration name _) = exportValue exps name mn+  updateExports exps (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ updateExports exps d+  updateExports exps _ = return exps++-- |+-- Resolves the exports for a module, filtering out members that have not been+-- exported and elaborating re-exports of other modules.+--+resolveExports :: forall m. (Applicative m, MonadError MultipleErrors m) => Env -> ModuleName -> Imports -> Exports -> [DeclarationRef] -> m Exports+resolveExports env mn imps exps refs =+  rethrow (onErrorMessages (ErrorInModule mn)) $ do+    filtered <- filterModule mn exps refs+    foldM elaborateModuleExports filtered refs++  where++  -- Takes the current module's imports, the accumulated list of exports, and a+  -- `DeclarationRef` for an explicit export. When the ref refers to another+  -- module, export anything from the imports that matches for that module.+  elaborateModuleExports :: Exports -> DeclarationRef -> m Exports+  elaborateModuleExports result (PositionedDeclarationRef pos _ r) =+    rethrowWithPosition pos $ elaborateModuleExports result r+  elaborateModuleExports result (ModuleRef name) | name == mn = do+    let types' = exportedTypes result ++ exportedTypes exps+    let classes' = exportedTypeClasses result ++ exportedTypeClasses exps+    let values' = exportedValues result ++ exportedValues exps+    return result { exportedTypes = types'+                  , exportedTypeClasses = classes'+                  , exportedValues = values' }+  elaborateModuleExports result (ModuleRef name) = do+    let isPseudo = isPseudoModule name+    when (not isPseudo && not (isImportedModule name)) $+      throwError . errorMessage . UnknownExportModule $ name+    let reTypes = extract isPseudo name (importedTypes imps)+    let reDctors = extract isPseudo name (importedDataConstructors imps)+    let reClasses = extract isPseudo name (importedTypeClasses imps)+    let reValues = extract isPseudo name (importedValues imps)+    result' <- foldM (\exps' ((tctor, dctors), mn') -> exportType exps' tctor dctors mn') result (resolveTypeExports reTypes reDctors)+    result'' <- foldM (uncurry . exportTypeClass) result' (map resolveClass reClasses)+    foldM (uncurry . exportValue) result'' (map resolveValue reValues)+  elaborateModuleExports result _ = return result++  -- Extracts a list of values for a module based on a lookup table. If the+  -- boolean is true the values are filtered by the qualification of the+  extract :: Bool -> ModuleName -> M.Map (Qualified a) (Qualified a, ModuleName) -> [Qualified a]+  extract True name = map fst . M.elems . M.filterWithKey (\k _ -> eqQual name k)+  extract False name = map fst . M.elems . M.filter (eqQual name . fst)++  -- Check whether a module name refers to a "pseudo module" that came into+  -- existence in an import scope due to importing one or more modules as+  -- qualified.+  isPseudoModule :: ModuleName -> Bool+  isPseudoModule = testQuals M.keys+    where+    -- Test for the presence of a `ModuleName` in a set of imports, using a+    -- function to either extract the keys or values. We test the keys to see if a+    -- value being re-exported belongs to a qualified module, and we test the+    -- values if that fails to see whether the value has been imported at all.+    testQuals :: (forall a. M.Map (Qualified a) (Qualified a, ModuleName) -> [Qualified a]) -> ModuleName -> Bool+    testQuals f mn' = any (eqQual mn') (f (importedTypes imps))+                   || any (eqQual mn') (f (importedDataConstructors imps))+                   || any (eqQual mn') (f (importedTypeClasses imps))+                   || any (eqQual mn') (f (importedValues imps))++  -- Check whether a module name refers to a module that has been imported+  -- without qualification into an import scope.+  isImportedModule :: ModuleName -> Bool+  isImportedModule = flip elem (importedModules imps)++  -- Check whether a module name matches that of a qualified value.+  eqQual :: ModuleName -> Qualified a -> Bool+  eqQual mn'' (Qualified (Just mn''') _) = mn'' == mn'''+  eqQual _ _ = False++  -- Constructs a list of types with their data constructors and the original+  -- module they were defined in from a list of type and data constructor names.+  resolveTypeExports :: [Qualified ProperName] -> [Qualified ProperName] -> [((ProperName, [ProperName]), ModuleName)]+  resolveTypeExports tctors dctors = map go tctors+    where+    go :: Qualified ProperName -> ((ProperName, [ProperName]), ModuleName)+    go (Qualified (Just mn'') name) = fromMaybe (error "Missing value in resolveTypeExports") $ do+      exps' <- envModuleExports <$> mn'' `M.lookup` env+      ((_, dctors'), mnOrig) <- find (\((name', _), _) -> name == name') (exportedTypes exps')+      let relevantDctors = mapMaybe (\(Qualified mn''' dctor) -> if mn''' == Just mnOrig then Just dctor else Nothing) dctors+      return ((name, intersect relevantDctors dctors'), mnOrig)+    go (Qualified Nothing _) = error "Unqualified value in resolveTypeExports"+++  -- Looks up an imported class and re-qualifies it with the original module it+  -- came from.+  resolveClass :: Qualified ProperName -> (ProperName, ModuleName)+  resolveClass className = splitQual $ fromMaybe (error "Missing value in resolveClass") $+    resolve exportedTypeClasses className++  -- Looks up an imported value and re-qualifies it with the original module it+  -- came from.+  resolveValue :: Qualified Ident -> (Ident, ModuleName)+  resolveValue ident = splitQual $ fromMaybe (error "Missing value in resolveValue") $+    resolve exportedValues ident++  resolve :: (Eq a) => (Exports -> [(a, ModuleName)]) -> Qualified a -> Maybe (Qualified a)+  resolve f (Qualified (Just mn'') a) = do+    exps' <- envModuleExports <$> mn'' `M.lookup` env+    mn''' <- snd <$> find ((== a) . fst) (f exps')+    return $ Qualified (Just mn''') a+  resolve _ _ = error "Unqualified value in resolve"++  -- A partial function that takes a qualified value and extracts the value and+  -- qualified module components.+  splitQual :: Qualified a -> (a, ModuleName)+  splitQual (Qualified (Just mn'') a) = (a, mn'')+  splitQual _ = error "Unqualified value in splitQual"++-- |+-- Filters the full list of exportable values, types, and classes for a module+-- based on a list of export declaration references.+--+filterModule :: forall m. (Applicative m, MonadError MultipleErrors m) => ModuleName -> Exports -> [DeclarationRef] -> m Exports+filterModule mn exps refs = do+  types <- foldM (filterTypes $ exportedTypes exps) [] refs+  values <- foldM (filterValues $ exportedValues exps) [] refs+  classes <- foldM (filterClasses $ exportedTypeClasses exps) [] refs+  return exps { exportedTypes = types , exportedTypeClasses = classes , exportedValues = values }++  where++  -- Takes a list of all the exportable types with their data constructors, the+  -- accumulated list of filtered exports, and a `DeclarationRef` for an+  -- explicit export. When the ref refers to a type in the list of exportable+  -- values, the type and specified data constructors are included in the+  -- result.+  filterTypes :: [((ProperName, [ProperName]), ModuleName)] -> [((ProperName, [ProperName]), ModuleName)] -> DeclarationRef -> m [((ProperName, [ProperName]), ModuleName)]+  filterTypes exps' result (PositionedDeclarationRef pos _ r) =+    rethrowWithPosition pos $ filterTypes exps' result r+  filterTypes exps' result (TypeRef name expDcons) =+    case (\((name', _), mn') -> name == name' && mn == mn') `find` exps' of+      Nothing -> throwError . errorMessage . UnknownExportType $ name+      Just ((_, dcons), _) -> do+        let expDcons' = fromMaybe dcons expDcons+        mapM_ (checkDcon name dcons) expDcons'+        return $ ((name, expDcons'), mn) : result+  filterTypes _ result _ = return result++  -- Ensures a data constructor is exportable for a given type. Takes a type+  -- name, a list of exportable data constructors for the type, and the name of+  -- the data constructor to check.+  checkDcon :: ProperName -> [ProperName] -> ProperName -> m ()+  checkDcon tcon exps' name =+    if name `elem` exps'+    then return ()+    else throwError . errorMessage $ UnknownExportDataConstructor tcon name++  -- Takes a list of all the exportable classes, the accumulated list of+  -- filtered exports, and a `DeclarationRef` for an explicit export. When the+  -- ref refers to a class in the list of exportable classes, the class is+  -- included in the result.+  filterClasses :: [(ProperName, ModuleName)] -> [(ProperName, ModuleName)] -> DeclarationRef -> m [(ProperName, ModuleName)]+  filterClasses exps' result (PositionedDeclarationRef pos _ r) =+    rethrowWithPosition pos $ filterClasses exps' result r+  filterClasses exps' result (TypeClassRef name) =+    if (name, mn) `elem` exps'+    then return $ (name, mn) : result+    else throwError . errorMessage . UnknownExportTypeClass $ name+  filterClasses _ result _ = return result++  -- Takes a list of all the exportable values, the accumulated list of filtered+  -- exports, and a `DeclarationRef` for an explicit export. When the ref refers+  -- to a value in the list of exportable values, the value is included in the+  -- result.+  filterValues :: [(Ident, ModuleName)] -> [(Ident, ModuleName)] -> DeclarationRef -> m [(Ident, ModuleName)]+  filterValues exps' result (PositionedDeclarationRef pos _ r) =+    rethrowWithPosition pos $ filterValues exps' result r+  filterValues exps' result (ValueRef name) =+    if (name, mn) `elem` exps'+    then return $ (name, mn) : result+    else throwError . errorMessage . UnknownExportValue $ name+  filterValues _ result _ = return result
+ src/Language/PureScript/Sugar/Names/Imports.hs view
@@ -0,0 +1,202 @@+-----------------------------------------------------------------------------+--+-- Module      :  Language.PureScript.Sugar.Names.Imports+-- License     :  MIT (http://opensource.org/licenses/MIT)+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>+-- Stability   :  experimental+-- Portability :+--+-- |+--+-----------------------------------------------------------------------------++{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections #-}++module Language.PureScript.Sugar.Names.Imports (resolveImports) where++import Data.List (find)+import Data.Maybe (fromMaybe, isNothing)++import Control.Arrow (first)+#if __GLASGOW_HASKELL__ < 710+import Control.Applicative (Applicative(..), (<$>))+#endif+import Control.Monad+import Control.Monad.Error.Class (MonadError(..))+import Control.Monad.Writer (MonadWriter(..), censor)++import qualified Data.Map as M++import Language.PureScript.AST+import Language.PureScript.Names+import Language.PureScript.Errors+import Language.PureScript.Sugar.Names.Env++-- Finds the imports within a module, mapping the imported module name to an optional set of+-- explicitly imported declarations.+findImports :: forall m. (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => [Declaration] -> m (M.Map ModuleName [(Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)])+findImports = foldM (go Nothing) M.empty+  where+  go pos result (ImportDeclaration mn typ qual) = do+    checkImportRefType typ+    let imp = (pos, typ, qual)+    return $ M.insert mn (maybe [imp] (imp :) (mn `M.lookup` result)) result+  go _ result (PositionedDeclaration pos _ d) = rethrowWithPosition pos $ go (Just pos) result d+  go _ result _ = return result++  -- Ensure that classes don't appear in an `import X hiding (...)`+  checkImportRefType :: ImportDeclarationType -> m ()+  checkImportRefType (Hiding refs) = mapM_ checkImportRef refs+  checkImportRefType _ = return ()+  checkImportRef :: DeclarationRef -> m ()+  checkImportRef (ModuleRef name) = throwError . errorMessage $ ImportHidingModule name+  checkImportRef _ = return ()++-- |+-- Constructs a set of imports for a module.+--+resolveImports :: forall m. (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => Env -> Module -> m Imports+resolveImports env (Module _ _ currentModule decls _) =+  censor (onErrorMessages (ErrorInModule currentModule)) $ do+    scope <- M.insert currentModule [(Nothing, Implicit, Nothing)] <$> findImports decls+    foldM resolveImport' nullImports (M.toList scope)+  where++  resolveImport' :: Imports -> (ModuleName, [(Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName)]) -> m Imports+  resolveImport' ie (mn, imps) = foldM go ie imps+    where+    go :: Imports -> (Maybe SourceSpan, ImportDeclarationType, Maybe ModuleName) -> m Imports+    go ie' (pos, typ, impQual) = do+      modExports <- positioned $ maybe (throwError . errorMessage $ UnknownModule mn) (return . envModuleExports) $ mn `M.lookup` env+      let ie'' = ie' { importedModules = mn : importedModules ie' }+      positioned $ resolveImport currentModule mn modExports ie'' impQual typ+      where+      positioned err = case pos of+        Nothing -> err+        Just pos' -> rethrowWithPosition pos' err++-- |+-- Extends the local environment for a module by resolving an import of another module.+--+resolveImport :: forall m. (Applicative m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) => ModuleName -> ModuleName -> Exports -> Imports -> Maybe ModuleName -> ImportDeclarationType -> m Imports+resolveImport currentModule importModule exps imps impQual =+  resolveByType+  where++  resolveByType :: ImportDeclarationType -> m Imports+  resolveByType Implicit = importAll importExplicit+  resolveByType (Explicit explImports) = checkRefs explImports >> foldM importExplicit imps explImports+  resolveByType (Hiding hiddenImports) = checkRefs hiddenImports >> importAll (importNonHidden hiddenImports)++  -- Check that a 'DeclarationRef' refers to an importable symbol+  checkRefs :: [DeclarationRef] -> m ()+  checkRefs = mapM_ check+    where+    check (PositionedDeclarationRef pos _ r) =+      rethrowWithPosition pos $ check r+    check (ValueRef name) =+      checkImportExists UnknownImportValue (fst `map` exportedValues exps) name+    check (TypeRef name dctors) = do+      checkImportExists UnknownImportType ((fst . fst) `map` exportedTypes exps) name+      let allDctors = fst `map` allExportedDataConstructors name+      maybe (return ()) (mapM_ $ checkDctorExists name allDctors) dctors+    check (TypeClassRef name) =+      checkImportExists UnknownImportTypeClass (fst `map` exportedTypeClasses exps) name+    --check (ModuleRef name) =+    --  checkImportExists (const UnknownModule) (exportedModules exps) name+    check _ = error "Invalid argument to checkRefs"++  -- Check that an explicitly imported item exists in the module it is being imported from+  checkImportExists :: (Eq a, Show a) => (ModuleName -> a -> SimpleErrorMessage) -> [a] -> a -> m ()+  checkImportExists unknown exports item =+    when (item `notElem` exports) $ throwError . errorMessage $ unknown importModule item++  -- Ensure that an explicitly imported data constructor exists for the type it is being imported+  -- from+  checkDctorExists :: ProperName -> [ProperName] -> ProperName -> m ()+  checkDctorExists tcon = checkImportExists (flip UnknownImportDataConstructor tcon)++  importNonHidden :: [DeclarationRef] -> Imports -> DeclarationRef -> m Imports+  importNonHidden hidden m ref | isHidden ref = return m+                               | otherwise = importExplicit m ref+    where+    -- TODO: rework this to be not confusing+    isHidden :: DeclarationRef -> Bool+    isHidden ref'@(TypeRef _ _) = foldl (checkTypeRef ref') False hidden+    isHidden ref' = ref' `elem` hidden+    checkTypeRef :: DeclarationRef -> Bool -> DeclarationRef -> Bool+    checkTypeRef _ True _ = True+    checkTypeRef r acc (PositionedDeclarationRef _ _ h) = checkTypeRef r acc h+    checkTypeRef (TypeRef _ Nothing) acc (TypeRef _ (Just _)) = acc+    checkTypeRef (TypeRef name (Just dctor)) _ (TypeRef name' (Just dctor')) = name == name' && dctor == dctor'+    checkTypeRef (TypeRef name _) _ (TypeRef name' Nothing) = name == name'+    checkTypeRef (PositionedDeclarationRef _ _ r) acc hiddenRef = checkTypeRef r acc hiddenRef+    checkTypeRef _ acc _ = acc++  -- Import all symbols+  importAll :: (Imports -> DeclarationRef -> m Imports) -> m Imports+  importAll importer = do+    imp' <- foldM (\m ((name, dctors), _) -> importer m (TypeRef name (Just dctors))) imps (exportedTypes exps)+    imp'' <- foldM (\m (name, _) -> importer m (ValueRef name)) imp' (exportedValues exps)+    foldM (\m (name, _) -> importer m (TypeClassRef name)) imp'' (exportedTypeClasses exps)++  -- Import something explicitly+  importExplicit :: Imports -> DeclarationRef -> m Imports+  importExplicit imp (PositionedDeclarationRef pos _ r) =+    rethrowWithPosition pos . warnWithPosition pos $ importExplicit imp r+  importExplicit imp (ValueRef name) = do+    values' <- updateImports (importedValues imp) (exportedValues exps) name+    return $ imp { importedValues = values' }+  importExplicit imp (TypeRef name dctors) = do+    types' <- updateImports (importedTypes imp) (first fst `map` exportedTypes exps) name+    let exportedDctors :: [(ProperName, ModuleName)]+        exportedDctors = allExportedDataConstructors name+        dctorNames :: [ProperName]+        dctorNames = fst `map` exportedDctors+    maybe (return ()) (mapM_ $ checkDctorExists name dctorNames) dctors+    when (null dctorNames && isNothing dctors) . tell . errorMessage $ MisleadingEmptyTypeImport importModule name+    dctors' <- foldM (flip updateImports exportedDctors) (importedDataConstructors imp) (fromMaybe dctorNames dctors)+    return $ imp { importedTypes = types', importedDataConstructors = dctors' }+  importExplicit imp (TypeClassRef name) = do+    typeClasses' <- updateImports (importedTypeClasses imp) (exportedTypeClasses exps) name+    return $ imp { importedTypeClasses = typeClasses' }+  importExplicit _ _ = error "Invalid argument to importExplicit"++  -- Find all exported data constructors for a given type+  allExportedDataConstructors :: ProperName -> [(ProperName, ModuleName)]+  allExportedDataConstructors name =+    case find ((== name) . fst . fst) (exportedTypes exps) of+      Nothing -> error "Invalid state in allExportedDataConstructors"+      Just ((_, dctors), mn) -> map (, mn) dctors++  -- Add something to the Imports if it does not already exist there+  updateImports :: (Ord a, Show a) => M.Map (Qualified a) (Qualified a, ModuleName)+                                   -> [(a, ModuleName)]+                                   -> a+                                   -> m (M.Map (Qualified a) (Qualified a, ModuleName))+  updateImports imps' exps' name = case M.lookup (Qualified impQual name) imps' of++    -- If the name is not already present add it to the list, after looking up+    -- where it was originally defined+    Nothing ->+      let mnOrig = fromMaybe (error "Invalid state in updateImports") (name `lookup` exps')+      in return $ M.insert (Qualified impQual name) (Qualified (Just importModule) name, mnOrig) imps'++    -- If the name already is present check whether it's a duplicate import+    -- before rejecting it. For example, if module A defines X, and module B+    -- re-exports A, importing A and B in C should not result in a "conflicting+    -- import for `x`" error+    Just (Qualified (Just mn) _, mnOrig)+       | mnOrig == fromMaybe (error "Invalid state in updateImports") (name `lookup` exps') -> return imps'+       | otherwise -> throwError . errorMessage $ err+        where+        err = if currentModule `elem` [mn, importModule]+              then ConflictingImport (show name) importModule+              else ConflictingImports (show name) mn importModule++    Just (Qualified Nothing _, _) ->+      error "Invalid state in updateImports"
src/Language/PureScript/Sugar/ObjectWildcards.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Sugar.ObjectWildcards--- Copyright   :  (c) 2013-14 Phil Freeman, (c) 2014 Gary Burgess, and other contributors--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com> -- Stability   :  experimental@@ -14,12 +14,15 @@  {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Sugar.ObjectWildcards (   desugarObjectConstructors ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Arrow (second) import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Supply.Class@@ -32,7 +35,7 @@ import Language.PureScript.Names  desugarObjectConstructors :: forall m. (Applicative m, MonadSupply m, MonadError MultipleErrors m) => Module -> m Module-desugarObjectConstructors (Module coms mn ds exts) = Module coms mn <$> mapM desugarDecl ds <*> pure exts+desugarObjectConstructors (Module ss coms mn ds exts) = Module ss coms mn <$> mapM desugarDecl ds <*> pure exts   where    desugarDecl :: Declaration -> m Declaration
src/Language/PureScript/Sugar/Operators.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Sugar.Operators--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -20,6 +20,7 @@ {-# LANGUAGE Rank2Types #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Sugar.Operators (   rebracket,@@ -31,7 +32,9 @@ import Language.PureScript.Errors import Language.PureScript.Names +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.State import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Supply.Class@@ -57,7 +60,7 @@   mapM (rebracketModule opTable) ms  removeSignedLiterals :: Module -> Module-removeSignedLiterals (Module coms mn ds exts) = Module coms mn (map f' ds) exts+removeSignedLiterals (Module ss coms mn ds exts) = Module ss coms mn (map f' ds) exts   where   (f', _, _) = everywhereOnValues id go id @@ -65,9 +68,9 @@   go other = other  rebracketModule :: (Applicative m, MonadError MultipleErrors m) => [[(Qualified Ident, Expr -> Expr -> Expr, Associativity)]] -> Module -> m Module-rebracketModule opTable (Module coms mn ds exts) =+rebracketModule opTable (Module ss coms mn ds exts) =   let (f, _, _) = everywhereOnValuesTopDownM return (matchOperators opTable) return-  in Module coms mn <$> (map removeParens <$> parU ds f) <*> pure exts+  in Module ss coms mn <$> (map removeParens <$> parU ds f) <*> pure exts  removeParens :: Declaration -> Declaration removeParens =@@ -78,7 +81,7 @@   go val = val  collectFixities :: Module -> [(Qualified Ident, SourceSpan, Fixity)]-collectFixities (Module _ moduleName ds _) = concatMap collect ds+collectFixities (Module _ _ moduleName ds _) = concatMap collect ds   where   collect :: Declaration -> [(Qualified Ident, SourceSpan, Fixity)]   collect (PositionedDeclaration pos _ (FixityDeclaration fixity name)) = [(Qualified (Just moduleName) (Op name), pos, fixity)]@@ -152,7 +155,7 @@   guard $ ident == op  desugarOperatorSections :: forall m. (Applicative m, MonadSupply m, MonadError MultipleErrors m) => Module -> m Module-desugarOperatorSections (Module coms mn ds exts) = Module coms mn <$> mapM goDecl ds <*> pure exts+desugarOperatorSections (Module ss coms mn ds exts) = Module ss coms mn <$> mapM goDecl ds <*> pure exts   where    goDecl :: Declaration -> m Declaration
src/Language/PureScript/Sugar/TypeClasses.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Sugar.TypeClasses--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -15,6 +15,7 @@ -----------------------------------------------------------------------------  {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Sugar.TypeClasses   ( desugarTypeClasses@@ -33,7 +34,9 @@  import qualified Language.PureScript.Constants as C +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Arrow (first, second) import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.State@@ -54,9 +57,9 @@ desugarTypeClasses = flip evalStateT M.empty . mapM desugarModule  desugarModule :: (Functor m, Applicative m, MonadSupply m, MonadError MultipleErrors m) => Module -> Desugar m Module-desugarModule (Module coms name decls (Just exps)) = do+desugarModule (Module ss coms name decls (Just exps)) = do   (newExpss, declss) <- unzip <$> parU (sortBy classesFirst decls) (desugarDecl name exps)-  return $ Module coms name (concat declss) $ Just (exps ++ catMaybes newExpss)+  return $ Module ss coms name (concat declss) $ Just (exps ++ catMaybes newExpss)   where   classesFirst :: Declaration -> Declaration -> Ordering   classesFirst d1 d2
src/Language/PureScript/Sugar/TypeClasses/Deriving.hs view
@@ -19,6 +19,7 @@ {-# LANGUAGE PatternGuards #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP #-}
 
 module Language.PureScript.Sugar.TypeClasses.Deriving (
     deriveInstances
@@ -28,7 +29,9 @@ import Data.Maybe (fromMaybe)
 import Data.Ord (comparing)
 
+#if __GLASGOW_HASKELL__ < 710
 import Control.Applicative
+#endif
 import Control.Monad (replicateM)
 import Control.Monad.Supply.Class (MonadSupply, freshName)
 import Control.Monad.Error.Class (MonadError(..))
@@ -42,17 +45,17 @@ 
 -- | Elaborates deriving instance declarations by code generation.
 deriveInstances ::  (Functor m, Applicative m, MonadError MultipleErrors m, MonadSupply m) => Module -> m Module
-deriveInstances (Module coms mn ds exts) = Module coms mn <$> mapM (deriveInstance mn ds) ds <*> pure exts
+deriveInstances (Module ss coms mn ds exts) = Module ss coms mn <$> mapM (deriveInstance mn ds) ds <*> pure exts
 
--- | Takes a declaration, and if the declaration is a deriving TypeInstanceDeclaration, 
+-- | Takes a declaration, and if the declaration is a deriving TypeInstanceDeclaration,
 -- elaborates that into an instance declaration via code generation.
 deriveInstance :: (Functor m, MonadError MultipleErrors m, MonadSupply m) => ModuleName -> [Declaration] -> Declaration -> m Declaration
-deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@[ty] DerivedInstance) 
+deriveInstance mn ds (TypeInstanceDeclaration nm deps className tys@[ty] DerivedInstance)
   | className == Qualified (Just dataGeneric) (ProperName C.generic)
   , Just (Qualified mn' tyCon) <- unwrapTypeConstructor ty
   , mn == fromMaybe mn mn'
   = TypeInstanceDeclaration nm deps className tys . ExplicitInstance <$> deriveGeneric mn ds tyCon
-deriveInstance _ _ (TypeInstanceDeclaration _ _ className tys DerivedInstance) 
+deriveInstance _ _ (TypeInstanceDeclaration _ _ className tys DerivedInstance)
   = throwError . errorMessage $ CannotDerive className tys
 deriveInstance mn ds (PositionedDeclaration pos com d) = PositionedDeclaration pos com <$> deriveInstance mn ds d
 deriveInstance _  _  e = return e
@@ -90,7 +93,7 @@ mkSpineFunction :: forall m. (Functor m, MonadSupply m) => ModuleName -> Declaration -> m Expr
 mkSpineFunction mn (DataDeclaration _ _ _ args) = lamCase "$x" <$> mapM mkCtorClause args
   where
-  prodConstructor :: Expr -> Expr      
+  prodConstructor :: Expr -> Expr
   prodConstructor = App (Constructor (Qualified (Just dataGeneric) (ProperName "SProd")))
 
   recordConstructor :: Expr -> Expr
@@ -100,10 +103,10 @@   mkCtorClause (ctorName, tys) = do
     idents <- replicateM (length tys) (fmap Ident freshName)
     return $ CaseAlternative [ConstructorBinder (Qualified (Just mn) ctorName) (map VarBinder idents)] (Right (caseResult idents))
-    where 
-    caseResult idents = 
-      App (prodConstructor (StringLiteral . runProperName $ ctorName)) 
-        . ArrayLiteral 
+    where
+    caseResult idents =
+      App (prodConstructor (StringLiteral . runProperName $ ctorName))
+        . ArrayLiteral
         $ zipWith toSpineFun (map (Var . Qualified Nothing) idents) tys
 
   toSpineFun :: Expr -> Type -> Expr
@@ -118,15 +121,15 @@ mkSignatureFunction :: ModuleName -> Declaration -> Expr
 mkSignatureFunction _ (DataDeclaration _ _ _ args) = lamNull . mkSigProd $ map mkProdClause args
   where
-  mkSigProd :: [Expr] -> Expr      
+  mkSigProd :: [Expr] -> Expr
   mkSigProd = App (Constructor (Qualified (Just dataGeneric) (ProperName "SigProd"))) . ArrayLiteral
 
-  mkSigRec :: [Expr] -> Expr      
+  mkSigRec :: [Expr] -> Expr
   mkSigRec = App (Constructor (Qualified (Just dataGeneric) (ProperName "SigRecord"))) . ArrayLiteral
-  
+
   proxy :: Type -> Type
   proxy = TypeApp (TypeConstructor (Qualified (Just dataGeneric) (ProperName "Proxy")))
-  
+
   mkProdClause :: (ProperName, [Type]) -> Expr
   mkProdClause (ctorName, tys) = ObjectLiteral [ ("sigConstructor", StringLiteral (runProperName ctorName))
                                                , ("sigValues", ArrayLiteral . map mkProductSignature $ tys)
@@ -147,24 +150,24 @@ mkFromSpineFunction :: forall m. (Functor m, MonadSupply m) => ModuleName -> Declaration -> m Expr
 mkFromSpineFunction mn (DataDeclaration _ _ _ args) = lamCase "$x" <$> (addCatch <$> mapM mkAlternative args)
   where
-  mkJust :: Expr -> Expr      
+  mkJust :: Expr -> Expr
   mkJust = App (Constructor (Qualified (Just dataMaybe) (ProperName "Just")))
 
-  mkNothing :: Expr      
+  mkNothing :: Expr
   mkNothing = Constructor (Qualified (Just dataMaybe) (ProperName "Nothing"))
-  
-  prodBinder :: [Binder] -> Binder      
+
+  prodBinder :: [Binder] -> Binder
   prodBinder = ConstructorBinder (Qualified (Just dataGeneric) (ProperName "SProd"))
 
-  recordBinder :: [Binder] -> Binder    
+  recordBinder :: [Binder] -> Binder
   recordBinder = ConstructorBinder (Qualified (Just dataGeneric) (ProperName "SRecord"))
- 
+
   mkAlternative :: (ProperName, [Type]) -> m CaseAlternative
   mkAlternative (ctorName, tys) = do
     idents <- replicateM (length tys) (fmap Ident freshName)
     return $ CaseAlternative [ prodBinder [ StringBinder (runProperName ctorName), ArrayBinder (map VarBinder idents)]]
-               . Right 
-               $ liftApplicative (mkJust $ Constructor (Qualified (Just mn) ctorName)) 
+               . Right
+               $ liftApplicative (mkJust $ Constructor (Qualified (Just mn) ctorName))
                                  (zipWith fromSpineFun (map (Var . (Qualified Nothing)) idents) tys)
 
   addCatch :: [CaseAlternative] -> [CaseAlternative]
@@ -172,19 +175,19 @@     where
     catchAll = CaseAlternative [NullBinder] (Right mkNothing)
 
-  fromSpineFun e r 
-    | Just rec <- objectType r 
+  fromSpineFun e r
+    | Just rec <- objectType r
     = App (lamCase "r" [ mkRecCase (decomposeRec rec)
                        , CaseAlternative [NullBinder] (Right mkNothing)
-                       ]) 
+                       ])
           (App e (mkPrelVar "unit"))
 
   fromSpineFun e _ = App (mkGenVar C.fromSpine) (App e (mkPrelVar "unit"))
-  
-  mkRecCase rs = CaseAlternative [ recordBinder [ ArrayBinder (map (VarBinder . Ident . fst) rs) 
+
+  mkRecCase rs = CaseAlternative [ recordBinder [ ArrayBinder (map (VarBinder . Ident . fst) rs)
                                                 ]
-                                 ] 
-                   . Right 
+                                 ]
+                   . Right
                    $ liftApplicative (mkRecFun rs) (map (\(x, y) -> fromSpineFun (Accessor "recValue" (mkVar x)) y) rs)
 
   mkRecFun :: [(String, Type)] -> Expr
@@ -226,4 +229,4 @@ decomposeRec :: Type -> [(String, Type)]
 decomposeRec = sortBy (comparing fst) . go
     where go (RCons str typ typs) = (str, typ) : decomposeRec typs
-          go _ = []+          go _ = []
src/Language/PureScript/Sugar/TypeDeclarations.hs view
@@ -1,8 +1,8 @@ ----------------------------------------------------------------------------- -- -- Module      :  Language.PureScript.Sugar.TypeDeclarations--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- Copyright   :  (c) 2013-15 Phil Freeman, (c) 2014-15 Gary Burgess+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -15,13 +15,16 @@ -----------------------------------------------------------------------------  {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Sugar.TypeDeclarations (     desugarTypeDeclarations,     desugarTypeDeclarationsModule ) where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad (forM) import Control.Monad.Error.Class (MonadError(..)) @@ -35,9 +38,9 @@ -- Replace all top level type declarations in a module with type annotations -- desugarTypeDeclarationsModule :: (Functor m, Applicative m, MonadError MultipleErrors m) => [Module] -> m [Module]-desugarTypeDeclarationsModule ms = forM ms $ \(Module coms name ds exps) ->+desugarTypeDeclarationsModule ms = forM ms $ \(Module ss coms name ds exps) ->   rethrow (onErrorMessages (ErrorInModule name)) $-    Module coms name <$> desugarTypeDeclarations ds <*> pure exps+    Module ss coms name <$> desugarTypeDeclarations ds <*> pure exps  -- | -- Replace all top level type declarations with type annotations
src/Language/PureScript/Traversals.hs view
@@ -12,9 +12,13 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-}+ module Language.PureScript.Traversals where +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif  fstM :: (Functor f) => (a -> f c) -> (a, b) -> f (c, b) fstM f (a, b) = flip (,) b <$> f a
src/Language/PureScript/TypeChecker.hs view
@@ -14,6 +14,7 @@ -----------------------------------------------------------------------------  {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.TypeChecker (     module T,@@ -31,7 +32,9 @@  import qualified Data.Map as M +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative ((<$>), (<*))+#endif import Control.Monad.State import Control.Monad.Error.Class (MonadError(..)) @@ -48,7 +51,7 @@   env <- getEnv   putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (ctorKind, DataType args dctors) (types env) }   forM_ dctors $ \(dctor, tys) ->-    rethrow (onErrorMessages (ErrorInDataConstructor dctor)) $+    warnAndRethrow (onErrorMessages (ErrorInDataConstructor dctor)) $       addDataConstructor moduleName dtype name (map fst args) dctor tys  addDataConstructor :: ModuleName -> DataDeclType -> ProperName -> [String] -> ProperName -> [Type] -> Check ()@@ -130,11 +133,11 @@ --  * Process module imports -- typeCheckAll :: Maybe ModuleName -> ModuleName -> [DeclarationRef] -> [Declaration] -> Check [Declaration]-typeCheckAll mainModuleName moduleName exps ds = mapM go ds <* mapM_ checkOrphanFixities ds+typeCheckAll mainModuleName moduleName _ ds = mapM go ds <* mapM_ checkOrphanFixities ds   where   go :: Declaration -> Check Declaration   go (DataDeclaration dtype name args dctors) = do-    rethrow (onErrorMessages (ErrorInTypeConstructor name)) $ do+    warnAndRethrow (onErrorMessages (ErrorInTypeConstructor name)) $ do       when (dtype == Newtype) $ checkNewtype dctors       checkDuplicateTypeArguments $ map fst args       ctorKind <- kindsOf True moduleName name args (concatMap snd dctors)@@ -147,7 +150,7 @@     checkNewtype [(_, _)] = throwError . errorMessage $ InvalidNewtype     checkNewtype _ = throwError . errorMessage $ InvalidNewtype   go (d@(DataBindingGroupDeclaration tys)) = do-    rethrow (onErrorMessages ErrorInDataBindingGroup) $ do+    warnAndRethrow (onErrorMessages ErrorInDataBindingGroup) $ do       let syns = mapMaybe toTypeSynonym tys       let dataDecls = mapMaybe toDataDecl tys       (syn_ks, data_ks) <- kindsOfAll moduleName syns (map (\(_, name, args, dctors) -> (name, args, concatMap snd dctors)) dataDecls)@@ -168,7 +171,7 @@     toDataDecl (PositionedDeclaration _ _ d') = toDataDecl d'     toDataDecl _ = Nothing   go (TypeSynonymDeclaration name args ty) = do-    rethrow (onErrorMessages (ErrorInTypeSynonym name)) $ do+    warnAndRethrow (onErrorMessages (ErrorInTypeSynonym name)) $ do       checkDuplicateTypeArguments $ map fst args       kind <- kindsOf False moduleName name args [ty]       let args' = args `withKinds` kind@@ -176,14 +179,14 @@     return $ TypeSynonymDeclaration name args ty   go (TypeDeclaration{}) = error "Type declarations should have been removed"   go (ValueDeclaration name nameKind [] (Right val)) =-    rethrow (onErrorMessages (ErrorInValueDeclaration name)) $ do+    warnAndRethrow (onErrorMessages (ErrorInValueDeclaration name)) $ do       valueIsNotDefined moduleName name       [(_, (val', ty))] <- typesOf mainModuleName moduleName [(name, val)]       addValue moduleName name ty nameKind       return $ ValueDeclaration name nameKind [] $ Right val'   go (ValueDeclaration{}) = error "Binders were not desugared"   go (BindingGroupDeclaration vals) =-    rethrow (onErrorMessages (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do+    warnAndRethrow (onErrorMessages (ErrorInBindingGroup (map (\(ident, _, _) -> ident) vals))) $ do       forM_ (map (\(ident, _, _) -> ident) vals) $ \name ->         valueIsNotDefined moduleName name       tys <- typesOf mainModuleName moduleName $ map (\(ident, _, ty) -> (ident, ty)) vals@@ -200,7 +203,7 @@     putEnv $ env { types = M.insert (Qualified (Just moduleName) name) (kind, ExternData) (types env) }     return d   go (d@(ExternDeclaration name ty)) = do-    rethrow (onErrorMessages (ErrorInForeignImport name)) $ do+    warnAndRethrow (onErrorMessages (ErrorInForeignImport name)) $ do       env <- getEnv       kind <- kindOf moduleName ty       guardWith (errorMessage (ExpectedType kind)) $ kind == Star@@ -221,14 +224,14 @@   go (d@(ExternInstanceDeclaration dictName deps className tys)) =     goInstance d dictName deps className tys   go (PositionedDeclaration pos com d) =-    rethrowWithPosition pos $ PositionedDeclaration pos com <$> go d+    warnAndRethrowWithPosition pos $ PositionedDeclaration pos com <$> go d    checkOrphanFixities :: Declaration -> Check ()   checkOrphanFixities (FixityDeclaration _ name) = do     env <- getEnv     guardWith (errorMessage (OrphanFixityDeclaration name)) $ M.member (moduleName, Op name) $ names env   checkOrphanFixities (PositionedDeclaration pos _ d) =-    rethrowWithPosition pos $ checkOrphanFixities d+    warnAndRethrowWithPosition pos $ checkOrphanFixities d   checkOrphanFixities _ = return ()    goInstance :: Declaration -> Ident -> [Constraint] -> Qualified ProperName -> [Type] -> Check Declaration@@ -236,16 +239,16 @@     mapM_ (checkTypeClassInstance moduleName) tys     forM_ deps $ mapM_ (checkTypeClassInstance moduleName) . snd     checkOrphanInstance moduleName className tys-    let dict = TypeClassDictionaryInScope (Qualified (Just moduleName) dictName) className tys (Just deps) TCDRegular isInstanceExported+    let dict = TypeClassDictionaryInScope (Qualified (Just moduleName) dictName) [] className tys (Just deps) TCDRegular     addTypeClassDictionaries (Just moduleName) . M.singleton className $ M.singleton (canonicalizeDictionary dict) dict     return d      where      checkOrphanInstance :: ModuleName -> Qualified ProperName -> [Type] -> Check ()-    checkOrphanInstance mn (Qualified (Just mn') _) tys-      | mn == mn' || any checkType tys = return ()-      | otherwise = throwError . errorMessage $ OrphanInstance dictName className tys+    checkOrphanInstance mn (Qualified (Just mn') _) tys'+      | mn == mn' || any checkType tys' = return ()+      | otherwise = throwError . errorMessage $ OrphanInstance dictName className tys'       where       checkType :: Type -> Bool       checkType (TypeVar _) = False@@ -255,14 +258,6 @@       checkType _ = error "Invalid type in instance in checkOrphanInstance"     checkOrphanInstance _ _ _ = error "Unqualified class name in checkOrphanInstance" -    isInstanceExported :: Bool-    isInstanceExported = any exportsInstance exps--    exportsInstance :: DeclarationRef -> Bool-    exportsInstance (TypeInstanceRef name) | name == dictName = True-    exportsInstance (PositionedDeclarationRef _ _ r) = exportsInstance r-    exportsInstance _ = False-   -- |   -- This function adds the argument kinds for a type constructor so that they may appear in the externs file,   -- extracted from the kind of the type constructor itself.@@ -278,15 +273,15 @@ -- required by exported members are also exported. -- typeCheckModule :: Maybe ModuleName -> Module -> Check Module-typeCheckModule _ (Module _ _ _ Nothing) = error "exports should have been elaborated"-typeCheckModule mainModuleName (Module coms mn decls (Just exps)) = rethrow (onErrorMessages (ErrorInModule mn)) $ do+typeCheckModule _ (Module _ _ _ _ Nothing) = error "exports should have been elaborated"+typeCheckModule mainModuleName (Module ss coms mn decls (Just exps)) = warnAndRethrow (onErrorMessages (ErrorInModule mn)) $ do   modify (\s -> s { checkCurrentModule = Just mn })   decls' <- typeCheckAll mainModuleName mn exps decls   forM_ exps $ \e -> do     checkTypesAreExported e     checkClassMembersAreExported e     checkClassesAreExported e-  return $ Module coms mn decls' (Just exps)+  return $ Module ss coms mn decls' (Just exps)   where    checkMemberExport :: (Type -> [DeclarationRef]) -> DeclarationRef -> Check ()
src/Language/PureScript/TypeChecker/Entailment.hs view
@@ -14,6 +14,7 @@ -----------------------------------------------------------------------------  {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.TypeChecker.Entailment (     entails@@ -22,13 +23,18 @@ import Data.Function (on) import Data.List import Data.Maybe (maybeToList)+#if __GLASGOW_HASKELL__ < 710 import Data.Foldable (foldMap)+#endif import qualified Data.Map as M +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Arrow (Arrow(..)) import Control.Monad.State import Control.Monad.Error.Class (MonadError(..))+import Control.Monad.Writer.Class (tell)  import Language.PureScript.AST import Language.PureScript.Errors@@ -41,13 +47,11 @@ import Language.PureScript.Types import qualified Language.PureScript.Constants as C -newtype Work = Work Integer deriving (Show, Eq, Ord, Num)- -- | -- Check that the current set of type class dictionaries entail the specified type class goal, and, if so, -- return a type class dictionary reference. ---entails :: Environment -> ModuleName -> M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)) -> Constraint -> Bool -> Check Expr+entails :: Environment -> ModuleName -> M.Map (Maybe ModuleName) (M.Map (Qualified ProperName) (M.Map (Qualified Ident) TypeClassDictionaryInScope)) -> Constraint -> Check Expr entails env moduleName context = solve   where     forClassName :: Qualified ProperName -> [TypeClassDictionaryInScope]@@ -56,56 +60,61 @@     findDicts :: Qualified ProperName -> Maybe ModuleName -> [TypeClassDictionaryInScope]     findDicts cn = maybe [] M.elems . (>>= M.lookup cn) . flip M.lookup context -    solve :: Constraint -> Bool -> Check Expr-    solve (className, tys) trySuperclasses = do-      let dicts = flip evalStateT (Work 0) $ go trySuperclasses className tys-      checkOverlaps dicts+    solve :: Constraint -> Check Expr+    solve (className, tys) = do+      dict <- go 0 className tys+      return $ dictionaryValueToValue dict       where-      go :: Bool -> Qualified ProperName -> [Type] -> StateT Work [] DictionaryValue-      go trySuperclasses' className' tys' = do-        workDone <- get-        guard $ workDone < 1000-        modify (1 +)-        directInstances <|> superclassInstances+      go :: Int -> Qualified ProperName -> [Type] -> Check DictionaryValue+      go work className' tys' | work > 1000 = throwError . errorMessage $ PossiblyInfiniteInstance className' tys'+      go work className' tys' = do+        let instances = do+              tcd <- forClassName className'+              -- Make sure the type unifies with the type in the type instance definition+              subst <- maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys' (tcdInstanceTypes tcd)+              return (subst, tcd)+        (subst, tcd) <- unique instances+        -- Solve any necessary subgoals+        args <- solveSubgoals subst (tcdDependencies tcd)+        return $ foldr (\(superclassName, index) dict -> SubclassDictionaryValue dict superclassName index) +                       (mkDictionary (canonicalizeDictionary tcd) args) +                       (tcdPath tcd)         where-        directInstances :: StateT Work [] DictionaryValue-        directInstances = do-          tcd <- lift $ forClassName className'-          -- Make sure the type unifies with the type in the type instance definition-          subst <- lift . maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys' (tcdInstanceTypes tcd)-          -- Solve any necessary subgoals-          args <- solveSubgoals subst (tcdDependencies tcd)-          return $ mkDictionary (canonicalizeDictionary tcd) args+            +        unique :: [(a, TypeClassDictionaryInScope)] -> Check (a, TypeClassDictionaryInScope)+        unique [] = throwError . errorMessage $ NoInstanceFound className' tys'+        unique [a] = return a+        unique tcds | pairwise overlapping (map snd tcds) = do+                        tell . errorMessage $ OverlappingInstances className' tys' (map (tcdName . snd) tcds)+                        return (head tcds)+                    | otherwise = return (minimumBy (compare `on` length . tcdPath . snd) tcds) -        superclassInstances :: StateT Work [] DictionaryValue-        superclassInstances = do-          guard trySuperclasses'-          (subclassName, (args, _, implies)) <- lift $ M.toList (typeClasses env)-          -- Try each superclass-          (index, (superclass, suTyArgs)) <- lift $ zip [0..] implies-          -- Make sure the type class name matches the superclass name-          guard $ className' == superclass-          -- Make sure the types unify with the types in the superclass implication-          subst <- lift . maybeToList . (>>= verifySubstitution) . fmap concat $ zipWithM (typeHeadsAreEqual moduleName env) tys' suTyArgs-          -- Finally, satisfy the subclass constraint-          args' <- lift . maybeToList $ mapM ((`lookup` subst) . fst) args-          suDict <- go True subclassName args'-          return $ SubclassDictionaryValue suDict superclass index+        -- |+        -- Check if two dictionaries are overlapping+        --+        -- Dictionaries which are subclass dictionaries cannot overlap, since otherwise the overlap would have+        -- been caught when constructing superclass dictionaries.+        overlapping :: TypeClassDictionaryInScope -> TypeClassDictionaryInScope -> Bool+        overlapping TypeClassDictionaryInScope{ tcdPath = _ : _ } _ = False+        overlapping _ TypeClassDictionaryInScope{ tcdPath = _ : _ } = False+        overlapping TypeClassDictionaryInScope{ tcdDependencies = Nothing } _ = False+        overlapping _ TypeClassDictionaryInScope{ tcdDependencies = Nothing } = False+        overlapping tcd1 tcd2 = tcdName tcd1 /= tcdName tcd2 -      -- Create dictionaries for subgoals which still need to be solved by calling go recursively-      -- E.g. the goal (Show a, Show b) => Show (Either a b) can be satisfied if the current type-      -- unifies with Either a b, and we can satisfy the subgoals Show a and Show b recursively.-      solveSubgoals :: [(String, Type)] -> Maybe [Constraint] -> StateT Work [] (Maybe [DictionaryValue])-      solveSubgoals _ Nothing = return Nothing-      solveSubgoals subst (Just subgoals) = do-        dict <- mapM (uncurry (go True) . second (map (replaceAllTypeVars subst))) subgoals-        return $ Just dict+        -- Create dictionaries for subgoals which still need to be solved by calling go recursively+        -- E.g. the goal (Show a, Show b) => Show (Either a b) can be satisfied if the current type+        -- unifies with Either a b, and we can satisfy the subgoals Show a and Show b recursively.+        solveSubgoals :: [(String, Type)] -> Maybe [Constraint] -> Check (Maybe [DictionaryValue])+        solveSubgoals _ Nothing = return Nothing+        solveSubgoals subst (Just subgoals) = do+          dict <- mapM (uncurry (go (work + 1)) . second (map (replaceAllTypeVars subst))) subgoals+          return $ Just dict         -      -- Make a dictionary from subgoal dictionaries by applying the correct function-      mkDictionary :: Qualified Ident -> Maybe [DictionaryValue] -> DictionaryValue-      mkDictionary fnName Nothing = LocalDictionaryValue fnName-      mkDictionary fnName (Just []) = GlobalDictionaryValue fnName-      mkDictionary fnName (Just dicts) = DependentDictionaryValue fnName dicts+        -- Make a dictionary from subgoal dictionaries by applying the correct function+        mkDictionary :: Qualified Ident -> Maybe [DictionaryValue] -> DictionaryValue+        mkDictionary fnName Nothing = LocalDictionaryValue fnName+        mkDictionary fnName (Just []) = GlobalDictionaryValue fnName+        mkDictionary fnName (Just dicts) = DependentDictionaryValue fnName dicts              -- Turn a DictionaryValue into a Expr       dictionaryValueToValue :: DictionaryValue -> Expr@@ -122,46 +131,7 @@         let grps = groupBy ((==) `on` fst) subst         guard (all (pairwise (unifiesWith env) . map snd) grps)         return $ map head grps-      -- |-      -- Check for overlapping instances-      ---      checkOverlaps :: [DictionaryValue] -> Check Expr-      checkOverlaps dicts =-        case [ (d1, d2) | d1 <- dicts, d2 <- dicts, d1 `overlapping` d2 ] of-          ds@(_ : _) -> throwError . errorMessage $ OverlappingInstances className tys $ nub (map fst ds)-          _ -> case chooseSimplestDictionaries dicts of-                 [] -> throwError . errorMessage $ NoInstanceFound className tys-                 d : _ -> return $ dictionaryValueToValue d-      -- Choose the simplest DictionaryValues from a list of candidates-      -- The reason for this function is as follows:-      -- When considering overlapping instances, we don't want to consider the same dictionary-      -- to be an overlap of itself when obtained as a superclass of another class.-      -- Observing that we probably don't want to select a superclass instance when an instance-      -- is available directly, and that there is no way for a superclass instance to actually-      -- introduce an overlap that wouldn't have been there already, we simply remove dictionaries-      -- obtained as superclass instances if there are simpler instances available.-      chooseSimplestDictionaries :: [DictionaryValue] -> [DictionaryValue]-      chooseSimplestDictionaries ds = case filter isSimpleDictionaryValue ds of-                                        [] -> ds-                                        simple -> simple-      isSimpleDictionaryValue SubclassDictionaryValue{} = False-      isSimpleDictionaryValue (DependentDictionaryValue _ ds) = all isSimpleDictionaryValue ds-      isSimpleDictionaryValue _ = True-      -- |-      -- Check if two dictionaries are overlapping-      ---      -- Dictionaries which are subclass dictionaries cannot overlap, since otherwise the overlap would have-      -- been caught when constructing superclass dictionaries.-      ---      overlapping :: DictionaryValue -> DictionaryValue -> Bool-      overlapping (LocalDictionaryValue nm1)         (LocalDictionaryValue nm2)  | nm1 == nm2 = False-      overlapping (GlobalDictionaryValue nm1)        (GlobalDictionaryValue nm2) | nm1 == nm2 = False-      overlapping (DependentDictionaryValue nm1 ds1) (DependentDictionaryValue nm2 ds2)-        | nm1 == nm2 = or $ zipWith overlapping ds1 ds2-      overlapping SubclassDictionaryValue{} _ = False-      overlapping _ SubclassDictionaryValue{} = False-      overlapping _ _ = True-+           valUndefined :: Expr     valUndefined = Var (Qualified (Just (ModuleName [ProperName C.prim])) (Ident C.undefined)) 
src/Language/PureScript/TypeChecker/Kinds.hs view
@@ -14,7 +14,10 @@ -----------------------------------------------------------------------------  {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TupleSections #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.TypeChecker.Kinds (     kindOf,@@ -29,7 +32,9 @@ import qualified Data.Map as M  import Control.Arrow (second)+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.State@@ -72,12 +77,12 @@ -- kindOf :: ModuleName -> Type -> Check Kind kindOf _ ty = fst <$> kindOfWithScopedVars ty-    + -- | -- Infer the kind of a single type, returning the kinds of any scoped type variables ---kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])   -kindOfWithScopedVars ty = +kindOfWithScopedVars :: Type -> Check (Kind, [(String, Kind)])+kindOfWithScopedVars ty =   rethrow (onErrorMessages (ErrorCheckingKind ty)) $     fmap tidyUp . liftUnify $ infer ty   where
src/Language/PureScript/TypeChecker/Monad.hs view
@@ -13,18 +13,25 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, RankNTypes,-    MultiParamTypeClasses, FlexibleContexts, GADTs #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.TypeChecker.Monad where  import Data.Maybe import qualified Data.Map as M +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.State import Control.Monad.Unify-import Control.Monad.Writer+import Control.Monad.Writer.Strict import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Trans.Except 
src/Language/PureScript/TypeChecker/Skolems.hs view
@@ -13,6 +13,8 @@ -- ----------------------------------------------------------------------------- +{-# LANGUAGE CPP #-}+ module Language.PureScript.TypeChecker.Skolems (     newSkolemConstant,     introduceSkolemScope,@@ -25,7 +27,9 @@ import Data.List (nub, (\\)) import Data.Monoid +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.Unify 
src/Language/PureScript/TypeChecker/Subsumption.hs view
@@ -69,7 +69,7 @@   subsumes val ty1 ty2 subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do   dicts <- getTypeClassDictionaries-  subsumes' (Just $ foldl App val (map (flip (TypeClassDictionary True) dicts) constraints)) ty1 ty2+  subsumes' (Just $ foldl App val (map (flip TypeClassDictionary dicts) constraints)) ty1 ty2 subsumes' val (TypeApp f1 r1) (TypeApp f2 r2) | f1 == tyObject && f2 == tyObject = do   let     (ts1, r1') = rowToList r1
src/Language/PureScript/TypeChecker/Synonyms.hs view
@@ -13,7 +13,10 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, GADTs #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.TypeChecker.Synonyms (     saturateAllTypeSynonyms,@@ -27,7 +30,9 @@ import Data.Maybe (fromMaybe) import qualified Data.Map as M +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad.Error.Class (MonadError(..)) import Control.Monad.State 
src/Language/PureScript/TypeChecker/Types.hs view
@@ -13,7 +13,10 @@ -- ----------------------------------------------------------------------------- -{-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, OverloadedStrings #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.TypeChecker.Types (     typesOf@@ -40,7 +43,9 @@ import Data.Maybe (fromMaybe) import qualified Data.Map as M +#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad import Control.Monad.State import Control.Monad.Unify@@ -166,7 +171,7 @@   where   g :: Expr -> Expr   g (TypedValue checkTy val t) = TypedValue checkTy val (f t)-  g (TypeClassDictionary b (nm, tys) sco) = TypeClassDictionary b (nm, map f tys) sco+  g (TypeClassDictionary (nm, tys) sco) = TypeClassDictionary (nm, map f tys) sco   g other = other  -- |@@ -177,9 +182,9 @@   let (_, f, _) = everywhereOnValuesTopDownM return go return   in f   where-  go (TypeClassDictionary trySuperclasses constraint dicts) = do+  go (TypeClassDictionary constraint dicts) = do     env <- getEnv-    entails env mn dicts constraint trySuperclasses+    entails env mn dicts constraint   go other = return other  -- |@@ -202,7 +207,7 @@ instantiatePolyTypeWithUnknowns val (ConstrainedType constraints ty) = do    dicts <- getTypeClassDictionaries    (_, ty') <- instantiatePolyTypeWithUnknowns (error "Types under a constraint cannot themselves be constrained") ty-   return (foldl App val (map (flip (TypeClassDictionary True) dicts) constraints), ty')+   return (foldl App val (map (flip TypeClassDictionary dicts) constraints), ty') instantiatePolyTypeWithUnknowns val ty = return (val, ty)  -- |@@ -268,7 +273,7 @@   case ty of     ConstrainedType constraints ty' -> do       dicts <- getTypeClassDictionaries-      return $ TypedValue True (foldl App (Var var) (map (flip (TypeClassDictionary True) dicts) constraints)) ty'+      return $ TypedValue True (foldl App (Var var) (map (flip TypeClassDictionary dicts) constraints)) ty'     _ -> return $ TypedValue True (Var var) ty infer' v@(Constructor c) = do   env <- getEnv@@ -292,7 +297,7 @@   return $ TypedValue True (Let ds' val') valTy infer' (SuperClassDictionary className tys) = do   dicts <- getTypeClassDictionaries-  return $ TypeClassDictionary False (className, tys) dicts+  return $ TypeClassDictionary (className, tys) dicts infer' (TypedValue checkType val ty) = do   Just moduleName <- checkCurrentModule <$> get   (kind, args) <- liftCheck $ kindOfWithScopedVars ty@@ -300,7 +305,7 @@   ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty   val' <- if checkType then withScopedTypeVars moduleName args (check val ty') else return val   return $ TypedValue True val' ty'-infer' (PositionedValue pos _ val) = rethrowWithPosition pos $ infer' val+infer' (PositionedValue pos _ val) = warnAndRethrowWithPosition pos $ infer' val infer' _ = error "Invalid argument to infer"  inferLetBinding :: [Declaration] -> [Declaration] -> Expr -> (Expr -> UnifyT Type Check Expr) -> UnifyT Type Check ([Declaration], Expr)@@ -329,7 +334,7 @@   bindNames dict $ do     makeBindingGroupVisible     inferLetBinding (seen ++ [BindingGroupDeclaration ds']) rest ret j-inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = rethrowWithPosition pos $ do+inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = warnAndRethrowWithPosition pos $ do   (d' : ds', val') <- inferLetBinding seen (d : ds) ret j   return (PositionedDeclaration pos com d' : ds', val') inferLetBinding _ _ _ _ = error "Invalid argument to inferLetBinding"@@ -401,7 +406,7 @@   m <- inferBinder val binder   return $ M.insert name val m inferBinder val (PositionedBinder pos _ binder) =-  rethrowWithPosition pos $ inferBinder val binder+  warnAndRethrowWithPosition pos $ inferBinder val binder  -- | -- Check the types of the return values in a set of binders in a case statement@@ -449,10 +454,25 @@   dictNames <- forM constraints $ \(Qualified _ (ProperName className), _) -> do     n <- liftCheck freshDictionaryName     return $ Ident $ "__dict_" ++ className ++ "_" ++ show n-  val' <- withBindingGroupVisible $ withTypeClassDictionaries (zipWith (\name (className, instanceTy) ->-    TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular False) (map (Qualified Nothing) dictNames)-      constraints) $ check val ty+  dicts <- join <$> liftCheck (zipWithM (newDictionaries []) (map (Qualified Nothing) dictNames) constraints)+  val' <- withBindingGroupVisible $ withTypeClassDictionaries dicts $ check val ty   return $ TypedValue True (foldr (Abs . Left) val' dictNames) t+  where+  -- | Add a dictionary for the constraint to the scope, and dictionaries+  -- for all implies superclass instances.+  newDictionaries :: [(Qualified ProperName, Integer)] -> Qualified Ident -> (Qualified ProperName, [Type]) -> Check [TypeClassDictionaryInScope]+  newDictionaries path name (className, instanceTy) = do+    tcs <- gets (typeClasses . checkEnv)+    let (args, _, superclasses) = fromMaybe (error "newDictionaries: type class lookup failed") $ M.lookup className tcs+    supDicts <- join <$> zipWithM (\(supName, supArgs) index ->+                                      newDictionaries ((supName, index) : path)+                                                      name+                                                      (supName, instantiateSuperclass (map fst args) supArgs instanceTy)+                                  ) superclasses [0..]+    return (TypeClassDictionaryInScope name path className instanceTy Nothing TCDRegular : supDicts)++  instantiateSuperclass :: [String] -> [Type] -> [Type] -> [Type]+  instantiateSuperclass args supArgs tys = map (replaceAllTypeVars (zip args tys)) supArgs check' val (SaturatedTypeSynonym name args) = do   ty <- introduceSkolemScope <=< expandTypeSynonym name $ args   check val ty@@ -501,13 +521,9 @@   -- TypeClassDictionary placeholder. The reason we do this is that it is necessary to have the   -- correct super instance dictionaries in scope, and these are not available when the type class   -- declaration gets desugared.-  ---  -- Note also that the first argument to TypeClassDictionary is False, meaning we _do not_ want-  -- to consider superclass instances when searching for this dictionary - doing so might lead-  -- to traversing a cycle in the instance graph.   -}   dicts <- getTypeClassDictionaries-  return $ TypeClassDictionary False (className, tys) dicts+  return $ TypeClassDictionary (className, tys) dicts check' (TypedValue checkType val ty1) ty2 = do   Just moduleName <- checkCurrentModule <$> get   (kind, args) <- liftCheck $ kindOfWithScopedVars ty1@@ -570,7 +586,7 @@   val' <- check' val ty   return $ TypedValue True val' kt check' (PositionedValue pos _ val) ty =-  rethrowWithPosition pos $ check' val ty+  warnAndRethrowWithPosition pos $ check' val ty check' val ty = throwError . errorMessage $ ExprDoesNotHaveType val ty  containsTypeSynonyms :: Type -> Bool@@ -648,7 +664,7 @@   checkFunctionApplication fn ty arg ret checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do   dicts <- getTypeClassDictionaries-  checkFunctionApplication' (foldl App fn (map (flip (TypeClassDictionary True) dicts) constraints)) fnTy arg ret+  checkFunctionApplication' (foldl App fn (map (flip TypeClassDictionary dicts) constraints)) fnTy arg ret checkFunctionApplication' fn fnTy dict@TypeClassDictionary{} _ =   return (fnTy, App fn dict) checkFunctionApplication' _ fnTy arg _ = throwError . errorMessage $ CannotApplyFunction fnTy arg
src/Language/PureScript/TypeChecker/Unify.hs view
@@ -14,7 +14,9 @@ -----------------------------------------------------------------------------  {-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleInstances, FlexibleContexts, MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}  module Language.PureScript.TypeChecker.Unify (     unifyTypes,@@ -157,14 +159,14 @@ unifiesWith e r1@(RCons _ _ _) r2@(RCons _ _ _) =   let (s1, r1') = rowToList r1       (s2, r2') = rowToList r2-      +       int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]       sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]       sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]   in all (\(t1, t2) -> unifiesWith e t1 t2) int && go sd1 r1' sd2 r2'   where   go :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Bool-  go [] REmpty          [] REmpty          = True +  go [] REmpty          [] REmpty          = True   go [] (TypeVar v1)    [] (TypeVar v2)    = v1 == v2   go [] (Skolem _ s1 _) [] (Skolem _ s2 _) = s1 == s2   go _  (TUnknown _)    _  _               = True
src/Language/PureScript/TypeClassDictionaries.hs view
@@ -26,30 +26,18 @@ -- data TypeClassDictionaryInScope   = TypeClassDictionaryInScope {-    -- |-    -- The identifier with which the dictionary can be accessed at runtime-    --+    -- | The identifier with which the dictionary can be accessed at runtime       tcdName :: Qualified Ident-    -- |-    -- The name of the type class to which this type class instance applies-    --+    -- | How to obtain this instance via superclass relationships+    , tcdPath :: [(Qualified ProperName, Integer)]+    -- | The name of the type class to which this type class instance applies     , tcdClassName :: Qualified ProperName-    -- |-    -- The types to which this type class instance applies-    --+    -- | The types to which this type class instance applies     , tcdInstanceTypes :: [Type]-    -- |-    -- Type class dependencies which must be satisfied to construct this dictionary-    --+    -- | Type class dependencies which must be satisfied to construct this dictionary     , tcdDependencies :: Maybe [Constraint]-    -- |-    -- The type of this dictionary-    --+    -- | The type of this dictionary     , tcdType :: TypeClassDictionaryType-    -- |-    -- Is this instance exported by its module?-    ---    , tcdExported :: Bool     } deriving (Show, Data, Typeable)  -- |
src/Language/PureScript/Types.hs view
@@ -16,6 +16,7 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE CPP #-}  module Language.PureScript.Types where @@ -26,7 +27,9 @@  import Control.Monad.Unify import Control.Arrow (second)+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Monad ((<=<))  import Language.PureScript.Names
tests/Main.hs view
@@ -1,8 +1,7 @@ ----------------------------------------------------------------------------- -- -- Module      :  Main--- Copyright   :  (c) Phil Freeman 2013--- License     :  MIT+-- License     :  MIT (http://opensource.org/licenses/MIT) -- -- Maintainer  :  Phil Freeman <paf31@cantab.net> -- Stability   :  experimental@@ -17,6 +16,7 @@ {-# LANGUAGE TupleSections #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE CPP #-}  -- Failing tests can specify the kind of error that should be thrown with a -- @shouldFailWith declaration. For example:@@ -42,18 +42,22 @@ import Data.Char (isSpace) import Data.Maybe (mapMaybe, fromMaybe) import Data.List (isSuffixOf, sort, stripPrefix)+#if __GLASGOW_HASKELL__ < 710 import Data.Traversable (traverse)+#endif import Data.Time.Clock (UTCTime())  import qualified Data.Map as M  import Control.Monad import Control.Monad.IO.Class (liftIO)+#if __GLASGOW_HASKELL__ < 710 import Control.Applicative+#endif import Control.Arrow ((>>>))  import Control.Monad.Reader-import Control.Monad.Writer+import Control.Monad.Writer.Strict import Control.Monad.Trans.Maybe import Control.Monad.Trans.Except import Control.Monad.Error.Class@@ -62,10 +66,13 @@ import System.Process import System.FilePath import System.Directory+import qualified System.Info import qualified System.FilePath.Glob as Glob  import Text.Parsec (ParseError) +import TestsSetup+ modulesDir :: FilePath modulesDir = ".test_modules" </> "node_modules" @@ -166,11 +173,6 @@   trim =     dropWhile isSpace >>> reverse >>> dropWhile isSpace >>> reverse -findNodeProcess :: IO (Maybe String)-findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names-  where-  names = ["nodejs", "node"]- main :: IO () main = do   fetchSupportCode@@ -204,16 +206,6 @@         let fp' = fromMaybe fp $ stripPrefix (failing ++ [pathSeparator]) fp         in putStrLn $ fp' ++ ": " ++ err       exitFailure--fetchSupportCode :: IO ()-fetchSupportCode = do-  setCurrentDirectory "tests/support"-  callProcess "npm" ["install"]-  -- Sometimes we run as a root (e.g. in simple docker containers)-  -- And we are non-interactive: https://github.com/bower/bower/issues/1162-  callProcess "node_modules/.bin/bower" ["--allow-root", "install", "--config.interactive=false"]-  callProcess "node" ["setup.js"]-  setCurrentDirectory "../.."  supportModules :: [String] supportModules =
+ tests/common/TestsSetup.hs view
@@ -0,0 +1,48 @@+-----------------------------------------------------------------------------+--+-- Module      :  Main+-- License     :  MIT (http://opensource.org/licenses/MIT)+--+-- Maintainer  :  Phil Freeman <paf31@cantab.net>+-- Stability   :  experimental+-- Portability :+--+-- |+--+-----------------------------------------------------------------------------++{-# LANGUAGE CPP #-}++module TestsSetup where++import Data.Maybe (fromMaybe)++#if __GLASGOW_HASKELL__ < 710+import Control.Applicative+#endif+import Control.Monad++import Control.Monad.Trans.Maybe++import System.Process+import System.Directory+import System.Info++findNodeProcess :: IO (Maybe String)+findNodeProcess = runMaybeT . msum $ map (MaybeT . findExecutable) names+  where+  names = ["nodejs", "node"]++fetchSupportCode :: IO ()+fetchSupportCode = do+  node <- fromMaybe (error "cannot find node executable") <$> findNodeProcess+  setCurrentDirectory "tests/support"+  if System.Info.os == "mingw32"+    then callProcess "setup-win.cmd" []+    else do+      callProcess "npm" ["install"]+      -- Sometimes we run as a root (e.g. in simple docker containers)+      -- And we are non-interactive: https://github.com/bower/bower/issues/1162+      callProcess "node_modules/.bin/bower" ["--allow-root", "install", "--config.interactive=false"]+  callProcess node ["setup.js"]+  setCurrentDirectory "../.."
+ tests/support/setup-win.cmd view
@@ -0,0 +1,3 @@+@echo off+call npm install+call node_modules\.bin\bower install --config.interactive=false