diff --git a/src/lint/linter/__tests__/xhpast/php54-features.lint-test b/src/lint/linter/__tests__/xhpast/php54-features.lint-test --- a/src/lint/linter/__tests__/xhpast/php54-features.lint-test +++ b/src/lint/linter/__tests__/xhpast/php54-features.lint-test @@ -6,9 +6,26 @@ // The check above should be this, see T4334. // $o->m()[0]; +final class SomeClass extends Phobject { + public function someMethod() { + return function () { + $this->someOtherMethod(); + }; + } + + public static function someStaticMethod() { + return function () { + self::someOtherMethod(); + }; + } +} + ~~~~~~~~~~ error:3:5 error:4:9 +error:9:13 +error:12:7 +error:18:7 ~~~~~~~~~~ ~~~~~~~~~~ { 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 @@ -402,6 +402,52 @@ break; } } + + $closures = $this->getAnonymousClosures($root); + foreach ($closures as $closure) { + $static_accesses = $closure + ->selectDescendantsOfType('n_CLASS_STATIC_ACCESS'); + + foreach ($static_accesses as $static_access) { + $class = $static_access->getChildByIndex(0); + + if ($class->getTypeName() != 'n_CLASS_NAME') { + continue; + } + + if (strtolower($class->getConcreteString()) != 'self') { + continue; + } + + $this->raiseLintAtNode( + $class, + pht( + 'The use of `%s` in an anonymous closure is not '. + 'available before PHP 5.4.', + 'self')); + } + + $property_accesses = $closure + ->selectDescendantsOfType('n_OBJECT_PROPERTY_ACCESS'); + foreach ($property_accesses as $property_access) { + $variable = $property_access->getChildByIndex(0); + + if ($variable->getTypeName() != 'n_VARIABLE') { + continue; + } + + if ($variable->getConcreteString() != '$this') { + continue; + } + + $this->raiseLintAtNode( + $variable, + pht( + 'The use of `%s` in an anonymous closure is not '. + 'available before PHP 5.4.', + '$this')); + } + } } private function lintPHP54Incompatibilities(XHPASTNode $root) {