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

Add a linter rule to detect variable arguments for break and continue

Summary: In PHP 5.4, the `break` and `continue` statements no longer accept variable arguments (e.g., `break 1 + foo() * $bar;`). Static arguments still work, such as break 2;. As a side effect of this change `break 0;` and `continue 0;` are no longer allowed.

Test Plan: Added some test cases.

Reviewers: epriestley, #blessed_reviewers

Reviewed By: epriestley, #blessed_reviewers

Subscribers: epriestley, Korvin

Differential Revision: https://secure.phabricator.com/D10567
This commit is contained in:
Joshua Spence 2014-09-26 08:36:29 +10:00
parent 247a4fabb8
commit 8ed1459ecd
4 changed files with 58 additions and 5 deletions

View file

@ -545,10 +545,14 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
if (version_compare($this->version, '5.3.0') < 0) { if (version_compare($this->version, '5.3.0') < 0) {
$this->lintPHP53Features($root); $this->lintPHP53Features($root);
} else {
$this->lintPHP53Incompatibilities($root);
} }
if (version_compare($this->version, '5.4.0') < 0) { if (version_compare($this->version, '5.4.0') < 0) {
$this->lintPHP54Features($root); $this->lintPHP54Features($root);
} else {
$this->lintPHP54Incompatibilities($root);
} }
} }
@ -637,19 +641,51 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
} }
} }
private function lintPHP53Incompatibilities(XHPASTNode $root) {}
private function lintPHP54Features(XHPASTNode $root) { private function lintPHP54Features(XHPASTNode $root) {
$indexes = $root->selectDescendantsOfType('n_INDEX_ACCESS'); $indexes = $root->selectDescendantsOfType('n_INDEX_ACCESS');
foreach ($indexes as $index) { foreach ($indexes as $index) {
$left = $index->getChildByIndex(0); switch ($index->getChildByIndex(0)->getTypeName()) {
switch ($left->getTypeName()) {
case 'n_FUNCTION_CALL': case 'n_FUNCTION_CALL':
case 'n_METHOD_CALL': case 'n_METHOD_CALL':
$this->raiseLintAtNode( $this->raiseLintAtNode(
$index->getChildByIndex(1), $index->getChildByIndex(1),
self::LINT_PHP_COMPATIBILITY, self::LINT_PHP_COMPATIBILITY,
'The f()[...] syntax was not introduced until PHP 5.4, but this '. pht(
'The `%s` syntax was not introduced until PHP 5.4, but this '.
'codebase targets an earlier version of PHP. You can rewrite '. 'codebase targets an earlier version of PHP. You can rewrite '.
'this expression using idx().'); 'this expression using `%s`.',
'f()[...]',
'idx()'));
break;
}
}
}
private function lintPHP54Incompatibilities(XHPASTNode $root) {
$breaks = $root->selectDescendantsOfTypes(array('n_BREAK', 'n_CONTINUE'));
foreach ($breaks as $break) {
$arg = $break->getChildByIndex(0);
switch ($arg->getTypeName()) {
case 'n_EMPTY':
break;
case 'n_NUMERIC_SCALAR':
if ($arg->getConcreteString() != '0') {
break;
}
default:
$this->raiseLintAtNode(
$break->getChildByIndex(0),
self::LINT_PHP_COMPATIBILITY,
pht(
'The `%s` and `%s` statements no longer accept '.
'variable arguments.',
'break',
'continue'));
break; break;
} }
} }

View file

@ -0,0 +1,17 @@
<?php
break;
break 0;
break 1;
break 1 + foo() * $bar;
continue;
continue 0;
continue 1;
continue 1 + foo() * $bar;
~~~~~~~~~~
error:3:7
error:5:7
error:7:10
error:9:10
~~~~~~~~~~
~~~~~~~~~~
{"config": {"xhpast.php-version": "5.4.0"}}