@@ -20,8 +20,11 @@ module Language.PureScript.Parser.JS
22import Control.Applicative ((*>), (<*))
22import Control.Applicative ((*>), (<*))
23−import Control.Monad (msum)
23+import Control.Monad (forM_, when, msum)
24import Control.Monad.Error.Class (MonadError(..))
24import Control.Monad.Error.Class (MonadError(..))
25+import Control.Monad.Writer.Class (MonadWriter(..))
26+import Data.Function (on)
27+import Data.List (sortBy, groupBy)
25import Language.PureScript.Errors
28import Language.PureScript.Errors
26import Language.PureScript.Names
29import Language.PureScript.Names
27import Language.PureScript.Parser.Common
30import Language.PureScript.Parser.Common
@@ -32,13 +35,20 @@ import qualified Text.Parsec as PS
33type ForeignJS = String
36type ForeignJS = String
35−parseForeignModulesFromFiles :: (MonadError MultipleErrors m, Functor m) => [(FilePath, ForeignJS)] -> m (M.Map ModuleName (FilePath, ForeignJS))
38+parseForeignModulesFromFiles :: (Functor m, MonadError MultipleErrors m, MonadWriter MultipleErrors m)
39+ => [(FilePath, ForeignJS)]
40+ -> m (M.Map ModuleName (FilePath, ForeignJS))
36parseForeignModulesFromFiles files = do
41parseForeignModulesFromFiles files = do
37− -- TODO: emit MultipleFFIModules error when duplicates are found
38 foreigns <- parU files $ \(path, file) ->
42 foreigns <- parU files $ \(path, file) ->
39 case findModuleName (lines file) of
43 case findModuleName (lines file) of
40 Just name -> return (name, (path, file))
44 Just name -> return (name, (path, file))
41 Nothing -> throwError (errorMessage $ ErrorParsingFFIModule path)
45 Nothing -> throwError (errorMessage $ ErrorParsingFFIModule path)
46+ let grouped = groupBy ((==) `on` fst) $ sortBy (compare `on` fst) foreigns
47+ forM_ grouped $ \grp ->
48+ when (length grp > 1) $ do
49+ let mn = fst (head grp)
50+ paths = map (fst . snd) grp
51+ tell $ errorMessage $ MultipleFFIModules mn paths
42 return $ M.fromList foreigns
52 return $ M.fromList foreigns
44findModuleName :: [String] -> Maybe ModuleName
54findModuleName :: [String] -> Maybe ModuleName