Page MenuHomePhabricator

D14443.diff
No OneTemporary

D14443.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -248,6 +248,8 @@
'ArcanistPHPOpenTagXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPHPOpenTagXHPASTLinterRuleTestCase.php',
'ArcanistPHPShortTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPShortTagXHPASTLinterRule.php',
'ArcanistPHPShortTagXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPHPShortTagXHPASTLinterRuleTestCase.php',
+ 'ArcanistParentMemberReferenceXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParentMemberReferenceXHPASTLinterRule.php',
+ 'ArcanistParentMemberReferenceXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistParentMemberReferenceXHPASTLinterRuleTestCase.php',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParenthesesSpacingXHPASTLinterRule.php',
'ArcanistParenthesesSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistParenthesesSpacingXHPASTLinterRuleTestCase.php',
'ArcanistParseStrUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php',
@@ -618,6 +620,8 @@
'ArcanistPHPOpenTagXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistPHPShortTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPHPShortTagXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
+ 'ArcanistParentMemberReferenceXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistParentMemberReferenceXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistParenthesesSpacingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistParseStrUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
diff --git a/src/lint/linter/xhpast/rules/ArcanistParentMemberReferenceXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistParentMemberReferenceXHPASTLinterRule.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/ArcanistParentMemberReferenceXHPASTLinterRule.php
@@ -0,0 +1,71 @@
+<?php
+
+final class ArcanistParentMemberReferenceXHPASTLinterRule
+ extends ArcanistXHPASTLinterRule {
+
+ const ID = 83;
+
+ public function getLintName() {
+ return pht('Parent Member Reference');
+ }
+
+ public function getLintSeverity() {
+ return ArcanistLintSeverity::SEVERITY_WARNING;
+ }
+
+ public function process(XHPASTNode $root) {
+ $class_declarations = $root->selectDescendantsOfType('n_CLASS_DECLARATION');
+
+ foreach ($class_declarations as $class_declaration) {
+ $extends_list = $class_declaration
+ ->getChildByIndex(2);
+ $parent_class = null;
+
+ if ($extends_list->getTypeName() == 'n_EXTENDS_LIST') {
+ $parent_class = $extends_list
+ ->getChildOfType(0, 'n_CLASS_NAME')
+ ->getConcreteString();
+ }
+
+ if (!$parent_class) {
+ continue;
+ }
+
+ $class_static_accesses = $class_declaration
+ ->selectDescendantsOfType('n_CLASS_STATIC_ACCESS');
+ $closures = $this->getAnonymousClosures($class_declaration);
+
+ foreach ($class_static_accesses as $class_static_access) {
+ $double_colons = $class_static_access
+ ->selectTokensOfType('T_PAAMAYIM_NEKUDOTAYIM');
+ $class_ref = $class_static_access->getChildByIndex(0);
+
+ if ($class_ref->getTypeName() != 'n_CLASS_NAME') {
+ continue;
+ }
+ $class_ref_name = $class_ref->getConcreteString();
+
+ if (strtolower($parent_class) == strtolower($class_ref_name)) {
+ $in_closure = false;
+
+ foreach ($closures as $closure) {
+ if ($class_ref->isDescendantOf($closure)) {
+ $in_closure = true;
+ break;
+ }
+ }
+
+ if (version_compare($this->version, '5.4.0', '>=') || !$in_closure) {
+ $this->raiseLintAtNode(
+ $class_ref,
+ pht(
+ 'Use `%s` to call parent method.',
+ 'parent::'),
+ 'parent');
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/ArcanistParentMemberReferenceXHPASTLinterRuleTestCase.php b/src/lint/linter/xhpast/rules/__tests__/ArcanistParentMemberReferenceXHPASTLinterRuleTestCase.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/ArcanistParentMemberReferenceXHPASTLinterRuleTestCase.php
@@ -0,0 +1,11 @@
+<?php
+
+final class ArcanistParentMemberReferenceXHPASTLinterRuleTestCase
+ extends ArcanistXHPASTLinterRuleTestCase {
+
+ public function testLinter() {
+ $this->executeTestsInDirectory(
+ dirname(__FILE__).'/parent-member-references/');
+ }
+
+}
diff --git a/src/lint/linter/xhpast/rules/__tests__/parent-member-references/not-parent.lint-test b/src/lint/linter/xhpast/rules/__tests__/parent-member-references/not-parent.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/parent-member-references/not-parent.lint-test
@@ -0,0 +1,7 @@
+<?php
+class Foobar {
+ public function someMethod() {
+ Bar::someOtherMethod();
+ }
+}
+~~~~~~~~~~
diff --git a/src/lint/linter/xhpast/rules/__tests__/parent-member-references/parent.lint-test b/src/lint/linter/xhpast/rules/__tests__/parent-member-references/parent.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/xhpast/rules/__tests__/parent-member-references/parent.lint-test
@@ -0,0 +1,15 @@
+<?php
+class Foo extends Bar {
+ public function someMethod() {
+ Bar::someOtherMethod();
+ }
+}
+~~~~~~~~~~
+warning:4:5
+~~~~~~~~~~
+<?php
+class Foo extends Bar {
+ public function someMethod() {
+ parent::someOtherMethod();
+ }
+}

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 19, 5:17 PM (3 d, 2 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7706076
Default Alt Text
D14443.diff (5 KB)

Event Timeline