1<?php 2/* 3 * This file is part of the php-code-coverage package. 4 * 5 * (c) Sebastian Bergmann <sebastian@phpunit.de> 6 * 7 * For the full copyright and license information, please view the LICENSE 8 * file that was distributed with this source code. 9 */ 10 11namespace SebastianBergmann\CodeCoverage\Node; 12 13use SebastianBergmann\CodeCoverage\InvalidArgumentException; 14 15/** 16 * Represents a directory in the code coverage information tree. 17 */ 18class Directory extends AbstractNode implements \IteratorAggregate 19{ 20 /** 21 * @var AbstractNode[] 22 */ 23 private $children = []; 24 25 /** 26 * @var Directory[] 27 */ 28 private $directories = []; 29 30 /** 31 * @var File[] 32 */ 33 private $files = []; 34 35 /** 36 * @var array 37 */ 38 private $classes; 39 40 /** 41 * @var array 42 */ 43 private $traits; 44 45 /** 46 * @var array 47 */ 48 private $functions; 49 50 /** 51 * @var array 52 */ 53 private $linesOfCode = null; 54 55 /** 56 * @var int 57 */ 58 private $numFiles = -1; 59 60 /** 61 * @var int 62 */ 63 private $numExecutableLines = -1; 64 65 /** 66 * @var int 67 */ 68 private $numExecutedLines = -1; 69 70 /** 71 * @var int 72 */ 73 private $numClasses = -1; 74 75 /** 76 * @var int 77 */ 78 private $numTestedClasses = -1; 79 80 /** 81 * @var int 82 */ 83 private $numTraits = -1; 84 85 /** 86 * @var int 87 */ 88 private $numTestedTraits = -1; 89 90 /** 91 * @var int 92 */ 93 private $numMethods = -1; 94 95 /** 96 * @var int 97 */ 98 private $numTestedMethods = -1; 99 100 /** 101 * @var int 102 */ 103 private $numFunctions = -1; 104 105 /** 106 * @var int 107 */ 108 private $numTestedFunctions = -1; 109 110 /** 111 * Returns the number of files in/under this node. 112 * 113 * @return int 114 */ 115 public function count() 116 { 117 if ($this->numFiles == -1) { 118 $this->numFiles = 0; 119 120 foreach ($this->children as $child) { 121 $this->numFiles += count($child); 122 } 123 } 124 125 return $this->numFiles; 126 } 127 128 /** 129 * Returns an iterator for this node. 130 * 131 * @return \RecursiveIteratorIterator 132 */ 133 public function getIterator() 134 { 135 return new \RecursiveIteratorIterator( 136 new Iterator($this), 137 \RecursiveIteratorIterator::SELF_FIRST 138 ); 139 } 140 141 /** 142 * Adds a new directory. 143 * 144 * @param string $name 145 * 146 * @return Directory 147 */ 148 public function addDirectory($name) 149 { 150 $directory = new self($name, $this); 151 152 $this->children[] = $directory; 153 $this->directories[] = &$this->children[count($this->children) - 1]; 154 155 return $directory; 156 } 157 158 /** 159 * Adds a new file. 160 * 161 * @param string $name 162 * @param array $coverageData 163 * @param array $testData 164 * @param bool $cacheTokens 165 * 166 * @return File 167 * 168 * @throws InvalidArgumentException 169 */ 170 public function addFile($name, array $coverageData, array $testData, $cacheTokens) 171 { 172 $file = new File( 173 $name, 174 $this, 175 $coverageData, 176 $testData, 177 $cacheTokens 178 ); 179 180 $this->children[] = $file; 181 $this->files[] = &$this->children[count($this->children) - 1]; 182 183 $this->numExecutableLines = -1; 184 $this->numExecutedLines = -1; 185 186 return $file; 187 } 188 189 /** 190 * Returns the directories in this directory. 191 * 192 * @return array 193 */ 194 public function getDirectories() 195 { 196 return $this->directories; 197 } 198 199 /** 200 * Returns the files in this directory. 201 * 202 * @return array 203 */ 204 public function getFiles() 205 { 206 return $this->files; 207 } 208 209 /** 210 * Returns the child nodes of this node. 211 * 212 * @return array 213 */ 214 public function getChildNodes() 215 { 216 return $this->children; 217 } 218 219 /** 220 * Returns the classes of this node. 221 * 222 * @return array 223 */ 224 public function getClasses() 225 { 226 if ($this->classes === null) { 227 $this->classes = []; 228 229 foreach ($this->children as $child) { 230 $this->classes = array_merge( 231 $this->classes, 232 $child->getClasses() 233 ); 234 } 235 } 236 237 return $this->classes; 238 } 239 240 /** 241 * Returns the traits of this node. 242 * 243 * @return array 244 */ 245 public function getTraits() 246 { 247 if ($this->traits === null) { 248 $this->traits = []; 249 250 foreach ($this->children as $child) { 251 $this->traits = array_merge( 252 $this->traits, 253 $child->getTraits() 254 ); 255 } 256 } 257 258 return $this->traits; 259 } 260 261 /** 262 * Returns the functions of this node. 263 * 264 * @return array 265 */ 266 public function getFunctions() 267 { 268 if ($this->functions === null) { 269 $this->functions = []; 270 271 foreach ($this->children as $child) { 272 $this->functions = array_merge( 273 $this->functions, 274 $child->getFunctions() 275 ); 276 } 277 } 278 279 return $this->functions; 280 } 281 282 /** 283 * Returns the LOC/CLOC/NCLOC of this node. 284 * 285 * @return array 286 */ 287 public function getLinesOfCode() 288 { 289 if ($this->linesOfCode === null) { 290 $this->linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0]; 291 292 foreach ($this->children as $child) { 293 $linesOfCode = $child->getLinesOfCode(); 294 295 $this->linesOfCode['loc'] += $linesOfCode['loc']; 296 $this->linesOfCode['cloc'] += $linesOfCode['cloc']; 297 $this->linesOfCode['ncloc'] += $linesOfCode['ncloc']; 298 } 299 } 300 301 return $this->linesOfCode; 302 } 303 304 /** 305 * Returns the number of executable lines. 306 * 307 * @return int 308 */ 309 public function getNumExecutableLines() 310 { 311 if ($this->numExecutableLines == -1) { 312 $this->numExecutableLines = 0; 313 314 foreach ($this->children as $child) { 315 $this->numExecutableLines += $child->getNumExecutableLines(); 316 } 317 } 318 319 return $this->numExecutableLines; 320 } 321 322 /** 323 * Returns the number of executed lines. 324 * 325 * @return int 326 */ 327 public function getNumExecutedLines() 328 { 329 if ($this->numExecutedLines == -1) { 330 $this->numExecutedLines = 0; 331 332 foreach ($this->children as $child) { 333 $this->numExecutedLines += $child->getNumExecutedLines(); 334 } 335 } 336 337 return $this->numExecutedLines; 338 } 339 340 /** 341 * Returns the number of classes. 342 * 343 * @return int 344 */ 345 public function getNumClasses() 346 { 347 if ($this->numClasses == -1) { 348 $this->numClasses = 0; 349 350 foreach ($this->children as $child) { 351 $this->numClasses += $child->getNumClasses(); 352 } 353 } 354 355 return $this->numClasses; 356 } 357 358 /** 359 * Returns the number of tested classes. 360 * 361 * @return int 362 */ 363 public function getNumTestedClasses() 364 { 365 if ($this->numTestedClasses == -1) { 366 $this->numTestedClasses = 0; 367 368 foreach ($this->children as $child) { 369 $this->numTestedClasses += $child->getNumTestedClasses(); 370 } 371 } 372 373 return $this->numTestedClasses; 374 } 375 376 /** 377 * Returns the number of traits. 378 * 379 * @return int 380 */ 381 public function getNumTraits() 382 { 383 if ($this->numTraits == -1) { 384 $this->numTraits = 0; 385 386 foreach ($this->children as $child) { 387 $this->numTraits += $child->getNumTraits(); 388 } 389 } 390 391 return $this->numTraits; 392 } 393 394 /** 395 * Returns the number of tested traits. 396 * 397 * @return int 398 */ 399 public function getNumTestedTraits() 400 { 401 if ($this->numTestedTraits == -1) { 402 $this->numTestedTraits = 0; 403 404 foreach ($this->children as $child) { 405 $this->numTestedTraits += $child->getNumTestedTraits(); 406 } 407 } 408 409 return $this->numTestedTraits; 410 } 411 412 /** 413 * Returns the number of methods. 414 * 415 * @return int 416 */ 417 public function getNumMethods() 418 { 419 if ($this->numMethods == -1) { 420 $this->numMethods = 0; 421 422 foreach ($this->children as $child) { 423 $this->numMethods += $child->getNumMethods(); 424 } 425 } 426 427 return $this->numMethods; 428 } 429 430 /** 431 * Returns the number of tested methods. 432 * 433 * @return int 434 */ 435 public function getNumTestedMethods() 436 { 437 if ($this->numTestedMethods == -1) { 438 $this->numTestedMethods = 0; 439 440 foreach ($this->children as $child) { 441 $this->numTestedMethods += $child->getNumTestedMethods(); 442 } 443 } 444 445 return $this->numTestedMethods; 446 } 447 448 /** 449 * Returns the number of functions. 450 * 451 * @return int 452 */ 453 public function getNumFunctions() 454 { 455 if ($this->numFunctions == -1) { 456 $this->numFunctions = 0; 457 458 foreach ($this->children as $child) { 459 $this->numFunctions += $child->getNumFunctions(); 460 } 461 } 462 463 return $this->numFunctions; 464 } 465 466 /** 467 * Returns the number of tested functions. 468 * 469 * @return int 470 */ 471 public function getNumTestedFunctions() 472 { 473 if ($this->numTestedFunctions == -1) { 474 $this->numTestedFunctions = 0; 475 476 foreach ($this->children as $child) { 477 $this->numTestedFunctions += $child->getNumTestedFunctions(); 478 } 479 } 480 481 return $this->numTestedFunctions; 482 } 483} 484