mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-26 00:32:41 +01:00
Add a linter rule for *val
functions
Summary: Type casts should be used instead of calls to the `*val` functions as function calls impose additional overhead. Test Plan: Added unit tests. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Differential Revision: https://secure.phabricator.com/D14572
This commit is contained in:
parent
4f1141d0c5
commit
578f540a92
5 changed files with 99 additions and 0 deletions
|
@ -145,6 +145,8 @@ phutil_register_library_map(array(
|
|||
'ArcanistFlake8LinterTestCase' => 'lint/linter/__tests__/ArcanistFlake8LinterTestCase.php',
|
||||
'ArcanistFormattedStringXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistFormattedStringXHPASTLinterRule.php',
|
||||
'ArcanistFormattedStringXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistFormattedStringXHPASTLinterRuleTestCase.php',
|
||||
'ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRule.php',
|
||||
'ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRuleTestCase.php',
|
||||
'ArcanistFutureLinter' => 'lint/linter/ArcanistFutureLinter.php',
|
||||
'ArcanistGeneratedLinter' => 'lint/linter/ArcanistGeneratedLinter.php',
|
||||
'ArcanistGeneratedLinterTestCase' => 'lint/linter/__tests__/ArcanistGeneratedLinterTestCase.php',
|
||||
|
@ -539,6 +541,8 @@ phutil_register_library_map(array(
|
|||
'ArcanistFlake8LinterTestCase' => 'ArcanistExternalLinterTestCase',
|
||||
'ArcanistFormattedStringXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistFormattedStringXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||
'ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||
'ArcanistFutureLinter' => 'ArcanistLinter',
|
||||
'ArcanistGeneratedLinter' => 'ArcanistLinter',
|
||||
'ArcanistGeneratedLinterTestCase' => 'ArcanistLinterTestCase',
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<?php
|
||||
|
||||
final class ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRule
|
||||
extends ArcanistXHPASTLinterRule {
|
||||
|
||||
const ID = 105;
|
||||
|
||||
public function getLintName() {
|
||||
return pht('Function Call Should Be Type Cast');
|
||||
}
|
||||
|
||||
public function getLintSeverity() {
|
||||
return ArcanistLintSeverity::SEVERITY_ADVICE;
|
||||
}
|
||||
|
||||
public function process(XHPASTNode $root) {
|
||||
static $cast_functions = array(
|
||||
'boolval' => 'bool',
|
||||
'doubleval' => 'double',
|
||||
'floatval' => 'double',
|
||||
'intval' => 'int',
|
||||
'strval' => 'string',
|
||||
);
|
||||
|
||||
$casts = $this->getFunctionCalls($root, array_keys($cast_functions));
|
||||
|
||||
foreach ($casts as $cast) {
|
||||
$function_name = $cast
|
||||
->getChildOfType(0, 'n_SYMBOL_NAME')
|
||||
->getConcreteString();
|
||||
$cast_name = $cast_functions[$function_name];
|
||||
|
||||
$parameters = $cast->getChildOfType(1, 'n_CALL_PARAMETER_LIST');
|
||||
$replacement = null;
|
||||
|
||||
// Only suggest a replacement if the function call has exactly
|
||||
// one parameter.
|
||||
if (count($parameters->getChildren()) == 1) {
|
||||
$parameter = $parameters->getChildByIndex(0);
|
||||
$replacement = '('.$cast_name.')'.$parameter->getConcreteString();
|
||||
}
|
||||
|
||||
$this->raiseLintAtNode(
|
||||
$cast,
|
||||
pht(
|
||||
'For consistency, use `%s` (a type cast) instead of `%s` '.
|
||||
'(a function call). Function calls impose additional overhead.',
|
||||
'('.$cast_name.')',
|
||||
$function_name),
|
||||
$replacement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
final class ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRuleTestCase
|
||||
extends ArcanistXHPASTLinterRuleTestCase {
|
||||
|
||||
public function testLinter() {
|
||||
$this->executeTestsInDirectory(
|
||||
dirname(__FILE__).'/function-call-should-be-type-cast/');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
boolval($x);
|
||||
doubleval($x);
|
||||
floatval($x);
|
||||
intval($x);
|
||||
strval($x);
|
||||
~~~~~~~~~~
|
||||
advice:2:1
|
||||
advice:3:1
|
||||
advice:4:1
|
||||
advice:5:1
|
||||
advice:6:1
|
||||
~~~~~~~~~~
|
||||
<?php
|
||||
(bool)$x;
|
||||
(double)$x;
|
||||
(double)$x;
|
||||
(int)$x;
|
||||
(string)$x;
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
// If the function call doesn't have exactly one parameter,
|
||||
// we don't provide an autofix.
|
||||
strval($x, $y);
|
||||
~~~~~~~~~~
|
||||
advice:4:1
|
||||
~~~~~~~~~~
|
||||
<?php
|
||||
// If the function call doesn't have exactly one parameter,
|
||||
// we don't provide an autofix.
|
||||
strval($x, $y);
|
Loading…
Reference in a new issue