Page MenuHomePhabricator

D13820.id.diff
No OneTemporary

D13820.id.diff

diff --git a/src/lint/linter/ArcanistXHPASTLinter.php b/src/lint/linter/ArcanistXHPASTLinter.php
--- a/src/lint/linter/ArcanistXHPASTLinter.php
+++ b/src/lint/linter/ArcanistXHPASTLinter.php
@@ -67,14 +67,21 @@
}
public function setLinterConfigurationValue($key, $value) {
+ $matched = false;
+
foreach ($this->rules as $rule) {
foreach ($rule->getLinterConfigurationOptions() as $k => $spec) {
if ($k == $key) {
- return $rule->setLinterConfigurationValue($key, $value);
+ $matched = true;
+ $rule->setLinterConfigurationValue($key, $value);
}
}
}
+ if ($matched) {
+ return;
+ }
+
return parent::setLinterConfigurationValue($key, $value);
}
diff --git a/src/lint/linter/__tests__/xhpast/self-member-references-php53.lint-test b/src/lint/linter/__tests__/xhpast/self-member-references-php53.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/self-member-references-php53.lint-test
@@ -0,0 +1,19 @@
+<?php
+
+final class SomeClass extends Phobject {
+ public static function someMethod() {
+ $closure = function () {
+ SomeClass::someOtherMethod();
+ };
+ $closure();
+ }
+}
+~~~~~~~~~~
+error:3:13
+~~~~~~~~~~
+~~~~~~~~~~
+{
+ "config": {
+ "xhpast.php-version": "5.3.0"
+ }
+}
diff --git a/src/lint/linter/__tests__/xhpast/self-member-references-php54.lint-test b/src/lint/linter/__tests__/xhpast/self-member-references-php54.lint-test
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/__tests__/xhpast/self-member-references-php54.lint-test
@@ -0,0 +1,30 @@
+<?php
+
+final class SomeClass extends Phobject {
+ public static function someMethod() {
+ $closure = function () {
+ SomeClass::someOtherMethod();
+ };
+ $closure();
+ }
+}
+~~~~~~~~~~
+error:3:13
+advice:6:7
+~~~~~~~~~~
+<?php
+
+final class SomeClass extends Phobject {
+ public static function someMethod() {
+ $closure = function () {
+ self::someOtherMethod();
+ };
+ $closure();
+ }
+}
+~~~~~~~~~~
+{
+ "config": {
+ "xhpast.php-version": "5.4.0"
+ }
+}
diff --git a/src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php b/src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php
--- a/src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php
+++ b/src/lint/linter/xhpast/ArcanistXHPASTLinterRule.php
@@ -5,6 +5,9 @@
private $linter = null;
private $lintID = null;
+ protected $version;
+ protected $windowsVersion;
+
final public static function loadAllRules() {
return id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
@@ -47,10 +50,29 @@
}
public function getLinterConfigurationOptions() {
- return array();
+ return array(
+ 'xhpast.php-version' => array(
+ 'type' => 'optional string',
+ 'help' => pht('PHP version to target.'),
+ ),
+ 'xhpast.php-version.windows' => array(
+ 'type' => 'optional string',
+ 'help' => pht('PHP version to target on Windows.'),
+ ),
+ );
}
- public function setLinterConfigurationValue($key, $value) {}
+ public function setLinterConfigurationValue($key, $value) {
+ switch ($key) {
+ case 'xhpast.php-version':
+ $this->version = $value;
+ return;
+
+ case 'xhpast.php-version.windows':
+ $this->windowsVersion = $value;
+ return;
+ }
+ }
abstract public function process(XHPASTNode $root);
@@ -139,6 +161,28 @@
/* -( Utility )------------------------------------------------------------ */
/**
+ * Retrieve all anonymous closure(s).
+ *
+ * Returns all descendant nodes which represent an anonymous function
+ * declaration.
+ *
+ * @param XHPASTNode Root node.
+ * @return AASTNodeList
+ */
+ protected function getAnonymousClosures(XHPASTNode $root) {
+ $func_decls = $root->selectDescendantsOfType('n_FUNCTION_DECLARATION');
+ $nodes = array();
+
+ foreach ($func_decls as $func_decl) {
+ if ($func_decl->getChildByIndex(2)->getTypeName() == 'n_EMPTY') {
+ $nodes[] = $func_decl;
+ }
+ }
+
+ return AASTNodeList::newFromTreeAndNodes($root->getTree(), $nodes);
+ }
+
+ /**
* Retrieve all calls to some specified function(s).
*
* Returns all descendant nodes which represent a function call to one of the
diff --git a/src/lint/linter/xhpast/rules/ArcanistPHPCompatibilityXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistPHPCompatibilityXHPASTLinterRule.php
--- a/src/lint/linter/xhpast/rules/ArcanistPHPCompatibilityXHPASTLinterRule.php
+++ b/src/lint/linter/xhpast/rules/ArcanistPHPCompatibilityXHPASTLinterRule.php
@@ -5,41 +5,10 @@
const ID = 45;
- private $version;
- private $windowsVersion;
-
public function getLintName() {
return pht('PHP Compatibility');
}
- public function getLinterConfigurationOptions() {
- return parent::getLinterConfigurationOptions() + array(
- 'xhpast.php-version' => array(
- 'type' => 'optional string',
- 'help' => pht('PHP version to target.'),
- ),
- 'xhpast.php-version.windows' => array(
- 'type' => 'optional string',
- 'help' => pht('PHP version to target on Windows.'),
- ),
- );
- }
-
- public function setLinterConfigurationValue($key, $value) {
- switch ($key) {
- case 'xhpast.php-version':
- $this->version = $value;
- return;
-
- case 'xhpast.php-version.windows':
- $this->windowsVersion = $value;
- return;
-
- default:
- return parent::setLinterConfigurationValue($key, $value);
- }
- }
-
public function process(XHPASTNode $root) {
static $compat_info;
diff --git a/src/lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php
--- a/src/lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php
+++ b/src/lint/linter/xhpast/rules/ArcanistSelfMemberReferenceXHPASTLinterRule.php
@@ -23,6 +23,7 @@
$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
@@ -35,12 +36,23 @@
$class_ref_name = $class_ref->getConcreteString();
if (strtolower($class_name) == strtolower($class_ref_name)) {
- $this->raiseLintAtNode(
- $class_ref,
- pht(
- 'Use `%s` for local static member references.',
- 'self::'),
- 'self');
+ $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` for local static member references.',
+ 'self::'),
+ 'self');
+ }
}
static $self_refs = array(

File Metadata

Mime Type
text/plain
Expires
Sat, Mar 15, 5:42 AM (1 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7382497
Default Alt Text
D13820.id.diff (7 KB)

Event Timeline