1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-25 16:22:42 +01:00

Add a linter rule for curly brace array indexes

Summary: In PHP, both `$x['key']` and `$x{'key'}` can be used to access an array (see  http://stackoverflow.com/questions/8092248/php-curly-braces-in-array-notation), but the former should be preferred.

Test Plan: Added test cases.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D14603
This commit is contained in:
Joshua Spence 2015-12-09 06:56:48 +11:00
parent a6e81daad1
commit d2e7785497
6 changed files with 90 additions and 0 deletions

View file

@ -96,6 +96,8 @@ phutil_register_library_map(array(
'ArcanistCppcheckLinterTestCase' => 'lint/linter/__tests__/ArcanistCppcheckLinterTestCase.php',
'ArcanistCpplintLinter' => 'lint/linter/ArcanistCpplintLinter.php',
'ArcanistCpplintLinterTestCase' => 'lint/linter/__tests__/ArcanistCpplintLinterTestCase.php',
'ArcanistCurlyBraceArrayIndexXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistCurlyBraceArrayIndexXHPASTLinterRule.php',
'ArcanistCurlyBraceArrayIndexXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistCurlyBraceArrayIndexXHPASTLinterRuleTestCase.php',
'ArcanistDeclarationParenthesesXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistDeclarationParenthesesXHPASTLinterRule.php',
'ArcanistDeclarationParenthesesXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistDeclarationParenthesesXHPASTLinterRuleTestCase.php',
'ArcanistDefaultParametersXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistDefaultParametersXHPASTLinterRule.php',
@ -502,6 +504,8 @@ phutil_register_library_map(array(
'ArcanistCppcheckLinterTestCase' => 'ArcanistExternalLinterTestCase',
'ArcanistCpplintLinter' => 'ArcanistExternalLinter',
'ArcanistCpplintLinterTestCase' => 'ArcanistExternalLinterTestCase',
'ArcanistCurlyBraceArrayIndexXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistCurlyBraceArrayIndexXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistDeclarationParenthesesXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistDeclarationParenthesesXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistDefaultParametersXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',

View file

@ -0,0 +1,52 @@
<?php
final class ArcanistCurlyBraceArrayIndexXHPASTLinterRule
extends ArcanistXHPASTLinterRule {
const ID = 119;
public function getLintName() {
return pht('Curly Brace Array Index');
}
public function getLintSeverity() {
return ArcanistLintSeverity::SEVERITY_WARNING;
}
public function process(XHPASTNode $root) {
$index_accesses = $root->selectDescendantsOfType('n_INDEX_ACCESS');
foreach ($index_accesses as $index_access) {
$tokens = $index_access->getChildByIndex(1)->getTokens();
$left_brace = head($tokens)->getPrevToken();
while (!$left_brace->isSemantic()) {
$left_brace = $left_brace->getPrevToken();
}
$right_brace = last($tokens)->getNextToken();
while (!$right_brace->isSemantic()) {
$right_brace = $right_brace->getNextToken();
}
if ($left_brace->getValue() == '{' || $right_brace->getValue() == '}') {
$replacement = null;
foreach ($index_access->getTokens() as $token) {
if ($token === $left_brace) {
$replacement .= '[';
} else if ($token === $right_brace) {
$replacement .= ']';
} else {
$replacement .= $token->getValue();
}
}
$this->raiseLintAtNode(
$index_access,
pht('Use `%s` instead of `%s`.', "\$x['key']", "\$x{'key'}"),
$replacement);
}
}
}
}

View file

@ -0,0 +1,11 @@
<?php
final class ArcanistCurlyBraceArrayIndexXHPASTLinterRuleTestCase
extends ArcanistXHPASTLinterRuleTestCase {
public function testLinter() {
$this->executeTestsInDirectory(
dirname(__FILE__).'/curly-brace-array-index/');
}
}

View file

@ -0,0 +1,9 @@
<?php
$x['key'];
$y{'key'};
~~~~~~~~~~
warning:3:1
~~~~~~~~~~
<?php
$x['key'];
$y['key'];

View file

@ -0,0 +1,7 @@
<?php
$x[$y{'key'}];
~~~~~~~~~~
warning:2:4
~~~~~~~~~~
<?php
$x[$y['key']];

View file

@ -0,0 +1,7 @@
<?php
$x { 'key' /* comment */ };
~~~~~~~~~~
warning:2:1
~~~~~~~~~~
<?php
$x [ 'key' /* comment */ ];