diff --git a/src/lint/linter/xhpast/rules/ArcanistUnexpectedReturnValueXHPASTLinterRule.php b/src/lint/linter/xhpast/rules/ArcanistUnexpectedReturnValueXHPASTLinterRule.php index b73ea0a5..10ffda44 100644 --- a/src/lint/linter/xhpast/rules/ArcanistUnexpectedReturnValueXHPASTLinterRule.php +++ b/src/lint/linter/xhpast/rules/ArcanistUnexpectedReturnValueXHPASTLinterRule.php @@ -1,48 +1,63 @@ selectDescendantsOfType('n_METHOD_DECLARATION'); foreach ($methods as $method) { $method_name = $method ->getChildOfType(2, 'n_STRING') ->getConcreteString(); switch (strtolower($method_name)) { case '__construct': case '__destruct': $returns = $method->selectDescendantsOfType('n_RETURN'); foreach ($returns as $return) { $return_value = $return->getChildByIndex(0); if ($return_value->getTypeName() == 'n_EMPTY') { continue; } + if ($this->isInAnonymousFunction($return)) { + continue; + } + $this->raiseLintAtNode( $return, pht( 'Unexpected `%s` value in `%s` method.', 'return', $method_name)); } break; } } } + private function isInAnonymousFunction(XHPASTNode $node) { + while ($node) { + if ($node->getTypeName() == 'n_FUNCTION_DECLARATION' && + $node->getChildByIndex(2)->getTypeName() == 'n_EMPTY') { + return true; + } + + $node = $node->getParentNode(); + } + } + } diff --git a/src/lint/linter/xhpast/rules/__tests__/unexpected-return-value/closure.lint-test b/src/lint/linter/xhpast/rules/__tests__/unexpected-return-value/closure.lint-test new file mode 100644 index 00000000..65536bfe --- /dev/null +++ b/src/lint/linter/xhpast/rules/__tests__/unexpected-return-value/closure.lint-test @@ -0,0 +1,11 @@ +closure = function() { + return null; + }; + } +} +~~~~~~~~~~