1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-12-23 14:00:55 +01:00

Add a lint rule for spaces before the closing paren of a function/method call

Summary: This is technically documented, but not currently enforced and we aren't consistent about it in the codebase.

Test Plan: See D5002.

Reviewers: chad, vrana

Reviewed By: chad

CC: aran

Differential Revision: https://secure.phabricator.com/D5003
This commit is contained in:
epriestley 2013-02-19 13:50:13 -08:00
parent eda3fc2ab4
commit 157184e01d
3 changed files with 167 additions and 2 deletions

View file

@ -43,7 +43,8 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
const LINT_COMMENT_SPACING = 34; const LINT_COMMENT_SPACING = 34;
const LINT_PHP_54_FEATURES = 35; const LINT_PHP_54_FEATURES = 35;
const LINT_SLOWNESS = 36; const LINT_SLOWNESS = 36;
const LINT_CLOSING_CALL_PAREN = 37;
const LINT_CLOSING_DECL_PAREN = 38;
public function getLintNameMap() { public function getLintNameMap() {
return array( return array(
@ -81,6 +82,8 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
self::LINT_REUSED_AS_ITERATOR => 'Variable Reused As Iterator', self::LINT_REUSED_AS_ITERATOR => 'Variable Reused As Iterator',
self::LINT_COMMENT_SPACING => 'Comment Spaces', self::LINT_COMMENT_SPACING => 'Comment Spaces',
self::LINT_SLOWNESS => 'Slow Construct', self::LINT_SLOWNESS => 'Slow Construct',
self::LINT_CLOSING_CALL_PAREN => 'Call Formatting',
self::LINT_CLOSING_DECL_PAREN => 'Declaration Formatting',
); );
} }
@ -106,6 +109,8 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
self::LINT_IMPLICIT_FALLTHROUGH => $warning, self::LINT_IMPLICIT_FALLTHROUGH => $warning,
self::LINT_SLOWNESS => $warning, self::LINT_SLOWNESS => $warning,
self::LINT_COMMENT_SPACING => $advice, self::LINT_COMMENT_SPACING => $advice,
self::LINT_CLOSING_CALL_PAREN => $warning,
self::LINT_CLOSING_DECL_PAREN => $warning,
// This is disabled by default because it implies a very strict policy // This is disabled by default because it implies a very strict policy
// which isn't necessary in the general case. // which isn't necessary in the general case.
@ -160,7 +165,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
} }
public function getCacheVersion() { public function getCacheVersion() {
$version = '2'; $version = '3';
$path = xhpast_get_binary_path(); $path = xhpast_get_binary_path();
if (Filesystem::pathExists($path)) { if (Filesystem::pathExists($path)) {
$version .= '-'.md5_file($path); $version .= '-'.md5_file($path);
@ -215,6 +220,8 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
'lintPlusOperatorOnStrings' => self::LINT_PLUS_OPERATOR_ON_STRINGS, 'lintPlusOperatorOnStrings' => self::LINT_PLUS_OPERATOR_ON_STRINGS,
'lintDuplicateKeysInArray' => self::LINT_DUPLICATE_KEYS_IN_ARRAY, 'lintDuplicateKeysInArray' => self::LINT_DUPLICATE_KEYS_IN_ARRAY,
'lintRaggedClasstreeEdges' => self::LINT_RAGGED_CLASSTREE_EDGE, 'lintRaggedClasstreeEdges' => self::LINT_RAGGED_CLASSTREE_EDGE,
'lintClosingCallParen' => self::LINT_CLOSING_CALL_PAREN,
'lintClosingDeclarationParen' => self::LINT_CLOSING_DECL_PAREN,
); );
foreach ($method_codes as $method => $codes) { foreach ($method_codes as $method => $codes) {
@ -2017,6 +2024,64 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
} }
} }
private function lintClosingCallParen($root) {
$calls = $root->selectDescendantsOfType('n_FUNCTION_CALL');
$calls = $calls->add($root->selectDescendantsOfType('n_METHOD_CALL'));
foreach ($calls as $call) {
// If the last parameter of a call is a HEREDOC, don't apply this rule.
$params = $call
->getChildOfType(1, 'n_CALL_PARAMETER_LIST')
->getChildren();
if ($params) {
$last_param = last($params);
if ($last_param->getTypeName() == 'n_HEREDOC') {
continue;
}
}
$tokens = $call->getTokens();
$last = array_pop($tokens);
$trailing = $last->getNonsemanticTokensBefore();
$trailing_text = implode('', mpull($trailing, 'getValue'));
if (preg_match('/^\s+$/', $trailing_text)) {
$this->raiseLintAtOffset(
$last->getOffset() - strlen($trailing_text),
self::LINT_CLOSING_CALL_PAREN,
'Convention: no spaces before closing parenthesis in calls.',
$trailing_text,
'');
}
}
}
private function lintClosingDeclarationParen($root) {
$decs = $root->selectDescendantsOfType('n_FUNCTION_DECLARATION');
$decs = $decs->add($root->selectDescendantsOfType('n_METHOD_DECLARATION'));
foreach ($decs as $dec) {
$params = $dec->getChildOfType(3, 'n_DECLARATION_PARAMETER_LIST');
$tokens = $params->getTokens();
$last = array_pop($tokens);
$trailing = $last->getNonsemanticTokensBefore();
$trailing_text = implode('', mpull($trailing, 'getValue'));
if (preg_match('/^\s+$/', $trailing_text)) {
$this->raiseLintAtOffset(
$last->getOffset() - strlen($trailing_text),
self::LINT_CLOSING_DECL_PAREN,
'Convention: no spaces before closing parenthesis in function and '.
'method declarations.',
$trailing_text,
'');
}
}
}
public function getSuperGlobalNames() { public function getSuperGlobalNames() {
return array( return array(
'$GLOBALS', '$GLOBALS',

View file

@ -0,0 +1,39 @@
<?php
f(1);
f(1 );
f(1 /* oh */ );
f(
1);
f(
1
);
array(
1,
);
f(<<<EODOC
The duck says, "Quack!"
The robot says, "Beep beep boop boop!"
EODOC
);
~~~~~~~~~~
warning:4:4
warning:9:4
~~~~~~~~~~
<?php
f(1);
f(1);
f(1 /* oh */ );
f(
1);
f(
1);
array(
1,
);
f(<<<EODOC
The duck says, "Quack!"
The robot says, "Beep beep boop boop!"
EODOC
);

View file

@ -0,0 +1,61 @@
<?php
function f($x) {}
function g($x ) {}
function &h($x) {}
function &i($x ) {}
final class X {
function a($x) { }
function b($x ) { }
final public static function &c($x) { }
final public static function &d($x ) { }
abstract private function e($x);
abstract private function f($x );
}
f(function($x) { });
f(function($x ) { });
f(function($x ) use ($z) { });
~~~~~~~~~~
warning:4:14
warning:7:15
error:9:13
warning:12:16
warning:15:37
warning:18:33
disabled:22:3
disabled:23:3
warning:23:14
disabled:24:3
warning:24:14
~~~~~~~~~~
<?php
function f($x) {}
function g($x) {}
function &h($x) {}
function &i($x) {}
final class X {
function a($x) { }
function b($x) { }
final public static function &c($x) { }
final public static function &d($x) { }
abstract private function e($x);
abstract private function f($x);
}
f(function($x) { });
f(function($x) { });
f(function($x) use ($z) { });