1 | <?php |
---|
2 | // |
---|
3 | // This is an experiemental file, used to generate dojo11.cix, |
---|
4 | // the XML for ActiveState's Komodo Editor code-completion. |
---|
5 | // |
---|
6 | // it requires php5, a lot of memory, and write access to |
---|
7 | // the ./cache folder in this path. It will parse the dojo |
---|
8 | // tree (or read from cache if a file is unmodified), and dump |
---|
9 | // the results to "valid" XML (i think). |
---|
10 | // |
---|
11 | // to use: |
---|
12 | // /usr/local/php5/bin/php -q makeCix.php > ../resources/dojo.cix |
---|
13 | // |
---|
14 | |
---|
15 | // $Rev: $ |
---|
16 | $current_version = "1.6.0"; |
---|
17 | |
---|
18 | header("Content-type: text/xml"); |
---|
19 | |
---|
20 | ini_set("memory_limit","512M"); |
---|
21 | include_once('includes/dojo.inc'); |
---|
22 | |
---|
23 | $files = dojo_get_files(); |
---|
24 | |
---|
25 | // our namespaces: |
---|
26 | $out = array("dijit" => array(), "dojox" => array(), "dojo" => array() ); |
---|
27 | // put the results of each file into $array[$namespace] |
---|
28 | foreach ($files as $set){ |
---|
29 | list($namespace,$file) = $set; |
---|
30 | $data = dojo_get_contents_cache($namespace, $file); |
---|
31 | $out[$namespace] = array_merge($out[$namespace],$data); |
---|
32 | } |
---|
33 | // and do some weeeird array manipulations: |
---|
34 | $out = @expando_dojo($out); |
---|
35 | |
---|
36 | // start a new document |
---|
37 | $doc = new DOMDocument('1.0'); |
---|
38 | // setup for codeintel: |
---|
39 | $codeintel = $doc->createElement('codeintel'); |
---|
40 | $codeintel->setAttribute("description","Dojo Toolkit API - version " . $current_version); |
---|
41 | $codeintel->setAttribute("version","2.0"); |
---|
42 | $codeintel->setAttribute("encoding","UTF-8"); |
---|
43 | // wrap all the api in one "file" tag: |
---|
44 | $data = $doc->createElement('file'); |
---|
45 | $data->setAttribute("lang","JavaScript"); |
---|
46 | $data->setAttribute("path",""); |
---|
47 | $f = $codeintel->appendChild($data); |
---|
48 | // and all the namespaces under one heading "dojo" |
---|
49 | $api = $doc->createElement('scope'); |
---|
50 | $api->setAttribute("ilk","blob"); |
---|
51 | $api->setAttribute("lang","JavaScript"); |
---|
52 | $api->setAttribute("name","dojo"); |
---|
53 | $namespace = $f->appendChild($api); |
---|
54 | |
---|
55 | // iterate through our modified array, and make an XML tree of the data: |
---|
56 | foreach ($out as $ns => $data){ |
---|
57 | |
---|
58 | // each top-level namespace get's it own scope |
---|
59 | $nsdata = $doc->createElement('scope'); |
---|
60 | $nsdata->setAttribute("ilk","class"); |
---|
61 | $nsdata->setAttribute("name",$ns); |
---|
62 | |
---|
63 | foreach ($data as $obj => $info){ |
---|
64 | |
---|
65 | $objElm = $doc->createElement('scope'); |
---|
66 | if(!empty($info['type'])){ |
---|
67 | |
---|
68 | $tt = $info['type']; |
---|
69 | switch($tt){ |
---|
70 | case "Object" : |
---|
71 | // inspect this object deeper, but append to namespace: |
---|
72 | $nsdata->appendChild(dojo_inspect($data[$obj],$obj,$doc, "variable")); |
---|
73 | break; |
---|
74 | case "Function" : |
---|
75 | if($info['classlike']){ |
---|
76 | // inspect deeper, append to namesapce: |
---|
77 | $nsdata->setAttribute("ilk","class"); |
---|
78 | $nsdata->appendChild(dojo_inspect($data[$obj],$obj,$doc)); |
---|
79 | }else{ |
---|
80 | // functions usually have param data: |
---|
81 | $objElm->setAttribute("ilk",strtolower($tt)); |
---|
82 | $objElm->setAttribute("name",$obj); |
---|
83 | if(is_array($info['parameters'])){ |
---|
84 | // generate the signature |
---|
85 | $sig = $obj."("; |
---|
86 | foreach($info['parameters'] as $param => $pData){ |
---|
87 | $sig .= $param.","; |
---|
88 | $paramElm = $doc->createElement('variable'); |
---|
89 | if(!empty($pData['type'])){ |
---|
90 | $paramElm->setAttribute("citdl",$pData['type']); |
---|
91 | } |
---|
92 | $paramElm->setAttribute("name",$param); |
---|
93 | $paramElm->setAttribute("ilk","argument"); |
---|
94 | if($pData['summary']){ |
---|
95 | $paramElm->setAttribute("doc", fix_utf(htmlentities($pData['summary']))); |
---|
96 | } |
---|
97 | $objElm -> appendChild($paramElm); |
---|
98 | } |
---|
99 | $sig = substr($sig,0,strlen($sig)-1); |
---|
100 | $sig .= ")"; |
---|
101 | $objElm->setAttribute("signature",$sig); |
---|
102 | unset($sig); |
---|
103 | } |
---|
104 | } |
---|
105 | break; |
---|
106 | } |
---|
107 | unset($tt); |
---|
108 | } |
---|
109 | // pertinent data: |
---|
110 | if(!empty($info['returns'])){ |
---|
111 | $objElm->setAttribute("returns",htmlentities($info['returns'])); |
---|
112 | } |
---|
113 | // helpful data: |
---|
114 | if(!empty($info['summary'])){ |
---|
115 | $objElm->setAttribute("doc", fix_utf(htmlentities($info['summary']))); |
---|
116 | } |
---|
117 | |
---|
118 | // avoid appending this node if we skipped popoulating it (in the case of nsdata->appendCHild()) |
---|
119 | if($objElm->hasAttribute("name")){ |
---|
120 | $nsdata->appendChild($objElm); |
---|
121 | } |
---|
122 | } |
---|
123 | |
---|
124 | // and dump all the data to this namesapce |
---|
125 | $namespace->appendChild($nsdata); |
---|
126 | |
---|
127 | } |
---|
128 | |
---|
129 | // append the APi to the document, and print: |
---|
130 | $doc->appendChild($codeintel); |
---|
131 | print $doc->saveXML(); |
---|
132 | |
---|
133 | |
---|
134 | function dojo_inspect($data,$ns,$doc,$t="scope"){ |
---|
135 | // summary: inspect some namespace (as top), with some passed data. |
---|
136 | if ($t == "argument") { |
---|
137 | $elm = $doc->createElement("variable"); |
---|
138 | $elm->setAttribute("ilk", "argument"); |
---|
139 | } else { |
---|
140 | $elm = $doc->createElement($t); |
---|
141 | } |
---|
142 | $elm->setAttribute("name",$ns); |
---|
143 | |
---|
144 | foreach ($data as $obj => $info){ |
---|
145 | switch($obj){ |
---|
146 | // these are all the ones we don't _really_ care about in this context: |
---|
147 | case "prototype" : //$elm->setAttribute("classref",$info['prototype']); break; |
---|
148 | case "chains" : |
---|
149 | case "mixins" : |
---|
150 | case "instance" : |
---|
151 | case "optional" : |
---|
152 | case "classlike" : |
---|
153 | case "examples" : |
---|
154 | case "private_parent" : |
---|
155 | case "description" : |
---|
156 | case "source" : |
---|
157 | case "style" : |
---|
158 | break; |
---|
159 | |
---|
160 | // mmm, duplicated from above: |
---|
161 | case "parameters" : |
---|
162 | $sig = $ns."("; |
---|
163 | foreach($info as $key => $val){ |
---|
164 | $sig .= $key.","; |
---|
165 | $elm->appendChild(dojo_inspect($val,$key,$doc,"argument")); |
---|
166 | } |
---|
167 | $sig = substr($sig,0,strlen($sig)-1); |
---|
168 | $sig .= ")"; |
---|
169 | $elm->setAttribute("signature",$sig); |
---|
170 | break; |
---|
171 | |
---|
172 | // some pertinant info about this element: |
---|
173 | case "returns" : $elm->setAttribute("returns",htmlentities($info)); |
---|
174 | case "private" : $elm->setAttribute("attributes","private"); break; |
---|
175 | |
---|
176 | case "type" : |
---|
177 | if($info) { |
---|
178 | switch ($info){ |
---|
179 | case "Function" : |
---|
180 | $elm->setAttribute("ilk","function"); |
---|
181 | break; |
---|
182 | default: |
---|
183 | if (is_array($info)) { |
---|
184 | if ($info["instance"]) { |
---|
185 | $elm->setAttribute("citdl",$info["instance"]); |
---|
186 | } |
---|
187 | } else { |
---|
188 | $elm->setAttribute("citdl",$info); |
---|
189 | } |
---|
190 | } |
---|
191 | } |
---|
192 | break; |
---|
193 | |
---|
194 | // ahhh, the blessed summary: |
---|
195 | case "summary" : $elm->setAttribute("doc", fix_utf(htmlentities($info))); |
---|
196 | break; |
---|
197 | |
---|
198 | // just in case we missed something? |
---|
199 | default : |
---|
200 | $scope_type = "scope"; |
---|
201 | if (($data[$obj]["instance"] != NULL) || |
---|
202 | ($data[$obj]["type"] == "Object")) { |
---|
203 | $scope_type = "variable"; |
---|
204 | } |
---|
205 | $elm->appendChild(dojo_inspect($data[$obj],$obj,$doc,$scope_type)); |
---|
206 | break; |
---|
207 | } |
---|
208 | } |
---|
209 | // give it back as a domNode: |
---|
210 | return $elm; |
---|
211 | |
---|
212 | } |
---|
213 | |
---|
214 | function dojo_get_contents_cache($namespace, $file, $forceNew = false){ |
---|
215 | // summary: a shim to dojo_get_contents, providing filemtime checking/caching |
---|
216 | // from parsing: XML takes ~ 80000ms on my MacBook Pro, from cache: |
---|
217 | // 7000ms ... pass true as third param to force cache reloading. |
---|
218 | |
---|
219 | // if the file hasn't been change since the last time, skip parsing it |
---|
220 | $mtime = dojo_get_file_time($namespace, $file); |
---|
221 | $cfile = "./cache/".md5($namespace.$file).".".$mtime; |
---|
222 | |
---|
223 | if(!$forceNew && file_exists($cfile)){ |
---|
224 | // read it from the cache: |
---|
225 | $cache = file_get_contents($cfile); |
---|
226 | $data = unserialize($cache); |
---|
227 | |
---|
228 | }else{ |
---|
229 | // parse the file, and save the cached results: |
---|
230 | $data = @dojo_get_contents($namespace, $file); |
---|
231 | $cache = serialize($data); |
---|
232 | $fp = fopen($cfile,"w+"); |
---|
233 | fputs($fp,$cache); |
---|
234 | fclose($fp); |
---|
235 | |
---|
236 | } |
---|
237 | return $data; |
---|
238 | |
---|
239 | } |
---|
240 | |
---|
241 | function expando_dojo($array){ |
---|
242 | // ugly array manipulation to turn an array like: |
---|
243 | // array( "one" => array("one","two","three"), "one.more"=>array("two","four","six") |
---|
244 | // into: |
---|
245 | // array("one" => array("more"=>array("two","four","six"), "one", "two", "three")); |
---|
246 | |
---|
247 | $ret = array(); |
---|
248 | foreach($array as $namespace => $results){ |
---|
249 | foreach($results as $item => $data){ |
---|
250 | switch($item{0}){ |
---|
251 | case "#" : break; |
---|
252 | default: |
---|
253 | $list = explode(".",$item); |
---|
254 | $n = count($list); |
---|
255 | $me = $list[$n]; |
---|
256 | // NOT happy with this: |
---|
257 | if(!($list[0]==$namespace)){ continue; } |
---|
258 | switch($n){ |
---|
259 | case 8 : |
---|
260 | fprintf("UNCAUGHT! %s", $item); // way tooooo deep. |
---|
261 | break; |
---|
262 | case 7 : |
---|
263 | $l1 = $list[1]; |
---|
264 | $l2 = $list[2]; |
---|
265 | $l3 = $list[3]; |
---|
266 | $l4 = $list[4]; |
---|
267 | $l5 = $list[5]; |
---|
268 | $l6 = $list[6]; |
---|
269 | if ($ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] == NULL) |
---|
270 | $ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] = $data; |
---|
271 | else |
---|
272 | $ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6]); |
---|
273 | break; |
---|
274 | case 6 : |
---|
275 | $l1 = $list[1]; |
---|
276 | $l2 = $list[2]; |
---|
277 | $l3 = $list[3]; |
---|
278 | $l4 = $list[4]; |
---|
279 | $l5 = $list[5]; |
---|
280 | if ($ret[$namespace][$l1][$l2][$l3][$l4][$l5] == NULL) |
---|
281 | $ret[$namespace][$l1][$l2][$l3][$l4][$l5] = $data; |
---|
282 | else |
---|
283 | $ret[$namespace][$l1][$l2][$l3][$l4][$l5] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4][$l5]); |
---|
284 | break; |
---|
285 | case 5 : |
---|
286 | $l1 = $list[1]; |
---|
287 | $l2 = $list[2]; |
---|
288 | $l3 = $list[3]; |
---|
289 | $l4 = $list[4]; |
---|
290 | if ($ret[$namespace][$l1][$l2][$l3][$l4] == NULL) |
---|
291 | $ret[$namespace][$l1][$l2][$l3][$l4] = $data; |
---|
292 | else |
---|
293 | $ret[$namespace][$l1][$l2][$l3][$l4] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4]); |
---|
294 | break; |
---|
295 | case 4 : |
---|
296 | $l1 = $list[1]; |
---|
297 | $l2 = $list[2]; |
---|
298 | $l3 = $list[3]; |
---|
299 | if ($ret[$namespace][$l1][$l2][$l3] == NULL) |
---|
300 | $ret[$namespace][$l1][$l2][$l3] = $data; |
---|
301 | else |
---|
302 | $ret[$namespace][$l1][$l2][$l3] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3]); |
---|
303 | break; |
---|
304 | case 3 : |
---|
305 | $l1 = $list[1]; |
---|
306 | $l2 = $list[2]; |
---|
307 | |
---|
308 | if ($ret[$namespace][$l1][$l2] == NULL) |
---|
309 | $ret[$namespace][$l1][$l2] = $data; |
---|
310 | else |
---|
311 | $ret[$namespace][$l1][$l2] = array_merge_recursive($data, $ret[$namespace][$l1][$l2]); |
---|
312 | break; |
---|
313 | case 2 : |
---|
314 | $l1 = $list[1]; |
---|
315 | $ret[$namespace][$l1] = $data; |
---|
316 | break; |
---|
317 | } |
---|
318 | break; |
---|
319 | } |
---|
320 | |
---|
321 | } |
---|
322 | |
---|
323 | } |
---|
324 | return $ret; |
---|
325 | } |
---|
326 | |
---|
327 | function fix_utf($str){ |
---|
328 | return iconv('utf-8','utf-8', $str); |
---|
329 | } |
---|
330 | |
---|
331 | ?> |
---|