[483] | 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 | ?> |
---|