git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Ensure new names are always unique
8faf3bfGary Burgess
src/Language/PureScript/Renamer.hs+15−11
@@ -18,21 +18,21 @@ module Language.PureScript.Renamer (renameInModules) where
18import Control.Applicative
18import Control.Applicative
19import Control.Monad.State
19import Control.Monad.State
20
20
21+import Data.List (find)
21import qualified Data.Map as M
22import qualified Data.Map as M
22
23
23import Language.PureScript.Declarations
24import Language.PureScript.Declarations
24import Language.PureScript.Environment
25import Language.PureScript.Environment
25import Language.PureScript.Names
26import Language.PureScript.Names
26−import Language.PureScript.Supply
27import Language.PureScript.Traversals
27import Language.PureScript.Traversals
28
28
29−type Rename = StateT (M.Map Ident Ident) Supply
29+type Rename = State (M.Map Ident Ident)
30
30
31-- |
31-- |
32−-- Create a Rename state value for a scope from a list of idents.
32+-- Runs renaming starting with a list of idents for the initial scope.
33--
33--
34−createScope :: [Ident] -> M.Map Ident Ident
34+runRename :: [Ident] -> Rename a -> a
35−createScope scopeNames = M.fromList (zip scopeNames scopeNames)
35+runRename scope = flip evalState (M.fromList $ zip scope scope)
36
36
37-- |
37-- |
38-- Creates a new renaming scope using the current as a basis. Used to backtrack
38-- Creates a new renaming scope using the current as a basis. Used to backtrack
@@ -47,12 +47,16 @@ newScope x = get >>= lift . evalStateT x
47--
47--
48updateScope :: Ident -> Rename Ident
48updateScope :: Ident -> Rename Ident
49updateScope name = do
49updateScope name = do
50− name' <- gets $ M.lookup name
50+ scope <- get
51− name'' <- case name' of
51+ name' <- case M.lookup name scope of
52+ Just _ -> do
52− Just _ -> Ident . (runIdent name ++) <$> lift freshName
53+ let newNames = map (\i -> Ident (runIdent name ++ "_" ++ show (i :: Int))) [1..]
54+ let (Just newName) = find (\nn -> M.lookup nn scope == Nothing) newNames
55+ modify $ M.insert newName newName
56+ return newName
53 Nothing -> return name
57 Nothing -> return name
54− modify $ M.insert name name''
58+ modify $ M.insert name name'
55− return name''
59+ return name'
56
60
57-- |
61-- |
58-- Finds the new name to use for an ident.
62-- Finds the new name to use for an ident.
@@ -86,7 +90,7 @@ renameInModules = map go
86 go :: Module -> Module
90 go :: Module -> Module
87 go (Module mn decls exps) = Module mn (renameInDecl' (findDeclIdents decls) `map` decls) exps
91 go (Module mn decls exps) = Module mn (renameInDecl' (findDeclIdents decls) `map` decls) exps
88 renameInDecl' :: [Ident] -> Declaration -> Declaration
92 renameInDecl' :: [Ident] -> Declaration -> Declaration
89− renameInDecl' scope = evalSupply 1 . flip evalStateT (createScope scope) . renameInDecl True
93+ renameInDecl' scope = runRename scope . renameInDecl True
90
94
91-- |
95-- |
92-- Renames within a declaration. isTopLevel is used to determine whether the
96-- Renames within a declaration. isTopLevel is used to determine whether the