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

Add a linter rule for interface method bodies

Summary:
`interface` methods cannot contain a body. This construct will cause a fatal error:

```
PHP Fatal error:  Interface function X::Y() cannot contain body in /home/josh/workspace/github.com/phacility/arcanist/test.php on line 4
```

Test Plan: Added unit tests.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin

Differential Revision: https://secure.phabricator.com/D14561
This commit is contained in:
Joshua Spence 2015-11-26 07:12:00 +11:00
parent 28f5b0ddc6
commit 8183a45804
5 changed files with 60 additions and 0 deletions

View file

@ -178,6 +178,8 @@ phutil_register_library_map(array(
'ArcanistInstallCertificateWorkflow' => 'workflow/ArcanistInstallCertificateWorkflow.php',
'ArcanistInstanceOfOperatorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistInstanceOfOperatorXHPASTLinterRule.php',
'ArcanistInstanceofOperatorXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistInstanceofOperatorXHPASTLinterRuleTestCase.php',
'ArcanistInterfaceMethodBodyXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistInterfaceMethodBodyXHPASTLinterRule.php',
'ArcanistInterfaceMethodBodyXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistInterfaceMethodBodyXHPASTLinterRuleTestCase.php',
'ArcanistInvalidDefaultParameterXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistInvalidDefaultParameterXHPASTLinterRule.php',
'ArcanistInvalidDefaultParameterXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistInvalidDefaultParameterXHPASTLinterRuleTestCase.php',
'ArcanistInvalidModifiersXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistInvalidModifiersXHPASTLinterRule.php',
@ -566,6 +568,8 @@ phutil_register_library_map(array(
'ArcanistInstallCertificateWorkflow' => 'ArcanistWorkflow',
'ArcanistInstanceOfOperatorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistInstanceofOperatorXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistInterfaceMethodBodyXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistInterfaceMethodBodyXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistInvalidDefaultParameterXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistInvalidDefaultParameterXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistInvalidModifiersXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',

View file

@ -0,0 +1,33 @@
<?php
final class ArcanistInterfaceMethodBodyXHPASTLinterRule
extends ArcanistXHPASTLinterRule {
const ID = 114;
public function getLintName() {
return pht('`%s` Method Cannot Contain Body', 'interface');
}
public function process(XHPASTNode $root) {
$interfaces = $root->selectDescendantsOfType('n_INTERFACE_DECLARATION');
foreach ($interfaces as $interface) {
$methods = $interface->selectDescendantsOfType('n_METHOD_DECLARATION');
foreach ($methods as $method) {
$body = $method->getChildByIndex(5);
if ($body->getTypeName() != 'n_EMPTY') {
$this->raiseLintAtNode(
$body,
pht(
'`%s` methods cannot contain a body. This construct will '.
'cause a fatal error.',
'interface'));
}
}
}
}
}

View file

@ -0,0 +1,10 @@
<?php
final class ArcanistInterfaceMethodBodyXHPASTLinterRuleTestCase
extends ArcanistXHPASTLinterRuleTestCase {
public function testLinter() {
$this->executeTestsInDirectory(dirname(__FILE__).'/interface-method-body/');
}
}

View file

@ -0,0 +1,7 @@
<?php
interface SomeInterface {
public function someMethod() {}
}
~~~~~~~~~~
error:4:32

View file

@ -0,0 +1,6 @@
<?php
interface SomeInterface {
public function someMethod();
}
~~~~~~~~~~