-- | -- Common functions used by the various optimizer phases -- module Language.PureScript.CodeGen.JS.Optimizer.Common where import Prelude.Compat import Data.Maybe (fromMaybe) import Language.PureScript.Crash import Language.PureScript.CodeGen.JS.AST applyAll :: [a -> a] -> a -> a applyAll = foldl1 (.) replaceIdent :: String -> JS -> JS -> JS replaceIdent var1 js = everywhereOnJS replace where replace (JSVar _ var2) | var1 == var2 = js replace other = other replaceIdents :: [(String, JS)] -> JS -> JS replaceIdents vars = everywhereOnJS replace where replace v@(JSVar _ var) = fromMaybe v $ lookup var vars replace other = other isReassigned :: String -> JS -> Bool isReassigned var1 = everythingOnJS (||) check where check :: JS -> Bool check (JSFunction _ _ args _) | var1 `elem` args = True check (JSVariableIntroduction _ arg _) | var1 == arg = True check (JSAssignment _ (JSVar _ arg) _) | var1 == arg = True check (JSFor _ arg _ _ _) | var1 == arg = True check (JSForIn _ arg _ _) | var1 == arg = True check _ = False isRebound :: JS -> JS -> Bool isRebound js d = any (\v -> isReassigned v d || isUpdated v d) (everythingOnJS (++) variablesOf js) where variablesOf (JSVar _ var) = [var] variablesOf _ = [] isUsed :: String -> JS -> Bool isUsed var1 = everythingOnJS (||) check where check :: JS -> Bool check (JSVar _ var2) | var1 == var2 = True check (JSAssignment _ target _) | var1 == targetVariable target = True check _ = False targetVariable :: JS -> String targetVariable (JSVar _ var) = var targetVariable (JSAccessor _ _ tgt) = targetVariable tgt targetVariable (JSIndexer _ _ tgt) = targetVariable tgt targetVariable _ = internalError "Invalid argument to targetVariable" isUpdated :: String -> JS -> Bool isUpdated var1 = everythingOnJS (||) check where check :: JS -> Bool check (JSAssignment _ target _) | var1 == targetVariable target = True check _ = False removeFromBlock :: ([JS] -> [JS]) -> JS -> JS removeFromBlock go (JSBlock ss sts) = JSBlock ss (go sts) removeFromBlock _ js = js isFn :: (String, String) -> JS -> Bool isFn (moduleName, fnName) (JSAccessor _ x (JSVar _ y)) = x == fnName && y == moduleName isFn (moduleName, fnName) (JSIndexer _ (JSStringLiteral _ x) (JSVar _ y)) = x == fnName && y == moduleName isFn _ _ = False isDict :: (String, String) -> JS -> Bool isDict (moduleName, dictName) (JSAccessor _ x (JSVar _ y)) = x == dictName && y == moduleName isDict _ _ = False isDict' :: [(String, String)] -> JS -> Bool isDict' xs js = any (`isDict` js) xs