control-freak-ide/server/nodejs/util/docscripts/makeCix.php
plastic-hub-dev-node-saturn 538369cff7 latest
2021-05-12 18:35:18 +02:00

332 lines
9.6 KiB
PHP

<?php
//
// This is an experiemental file, used to generate dojo11.cix,
// the XML for ActiveState's Komodo Editor code-completion.
//
// it requires php5, a lot of memory, and write access to
// the ./cache folder in this path. It will parse the dojo
// tree (or read from cache if a file is unmodified), and dump
// the results to "valid" XML (i think).
//
// to use:
// /usr/local/php5/bin/php -q makeCix.php > ../resources/dojo.cix
//
// $Rev: $
$current_version = "1.6.0";
header("Content-type: text/xml");
ini_set("memory_limit","512M");
include_once('includes/dojo.inc');
$files = dojo_get_files();
// our namespaces:
$out = array("dijit" => array(), "dojox" => array(), "dojo" => array() );
// put the results of each file into $array[$namespace]
foreach ($files as $set){
list($namespace,$file) = $set;
$data = dojo_get_contents_cache($namespace, $file);
$out[$namespace] = array_merge($out[$namespace],$data);
}
// and do some weeeird array manipulations:
$out = @expando_dojo($out);
// start a new document
$doc = new DOMDocument('1.0');
// setup for codeintel:
$codeintel = $doc->createElement('codeintel');
$codeintel->setAttribute("description","Dojo Toolkit API - version " . $current_version);
$codeintel->setAttribute("version","2.0");
$codeintel->setAttribute("encoding","UTF-8");
// wrap all the api in one "file" tag:
$data = $doc->createElement('file');
$data->setAttribute("lang","JavaScript");
$data->setAttribute("path","");
$f = $codeintel->appendChild($data);
// and all the namespaces under one heading "dojo"
$api = $doc->createElement('scope');
$api->setAttribute("ilk","blob");
$api->setAttribute("lang","JavaScript");
$api->setAttribute("name","dojo");
$namespace = $f->appendChild($api);
// iterate through our modified array, and make an XML tree of the data:
foreach ($out as $ns => $data){
// each top-level namespace get's it own scope
$nsdata = $doc->createElement('scope');
$nsdata->setAttribute("ilk","class");
$nsdata->setAttribute("name",$ns);
foreach ($data as $obj => $info){
$objElm = $doc->createElement('scope');
if(!empty($info['type'])){
$tt = $info['type'];
switch($tt){
case "Object" :
// inspect this object deeper, but append to namespace:
$nsdata->appendChild(dojo_inspect($data[$obj],$obj,$doc, "variable"));
break;
case "Function" :
if($info['classlike']){
// inspect deeper, append to namesapce:
$nsdata->setAttribute("ilk","class");
$nsdata->appendChild(dojo_inspect($data[$obj],$obj,$doc));
}else{
// functions usually have param data:
$objElm->setAttribute("ilk",strtolower($tt));
$objElm->setAttribute("name",$obj);
if(is_array($info['parameters'])){
// generate the signature
$sig = $obj."(";
foreach($info['parameters'] as $param => $pData){
$sig .= $param.",";
$paramElm = $doc->createElement('variable');
if(!empty($pData['type'])){
$paramElm->setAttribute("citdl",$pData['type']);
}
$paramElm->setAttribute("name",$param);
$paramElm->setAttribute("ilk","argument");
if($pData['summary']){
$paramElm->setAttribute("doc", fix_utf(htmlentities($pData['summary'])));
}
$objElm -> appendChild($paramElm);
}
$sig = substr($sig,0,strlen($sig)-1);
$sig .= ")";
$objElm->setAttribute("signature",$sig);
unset($sig);
}
}
break;
}
unset($tt);
}
// pertinent data:
if(!empty($info['returns'])){
$objElm->setAttribute("returns",htmlentities($info['returns']));
}
// helpful data:
if(!empty($info['summary'])){
$objElm->setAttribute("doc", fix_utf(htmlentities($info['summary'])));
}
// avoid appending this node if we skipped popoulating it (in the case of nsdata->appendCHild())
if($objElm->hasAttribute("name")){
$nsdata->appendChild($objElm);
}
}
// and dump all the data to this namesapce
$namespace->appendChild($nsdata);
}
// append the APi to the document, and print:
$doc->appendChild($codeintel);
print $doc->saveXML();
function dojo_inspect($data,$ns,$doc,$t="scope"){
// summary: inspect some namespace (as top), with some passed data.
if ($t == "argument") {
$elm = $doc->createElement("variable");
$elm->setAttribute("ilk", "argument");
} else {
$elm = $doc->createElement($t);
}
$elm->setAttribute("name",$ns);
foreach ($data as $obj => $info){
switch($obj){
// these are all the ones we don't _really_ care about in this context:
case "prototype" : //$elm->setAttribute("classref",$info['prototype']); break;
case "chains" :
case "mixins" :
case "instance" :
case "optional" :
case "classlike" :
case "examples" :
case "private_parent" :
case "description" :
case "source" :
case "style" :
break;
// mmm, duplicated from above:
case "parameters" :
$sig = $ns."(";
foreach($info as $key => $val){
$sig .= $key.",";
$elm->appendChild(dojo_inspect($val,$key,$doc,"argument"));
}
$sig = substr($sig,0,strlen($sig)-1);
$sig .= ")";
$elm->setAttribute("signature",$sig);
break;
// some pertinant info about this element:
case "returns" : $elm->setAttribute("returns",htmlentities($info));
case "private" : $elm->setAttribute("attributes","private"); break;
case "type" :
if($info) {
switch ($info){
case "Function" :
$elm->setAttribute("ilk","function");
break;
default:
if (is_array($info)) {
if ($info["instance"]) {
$elm->setAttribute("citdl",$info["instance"]);
}
} else {
$elm->setAttribute("citdl",$info);
}
}
}
break;
// ahhh, the blessed summary:
case "summary" : $elm->setAttribute("doc", fix_utf(htmlentities($info)));
break;
// just in case we missed something?
default :
$scope_type = "scope";
if (($data[$obj]["instance"] != NULL) ||
($data[$obj]["type"] == "Object")) {
$scope_type = "variable";
}
$elm->appendChild(dojo_inspect($data[$obj],$obj,$doc,$scope_type));
break;
}
}
// give it back as a domNode:
return $elm;
}
function dojo_get_contents_cache($namespace, $file, $forceNew = false){
// summary: a shim to dojo_get_contents, providing filemtime checking/caching
// from parsing: XML takes ~ 80000ms on my MacBook Pro, from cache:
// 7000ms ... pass true as third param to force cache reloading.
// if the file hasn't been change since the last time, skip parsing it
$mtime = dojo_get_file_time($namespace, $file);
$cfile = "./cache/".md5($namespace.$file).".".$mtime;
if(!$forceNew && file_exists($cfile)){
// read it from the cache:
$cache = file_get_contents($cfile);
$data = unserialize($cache);
}else{
// parse the file, and save the cached results:
$data = @dojo_get_contents($namespace, $file);
$cache = serialize($data);
$fp = fopen($cfile,"w+");
fputs($fp,$cache);
fclose($fp);
}
return $data;
}
function expando_dojo($array){
// ugly array manipulation to turn an array like:
// array( "one" => array("one","two","three"), "one.more"=>array("two","four","six")
// into:
// array("one" => array("more"=>array("two","four","six"), "one", "two", "three"));
$ret = array();
foreach($array as $namespace => $results){
foreach($results as $item => $data){
switch($item{0}){
case "#" : break;
default:
$list = explode(".",$item);
$n = count($list);
$me = $list[$n];
// NOT happy with this:
if(!($list[0]==$namespace)){ continue; }
switch($n){
case 8 :
fprintf("UNCAUGHT! %s", $item); // way tooooo deep.
break;
case 7 :
$l1 = $list[1];
$l2 = $list[2];
$l3 = $list[3];
$l4 = $list[4];
$l5 = $list[5];
$l6 = $list[6];
if ($ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] == NULL)
$ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] = $data;
else
$ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4][$l5][$l6]);
break;
case 6 :
$l1 = $list[1];
$l2 = $list[2];
$l3 = $list[3];
$l4 = $list[4];
$l5 = $list[5];
if ($ret[$namespace][$l1][$l2][$l3][$l4][$l5] == NULL)
$ret[$namespace][$l1][$l2][$l3][$l4][$l5] = $data;
else
$ret[$namespace][$l1][$l2][$l3][$l4][$l5] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4][$l5]);
break;
case 5 :
$l1 = $list[1];
$l2 = $list[2];
$l3 = $list[3];
$l4 = $list[4];
if ($ret[$namespace][$l1][$l2][$l3][$l4] == NULL)
$ret[$namespace][$l1][$l2][$l3][$l4] = $data;
else
$ret[$namespace][$l1][$l2][$l3][$l4] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3][$l4]);
break;
case 4 :
$l1 = $list[1];
$l2 = $list[2];
$l3 = $list[3];
if ($ret[$namespace][$l1][$l2][$l3] == NULL)
$ret[$namespace][$l1][$l2][$l3] = $data;
else
$ret[$namespace][$l1][$l2][$l3] = array_merge_recursive($data, $ret[$namespace][$l1][$l2][$l3]);
break;
case 3 :
$l1 = $list[1];
$l2 = $list[2];
if ($ret[$namespace][$l1][$l2] == NULL)
$ret[$namespace][$l1][$l2] = $data;
else
$ret[$namespace][$l1][$l2] = array_merge_recursive($data, $ret[$namespace][$l1][$l2]);
break;
case 2 :
$l1 = $list[1];
$ret[$namespace][$l1] = $data;
break;
}
break;
}
}
}
return $ret;
}
function fix_utf($str){
return iconv('utf-8','utf-8', $str);
}
?>