Skip to content

Instantly share code, notes, and snippets.

@marinaglancy
Created January 9, 2012 07:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marinaglancy/1581626 to your computer and use it in GitHub Desktop.
Save marinaglancy/1581626 to your computer and use it in GitHub Desktop.
Script to get rid of @subpackage token in phpdocs
<?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