Page MenuHomePhabricator

D14443.id34911.diff
No OneTemporary

D14443.id34911.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
@@ -190,6 +190,7 @@
'ArcanistPHPEchoTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPEchoTagXHPASTLinterRule.php',
'ArcanistPHPOpenTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPOpenTagXHPASTLinterRule.php',
'ArcanistPHPShortTagXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPHPShortTagXHPASTLinterRule.php',
+ 'ArcanistParentMemberReferenceXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParentMemberReferenceXHPASTLinterRule.php',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParenthesesSpacingXHPASTLinterRule.php',
'ArcanistParseStrUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php',
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
@@ -479,6 +480,7 @@
'ArcanistPHPEchoTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPHPOpenTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPHPShortTagXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
+ 'ArcanistParentMemberReferenceXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistParenthesesSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistParseStrUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPasteWorkflow' => 'ArcanistWorkflow',
diff --git a/src/lint/linter/__tests__/xhpast/parent-member-references.lint-test b/src/lint/linter/__tests__/xhpast/parent-member-references.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/parent-member-references.lint-test
@@ -0,0 +1,29 @@
+<?php
+
+class Foo extends Bar {
+ public function someMethod() {
+ Bar::someOtherMethod();
+ }
+}
+
+class Foobar {
+ public function someMethod() {
+ Bar::someOtherMethod();
+ }
+}
+~~~~~~~~~~
+warning:5:5
+~~~~~~~~~~
+<?php
+
+class Foo extends Bar {
+ public function someMethod() {
+ parent::someOtherMethod();
+ }
+}
+
+class Foobar {
+ public function someMethod() {
+ Bar::someOtherMethod();
+ }
+}
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');
+ }
+ }
+ }
+ }
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Tue, Mar 25, 12:55 AM (3 d, 20 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7718809
Default Alt Text
D14443.id34911.diff (4 KB)

Event Timeline