1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-22 23:02:41 +01:00

Add a "binary integer casing" linter rule

Summary: Adds a linter rule which ensures that binary integers are written in lowercase (i.e. `0b1` instead of `0B1`).

Test Plan: Added test cases.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D14644
This commit is contained in:
Joshua Spence 2015-12-03 09:47:27 +11:00
parent ae3c2cb0e1
commit 3c193984da
5 changed files with 72 additions and 3 deletions

View file

@ -32,6 +32,8 @@ phutil_register_library_map(array(
'ArcanistBaseXHPASTLinter' => 'lint/linter/ArcanistBaseXHPASTLinter.php', 'ArcanistBaseXHPASTLinter' => 'lint/linter/ArcanistBaseXHPASTLinter.php',
'ArcanistBinaryExpressionSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBinaryExpressionSpacingXHPASTLinterRule.php', 'ArcanistBinaryExpressionSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBinaryExpressionSpacingXHPASTLinterRule.php',
'ArcanistBinaryExpressionSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBinaryExpressionSpacingXHPASTLinterRuleTestCase.php', 'ArcanistBinaryExpressionSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBinaryExpressionSpacingXHPASTLinterRuleTestCase.php',
'ArcanistBinaryNumericScalarCasingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBinaryNumericScalarCasingXHPASTLinterRule.php',
'ArcanistBinaryNumericScalarCasingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBinaryNumericScalarCasingXHPASTLinterRuleTestCase.php',
'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBlacklistedFunctionXHPASTLinterRule.php', 'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBlacklistedFunctionXHPASTLinterRule.php',
'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase.php', 'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase.php',
'ArcanistBookmarkWorkflow' => 'workflow/ArcanistBookmarkWorkflow.php', 'ArcanistBookmarkWorkflow' => 'workflow/ArcanistBookmarkWorkflow.php',
@ -434,6 +436,8 @@ phutil_register_library_map(array(
'ArcanistBaseXHPASTLinter' => 'ArcanistFutureLinter', 'ArcanistBaseXHPASTLinter' => 'ArcanistFutureLinter',
'ArcanistBinaryExpressionSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule', 'ArcanistBinaryExpressionSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistBinaryExpressionSpacingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase', 'ArcanistBinaryExpressionSpacingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistBinaryNumericScalarCasingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistBinaryNumericScalarCasingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule', 'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase', 'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistBookmarkWorkflow' => 'ArcanistFeatureWorkflow', 'ArcanistBookmarkWorkflow' => 'ArcanistFeatureWorkflow',

View file

@ -0,0 +1,49 @@
<?php
final class ArcanistBinaryNumericScalarCasingXHPASTLinterRule
extends ArcanistXHPASTLinterRule {
const ID = 131;
public function getLintName() {
return pht('Binary Integer Casing');
}
public function getLintSeverity() {
return ArcanistLintSeverity::SEVERITY_WARNING;
}
public function process(XHPASTNode $root) {
$binaries = $this->getBinaryNumericScalars($root);
foreach ($binaries as $binary) {
$value = substr($binary->getConcreteString(), 2);
if (!preg_match('/^0b[01]+$/', $binary->getConcreteString())) {
$this->raiseLintAtNode(
$binary,
pht(
'For consistency, write binary integers with a leading `%s`.',
'0b'),
'0b'.$value);
}
}
}
private function getBinaryNumericScalars(XHPASTNode $root) {
$numeric_scalars = $root->selectDescendantsOfType('n_NUMERIC_SCALAR');
$binary_numeric_scalars = array();
foreach ($numeric_scalars as $numeric_scalar) {
$number = $numeric_scalar->getConcreteString();
if (preg_match('/^0b[01]+$/i', $number)) {
$binary_numeric_scalars[] = $numeric_scalar;
}
}
return $binary_numeric_scalars;
}
}

View file

@ -6,7 +6,7 @@ final class ArcanistHexadecimalNumericScalarCasingXHPASTLinterRule
const ID = 127; const ID = 127;
public function getLintName() { public function getLintName() {
return pht('Hexadecimal Casing'); return pht('Hexadecimal Integer Casing');
} }
public function getLintSeverity() { public function getLintSeverity() {
@ -23,8 +23,8 @@ final class ArcanistHexadecimalNumericScalarCasingXHPASTLinterRule
$this->raiseLintAtNode( $this->raiseLintAtNode(
$hexadecimal, $hexadecimal,
pht( pht(
'For consistency, write hexadecimals in uppercase '. 'For consistency, write hexadecimals integers '.
'with a leading `%s`.', 'in uppercase with a leading `%s`.',
'0x'), '0x'),
'0x'.strtoupper($value)); '0x'.strtoupper($value));
} }

View file

@ -0,0 +1,11 @@
<?php
final class ArcanistBinaryNumericScalarCasingXHPASTLinterRuleTestCase
extends ArcanistXHPASTLinterRuleTestCase {
public function testLinter() {
$this->executeTestsInDirectory(
dirname(__FILE__).'/binary-numeric-scalar-casing/');
}
}

View file

@ -0,0 +1,5 @@
<?php
0b1;
0B1;
~~~~~~~~~~
warning:3:1