class PHP_CodeCoverage_Util

Utility methods.

@category PHP @package CodeCoverage @author Sebastian Bergmann <sebastian@phpunit.de> @copyright 2009-2013 Sebastian Bergmann <sebastian@phpunit.de> @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License @link http://github.com/sebastianbergmann/php-code-coverage @since Class available since Release 1.0.0

Hierarchy

Expanded class hierarchy of PHP_CodeCoverage_Util

File

drupal/core/vendor/phpunit/php-code-coverage/PHP/CodeCoverage/Util.php, line 57

View source
class PHP_CodeCoverage_Util {

  /**
   * @var array
   */
  protected static $ignoredLines = array();

  /**
   * @var array
   */
  protected static $ids = array();

  /**
   * Returns the lines of a source file that should be ignored.
   *
   * @param  string  $filename
   * @param  boolean $cacheTokens
   * @return array
   * @throws PHP_CodeCoverage_Exception
   */
  public static function getLinesToBeIgnored($filename, $cacheTokens = TRUE) {
    if (!is_string($filename)) {
      throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(1, 'string');
    }
    if (!is_bool($cacheTokens)) {
      throw PHP_CodeCoverage_Util_InvalidArgumentHelper::factory(2, 'boolean');
    }
    if (!isset(self::$ignoredLines[$filename])) {
      self::$ignoredLines[$filename] = array();
      $ignore = FALSE;
      $stop = FALSE;
      $lines = file($filename);
      foreach ($lines as $index => $line) {
        if (!trim($line)) {
          self::$ignoredLines[$filename][$index + 1] = TRUE;
        }
      }
      if ($cacheTokens) {
        $tokens = PHP_Token_Stream_CachingFactory::get($filename);
      }
      else {
        $tokens = new PHP_Token_Stream($filename);
      }
      $classes = array_merge($tokens
        ->getClasses(), $tokens
        ->getTraits());
      $tokens = $tokens
        ->tokens();
      foreach ($tokens as $token) {
        switch (get_class($token)) {
          case 'PHP_Token_COMMENT':
          case 'PHP_Token_DOC_COMMENT':
            $_token = trim($token);
            $_line = trim($lines[$token
              ->getLine() - 1]);
            if ($_token == '// @codeCoverageIgnore' || $_token == '//@codeCoverageIgnore') {
              $ignore = TRUE;
              $stop = TRUE;
            }
            else {
              if ($_token == '// @codeCoverageIgnoreStart' || $_token == '//@codeCoverageIgnoreStart') {
                $ignore = TRUE;
              }
              else {
                if ($_token == '// @codeCoverageIgnoreEnd' || $_token == '//@codeCoverageIgnoreEnd') {
                  $stop = TRUE;
                }
              }
            }

            // be sure the comment doesn't have some token BEFORE it on the same line...
            // it would not be safe to ignore the whole line in those cases.
            if (0 === strpos($_token, $_line)) {
              $count = substr_count($token, "\n");
              $line = $token
                ->getLine();
              for ($i = $line; $i < $line + $count; $i++) {
                self::$ignoredLines[$filename][$i] = TRUE;
              }
              if ($token instanceof PHP_Token_DOC_COMMENT) {

                // Workaround for the fact the DOC_COMMENT token
                // does not include the final \n character in its
                // text.
                if (substr(trim($lines[$i - 1]), -2) == '*/') {
                  self::$ignoredLines[$filename][$i] = TRUE;
                }
              }
            }
            break;
          case 'PHP_Token_INTERFACE':
          case 'PHP_Token_TRAIT':
          case 'PHP_Token_CLASS':
          case 'PHP_Token_FUNCTION':
            $docblock = $token
              ->getDocblock();
            if (strpos($docblock, '@codeCoverageIgnore')) {
              $endLine = $token
                ->getEndLine();
              for ($i = $token
                ->getLine(); $i <= $endLine; $i++) {
                self::$ignoredLines[$filename][$i] = TRUE;
              }
            }
            else {
              if ($token instanceof PHP_Token_INTERFACE || $token instanceof PHP_Token_TRAIT || $token instanceof PHP_Token_CLASS) {
                if (empty($classes[$token
                  ->getName()]['methods'])) {
                  for ($i = $token
                    ->getLine(); $i <= $token
                    ->getEndLine(); $i++) {
                    self::$ignoredLines[$filename][$i] = TRUE;
                  }
                }
                else {
                  $firstMethod = array_shift($classes[$token
                    ->getName()]['methods']);
                  $lastMethod = array_pop($classes[$token
                    ->getName()]['methods']);
                  if ($lastMethod === NULL) {
                    $lastMethod = $firstMethod;
                  }
                  for ($i = $token
                    ->getLine(); $i < $firstMethod['startLine']; $i++) {
                    self::$ignoredLines[$filename][$i] = TRUE;
                  }
                  for ($i = $token
                    ->getEndLine(); $i > $lastMethod['endLine']; $i--) {
                    self::$ignoredLines[$filename][$i] = TRUE;
                  }
                }
              }
            }
            break;
          case 'PHP_Token_INTERFACE':
            $endLine = $token
              ->getEndLine();
            for ($i = $token
              ->getLine(); $i <= $endLine; $i++) {
              self::$ignoredLines[$filename][$i] = TRUE;
            }
            break;
          case 'PHP_Token_NAMESPACE':
            self::$ignoredLines[$filename][$token
              ->getEndLine()] = TRUE;

          // Intentional fallthrough
          case 'PHP_Token_OPEN_TAG':
          case 'PHP_Token_CLOSE_TAG':
          case 'PHP_Token_USE':
            self::$ignoredLines[$filename][$token
              ->getLine()] = TRUE;
            break;
        }
        if ($ignore) {
          self::$ignoredLines[$filename][$token
            ->getLine()] = TRUE;
          if ($stop) {
            $ignore = FALSE;
            $stop = FALSE;
          }
        }
      }
    }
    return self::$ignoredLines[$filename];
  }

  /**
   * @param  float $a
   * @param  float $b
   * @return float ($a / $b) * 100
   */
  public static function percent($a, $b, $asString = FALSE, $fixedWidth = FALSE) {
    if ($asString && $b == 0) {
      return '';
    }
    if ($b > 0) {
      $percent = $a / $b * 100;
    }
    else {
      $percent = 100;
    }
    if ($asString) {
      if ($fixedWidth) {
        return sprintf('%6.2F%%', $percent);
      }
      return sprintf('%01.2F%%', $percent);
    }
    else {
      return $percent;
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
PHP_CodeCoverage_Util::$ids protected static property
PHP_CodeCoverage_Util::$ignoredLines protected static property
PHP_CodeCoverage_Util::getLinesToBeIgnored public static function Returns the lines of a source file that should be ignored.
PHP_CodeCoverage_Util::percent public static function