Created
March 21, 2017 09:58
-
-
Save viankakrisna/eace0081b543a806981de50d7cb0ae96 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
for f in $(find $dir -name '*.php'); | |
do | |
(./wp-phptidy.php replace $f) | |
done | |
for f in $(find $dir -name '*.phptidybak~'); | |
do | |
(rm -f $f) | |
done |
This file contains hidden or 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
#!/usr/bin/php | |
<?php | |
/** | |
* phptidy | |
* | |
* See README for more information. | |
* | |
* MODIFIED VERSION for TextWrangler Unix Script | |
* See http://wp.me/pN7Q4-72 | |
* | |
* PHP version >= 5.0 | |
* | |
* @copyright 2003-2008 Magnus Rosenbaum | |
* @license GPL v2 | |
* | |
* This program is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU General Public License | |
* as published by the Free Software Foundation; either version 2 | |
* of the License, or (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
* | |
* @version 2.9 (2009-01-07) | |
* @author Magnus Rosenbaum <[email protected]> | |
* @package phptidy | |
*/ | |
//////////////// DEFAULT CONFIGURATION /////////////////// | |
// You can overwrite all these settings in your configuration files. | |
// List of files in your project | |
// Wildcards for glob() may be used. | |
// Example: array("*.php", "inc/*.php"); | |
$project_files = array(); | |
// List of files you want to exclude from the project files | |
// Wildcards are not allowed here. | |
// Example: array("inc/external_lib.php"); | |
$project_files_excludes = array(); | |
// The automatically added author in the phpdoc file docblocks | |
// If left empty no new @author doctags will be added. | |
// Example: "Your Name <[email protected]>" | |
$default_author = ""; | |
// Name of the automatically added @package doctag in the phpdoc file docblocks | |
// Example: "myproject" | |
$default_package = ""; | |
// String used for indenting | |
// If you indent with spaces you can use as much spaces as you like. | |
// Useful values: "\t" for indenting with tabs, | |
// " " for indenting with two spaces | |
$indent_char = "\t"; | |
// Control structures with the opening curly brace on a new line | |
// Examples: false always on the same line | |
// true always on a new line | |
// array(T_CLASS, T_FUNCTION) for PEAR Coding Standards | |
$curly_brace_newline = false; | |
// PHP open tag | |
// All php open tags will be replaced by the here defined kind of open tag. | |
// Useful values: "<?", "<?php", "<?PHP" | |
$open_tag = "<?php"; | |
// Check encoding | |
// If left empty the encoding will not be checked. | |
// See http://php.net/manual/en/ref.mbstring.html for a list of supported | |
// encodings. | |
// Examples: "ASCII", "UTF-8", "ISO-8859-1" | |
$encoding = ""; | |
// Docroot-Variables | |
// phptidy will strip these variables and constants from the beginning of | |
// include and require commands to generate appropriate @see tags also for | |
// these files. | |
// Example: array('DOCROOT', '$docroot', '$GLOBALS[\'docroot\']'); | |
$docrootvars = array(); | |
// Enable the single cleanup functions | |
$fix_token_case = true; | |
$fix_builtin_functions_case = true; | |
$replace_inline_tabs = true; | |
$replace_phptags = true; | |
$replace_shell_comments = true; | |
$fix_statement_brackets = true; | |
$fix_separation_whitespace = true; | |
$fix_comma_space = true; | |
$fix_round_bracket_space = true; | |
$add_file_docblock = false; | |
$add_function_docblocks = false; | |
$add_doctags = false; | |
$fix_docblock_format = true; | |
$fix_docblock_space = false; | |
$add_blank_lines = false; | |
$indent = true; | |
///////////// END OF DEFAULT CONFIGURATION //////////////// | |
define( 'CONFIGFILE', __DIR__ . "/.phptidy-config.php" ); | |
define( 'CACHEFILE', __DIR__ . "/.phptidy-cache" ); | |
error_reporting( E_ALL ); | |
if ( !version_compare( phpversion(), "5.0", ">=" ) ) { | |
echo "Error: phptidy requires PHP 5 or newer.\n"; | |
exit( 1 ); | |
} | |
if ( php_sapi_name() != "cli" ) { | |
echo "Error: phptidy has to be run on command line with CLI SAPI\n"; | |
exit( 1 ); | |
} | |
// Read command line | |
$command = ""; | |
$files = array(); | |
$options = array(); | |
foreach ( $_SERVER['argv'] as $key => $value ) { | |
if ( $key==0 ) continue; | |
if ( $key==1 ) { | |
$command = $value; | |
continue; | |
} | |
if ( substr( $value, 0, 1 )=="-" ) { | |
$options[] = $value; | |
} else { | |
$files[] = $value; | |
} | |
} | |
// Get command | |
switch ( $command ) { | |
case "help": | |
case "--help": | |
case "-h": | |
usage(); | |
exit; | |
case "suffix": | |
case "replace": | |
case "diff": | |
case "source": | |
case "files": | |
case "tokens": | |
break; | |
default: | |
echo "Unknown command: '".$command."'\n"; | |
case "": | |
usage(); | |
exit( 1 ); | |
} | |
// Get options | |
$verbose = false; | |
foreach ( $options as $option ) { | |
switch ( $option ) { | |
case "-v": | |
case "--verbose": | |
$verbose = true; | |
continue 2; | |
} | |
echo "Unknown option: '".$option."'\n"; | |
usage(); | |
exit( 1 ); | |
} | |
// Load config file | |
if ( file_exists( CONFIGFILE ) ) { | |
verbose( "Using configuration file ".CONFIGFILE."\n" ); | |
require CONFIGFILE; | |
} else { | |
verbose( "Running without configuration file\n" ); | |
} | |
// Files from config file | |
if ( !count( $files ) ) { | |
if ( !count( $project_files ) ) { | |
echo "Error: No files supplied on commandline and also no project files specified in config file\n"; | |
exit( 1 ); | |
} | |
foreach ( $project_files as $pf ) { | |
$files = array_unique( array_merge( $files, glob( $pf ) ) ); | |
} | |
} | |
// File excludes from config file | |
foreach ( $project_files_excludes as $file_exclude ) { | |
if ( | |
( $key = array_search( $file_exclude, $files ) ) !== false | |
) unset( $files[$key] ); | |
} | |
// Check files | |
foreach ( $files as $key => $file ) { | |
// Ignore backups and results from phptidy | |
if ( | |
substr( $file, -12 )==".phptidybak~" or | |
substr( $file, -12 )==".phptidy.php" | |
) { | |
unset( $files[$key] ); | |
continue; | |
} | |
if ( !is_readable( $file ) or !is_file( $file ) ) { | |
echo "Error: File '".$file."' does not exist or is not readable\n"; | |
exit( 1 ); | |
} | |
} | |
// Show files | |
if ( $command=="files" ) { | |
print_r( $files ); | |
exit; | |
} | |
// Read cache file | |
if ( file_exists( CACHEFILE ) ) { | |
verbose( "Using cache file ".CACHEFILE."\n" ); | |
$cache = unserialize( file_get_contents( CACHEFILE ) ); | |
$cache_orig = $cache; | |
} else { | |
$cache = array( | |
'md5sums' => array(), | |
); | |
$cache_orig = false; | |
} | |
// Find functions and includes | |
verbose( "Find functions and includes " ); | |
$functions = array(); | |
$seetags = array(); | |
foreach ( $files as $file ) { | |
verbose( "." ); | |
$source = file_get_contents( $file ); | |
$functions = array_unique( array_merge( $functions, get_functions( $source ) ) ); | |
find_includes( $seetags, $source, $file ); | |
} | |
verbose( "\n" ); | |
$md5sum = md5( serialize( $functions ).serialize( $seetags ) ); | |
if ( isset( $cache['functions_seetags'] ) and $md5sum == $cache['functions_seetags'] ) { | |
// Use cache only if functions and seetags haven't changed | |
$use_cache = true; | |
} else { | |
$use_cache = false; | |
$cache['functions_seetags'] = $md5sum; | |
} | |
if ( !extension_loaded( "tokenizer" ) ) { | |
echo "Error: The 'Tokenizer' extension for PHP is missing. See http://php.net/manual/en/book.tokenizer.php for more information.\n"; | |
exit( 1 ); | |
} | |
verbose( "Process files\n" ); | |
$replaced = 0; | |
foreach ( $files as $file ) { | |
verbose( " ".$file."\n" ); | |
$source_orig = file_get_contents( $file ); | |
// Cache | |
$md5sum = md5( $source_orig ); | |
if ( $use_cache and isset( $cache['md5sums'][$file] ) and $md5sum == $cache['md5sums'][$file] ) { | |
// Original file has not changed, so we don't process it | |
verbose( " File unchanged since last processing.\n" ); | |
continue; | |
} | |
// Check encoding | |
if ( $encoding and !mb_check_encoding( $source_orig, $encoding ) ) { | |
echo " File contains characters which are not valid in ".$encoding.":\n"; | |
$source_converted = mb_convert_encoding( $source_orig, $encoding ); | |
$tmpfile = "/tmp/tmp.phptidy.php"; | |
if ( !file_put_contents( $tmpfile, $source_converted ) ) { | |
echo "Error: The temporary file '".$tmpfile."' could not be saved.\n"; | |
exit( 1 ); | |
} | |
system( "echo -ne '\\033[01;31m'; diff -u ".$file." ".$tmpfile." 2>&1; echo -ne '\\033[00m'" ); | |
} | |
// Process source code | |
$source = $source_orig; | |
$count = 0; | |
do { | |
$source_in = $source; | |
$source = phptidy( $source_in ); | |
++$count; | |
if ( $count > 3 ) { | |
echo " Code processed 3 times and still not consistent!\n"; | |
break; | |
} | |
} while ( $source != $source_in ); | |
// Processing has not changed content of file | |
if ( $count == 1 ) { | |
verbose( " Processed without changes.\n" ); | |
// Write md5sum of the unchanged file into cache | |
$cache['md5sums'][$file] = $md5sum; | |
continue; | |
} | |
// Output | |
switch ( $command ) { | |
case "suffix": | |
$newfile = $file.".phptidy.php"; | |
if ( !file_put_contents( $newfile, $source ) ) { | |
echo "Error: The file '".$newfile."' could not be saved.\n"; | |
exit( 1 ); | |
} | |
verbose( " ".$newfile." saved.\n" ); | |
break; | |
case "replace": | |
$backupfile = dirname( $file ).( dirname( $file )?"/":"" ).".".basename( $file ).".phptidybak~"; | |
if ( !copy( $file, $backupfile ) ) { | |
echo "Error: The file '".$backupfile."' could not be saved.\n"; | |
exit( 1 ); | |
} | |
if ( !file_put_contents( $file, $source ) ) { | |
echo "Error: The file '".$file."' could not be overwritten.\n"; | |
exit( 1 ); | |
} | |
verbose( " replaced.\n" ); | |
++$replaced; | |
// Write new md5sum into cache | |
$cache['md5sums'][$file] = md5( $source ); | |
break; | |
case "diff": | |
$tmpfile = "/tmp/tmp.phptidy.php"; | |
if ( !file_put_contents( $tmpfile, $source ) ) { | |
echo "Error: The temporary file '".$tmpfile."' could not be saved.\n"; | |
exit( 1 ); | |
} | |
system( "echo -ne '\\033[01;34m'; diff -u ".$file." ".$tmpfile." 2>&1; echo -ne '\\033[00m'" ); | |
break; | |
case "source": | |
echo $source; | |
break; | |
} | |
} | |
if ( $command=="replace" ) { | |
if ( $replaced ) { | |
verbose( "Replaced ".$replaced." files.\n" ); | |
} | |
if ( $cache != $cache_orig ) { | |
verbose( "Write cache file ".CACHEFILE."\n" ); | |
if ( !file_put_contents( CACHEFILE, serialize( $cache ) ) ) { | |
echo "Warning: The cache file '".CACHEFILE."' could not be saved.\n"; | |
} | |
} | |
} | |
/////////////////// FUNCTIONS ////////////////////// | |
/** | |
* Output script status messages | |
*/ | |
function verbose( $msg ) { | |
if ( $GLOBALS['verbose'] ) echo $msg; | |
} | |
/** | |
* Display usage information | |
*/ | |
function usage() { | |
echo " | |
Usage: phptidy.php command [files|options] | |
Commands: | |
suffix Write output into files with suffix .phptidy.php | |
replace Replace files and backup original as .phptidybak | |
diff Show diff between old and new source | |
source Show processed source code of affected files | |
files Show files that would be processed | |
tokens Show source file tokens | |
help Display this message | |
Options: | |
-v Verbose messages | |
If no files are supplied on command line, they will be read from the config | |
file. | |
See README and source comments for more information. | |
"; | |
} | |
/** | |
* Clean up source code | |
* | |
* @param string $source | |
* @return string | |
*/ | |
function phptidy( $source ) { | |
// Replace non-Unix line breaks | |
// http://pear.php.net/manual/en/standards.file.php | |
// Windows line breaks -> Unix line breaks | |
$source = str_replace( "\r\n", "\n", $source ); | |
// Mac line breaks -> Unix line breaks | |
$source = str_replace( "\r", "\n", $source ); | |
$tokens = get_tokens( $source ); | |
if ( $GLOBALS['command']=="tokens" ) { | |
print_tokens( $tokens ); | |
exit; | |
} | |
// Simple formatting | |
if ( $GLOBALS['fix_token_case'] ) fix_token_case( $tokens ); | |
if ( $GLOBALS['fix_builtin_functions_case'] ) fix_builtin_functions_case( $tokens ); | |
if ( $GLOBALS['replace_inline_tabs'] ) replace_inline_tabs( $tokens ); | |
if ( $GLOBALS['replace_phptags'] ) replace_phptags( $tokens ); | |
if ( $GLOBALS['replace_shell_comments'] ) replace_shell_comments( $tokens ); | |
if ( $GLOBALS['fix_statement_brackets'] ) fix_statement_brackets( $tokens ); | |
if ( $GLOBALS['fix_separation_whitespace'] ) fix_separation_whitespace( $tokens ); | |
if ( $GLOBALS['fix_comma_space'] ) fix_comma_space( $tokens ); | |
if ( $GLOBALS['fix_round_bracket_space'] ) fix_round_bracket_space( $tokens ); | |
// PhpDocumentor | |
if ( $GLOBALS['add_doctags'] ) { | |
list( $usestags, $paramtags, $returntags ) = collect_doctags( $tokens ); | |
//print_r($usestags); | |
//print_r($paramtags); | |
//print_r($returntags); | |
} | |
if ( $GLOBALS['add_file_docblock'] ) add_file_docblock( $tokens ); | |
if ( $GLOBALS['add_function_docblocks'] ) add_function_docblocks( $tokens ); | |
if ( $GLOBALS['add_doctags'] ) { | |
add_doctags( $tokens, $usestags, $paramtags, $returntags, $GLOBALS['seetags'] ); | |
} | |
if ( $GLOBALS['fix_docblock_format'] ) fix_docblock_format( $tokens ); | |
if ( $GLOBALS['fix_docblock_space'] ) fix_docblock_space( $tokens ); | |
if ( $GLOBALS['add_blank_lines'] ) add_blank_lines( $tokens ); | |
// Indenting | |
if ( $GLOBALS['indent'] ) { | |
indent( $tokens ); | |
strip_closetag_indenting( $tokens ); | |
} | |
$source = combine_tokens( $tokens ); | |
// Strip trailing whitespace | |
$source = preg_replace( "/[ \t]+\n/", "\n", $source ); | |
if ( substr( $source, -1 )!="\n" ) { | |
// Add one line break at the end of the file | |
// http://pear.php.net/manual/en/standards.file.php | |
$source .= "\n"; | |
} else { | |
// Strip empty lines at the end of the file | |
while ( substr( $source, -2 )=="\n\n" ) $source = substr( $source, 0, -1 ); | |
} | |
return $source; | |
} | |
//////////////// TOKEN FUNCTIONS /////////////////// | |
/** | |
* Returns the text part of a token | |
* | |
* @param mixed $token | |
* @return string | |
*/ | |
function token_text( $token ) { | |
if ( is_string( $token ) ) return $token; | |
return $token[1]; | |
} | |
/** | |
* Prints all tokens | |
* | |
* @param array $tokens | |
*/ | |
function print_tokens( $tokens ) { | |
foreach ( $tokens as $token ) { | |
if ( is_string( $token ) ) { | |
echo $token."\n"; | |
} else { | |
list( $id, $text ) = $token; | |
echo token_name( $id )." ".addcslashes( $text, "\0..\40!@\@\177..\377" )."\n"; | |
} | |
} | |
} | |
/** | |
* Wrapper for token_get_all(), because there is new mysterious index 2 ... | |
* | |
* @param string $source | |
* @return array | |
*/ | |
function get_tokens( &$source ) { | |
$tokens = token_get_all( $source ); | |
foreach ( $tokens as &$token ) { | |
if ( isset( $token[2] ) ) unset( $token[2] ); | |
} | |
return $tokens; | |
} | |
/** | |
* Combines the tokens to the source code | |
* | |
* @param array $tokens | |
* @return string | |
*/ | |
function combine_tokens( $tokens ) { | |
$out = ""; | |
foreach ( $tokens as $key => $token ) { | |
if ( is_string( $token ) ) { | |
$out .= $token; | |
} else { | |
$out .= $token[1]; | |
} | |
} | |
return $out; | |
} | |
/** | |
* Displays a possible syntax error | |
* | |
* @param array $tokens | |
* @param integer $key | |
* @param string $message (optional) | |
*/ | |
function possible_syntax_error( $tokens, $key, $message="" ) { | |
echo "Possible syntax error detected"; | |
if ( $message ) echo " (".$message.")"; | |
echo ":\n"; | |
echo combine_tokens( array_slice( $tokens, max( 0, $key-5 ), 10 ) )."\n"; | |
} | |
/** | |
* Removes whitespace from the beginning of a token array | |
* | |
* @param array $tokens | |
*/ | |
function tokens_ltrim( &$tokens ) { | |
while ( | |
isset( $tokens[0][0] ) and | |
$tokens[0][0] === T_WHITESPACE | |
) { | |
array_splice( $tokens, 0, 1 ); | |
} | |
} | |
/** | |
* Removes whitespace from the end of a token array | |
* | |
* @param array $tokens (reference) | |
*/ | |
function tokens_rtrim( &$tokens ) { | |
while ( | |
isset( $tokens[$k=count( $tokens )-1][0] ) and | |
$tokens[$k][0] === T_WHITESPACE | |
) { | |
array_splice( $tokens, -1 ); | |
} | |
} | |
/** | |
* Removes all whitespace | |
* | |
* @param array $tokens (reference) | |
*/ | |
function strip_whitespace( &$tokens ) { | |
foreach ( $tokens as $key => $token ) { | |
if ( | |
isset( $token[0] ) and | |
$token[0] === T_WHITESPACE | |
) { | |
unset( $tokens[$key] ); | |
} | |
} | |
$tokens = array_values( $tokens ); | |
} | |
/** | |
* Gets the argument of a statement | |
* | |
* @param array $tokens | |
* @param integer $key Key of the token of the command for which we want the argument | |
* @return array | |
*/ | |
function get_argument_tokens( &$tokens, $key ) { | |
$tokens_arg = array(); | |
$round_braces_count = 0; | |
$curly_braces_count = 0; | |
++$key; | |
while ( isset( $tokens[$key] ) ) { | |
$token = &$tokens[$key]; | |
if ( is_string( $token ) ) { | |
if ( $token === ";" ) break; | |
} else { | |
if ( $token[0] === T_CLOSE_TAG ) break; | |
} | |
if ( $token === "(" ) { | |
++$round_braces_count; | |
} elseif ( $token === ")" ) { | |
--$round_braces_count; | |
} elseif ( | |
$token === "{" or ( | |
is_array( $token ) and ( | |
$token[0] === T_CURLY_OPEN or | |
$token[0] === T_DOLLAR_OPEN_CURLY_BRACES | |
) | |
) | |
) { | |
++$curly_braces_count; | |
} elseif ( $token === "}" ) { | |
--$curly_braces_count; | |
} | |
if ( $round_braces_count < 0 or $round_braces_count < 0 ) break; | |
$tokens_arg[] = $token; | |
++$key; | |
} | |
return $tokens_arg; | |
} | |
//////////////// FORMATTING FUNCTIONS /////////////////// | |
/** | |
* Checks for some tokens which must not be touched | |
* | |
* @param array $token | |
* @return boolean | |
*/ | |
function token_is_taboo( &$token ) { | |
return ( | |
// Do not touch HTML content | |
$token[0] === T_INLINE_HTML or | |
$token[0] === T_CLOSE_TAG or | |
// Do not touch the content of strings | |
$token[0] === T_CONSTANT_ENCAPSED_STRING or | |
$token[0] === T_ENCAPSED_AND_WHITESPACE or | |
// Do not touch the content of multiline comments | |
( $token[0] === T_COMMENT and substr( $token[1], 0, 2 ) === "/*" ) | |
); | |
} | |
/** | |
* Converts commands to lower case | |
* | |
* @param array $tokens (reference) | |
*/ | |
function fix_token_case( &$tokens ) { | |
static $lower_case_tokens = array( | |
T_ABSTRACT, | |
T_ARRAY, | |
T_ARRAY_CAST, | |
T_AS, | |
T_BOOL_CAST, | |
T_BREAK, | |
T_CASE, | |
T_CATCH, | |
T_CLASS, | |
T_CLONE, | |
T_CONST, | |
T_CONTINUE, | |
T_DECLARE, | |
T_DEFAULT, | |
T_DO, | |
T_DOUBLE_CAST, | |
T_ECHO, | |
T_ELSE, | |
T_ELSEIF, | |
T_EMPTY, | |
T_ENDDECLARE, | |
T_ENDFOR, | |
T_ENDFOREACH, | |
T_ENDIF, | |
T_ENDSWITCH, | |
T_ENDWHILE, | |
T_EVAL, | |
T_EXIT, | |
T_EXTENDS, | |
T_FINAL, | |
T_FOR, | |
T_FOREACH, | |
T_FUNCTION, | |
T_GLOBAL, | |
T_IF, | |
T_IMPLEMENTS, | |
T_INCLUDE, | |
T_INCLUDE_ONCE, | |
T_INSTANCEOF, | |
T_INT_CAST, | |
T_INTERFACE, | |
T_ISSET, | |
T_LIST, | |
T_LOGICAL_AND, | |
T_LOGICAL_OR, | |
T_LOGICAL_XOR, | |
T_NEW, | |
T_OBJECT_CAST, | |
T_PRINT, | |
T_PRIVATE, | |
T_PUBLIC, | |
T_PROTECTED, | |
T_REQUIRE, | |
T_REQUIRE_ONCE, | |
T_RETURN, | |
T_STATIC, | |
T_STRING_CAST, | |
T_SWITCH, | |
T_THROW, | |
T_TRY, | |
T_UNSET, | |
T_UNSET_CAST, | |
T_VAR, | |
T_WHILE | |
); | |
foreach ( $tokens as &$token ) { | |
if ( is_string( $token ) ) continue; | |
if ( $token[1] === strtolower( $token[1] ) ) continue; | |
if ( in_array( $token[0], $lower_case_tokens ) ) { | |
$token[1] = strtolower( $token[1] ); | |
} | |
} | |
} | |
/** | |
* Converts builtin functions to lower case | |
* | |
* @param array $tokens (reference) | |
*/ | |
function fix_builtin_functions_case( &$tokens ) { | |
static $defined_internal_functions = false; | |
if ( $defined_internal_functions === false ) { | |
$defined_functions = get_defined_functions(); | |
$defined_internal_functions = $defined_functions['internal']; | |
} | |
foreach ( $tokens as $key => &$token ) { | |
if ( | |
is_string( $token ) or | |
$token[0] !== T_STRING or | |
!isset( $tokens[$key+2] ) or | |
// Ignore object methods | |
( is_array( $tokens[$key-1] ) and $tokens[$key-1][0] === T_OBJECT_OPERATOR ) | |
) continue; | |
if ( | |
$tokens[$key+1] === "(" | |
) { | |
$lowercase = strtolower( $token[1] ); | |
if ( | |
$token[1] !== $lowercase and | |
in_array( $lowercase, $defined_internal_functions ) | |
) { | |
$token[1] = $lowercase; | |
} | |
} elseif ( | |
$tokens[$key+2] === "(" and | |
is_array( $tokens[$key+1] ) and $tokens[$key+1][0] === T_WHITESPACE | |
) { | |
if ( | |
in_array( strtolower( $token[1] ), $defined_internal_functions ) | |
) { | |
$token[1] = strtolower( $token[1] ); | |
// Remove whitespace between function name and opening round bracket | |
unset( $tokens[$key+1] ); | |
} | |
} | |
} | |
$tokens = array_values( $tokens ); | |
} | |
/** | |
* Replaces inline tabs with spaces | |
* | |
* @param array $tokens (reference) | |
*/ | |
function replace_inline_tabs( &$tokens ) { | |
foreach ( $tokens as &$token ) { | |
if ( is_string( $token ) ) { | |
$text =& $token; | |
} else { | |
if ( token_is_taboo( $token ) ) continue; | |
$text =& $token[1]; | |
} | |
// Replace one tab with one space | |
$text = str_replace( "\t", " ", $text ); | |
} | |
} | |
/** | |
* Replaces PHP-Open-Tags with consistent tags | |
* | |
* @param array $tokens (reference) | |
*/ | |
function replace_phptags( &$tokens ) { | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) ) continue; | |
switch ( $token[0] ) { | |
case T_OPEN_TAG: | |
// The open tag is already the right one | |
if ( rtrim( $token[1] ) == $GLOBALS['open_tag'] ) continue; | |
// Collect following whitespace | |
preg_match( "/\s*$/", $token[1], $matches ); | |
$whitespace = $matches[0]; | |
if ( $tokens[$key+1][0] === T_WHITESPACE ) { | |
$whitespace .= $tokens[$key+1][1]; | |
array_splice( $tokens, $key+1, 1 ); | |
} | |
if ( $GLOBALS['open_tag']=="<?" ) { | |
// Short open tags have the following whitespace in a seperate token | |
array_splice( $tokens, $key, 1, array( | |
array( T_OPEN_TAG, $GLOBALS['open_tag'] ), | |
array( T_WHITESPACE, $whitespace ) | |
) ); | |
} else { | |
// Long open tags have the following whitespace included in the token string | |
switch ( strlen( $whitespace ) ) { | |
case 0: | |
// Add an additional space if no whitespace is found | |
$whitespace = " "; | |
case 1: | |
// Use the one found space or newline | |
$tokens[$key][1] = $GLOBALS['open_tag'].$whitespace; | |
break; | |
default: | |
// Use the first space or newline for the open tag and append the rest of the whitespace as a seperate token | |
array_splice( $tokens, $key, 1, array( | |
array( T_OPEN_TAG, $GLOBALS['open_tag'].substr( $whitespace, 0, 1 ) ), | |
array( T_WHITESPACE, substr( $whitespace, 1 ) ) | |
) ); | |
} | |
} | |
break; | |
case T_OPEN_TAG_WITH_ECHO: | |
// If we use short tags we also accept the echo tags | |
if ( $GLOBALS['open_tag']=="<?" ) continue; | |
if ( $tokens[$key+1][0] === T_WHITESPACE ) { | |
// If there is already whitespace following we only replace the open tag | |
array_splice( $tokens, $key, 1, array( | |
array( T_OPEN_TAG, $GLOBALS['open_tag']." " ), | |
array( T_ECHO, "echo" ) | |
) ); | |
} else { | |
// If there is no whitespace following we add one space | |
array_splice( $tokens, $key, 1, array( | |
array( T_OPEN_TAG, $GLOBALS['open_tag']." " ), | |
array( T_ECHO, "echo" ), | |
array( T_WHITESPACE, " " ) | |
) ); | |
} | |
} | |
} | |
} | |
/** | |
* Replaces shell style comments with C style comments | |
* | |
* http://pear.php.net/manual/en/standards.comments.php | |
* | |
* @param array $tokens (reference) | |
*/ | |
function replace_shell_comments( &$tokens ) { | |
foreach ( $tokens as &$token ) { | |
if ( is_string( $token ) ) continue; | |
if ( | |
$token[0] === T_COMMENT and | |
substr( $token[1], 0, 1 ) === "#" | |
) { | |
$token[1] = "//".substr( $token[1], 1 ); | |
} | |
} | |
} | |
/** | |
* Enforces statements without brackets and fixes whitespace | |
* | |
* http://pear.php.net/manual/en/standards.including.php | |
* | |
* @param array $tokens (reference) | |
*/ | |
function fix_statement_brackets( &$tokens ) { | |
static $statement_tokens = array( | |
T_INCLUDE, | |
T_INCLUDE_ONCE, | |
T_REQUIRE, | |
T_REQUIRE_ONCE, | |
T_RETURN, | |
T_BREAK, | |
T_CONTINUE, | |
T_ECHO | |
); | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) or !in_array( $token[0], $statement_tokens ) ) continue; | |
$tokens_arg = get_argument_tokens( $tokens, $key ); | |
$tokens_arg_orig = $tokens_arg; | |
tokens_ltrim( $tokens_arg ); | |
if ( !count( $tokens_arg ) or $tokens_arg[0] !== "(" ) continue; | |
tokens_rtrim( $tokens_arg ); | |
// Check if the opening bracket has a matching one at the end of the expression | |
$round_braces_count = 0; | |
foreach ( $tokens_arg as $k => $t ) { | |
if ( is_string( $t ) ) { | |
if ( $t === "(" ) ++$round_braces_count; | |
elseif ( $t === ")" ) --$round_braces_count; | |
else continue; | |
// Check if the expression begins without a bracket or if the bracket was closed before the end of the expression was reached | |
if ( $round_braces_count == 0 and $k != count( $tokens_arg )-1 ) { | |
continue 2; | |
} | |
if ( $round_braces_count < 0 ) { | |
possible_syntax_error( $tokens, $key, "Closing round bracket found which has not been opened" ); | |
continue 2; | |
} | |
} else { | |
// Do not touch multiline expressions | |
if ( $t[0] === T_WHITESPACE and strpos( $t[1], "\n" )!==false ) { | |
continue 2; | |
} | |
} | |
} | |
// Detect missing brackets | |
if ( $round_braces_count != 0 ) { | |
possible_syntax_error( $tokens, $key, "Round bracket opened but no matching closing bracket found" ); | |
continue; | |
} | |
// Remove the outermost brackets | |
$tokens_arg = array_slice( $tokens_arg, 1, -1 ); | |
tokens_ltrim( $tokens_arg ); | |
tokens_rtrim( $tokens_arg ); | |
// Add one space between the command and the argument if the argument is not empty | |
if ( $tokens_arg ) { | |
array_unshift( $tokens_arg, array( T_WHITESPACE, " " ) ); | |
} | |
array_splice( $tokens, $key+1, count( $tokens_arg_orig ), $tokens_arg ); | |
} | |
} | |
/** | |
* Fixes whitespace between commands and braces | |
* | |
* @param array $tokens (reference) | |
*/ | |
function fix_separation_whitespace( &$tokens ) { | |
$control_structure = false; | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) ) { | |
// Exactly 1 space or a newline between closing round bracket and opening curly bracket | |
if ( $tokens[$key] === ")" ) { | |
if ( | |
isset( $tokens[$key+1] ) and $tokens[$key+1] === "{" | |
) { | |
// Insert an additional space or newline before the bracket | |
array_splice( $tokens, $key+1, 0, array( | |
array( T_WHITESPACE, separation_whitespace( $control_structure ) ) | |
) ); | |
} elseif ( | |
isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === T_WHITESPACE and | |
isset( $tokens[$key+2] ) and $tokens[$key+2] === "{" | |
) { | |
// Set the existing whitespace before the bracket to exactly one space or newline | |
$tokens[$key+1][1] = separation_whitespace( $control_structure ); | |
} | |
} | |
} else { | |
switch ( $token[0] ) { | |
case T_CLASS: | |
// Class definition | |
if ( | |
isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === T_WHITESPACE and | |
isset( $tokens[$key+2][0] ) and $tokens[$key+2][0] === T_STRING | |
) { | |
// Exactly 1 space between 'class' and the class name | |
$tokens[$key+1][1] = " "; | |
// Exactly 1 space between the class name and the opening curly bracket | |
if ( $tokens[$key+3] === "{" ) { | |
// Insert an additional space or newline before the bracket | |
array_splice( $tokens, $key+3, 0, array( | |
array( T_WHITESPACE, separation_whitespace( T_CLASS ) ) | |
) ); | |
} elseif ( | |
isset( $tokens[$key+3][0] ) and $tokens[$key+3][0] === T_WHITESPACE and | |
isset( $tokens[$key+4] ) and $tokens[$key+4] === "{" | |
) { | |
// Set the existing whitespace before the bracket to exactly one space or a newline | |
$tokens[$key+3][1] = separation_whitespace( T_CLASS ); | |
} | |
} | |
break; | |
case T_FUNCTION: | |
// Function definition | |
if ( | |
isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === T_WHITESPACE and | |
isset( $tokens[$key+2][0] ) and $tokens[$key+2][0] === T_STRING | |
) { | |
// Exactly 1 Space between 'function' and the function name | |
$tokens[$key+1][1] = " "; | |
// No whitespace between function name and opening round bracket | |
if ( isset( $tokens[$key+3][0] ) and $tokens[$key+3][0] === T_WHITESPACE ) { | |
// Remove the whitespace | |
array_splice( $tokens, $key+3, 1 ); | |
} | |
} | |
break; | |
case T_IF: | |
case T_ELSEIF: | |
case T_FOR: | |
case T_FOREACH: | |
case T_WHILE: | |
case T_SWITCH: | |
// At least 1 space between a statement and a opening round bracket | |
if ( $tokens[$key+1] === "(" ) { | |
// Insert an additional space or newline before the bracket | |
array_splice( $tokens, $key+1, 0, array( | |
array( T_WHITESPACE, separation_whitespace( T_SWITCH ) ), | |
) ); | |
} | |
break; | |
case T_ELSE: | |
case T_DO: | |
// Exactly 1 space between a command and a opening curly bracket | |
if ( $tokens[$key+1] === "{" ) { | |
// Insert an additional space or newline before the bracket | |
array_splice( $tokens, $key+1, 0, array( | |
array( T_WHITESPACE, separation_whitespace( T_DO ) ), | |
) ); | |
} elseif ( | |
isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === T_WHITESPACE and | |
isset( $tokens[$key+2] ) and $tokens[$key+2] === "{" | |
) { | |
// Set the existing whitespace before the bracket to exactly one space or a newline | |
$tokens[$key+1][1] = separation_whitespace( T_DO ); | |
} | |
break; | |
default: | |
// Do not set $control_structure if the token is no control structure | |
continue 2; | |
} | |
$control_structure = $token[0]; | |
} | |
} | |
} | |
/** | |
* Whitespace before an opening curly bracket depending on the control structure | |
* | |
* @param integer $control_structure token of the control structure | |
* @return string | |
*/ | |
function separation_whitespace( $control_structure ) { | |
if ( | |
$GLOBALS['curly_brace_newline']===true or ( | |
is_array( $GLOBALS['curly_brace_newline'] ) and | |
in_array( $control_structure, $GLOBALS['curly_brace_newline'] ) | |
) | |
) return "\n"; | |
return " "; | |
} | |
/** | |
* Adds one space after a comma | |
* | |
* @param array $tokens (reference) | |
*/ | |
function fix_comma_space( &$tokens ) { | |
foreach ( $tokens as $key => &$token ) { | |
if ( !is_string( $token ) ) continue; | |
if ( | |
// If the current token ends with a comma... | |
substr( $token, -1 ) === "," and | |
// ...and the next token is no whitespace | |
!( isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === T_WHITESPACE ) | |
) { | |
// Insert one space | |
array_splice( $tokens, $key+1, 0, array( | |
array( T_WHITESPACE, " " ) | |
) ); | |
} | |
} | |
} | |
/** | |
* Adds one space after a round bracket | |
* | |
* @param array $tokens (reference) | |
*/ | |
function fix_round_bracket_space( &$tokens ) { | |
foreach ( $tokens as $key => &$token ) { | |
if ( !is_string( $token ) ) continue; | |
if ( | |
// If the current token is a start round bracket... | |
$token === "(" and | |
// ...and the next token is no whitespace | |
!( isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === T_WHITESPACE ) and | |
// ...and the next token is not an end round bracket | |
!( isset( $tokens[$key+1][0] ) and $tokens[$key+1][0] === ')' ) | |
) { | |
// Insert one space | |
array_splice( $tokens, $key+1, 0, array( | |
array( T_WHITESPACE, " " ) | |
) ); | |
} | |
else if ( | |
// If the current token is an end round bracket... | |
$token === ")" and | |
// ...and the previous token is no whitespace | |
!( isset( $tokens[$key-1][0] ) and $tokens[$key-1][0] === T_WHITESPACE ) and | |
// ...and the previous token is a start round bracket | |
!( isset( $tokens[$key-1][0] ) and $tokens[$key-1][0] === '(' ) | |
) { | |
// Insert one space | |
array_splice( $tokens, $key, 0, array( | |
array( T_WHITESPACE, " " ) | |
) ); | |
} | |
} | |
} | |
/** | |
* Fixes the format of a DocBlock | |
* | |
* @param array $tokens (reference) | |
*/ | |
function fix_docblock_format( &$tokens ) { | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) or $token[0] !== T_DOC_COMMENT ) continue; | |
$lines_orig = explode( "\n", $tokens[$key][1] ); | |
$lines = array(); | |
$comments_started = false; | |
$doctags_started = false; | |
$last_line = false; | |
$param_max_variable_length = 0; | |
foreach ( $lines_orig as $line ) { | |
$line = trim( $line ); | |
// Strip empty lines | |
if ( $line=="" ) continue; | |
if ( $line!="/**" and $line!="*/" ) { | |
// Add stars where missing | |
if ( substr( $line, 0, 1 )!="*" ) $line = "* ".$line; | |
elseif ( $line!="*" and substr( $line, 0, 2 )!="* " ) $line = "* ".substr( $line, 1 ); | |
// Strip empty lines at the beginning | |
if ( !$comments_started ) { | |
if ( $line=="*" and count( $lines_orig )>3 ) continue; | |
$comments_started = true; | |
} | |
if ( substr( $line, 0, 3 )=="* @" ) { | |
// Add empty line before DocTags if missing | |
if ( !$doctags_started ) { | |
if ( $last_line!="*" ) $lines[] = "*"; | |
if ( $last_line=="/**" ) $lines[] = "*"; | |
$doctags_started = true; | |
} | |
// DocTag format | |
if ( preg_match( '/^\* @param(\s+[^\s\$]*)?\s+(&?\$[^\s]+)/', $line, $matches ) ) { | |
$param_max_variable_length = max( $param_max_variable_length, strlen( $matches[2] ) ); | |
} | |
} | |
} | |
$lines[] = $line; | |
$last_line = $line; | |
} | |
foreach ( $lines as $l => $line ) { | |
// DocTag format | |
if ( preg_match( '/^\* @param(\s+([^\s\$]*))?(\s+(&?\$[^\s]+))?(.*)$/', $line, $matches ) ) { | |
$line = "* @param "; | |
if ( $matches[2] ) $line .= str_pad( $matches[2], 7 ); else $line .= "unknown"; | |
$line .= " "; | |
if ( $matches[4] ) $line .= str_pad( $matches[4], $param_max_variable_length )." "; | |
$line .= trim( $matches[5] ); | |
$lines[$l] = $line; | |
} | |
} | |
$token[1] = join( "\n", $lines ); | |
} | |
} | |
/** | |
* Adjusts empty lines after DocBlocks | |
* | |
* @param array $tokens (reference) | |
*/ | |
function fix_docblock_space( &$tokens ) { | |
$filedocblock = true; | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) or $token[0] !== T_DOC_COMMENT ) continue; | |
if ( $filedocblock ) { | |
// Exactly 2 empty lines after the file DocBlock | |
if ( $tokens[$key+1][0] === T_WHITESPACE ) { | |
$tokens[$key+1][1] = preg_replace( "/\n([ \t]*\n)*/", "\n\n\n", $tokens[$key+1][1] ); | |
} | |
$filedocblock = false; | |
} else { | |
// Delete empty lines after the DocBlock | |
if ( $tokens[$key+1][0] === T_WHITESPACE ) { | |
$tokens[$key+1][1] = preg_replace( "/\n([ \t]*\n)+/", "\n", $tokens[$key+1][1] ); | |
} | |
// Add empty lines before the DocBlock | |
if ( $tokens[$key-1][0] === T_WHITESPACE ) { | |
$n = 2; | |
if ( substr( token_text( $tokens[$key-2] ), -1 ) == "\n" ) --$n; | |
// At least 2 empty lines before the docblock of a function | |
if ( $tokens[$key+2][0] === T_FUNCTION ) ++$n; | |
if ( strpos( $tokens[$key-1][1], str_repeat( "\n", $n ) ) === false ) { | |
$tokens[$key-1][1] = preg_replace( "/(\n){1,".$n."}/", str_repeat( "\n", $n ), $tokens[$key-1][1] ); | |
} | |
} | |
} | |
} | |
} | |
/** | |
* Adds 2 blank lines after functions and classes | |
* | |
* @param array $tokens (reference) | |
*/ | |
function add_blank_lines( &$tokens ) { | |
// Level of curly brackets | |
$curly_braces_count = 0; | |
$curly_brace_opener = array(); | |
$control_structure = false; | |
$heredoc_started = false; | |
foreach ( $tokens as $key => &$token ) { | |
// Skip HEREDOC | |
if ( $heredoc_started ) { | |
if ( isset( $token[0] ) and $token[0] === T_END_HEREDOC ) { | |
$heredoc_started = false; | |
} | |
continue; | |
} | |
if ( is_array( $token ) ) { | |
// Detect beginning of a HEREDOC block | |
if ( $token[0] === T_START_HEREDOC ) { | |
$heredoc_started = true; | |
continue; | |
} | |
// Remember the type of control structure | |
if ( in_array( $token[0], array( T_IF, T_ELSEIF, T_WHILE, T_FOR, T_FOREACH, T_SWITCH, T_FUNCTION, T_CLASS ) ) ) { | |
$control_structure = $token[0]; | |
continue; | |
} | |
} | |
if ( $token === "}" ) { | |
if ( | |
$curly_brace_opener[$curly_braces_count] === T_FUNCTION or | |
$curly_brace_opener[$curly_braces_count] === T_CLASS | |
) { | |
// At least 2 blank lines after a function or class | |
if ( | |
$tokens[$key+1][0] === T_WHITESPACE and | |
substr( $tokens[$key+1][1], 0, 2 ) != "\n\n\n" | |
) { | |
$tokens[$key+1][1] = preg_replace( "/^([ \t]*\n){1,3}/", "\n\n\n", $tokens[$key+1][1] ); | |
} | |
} | |
--$curly_braces_count; | |
} elseif ( | |
$token === "{" or ( | |
is_array( $token ) and ( | |
$token[0] === T_CURLY_OPEN or | |
$token[0] === T_DOLLAR_OPEN_CURLY_BRACES | |
) | |
) | |
) { | |
++$curly_braces_count; | |
$curly_brace_opener[$curly_braces_count] = $control_structure; | |
} | |
} | |
} | |
/** | |
* Indenting | |
* | |
* @param array $tokens (reference) | |
*/ | |
function indent( &$tokens ) { | |
// Level of curly brackets | |
$curly_braces_count = 0; | |
// Level of round brackets | |
$round_braces_count = 0; | |
$round_brace_opener = false; | |
$round_braces_control = 0; | |
// Number of opened control structures without curly brackets inside of a level of curly brackets | |
$control_structure = array( 0 ); | |
$heredoc_started = false; | |
$trinity_started = false; | |
foreach ( $tokens as $key => &$token ) { | |
// Skip HEREDOC | |
if ( $heredoc_started ) { | |
if ( isset( $token[0] ) and $token[0] === T_END_HEREDOC ) { | |
$heredoc_started = false; | |
} | |
continue; | |
} | |
// Detect beginning of a HEREDOC block | |
if ( isset( $token[0] ) and $token[0] === T_START_HEREDOC ) { | |
$heredoc_started = true; | |
continue; | |
} | |
// The closing bracket itself has to be not indented again, so we decrease the brackets count before we reach the bracket. | |
if ( isset( $tokens[$key+1] ) ) { | |
if ( is_string( $tokens[$key+1] ) ) { | |
if ( | |
is_string( $token ) or | |
$token[0] !== T_WHITESPACE or | |
strpos( $token[1], "\n" )!==false | |
) { | |
if ( $tokens[$key+1] === "}" ) --$curly_braces_count; | |
elseif ( $tokens[$key+1] === ")" ) --$round_braces_count; | |
} | |
} else { | |
if ( | |
// If the next token is a T_WHITESPACE without a \n, we have to look at the one after the next. | |
isset( $tokens[$key+2] ) and | |
$tokens[$key+1][0] === T_WHITESPACE and | |
strpos( $tokens[$key+1][1], "\n" )===false | |
) { | |
if ( $tokens[$key+2] === "}" ) --$curly_braces_count; | |
elseif ( $tokens[$key+2] === ")" ) --$round_braces_count; | |
} | |
} | |
} | |
if ( $token === "(" ) ++$round_braces_control; | |
elseif ( $token === ")" ) --$round_braces_control; | |
if ( $token === "(" ) { | |
if ( $round_braces_control==1 ) { | |
// Remember which command was before the bracket | |
$k = $key; | |
do { | |
--$k; | |
} while ( | |
isset( $tokens[$k] ) and ( | |
$tokens[$k][0] === T_WHITESPACE or | |
$tokens[$k][0] === T_STRING | |
) | |
); | |
if ( is_array( $tokens[$k] ) ) { | |
$round_brace_opener = $tokens[$k][0]; | |
} else { | |
$round_brace_opener = false; | |
} | |
} | |
++$round_braces_count; | |
} elseif ( | |
( | |
$token === ")" and | |
$round_braces_control == 0 and | |
in_array( | |
$round_brace_opener, | |
array( T_IF, T_ELSEIF, T_WHILE, T_FOR, T_FOREACH, T_SWITCH, T_FUNCTION ) | |
) | |
) or ( | |
is_array( $token ) and ( | |
$token[0] === T_ELSE or $token[0] === T_DO | |
) | |
) | |
) { | |
// All control stuctures end with a curly bracket, except "else" and "do". | |
if ( isset( $control_structure[$curly_braces_count] ) ) { | |
++$control_structure[$curly_braces_count]; | |
} else { | |
$control_structure[$curly_braces_count] = 1; | |
} | |
} elseif ( $token === ";" or $token === "}" ) { | |
// After a command or a set of commands a control structure is closed. | |
if ( !empty( $control_structure[$curly_braces_count] ) ) --$control_structure[$curly_braces_count]; | |
} else { | |
indent_text( | |
$tokens, | |
$key, | |
$curly_braces_count, | |
$round_braces_count, | |
$control_structure, | |
( is_array( $token ) and $token[0] === T_DOC_COMMENT ), | |
$trinity_started | |
); | |
} | |
if ( | |
$token === "{" or ( | |
is_array( $token ) and ( | |
$token[0] === T_CURLY_OPEN or | |
$token[0] === T_DOLLAR_OPEN_CURLY_BRACES | |
) | |
) | |
) { | |
// If a curly bracket occurs, no command without brackets can follow. | |
if ( !empty( $control_structure[$curly_braces_count] ) ) --$control_structure[$curly_braces_count]; | |
++$curly_braces_count; | |
// Inside of the new level of curly brackets it starts with no control structure. | |
$control_structure[$curly_braces_count] = 0; | |
} | |
} | |
} | |
/** | |
* Indents one token | |
* | |
* @param array $tokens (reference) | |
* @param integer $key | |
* @param integer $curly_braces_count | |
* @param integer $round_braces_count | |
* @param array $control_structure | |
* @param boolean $docblock | |
* @param boolean $trinity_started (reference) | |
*/ | |
function indent_text( &$tokens, $key, $curly_braces_count, $round_braces_count, $control_structure, $docblock, &$trinity_started ) { | |
if ( is_string( $tokens[$key] ) ) { | |
$text =& $tokens[$key]; | |
// If there is no line break it is only a inline string, not involved in indenting | |
if ( strpos( $text, "\n" )===false ) return; | |
} else { | |
$text =& $tokens[$key][1]; | |
// If there is no line break it is only a inline string, not involved in indenting | |
if ( strpos( $text, "\n" )===false ) return; | |
if ( token_is_taboo( $tokens[$key] ) ) return; | |
} | |
$indent = $curly_braces_count + $round_braces_count; | |
for ( $i=0; $i<=$curly_braces_count; ++$i ) { | |
$indent += $control_structure[$i]; | |
} | |
// One indentation level less for "switch ... case ... default" | |
if ( | |
isset( $tokens[$key+1] ) and | |
is_array( $tokens[$key+1] ) and ( | |
$tokens[$key+1][0] === T_CASE or | |
$tokens[$key+1][0] === T_DEFAULT or ( | |
isset( $tokens[$key+2] ) and | |
is_array( $tokens[$key+2] ) and ( | |
$tokens[$key+2][0] === T_CASE or | |
$tokens[$key+2][0] === T_DEFAULT | |
) and | |
// T_WHITESPACE without \n first | |
$tokens[$key+1][0] === T_WHITESPACE and | |
strpos( $tokens[$key+1][1], "\n" )===false | |
) | |
) | |
) --$indent; | |
// One indentation level less for an opening curly brace on a seperate line | |
if ( | |
isset( $tokens[$key+2] ) and ( | |
$tokens[$key+1] === "{" or ( | |
is_array( $tokens[$key+1] ) and ( | |
$tokens[$key+1][0] === T_CURLY_OPEN or | |
$tokens[$key+1][0] === T_DOLLAR_OPEN_CURLY_BRACES | |
) | |
) | |
) and ( | |
is_array( $tokens[$key+2] ) and | |
$tokens[$key+2][0] === T_WHITESPACE and | |
strpos( $tokens[$key+2][1], "\n" )!==false | |
) and ( | |
// Only if the curly brace belongs to a control structure | |
$control_structure[$curly_braces_count] > 0 | |
) | |
) --$indent; | |
// One additional indentation level for operators at the beginning or the end of a line | |
if ( !$round_braces_count ) { | |
static $operators = array( | |
// arithmetic | |
"+", | |
"-", | |
"*", | |
"/", | |
"%", | |
// assignment | |
"=", | |
array( T_PLUS_EQUAL, "+=" ), | |
array( T_MINUS_EQUAL, "-=" ), | |
array( T_MUL_EQUAL, "*=" ), | |
array( T_DIV_EQUAL, "/=" ), | |
array( T_MOD_EQUAL, "%=" ), | |
array( T_AND_EQUAL, "&=" ), | |
array( T_OR_EQUAL, "|=" ), | |
array( T_XOR_EQUAL, "^=" ), | |
// bitwise | |
"&", | |
"|", | |
"^", | |
array( T_SL, "<<" ), | |
array( T_SR, ">>" ), | |
// comparison | |
array( T_IS_EQUAL, "==" ), | |
array( T_IS_IDENTICAL, "===" ), | |
array( T_IS_NOT_EQUAL, "!=" ), | |
array( T_IS_NOT_EQUAL, "<>" ), | |
array( T_IS_NOT_IDENTICAL, "!==" ), | |
"<", | |
">", | |
array( T_IS_SMALLER_OR_EQUAL, "<=" ), | |
array( T_IS_GREATER_OR_EQUAL, ">=" ), | |
// logical | |
array( T_LOGICAL_AND, "and" ), | |
array( T_LOGICAL_OR, "or" ), | |
array( T_LOGICAL_XOR, "xor" ), | |
array( T_BOOLEAN_AND, "&&" ), | |
array( T_BOOLEAN_OR, "||" ), | |
// string | |
".", | |
array( T_CONCAT_EQUAL, ".=" ), | |
// type | |
array( T_INSTANCEOF, "instanceof" ) | |
); | |
if ( | |
( isset( $tokens[$key+1] ) and in_array( $tokens[$key+1], $operators ) ) or | |
( isset( $tokens[$key-1] ) and in_array( $tokens[$key-1], $operators ) ) | |
) { | |
++$indent; | |
} elseif ( | |
( isset( $tokens[$key+1] ) and $tokens[$key+1] === "?" ) or | |
( isset( $tokens[$key-1] ) and $tokens[$key-1] === "?" ) | |
) { | |
++$indent; | |
$trinity_started = true; | |
} elseif ( | |
$trinity_started and ( | |
( isset( $tokens[$key+1] ) and $tokens[$key+1] === ":" ) or | |
( isset( $tokens[$key-1] ) and $tokens[$key-1] === ":" ) | |
) | |
) { | |
++$indent; | |
$trinity_started = false; | |
} | |
} | |
$indent_str = str_repeat( $GLOBALS['indent_char'], max( $indent, 0 ) ); | |
// Indent the current token | |
$text = preg_replace( | |
"/\n[ \t]*/", | |
"\n".$indent_str.( $docblock?" ":"" ), | |
$text | |
); | |
// Cut the indenting at the beginning of the next token | |
// End of file reached | |
if ( !isset( $tokens[$key+1] ) ) return; | |
if ( is_string( $tokens[$key+1] ) ) { | |
$text2 =& $tokens[$key+1]; | |
} else { | |
$text2 =& $tokens[$key+1][1]; | |
} | |
// Remove indenting at beginning of the the next token | |
$text2 = preg_replace( | |
"/^[ \t]*/", | |
"", | |
$text2 | |
); | |
} | |
/** | |
* Strips indenting before single closing PHP tags | |
* | |
* @param array $tokens (reference) | |
*/ | |
function strip_closetag_indenting( &$tokens ) { | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) ) continue; | |
if ( | |
// T_CLOSE_TAG with following \n | |
$token[0] === T_CLOSE_TAG and | |
substr( $token[1], -1 ) === "\n" | |
) { | |
if ( | |
// T_WHITESPACE or T_COMMENT before with \n at the end | |
isset( $tokens[$key-1] ) and | |
is_array( $tokens[$key-1] ) and | |
( $tokens[$key-1][0] === T_WHITESPACE or $tokens[$key-1][0] === T_COMMENT ) and | |
preg_match( "/\n[ \t]*$/", $tokens[$key-1][1] ) | |
) { | |
$tokens[$key-1][1] = preg_replace( "/\n[ \t]*$/", "\n", $tokens[$key-1][1] ); | |
} elseif ( | |
// T_WHITESPACE before without \n | |
isset( $tokens[$key-1] ) and | |
is_array( $tokens[$key-1] ) and | |
$tokens[$key-1][0] === T_WHITESPACE and | |
strpos( $tokens[$key-1][1], "\n" )===false and | |
// T_WHITESPACE before or T_COMMENT with \n at the end | |
isset( $tokens[$key-2] ) and | |
is_array( $tokens[$key-2] ) and | |
( $tokens[$key-2][0] === T_WHITESPACE or $tokens[$key-2][0] === T_COMMENT ) and | |
preg_match( "/\n[ \t]*$/", $tokens[$key-2][1] ) | |
) { | |
$tokens[$key-1] = ""; | |
$tokens[$key-2][1] = preg_replace( "/\n[ \t]*$/", "\n", $tokens[$key-2][1] ); | |
} | |
} | |
} | |
} | |
//////////////// PHPDOC FUNCTIONS /////////////////// | |
/** | |
* Gets all defined functions | |
* | |
* Functions inside of curly braces will be ignored. | |
* | |
* @param string $content | |
* @return array | |
*/ | |
function get_functions( &$content ) { | |
$tokens = get_tokens( $content ); | |
$functions = array(); | |
$curly_braces_count = 0; | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) ) { | |
if ( $token === "{" ) ++$curly_braces_count; | |
elseif ( $token === "}" ) --$curly_braces_count; | |
} elseif ( | |
$token[0] === T_FUNCTION and | |
$curly_braces_count === 0 and | |
isset( $tokens[$key+2] ) and | |
is_array( $tokens[$key+2] ) | |
) { | |
$functions[] = $tokens[$key+2][1]; | |
} | |
} | |
return $functions; | |
} | |
/** | |
* Gets all defined includes | |
* | |
* @param array $seetags (reference) | |
* @param string $content | |
* @param string $file | |
*/ | |
function find_includes( &$seetags, &$content, $file ) { | |
$tokens = get_tokens( $content ); | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) ) continue; | |
if ( !in_array( $token[0], array( T_REQUIRE, T_REQUIRE_ONCE, T_INCLUDE, T_INCLUDE_ONCE ) ) ) continue; | |
$t = get_argument_tokens( $tokens, $key ); | |
strip_whitespace( $t ); | |
// Strip round brackets | |
if ( $t[0] === "(" and $t[count( $t )-1] === ")" ) { | |
$t = array_splice( $t, 1, -1 ); | |
} | |
if ( !$t ) { | |
possible_syntax_error( $tokens, $key, "Missing argument" ); | |
continue; | |
} | |
if ( !is_array( $t[0] ) ) continue; | |
// Strip leading docroot variable or constant | |
if ( | |
( $t[0][0] === T_VARIABLE or $t[0][0] === T_STRING ) and | |
in_array( $t[0][1], $GLOBALS['docrootvars'] ) and | |
$t[1] === "." | |
) { | |
$t = array_splice( $t, 2 ); | |
} | |
if ( | |
count( $t ) == 1 and | |
$t[0][0] === T_CONSTANT_ENCAPSED_STRING | |
) { | |
$includedfile = substr( $t[0][1], 1, -1 ); | |
$seetags[$includedfile][] = array( $file ); | |
continue; | |
} | |
if ( !$t ) { | |
possible_syntax_error( $tokens, $key, "String concatenator without following string" ); | |
} | |
} | |
} | |
/** | |
* Replaces one DocTag in a DocBlock | |
* | |
* Existing valid DocTags will be used without change | |
* | |
* @param string $text Content of the DocBlock | |
* @param string $tagname Name of the tag | |
* @param array $tags All tags to be inserted | |
* @return string | |
*/ | |
function add_doctags_to_doc_comment( $text, $tagname, $tags ) { | |
if ( !count( $tags ) ) return $text; | |
// Replacement for array_unique() | |
$tagids = array(); | |
foreach ( $tags as $key => $tag ) { | |
if ( !in_array( $tag[0], $tagids ) ) { | |
$tagids[] = $tag[0]; | |
} else { | |
unset( $tags[$key] ); | |
} | |
} | |
$oldtags = array(); | |
$lines = explode( "\n", $text ); | |
$newtext = ""; | |
foreach ( $lines as $key => $line ) { | |
// Add doctags after the last line | |
if ( $key == count( $lines )-1 ) { | |
foreach ( $tags as $tag ) { | |
$tagid = $tag[0]; | |
if ( isset( $oldtags[$tagid] ) and count( $oldtags[$tagid] ) ) { | |
// Use existing line | |
foreach ( $oldtags[$tagid] as $oldtag ) { | |
if ( | |
$tagname == "param" and | |
preg_match( '/^\s*\*\s+@param\s+([A-Za-z0-9_]+)\s+(\$[A-Za-z0-9_]+)\s+(.*)$/', $oldtag, $matches ) | |
) { | |
// Replace param type if a type hint exists | |
if ( empty( $tag[1] ) ) $tag[1] = $matches[1]; | |
// Add comment for optional and reference if not already existing | |
if ( | |
isset( $tag[2] ) and | |
substr( $matches[3], 0, strlen( $tag[2] ) ) != $tag[2] | |
) { | |
$matches[3] = $tag[2]." ".$matches[3]; | |
} | |
$newtext .= "* @param ".$tag[1]." ".$tag[0]." ".$matches[3]."\n"; | |
} else { | |
// Take old line without changes | |
$newtext .= $oldtag."\n"; | |
} | |
} | |
} else { | |
// Add new line | |
switch ( $tagname ) { | |
case "param": | |
if ( empty( $tag[1] ) ) $tag[1] = "unknown"; | |
$newtext .= "* @param ".$tag[1]." ".$tag[0].( isset( $tag[2] )?" ".$tag[2]:"" )."\n"; | |
break; | |
case "uses": | |
$newtext .= "* @uses ".$tag[0]."()\n"; | |
break; | |
case "return": | |
$newtext .= "* @return unknown\n"; | |
break; | |
case "author": | |
if ( $GLOBALS['default_author'] ) { | |
$newtext .= "* @author ".$GLOBALS['default_author']."\n"; | |
} | |
break; | |
case "package": | |
$newtext .= "* @package ".$GLOBALS['default_package']."\n"; | |
break; | |
case "see": | |
$newtext .= "* @see ".$tag[0]."\n"; | |
break; | |
} | |
} | |
} | |
} | |
// Match DocTag | |
$regex = '^\s*\*\s+@'.$tagname; | |
// Match param tag variable | |
if ( $tagname=="param" ) $regex .= '[^\$]*(\$[A-Za-z0-9_]+)'; | |
if ( preg_match( '/'.$regex.'/', $line, $matches ) ) { | |
if ( $tagname=="param" ) $oldtags[$matches[1]][] = $line; | |
else $oldtags[""][] = $line; | |
} else { | |
// Don't change lines without a DocTag | |
$newtext .= $line; | |
// Add a line break after every line except the last | |
if ( $key != count( $lines )-1 ) $newtext.="\n"; | |
} | |
} | |
return $newtext; | |
} | |
/** | |
* Collects the doctags for a function docblock | |
* | |
* @param array $tokens (reference) | |
* @return array | |
*/ | |
function collect_doctags( &$tokens ) { | |
$function_declarations = array(); | |
$function = ""; | |
$curly_braces_count = 0; | |
$usestags = array(); | |
$paramtags = array(); | |
$returntags = array(); | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) ) { | |
if ( $token === "{" ) { | |
++$curly_braces_count; | |
} elseif ( $token === "}" ) { | |
if ( --$curly_braces_count==0 ) $function = ""; | |
} | |
} else { | |
switch ( $token[0] ) { | |
case T_FUNCTION: | |
// Find function definitions | |
$round_braces_count = 0; | |
$k = $key + 1; | |
if ( is_string( $tokens[$k] ) or $tokens[$k][0] !== T_WHITESPACE ) { | |
possible_syntax_error( $tokens, $k, "No whitespace found between function keyword and function name" ); | |
break; | |
} | |
++$k; | |
// & before function name | |
if ( $tokens[$k] === "&" ) ++$k; | |
if ( is_string( $tokens[$k] ) or $tokens[$k][0] !== T_STRING ) { | |
possible_syntax_error( $tokens, $k, "No string for function name found" ); | |
break; | |
} | |
$function = $tokens[$k][1]; | |
$function_declarations[] = $key; | |
// Collect param-doctags | |
$k += 2; | |
// Area between round brackets | |
$reference = false; | |
while ( ( $tokens[$k] != ")" or $round_braces_count ) and $k < count( $tokens ) ) { | |
if ( is_string( $tokens[$k] ) ) { | |
if ( $tokens[$k] === "(" ) ++$round_braces_count; | |
elseif ( $tokens[$k] === ")" ) --$round_braces_count; | |
elseif ( $tokens[$k] === "&" ) $reference = true; | |
} else { | |
$typehint = false; | |
if ( | |
$tokens[$k][0] === T_VARIABLE | |
) { | |
$typehint = ""; | |
} elseif ( | |
$tokens[$k][0] === T_ARRAY and | |
isset( $tokens[$k+1][0] ) and $tokens[$k+1][0] === T_WHITESPACE and | |
isset( $tokens[$k+2][0] ) and $tokens[$k+2][0] === T_VARIABLE | |
) { | |
$k += 2; | |
$typehint = "array"; | |
} elseif ( | |
$tokens[$k][0] === T_STRING and | |
isset( $tokens[$k+1][0] ) and $tokens[$k+1][0] === T_WHITESPACE and | |
isset( $tokens[$k+2][0] ) and $tokens[$k+2][0] === T_VARIABLE | |
) { | |
$k += 2; | |
$typehint = "object"; | |
} | |
if ( $typehint !== false ) { | |
$comments = array(); | |
if ( | |
( isset( $tokens[$k+1] ) and $tokens[$k+1] === "=" ) or ( | |
isset( $tokens[$k+1][0] ) and $tokens[$k+1][0] === T_WHITESPACE and | |
isset( $tokens[$k+2] ) and $tokens[$k+2] === "=" | |
) | |
) { | |
$comments[] = "optional"; | |
} | |
if ( $reference ) { | |
$comments[] = "reference"; | |
$reference = false; | |
} | |
if ( count( $comments ) ) { | |
$comment = "(".join( ", ", $comments ).")"; | |
} else { | |
$comment = ""; | |
} | |
$paramtags[$function][] = array( $tokens[$k][1], $typehint, $comment ); | |
} | |
} | |
++$k; | |
} | |
break; | |
case T_CURLY_OPEN: | |
case T_DOLLAR_OPEN_CURLY_BRACES: | |
++$curly_braces_count; | |
break; | |
case T_STRING: | |
// Find function calls | |
if ( | |
$tokens[$key+1] === "(" and | |
!in_array( $key-2, $function_declarations ) and | |
in_array( $token[1], $GLOBALS['functions'] ) | |
) { | |
$usestags[$function][] = array( $token[1] ); | |
} | |
break; | |
case T_RETURN: | |
// Find returns | |
if ( | |
$tokens[$key+1] != ";" and | |
$tokens[$key+2] != ";" | |
) { | |
$returntags[$function][] = array( "" ); | |
} | |
break; | |
} | |
} | |
} | |
return array( $usestags, $paramtags, $returntags ); | |
} | |
/** | |
* Adds file DocBlocks where missing | |
* | |
* @param array $tokens (reference) | |
*/ | |
function add_file_docblock( &$tokens ) { | |
$default_file_docblock = "/**\n". | |
" * ".$GLOBALS['file']."\n". | |
" *\n"; | |
if ( $GLOBALS['default_author'] ) { | |
$default_file_docblock .= " * @author ".$GLOBALS['default_author']."\n"; | |
} | |
$default_file_docblock .= " * @package ".$GLOBALS['default_package']."\n". | |
" */"; | |
// File begins with PHP | |
switch ( $tokens[0][0] ) { | |
case T_OPEN_TAG: | |
if ( $GLOBALS['open_tag']=="<?" ) { | |
if ( $tokens[1][0] === T_WHITESPACE and $tokens[2][0] === T_DOC_COMMENT ) return; | |
// Insert new file docblock after open tag | |
array_splice( $tokens, 0, 1, array( | |
array( T_OPEN_TAG, "<?" ), | |
array( T_WHITESPACE, "\n" ), | |
array( T_DOC_COMMENT, $default_file_docblock ), | |
array( T_WHITESPACE, "\n" ) | |
) ); | |
} else { | |
if ( $tokens[1][0] === T_DOC_COMMENT ) return; | |
// Insert new file docblock after open tag | |
array_splice( $tokens, 0, 1, array( | |
array( T_OPEN_TAG, $GLOBALS['open_tag']."\n" ), | |
array( T_DOC_COMMENT, $default_file_docblock ), | |
array( T_WHITESPACE, "\n" ) | |
) ); | |
} | |
break; | |
case T_INLINE_HTML: | |
if ( preg_match( "/^#!\//", $tokens[0][1] ) ) { | |
// File begins with "shebang"-line for direct execution | |
if ( $GLOBALS['open_tag']=="<?" ) { | |
if ( $tokens[2][0] === T_WHITESPACE and $tokens[3][0] === T_DOC_COMMENT ) return; | |
// Insert new file docblock after open tag | |
array_splice( $tokens, 1, 1, array( | |
array( T_OPEN_TAG, "<?" ), | |
array( T_WHITESPACE, "\n" ), | |
array( T_DOC_COMMENT, $default_file_docblock ), | |
array( T_WHITESPACE, "\n" ) | |
) ); | |
} else { | |
if ( $tokens[2][0] === T_DOC_COMMENT ) return; | |
// Insert new file docblock after open tag | |
array_splice( $tokens, 1, 1, array( | |
array( T_OPEN_TAG, $GLOBALS['open_tag']."\n" ), | |
array( T_DOC_COMMENT, $default_file_docblock ), | |
array( T_WHITESPACE, "\n" ) | |
) ); | |
} | |
} else { | |
// File begins with HTML | |
// Insert new file docblock in open and close tags at the beginning of the file | |
if ( $GLOBALS['open_tag']=="<?" ) { | |
array_splice( $tokens, 0, 0, array( | |
array( T_OPEN_TAG, "<?" ), | |
array( T_WHITESPACE, "\n" ), | |
array( T_DOC_COMMENT, $default_file_docblock ), | |
array( T_WHITESPACE, "\n\n\n" ), | |
array( T_CLOSE_TAG, "?>\n" ) | |
) ); | |
} else { | |
array_splice( $tokens, 0, 0, array( | |
array( T_OPEN_TAG, $GLOBALS['open_tag']."\n" ), | |
array( T_DOC_COMMENT, $default_file_docblock ), | |
array( T_WHITESPACE, "\n\n\n" ), | |
array( T_CLOSE_TAG, "?>\n" ) | |
) ); | |
} | |
} | |
} | |
} | |
/** | |
* Adds funktion DocBlocks where missing | |
* | |
* @param array $tokens (reference) | |
*/ | |
function add_function_docblocks( &$tokens ) { | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) or $token[0] !== T_FUNCTION ) continue; | |
// Find beginning of the function declaration | |
$k = $key; | |
while ( | |
isset( $tokens[$k-1] ) and | |
strpos( token_text( $tokens[$k-1] ), "\n" )===false | |
) --$k; | |
if ( | |
!isset( $tokens[$k-2] ) or | |
!is_array( $tokens[$k-2] ) or | |
$tokens[$k-2][0] != T_DOC_COMMENT | |
) { | |
// Collect old non-phpdoc comments | |
$comment = ""; | |
$replace = 0; | |
while ( | |
isset( $tokens[$k-1] ) and | |
is_array( $tokens[$k-1] ) and | |
$tokens[$k-1][0] === T_COMMENT | |
) { | |
$comment = " * ".trim( ltrim( trim( $tokens[$k-1][1] ), "/#" ) )."\n".$comment; | |
--$k; | |
++$replace; | |
} | |
if ( !$comment ) $comment = " *\n"; | |
array_splice( $tokens, $k, $replace, array( | |
array( T_DOC_COMMENT, "/**\n". | |
$comment. | |
" */" ), | |
array( T_WHITESPACE, "\n" ) | |
) ); | |
} | |
} | |
} | |
/** | |
* Adds DocTags to file or function DocBlocks | |
* | |
* @param array $tokens (reference) | |
* @param array $usetags | |
* @param array $paramtags | |
* @param array $returntags | |
* @param array $seetags | |
*/ | |
function add_doctags( &$tokens, $usetags, $paramtags, $returntags, $seetags ) { | |
$filedocblock = false; | |
foreach ( $tokens as $key => &$token ) { | |
if ( is_string( $token ) ) continue; | |
list( $id, $text ) = $token; | |
if ( $id != T_DOC_COMMENT ) continue; | |
$k = $key + 1; | |
while ( in_array( $tokens[$k][0], array( T_WHITESPACE, T_STATIC, T_PUBLIC, T_PROTECTED, T_PRIVATE ) ) ) ++$k; | |
if ( | |
$tokens[$k][0] === T_FUNCTION and | |
$tokens[$k+1][0] === T_WHITESPACE and | |
$tokens[$k+2][0] === T_STRING | |
) { | |
// Function DocBlock | |
$f = $tokens[$k+2][1]; | |
if ( isset( $paramtags[$f] ) ) { | |
$tokens[$key] = array( $id, add_doctags_to_doc_comment( $tokens[$key][1], "param", $paramtags[$f] ) ); | |
} | |
if ( isset( $returntags[$f] ) ) { | |
$tokens[$key] = array( $id, add_doctags_to_doc_comment( $tokens[$key][1], "return", $returntags[$f] ) ); | |
} | |
if ( isset( $usestags[$f] ) ) { | |
$tokens[$key] = array( $id, add_doctags_to_doc_comment( $tokens[$key][1], "uses", $usestags[$f] ) ); | |
} | |
} elseif ( !$filedocblock ) { | |
// File DocBlock | |
if ( isset( $usestags[""] ) ) { | |
$tokens[$key] = array( $id, add_doctags_to_doc_comment( $tokens[$key][1], "uses", $usestags[""] ) ); | |
} | |
$tokens[$key] = array( $id, add_doctags_to_doc_comment( $tokens[$key][1], "author", array( array( "" ) ) ) ); | |
$tokens[$key] = array( $id, add_doctags_to_doc_comment( $tokens[$key][1], "package", array( array( "" ) ) ) ); | |
if ( isset( $seetags[$GLOBALS['file']] ) ) { | |
$tokens[$key] = array( $id, add_doctags_to_doc_comment( $tokens[$key][1], "see", $seetags[$GLOBALS['file']] ) ); | |
} | |
} | |
$filedocblock = true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment