on master help sign in
Add check for module alias clashes.
commite914ae0f445e8b8373c3f44a7f0c7dd880c66495 authorMatus Tejiscak <ziman@functor.sk> dateMon 27 Jan 2014, 17:18 (13 years ago) parentb634841
5 files changed+26−11
src/Idris/Chaser.hs+1−1 src/Idris/Parser.hs+19−10 test/test038/Multiple.idr+4 test/test038/expected+1 test/test038/run+1
src/Idris/Chaser.hs+1−1
@@ -132,7 +132,7 @@ buildTree built fp = btree [] fp
132132 file_in <- runIO $ readFile f
133133 file <- if lit then tclift $ unlit f file_in else return file_in
134134 (_, modules, _) <- parseImports f file
135− ms <- mapM (btree done . fst) modules
135+ ms <- mapM (btree done) [realName | (realName, alias, fc) <- modules]
136136 return (concat ms)
137137 else return [] -- IBC with no source available
138138-- (\c -> return []) -- error, can't chase modules here
src/Idris/Parser.hs+19−10
@@ -47,11 +47,13 @@ import Control.Monad
4747import Control.Monad.Error (throwError, catchError)
4848import Control.Monad.State.Strict
4949
50+import Data.Function
5051import Data.Maybe
5152import qualified Data.List.Split as Spl
5253import Data.List
5354import Data.Monoid
5455import Data.Char
56+import Data.Ord
5557import qualified Data.Map as M
5658import qualified Data.HashSet as HS
5759import qualified Data.Text as T
@@ -92,12 +94,13 @@ moduleHeader = try (do reserved "module"
9294{- | Parses an import statement
9395 Import ::= 'import' Identifier_t ';'?;
9496 -}
95−import_ :: IdrisParser (String, Maybe String)
96−import_ = do reserved "import"
97+import_ :: IdrisParser (String, Maybe String, FC)
98+import_ = do fc <- getFC
99+ reserved "import"
97100 id <- identifier
98101 newName <- optional (reserved "as" *> identifier)
99102 option ';' (lchar ';')
100− return (toPath id, toPath <$> newName)
103+ return (toPath id, toPath <$> newName, fc)
101104 <?> "import statement"
102105 where toPath = foldl1' (</>) . Spl.splitOn "."
103106
@@ -936,7 +939,7 @@ parseTactic :: IState -> String -> Result PTactic
936939parseTactic st = runparser (fullTactic defaultSyntax) st "(input)"
937940
938941-- | Parse module header and imports
939−parseImports :: FilePath -> String -> Idris ([String], [(String, Maybe String)], Maybe Delta)
942+parseImports :: FilePath -> String -> Idris ([String], [(String, Maybe String, FC)], Maybe Delta)
940943parseImports fname input
941944 = do i <- getIState
942945 case parseString (runInnerParser (evalStateT imports i)) (Directed (UTF8.fromString fname) 0 0 0 0) input of
@@ -944,7 +947,7 @@ parseImports fname input
944947 Success (x, i) -> do -- Discard state updates (there should be
945948 -- none anyway)
946949 return x
947− where imports :: IdrisParser (([String], [(String, Maybe String)], Maybe Delta), IState)
950+ where imports :: IdrisParser (([String], [(String, Maybe String, FC)], Maybe Delta), IState)
948951 imports = do whiteSpace
949952 mname <- moduleHeader
950953 ps <- many import_
@@ -1056,15 +1059,21 @@ loadSource h lidr f
10561059 file_in <- runIO $ readFile f
10571060 file <- if lidr then tclift $ unlit f file_in else return file_in
10581061 (mname, imports, pos) <- parseImports f file
1059− let modules = map fst imports
1060− modAliases = M.fromList
1061− [(prep alias, prep realName) | (realName, Just alias) <- imports]
1062+
1063+ -- process and check module aliases
1064+ let modAliases = M.fromList
1065+ [(prep alias, prep realName) | (realName, Just alias, fc) <- imports]
10621066 prep = map T.pack . reverse . Spl.splitOn "/"
1063− logLvl 3 $ "Module aliases: " ++ show (M.toList modAliases)
1067+ aliasNames = [(alias, fc) | (_, Just alias, fc) <- imports]
1068+ histogram = groupBy ((==) `on` fst) . sortBy (comparing fst) $ aliasNames
1069+ case map head . filter ((/= 1) . length) $ histogram of
1070+ [] -> logLvl 3 $ "Module aliases: " ++ show (M.toList modAliases)
1071+ (n,fc):_ -> throwError . At fc . Msg $ "import alias not unique: " ++ show n
1072+
10641073 i <- getIState
10651074 putIState (i { default_access = Hidden, module_aliases = modAliases })
10661075 clearIBC -- start a new .ibc file
1067− mapM_ (addIBC . IBCImport) modules
1076+ mapM_ (addIBC . IBCImport) [realName | (realName, alias, fc) <- imports]
10681077 let syntax = defaultSyntax{ syn_namespace = reverse mname }
10691078 ds' <- parseProg syntax f file pos
10701079 unless (null ds') $ do
test/test038/Multiple.idrnew file+4
@@ -0,0 +1,4 @@
1+module Multiple
2+
3+import Prelude.Vect as X
4+import Prelude.List as X
test/test038/expected+1
@@ -1,3 +1,4 @@
11MAIN-PASS
22Faulty.idr:6:7:When elaborating type of Faulty.fault:
33Can't disambiguate name: A.num, B.C.num
4+Multiple.idr:3:1:import alias not unique: "X"
test/test038/run+1
@@ -1,4 +1,5 @@
11#!/usr/bin/env bash
22idris $@ Main.idr --nocolour --check && echo MAIN-PASS
33idris $@ Faulty.idr --nocolour --check && echo FAULTY-PASS
4+idris $@ Multiple.idr --nocolour --check && echo MULTIPLE-PASS
45find -name \*.ibc -delete