1 | <?php |
---|
2 | |
---|
3 | require_once('JavaScriptFunction.php'); |
---|
4 | require_once('JavaScriptFunctionCall.php'); |
---|
5 | require_once('JavaScriptAssignment.php'); |
---|
6 | require_once('Destructable.php'); |
---|
7 | |
---|
8 | class JavaScriptStatements extends Destructable { |
---|
9 | protected $statements; |
---|
10 | protected $function_calls; |
---|
11 | protected $function_assignments; |
---|
12 | protected $prefixes = array(); |
---|
13 | |
---|
14 | public function __construct($statements) { |
---|
15 | if (!is_array($statements)) { |
---|
16 | $statements = array($statements); |
---|
17 | } |
---|
18 | $this->statements = $statements; |
---|
19 | } |
---|
20 | |
---|
21 | public function __destruct() { |
---|
22 | $this->mem_flush('statements', 'function_calls', 'function_assignments', 'prefixes'); |
---|
23 | } |
---|
24 | |
---|
25 | public function function_calls($global_scope = FALSE, $name = NULL) { |
---|
26 | $calls = $this->function_calls = isset($this->function_calls) ? $this->function_calls : $this->resolve_something('resolve_function_calls'); |
---|
27 | if ($name) { |
---|
28 | $names = array_slice(func_get_args(), 1); |
---|
29 | $filtered = array(); |
---|
30 | foreach ($names as $name) { |
---|
31 | foreach ($calls as $call) { |
---|
32 | if ($call->name() == $name) { |
---|
33 | $filtered[] = $call; |
---|
34 | } |
---|
35 | } |
---|
36 | } |
---|
37 | $calls = $filtered; |
---|
38 | } |
---|
39 | if ($global_scope) { |
---|
40 | $filtered = array(); |
---|
41 | foreach ($calls as $call) { |
---|
42 | if ($call->is_global()) { |
---|
43 | $filtered[] = $call; |
---|
44 | } |
---|
45 | } |
---|
46 | $calls = $filtered; |
---|
47 | } |
---|
48 | return $calls; |
---|
49 | } |
---|
50 | |
---|
51 | private function resolve_function_calls($statement, $parent) { |
---|
52 | if (is_object($statement) && $statement->id == '(' && $statement->arity == 'binary' && (is_object($statement->first) && $statement->first->is_lookup())) { |
---|
53 | $call = new JavaScriptFunctionCall($statement->first, $statement->second); |
---|
54 | if ($parent->id == '=') { |
---|
55 | $name = $parent->first; |
---|
56 | while ($name) { |
---|
57 | if ($name && $name->arity == 'name') { |
---|
58 | if ($name->global_scope) { |
---|
59 | $call->setAssignment($parent->first); |
---|
60 | } |
---|
61 | break; |
---|
62 | } |
---|
63 | $name = $name->first; |
---|
64 | } |
---|
65 | } |
---|
66 | return $call; |
---|
67 | } |
---|
68 | } |
---|
69 | |
---|
70 | public function assignments($global_scope=FALSE, $into_functions=TRUE) { |
---|
71 | $assignments = $this->function_assignments = isset($this->function_assignments) ? $this->function_assignments : $this->resolve_something('resolve_assignments', array(), !$into_functions); |
---|
72 | if ($global_scope) { |
---|
73 | $filtered = array(); |
---|
74 | foreach ($assignments as $item) { |
---|
75 | if ($item->is_global()) { |
---|
76 | $filtered[] = $item; |
---|
77 | } |
---|
78 | } |
---|
79 | $assignments = $filtered; |
---|
80 | } |
---|
81 | return $assignments; |
---|
82 | } |
---|
83 | |
---|
84 | private function resolve_assignments($statement, $parent) { |
---|
85 | if ($statement->id == '=' && $statement->second) { |
---|
86 | return new JavaScriptAssignment($statement->first, $statement->second); |
---|
87 | } |
---|
88 | } |
---|
89 | |
---|
90 | public function prefix($prefix_name) { |
---|
91 | return isset($this->prefixes[$prefix_name]) ? $this->prefixes[$prefix_name] : $this->resolve_something('resolve_prefix', array($prefix_name)); |
---|
92 | } |
---|
93 | |
---|
94 | private function resolve_prefix($statement, $parent, $prefix_name) { |
---|
95 | if ($statement->arity == 'statement' && $statement->value == $prefix_name) { |
---|
96 | return $statement; |
---|
97 | } |
---|
98 | } |
---|
99 | |
---|
100 | private function resolve_something($found_callback, $passed_args = array(), $seen_function=FALSE, $somethings = array(), $statements = NULL, $parent = NULL) { |
---|
101 | if (!$statements) { |
---|
102 | $statements = $this->statements; |
---|
103 | } |
---|
104 | |
---|
105 | if (!is_array($statements)) { |
---|
106 | $statements = array($statements); |
---|
107 | } |
---|
108 | |
---|
109 | foreach ($statements as $statement) { |
---|
110 | if (is_array($statement)) { |
---|
111 | foreach ($statement as $st) { |
---|
112 | if (!$seen_function || $st->id != 'function') { |
---|
113 | $somethings = $this->resolve_something($found_callback, $passed_args, $seen_function, $somethings, $st, NULL); |
---|
114 | } |
---|
115 | } |
---|
116 | continue; |
---|
117 | } |
---|
118 | |
---|
119 | if ($statement->id == 'function') { |
---|
120 | if ($seen_function) { |
---|
121 | continue; |
---|
122 | } |
---|
123 | $seen_function = TRUE; |
---|
124 | } |
---|
125 | |
---|
126 | if ($something = call_user_func_array(array($this, $found_callback), array_merge(array($statement, $parent), $passed_args))) { |
---|
127 | $somethings[] = $something; |
---|
128 | } |
---|
129 | |
---|
130 | if ($statement->first) { |
---|
131 | $somethings = $this->resolve_something($found_callback, $passed_args, $seen_function, $somethings, $statement->first, $statement); |
---|
132 | } |
---|
133 | if ($statement->second) { |
---|
134 | $somethings = $this->resolve_something($found_callback, $passed_args, $seen_function, $somethings, $statement->second, $statement); |
---|
135 | } |
---|
136 | if ($statement->third) { |
---|
137 | $somethings = $this->resolve_something($found_callback, $passed_args, $seen_function, $somethings, $statement->third, $statement); |
---|
138 | } |
---|
139 | if (!empty($statement->block)) { |
---|
140 | $somethings = $this->resolve_something($found_callback, $passed_args, $seen_function, $somethings, $statement->block, $statement); |
---|
141 | } |
---|
142 | } |
---|
143 | |
---|
144 | return $somethings; |
---|
145 | } |
---|
146 | } |
---|