Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Refactor.

  • Loading branch information...
commit bfebe7705a7850de5c4552edc33089f5078dc10c 1 parent febf71d
@sebastianbergmann authored
View
8 .gitignore
@@ -3,5 +3,11 @@ build/code-browser
build/coverage
build/logs
build/pdepend
+build/phar
+build/phpdox
+build/SebastianBergmann
+build/phpcpd.bat
+build/phpcpd.php
+build/*.phar
+build/*.tgz
cache.properties
-phpunit.xml
View
33 LICENSE
@@ -0,0 +1,33 @@
+phploc
+
+Copyright (c) 2009-2012, Sebastian Bergmann <sebastian@phpunit.de>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ * Neither the name of Sebastian Bergmann nor the names of his
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
View
665 PHPLOC/Analyser.php
@@ -1,665 +0,0 @@
-<?php
-/**
- * phploc
- *
- * Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * * Neither the name of Sebastian Bergmann nor the names of his
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package phploc
- * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
- * @since File available since Release 1.0.0
- */
-
-if (!defined('T_TRAIT')) {
- define('T_TRAIT', 1000);
-}
-
-/**
- * PHPLOC code analyser.
- *
- * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
- * @link http://github.com/sebastianbergmann/phploc/tree
- * @since Class available since Release 1.0.0
- */
-class PHPLOC_Analyser
-{
- /**
- * @var array
- */
- protected $namespaces = array();
-
- /**
- * @var array
- */
- protected $classes = array();
-
- /**
- * @var array
- */
- protected $count = array(
- 'files' => 0,
- 'loc' => 0,
- 'nclocClasses' => 0,
- 'cloc' => 0,
- 'ncloc' => 0,
- 'eloc' => 0,
- 'ccn' => 0,
- 'ccnMethods' => 0,
- 'interfaces' => 0,
- 'traits' => 0,
- 'classes' => 0,
- 'abstractClasses' => 0,
- 'concreteClasses' => 0,
- 'anonymousFunctions' => 0,
- 'functions' => 0,
- 'methods' => 0,
- 'publicMethods' => 0,
- 'nonPublicMethods' => 0,
- 'nonStaticMethods' => 0,
- 'staticMethods' => 0,
- 'constants' => 0,
- 'classConstants' => 0,
- 'globalConstants' => 0,
- 'testClasses' => 0,
- 'testMethods' => 0,
- 'ccnByLoc' => 0,
- 'ccnByNom' => 0,
- 'nclocByNoc' => 0,
- 'nclocByNom' => 0
- );
-
- /**
- * @var array
- */
- protected $opcodeBlacklist = array(
- 'BYTEKIT_NOP' => TRUE
- );
-
- /**
- * @var ezcConsoleOutput
- */
- protected $output;
-
- /**
- * Constructor.
- *
- * @param ezcConsoleOutput $output
- * @since Method available since Release 1.5.0
- */
- public function __construct(ezcConsoleOutput $output = NULL)
- {
- $this->output = $output;
- }
-
- /**
- * Processes a set of files.
- *
- * @param array $files
- * @param boolean $countTests
- * @return array
- * @since Method available since Release 1.2.0
- */
- public function countFiles(array $files, $countTests)
- {
- if ($countTests) {
- if ($this->output !== NULL) {
- $bar = new ezcConsoleProgressbar($this->output, count($files));
- print "Preprocessing files\n";
- }
-
- foreach ($files as $file) {
- $this->preProcessFile($file);
-
- if ($this->output !== NULL) {
- $bar->advance();
- }
- }
-
- if ($this->output !== NULL) {
- print "\n\n";
- }
- }
-
- $directories = array();
-
- if ($this->output !== NULL) {
- $bar = new ezcConsoleProgressbar($this->output, count($files));
- print "Processing files\n";
- }
-
- foreach ($files as $file) {
- $directory = dirname($file);
-
- if (!isset($directories[$directory])) {
- $directories[$directory] = TRUE;
- }
-
- $this->countFile($file, $countTests);
-
- if ($this->output !== NULL) {
- $bar->advance();
- }
- }
-
- if ($this->output !== NULL) {
- print "\n\n";
- }
-
- $count = $this->count;
-
- if (!function_exists('bytekit_disassemble_file')) {
- unset($count['eloc']);
- }
-
- if (!$countTests) {
- unset($count['testClasses']);
- unset($count['testMethods']);
- }
-
- $count['directories'] = count($directories) - 1;
- $count['namespaces'] = count($this->namespaces);
- $count['classes'] = $count['abstractClasses'] +
- $count['concreteClasses'];
- $count['methods'] = $count['staticMethods'] +
- $count['nonStaticMethods'];
- $count['publicMethods'] = $count['methods'] -
- $count['nonPublicMethods'];
- $count['constants'] = $count['classConstants'] +
- $count['globalConstants'];
-
- if (isset($count['eloc']) && $count['eloc'] > 0) {
- $count['ccnByLoc'] = $count['ccn'] / $count['eloc'];
- }
-
- else if ($count['ncloc'] > 0) {
- $count['ccnByLoc'] = $count['ccn'] / $count['ncloc'];
- }
-
- if ($count['methods'] > 0) {
- if(isset($count['testMethods'])) {
- $countTestMethods = $count['testMethods'];
- } else {
- $countTestMethods = 0;
- }
- $count['ccnByNom'] = 1 + ($count['ccnMethods'] /
- ($count['methods'] - $countTestMethods));
- }
-
- if ($count['classes'] > 0) {
- $count['nclocByNoc'] = $count['nclocClasses'] / $count['classes'];
- }
-
- if ($count['methods'] > 0) {
- $count['nclocByNom'] = $count['nclocClasses'] / $count['methods'];
- }
-
- return $count;
- }
-
- /**
- * Pre-processes a single file.
- *
- * @param string $filename
- * @since Method available since Release 1.2.0
- */
- public function preProcessFile($filename)
- {
- $tokens = token_get_all(file_get_contents($filename));
- $numTokens = count($tokens);
- $namespace = FALSE;
-
- for ($i = 0; $i < $numTokens; $i++) {
- if (is_string($tokens[$i])) {
- continue;
- }
-
- list ($token, $value) = $tokens[$i];
-
- switch ($token) {
- case T_NAMESPACE: {
- $namespace = $this->getNamespaceName($tokens, $i);
- }
- break;
-
- case T_CLASS: {
- $className = $this->getClassName($namespace, $tokens, $i);
-
- if (isset($tokens[$i+4]) && is_array($tokens[$i+4]) &&
- $tokens[$i+4][0] == T_EXTENDS) {
- $parent = $this->getClassName(
- $namespace, $tokens, $i + 4
- );
- } else {
- $parent = NULL;
- }
-
- $this->classes[$className] = $parent;
- }
- break;
- }
- }
- }
-
- /**
- * Processes a single file.
- *
- * @param string $filename
- * @param boolean $countTests
- */
- public function countFile($filename, $countTests)
- {
- $buffer = file_get_contents($filename);
- $tokens = token_get_all($buffer);
- $numTokens = count($tokens);
- $loc = substr_count($buffer, "\n");
-
- unset($buffer);
-
- $nclocClasses = 0;
- $cloc = 0;
- $blocks = array();
- $currentBlock = FALSE;
- $namespace = FALSE;
- $className = NULL;
- $functionName = NULL;
- $testClass = FALSE;
-
- for ($i = 0; $i < $numTokens; $i++) {
- if (is_string($tokens[$i])) {
- if (trim($tokens[$i]) == '?') {
- if (!$testClass) {
- if ($className !== NULL) {
- $this->count['ccnMethods']++;
- }
-
- $this->count['ccn']++;
- }
- }
-
- if ($tokens[$i] == '{') {
- if ($currentBlock == T_CLASS) {
- $block = $className;
- }
-
- else if ($currentBlock == T_FUNCTION) {
- $block = $functionName;
- }
-
- else {
- $block = FALSE;
- }
-
- array_push($blocks, $block);
-
- $currentBlock = FALSE;
- }
-
- else if ($tokens[$i] == '}') {
- $block = array_pop($blocks);
-
- if ($block !== FALSE && $block !== NULL) {
- if ($block == $functionName) {
- $functionName = NULL;
- }
-
- else if ($block == $className) {
- $className = NULL;
- $testClass = FALSE;
- }
- }
- }
-
- continue;
- }
-
- list ($token, $value) = $tokens[$i];
-
- if ($className !== NULL) {
- if ($token != T_COMMENT && $token != T_DOC_COMMENT) {
- $nclocClasses += substr_count($value, "\n");
- }
- }
-
- switch ($token) {
- case T_NAMESPACE: {
- $namespace = $this->getNamespaceName($tokens, $i);
-
- if (!isset($this->namespaces[$namespace])) {
- $this->namespaces[$namespace] = TRUE;
- }
- }
- break;
-
- case T_CLASS:
- case T_INTERFACE:
- case T_TRAIT: {
- $className = $this->getClassName(
- $namespace, $tokens, $i
- );
- $currentBlock = T_CLASS;
-
- if ($token == T_TRAIT) {
- $this->count['traits']++;
- }
-
- else if ($token == T_INTERFACE) {
- $this->count['interfaces']++;
- }
-
- else {
- if ($countTests && $this->isTestClass($className)) {
- $testClass = TRUE;
- $this->count['testClasses']++;
- } else {
- if (isset($tokens[$i-2]) &&
- is_array($tokens[$i-2]) &&
- $tokens[$i-2][0] == T_ABSTRACT) {
- $this->count['abstractClasses']++;
- } else {
- $this->count['concreteClasses']++;
- }
- }
- }
- }
- break;
-
- case T_FUNCTION: {
- $currentBlock = T_FUNCTION;
-
- if (is_array($tokens[$i+2]) &&
- $tokens[$i+2][0] == T_STRING) {
- $functionName = $tokens[$i+2][1];
- }
-
- else if ($tokens[$i+2] == '&' &&
- is_array($tokens[$i+3]) &&
- $tokens[$i+3][0] == T_STRING) {
- $functionName = $tokens[$i+3][1];
- }
-
- else {
- $currentBlock = 'anonymous function';
- $functionName = 'anonymous function';
- $this->count['anonymousFunctions']++;
- }
-
- if ($currentBlock == T_FUNCTION) {
- if ($className === NULL) {
- $this->count['functions']++;
- } else {
- $static = FALSE;
- $visibility = T_PUBLIC;
-
- for ($j = $i; $j > 0; $j--) {
- if (is_string($tokens[$j])) {
- if ($tokens[$j] == '{' || $tokens[$j] == '}') {
- break;
- }
-
- continue;
- }
-
- if (isset($tokens[$j][0])) {
- switch ($tokens[$j][0]) {
- case T_PRIVATE: {
- $visibility = T_PRIVATE;
- }
- break;
-
- case T_PROTECTED: {
- $visibility = T_PROTECTED;
- }
- break;
-
- case T_STATIC: {
- $static = TRUE;
- }
- break;
- }
- }
- }
-
- if ($testClass &&
- strpos($functionName, 'test') === 0 &&
- $visibility == T_PUBLIC &&
- !$static) {
- $this->count['testMethods']++;
- }
-
- else if (!$testClass) {
- if ($static) {
- $this->count['staticMethods']++;
- } else {
- $this->count['nonStaticMethods']++;
- }
-
- if ($visibility != T_PUBLIC) {
- $this->count['nonPublicMethods']++;
- }
- }
- }
- }
- }
- break;
-
- case T_CURLY_OPEN: {
- $currentBlock = T_CURLY_OPEN;
- array_push($blocks, $currentBlock);
- }
- break;
-
- case T_DOLLAR_OPEN_CURLY_BRACES: {
- $currentBlock = T_DOLLAR_OPEN_CURLY_BRACES;
- array_push($blocks, $currentBlock);
- }
- break;
-
- case T_IF:
- case T_ELSEIF:
- case T_FOR:
- case T_FOREACH:
- case T_WHILE:
- case T_CASE:
- case T_CATCH:
- case T_BOOLEAN_AND:
- case T_LOGICAL_AND:
- case T_BOOLEAN_OR:
- case T_LOGICAL_OR: {
- if (!$testClass) {
- if ($className !== NULL) {
- $this->count['ccnMethods']++;
- }
-
- $this->count['ccn']++;
- }
- }
- break;
-
- case T_COMMENT:
- case T_DOC_COMMENT: {
- $cloc += substr_count($value, "\n") + 1;
- }
- break;
-
- case T_CONST: {
- $this->count['classConstants']++;
- }
- break;
-
- case T_STRING: {
- if ($value == 'define') {
- $this->count['globalConstants']++;
- }
- }
- break;
- }
- }
-
- $this->count['loc'] += $loc;
- $this->count['nclocClasses'] += $nclocClasses;
- $this->count['cloc'] += $cloc;
- $this->count['ncloc'] += $loc - $cloc;
- $this->count['files']++;
-
- if (function_exists('bytekit_disassemble_file')) {
- $this->count['eloc'] += $this->countEloc($filename, $loc);
- }
- }
-
- /**
- * Counts the Executable Lines of Code (ELOC) using Bytekit.
- *
- * @param string $filename
- * @param integer $loc
- * @return integer
- * @since Method available since Release 1.1.0
- */
- protected function countEloc($filename, $loc)
- {
- $bytecode = @bytekit_disassemble_file($filename);
-
- if (!is_array($bytecode)) {
- return 0;
- }
-
- $lines = array();
-
- foreach ($bytecode['functions'] as $function) {
- foreach ($function['raw']['opcodes'] as $opline) {
- if ($opline['lineno'] <= $loc &&
- !isset($this->opcodeBlacklist[$opline['opcode']]) &&
- !isset($lines[$opline['lineno']])) {
- $lines[$opline['lineno']] = TRUE;
- }
- }
- }
-
- return count($lines);
- }
-
- /**
- * @param array $tokens
- * @param integer $i
- * @return string
- * @since Method available since Release 1.3.0
- */
- protected function getNamespaceName(array $tokens, $i)
- {
- if (isset($tokens[$i+2][1])) {
- $namespace = $tokens[$i+2][1];
-
- for ($j = $i+3; ; $j += 2) {
- if (isset($tokens[$j]) && $tokens[$j][0] == T_NS_SEPARATOR) {
- $namespace .= '\\' . $tokens[$j+1][1];
- } else {
- break;
- }
- }
-
- return $namespace;
- }
-
- return FALSE;
- }
-
- /**
- * @param string $namespace
- * @param array $tokens
- * @param integer $i
- * @return string
- * @since Method available since Release 1.3.0
- */
- protected function getClassName($namespace, array $tokens, $i)
- {
- $i += 2;
- $namespaced = FALSE;
- $className = $tokens[$i][1];
-
- if ($className === '\\') {
- $namespaced = TRUE;
- }
-
- while (is_array($tokens[$i+1]) && $tokens[$i+1][0] !== T_WHITESPACE) {
- $className .= $tokens[++$i][1];
- }
-
- if (!$namespaced && $namespace !== FALSE) {
- $className = $namespace . '\\' . $className;
- }
-
- return $className;
- }
-
- /**
- * @param string $className
- * @return boolean
- * @since Method available since Release 1.2.0
- */
- protected function isTestClass($className)
- {
- $parent = $this->classes[$className];
- $result = FALSE;
-
- // Check ancestry for PHPUnit_Framework_TestCase.
- while ($parent !== NULL) {
- if ($parent == 'PHPUnit_Framework_TestCase' ||
- $parent == '\\PHPUnit_Framework_TestCase') {
- $result = TRUE;
- break;
- }
-
- if (isset($this->classes[$parent])) {
- $parent = $this->classes[$parent];
- }
-
- // Class has a parent that is declared in a file
- // that was not pre-processed.
- else {
- break;
- }
- }
-
- // Fallback: Treat the class as a test case class if the name
- // of the parent class ends with "TestCase".
- if (!$result) {
- if (substr($this->classes[$className], -8) == 'TestCase') {
- $result = TRUE;
- }
- }
-
- return $result;
- }
-}
View
313 PHPLOC/TextUI/Command.php
@@ -1,313 +0,0 @@
-<?php
-/**
- * phploc
- *
- * Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * * Neither the name of Sebastian Bergmann nor the names of his
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package phploc
- * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
- * @since File available since Release 1.0.0
- */
-
-/**
- * TextUI frontend for PHPLOC.
- *
- * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
- * @link http://github.com/sebastianbergmann/phploc/tree
- * @since Class available since Release 1.0.0
- */
-class PHPLOC_TextUI_Command
-{
- /**
- * Main method.
- */
- public function main()
- {
- $input = new ezcConsoleInput;
- $output = new ezcConsoleOutput;
-
- $input->registerOption(
- new ezcConsoleOption(
- '',
- 'count-tests',
- ezcConsoleInput::TYPE_NONE,
- FALSE,
- FALSE
- )
- );
-
- $input->registerOption(
- new ezcConsoleOption(
- '',
- 'exclude',
- ezcConsoleInput::TYPE_STRING,
- array(),
- TRUE
- )
- );
-
- $input->registerOption(
- new ezcConsoleOption(
- 'h',
- 'help',
- ezcConsoleInput::TYPE_NONE,
- NULL,
- FALSE,
- '',
- '',
- array(),
- array(),
- FALSE,
- FALSE,
- TRUE
- )
- );
-
- $input->registerOption(
- new ezcConsoleOption(
- '',
- 'log-xml',
- ezcConsoleInput::TYPE_STRING
- )
- );
-
- $input->registerOption(
- new ezcConsoleOption(
- '',
- 'log-csv',
- ezcConsoleInput::TYPE_STRING
- )
- );
-
- $input->registerOption(
- new ezcConsoleOption(
- '',
- 'suffixes',
- ezcConsoleInput::TYPE_STRING,
- 'php',
- FALSE
- )
- );
-
- $input->registerOption(
- new ezcConsoleOption(
- 'v',
- 'version',
- ezcConsoleInput::TYPE_NONE,
- NULL,
- FALSE,
- '',
- '',
- array(),
- array(),
- FALSE,
- FALSE,
- TRUE
- )
- );
-
- $input->registerOption(
- new ezcConsoleOption(
- '',
- 'progress',
- ezcConsoleInput::TYPE_NONE
- )
- );
-
- try {
- $input->process();
- }
-
- catch (ezcConsoleOptionException $e) {
- print $e->getMessage() . "\n";
- exit(1);
- }
-
- if ($input->getOption('help')->value) {
- $this->showHelp();
- exit(0);
- }
-
- else if ($input->getOption('version')->value) {
- $this->printVersionString();
- exit(0);
- }
-
- $arguments = $input->getArguments();
-
- if (empty($arguments)) {
- $this->showHelp();
- exit(1);
- }
-
- $countTests = $input->getOption('count-tests')->value;
- $excludes = $input->getOption('exclude')->value;
- $logXml = $input->getOption('log-xml')->value;
- $logCsv = $input->getOption('log-csv')->value;
- $suffixes = array_map(
- 'trim',
- explode(',', $input->getOption('suffixes')->value)
- );
-
- if ($input->getOption('progress')->value !== FALSE) {
- $progress = $output;
- } else {
- $progress = NULL;
- }
-
- $this->printVersionString();
-
- $files = $this->findFiles($arguments, $excludes, $suffixes);
-
- if (empty($files)) {
- $this->showError("No files found to scan.\n");
- }
-
- $analyser = new PHPLOC_Analyser($progress);
- $count = $analyser->countFiles($files, $countTests);
-
- $printer = new PHPLOC_TextUI_ResultPrinter_Text;
- $printer->printResult($count, $countTests);
-
- if ($logXml) {
- $printer = new PHPLOC_TextUI_ResultPrinter_XML;
- $printer->printResult($logXml, $count);
- }
-
- if ($logCsv) {
- $printer = new PHPLOC_TextUI_ResultPrinter_CSV;
- $printer->printResult($logCsv, $count);
- }
- }
-
- /**
- * Shows an error.
- *
- * @param string $message
- */
- protected function showError($message)
- {
- $this->printVersionString();
-
- print $message;
-
- exit(1);
- }
-
- /**
- * Shows the help.
- */
- protected function showHelp()
- {
- $this->printVersionString();
-
- print <<<EOT
-Usage: phploc [switches] <directory|file> ...
-
- --count-tests Count PHPUnit test case classes and test methods.
-
- --log-xml <file> Write result in XML format to file.
- --log-csv <file> Write result in CSV format to file.
-
- --exclude <directory> Exclude <directory> from code analysis.
- --suffixes <suffix,...> A comma-separated list of file suffixes to check.
-
- --help Prints this usage information.
- --version Prints the version and exits.
-
- --progress Print progress bar.
-
-EOT
-;
- }
-
- /**
- * Prints the version string.
- */
- protected function printVersionString()
- {
- printf(
- "phploc %s by Sebastian Bergmann.\n\n", PHPLOC_Version::id()
- );
- }
-
- /**
- * @param array $directories
- * @param array $excludes
- * @param array $suffixes
- * @return array
- * @since Method available since Release 1.7.0
- */
- protected function findFiles(array $directories, array $excludes, array $suffixes)
- {
- $files = array();
- $finder = new Symfony\Component\Finder\Finder;
- $iterate = FALSE;
-
- try {
- foreach ($directories as $directory) {
- if (!is_file($directory)) {
- $finder->in($directory);
- $iterate = TRUE;
- } else {
- $files[] = realpath($directory);
- }
- }
-
- foreach ($excludes as $exclude) {
- $finder->exclude($exclude);
- }
-
- foreach ($suffixes as $suffix) {
- $finder->name('*' . $suffix);
- }
- }
-
- catch (Exception $e) {
- $this->showError($e->getMessage() . "\n");
- exit(1);
- }
-
- if ($iterate) {
- foreach ($finder as $file) {
- $files[] = $file->getRealpath();
- }
- }
-
- return $files;
- }
-}
View
137 PHPLOC/TextUI/ResultPrinter/CSV.php
@@ -1,137 +0,0 @@
-<?php
-/**
- * phploc
- *
- * Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * * Neither the name of Sebastian Bergmann nor the names of his
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package phploc
- * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
- * @since File available since Release 1.6.0
- */
-
-/**
- * A CSV ResultPrinter for the TextUI.
- *
- * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
- * @link http://github.com/sebastianbergmann/phploc/tree
- * @since Class available since Release 1.6.0
- */
-class PHPLOC_TextUI_ResultPrinter_CSV
-{
- /**
- * Prints a result set.
- *
- * @param string $filename
- * @param array $count
- */
- public function printResult($filename, array $count)
- {
- $keys = array();
- $values = array();
-
- if ($count['directories'] > 0) {
- $keys[] = 'Directories';
- $values[] = $count['directories'];
- $keys[] = 'Files';
- $values[] = $count['files'];
- }
-
- $keys[] = 'Lines of Code (LOC)';
- $values[] = $count['loc'];
- $keys[] = 'Cyclomatic Complexity / Lines of Code';
- $values[] = $count['ccnByLoc'];
-
- if (isset($count['eloc'])) {
- $keys[] = 'Executable Lines of Code (ELOC)';
- $values[] = $count['eloc'];
- }
-
- $keys[] = 'Comment Lines of Code (CLOC)';
- $values[] = $count['cloc'];
- $keys[] = 'Non-Comment Lines of Code (NCLOC)';
- $values[] = $count['ncloc'];
- $keys[] = 'Namespaces';
- $values[] = $count['namespaces'];
- $keys[] = 'Interfaces';
- $values[] = $count['interfaces'];
- $keys[] = 'Traits';
- $values[] = $count['traits'];
- $keys[] = 'Classes';
- $values[] = $count['classes'];
- $keys[] = 'Abstract Classes';
- $values[] = $count['abstractClasses'];
- $keys[] = 'Concrete Classes';
- $values[] = $count['concreteClasses'];
- $keys[] = 'Average Class Length (NCLOC)';
- $values[] = $count['nclocByNoc'];
- $keys[] = 'Methods';
- $values[] = $count['methods'];
- $keys[] = 'Non-Static Methods';
- $values[] = $count['nonStaticMethods'];
- $keys[] = 'Static Methods';
- $values[] = $count['staticMethods'];
- $keys[] = 'Public Methods';
- $values[] = $count['publicMethods'];
- $keys[] = 'Non-Public Methods';
- $values[] = $count['nonPublicMethods'];
- $keys[] = 'Average Method Length (NCLOC)';
- $values[] = $count['nclocByNom'];
- $keys[] = 'Cyclomatic Complexity / Number of Methods';
- $values[] = $count['ccnByNom'];
- $keys[] = 'Anonymous Functions';
- $values[] = $count['anonymousFunctions'];
- $keys[] = 'Functions';
- $values[] = $count['functions'];
- $keys[] = 'Constants';
- $values[] = $count['constants'];
- $keys[] = 'Global Constants';
- $values[] = $count['globalConstants'];
- $keys[] = 'Class Constants';
- $values[] = $count['classConstants'];
-
- if (isset($count['testClasses'])) {
- $keys[] = 'Test Clases';
- $values[] = $count['testClasses'];
- $keys[] = 'Test Methods';
- $values[] = $count['testMethods'];
- }
-
- file_put_contents(
- $filename, implode(',', $keys) . PHP_EOL . implode(',', $values)
- );
- }
-}
View
144 PHPLOC/TextUI/ResultPrinter/Text.php
@@ -1,144 +0,0 @@
-<?php
-/**
- * phploc
- *
- * Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * * Neither the name of Sebastian Bergmann nor the names of his
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * @package phploc
- * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
- * @since File available since Release 1.1.0
- */
-
-/**
- * A ResultPrinter for the TextUI.
- *
- * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
- * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
- * @link http://github.com/sebastianbergmann/phploc/tree
- * @since Class available since Release 1.0.0
- */
-class PHPLOC_TextUI_ResultPrinter_Text
-{
- /**
- * Prints a result set.
- *
- * @param array $count
- * @param boolean $printTests
- */
- public function printResult(array $count, $printTests)
- {
- $args = array();
- $format = '';
-
- if ($count['directories'] > 0) {
- $format .= "Directories: %10d\n" .
- "Files: %10d\n\n";
- $args[] = $count['directories'];
- $args[] = $count['files'];
- }
-
- $format .= "Lines of Code (LOC): %10d\n" .
- " Cyclomatic Complexity / Lines of Code: %10.2f\n";
- $args[] = $count['loc'];
- $args[] = $count['ccnByLoc'];
-
- if (isset($count['eloc'])) {
- $format .= "Executable Lines of Code (ELOC): %10d\n";
- $args[] = $count['eloc'];
- }
-
- $format .= "Comment Lines of Code (CLOC): %10d\n" .
- "Non-Comment Lines of Code (NCLOC): %10d\n\n" .
- "Namespaces: %10d\n" .
- "Interfaces: %10d\n" .
- "Traits: %10d\n" .
- "Classes: %10d\n" .
- " Abstract: %10d (%.2f%%)\n" .
- " Concrete: %10d (%.2f%%)\n" .
- " Average Class Length (NCLOC): %10d\n" .
- "Methods: %10d\n" .
- " Scope:\n" .
- " Non-Static: %10d (%.2f%%)\n" .
- " Static: %10d (%.2f%%)\n" .
- " Visibility:\n" .
- " Public: %10d (%.2f%%)\n" .
- " Non-Public: %10d (%.2f%%)\n" .
- " Average Method Length (NCLOC): %10d\n" .
- " Cyclomatic Complexity / Number of Methods: %10.2f\n\n" .
- "Anonymous Functions: %10d\n" .
- "Functions: %10d\n\n" .
- "Constants: %10d\n" .
- " Global constants: %10d\n" .
- " Class constants: %10d\n";
-
- $args[] = $count['cloc'];
- $args[] = $count['ncloc'];
- $args[] = $count['namespaces'];
- $args[] = $count['interfaces'];
- $args[] = $count['traits'];
- $args[] = $count['classes'];
- $args[] = $count['abstractClasses'];
- $args[] = $count['classes'] > 0 ? ($count['abstractClasses'] / $count['classes']) * 100 : 0;
- $args[] = $count['concreteClasses'];
- $args[] = $count['classes'] > 0 ? ($count['concreteClasses'] / $count['classes']) * 100 : 0;
- $args[] = $count['nclocByNoc'];
- $args[] = $count['methods'];
- $args[] = $count['nonStaticMethods'];
- $args[] = $count['methods'] > 0 ? ($count['nonStaticMethods'] / $count['methods']) * 100 : 0;
- $args[] = $count['staticMethods'];
- $args[] = $count['methods'] > 0 ? ($count['staticMethods'] / $count['methods']) * 100 : 0;
- $args[] = $count['publicMethods'];
- $args[] = $count['methods'] > 0 ? ($count['publicMethods'] / $count['methods']) * 100 : 0;
- $args[] = $count['nonPublicMethods'];
- $args[] = $count['methods'] > 0 ? ($count['nonPublicMethods'] / $count['methods']) * 100 : 0;
- $args[] = $count['nclocByNom'];
- $args[] = $count['ccnByNom'];
- $args[] = $count['anonymousFunctions'];
- $args[] = $count['functions'];
- $args[] = $count['constants'];
- $args[] = $count['globalConstants'];
- $args[] = $count['classConstants'];
-
- if ($printTests) {
- $format .= "\nTests:\n Classes: %10d\n" .
- " Methods: %10d\n";
- $args[] = $count['testClasses'];
- $args[] = $count['testMethods'];
- }
-
- vprintf($format, $args);
- }
-}
View
59 build.xml
@@ -43,13 +43,12 @@
<target name="phpab" description="Generate autoloader scripts">
<exec executable="phpab">
<arg value="--output" />
- <arg path="PHPLOC/Autoload.php" />
- <arg value="--compat" />
+ <arg path="src/autoload.php" />
<arg value="--template" />
- <arg path="PHPLOC/Autoload.php.in" />
+ <arg path="src/autoload.php.in" />
<arg value="--indent" />
<arg value=" " />
- <arg path="PHPLOC" />
+ <arg path="src" />
</exec>
</target>
@@ -57,12 +56,12 @@
<apply executable="${php}" failonerror="true">
<arg value="-l" />
- <fileset dir="${basedir}/PHPLOC">
+ <fileset dir="${basedir}/src">
<include name="**/*.php" />
<modified />
</fileset>
- <fileset dir="${basedir}/Tests">
+ <fileset dir="${basedir}/tests">
<include name="**/*.php" />
<modified />
</fileset>
@@ -74,7 +73,7 @@
<exec executable="phploc">
<arg value="--log-csv" />
<arg value="${basedir}/build/logs/phploc.csv" />
- <arg path="${basedir}/PHPLOC" />
+ <arg path="${basedir}/src" />
</exec>
</target>
@@ -84,14 +83,14 @@
<arg value="--jdepend-xml=${basedir}/build/logs/jdepend.xml" />
<arg value="--jdepend-chart=${basedir}/build/pdepend/dependencies.svg" />
<arg value="--overview-pyramid=${basedir}/build/pdepend/overview-pyramid.svg" />
- <arg path="${basedir}/PHPLOC" />
+ <arg path="${basedir}/src" />
</exec>
</target>
<target name="phpmd"
description="Perform project mess detection using PHPMD">
<exec executable="phpmd">
- <arg path="${basedir}/PHPLOC" />
+ <arg path="${basedir}/src" />
<arg value="text" />
<arg value="${basedir}/build/phpmd.xml" />
</exec>
@@ -100,7 +99,7 @@
<target name="phpmd-ci"
description="Perform project mess detection using PHPMD">
<exec executable="phpmd">
- <arg path="${basedir}/PHPLOC" />
+ <arg path="${basedir}/src" />
<arg value="xml" />
<arg value="${basedir}/build/phpmd.xml" />
<arg value="--reportfile" />
@@ -113,8 +112,8 @@
<exec executable="phpcs">
<arg value="--standard=${basedir}/build/PHPCS" />
<arg value="--extensions=php" />
- <arg value="--ignore=Autoload.php" />
- <arg path="${basedir}/PHPLOC" />
+ <arg value="--ignore=autoload.php" />
+ <arg path="${basedir}/src" />
</exec>
</target>
@@ -125,8 +124,8 @@
<arg value="--report-file=${basedir}/build/logs/checkstyle.xml" />
<arg value="--standard=${basedir}/build/PHPCS" />
<arg value="--extensions=php" />
- <arg value="--ignore=Autoload.php" />
- <arg path="${basedir}/PHPLOC" />
+ <arg value="--ignore=autoload.php" />
+ <arg path="${basedir}/src" />
</exec>
</target>
@@ -134,7 +133,7 @@
<exec executable="phpcpd">
<arg value="--log-pmd" />
<arg value="${basedir}/build/logs/pmd-cpd.xml" />
- <arg path="${basedir}/PHPLOC" />
+ <arg path="${basedir}/src" />
</exec>
</target>
@@ -145,7 +144,10 @@
</not>
</condition>
- <exec executable="${phpunit_cmd}" failonerror="true"/>
+ <exec executable="${phpunit_cmd}" failonerror="true">
+ <arg value="--configuration" />
+ <arg path="${basedir}/build/phpunit.xml" />
+ </exec>
</target>
<target name="phpcb"
@@ -154,9 +156,32 @@
<arg value="--log" />
<arg path="${basedir}/build/logs" />
<arg value="--source" />
- <arg path="${basedir}/PHPLOC" />
+ <arg path="${basedir}/src" />
<arg value="--output" />
<arg path="${basedir}/build/code-browser" />
</exec>
</target>
+
+ <target name="pear">
+ <mkdir dir="${basedir}/build/SebastianBergmann/PHPLOC"/>
+
+ <copy todir="${basedir}/build/SebastianBergmann/PHPLOC">
+ <fileset dir="${basedir}/src"/>
+ </copy>
+
+ <copy file="LICENSE" todir="${basedir}/build"/>
+ <copy file="README.markdown" todir="${basedir}/build"/>
+ <copy file="phploc.bat" todir="${basedir}/build"/>
+ <copy file="phploc.php" todir="${basedir}/build"/>
+
+ <exec executable="pear" dir="${basedir}/build">
+ <arg value="package" />
+ </exec>
+
+ <delete dir="${basedir}/build/SebastianBergmann"/>
+ <delete file="${basedir}/build/LICENSE"/>
+ <delete file="${basedir}/build/README.markdown"/>
+ <delete file="${basedir}/build/phploc.bat"/>
+ <delete file="${basedir}/build/phploc.php"/>
+ </target>
</project>
View
25 package.xml → build/package.xml
@@ -30,17 +30,20 @@
<notes>http://github.com/sebastianbergmann/phploc/tree</notes>
<contents>
<dir name="/">
- <dir name="PHPLOC">
- <dir name="TextUI">
- <dir name="ResultPrinter">
+ <dir name="SebastianBergmann">
+ <dir name="PHPLOC">
+ <dir name="Log">
<file baseinstalldir="/" name="CSV.php" role="php" />
- <file baseinstalldir="/" name="Text.php" role="php" />
<file baseinstalldir="/" name="XML.php" role="php" />
</dir>
- <file baseinstalldir="/" name="Command.php" role="php" />
+ <dir name="TextUI">
+ <file baseinstalldir="/" name="Command.php" role="php" />
+ <file baseinstalldir="/" name="ResultPrinter.php" role="php" />
+ </dir>
+ <file baseinstalldir="/" name="autoload.php" role="php" />
+ <file baseinstalldir="/" name="Analyser.php" role="php" />
+ <file baseinstalldir="/" name="Version.php" role="php" />
</dir>
- <file baseinstalldir="/" name="Analyser.php" role="php" />
- <file baseinstalldir="/" name="Autoload.php" role="php" />
</dir>
<file baseinstalldir="/" name="phploc.php" role="script">
<tasks:replace from="/usr/bin/env php" to="php_bin" type="pear-config"/>
@@ -50,6 +53,8 @@
<tasks:replace from="@php_bin@" to="php_bin" type="pear-config" />
<tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config" />
</file>
+ <file baseinstalldir="/" name="LICENSE" role="doc"/>
+ <file baseinstalldir="/" name="README.markdown" role="doc"/>
</dir>
</contents>
<dependencies>
@@ -61,9 +66,9 @@
<min>1.9.4</min>
</pearinstaller>
<package>
- <name>Finder</name>
- <channel>pear.symfony.com</channel>
- <min>2.1.0RC1</min>
+ <name>FinderFacade</name>
+ <channel>pear.phpunit.de</channel>
+ <min>1.0.4</min>
</package>
<package>
<name>ConsoleTools</name>
View
8 phpunit.xml.dist → build/phpunit.xml
@@ -2,15 +2,17 @@
<phpunit backupGlobals="false"
backupStaticAttributes="false"
- syntaxCheck="false">
+ syntaxCheck="false"
+ bootstrap="../src/autoload.php"
+ strict="true">
<testsuites>
<testsuite name="PHPLOC">
- <directory suffix="Test.php">Tests</directory>
+ <directory suffix="Test.php">../tests</directory>
</testsuite>
</testsuites>
<filter>
<whitelist addUncoveredFilesFromWhitelist="true">
- <directory suffix=".php">PHPLOC</directory>
+ <directory suffix=".php">../src</directory>
</whitelist>
</filter>
</phpunit>
View
8 phploc.php
@@ -43,10 +43,10 @@
*/
if (strpos('@php_bin@', '@php_bin') === 0) {
- set_include_path(dirname(__FILE__) . PATH_SEPARATOR . get_include_path());
+ require __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'autoload.php';
+} else {
+ require 'SebastianBergmann/PHPCPD/autoload.php';
}
-require 'PHPLOC/Autoload.php';
-
-$textui = new PHPLOC_TextUI_Command;
+$textui = new SebastianBergmann\PHPLOC\TextUI\Command;
$textui->main();
View
668 src/Analyser.php
@@ -0,0 +1,668 @@
+<?php
+/**
+ * phploc
+ *
+ * Copyright (c) 2009-2012, Sebastian Bergmann <sb@sebastian-bergmann.de>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Sebastian Bergmann nor the names of his
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package phploc
+ * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
+ * @since File available since Release 1.0.0
+ */
+
+namespace SebastianBergmann\PHPLOC
+{
+ if (!defined('T_TRAIT')) {
+ define('T_TRAIT', 1000);
+ }
+
+ /**
+ * PHPLOC code analyser.
+ *
+ * @author Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @copyright 2009-2012 Sebastian Bergmann <sb@sebastian-bergmann.de>
+ * @license http://www.opensource.org/licenses/BSD-3-Clause The BSD 3-Clause License
+ * @link http://github.com/sebastianbergmann/phploc/tree
+ * @since Class available since Release 1.0.0
+ */
+ class Analyser
+ {
+ /**
+ * @var array
+ */
+ protected $namespaces = array();
+
+ /**
+ * @var array
+ */
+ protected $classes = array();
+
+ /**
+ * @var array
+ */
+ protected $count = array(
+ 'files' => 0,
+ 'loc' => 0,
+ 'nclocClasses' => 0,
+ 'cloc' => 0,
+ 'ncloc' => 0,
+ 'eloc' => 0,
+ 'ccn' => 0,
+ 'ccnMethods' => 0,
+ 'interfaces' => 0,
+ 'traits' => 0,
+ 'classes' => 0,
+ 'abstractClasses' => 0,
+ 'concreteClasses' => 0,
+ 'anonymousFunctions' => 0,
+ 'functions' => 0,
+ 'methods' => 0,
+ 'publicMethods' => 0,
+ 'nonPublicMethods' => 0,
+ 'nonStaticMethods' => 0,
+ 'staticMethods' => 0,
+ 'constants' => 0,
+ 'classConstants' => 0,
+ 'globalConstants' => 0,
+ 'testClasses' => 0,
+ 'testMethods' => 0,
+ 'ccnByLoc' => 0,
+ 'ccnByNom' => 0,
+ 'nclocByNoc' => 0,
+ 'nclocByNom' => 0
+ );
+
+ /**
+ * @var array
+ */
+ protected $opcodeBlacklist = array(
+ 'BYTEKIT_NOP' => TRUE
+ );
+
+ /**
+ * @var ezcConsoleOutput
+ */
+ protected $output;
+
+ /**
+ * Constructor.
+ *
+ * @param ezcConsoleOutput $output
+ * @since Method available since Release 1.5.0
+ */
+ public function __construct(ezcConsoleOutput $output = NULL)
+ {
+ $this->output = $output;
+ }
+
+ /**
+ * Processes a set of files.
+ *
+ * @param array $files
+ * @param boolean $countTests
+ * @return array
+ * @since Method available since Release 1.2.0
+ */
+ public function countFiles(array $files, $countTests)
+ {
+ if ($countTests) {
+ if ($this->output !== NULL) {
+ $bar = new \ezcConsoleProgressbar($this->output, count($files));
+ print "Preprocessing files\n";
+ }
+
+ foreach ($files as $file) {
+ $this->preProcessFile($file);
+
+ if ($this->output !== NULL) {
+ $bar->advance();
+ }
+ }
+
+ if ($this->output !== NULL) {
+ print "\n\n";
+ }
+ }
+
+ $directories = array();
+
+ if ($this->output !== NULL) {
+ $bar = new \ezcConsoleProgressbar($this->output, count($files));
+ print "Processing files\n";
+ }
+
+ foreach ($files as $file) {
+ $directory = dirname($file);
+
+ if (!isset($directories[$directory])) {
+ $directories[$directory] = TRUE;
+ }
+
+ $this->countFile($file, $countTests);
+
+ if ($this->output !== NULL) {
+ $bar->advance();
+ }
+ }
+
+ if ($this->output !== NULL) {
+ print "\n\n";
+ }
+
+ $count = $this->count;
+
+ if (!function_exists('bytekit_disassemble_file')) {
+ unset($count['eloc']);
+ }
+
+ if (!$countTests) {
+ unset($count['testClasses']);
+ unset($count['testMethods']);
+ }
+
+ $count['directories'] = count($directories) - 1;
+ $count['namespaces'] = count($this->namespaces);
+ $count['classes'] = $count['abstractClasses'] +
+ $count['concreteClasses'];
+ $count['methods'] = $count['staticMethods'] +
+ $count['nonStaticMethods'];
+ $count['publicMethods'] = $count['methods'] -
+ $count['nonPublicMethods'];
+ $count['constants'] = $count['classConstants'] +
+ $count['globalConstants'];
+
+ if (isset($count['eloc']) && $count['eloc'] > 0) {
+ $count['ccnByLoc'] = $count['ccn'] / $count['eloc'];
+ }
+
+ else if ($count['ncloc'] > 0) {
+ $count['ccnByLoc'] = $count['ccn'] / $count['ncloc'];
+ }
+
+ if ($count['methods'] > 0) {
+ if(isset($count['testMethods'])) {
+ $countTestMethods = $count['testMethods'];
+ } else {
+ $countTestMethods = 0;
+ }
+ $count['ccnByNom'] = 1 + ($count['ccnMethods'] /
+ ($count['methods'] - $countTestMethods));
+ }
+
+ if ($count['classes'] > 0) {
+ $count['nclocByNoc'] = $count['nclocClasses'] / $count['classes'];
+ }
+
+ if ($count['methods'] > 0) {
+ $count['nclocByNom'] = $count['nclocClasses'] / $count['methods'];
+ }
+
+ return $count;
+ }
+
+ /**
+ * Pre-processes a single file.
+ *
+ * @param string $filename
+ * @since Method available since Release 1.2.0
+ */
+ public function preProcessFile($filename)
+ {
+ $tokens = token_get_all(file_get_contents($filename));
+ $numTokens = count($tokens);
+ $namespace = FALSE;
+
+ for ($i = 0; $i < $numTokens; $i++) {
+ if (is_string($tokens[$i])) {
+ continue;
+ }
+
+ list ($token, $value) = $tokens[$i];
+
+ switch ($token) {
+ case T_NAMESPACE: {
+ $namespace = $this->getNamespaceName($tokens, $i);
+ }
+ break;
+
+ case T_CLASS: {
+ $className = $this->getClassName($namespace, $tokens, $i);
+
+ if (isset($tokens[$i+4]) && is_array($tokens[$i+4]) &&
+ $tokens[$i+4][0] == T_EXTENDS) {
+ $parent = $this->getClassName(
+ $namespace, $tokens, $i + 4
+ );
+ } else {
+ $parent = NULL;
+ }
+
+ $this->classes[$className] = $parent;
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * Processes a single file.
+ *
+ * @param string $filename
+ * @param boolean $countTests
+ */
+ public function countFile($filename, $countTests)
+ {
+ $buffer = file_get_contents($filename);
+ $tokens = token_get_all($buffer);
+ $numTokens = count($tokens);
+ $loc = substr_count($buffer, "\n");
+
+ unset($buffer);
+
+ $nclocClasses = 0;
+ $cloc = 0;
+ $blocks = array();
+ $currentBlock = FALSE;
+ $namespace = FALSE;
+ $className = NULL;
+ $functionName = NULL;
+ $testClass = FALSE;
+
+ for ($i = 0; $i < $numTokens; $i++) {
+ if (is_string($tokens[$i])) {
+ if (trim($tokens[$i]) == '?') {
+ if (!$testClass) {
+ if ($className !== NULL) {
+ $this->count['ccnMethods']++;
+ }
+
+ $this->count['ccn']++;
+ }
+ }
+
+ if ($tokens[$i] == '{') {
+ if ($currentBlock == T_CLASS) {
+ $block = $className;
+ }
+
+ else if ($currentBlock == T_FUNCTION) {
+ $block = $functionName;
+ }
+
+ else {
+ $block = FALSE;
+ }
+
+ array_push($blocks, $block);
+
+ $currentBlock = FALSE;
+ }
+
+ else if ($tokens[$i] == '}') {
+ $block = array_pop($blocks);
+
+ if ($block !== FALSE && $block !== NULL) {
+ if ($block == $functionName) {
+ $functionName = NULL;
+ }
+
+ else if ($block == $className) {
+ $className = NULL;
+ $testClass = FALSE;
+ }
+ }
+ }
+
+ continue;
+ }
+
+ list ($token, $value) = $tokens[$i];
+
+ if ($className !== NULL) {
+ if ($token != T_COMMENT && $token != T_DOC_COMMENT) {
+ $nclocClasses += substr_count($value, "\n");
+ }
+ }
+
+ switch ($token) {
+ case T_NAMESPACE: {
+ $namespace = $this->getNamespaceName($tokens, $i);
+
+ if (!isset($this->namespaces[$namespace])) {
+ $this->namespaces[$namespace] = TRUE;
+ }
+ }
+ break;
+
+ case T_CLASS:
+ case T_INTERFACE:
+ case T_TRAIT: {
+ $className = $this->getClassName(
+ $namespace, $tokens, $i
+ );
+ $currentBlock = T_CLASS;
+
+ if ($token == T_TRAIT) {
+ $this->count['traits']++;
+ }
+
+ else if ($token == T_INTERFACE) {
+ $this->count['interfaces']++;
+ }
+
+ else {
+ if ($countTests && $this->isTestClass($className)) {
+ $testClass = TRUE;
+ $this->count['testClasses']++;
+ } else {
+ if (isset($tokens[$i-2]) &&
+ is_array($tokens[$i-2]) &&
+ $tokens[$i-2][0] == T_ABSTRACT) {
+ $this->count['abstractClasses']++;
+ } else {
+ $this->count['concreteClasses']++;
+ }
+ }
+ }
+ }
+ break;
+
+ case T_FUNCTION: {
+ $currentBlock = T_FUNCTION;
+
+ if (is_array($tokens[$i+2]) &&
+ $tokens[$i+2][0] == T_STRING) {
+ $functionName = $tokens[$i+2][1];
+ }
+
+ else if ($tokens[$i+2] == '&' &&
+ is_array($tokens[$i+3]) &&
+ $tokens[$i+3][0] == T_STRING) {
+ $functionName = $tokens[$i+3][1];
+ }
+
+ else {
+ $currentBlock = 'anonymous function';
+ $functionName = 'anonymous function';
+ $this->count['anonymousFunctions']++;
+ }
+
+ if ($currentBlock == T_FUNCTION) {
+ if ($className === NULL) {
+ $this->count['functions']++;
+ } else {
+ $static = FALSE;
+ $visibility = T_PUBLIC;
+
+ for ($j = $i; $j > 0; $j--) {
+ if (is_string($tokens[$j])) {
+ if ($tokens[$j] == '{' || $tokens[$j] == '}') {
+ break;
+ }
+
+ continue;
+ }
+
+ if (isset($tokens[$j][0])) {
+ switch ($tokens[$j][0]) {
+ case T_PRIVATE: {
+ $visibility = T_PRIVATE;
+ }
+ break;
+
+ case T_PROTECTED: {
+ $visibility = T_PROTECTED;
+ }
+ break;
+
+ case T_STATIC: {
+ $static = TRUE;
+ }
+ break;
+ }
+ }
+ }
+
+ if ($testClass &&
+ strpos($functionName, 'test') === 0 &&
+ $visibility == T_PUBLIC &&
+ !$static) {
+ $this->count['testMethods']++;
+ }
+
+ else if (!$testClass) {
+ if ($static) {
+ $this->count['staticMethods']++;
+ } else {
+ $this->count['nonStaticMethods']++;
+ }
+
+ if ($visibility != T_PUBLIC) {
+ $this->count['nonPublicMethods']++;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case T_CURLY_OPEN: {
+ $currentBlock = T_CURLY_OPEN;
+ array_push($blocks, $currentBlock);
+ }
+ break;
+
+ case T_DOLLAR_OPEN_CURLY_BRACES: {
+ $currentBlock = T_DOLLAR_OPEN_CURLY_BRACES;
+ array_push($blocks, $currentBlock);
+ }
+ break;
+
+ case T_IF:
+ case T_ELSEIF:
+ case T_FOR:
+ case T_FOREACH:
+ case T_WHILE:
+ case T_CASE:
+ case T_CATCH:
+ case T_BOOLEAN_AND:
+ case T_LOGICAL_AND:
+ case T_BOOLEAN_OR:
+ case T_LOGICAL_OR: {
+ if (!$testClass) {
+ if ($className !== NULL) {
+ $this->count['ccnMethods']++;
+ }
+
+ $this->count['ccn']++;
+ }
+ }
+ break;
+
+ case T_COMMENT:
+ case T_DOC_COMMENT: {
+ $cloc += substr_count($value, "\n") + 1;
+ }
+ break;
+
+ case T_CONST: {
+ $this->count['classConstants']++;
+ }
+ break;
+
+ case T_STRING: {
+ if ($value == 'define') {
+ $this->count['globalConstants']++;
+ }
+ }
+ break;
+ }
+ }
+
+ $this->count['loc'] += $loc;
+ $this->count['nclocClasses'] += $nclocClasses;
+ $this->count['cloc'] += $cloc;
+ $this->count['ncloc'] += $loc - $cloc;
+ $this->count['files']++;
+
+ if (function_exists('bytekit_disassemble_file')) {
+ $this->count['eloc'] += $this->countEloc($filename, $loc);
+ }
+ }
+
+ /**
+ * Counts the Executable Lines of Code (ELOC) using Bytekit.
+ *
+ * @param string $filename
+ * @param integer $loc
+ * @return integer
+ * @since Method available since Release 1.1.0
+ */
+ protected function countEloc($filename, $loc)
+ {
+ $bytecode = @bytekit_disassemble_file($filename);
+
+ if (!is_array($bytecode)) {
+ return 0;
+ }
+
+ $lines = array();
+
+ foreach ($bytecode['functions'] as $function) {
+ foreach ($function['raw']['opcodes'] as $opline) {
+ if ($opline['lineno'] <= $loc &&
+ !isset($this->opcodeBlacklist[$opline['opcode']]) &&
+ !isset($lines[$opline['lineno']])) {
+ $lines[$opline['lineno']] = TRUE;
+ }
+ }
+ }