source: Dev/branches/rest-dojo-ui/client/util/docscripts/generate.php @ 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: 12.6 KB
Line 
1<?php
2
3# php generate.php
4# -- Runs everything in the modules directory
5# php generate.php dojo
6# php generate.php dijit
7# php generate.php dojox
8# -- Runs only the module starting with custom, custom2, etc.
9# php generate.php --store=file
10# php generate.php --store=mysql --db_host=localhost --db_user=api --db_password=password --db_name=api
11# -- Specifies storage type. "hash", "file" and "resource" currently supported
12# php generate.php --serialize=xml,json
13# -- Comma-separated list of serializations. "xml" and "json" supported
14# php generate.php --outfile=custom-api custom
15# -- Runs the custom module, serializes to custom-api.xml
16
17if (isset($_SERVER['HTTP_HOST'])) {
18  die('Run from command line');
19}
20
21ini_set('memory_limit', '256M');
22ini_set('display_errors', 1);
23error_reporting(E_ALL ^ E_NOTICE);
24$debug = true;
25
26require_once('lib/parser2/dojo2.inc');
27
28$keys = array();
29$namespaces = array();
30
31// Do this in 3 parts
32// 1. Turn all variables into single objects
33// 2. Internalize class members
34// 3. Serialize objects
35
36$args = array();
37$kwargs = array();
38$clean = false;
39$db_host = 'localhost';
40$db_user = 'root';
41$db_password = '';
42$db_name = 'generate';
43foreach (array_slice($argv, 1) as $arg) {
44  if ($arg{0} == '-') {
45    if (preg_match('%^--(outfile|store|serialize|db_host|db_user|db_password|db_name)=([^ ]+)$%', $arg, $match)) {
46      if ($match[1] == 'db_host') {
47        $db_host = $match[2];
48      }
49      elseif ($match[1] == 'db_user') {
50        $db_user = $match[2];
51      }
52      elseif ($match[1] == 'db_password') {
53        $db_password = $match[2];
54      }
55      elseif ($match[1] == 'db_name') {
56        $db_name == $match[2];
57      }
58      elseif ($match[1] == 'serialize') {
59        foreach (explode(',', $match[2]) as $serialize_type) {
60          $kwargs[$match[1]][$serialize_type] = true;
61        }
62      }
63      else {
64        $kwargs[$match[1]] = $match[2];
65      }
66    }
67    elseif ($arg == '--clean') {
68      $clean = true;
69    }
70    else {
71      die("ERROR: Unrecognized argument: $arg\n");
72    }
73  }
74  else {
75    $args[] = $arg;
76  }
77}
78if (!isset($kwargs['serialize'])) {
79  $kwargs['serialize'] = array(
80    'json' => true,
81    'xml' => true
82  );
83}
84// Use hash storage by default
85if (!isset($kwargs['store'])) {
86  $kwargs['store'] = 'hash';
87}
88
89require_once('lib/generator/' . $kwargs['store'] . '/Freezer.php');
90require_once('lib/generator/' . $kwargs['store'] . '/Serializer.php');
91require_once('lib/generator/JsonSerializer.php');
92require_once('lib/generator/XmlSerializer.php');
93
94if ($clean) {
95  Freezer::clean('cache', 'nodes');
96  Freezer::clean('cache', 'resources');
97  if ($kwargs['outfile']) {
98    if (isset($kwargs['serialize']['json'])) {
99      JsonSerializer::clean('cache', 'json', $kwargs['outfile']);
100    }
101    if (isset($kwargs['serialize']['xml'])) {
102      XmlSerializer::clean('cache', 'xml', $kwargs['outfile']);
103    }
104  }
105  else {
106    if (isset($kwargs['serialize']['json'])) {
107      JsonSerializer::clean('cache', 'json');
108    }
109    if (isset($kwargs['serialize']['xml'])) {
110      XmlSerializer::clean('cache', 'xml');
111    }
112  }
113}
114
115$files = dojo_get_files($args);
116$nodes = new Freezer('cache', 'nodes');
117$resources = new Freezer('cache', 'resources');
118
119print "=== PARSING FILES ===\n";
120flush();
121
122foreach ($files as $set){
123  list($namespace, $file) = $set;
124  if (!$namespaces[$namespace]) {
125    $namespaces[$namespace] = true;
126  }
127
128  $ctime = dojo_get_file_time($namespace, $file);
129  if ($ctime == $resources->open($namespace . '%' . $file, null)) {
130    continue;
131  }
132
133  printf("%-100s %6s KB\n", $namespace . '/' . $file, number_format(memory_get_usage() / 1024));
134  flush();
135
136  $contents = dojo_get_contents($namespace, $file);
137
138  $provides = $contents['#provides'];
139  unset($contents['#provides']);
140  $resource = $contents['#resource'];
141  unset($contents['#resource']);
142  $requires = $contents['#requires'];
143  unset($contents['#requires']);
144
145  // set by debugging in parsing
146  unset($contents['#debug']);
147  unset($contents['#unwrapped_source']);
148  unset($contents['#raw_source']);
149
150  foreach ($contents as $var => $content) {
151    foreach ($content as $key_key => $key_value) {
152      $key_type = 'undefined';
153      if (is_numeric($key_value)) {
154        $key_type = 'numeric';
155      }elseif(is_array($key_value)) {
156        $key_type = 'array';
157      }elseif(is_bool($key_value)) {
158        $key_type = 'bool';
159      }elseif(is_string($key_value)) {
160        $key_type = 'string';
161      }
162      $keys[$key_key][] = $key_type;
163      $keys[$key_key] = array_unique($keys[$key_key]);
164    }
165
166    $node = $nodes->open($var, array());
167
168    $new = !empty($node);
169
170    // Handle file-level information
171    if ($provides && (!is_array($node['#provides']) || !in_array($provides, $node['#provides']))) {
172      $node['#provides'][] = $provides;
173    }
174
175    if (!is_array($node['#namespaces']) || !in_array($namespace, $node['#namespaces'])) {
176      $node['#namespaces'][] = $namespace;
177    }
178
179    $node['#resource'][] = "$namespace/$resource";
180
181    if (trim($content['type']) && (empty($node['type']) || $content['type'] != 'Object')) {
182      $node['type'] = $content['type'];
183    }
184
185    if (!empty($content['tags'])) {
186      $node['tags'] = $content['tags'];
187    }
188
189    if (!empty($content['private'])) {
190      $node['private'] = $content['private'];
191    }
192
193    if (!empty($content['private_parent'])) {
194      $node['private_parent'] = $content['private_parent'];
195    }
196
197    if (trim($content['summary'])) {
198      $node['summary'] = $content['summary'];
199    }
200
201    if (trim($content['description'])) {
202      $node['description'] = $content['description'];
203    }
204
205    if (trim($content['exceptions'])) {
206      $node['exceptions'] = $content['exceptions'];
207    }
208
209    if ($content['private']) {
210      $node['private'] = $content['private'];
211    }
212
213    if ($content['private_parent']) {
214      $node['private_parent'] = $content['private_parent'];
215    }
216
217    if (is_array($content['alias'])) {
218      foreach ($content['alias'] as $alias) {
219        $node['alias'] = $alias;
220      }
221    }
222
223    if (is_array($content['examples'])) {
224      foreach ($content['examples'] as $example) {
225        if (!is_array($node['examples']) || !in_array($example, $node['examples'])) {
226          $node['examples'][] = $example;
227        }
228      }
229    }
230
231    if ($content['instance']) {
232      $node['instance'] = $content['instance'];
233    }
234   
235    if ($content['prototype']) {
236      $node['prototype'] = $content['prototype'];
237    }
238
239    if (!is_array($node['returns'])) {
240      $node['returns'] = array();
241    }
242    if (trim($content['returns'])) {
243      $node['returns'] = array_unique(array_merge($node['returns'], explode('|', $content['returns'])));
244    }
245
246    if (trim($content['return_summary'])) {
247      $node['return_summary'] = $content['return_summary'];
248    }
249
250    foreach (array('prototype', 'instance', 'normal') as $scope) {
251      if (!empty($content['mixins'][$scope])) {
252        if (empty($node['mixins'][$scope])) {
253          $node['mixins'][$scope] = array();
254        }
255        if (!is_array($content['mixins'][$scope])) {
256          print $content['mixins'][$scope];
257        }
258        $node['mixins'][$scope] = array_unique(array_merge($node['mixins'][$scope], $content['mixins'][$scope]));
259      }
260    }
261
262    if ($content['type'] == 'Function') {
263      if ($content['classlike']) {
264        $node['classlike'] = true;
265      }
266
267      if ($node['chains']) {
268        if (!$content['chains']['prototype']) {
269          $content['chains']['prototype'] = array();
270        }
271        $node['chains']['prototype'] = array_unique(array_merge($node['chains']['prototype'], $content['chains']['prototype']));
272        if (!$content['chains']['call']) {
273          $content['chains']['call'] = array();
274        }
275        $node['chains']['call'] = array_unique(array_merge($node['chains']['call'], $content['chains']['call']));
276      }
277      else {
278        $node['chains']['prototype'] = ($content['chains']['prototype']) ? $content['chains']['prototype'] : array();
279        $node['chains']['call'] = ($content['chains']['call']) ? $content['chains']['call'] : array();
280      }
281
282      if ($content['chains']) {
283        unset($content['chains']['prototype']);
284        unset($content['chains']['call']);
285        $types = array_keys($content['chains']);
286        if (!empty($types)) {
287          print_r($types);
288          die('Unexpected chain type');
289        }
290      }
291
292      if (!empty($content['parameters'])) {
293        if (!empty($node['parameters'])) {
294          $node_parameters = array_keys($node['parameters']);
295          $content_parameters = array_keys($content['parameters']);
296          $long_parameters = (count($node_parameters) > count($content_parameters)) ? $node_parameters : $content_parameters;
297          $short_parameters = (count($node_parameters) >  count($content_parameters)) ? $content_parameters : $node_parameters;
298
299          $match = true;
300          $total_short = count($short_parameters);
301          foreach ($long_parameters as $i => $parameter) {
302            if ($i < $total_short && $parameter != $short_parameters[$i]) {
303              $match = false;
304            }
305          }
306
307          if ($match) {
308            // Only process these if they match the first occurence
309            foreach ($content['parameters'] as $parameter_name => $parameter) {
310              if (empty($node['parameters'][$parameter_name]['type'])) {
311                $node['parameters'][$parameter_name]['type'] = $parameter['type'];
312              }
313              if (trim($parameter['summary'])) {
314                $node['parameters'][$parameter_name]['summary'] = $parameter['summary'];
315              }
316            }
317          }
318        }
319        else {
320          $node['parameters'] = $content['parameters'];
321        }
322      }
323    }
324
325    $nodes->save($var, $node);
326  }
327
328  $resources->save($namespace . '%' . $file, $ctime);
329
330  // print_r($keys);
331}
332
333unset($resources);
334
335print "=== BUILDING OBJECT STRUCTURE ===\n";
336flush();
337
338$roots = array();
339$ids = $nodes->ids();
340
341$percent = 0;
342
343$total = count($ids);
344$count_args = count($args);
345foreach ($ids as $pos => $id) {
346  $new_percent = floor($pos / $total * 50);
347  if ($new_percent % 5 == 0 && $percent % 5 != 0) {
348    print $new_percent . "%\n";
349  }
350  $percent = $new_percent;
351
352  $parts = explode('.', $id);
353  if (count($parts) > 1) {
354    $name = array_pop($parts);
355    $parent = implode('.', $parts);
356
357    $node = $nodes->open($id, array());
358    if (!is_array($node['#namespaces']) || ($count_args && !count(array_intersect($args, $node['#namespaces'])))) {
359      continue;
360    }
361    if (!array_key_exists($parent, $roots)) {
362      $roots[$parent] = array();
363    }
364    if ($node['type'] == 'Function') {
365      $roots[$id]['function'] = true;
366    }
367    if ($node['classlike']) {
368      $roots[$id]['classlike'] = true;
369    }
370  }
371}
372
373// Figure out whether a root item has children or not
374$pos = 0;
375$root_count = count($roots);
376$has_children_map = array();
377$rootids = array_keys($roots);
378//descending sort rootids, so children are processed before parents
379rsort($rootids);
380foreach ($rootids as $id) {
381  $root = $roots[$id];
382  $new_percent = floor(50 + ($pos++ / $root_count * 50));
383  if ($new_percent % 5 == 0 && $percent % 5 != 0) {
384    print floor($new_percent) . "%\n";
385  }
386  $percent = $new_percent;
387
388  $parts = explode('.', $id);
389  $parts_count = count($parts);
390  if ($parts_count > 1) {
391    if ($root['function'] && !$root['classlike']) {
392      if(!array_key_exists($id, $has_children_map)){
393          unset($roots[$id]);
394      }
395    }
396
397    $name = array_pop($parts);
398    $parent_id = implode('.', $parts);
399    $obj = array("name"=>$name, "id"=>$id);
400    if(array_key_exists($parent_id, $has_children_map)) {
401      array_push($has_children_map[$parent_id], $obj);
402    }
403    else{
404      $has_children_map[$parent_id] = array($obj);
405    }
406  }
407}
408
409print "=== SERIALIZING OBJECTS ===\n";
410
411// Aggregate and save
412$serializers = array();
413if ($kwargs['outfile']) {
414  if (isset($kwargs['serialize']['json'])) {
415    $serializers['json'] = new JsonSerializer('cache', 'json', $kwargs['outfile']);
416  }
417  if (isset($kwargs['serialize']['xml'])) {
418    $serializers['xml'] = new XmlSerializer('cache', 'xml', $kwargs['outfile']);
419  }
420}
421else {
422  if (isset($kwargs['serialize']['json'])) {
423    $serializers['json'] = new JsonSerializer('cache', 'json');
424  }
425  if (isset($kwargs['serialize']['xml'])) {
426    $serializers['xml'] = new XmlSerializer('cache', 'xml');
427  }
428}
429
430foreach ($roots as $id => $root) {
431  if(!$id){
432    // Minor bug
433    continue;
434  }
435
436  $node = $nodes->open($id, null);
437
438  if(array_key_exists($id, $has_children_map)){
439    foreach ($has_children_map[$id] as $child) {
440      $node['#children'][$child['name']] = $nodes->open($child['id'], null);
441    }
442  }
443
444  printf("%-100s %6s KB\n", $id, number_format(memory_get_usage() / 1024));
445  flush();
446
447  foreach ($serializers as $serializer) {
448    $serializer->setObject($id, $node);
449  }
450}
451
452// * Assemble parent/child relationships
453
454?>
Note: See TracBrowser for help on using the repository browser.