mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-26 00:32:41 +01:00
Add a linter rule for unnecessary use of the final
modifier
Summary: Ref T7409. This was based on rhttps://github.com/squizlabs/PHP_CodeSniffer/blob/master/CodeSniffer/Standards/Generic/Sniffs/CodeAnalysis/UnnecessaryFinalModifierSniff.php. Test Plan: Added unit tests. Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin, epriestley Maniphest Tasks: T7409 Differential Revision: https://secure.phabricator.com/D12135
This commit is contained in:
parent
8530cfcec1
commit
e79032fec2
3 changed files with 178 additions and 129 deletions
|
@ -54,6 +54,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
const LINT_IMPLICIT_VISIBILITY = 52;
|
const LINT_IMPLICIT_VISIBILITY = 52;
|
||||||
const LINT_CALL_TIME_PASS_BY_REF = 53;
|
const LINT_CALL_TIME_PASS_BY_REF = 53;
|
||||||
const LINT_FORMATTED_STRING = 54;
|
const LINT_FORMATTED_STRING = 54;
|
||||||
|
const LINT_UNNECESSARY_FINAL_MODIFIER = 55;
|
||||||
|
|
||||||
private $blacklistedFunctions = array();
|
private $blacklistedFunctions = array();
|
||||||
private $naminghook;
|
private $naminghook;
|
||||||
|
@ -121,6 +122,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
self::LINT_IMPLICIT_VISIBILITY => 'Implicit Method Visibility',
|
self::LINT_IMPLICIT_VISIBILITY => 'Implicit Method Visibility',
|
||||||
self::LINT_CALL_TIME_PASS_BY_REF => 'Call-Time Pass-By-Reference',
|
self::LINT_CALL_TIME_PASS_BY_REF => 'Call-Time Pass-By-Reference',
|
||||||
self::LINT_FORMATTED_STRING => 'Formatted String',
|
self::LINT_FORMATTED_STRING => 'Formatted String',
|
||||||
|
self::LINT_UNNECESSARY_FINAL_MODIFIER => 'Unnecessary Final Modifier',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,6 +165,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
self::LINT_ARRAY_SEPARATOR => $advice,
|
self::LINT_ARRAY_SEPARATOR => $advice,
|
||||||
self::LINT_CONSTRUCTOR_PARENTHESES => $advice,
|
self::LINT_CONSTRUCTOR_PARENTHESES => $advice,
|
||||||
self::LINT_IMPLICIT_VISIBILITY => $advice,
|
self::LINT_IMPLICIT_VISIBILITY => $advice,
|
||||||
|
self::LINT_UNNECESSARY_FINAL_MODIFIER => $advice,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +233,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
|
|
||||||
public function getVersion() {
|
public function getVersion() {
|
||||||
// The version number should be incremented whenever a new rule is added.
|
// The version number should be incremented whenever a new rule is added.
|
||||||
return '16';
|
return '17';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function resolveFuture($path, Future $future) {
|
protected function resolveFuture($path, Future $future) {
|
||||||
|
@ -308,6 +311,7 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
'lintPropertyModifier' => self::LINT_IMPLICIT_VISIBILITY,
|
'lintPropertyModifier' => self::LINT_IMPLICIT_VISIBILITY,
|
||||||
'lintCallTimePassByReference' => self::LINT_CALL_TIME_PASS_BY_REF,
|
'lintCallTimePassByReference' => self::LINT_CALL_TIME_PASS_BY_REF,
|
||||||
'lintFormattedString' => self::LINT_FORMATTED_STRING,
|
'lintFormattedString' => self::LINT_FORMATTED_STRING,
|
||||||
|
'lintUnnecessaryFinalModifier' => self::LINT_UNNECESSARY_FINAL_MODIFIER,
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($method_codes as $method => $codes) {
|
foreach ($method_codes as $method => $codes) {
|
||||||
|
@ -3188,6 +3192,43 @@ final class ArcanistXHPASTLinter extends ArcanistBaseXHPASTLinter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function lintUnnecessaryFinalModifier(XHPASTNode $root) {
|
||||||
|
$classes = $root->selectDescendantsOfType('n_CLASS_DECLARATION');
|
||||||
|
|
||||||
|
foreach ($classes as $class) {
|
||||||
|
$attributes = $class->getChildOfType(0, 'n_CLASS_ATTRIBUTES');
|
||||||
|
$is_final = false;
|
||||||
|
|
||||||
|
foreach ($attributes->getChildren() as $attribute) {
|
||||||
|
if ($attribute->getConcreteString() == 'final') {
|
||||||
|
$is_final = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$is_final) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$methods = $class->selectDescendantsOfType('n_METHOD_DECLARATION');
|
||||||
|
foreach ($methods as $method) {
|
||||||
|
$attributes = $method->getChildOfType(0, 'n_METHOD_MODIFIER_LIST');
|
||||||
|
|
||||||
|
foreach ($attributes->getChildren() as $attribute) {
|
||||||
|
if ($attribute->getConcreteString() == 'final') {
|
||||||
|
$this->raiseLintAtNode(
|
||||||
|
$attribute,
|
||||||
|
self::LINT_UNNECESSARY_FINAL_MODIFIER,
|
||||||
|
pht(
|
||||||
|
'Unnecessary %s modifier in %s class.',
|
||||||
|
'final',
|
||||||
|
'final'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function getSuperGlobalNames() {
|
public function getSuperGlobalNames() {
|
||||||
return array(
|
return array(
|
||||||
'$GLOBALS',
|
'$GLOBALS',
|
||||||
|
|
|
@ -11,8 +11,8 @@ final class X {
|
||||||
public function a($x) {}
|
public function a($x) {}
|
||||||
public function b($x ) {}
|
public function b($x ) {}
|
||||||
|
|
||||||
final public static function &c($x) {}
|
public static function &c($x) {}
|
||||||
final public static function &d($x ) {}
|
public static function &d($x ) {}
|
||||||
|
|
||||||
abstract private function e($x);
|
abstract private function e($x);
|
||||||
abstract private function f($x );
|
abstract private function f($x );
|
||||||
|
@ -27,7 +27,7 @@ warning:4:14
|
||||||
warning:7:15
|
warning:7:15
|
||||||
error:9:13
|
error:9:13
|
||||||
warning:12:23
|
warning:12:23
|
||||||
warning:15:37
|
warning:15:31
|
||||||
warning:18:33
|
warning:18:33
|
||||||
warning:23:14
|
warning:23:14
|
||||||
warning:24:14
|
warning:24:14
|
||||||
|
@ -45,8 +45,8 @@ final class X {
|
||||||
public function a($x) {}
|
public function a($x) {}
|
||||||
public function b($x) {}
|
public function b($x) {}
|
||||||
|
|
||||||
final public static function &c($x) {}
|
public static function &c($x) {}
|
||||||
final public static function &d($x) {}
|
public static function &d($x) {}
|
||||||
|
|
||||||
abstract private function e($x);
|
abstract private function e($x);
|
||||||
abstract private function f($x);
|
abstract private function f($x);
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
final class Foo {
|
||||||
|
public function bar() {}
|
||||||
|
public final function baz() {}
|
||||||
|
}
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:2:13 XHP19
|
||||||
|
advice:4:10
|
Loading…
Reference in a new issue