1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-24 15:52: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) {
$this->lintPHP53Features($root);
} else {
$this->lintPHP53Incompatibilities($root);
}
if (version_compare($this->version, '5.4.0') < 0) {
$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) {
$indexes = $root->selectDescendantsOfType('n_INDEX_ACCESS');
foreach ($indexes as $index) {
$left = $index->getChildByIndex(0);
switch ($left->getTypeName()) {
switch ($index->getChildByIndex(0)->getTypeName()) {
case 'n_FUNCTION_CALL':
case 'n_METHOD_CALL':
$this->raiseLintAtNode(
$index->getChildByIndex(1),
self::LINT_PHP_COMPATIBILITY,
'The f()[...] syntax was not introduced until PHP 5.4, but this '.
'codebase targets an earlier version of PHP. You can rewrite '.
'this expression using idx().');
pht(
'The `%s` syntax was not introduced until PHP 5.4, but this '.
'codebase targets an earlier version of PHP. You can rewrite '.
'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;
}
}

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"}}