PageRenderTime 29ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/buildscripts/classtree/build.php

http://prado3.googlecode.com/
PHP | 258 lines | 114 code | 10 blank | 134 comment | 2 complexity | ce2907ae50576652ca1201fb006baedd MD5 | raw file
Possible License(s): Apache-2.0, IPL-1.0, LGPL-3.0, LGPL-2.1, BSD-3-Clause
  1. <?php
  2. $basePath=dirname(__FILE__);
  3. $frameworkPath=realpath($basePath.'/../../framework');
  4. require_once($frameworkPath.'/prado.php');
  5. require_once($basePath.'/DWExtension.php');
  6. //the manager class sets up some dependency paths
  7. Prado::using('System.Data.SqlMap.TSqlMapManager');
  8. $exclusions=array(
  9. 'pradolite.php',
  10. 'prado-cli.php',
  11. 'JSMin.php',
  12. '.svn',
  13. '/I18N/core',
  14. '/3rdParty',
  15. '/Testing',
  16. '/Web/UI/WebControls/assets',
  17. );
  18. $a=new ClassTreeBuilder($frameworkPath,$exclusions);
  19. $a->buildTree();
  20. $a->saveToFile($basePath.'/classes.data');
  21. $a->saveAsDWExtension($basePath);
  22. class ClassTreeBuilder
  23. {
  24. const REGEX_RULES='/^\s*(abstract\s+)?class\s+(\w+)(\s+extends\s+(\w+)\s*|\s*)/msS';
  25. private $_frameworkPath;
  26. private $_exclusions;
  27. private $_classes=array();
  28. public function __construct($frameworkPath,$exclusions)
  29. {
  30. $this->_frameworkPath=realpath($frameworkPath);
  31. $this->_exclusions=array();
  32. foreach($exclusions as $exclusion)
  33. {
  34. if($exclusion[0]==='/')
  35. $this->_exclusions[realpath($frameworkPath.'/'.$exclusion)]=true;
  36. else
  37. $this->_exclusions[$exclusion]=true;
  38. }
  39. }
  40. public function buildTree()
  41. {
  42. $sourceFiles=$this->getSourceFiles($this->_frameworkPath);
  43. foreach($sourceFiles as $sourceFile)
  44. $this->parseFile($sourceFile);
  45. ksort($this->_classes);
  46. foreach(array_keys($this->_classes) as $className)
  47. {
  48. $parentClass=$this->_classes[$className]['ParentClass'];
  49. if(isset($this->_classes[$parentClass]))
  50. $this->_classes[$parentClass]['ChildClasses'][]=$className;
  51. }
  52. echo "\nClass tree built successfully. Total ".count($this->_classes)." classes found.\n";
  53. }
  54. public function saveToFile($fileName)
  55. {
  56. file_put_contents($fileName,serialize($this->_classes));
  57. }
  58. public function displayTree()
  59. {
  60. $this->displayTreeInternal(array_keys($this->_baseClasses),0);
  61. }
  62. public function displayTreeInternal($classNames,$level)
  63. {
  64. foreach($classNames as $className)
  65. {
  66. echo str_repeat(' ',$level*4);
  67. echo $className.':'.$this->_classes[$className]->Package."\n";
  68. $this->displayTreeInternal(array_keys($this->_classes[$className]->ChildClasses),$level+1);
  69. }
  70. }
  71. protected function parseFile($sourceFile)
  72. {
  73. include_once($sourceFile);
  74. $classFile=strtr(substr($sourceFile,strlen($this->_frameworkPath)),'\\','/');
  75. echo "Parsing $classFile...\n";
  76. $content=file_get_contents($sourceFile);
  77. if(preg_match('/@package\s+([\w\.]+)\s*/msS',$content,$matches)>0)
  78. $package=$matches[1];
  79. else
  80. $package='';
  81. $n=preg_match_all(self::REGEX_RULES,$content,$matches,PREG_SET_ORDER);
  82. for($i=0;$i<$n;++$i)
  83. {
  84. $className=$matches[$i][2];
  85. if(isset($this->_classes[$className]))
  86. throw new Exception("Class $className is defined in both $sourceFile and ".$this->_classes[$className]->ClassFile);
  87. $c=new TComponentReflection($className);
  88. $properties=$c->getProperties();
  89. $this->parseMethodComments($properties);
  90. $events=$c->getEvents();
  91. $this->parseMethodComments($events);
  92. $methods=$c->getMethods();
  93. $this->parseMethodComments($methods);
  94. $this->_classes[$className]=array(
  95. 'ClassFile'=>$classFile,
  96. 'Package'=>$package,
  97. 'ParentClass'=>isset($matches[$i][4])?$matches[$i][4]:'',
  98. 'ChildClasses'=>array(),
  99. 'Properties'=>$properties,
  100. 'Events'=>$events,
  101. 'Methods'=>$methods);
  102. }
  103. }
  104. protected function parseMethodComments(&$methods)
  105. {
  106. foreach(array_keys($methods) as $key)
  107. {
  108. $method=&$methods[$key];
  109. $comments=$method['comments'];
  110. $s='';
  111. foreach(explode("\n",$comments) as $line)
  112. {
  113. $line=trim($line);
  114. $line=trim($line,'/*');
  115. $s.=' '.$line;
  116. }
  117. $s=trim($s);
  118. $s=preg_replace('/\{@link.*?([\w\(\)]+)\}/i','$1',$s);
  119. $pos1=strpos($s,'@');
  120. $pos2=strpos($s,'.');
  121. if($pos1===false)
  122. {
  123. if($pos2!==false)
  124. $method['comments']=substr($s,0,$pos2);
  125. else
  126. $method['comments']=$s;
  127. }
  128. else if($pos1>0)
  129. {
  130. if($pos2 && $pos2<$pos1) // use the first line as comment
  131. $method['comments']=substr($s,0,$pos2);
  132. else
  133. $method['comments']=substr($s,0,$pos1);
  134. }
  135. else
  136. {
  137. $matches=array();
  138. if(preg_match('/@return\s+[\w\|]+\s+([^\.]*)/',$s,$matches)>0)
  139. $method['comments']=$matches[1];
  140. else
  141. $method['comments']='';
  142. }
  143. }
  144. }
  145. protected function isValidPath($path)
  146. {
  147. if(is_dir($path))
  148. return !isset($this->_exclusions[basename($path)]) && !isset($this->_exclusions[$path]);
  149. else
  150. return basename($path)!==basename($path,'.php') && !isset($this->_exclusions[basename($path)]);
  151. }
  152. public function getSourceFiles($path)
  153. {
  154. $files=array();
  155. $folder=opendir($path);
  156. while($file=readdir($folder))
  157. {
  158. if($file==='.' || $file==='..')
  159. continue;
  160. $fullPath=realpath($path.'/'.$file);
  161. if($this->isValidPath($fullPath))
  162. {
  163. if(is_file($fullPath))
  164. $files[]=$fullPath;
  165. else
  166. $files=array_merge($files,$this->getSourceFiles($fullPath));
  167. }
  168. }
  169. closedir($folder);
  170. return $files;
  171. }
  172. public function saveAsDWExtension($basePath)
  173. {
  174. $tagPath=$basePath.'/Configuration/TagLibraries/PRADO';
  175. // prepare the directory to save tag lib
  176. @mkdir($basePath.'/Configuration');
  177. @mkdir($basePath.'/Configuration/TagLibraries');
  178. @mkdir($basePath.'/Configuration/TagLibraries/PRADO');
  179. $docMXI = new PradoMXIDocument(Prado::getVersion());
  180. $tagChooser = new PradoTagChooser;
  181. $controlClass = new ReflectionClass('TControl');
  182. foreach($this->_classes as $className=>$classInfo)
  183. {
  184. $class = new ReflectionClass($className);
  185. if($class->isInstantiable() && ($className==='TControl' || $class->isSubclassOf($controlClass)))
  186. {
  187. $docMXI->addTag($className);
  188. $tagChooser->addElement($className);
  189. $docVTM = new PradoVTMDocument($className);
  190. foreach($classInfo['Properties'] as $name=>$property)
  191. {
  192. $type=$property['type'];
  193. if(isset($this->_classes[$type]) && ($type==='TFont' || strrpos($type,'Style')===strlen($type)-5 && $type!=='TStyle'))
  194. $this->processObjectType($type,$this->_classes[$type],$name,$docVTM);
  195. if($property['readonly'] || $property['protected'])
  196. continue;
  197. if(($type=$this->checkType($className,$name,$property['type']))!=='')
  198. $docVTM->addAttribute($name,$type);
  199. }
  200. foreach($classInfo['Events'] as $name=>$event)
  201. {
  202. $docVTM->addEvent($name);
  203. }
  204. file_put_contents($tagPath.'/'.$className.'.vtm',$docVTM->getXML());
  205. }
  206. }
  207. file_put_contents($basePath.'/PRADO.mxi',$docMXI->getXML());
  208. file_put_contents($tagPath.'/TagChooser.xml',$tagChooser->getXML());
  209. }
  210. private function processObjectType($objectType,$objectInfo,$prefix,$doc)
  211. {
  212. foreach($objectInfo['Properties'] as $name=>$property)
  213. {
  214. if($property['type']==='TFont')
  215. $this->processObjectType('TFont',$this->_classes['TFont'],$prefix.'.'.$name,$doc);
  216. if($property['readonly'] || $property['protected'])
  217. continue;
  218. if(($type=$this->checkType($objectType,$name,$property['type']))!=='')
  219. $doc->addAttribute($prefix.'.'.$name,$type);
  220. }
  221. }
  222. private function checkType($className,$propertyName,$type)
  223. {
  224. if(strrpos($propertyName,'Color')===strlen($propertyName)-5)
  225. return 'color';
  226. if($propertyName==='Style')
  227. return 'style';
  228. if($type==='boolean')
  229. return array('true','false');
  230. if($type==='string' || $type==='integer' || $type==='ITemplate')
  231. return 'text';
  232. return '';
  233. }
  234. }
  235. ?>