module Language.ECMAScript3.Analysis.Environment
{-# DEPRECATED "Use 'Language.ECMAScript.Analysis.LexicalEnvironment'\
\ from package 'language-ecmascript-analysis'" #-}
( env
, localVars
, EnvTree (..)
) where
import Data.List
import Data.Maybe
import qualified Data.Map as M
import Data.Map (Map)
import qualified Data.Set as S
import Data.Set (Set)
import Text.ParserCombinators.Parsec.Pos (SourcePos)
import Language.ECMAScript3.Syntax
data Partial = Partial {
Partial -> Map String SourcePos
partialLocals :: M.Map String SourcePos,
Partial -> Map String SourcePos
partialReferences :: M.Map String SourcePos,
Partial -> [Partial]
partialNested :: [Partial]
}
empty :: Partial
empty :: Partial
empty = Map String SourcePos
-> Map String SourcePos -> [Partial] -> Partial
Partial Map String SourcePos
forall k a. Map k a
M.empty Map String SourcePos
forall k a. Map k a
M.empty []
ref :: Id SourcePos -> Partial
ref :: Id SourcePos -> Partial
ref (Id p :: SourcePos
p v :: String
v) = Map String SourcePos
-> Map String SourcePos -> [Partial] -> Partial
Partial Map String SourcePos
forall k a. Map k a
M.empty (String -> SourcePos -> Map String SourcePos
forall k a. k -> a -> Map k a
M.singleton String
v SourcePos
p) []
decl :: Id SourcePos -> Partial
decl :: Id SourcePos -> Partial
decl (Id p :: SourcePos
p v :: String
v) = Map String SourcePos
-> Map String SourcePos -> [Partial] -> Partial
Partial (String -> SourcePos -> Map String SourcePos
forall k a. k -> a -> Map k a
M.singleton String
v SourcePos
p) Map String SourcePos
forall k a. Map k a
M.empty []
nest :: Partial -> Partial
nest :: Partial -> Partial
nest partial :: Partial
partial = Map String SourcePos
-> Map String SourcePos -> [Partial] -> Partial
Partial Map String SourcePos
forall k a. Map k a
M.empty Map String SourcePos
forall k a. Map k a
M.empty [Partial
partial]
unions :: [Partial] -> Partial
unions :: [Partial] -> Partial
unions ps :: [Partial]
ps = Map String SourcePos
-> Map String SourcePos -> [Partial] -> Partial
Partial ([Map String SourcePos] -> Map String SourcePos
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions ((Partial -> Map String SourcePos)
-> [Partial] -> [Map String SourcePos]
forall a b. (a -> b) -> [a] -> [b]
map Partial -> Map String SourcePos
partialLocals [Partial]
ps))
([Map String SourcePos] -> Map String SourcePos
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions ((Partial -> Map String SourcePos)
-> [Partial] -> [Map String SourcePos]
forall a b. (a -> b) -> [a] -> [b]
map Partial -> Map String SourcePos
partialReferences [Partial]
ps))
((Partial -> [Partial]) -> [Partial] -> [Partial]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Partial -> [Partial]
partialNested [Partial]
ps)
javascript :: JavaScript SourcePos -> Partial
javascript :: JavaScript SourcePos -> Partial
javascript (Script _ ss :: [Statement SourcePos]
ss) = [Partial] -> Partial
unions ((Statement SourcePos -> Partial)
-> [Statement SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Statement SourcePos -> Partial
stmt [Statement SourcePos]
ss)
lvalue :: LValue SourcePos -> Partial
lvalue :: LValue SourcePos -> Partial
lvalue lv :: LValue SourcePos
lv = case LValue SourcePos
lv of
LVar p :: SourcePos
p x :: String
x -> Id SourcePos -> Partial
ref (SourcePos -> String -> Id SourcePos
forall a. a -> String -> Id a
Id SourcePos
p String
x)
LDot _ e :: Expression SourcePos
e _ -> Expression SourcePos -> Partial
expr Expression SourcePos
e
LBracket _ e1 :: Expression SourcePos
e1 e2 :: Expression SourcePos
e2 -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e1, Expression SourcePos -> Partial
expr Expression SourcePos
e2]
expr :: Expression SourcePos -> Partial
expr :: Expression SourcePos -> Partial
expr e :: Expression SourcePos
e = case Expression SourcePos
e of
StringLit _ _ -> Partial
empty
RegexpLit {} -> Partial
empty
NumLit _ _ -> Partial
empty
IntLit _ _ -> Partial
empty
BoolLit _ _ -> Partial
empty
NullLit _ -> Partial
empty
ArrayLit _ es :: [Expression SourcePos]
es -> [Partial] -> Partial
unions ((Expression SourcePos -> Partial)
-> [Expression SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Expression SourcePos -> Partial
expr [Expression SourcePos]
es)
ObjectLit _ props :: [(Prop SourcePos, Expression SourcePos)]
props -> [Partial] -> Partial
unions (((Prop SourcePos, Expression SourcePos) -> Partial)
-> [(Prop SourcePos, Expression SourcePos)] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map (Expression SourcePos -> Partial
expr(Expression SourcePos -> Partial)
-> ((Prop SourcePos, Expression SourcePos) -> Expression SourcePos)
-> (Prop SourcePos, Expression SourcePos)
-> Partial
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Prop SourcePos, Expression SourcePos) -> Expression SourcePos
forall a b. (a, b) -> b
snd) [(Prop SourcePos, Expression SourcePos)]
props)
ThisRef _ -> Partial
empty
VarRef _ id :: Id SourcePos
id -> Partial
empty
DotRef _ e :: Expression SourcePos
e _ -> Expression SourcePos -> Partial
expr Expression SourcePos
e
BracketRef _ e1 :: Expression SourcePos
e1 e2 :: Expression SourcePos
e2 -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e1, Expression SourcePos -> Partial
expr Expression SourcePos
e2]
NewExpr _ e1 :: Expression SourcePos
e1 es :: [Expression SourcePos]
es -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e1, [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Expression SourcePos -> Partial)
-> [Expression SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Expression SourcePos -> Partial
expr [Expression SourcePos]
es]
PrefixExpr _ _ e :: Expression SourcePos
e -> Expression SourcePos -> Partial
expr Expression SourcePos
e
InfixExpr _ _ e1 :: Expression SourcePos
e1 e2 :: Expression SourcePos
e2 -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e1, Expression SourcePos -> Partial
expr Expression SourcePos
e2]
CondExpr _ e1 :: Expression SourcePos
e1 e2 :: Expression SourcePos
e2 e3 :: Expression SourcePos
e3 -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e1, Expression SourcePos -> Partial
expr Expression SourcePos
e2, Expression SourcePos -> Partial
expr Expression SourcePos
e3]
AssignExpr _ _ lv :: LValue SourcePos
lv e :: Expression SourcePos
e -> [Partial] -> Partial
unions [LValue SourcePos -> Partial
lvalue LValue SourcePos
lv, Expression SourcePos -> Partial
expr Expression SourcePos
e]
UnaryAssignExpr _ _ lv :: LValue SourcePos
lv -> LValue SourcePos -> Partial
lvalue LValue SourcePos
lv
ListExpr _ es :: [Expression SourcePos]
es -> [Partial] -> Partial
unions ((Expression SourcePos -> Partial)
-> [Expression SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Expression SourcePos -> Partial
expr [Expression SourcePos]
es)
CallExpr _ e :: Expression SourcePos
e es :: [Expression SourcePos]
es -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e, [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Expression SourcePos -> Partial)
-> [Expression SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Expression SourcePos -> Partial
expr [Expression SourcePos]
es]
FuncExpr _ _ args :: [Id SourcePos]
args ss :: [Statement SourcePos]
ss -> Partial -> Partial
nest (Partial -> Partial) -> Partial -> Partial
forall a b. (a -> b) -> a -> b
$ [Partial] -> Partial
unions [[Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Id SourcePos -> Partial) -> [Id SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Id SourcePos -> Partial
decl [Id SourcePos]
args
,[Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Statement SourcePos -> Partial)
-> [Statement SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Statement SourcePos -> Partial
stmt [Statement SourcePos]
ss]
caseClause :: CaseClause SourcePos -> Partial
caseClause :: CaseClause SourcePos -> Partial
caseClause cc :: CaseClause SourcePos
cc = case CaseClause SourcePos
cc of
CaseClause _ e :: Expression SourcePos
e ss :: [Statement SourcePos]
ss -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e, [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Statement SourcePos -> Partial)
-> [Statement SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Statement SourcePos -> Partial
stmt [Statement SourcePos]
ss]
CaseDefault _ ss :: [Statement SourcePos]
ss -> [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Statement SourcePos -> Partial)
-> [Statement SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Statement SourcePos -> Partial
stmt [Statement SourcePos]
ss
catchClause :: CatchClause SourcePos -> Partial
catchClause :: CatchClause SourcePos -> Partial
catchClause (CatchClause _ id :: Id SourcePos
id s :: Statement SourcePos
s) = [Partial] -> Partial
unions [Id SourcePos -> Partial
decl Id SourcePos
id, Statement SourcePos -> Partial
stmt Statement SourcePos
s]
varDecl :: VarDecl SourcePos -> Partial
varDecl :: VarDecl SourcePos -> Partial
varDecl (VarDecl _ id :: Id SourcePos
id Nothing) = Id SourcePos -> Partial
decl Id SourcePos
id
varDecl (VarDecl _ id :: Id SourcePos
id (Just e :: Expression SourcePos
e)) = [Partial] -> Partial
unions [Id SourcePos -> Partial
decl Id SourcePos
id, Expression SourcePos -> Partial
expr Expression SourcePos
e]
forInit :: ForInit SourcePos -> Partial
forInit :: ForInit SourcePos -> Partial
forInit fi :: ForInit SourcePos
fi = case ForInit SourcePos
fi of
NoInit -> Partial
empty
VarInit ds :: [VarDecl SourcePos]
ds -> [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (VarDecl SourcePos -> Partial) -> [VarDecl SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map VarDecl SourcePos -> Partial
varDecl [VarDecl SourcePos]
ds
ExprInit e :: Expression SourcePos
e -> Expression SourcePos -> Partial
expr Expression SourcePos
e
forInInit :: ForInInit SourcePos -> Partial
forInInit :: ForInInit SourcePos -> Partial
forInInit (ForInVar id :: Id SourcePos
id) = Id SourcePos -> Partial
decl Id SourcePos
id
forInInit (ForInLVal lv :: LValue SourcePos
lv) = LValue SourcePos -> Partial
lvalue LValue SourcePos
lv
stmt :: Statement SourcePos -> Partial
stmt :: Statement SourcePos -> Partial
stmt s :: Statement SourcePos
s = case Statement SourcePos
s of
BlockStmt _ ss :: [Statement SourcePos]
ss -> [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Statement SourcePos -> Partial)
-> [Statement SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Statement SourcePos -> Partial
stmt [Statement SourcePos]
ss
EmptyStmt _ -> Partial
empty
ExprStmt _ e :: Expression SourcePos
e -> Expression SourcePos -> Partial
expr Expression SourcePos
e
IfStmt _ e :: Expression SourcePos
e s1 :: Statement SourcePos
s1 s2 :: Statement SourcePos
s2 -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e, Statement SourcePos -> Partial
stmt Statement SourcePos
s1, Statement SourcePos -> Partial
stmt Statement SourcePos
s2]
IfSingleStmt _ e :: Expression SourcePos
e s :: Statement SourcePos
s -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e, Statement SourcePos -> Partial
stmt Statement SourcePos
s]
SwitchStmt _ e :: Expression SourcePos
e cases :: [CaseClause SourcePos]
cases -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e, [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (CaseClause SourcePos -> Partial)
-> [CaseClause SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map CaseClause SourcePos -> Partial
caseClause [CaseClause SourcePos]
cases]
WhileStmt _ e :: Expression SourcePos
e s :: Statement SourcePos
s -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e, Statement SourcePos -> Partial
stmt Statement SourcePos
s]
DoWhileStmt _ s :: Statement SourcePos
s e :: Expression SourcePos
e -> [Partial] -> Partial
unions [Statement SourcePos -> Partial
stmt Statement SourcePos
s, Expression SourcePos -> Partial
expr Expression SourcePos
e]
BreakStmt _ _ -> Partial
empty
ContinueStmt _ _ -> Partial
empty
LabelledStmt _ _ s :: Statement SourcePos
s -> Statement SourcePos -> Partial
stmt Statement SourcePos
s
ForInStmt _ fii :: ForInInit SourcePos
fii e :: Expression SourcePos
e s :: Statement SourcePos
s -> [Partial] -> Partial
unions [ForInInit SourcePos -> Partial
forInInit ForInInit SourcePos
fii, Expression SourcePos -> Partial
expr Expression SourcePos
e, Statement SourcePos -> Partial
stmt Statement SourcePos
s]
ForStmt _ fi :: ForInit SourcePos
fi me1 :: Maybe (Expression SourcePos)
me1 me2 :: Maybe (Expression SourcePos)
me2 s :: Statement SourcePos
s ->
[Partial] -> Partial
unions [ForInit SourcePos -> Partial
forInit ForInit SourcePos
fi, Partial
-> (Expression SourcePos -> Partial)
-> Maybe (Expression SourcePos)
-> Partial
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Partial
empty Expression SourcePos -> Partial
expr Maybe (Expression SourcePos)
me1, Partial
-> (Expression SourcePos -> Partial)
-> Maybe (Expression SourcePos)
-> Partial
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Partial
empty Expression SourcePos -> Partial
expr Maybe (Expression SourcePos)
me2, Statement SourcePos -> Partial
stmt Statement SourcePos
s]
TryStmt _ s :: Statement SourcePos
s mcatch :: Maybe (CatchClause SourcePos)
mcatch ms :: Maybe (Statement SourcePos)
ms ->
[Partial] -> Partial
unions [Statement SourcePos -> Partial
stmt Statement SourcePos
s, Partial
-> (CatchClause SourcePos -> Partial)
-> Maybe (CatchClause SourcePos)
-> Partial
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Partial
empty CatchClause SourcePos -> Partial
catchClause Maybe (CatchClause SourcePos)
mcatch, Partial
-> (Statement SourcePos -> Partial)
-> Maybe (Statement SourcePos)
-> Partial
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Partial
empty Statement SourcePos -> Partial
stmt Maybe (Statement SourcePos)
ms]
ThrowStmt _ e :: Expression SourcePos
e -> Expression SourcePos -> Partial
expr Expression SourcePos
e
ReturnStmt _ me :: Maybe (Expression SourcePos)
me -> Partial
-> (Expression SourcePos -> Partial)
-> Maybe (Expression SourcePos)
-> Partial
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Partial
empty Expression SourcePos -> Partial
expr Maybe (Expression SourcePos)
me
WithStmt _ e :: Expression SourcePos
e s :: Statement SourcePos
s -> [Partial] -> Partial
unions [Expression SourcePos -> Partial
expr Expression SourcePos
e, Statement SourcePos -> Partial
stmt Statement SourcePos
s]
VarDeclStmt _ decls :: [VarDecl SourcePos]
decls -> [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (VarDecl SourcePos -> Partial) -> [VarDecl SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map VarDecl SourcePos -> Partial
varDecl [VarDecl SourcePos]
decls
FunctionStmt _ fnId :: Id SourcePos
fnId args :: [Id SourcePos]
args ss :: [Statement SourcePos]
ss ->
[Partial] -> Partial
unions [Id SourcePos -> Partial
decl Id SourcePos
fnId, Partial -> Partial
nest (Partial -> Partial) -> Partial -> Partial
forall a b. (a -> b) -> a -> b
$ [Partial] -> Partial
unions [[Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Id SourcePos -> Partial) -> [Id SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Id SourcePos -> Partial
decl [Id SourcePos]
args,
[Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Statement SourcePos -> Partial)
-> [Statement SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Statement SourcePos -> Partial
stmt [Statement SourcePos]
ss]]
data EnvTree = EnvTree (M.Map String SourcePos) [EnvTree]
makeEnvTree :: Map String SourcePos
-> Partial
-> (EnvTree,Map String SourcePos)
makeEnvTree :: Map String SourcePos -> Partial -> (EnvTree, Map String SourcePos)
makeEnvTree enclosing :: Map String SourcePos
enclosing (Partial locals :: Map String SourcePos
locals references :: Map String SourcePos
references nested :: [Partial]
nested) = (EnvTree
tree,Map String SourcePos
globals) where
nestedResults :: [(EnvTree, Map String SourcePos)]
nestedResults = (Partial -> (EnvTree, Map String SourcePos))
-> [Partial] -> [(EnvTree, Map String SourcePos)]
forall a b. (a -> b) -> [a] -> [b]
map (Map String SourcePos -> Partial -> (EnvTree, Map String SourcePos)
makeEnvTree (Map String SourcePos
locals Map String SourcePos
-> Map String SourcePos -> Map String SourcePos
forall k a. Ord k => Map k a -> Map k a -> Map k a
`M.union` Map String SourcePos
enclosing)) [Partial]
nested
tree :: EnvTree
tree = Map String SourcePos -> [EnvTree] -> EnvTree
EnvTree Map String SourcePos
locals (((EnvTree, Map String SourcePos) -> EnvTree)
-> [(EnvTree, Map String SourcePos)] -> [EnvTree]
forall a b. (a -> b) -> [a] -> [b]
map (EnvTree, Map String SourcePos) -> EnvTree
forall a b. (a, b) -> a
fst [(EnvTree, Map String SourcePos)]
nestedResults)
globals' :: Map String SourcePos
globals' = (Map String SourcePos
references Map String SourcePos
-> Map String SourcePos -> Map String SourcePos
forall k a b. Ord k => Map k a -> Map k b -> Map k a
`M.difference` Map String SourcePos
locals) Map String SourcePos
-> Map String SourcePos -> Map String SourcePos
forall k a b. Ord k => Map k a -> Map k b -> Map k a
`M.difference` Map String SourcePos
enclosing
globals :: Map String SourcePos
globals = [Map String SourcePos] -> Map String SourcePos
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions (Map String SourcePos
globals'Map String SourcePos
-> [Map String SourcePos] -> [Map String SourcePos]
forall a. a -> [a] -> [a]
:((EnvTree, Map String SourcePos) -> Map String SourcePos)
-> [(EnvTree, Map String SourcePos)] -> [Map String SourcePos]
forall a b. (a -> b) -> [a] -> [b]
map (EnvTree, Map String SourcePos) -> Map String SourcePos
forall a b. (a, b) -> b
snd [(EnvTree, Map String SourcePos)]
nestedResults)
env :: Map String SourcePos
-> [Statement SourcePos]
-> (EnvTree,Map String SourcePos)
env :: Map String SourcePos
-> [Statement SourcePos] -> (EnvTree, Map String SourcePos)
env globals :: Map String SourcePos
globals program :: [Statement SourcePos]
program = Map String SourcePos -> Partial -> (EnvTree, Map String SourcePos)
makeEnvTree Map String SourcePos
globals ([Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Statement SourcePos -> Partial)
-> [Statement SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Statement SourcePos -> Partial
stmt [Statement SourcePos]
program)
localVars :: [Statement SourcePos]
-> [(String, SourcePos)]
localVars :: [Statement SourcePos] -> [(String, SourcePos)]
localVars body :: [Statement SourcePos]
body = Map String SourcePos -> [(String, SourcePos)]
forall k a. Map k a -> [(k, a)]
M.toList Map String SourcePos
locals where
Partial locals :: Map String SourcePos
locals _ _ = [Partial] -> Partial
unions ([Partial] -> Partial) -> [Partial] -> Partial
forall a b. (a -> b) -> a -> b
$ (Statement SourcePos -> Partial)
-> [Statement SourcePos] -> [Partial]
forall a b. (a -> b) -> [a] -> [b]
map Statement SourcePos -> Partial
stmt [Statement SourcePos]
body