root / trunk / docscripts / inc / DojoFunctionDeclare.php

Revision 6373, 10.0 kB (checked in by pottedmeat, 2 years ago)

Properly handle instantiated functions. Make sure things output in function_names, aliasing, and bug fixes

Line 
1<?php
2
3require_once('DojoFunctionBody.php');
4require_once('DojoBlock.php');
5
6class DojoFunctionDeclare extends DojoBlock
7{
8  private $object = 'DojoFunctionDeclare';
9 
10  private $parameters;
11  private $function_name;
12  private $body;
13 
14  private $anonymous = false;
15  private $prototype = '';
16    private $constructor = false;
17    private $aliases = '';
18
19  public function __construct($package, $line_number = false, $position = false)
20  {
21    parent::__construct($package, $line_number, $position);
22    $this->parameters = new DojoParameters($package);
23    $this->body = new DojoFunctionBody($package);
24  }
25
26  public function getFunctionName()
27  {
28    return $this->function_name;
29  }
30   
31    public function getAliases()
32    {
33        return $this->aliases;
34    }
35 
36  public function setFunctionName($function_name)
37  {
38    $this->function_name = $function_name;
39  }
40 
41  public function setPrototype($function_name)
42  {
43    $this->prototype = $function_name;
44  }
45 
46  public function getPrototype()
47  {
48    return $this->prototype;
49  }
50 
51  public function setInstance($function_name)
52  {
53    $this->instance = $function_name;
54  }
55 
56  public function getInstance()
57  {
58    return $this->instance;
59  }
60   
61    public function setConstructor($constructor)
62    {
63        $this->constructor = $constructor;
64    }
65   
66    public function isConstructor()
67    {
68        return $this->constructor;
69    }
70 
71  public function isAnonymous()
72  {
73    return $this->anonymous;
74  }
75 
76  public function isThis()
77  {
78    return ($this->prototype || $this->instance);
79  }
80 
81  public function getThis()
82  {
83    return ($this->prototype) ? $this->prototype : $this->instance;
84  }
85 
86  public function getInstanceVariableNames()
87  {
88    return array_unique($this->body->getInstanceVariableNames());
89  }
90 
91  public function getReturnComments()
92  {
93    return array_unique($this->body->getReturnComments());
94  }
95 
96  public function getThisInheritanceCalls()
97  {
98    return array_unique($this->body->getThisInheritanceCalls());
99  }
100 
101  public function removeCodeFrom($lines){
102    for ($i = $this->start[0]; $i <= $this->end[0]; $i++) {
103      $line = $lines[$i];
104      if ($i == $this->start[0]) {
105        $lines[$i] = Text::blankOutAt($line, $this->start[1]);
106      }
107      elseif ($i == $this->end[0]) {
108        $lines[$i] = Text::blankOutAt($line, 0, $this->end[1]);
109      }
110      else {
111        $lines[$i] = Text::blankOut($line, $line);
112      }
113    }
114    return $lines;
115  }
116
117  public function build(){
118    if (!$this->start) {
119      die("DojoFunctionDeclare->build() used before setting a start position");
120    }
121    if ($this->end) {
122      return $this->end;
123    }
124
125      $lines = Text::chop($this->package->getCode(), $this->start[0], $this->start[1]);
126    $line = trim($lines[$this->start[0]]);
127    if (strpos($line, 'function') === 0) {
128      $line = substr($line, 8);
129      preg_match('%[^\s]%', $line, $match);
130      if ($match[0] != '(') {
131        $this->function_name = trim(substr($line, 0, strpos($line, '(')));
132      }
133    }
134    else {
135      $name = trim(substr($line, 0, strpos($line, '=')));
136            $extra = substr($line, strpos($line, '=') + 1);
137      if (preg_match('%^\s+new\s+%', $name, $match) || preg_match('%^\s*new\s+%', $extra, $match)) {
138        $this->anonymous = true;
139        $name = str_replace($match[0], '', $name);
140      }
141      if (($pos = strpos($name, '.prototype.')) !== false) {
142        $this->prototype = substr($name, 0, $pos);
143        $name = str_replace('.prototype', '', $name);
144      }
145      if (($pos = strpos($name, 'this.')) === 0) {
146        $this->instance = $this->getFunctionName();
147        $name = $this->getFunctionName() . "." . preg_replace('%^this\.%', '', $name);
148      }
149           
150            $full_lines = Text::chop($this->package->getCode(), $this->start[0], 0);
151            $full_line = substr($full_lines[$this->start[0]], 0, $this->start[1]);
152            if (preg_match('%(?:[a-zA-Z0-9._$]+\s*=\s*)+$%', $full_line, $matches)) {
153                $aliases = preg_split('%\s*=\s*%', $matches[0]);
154                foreach ($aliases as $alias) {
155                    $alias = trim($alias);
156                    if ($alias) {
157                        if (strpos($alias, 'this.') === 0) {
158                            print $this->getFunctionName;
159                            $alias = $this->getFunctionName() . "." . preg_replace('%^this\.%', '', $alias);
160                        }
161                        $this->aliases[] = $alias;
162                    }
163                }
164            }
165           
166            $this->function_name = $name;
167    }
168   
169    $this->parameters->setStart($this->start[0], strpos($lines[$this->start[0]], '('));
170    $end = $this->parameters->build();
171   
172    $lines = Text::chop($this->package->getCode(), $end[0], $end[1]);
173    foreach ($lines as $line_number => $line) {
174      if (($pos = strpos($line, '{')) !== false) {
175        $this->body->setStart($line_number, $pos);
176        return $this->end = $this->body->build();
177      }
178    }
179  }
180 
181  public function getParameter($pos)
182  {
183    return $this->parameters->getParameter($pos);
184  }
185 
186  public function getParameters()
187  {
188    return $this->parameters->getParameters();
189  }
190 
191  public function addBlockCommentKey($key)
192  {
193    $this->body->addBlockCommentKey($key);
194  }
195 
196  public function getBlockCommentKeys()
197  {
198    return $this->body->getBlockCommentKeys();
199  }
200 
201  public function getBlockComment($key)
202  {
203    return $this->body->getBlockComment($key);
204  }
205 
206  public function getSource()
207  {
208    return $this->body->getSource();
209  }
210 
211  public function getInstanceFunctions($function_name)
212  {
213    return $this->body->getInstanceFunctions($function_name);
214  }
215 
216  public function rollOut(&$output) {
217    $masquerading_as_function = $function_name = $this->getFunctionName();
218    if ($this->isThis()) {
219      $masquerading_as_function = $this->getThis();
220    }
221 
222    $package_name = $this->package->getPackageName();
223
224        if ($aliases = $this->getAliases()) {
225            foreach ($aliases as $alias) {
226                $output[$package_name]['meta']['functions'][$alias]['meta']['is'] = $function_name;
227            }
228        }
229        if ($this->isAnonymous()) {
230            $output[$package_name]['meta']['functions'][$function_name]['meta']['initialized'] = true;
231        }
232    $output[$package_name]['meta']['functions'][$function_name]['meta']['summary'] = '';
233
234    $parameters = $this->getParameters();
235    foreach ($parameters as $parameter) {
236      if ($parameter->isA(DojoVariable)) {
237        $output[$package_name]['meta']['functions'][$function_name]['meta']['parameters'][$parameter->getVariable()]['type'] = $parameter->getType();
238        $this->addBlockCommentKey($parameter->getVariable());
239      }
240    }
241   
242    $this->addBlockCommentKey('summary');
243    $this->addBlockCommentKey('description');
244        $this->addBlockCommentKey('returns');
245   
246    $output[$package_name]['meta']['functions'][$function_name]['meta']['src'] = $this->getSource();
247   
248    $all_variables = array();
249    $instance_variables = $this->getInstanceVariableNames();
250    foreach ($instance_variables as $instance_variable) {
251      $this->addBlockCommentKey($instance_variable);
252      $all_variables[] = $instance_variable;
253      if (isset($output[$package_name]['meta']['functions'][$masquerading_as_function]['meta']['instance_variables'])) {
254        if (!in_array($instance_variable, $output[$package_name]['meta']['functions'][$masquerading_as_function]['meta']['instance_variables'])) {
255          $output[$package_name]['meta']['functions'][$masquerading_as_function]['meta']['instance_variables'][] = $instance_variable;
256        }
257      }
258      else {
259        $output[$package_name]['meta']['functions'][$masquerading_as_function]['meta']['instance_variables'][] = $instance_variable;
260      }
261    }
262   
263    $instance_functions = $this->getInstanceFunctions($function_name);
264    foreach ($instance_functions as $instance_function) {
265      $instance_function->rollOut($output);
266            $output[$package_name]['meta']['functions'][$instance_function->getFunctionName()]['meta']['instance'] = $function_name;
267    }
268   
269    $comment_keys = $this->getBlockCommentKeys();
270    foreach ($comment_keys as $key) {
271      if ($key == 'summary') {
272        $output[$package_name]['meta']['functions'][$function_name]['meta']['summary'] = $this->getBlockComment($key);
273      }
274      elseif ($key == 'description') {
275        $output[$package_name]['meta']['functions'][$function_name]['meta']['description'] = $this->getBlockComment($key);
276      }
277            elseif ($key == 'returns') {
278                $output[$package_name]['meta']['functions'][$function_name]['extra']['returns'] = $this->getBlockComment($key);
279            }
280      elseif (in_array($key, $all_variables) && $comment = $this->getBlockComment($key)) {
281              list($type, $comment) = explode(' ', $comment, 2);
282        $type = preg_replace('%(^[^a-zA-Z0-9._$]|[^a-zA-Z0-9._$?]$)%', '', $type);
283        $output[$package_name]['meta']['functions'][$function_name]['extra']['variables'][$key]['type'] = $type;
284                $output[$package_name]['meta']['functions'][$function_name]['extra']['variables'][$key]['summary'] = $comment;
285      }
286      elseif (!empty($output[$package_name]['meta']['functions'][$function_name]['meta']['parameters']) && array_key_exists($key, $output[$package_name]['meta']['functions'][$function_name]['meta']['parameters']) && $comment = $this->getBlockComment($key)) {
287              list($type, $comment) = explode(' ', $comment, 2);
288        $type = preg_replace('%(^[^a-zA-Z0-9._$]|[^a-zA-Z0-9._$?]$)%', '', $type);
289        $output[$package_name]['meta']['functions'][$function_name]['extra']['parameters'][$key]['type'] = $type;
290                $output[$package_name]['meta']['functions'][$function_name]['extra']['parameters'][$key]['summary'] = $comment;
291      }
292    }
293 
294    $returns = $this->getReturnComments();
295    if (count($returns) == 1) {
296      $output[$package_name]['meta']['functions'][$function_name]['meta']['returns'] = $returns[0];
297    }
298    elseif ($returns) {
299      $output[$package_name]['meta']['functions'][$function_name]['meta']['returns'] = 'mixed';
300    }
301   
302    if ($calls = $this->getThisInheritanceCalls()) {
303      $output[$package_name]['meta']['functions'][$function_name]['meta']['call_chain'] = $calls;
304    }
305   
306    if ($this->getPrototype()) {
307      $output[$package_name]['meta']['functions'][$function_name]['meta']['prototype'] = $this->getPrototype();
308    }
309    if ($this->getInstance()) {
310      $output[$package_name]['meta']['functions'][$function_name]['meta']['instance'] = $this->getInstance();
311    }
312  }
313}
314
315?>
Note: See TracBrowser for help on using the browser.