mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 23:02:41 +01:00
Add a linter rule for alias functions
Summary: Ref T7409. Adds `ArcanistXHPASTLinter::LINT_ALIAS_FUNCTION` for linting the use of alias funtions. Based on [[https://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Generic/Sniffs/PHP/ForbiddenFunctionsSniff.php | Generic_Sniffs_PHP_ForbiddenFunctionsSniff]]. See [[http://php.net/manual/en/aliases.php | list of function aliases]]. Test Plan: Added unit tests. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley Maniphest Tasks: T7409 Differential Revision: https://secure.phabricator.com/D12422
This commit is contained in:
parent
e3a556af9b
commit
e1a057b4d9
2 changed files with 224 additions and 1 deletions
|
@ -64,6 +64,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
const LINT_CLASS_NAME_LITERAL = 62;
|
const LINT_CLASS_NAME_LITERAL = 62;
|
||||||
const LINT_USELESS_OVERRIDING_METHOD = 63;
|
const LINT_USELESS_OVERRIDING_METHOD = 63;
|
||||||
const LINT_NO_PARENT_SCOPE = 64;
|
const LINT_NO_PARENT_SCOPE = 64;
|
||||||
|
const LINT_ALIAS_FUNCTION = 65;
|
||||||
|
|
||||||
private $blacklistedFunctions = array();
|
private $blacklistedFunctions = array();
|
||||||
private $naminghook;
|
private $naminghook;
|
||||||
|
@ -200,6 +201,8 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
=> pht('Useless Overriding Method'),
|
=> pht('Useless Overriding Method'),
|
||||||
self::LINT_NO_PARENT_SCOPE
|
self::LINT_NO_PARENT_SCOPE
|
||||||
=> pht('No Parent Scope'),
|
=> pht('No Parent Scope'),
|
||||||
|
self::LINT_ALIAS_FUNCTION
|
||||||
|
=> pht('Alias Functions'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,6 +254,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
self::LINT_LOWERCASE_FUNCTIONS => $advice,
|
self::LINT_LOWERCASE_FUNCTIONS => $advice,
|
||||||
self::LINT_CLASS_NAME_LITERAL => $advice,
|
self::LINT_CLASS_NAME_LITERAL => $advice,
|
||||||
self::LINT_USELESS_OVERRIDING_METHOD => $advice,
|
self::LINT_USELESS_OVERRIDING_METHOD => $advice,
|
||||||
|
self::LINT_ALIAS_FUNCTION => $advice,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +322,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
|
|
||||||
public function getVersion() {
|
public function getVersion() {
|
||||||
// The version number should be incremented whenever a new rule is added.
|
// The version number should be incremented whenever a new rule is added.
|
||||||
return '26';
|
return '27';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function resolveFuture($path, Future $future) {
|
protected function resolveFuture($path, Future $future) {
|
||||||
|
@ -409,6 +413,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
'lintClassNameLiteral' => self::LINT_CLASS_NAME_LITERAL,
|
'lintClassNameLiteral' => self::LINT_CLASS_NAME_LITERAL,
|
||||||
'lintUselessOverridingMethods' => self::LINT_USELESS_OVERRIDING_METHOD,
|
'lintUselessOverridingMethods' => self::LINT_USELESS_OVERRIDING_METHOD,
|
||||||
'lintNoParentScope' => self::LINT_NO_PARENT_SCOPE,
|
'lintNoParentScope' => self::LINT_NO_PARENT_SCOPE,
|
||||||
|
'lintAliasFunctions' => self::LINT_ALIAS_FUNCTION,
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($method_codes as $method => $codes) {
|
foreach ($method_codes as $method => $codes) {
|
||||||
|
@ -3891,6 +3896,210 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function lintAliasFunctions(XHPASTNode $root) {
|
||||||
|
static $aliases = array(
|
||||||
|
'_' => 'gettext',
|
||||||
|
'chop' => 'rtrim',
|
||||||
|
'close' => 'closedir',
|
||||||
|
'com_get' => 'com_propget',
|
||||||
|
'com_propset' => 'com_propput',
|
||||||
|
'com_set' => 'com_propput',
|
||||||
|
'die' => 'exit',
|
||||||
|
'diskfreespace' => 'disk_free_space',
|
||||||
|
'doubleval' => 'floatval',
|
||||||
|
'drawarc' => 'swfshape_drawarc',
|
||||||
|
'drawcircle' => 'swfshape_drawcircle',
|
||||||
|
'drawcubic' => 'swfshape_drawcubic',
|
||||||
|
'drawcubicto' => 'swfshape_drawcubicto',
|
||||||
|
'drawcurve' => 'swfshape_drawcurve',
|
||||||
|
'drawcurveto' => 'swfshape_drawcurveto',
|
||||||
|
'drawglyph' => 'swfshape_drawglyph',
|
||||||
|
'drawline' => 'swfshape_drawline',
|
||||||
|
'drawlineto' => 'swfshape_drawlineto',
|
||||||
|
'fbsql' => 'fbsql_db_query',
|
||||||
|
'fputs' => 'fwrite',
|
||||||
|
'gzputs' => 'gzwrite',
|
||||||
|
'i18n_convert' => 'mb_convert_encoding',
|
||||||
|
'i18n_discover_encoding' => 'mb_detect_encoding',
|
||||||
|
'i18n_http_input' => 'mb_http_input',
|
||||||
|
'i18n_http_output' => 'mb_http_output',
|
||||||
|
'i18n_internal_encoding' => 'mb_internal_encoding',
|
||||||
|
'i18n_ja_jp_hantozen' => 'mb_convert_kana',
|
||||||
|
'i18n_mime_header_decode' => 'mb_decode_mimeheader',
|
||||||
|
'i18n_mime_header_encode' => 'mb_encode_mimeheader',
|
||||||
|
'imap_create' => 'imap_createmailbox',
|
||||||
|
'imap_fetchtext' => 'imap_body',
|
||||||
|
'imap_getmailboxes' => 'imap_list_full',
|
||||||
|
'imap_getsubscribed' => 'imap_lsub_full',
|
||||||
|
'imap_header' => 'imap_headerinfo',
|
||||||
|
'imap_listmailbox' => 'imap_list',
|
||||||
|
'imap_listsubscribed' => 'imap_lsub',
|
||||||
|
'imap_rename' => 'imap_renamemailbox',
|
||||||
|
'imap_scan' => 'imap_listscan',
|
||||||
|
'imap_scanmailbox' => 'imap_listscan',
|
||||||
|
'ini_alter' => 'ini_set',
|
||||||
|
'is_double' => 'is_float',
|
||||||
|
'is_integer' => 'is_int',
|
||||||
|
'is_long' => 'is_int',
|
||||||
|
'is_real' => 'is_float',
|
||||||
|
'is_writeable' => 'is_writable',
|
||||||
|
'join' => 'implode',
|
||||||
|
'key_exists' => 'array_key_exists',
|
||||||
|
'ldap_close' => 'ldap_unbind',
|
||||||
|
'magic_quotes_runtime' => 'set_magic_quotes_runtime',
|
||||||
|
'mbstrcut' => 'mb_strcut',
|
||||||
|
'mbstrlen' => 'mb_strlen',
|
||||||
|
'mbstrpos' => 'mb_strpos',
|
||||||
|
'mbstrrpos' => 'mb_strrpos',
|
||||||
|
'mbsubstr' => 'mb_substr',
|
||||||
|
'ming_setcubicthreshold' => 'ming_setCubicThreshold',
|
||||||
|
'ming_setscale' => 'ming_setScale',
|
||||||
|
'msql' => 'msql_db_query',
|
||||||
|
'msql_createdb' => 'msql_create_db',
|
||||||
|
'msql_dbname' => 'msql_result',
|
||||||
|
'msql_dropdb' => 'msql_drop_db',
|
||||||
|
'msql_fieldflags' => 'msql_field_flags',
|
||||||
|
'msql_fieldlen' => 'msql_field_len',
|
||||||
|
'msql_fieldname' => 'msql_field_name',
|
||||||
|
'msql_fieldtable' => 'msql_field_table',
|
||||||
|
'msql_fieldtype' => 'msql_field_type',
|
||||||
|
'msql_freeresult' => 'msql_free_result',
|
||||||
|
'msql_listdbs' => 'msql_list_dbs',
|
||||||
|
'msql_listfields' => 'msql_list_fields',
|
||||||
|
'msql_listtables' => 'msql_list_tables',
|
||||||
|
'msql_numfields' => 'msql_num_fields',
|
||||||
|
'msql_numrows' => 'msql_num_rows',
|
||||||
|
'msql_regcase' => 'sql_regcase',
|
||||||
|
'msql_selectdb' => 'msql_select_db',
|
||||||
|
'msql_tablename' => 'msql_result',
|
||||||
|
'mssql_affected_rows' => 'sybase_affected_rows',
|
||||||
|
'mssql_close' => 'sybase_close',
|
||||||
|
'mssql_connect' => 'sybase_connect',
|
||||||
|
'mssql_data_seek' => 'sybase_data_seek',
|
||||||
|
'mssql_fetch_array' => 'sybase_fetch_array',
|
||||||
|
'mssql_fetch_field' => 'sybase_fetch_field',
|
||||||
|
'mssql_fetch_object' => 'sybase_fetch_object',
|
||||||
|
'mssql_fetch_row' => 'sybase_fetch_row',
|
||||||
|
'mssql_field_seek' => 'sybase_field_seek',
|
||||||
|
'mssql_free_result' => 'sybase_free_result',
|
||||||
|
'mssql_get_last_message' => 'sybase_get_last_message',
|
||||||
|
'mssql_min_client_severity' => 'sybase_min_client_severity',
|
||||||
|
'mssql_min_error_severity' => 'sybase_min_error_severity',
|
||||||
|
'mssql_min_message_severity' => 'sybase_min_message_severity',
|
||||||
|
'mssql_min_server_severity' => 'sybase_min_server_severity',
|
||||||
|
'mssql_num_fields' => 'sybase_num_fields',
|
||||||
|
'mssql_num_rows' => 'sybase_num_rows',
|
||||||
|
'mssql_pconnect' => 'sybase_pconnect',
|
||||||
|
'mssql_query' => 'sybase_query',
|
||||||
|
'mssql_result' => 'sybase_result',
|
||||||
|
'mssql_select_db' => 'sybase_select_db',
|
||||||
|
'multcolor' => 'swfdisplayitem_multColor',
|
||||||
|
'mysql' => 'mysql_db_query',
|
||||||
|
'mysql_createdb' => 'mysql_create_db',
|
||||||
|
'mysql_db_name' => 'mysql_result',
|
||||||
|
'mysql_dbname' => 'mysql_result',
|
||||||
|
'mysql_dropdb' => 'mysql_drop_db',
|
||||||
|
'mysql_fieldflags' => 'mysql_field_flags',
|
||||||
|
'mysql_fieldlen' => 'mysql_field_len',
|
||||||
|
'mysql_fieldname' => 'mysql_field_name',
|
||||||
|
'mysql_fieldtable' => 'mysql_field_table',
|
||||||
|
'mysql_fieldtype' => 'mysql_field_type',
|
||||||
|
'mysql_freeresult' => 'mysql_free_result',
|
||||||
|
'mysql_listdbs' => 'mysql_list_dbs',
|
||||||
|
'mysql_listfields' => 'mysql_list_fields',
|
||||||
|
'mysql_listtables' => 'mysql_list_tables',
|
||||||
|
'mysql_numfields' => 'mysql_num_fields',
|
||||||
|
'mysql_numrows' => 'mysql_num_rows',
|
||||||
|
'mysql_selectdb' => 'mysql_select_db',
|
||||||
|
'mysql_tablename' => 'mysql_result',
|
||||||
|
'ociassignelem' => 'OCI-Collection::assignElem',
|
||||||
|
'ocibindbyname' => 'oci_bind_by_name',
|
||||||
|
'ocicancel' => 'oci_cancel',
|
||||||
|
'ocicloselob' => 'OCI-Lob::close',
|
||||||
|
'ocicollappend' => 'OCI-Collection::append',
|
||||||
|
'ocicollassign' => 'OCI-Collection::assign',
|
||||||
|
'ocicollmax' => 'OCI-Collection::max',
|
||||||
|
'ocicollsize' => 'OCI-Collection::size',
|
||||||
|
'ocicolltrim' => 'OCI-Collection::trim',
|
||||||
|
'ocicolumnisnull' => 'oci_field_is_null',
|
||||||
|
'ocicolumnname' => 'oci_field_name',
|
||||||
|
'ocicolumnprecision' => 'oci_field_precision',
|
||||||
|
'ocicolumnscale' => 'oci_field_scale',
|
||||||
|
'ocicolumnsize' => 'oci_field_size',
|
||||||
|
'ocicolumntype' => 'oci_field_type',
|
||||||
|
'ocicolumntyperaw' => 'oci_field_type_raw',
|
||||||
|
'ocicommit' => 'oci_commit',
|
||||||
|
'ocidefinebyname' => 'oci_define_by_name',
|
||||||
|
'ocierror' => 'oci_error',
|
||||||
|
'ociexecute' => 'oci_execute',
|
||||||
|
'ocifetch' => 'oci_fetch',
|
||||||
|
'ocifetchinto' => 'oci_fetch_array(),',
|
||||||
|
'ocifetchstatement' => 'oci_fetch_all',
|
||||||
|
'ocifreecollection' => 'OCI-Collection::free',
|
||||||
|
'ocifreecursor' => 'oci_free_statement',
|
||||||
|
'ocifreedesc' => 'oci_free_descriptor',
|
||||||
|
'ocifreestatement' => 'oci_free_statement',
|
||||||
|
'ocigetelem' => 'OCI-Collection::getElem',
|
||||||
|
'ociinternaldebug' => 'oci_internal_debug',
|
||||||
|
'ociloadlob' => 'OCI-Lob::load',
|
||||||
|
'ocilogon' => 'oci_connect',
|
||||||
|
'ocinewcollection' => 'oci_new_collection',
|
||||||
|
'ocinewcursor' => 'oci_new_cursor',
|
||||||
|
'ocinewdescriptor' => 'oci_new_descriptor',
|
||||||
|
'ocinlogon' => 'oci_new_connect',
|
||||||
|
'ocinumcols' => 'oci_num_fields',
|
||||||
|
'ociparse' => 'oci_parse',
|
||||||
|
'ocipasswordchange' => 'oci_password_change',
|
||||||
|
'ociplogon' => 'oci_pconnect',
|
||||||
|
'ociresult' => 'oci_result',
|
||||||
|
'ocirollback' => 'oci_rollback',
|
||||||
|
'ocisavelob' => 'OCI-Lob::save',
|
||||||
|
'ocisavelobfile' => 'OCI-Lob::import',
|
||||||
|
'ociserverversion' => 'oci_server_version',
|
||||||
|
'ocisetprefetch' => 'oci_set_prefetch',
|
||||||
|
'ocistatementtype' => 'oci_statement_type',
|
||||||
|
'ociwritelobtofile' => 'OCI-Lob::export',
|
||||||
|
'ociwritetemporarylob' => 'OCI-Lob::writeTemporary',
|
||||||
|
'odbc_do' => 'odbc_exec',
|
||||||
|
'odbc_field_precision' => 'odbc_field_len',
|
||||||
|
'pdf_add_outline' => 'pdf_add_bookmark',
|
||||||
|
'pg_clientencoding' => 'pg_client_encoding',
|
||||||
|
'pg_setclientencoding' => 'pg_set_client_encoding',
|
||||||
|
'pos' => 'current',
|
||||||
|
'recode' => 'recode_string',
|
||||||
|
'show_source' => 'highlight_file',
|
||||||
|
'sizeof' => 'count',
|
||||||
|
'snmpwalkoid' => 'snmprealwalk',
|
||||||
|
'strchr' => 'strstr',
|
||||||
|
'streammp3' => 'swfmovie_streamMp3',
|
||||||
|
'swfaction' => 'swfaction_init',
|
||||||
|
'swfbitmap' => 'swfbitmap_init',
|
||||||
|
'swfbutton' => 'swfbutton_init',
|
||||||
|
'swffill' => 'swffill_init',
|
||||||
|
'swffont' => 'swffont_init',
|
||||||
|
'swfgradient' => 'swfgradient_init',
|
||||||
|
'swfmorph' => 'swfmorph_init',
|
||||||
|
'swfmovie' => 'swfmovie_init',
|
||||||
|
'swfshape' => 'swfshape_init',
|
||||||
|
'swfsprite' => 'swfsprite_init',
|
||||||
|
'swftext' => 'swftext_init',
|
||||||
|
'swftextfield' => 'swftextfield_init',
|
||||||
|
'xptr_new_context' => 'xpath_new_context',
|
||||||
|
);
|
||||||
|
|
||||||
|
$functions = $this->getFunctionCalls($root, array_keys($aliases));
|
||||||
|
|
||||||
|
foreach ($functions as $function) {
|
||||||
|
$function_name = $function->getChildByIndex(0);
|
||||||
|
|
||||||
|
$this->raiseLintAtNode(
|
||||||
|
$function_name,
|
||||||
|
self::LINT_ALIAS_FUNCTION,
|
||||||
|
pht('Alias functions should be avoided.'),
|
||||||
|
$aliases[$function_name->getConcreteString()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve all calls to some specified function(s).
|
* Retrieve all calls to some specified function(s).
|
||||||
|
|
14
src/lint/linter/__tests__/xhpast/alias-functions.lint-test
Normal file
14
src/lint/linter/__tests__/xhpast/alias-functions.lint-test
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$x = array();
|
||||||
|
sizeof($x);
|
||||||
|
die();
|
||||||
|
~~~~~~~~~~
|
||||||
|
advice:4:1
|
||||||
|
advice:5:1
|
||||||
|
~~~~~~~~~~
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$x = array();
|
||||||
|
count($x);
|
||||||
|
exit();
|
Loading…
Reference in a new issue