@@ -34,7 +34,6 @@ import Control.Monad (replicateM, forM)
34import qualified Data.Map as M
34import qualified Data.Map as M
36import Language.PureScript.Names
36import Language.PureScript.Names
37−import Language.PureScript.Scope
38import Language.PureScript.Declarations
37import Language.PureScript.Declarations
39import Language.PureScript.CodeGen.Monad
38import Language.PureScript.CodeGen.Monad
40import Language.PureScript.Options
39import Language.PureScript.Options
@@ -44,6 +43,8 @@ import Language.PureScript.Optimizer
44import Language.PureScript.CodeGen.Common
43import Language.PureScript.CodeGen.Common
45import Language.PureScript.Environment
44import Language.PureScript.Environment
46+import qualified Language.PureScript.Scope as S
48-- Different types of modules which are supported
49-- Different types of modules which are supported
@@ -167,7 +168,8 @@ valueToJs _ _ _ _ = error "Invalid argument to valueToJs"
167extendObj :: JS -> [(String, JS)] -> JS
168extendObj :: JS -> [(String, JS)] -> JS
168extendObj obj sts = JSApp (JSFunction Nothing [] block) []
169extendObj obj sts = JSApp (JSFunction Nothing [] block) []
170− [newObj, key] = take 2 . map identToJs . unusedNames $ (obj, sts)
171+ [newObj, key] = take 2 . map identToJs . S.unusedNames $ used
172+ used = usedNamesJS obj ++ concatMap (usedNamesJS . snd) sts
171 jsKey = JSVar key
173 jsKey = JSVar key
172 jsNewObj = JSVar newObj
174 jsNewObj = JSVar newObj
173 block = JSBlock (objAssign:copy:extend ++ [JSReturn jsNewObj])
175 block = JSBlock (objAssign:copy:extend ++ [JSReturn jsNewObj])
@@ -247,12 +249,14 @@ qualifiedToJS _ f (Qualified _ a) = JSVar $ identToJs (f a)
247-- and guards.
249-- and guards.
249bindersToJs :: Options -> ModuleName -> Environment -> [CaseAlternative] -> [JS] -> JS
251bindersToJs :: Options -> ModuleName -> Environment -> [CaseAlternative] -> [JS] -> JS
250−bindersToJs opts m e binders vals = runGen (map identToJs (unusedNames (binders, vals))) $ do
252+bindersToJs opts m e binders vals = runGen (map identToJs (S.unusedNames usedNames)) $ do
251 valNames <- replicateM (length vals) fresh
253 valNames <- replicateM (length vals) fresh
252 jss <- forM binders $ \(CaseAlternative bs grd result) -> go valNames [JSReturn (valueToJs opts m (bindNames m (concatMap binderNames bs) e) result)] bs grd
254 jss <- forM binders $ \(CaseAlternative bs grd result) -> go valNames [JSReturn (valueToJs opts m (bindNames m (concatMap binderNames bs) e) result)] bs grd
253 return $ JSApp (JSFunction Nothing valNames (JSBlock (concat jss ++ [JSThrow (JSStringLiteral "Failed pattern match")])))
255 return $ JSApp (JSFunction Nothing valNames (JSBlock (concat jss ++ [JSThrow (JSStringLiteral "Failed pattern match")])))
258+ usedNames = concatMap usedNamesJS vals ++ concatMap S.usedNamesCaseAlternative binders
256 go :: [String] -> [JS] -> [Binder] -> Maybe Guard -> Gen [JS]
260 go :: [String] -> [JS] -> [Binder] -> Maybe Guard -> Gen [JS]
257 go _ done [] Nothing = return done
261 go _ done [] Nothing = return done
258 go _ done [] (Just cond) = return [JSIfElse (valueToJs opts m e cond) (JSBlock done) Nothing]
262 go _ done [] (Just cond) = return [JSIfElse (valueToJs opts m e cond) (JSBlock done) Nothing]
@@ -261,6 +265,20 @@ bindersToJs opts m e binders vals = runGen (map identToJs (unusedNames (binders,
261 binderToJs m e v done'' b
265 binderToJs m e v done'' b
262 go _ _ _ _ = error "Invalid arguments to bindersToJs"
266 go _ _ _ _ = error "Invalid arguments to bindersToJs"
269+-- Gather all used names appearing inside a value
271+usedNamesJS :: JS -> [Ident]
272+usedNamesJS val = nub $ everythingOnJS (++) namesJS val
274+ namesJS (JSVar name) = [Ident name]
275+ namesJS (JSFunction (Just name) args _) = Ident name : map Ident args
276+ namesJS (JSFunction Nothing args _) = map Ident args
277+ namesJS (JSVariableIntroduction name _) = [Ident name]
278+ namesJS (JSFor name _ _ _) = [Ident name]
279+ namesJS (JSForIn name _ _) = [Ident name]
265-- Generate code in the simplified Javascript intermediate representation for a pattern match
283-- Generate code in the simplified Javascript intermediate representation for a pattern match
266-- binder.
284-- binder.
@@ -342,3 +360,4 @@ isOnlyConstructor e ctor =
342 numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors e
360 numConstructors ty = length $ filter (((==) `on` typeConstructor) ty) $ M.toList $ dataConstructors e
343 typeConstructor (Qualified (Just moduleName) _, (tyCtor, _)) = (moduleName, tyCtor)
361 typeConstructor (Qualified (Just moduleName) _, (tyCtor, _)) = (moduleName, tyCtor)
344 typeConstructor _ = error "Invalid argument to isOnlyConstructor"
362 typeConstructor _ = error "Invalid argument to isOnlyConstructor"