source: Dev/branches/rest-dojo-ui/client/util/docscripts/includes/dojo.inc @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

  • Property svn:executable set to *
File size: 18.3 KB
Line 
1<?php
2
3require_once('lib/parser/Dojo.php');
4require_once('lib/parser/DojoPackage.php');
5
6DojoFunctionBody::$suffix = ':';
7
8$_dojo_properties_modules = array();
9
10function _dojo_get_namespaces($limit=null){
11  static $namespaces;
12  if (!isset($namespaces)) {
13    $namespaces = array();
14    $files = scandir('modules');
15    foreach ($files as $file) {
16      if (substr($file, -7) == '.module') {
17        $namespace = substr($file, 0, -7);
18        if (!$limit || in_array($namespace, $limit)) {
19          include_once('modules/' . $file);
20          $namespaces[] = substr($file, 0, -7);
21        }
22      }
23      elseif (substr($file, -18) == '.module.properties') {
24        $namespace = substr($file, 0, -18);
25        if (!$limit || in_array($namespace, $limit)) {
26          global $_dojo_properties_modules;
27          foreach (preg_split('%[\n\r]+%', file_get_contents('modules/' . $file)) as $line) {
28            list($line, ) = preg_split('%[!#]%', $line, 2);
29            if ($line = trim($line)) {
30              list($key, $line) = explode('=', $line, 2);
31              $key = str_replace('\\ ', ' ', trim($key));
32              $line = preg_replace('%^\s+%', '', $line);
33              if ($key == 'location') {
34                $line = _dojo_ensure_directory($line);
35              }
36              $_dojo_properties_modules[$namespace][$key] = $line;
37            }
38          }
39          $namespaces[] = substr($file, 0, -18);
40        }
41      }
42    }
43  }
44  return $namespaces;
45}
46
47function dojo_get_include($node, $provide) {
48  if ($node->jsdoc_project_name == $provide->title) {
49    return 'Included automatically';
50  }
51  else {
52    return 'dojo.require("%s");';
53  }
54}
55
56function _dojo_ensure_directory($directory) {
57  if (!is_dir($directory)) {
58    die("$directory is not a directory\n");
59  }
60  else {
61    if(substr($directory, -1) != '/'){
62      $directory .= '/';
63    }
64  }
65  return $directory;
66}
67
68function dojo_get_file_time($namespace, $file) {
69  if (function_exists($namespace . '_code_location')) {
70    return filectime(_dojo_ensure_directory(call_user_func($namespace . '_code_location')) . $file);
71  }
72  else {
73    global $_dojo_properties_modules;
74    return filectime($_dojo_properties_modules[$namespace]['location'] . $file);
75  }
76}
77
78function dojo_get_files($limit=null) {
79    $namespaces = _dojo_get_namespaces($limit);
80    $files = array();
81    foreach ($namespaces as $namespace) {
82        if (function_exists($namespace . '_code_location')) {
83          $location = _dojo_ensure_directory(call_user_func($namespace . '_code_location'));
84        }
85        else {
86          global $_dojo_properties_modules;
87          $location = $_dojo_properties_modules[$namespace]['location'];
88        }
89        if (!$location) die($namespace . '_code_location does not return useful result');
90        $dojo = new Dojo($namespace, $location);
91        $list = $dojo->getFileList();
92        foreach ($list as $i => $item) {
93            // Skip internationalization/tests/demos files
94            if (preg_match('%(^|/|\\\\)(nls|tests|demos)(\\\\|/)%', $item)) {
95              unset($list[$i]);
96              continue;
97            }
98            $list[$i] = array($namespace, $item);
99        }
100        $files = array_merge($files, array_values($list));
101    }
102
103    return $files;
104}
105
106function dojo_get_conditions() {
107    return array('svg', 'vml');
108}
109
110function dojo_get_environments() {
111    return array(
112        'common' => array(
113            'browser' => true
114        )
115    );
116}
117
118function dojo_get_contents($namespace, $file_name) {
119  $output = array();
120
121  if (function_exists($namespace . '_code_location')) {
122    $location = _dojo_ensure_directory(call_user_func($namespace . '_code_location'));
123  }
124  else {
125    global $_dojo_properties_modules;
126    $location = $_dojo_properties_modules[$namespace]['location'];
127  }
128
129  $dojo = new Dojo($namespace, $location);
130  $package = new DojoPackage($dojo, $file_name);
131
132  $output['#provides'] = $package->getPackageName();
133  $output['#resource'] = $package->getResourceName();
134
135  if ($output['#provides'] == 'null' || !$output['#resource'] == 'null') return array();
136
137  $compound_calls = $package->getFunctionCalls('dojo.kwCompoundRequire');
138  // Handle compound require calls
139  foreach ($compound_calls as $call) {
140    if ($call->getParameter(0)->isA(DojoObject)) {
141      $object = $call->getParameter(0)->getObject();
142      foreach ($object->getValues() as $key => $values) {
143        foreach ($values as $value) {
144          if ($value->isA(DojoArray)) {
145            foreach ($value->getArray()->getItems() as $item) {
146              if ($item->isA(DojoString)) {
147                $output['#requires'][] = array($key, $item->getString());
148              }
149              elseif ($item->isA(DojoArray)) {
150                $item = $item->getArray();
151                if ($item->getItem(0)->isA(DojoString)) {
152                  $output['#requires'][] = array($key, $item->getItem(0)->getString());
153                }
154              }
155            }
156          }
157        }
158      }
159    }
160  }
161  unset($compound_calls);
162  unset($call);
163  unset($object);
164  unset($key);
165  unset($value);
166  unset($item);
167
168  $require_calls = $package->getFunctionCalls('dojo.require');
169  // Handle dojo.require calls
170  foreach ($require_calls as $call) {
171    $require = $call->getParameter(0);
172    if ($require->isA(DojoString)) {
173      $output['#requires'][] = array('common', $require->getString());
174    }
175  }
176  unset($require_calls);
177  unset($call);
178  unset($require);
179
180  $require_if_calls = array_merge($package->getFunctionCalls('dojo.requireIf'), $package->getFunctionCalls('dojo.requireAfterIf'));
181  // Handle dojo.requireAfterIf calls
182  foreach ($require_if_calls as $call) {
183    $environment = $call->getParameter(0);
184    $require = $call->getParameter(1);
185    if ($environment && $require) {
186      $environment = $environment->getValue();
187      $require = $require->getValue();
188
189      unset($env);
190      unset($req);
191
192      if ($require instanceof DojoString) {
193        $req = $require->getValue();
194      }
195      if ($environment instanceof DojoString) {
196        $env = $environment->getValue();
197      }
198      elseif ($environment instanceof DojoVariable) {
199        $environment = $environment->getValue();
200        if ($environment == "dojo.isBrowser") {
201          $env = 'browser';
202        }
203        elseif ($environment == "dojo.render.svg.capable") {
204          $env = 'svg';
205        }
206        elseif ($environment == "dojo.render.vml.capable") {
207          $env = 'vml';
208        }
209        elseif (preg_match('%^dojox.gfx.render\s*=\s*"([a-z]+)"%', $environment, $match)) {
210          $env = $match[1];
211        }
212      }
213      if ($env && $req) {
214        $output['#requires'][] = array($env, $req);
215      }
216    }
217  }
218  unset($require_if_calls);
219  unset($call);
220  unset($environment);
221  unset($require);
222  unset($env);
223  unset($req);
224
225  $declare_calls = array_merge($package->getFunctionCalls('dojo.declare'), $package->getFunctionCalls('d.declare'), $package->getFunctionCalls('dojo.widget.defineWidget'));
226  // This closely matches dojo.widget.defineWidget as declared in src/widget/Widget.js
227  foreach ($declare_calls as $call) {
228    $init = null;
229    if ($call->getName() == 'dojo.declare' || $call->getName() == 'd.declare') {
230      $args = array($call->getParameter(0), null, $call->getParameter(1), $call->getParameter(2), $call->getParameter(3));
231      $name = $args[0]->getString();
232      if ($args[3]->isA(DojoFunctionDeclare)) {
233        $init = $args[3]->getFunction();
234      }
235      if ($args[3]->isA(DojoObject)) {
236        $args[4] = $args[3];
237        $args[3] = null;
238      }
239    }
240    else {
241      if ($call->getParameter(3)->isA(DojoString)) {
242        $args = array($call->getParameter(0), $call->getParameter(3), $call->getParameter(1), $call->getParameter(4), $call->getParameter(2));
243      }
244      else {
245        $args = array($call->getParameter(0));
246        $p = 3;
247        if ($call->getParameter(1)->isA(DojoString)) {
248          array_push($args, $call->getParameter(1), $call->getParameter(2));
249        }
250        else {
251          array_push($args, null, $call->getParameter(1));
252          $p = 2;
253        }
254        if ($call->getParameter($p)->isA(DojoFunctionDeclare)) {
255          $init = $call->getParameter($p)->getFunction();
256          array_push($args, $call->getParameter($p), $call->getParameter($p + 1));
257        }
258        else {
259          array_push($args, null, $call->getParameter($p));
260        }
261      }
262    }
263
264    $name = $args[0]->getString();
265    $output[$name]['type'] = 'Function';
266
267    // $args looks like (name, null, superclass(es), initializer, mixins)     
268    if ($args[2]->isA(DojoVariable)) {
269      $output[$name]['chains']['prototype'][] = $args[2]->getVariable();
270      $output[$name]['chains']['call'][] = $args[2]->getVariable();
271    }
272    elseif ($args[2]->isA(DojoArray)) {
273      $items = $args[2]->getArray()->getItems();
274      foreach ($items as $i => $item) {
275        if ($item->isA(DojoVariable)) {
276          $item = $item->getVariable();
277          if (!$i) {
278            $output[$name]['chains']['prototype'][] = $item;
279          }
280          else {
281            $output[$name]['mixins']['prototype'][] = $item . '.prototype';
282          }
283          $output[$name]['chains']['call'][] = $item;
284        }
285      }
286    }
287
288    unset($init);
289    if ($args[4]->isA(DojoObject)) {
290      $object = $args[4]->getObject();
291      $object->setName($name);
292      $object->setAnonymous(true);
293      $object->addBlockCommentKeySet('example');
294      foreach ($object->getValues() as $key => $values) {
295        foreach ($values as $value) {
296          $object->addBlockCommentKey($key);
297          $full_name = "$name.$key";
298          if ($value->isA(DojoFunctionDeclare)) {
299            if (($key == 'initializer' || $key == 'constructor')) {
300              $init = $value->getFunction();
301              $init->setConstructor(true);
302              continue;
303            }
304            $function = $value->getFunction($value);
305            $function->setPrototype($name);
306          }
307          $output[$full_name]['prototype'] = $name;
308        }
309      }
310      $object->rollOut($output, 'Function');
311
312      $keys = $object->getBlockCommentKeys();
313      foreach ($keys as $key) {
314        if ($key == 'example') {
315          $output[$name]['examples'] = $object->getBlockComment('example');
316        }
317        elseif ($key == 'summary') {
318          $output[$name]['summary'] = $object->getBlockComment('summary');
319        }
320        elseif ($key == 'description') {
321          $output[$name]['description'] = $object->getBlockComment('description');
322        }
323      }
324      unset($keys);
325    }
326   
327    if ($init) {
328      $init->setFunctionName($name);
329      $init->rollOut($output);
330    }
331  }
332  unset($declare_calls);
333  unset($call);
334  unset($init);
335  unset($args);
336  unset($name);
337  unset($p);
338  unset($items);
339  unset($item);
340  unset($object);
341  unset($values);
342  unset($key);
343  unset($value);
344  unset($full_name);
345  unset($function);
346
347  $inherit_calls = $package->getFunctionCalls('dojo.inherits', true);
348  foreach ($inherit_calls as $call) {
349    if ($call->getParameter(0)->isA(DojoVariable) && $call->getParameter(1)->isA(DojoVariable)) {
350      $output[$call->getParameter(0)->getVariable()]['chains']['prototype'][] = $call->getParameter(1)->getVariable();
351    }
352  }
353  unset($inherit_calls);
354  unset($call);
355
356  $mixin_calls = array_merge($package->getFunctionCalls('dojo.extend'), $package->getFunctionCalls('dojo.lang.extend', true), $package->getFunctionCalls('dojo.mixin'), $package->getFunctionCalls('dojo.lang.mixin'));
357  $declarations = $package->getFunctionDeclarations();
358  $executions = $package->getExecutedFunctions();
359  $objects = $package->getObjects();
360
361  // Since there can be chase conditions between declarations and calls, we need to find which were "swallowed" by larger blocks
362  $swallowed_mixins = $package->removeSwallowed($mixin_calls);
363  $package->removeSwallowed($executions);
364  $package->removeSwallowed($objects);
365
366  foreach ($objects as $object) {
367    $output[$object->getName()]['type'] = 'Object';
368    $object->rollOut($output);
369  }
370  unset($objects);
371  unset($object);
372
373  $aliases = $package->getAliases();
374  unset($aliases);
375
376  // Handle function declarations
377  foreach ($declarations as $declaration) {
378    $package->removeSwallowed($declaration);
379    foreach ($declaration as $declaration_instance){
380      $declaration_instance->removeSwallowedMixins($swallowed_mixins);
381      $declaration_instance->rollOut($output);
382    }
383  }
384  unset($declarations);
385  unset($declaration);
386  unset($declaration_instance);
387
388  foreach ($executions as $execution) {
389    $execution->removeSwallowedMixins($swallowed_mixins);
390    $execution->rollOut($output);
391
392    unset($execution);
393  }
394  $mixin_calls = array_merge($mixin_calls, $swallowed_mixins);
395
396  unset($swallowed_mixins);
397  unset($executions);
398
399  // Handle. dojo.lang.extend and dojo.lang.mixin calls
400  foreach ($mixin_calls as $call) {
401    $is_prototype = false;
402    if ($call->getParameter(0)->isA(DojoVariable) || $call->getParameter(0)->isA(DojoFunctionDeclare)) {
403      if ($call->getParameter(0)->isA(DojoVariable)) {
404        $object = $call->getParameter(0)->getVariable();
405        if (strpos($object, '(') !== false) {
406          continue;
407        }
408      }
409      else {
410        $function = $call->getParameter(0)->getFunction();
411        $object = $function->getFunctionName();
412        if (!$object) {
413          $object = $call->getAssignment();
414          $function->setFunctionName($object);
415        }
416        $function->setConstructor(true);
417        $function->rollOut($output);
418      }
419      $call_name = $call->getName();
420
421      if(strlen($object) > 10 && substr($object, -10) == '.prototype') {
422        $is_prototype = true;
423        $object = substr($object, 0, -10);
424      }
425      if ($call_name == 'dojo.lang.extend' || $call_name == 'dojo.extend') {
426        $is_prototype = true;
427      }
428
429      $parameters = $call->getParameters();
430      array_shift($parameters);
431      foreach ($parameters as $parameter) {
432        if ($parameter->isA(DojoObject)) {
433          $properties = $parameter->getObject();
434          $keys = $properties->getValues();
435          foreach ($keys as $key => $functions) {
436            foreach ($functions as $function) {
437              $full_variable_name = "$object.$key";
438
439              if ($is_prototype) {
440                  $output[$full_variable_name]['prototype'] = $object;
441              }
442              if ($function->isA(DojoFunctionDeclare)) {
443                $function = $function->getFunction();
444                if ($is_prototype) {
445                  $function->setPrototype($object);
446                }
447                $function->setFunctionName($full_variable_name);
448                $function->rollOut($output);
449              }
450              elseif ($function->isA(DojoObject)) {
451                $output[$full_variable_name]['type'] = 'Object';
452                $obj = $function->getObject();
453                $obj->setName($full_variable_name);
454                $obj->rollOut($output);
455              }
456              else {
457                if ($call_name == 'dojo.lang.mixin' || $call_name == 'dojo.mixin') {
458                  if (!isset($output[$full_variable_name])) {
459                    $output[$full_variable_name] = array();
460                  }
461                }
462              }
463            }
464          }
465        }
466        elseif ($parameter->isA(DojoVariable)) {
467          if ($call_name == 'dojo.lang.extend' || $call_name == 'dojo.extend') {
468            $output[$object]['mixins']['prototype'][] = $parameter->getVariable();
469          }
470          elseif ($call_name == 'dojo.lang.mixin' || $call_name == 'dojo.mixin') {
471            $output[$object]['mixins']['normal'][] = $parameter->getVariable();
472          }
473        }
474        elseif ($parameter->isA(DojoString)) {
475          print_r($call);
476          throw new Exception('Odd string');
477          $properties = $parameter->getString();
478          // Note: inherits expects to be reading from prototype values
479          if (($call_name == 'dojo.lang.extend' || $call_name == 'dojo.extend') && strpos($properties, '.prototype') !== false) {
480            $output[$object]['chains']['prototype'][] = str_replace('.prototype', '', $properties);
481          }
482          elseif (($call_name == 'dojo.lang.extend' || $call_name == 'dojo.extend') && strpos($properties, 'new ') !== false) {
483            $output[$object]['chains']['prototype'][] = str_replace('new ', '', $properties);
484          }
485          else {
486            $output[$properties]['inherits'] = $object;
487          }
488        }
489      }
490    }
491  }
492  unset($mixin_calls);
493  unset($call);
494  unset($is_prototype);
495  unset($object);
496  unset($call_name);
497  unset($properties);
498  unset($keys);
499  unset($key);
500  unset($function);
501  unset($variable_name);
502  unset($full_variable_name);
503
504  $external_variables = $package->getExternalVariables();
505  foreach ($external_variables as $external_variable) {
506    if (empty($output[$external_variable])) {
507      $output[$external_variable] = array();
508    }
509  }
510
511  // Remember, dojo.provides creates new objects if needed
512  $parts = explode('.', $output['#provides']);
513  while (count($parts)) {
514      if (!array_key_exists(implode('.', $parts), $output)) {
515          $output[implode('.', $parts)] = array('type' => 'Object');
516      }
517      array_pop($parts);
518  }
519  unset($parts);
520
521  list($project,) = explode('.', $output['#provides'], 2);
522  if ($output['#requires']) {
523    foreach ($output['#requires'] as &$require) {
524      list($require_project,) = explode('.', $require[1]);
525      if ($require_project != $project) {
526        $require[2] = $require_project;
527      }
528    }
529  }
530
531  foreach ($output as $object_name => $object) {
532    if ($object_name{0} == '#') {
533      continue;
534    }
535    $parts = explode('.', $object_name);
536    $last = array_pop($parts);
537    if ($last{0} == '_') {
538      $output[$object_name]['private'] = true;
539    }
540    if (preg_match('%\._+[^A-Z]%', implode('.', $parts), $match)) {
541        $output[$object_name]['private_parent'] = true;
542    }
543    if ($object['type'] == 'Function') {
544      if (preg_match('%^(_*)[A-Z]%', $last, $match)) {
545        if (strlen($match[1]) < 2) {
546          unset($output[$object_name]['private']);
547        }
548        $output[$object_name]['classlike'] = true;
549      }
550      elseif ($object['prototype'] && $output[$object['prototype']]) {
551        $output[$object['prototype']]['classlike'] = true;
552      }
553      elseif ($object['instance'] && $output[$object['instance']]) {
554        $output[$object['instance']]['classlike'] = true;
555      }
556    }
557    $output[$object_name]['summary'] = htmlentities($object['summary']);
558  }
559
560  $package->destroy();
561
562  return $output;
563}
564
565?>
Note: See TracBrowser for help on using the repository browser.