Created
January 9, 2012 07:13
-
-
Save marinaglancy/1581626 to your computer and use it in GitHub Desktop.
Script to get rid of @subpackage token in phpdocs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* This script will go through specified directory (recoursively), search for all .php and .inc files and analyze phpdocs. | |
* It will try to locate file-level phpdocs and sometimes display errors (this analysis is not complete at the moment). | |
* Also it will replace \package XXX \subpackage YYY with \package XXX_YYY | |
* | |
* @copyright Marina Glancy | |
*/ | |
// Specify an absolute or relative path to moodle source here (or you may specify only subdirectory) | |
$filesource = "moodle"; | |
process_path_rec($filesource); | |
// Uncomment if you want to display messages | |
function mylog($file, $message) { | |
echo $file . " : ". $message. "\n"; | |
} | |
function process_path_rec($path) { | |
if (is_dir($path)) { | |
$files = dirlist($path); | |
foreach ($files as $file) { | |
process_path_rec($file); | |
} | |
} else if (file_exists($path)) { | |
process_one_file($path); | |
} | |
} | |
function dirlist($dir) { | |
$files = array(); | |
if (is_dir($dir)) { | |
if ($dh = opendir($dir)) { | |
while (($file = readdir($dh)) !== false) { | |
if ($file != '.' && $file != '..') { | |
$files[] = $dir . '/'. $file; | |
} | |
} | |
closedir($dh); | |
} | |
} | |
return $files; | |
} | |
function process_one_file($file) { | |
$pathinfo = pathinfo($file); | |
if (empty($pathinfo['extension']) || ($pathinfo['extension'] != 'php' && $pathinfo['extension'] != 'inc')) { | |
//mylog($file, 'skipping'); | |
return; | |
} | |
//mylog($file, 'processing'); | |
$source = file_get_contents($file); | |
$tokens = token_get_all($source); | |
$found = false; | |
foreach ($tokens as $tid => $token) { | |
if (is_string($token)) { | |
// simple 1-character token | |
$id = -1; | |
$text = $token; | |
$tokens[$tid] = array($id, $text); | |
} else { | |
// token array | |
list($id, $text) = $token; | |
} | |
if ($found === false) { | |
if (in_array($id, array(T_OPEN_TAG, T_WHITESPACE, T_COMMENT))) { | |
} else if ($id == T_DOC_COMMENT) { | |
$found = $tid; | |
} else { | |
$found = -1; | |
} | |
} | |
} | |
if ($found !== false && $found !== -1) { | |
if ($found + 1 > sizeof($tokens) - 1) { | |
mylog($file, 'EOF reached after first phpdoc'); | |
$found = -1; | |
} else if ($found + 2 > sizeof($tokens) - 1) { | |
mylog($file, 'EOF reached after first phpdoc and tag: '.$id1.' : '.$text1); | |
$found = -1; | |
} else { | |
list($id1, $text1) = $tokens[$found+1]; | |
list($id2, $text2) = $tokens[$found+2]; | |
if ($id1 == T_WHITESPACE) { | |
if (count(split("\n", $text1)) > 2) { | |
// empty line following, ok | |
} else if (in_array($id2, array(T_DOC_COMMENT, T_COMMENT, T_REQUIRE_ONCE, T_REQUIRE, T_IF, T_INCLUDE_ONCE, T_INCLUDE))) { | |
// something non-documentable following, ok | |
} else if ($id2 == T_STRING && $text2 == 'defined') { | |
// something non-documentable following | |
mylog($file, 'Recommended to add an empty line after file-level phpdocs'); | |
} else if (in_array($id2, array(T_CLASS, T_ABSTRACT, T_INTERFACE, T_FUNCTION))) { | |
// this is the comment to the following class/function | |
$found = -1; | |
} else { | |
mylog($file, 'Add an empty line after file-level phpdocs. Otherwise it may be considered as a comment to the following line: '.$id2.' : '.$text2); | |
$found = -1; | |
} | |
} else if (in_array($id1, array(T_COMMENT, T_DOC_COMMENT))) { | |
// quite silly but still this was a file-level comment | |
mylog($file, 'Recommended to add an empty line after file-level phpdocs'); | |
} else { | |
mylog($file, 'Non-whitespace following the file-level phpdocs: '.$id1.' : '.$text1); | |
$found = -1; | |
} | |
} | |
} | |
$changed = false; | |
/* | |
// This adds @file to the file-level php doc, required by doxygen | |
if ($found !== false && $found !== -1 && !preg_match('/\W\@file\W/', $tokens[$found][1])) { | |
$tokens[$found][1] = preg_replace('|^/\*\*|', '/** @file ', $tokens[$found][1]); | |
$changed = true; | |
} | |
*/ | |
foreach ($tokens as $tid => $token) { | |
if ($token[0] == T_DOC_COMMENT) { | |
if (preg_match('/@package\s+(\w*)/', $token[1], $matches1)) { | |
$group = $matches1[1]; | |
if (preg_match('/@subpackage\s+(\w*)/', $token[1], $matches2)) { | |
$group .= '_'.$matches2[1]; | |
$token[1] = preg_replace('/ *\* *@subpackage\s+.*\n/', '', $token[1]); | |
$changed = true; | |
} | |
$tokens[$tid][1] = preg_replace('/(@package\s+)\w*/', '\1'.$group, $token[1]); | |
// Replaces @package with @ingroup (for doxygen) | |
// $tokens[$tid][1] = preg_replace('/@package\s+\w*/', '@ingroup '.$group, $token[1]); | |
// $changed = true; | |
} | |
} | |
} | |
if ($changed) { | |
$output = ''; | |
foreach ($tokens as $tid => $token) { | |
$output .= $token[1]; | |
} | |
if (is_writable($file)) { | |
$f = fopen($file, 'w'); | |
fwrite($f, $output); | |
fclose($f); | |
//mylog($file, 'changed'); | |
} else { | |
mylog($file, '!!!!!!! Is not writable'); | |
} | |
} | |
//static $mycnt=0; | |
//if ($mycnt++>100) exit; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment