mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 23:02: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',
|
'ArcanistFlake8LinterTestCase' => 'lint/linter/__tests__/ArcanistFlake8LinterTestCase.php',
|
||||||
'ArcanistFormattedStringXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistFormattedStringXHPASTLinterRule.php',
|
'ArcanistFormattedStringXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistFormattedStringXHPASTLinterRule.php',
|
||||||
'ArcanistFormattedStringXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistFormattedStringXHPASTLinterRuleTestCase.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',
|
'ArcanistFutureLinter' => 'lint/linter/ArcanistFutureLinter.php',
|
||||||
'ArcanistGeneratedLinter' => 'lint/linter/ArcanistGeneratedLinter.php',
|
'ArcanistGeneratedLinter' => 'lint/linter/ArcanistGeneratedLinter.php',
|
||||||
'ArcanistGeneratedLinterTestCase' => 'lint/linter/__tests__/ArcanistGeneratedLinterTestCase.php',
|
'ArcanistGeneratedLinterTestCase' => 'lint/linter/__tests__/ArcanistGeneratedLinterTestCase.php',
|
||||||
|
@ -539,6 +541,8 @@ phutil_register_library_map(array(
|
||||||
'ArcanistFlake8LinterTestCase' => 'ArcanistExternalLinterTestCase',
|
'ArcanistFlake8LinterTestCase' => 'ArcanistExternalLinterTestCase',
|
||||||
'ArcanistFormattedStringXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistFormattedStringXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistFormattedStringXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
'ArcanistFormattedStringXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
|
'ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
|
'ArcanistFunctionCallShouldBeTypeCastXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
'ArcanistFutureLinter' => 'ArcanistLinter',
|
'ArcanistFutureLinter' => 'ArcanistLinter',
|
||||||
'ArcanistGeneratedLinter' => 'ArcanistLinter',
|
'ArcanistGeneratedLinter' => 'ArcanistLinter',
|
||||||
'ArcanistGeneratedLinterTestCase' => 'ArcanistLinterTestCase',
|
'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