/Classes/Parser/Impl/ProjectParser.php

https://github.com/RichardDownes/PHPCodeParser · PHP · 198 lines · 73 code · 40 blank · 85 comment · 7 complexity · a01ef84a25056c329535c143ad645440 MD5 · raw file

  1. <?php
  2. namespace Parser\Impl;
  3. /*
  4. * Copyright 2011 Richard Downes
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. use Meta\PHPNamespace;
  19. use Meta\AbstractPHPStructure;
  20. /**
  21. * Contains Parser\ProjectParser
  22. *
  23. * @author Richard Downes <richard@sculpt.ie>
  24. * @copyright Copyright (c) 2011, Richard Downes
  25. * @package Parser.Impl
  26. */
  27. /**
  28. * Responsible for parsing an entire project
  29. *
  30. * @author Richard Downes <richard@sculpt.ie>
  31. */
  32. class ProjectParser
  33. {
  34. /**
  35. * The namespaces found in the project
  36. *
  37. * @var array $namespaces A list of namespaces
  38. */
  39. protected $namespaces;
  40. /**
  41. * Constructs a new instance of ProjectParser
  42. *
  43. */
  44. public function __construct()
  45. {
  46. $this->namespaces = array();
  47. }
  48. /**
  49. * Responsible for parsing the files in a directory
  50. *
  51. * @param string $directory The directory to parse
  52. * @return \Meta\PHPNamespace[]
  53. */
  54. public function parse($directory)
  55. {
  56. $iterator = new \DirectoryIterator($directory);
  57. foreach($iterator as $fileInfo)
  58. {
  59. if ($this->isParseableDirectory($fileInfo))
  60. {
  61. $this->parse($fileInfo->getPathName());
  62. }
  63. else if ($this->isParseableFile($fileInfo))
  64. {
  65. $structures = $this->parseFile($fileInfo->getPathName());
  66. $this->addStructures($structures);
  67. }
  68. }
  69. return $this->getNamespaces();
  70. }
  71. /**
  72. * Responsible for adding a list of structures to the overall list
  73. *
  74. * @param array $structures The structures to add
  75. * @return void
  76. */
  77. public function addStructures($structures)
  78. {
  79. foreach($structures as $structure)
  80. {
  81. $this->addStructure($structure);
  82. }
  83. }
  84. /**
  85. * Responsible for adding a structure to the correct namespace
  86. *
  87. * @param \Meta\AbstractPHPStructure $structure The structure to add
  88. * @return void
  89. */
  90. public function addStructure(AbstractPHPStructure $structure)
  91. {
  92. $ns = $structure->getNamespace();
  93. if (!array_key_exists($ns, $this->namespaces))
  94. {
  95. $namespace = new PHPNamespace();
  96. $namespace->setName($ns);
  97. $this->namespaces[$ns] = $namespace;
  98. }
  99. $this->namespaces[$ns]->addStructure($structure);
  100. }
  101. /**
  102. * Gets the list of namespaces that have been parsed
  103. *
  104. * @return array
  105. */
  106. public function getNamespaces()
  107. {
  108. return $this->namespaces;
  109. }
  110. /**
  111. * Sets the list of namespaces
  112. *
  113. * @param array $namespaces An array of PHPNamespaces objects
  114. * @return void
  115. */
  116. public function setNamespaces($namespaces)
  117. {
  118. $this->namespaces = $namespaces;
  119. }
  120. /**
  121. * Responsible for checking if a directory is parseable
  122. * This just checks if it is a directory and not a dot
  123. *
  124. * @param \SplFileInfo $fileInfo Information about the file to check
  125. * @return bool
  126. */
  127. protected function isParseableDirectory($fileInfo)
  128. {
  129. return ($fileInfo->isDir() && !$fileInfo->isDot());
  130. }
  131. /**
  132. * Responsible for checking if a file is parseable
  133. * This checks that the extension is .php
  134. *
  135. * @param \SQLFileInfo $fileInfo Information about the file to check
  136. * @return bool
  137. */
  138. protected function isParseableFile($fileInfo)
  139. {
  140. $tmp = strtolower($fileInfo->getFileName());
  141. $pos = strrpos($tmp, ".");
  142. return ($pos !== false && (substr($tmp, $pos) == ".php"));
  143. }
  144. /**
  145. * Responsible for parsing a file
  146. *
  147. * @param string $file The full path to the file to parse
  148. * @return \Meta\AbstractPHPStructure[]
  149. */
  150. protected function parseFile($file)
  151. {
  152. $content = file_get_contents($file);
  153. $tokens = token_get_all($content);
  154. $parser = new FileParser();
  155. $parser->parse($tokens);
  156. return $parser->getStructures();
  157. }
  158. }