private function isInAnonymousFunction(XHPASTNode $node)
 {
     while ($node) {
         if ($node->getTypeName() == 'n_FUNCTION_DECLARATION' && $node->getChildByIndex(2)->getTypeName() == 'n_EMPTY') {
             return true;
         }
         $node = $node->getParentNode();
     }
 }
 /**
  * Get class/method modifiers.
  *
  * @param  XHPASTNode         A node of type `n_CLASS_DECLARATION` or
  *                            `n_METHOD_DECLARATION`.
  * @return map<string, bool>  Class/method modifiers.
  */
 protected final function getModifiers(XHPASTNode $node)
 {
     $modifier_list = $node->getChildByIndex(0);
     switch ($modifier_list->getTypeName()) {
         case 'n_CLASS_ATTRIBUTES':
         case 'n_CLASS_MEMBER_MODIFIER_LIST':
         case 'n_METHOD_MODIFIER_LIST':
             break;
         default:
             return array();
     }
     $modifiers = array();
     foreach ($modifier_list->selectDescendantsOfType('n_STRING') as $modifier) {
         $modifiers[strtolower($modifier->getConcreteString())] = true;
     }
     return $modifiers;
 }
Esempio n. 3
0
/**
 * Parses meaning from calls to phutil_require_module() in __init__.php files.
 *
 * @group module
 */
function analyze_phutil_require_module(XHPASTNode $call, PhutilModuleRequirements $requirements, $create_dependency)
{
    $name = $call->getChildByIndex(0);
    $params = $call->getChildByIndex(1)->getChildren();
    if (count($params) !== 2) {
        $requirements->addLint($call, $call->getConcreteString(), ArcanistPhutilModuleLinter::LINT_ANALYZER_SIGNATURE, "Call to phutil_require_module() must have exactly two arguments.");
        return;
    }
    $module_param = array_pop($params);
    $library_param = array_pop($params);
    $library_value = $library_param->getStringLiteralValue();
    if ($library_value === null) {
        $requirements->addLint($library_param, $library_param->getConcreteString(), ArcanistPhutilModuleLinter::LINT_ANALYZER_SIGNATURE, "phutil_require_module() parameters must be string literals.");
        return;
    }
    $module_value = $module_param->getStringLiteralValue();
    if ($module_value === null) {
        $requirements->addLint($module_param, $module_param->getConcreteString(), ArcanistPhutilModuleLinter::LINT_ANALYZER_SIGNATURE, "phutil_require_module() parameters must be string literals.");
        return;
    }
    if ($create_dependency) {
        $requirements->addModuleDependency($name, $library_value . ':' . $module_value);
    }
}
 private function parseReturnType(DivinerAtom $atom, XHPASTNode $decl)
 {
     $return_spec = array();
     $metadata = $atom->getDocblockMeta();
     $return = idx($metadata, 'return');
     $type = null;
     $docs = null;
     if (!$return) {
         $return = idx($metadata, 'returns');
         if ($return) {
             $atom->addWarning(pht('Documentation uses `%s`, but should use `%s`.', '@returns', '@return'));
         }
     }
     $return = (array) $return;
     if (count($return) > 1) {
         $atom->addWarning(pht('Documentation specifies `%s` multiple times.', '@return'));
     }
     $return = head($return);
     if ($atom->getName() == '__construct' && $atom->getType() == 'method') {
         $return_spec = array('doctype' => 'this', 'docs' => '//Implicit.//');
         if ($return) {
             $atom->addWarning(pht('Method `%s` has explicitly documented `%s`. The `%s` method ' . 'always returns `%s`. Diviner documents this implicitly.', '__construct()', '@return', '__construct()', '$this'));
         }
     } else {
         if ($return) {
             $split = preg_split('/(?<!,)\\s+/', trim($return), 2);
             if (!empty($split[0])) {
                 $type = $split[0];
             }
             if ($decl->getChildByIndex(1)->getTypeName() == 'n_REFERENCE') {
                 $type = $type . ' &';
             }
             if (!empty($split[1])) {
                 $docs = $split[1];
             }
             $return_spec = array('doctype' => $type, 'docs' => $docs);
         } else {
             $return_spec = array('type' => 'wild');
         }
     }
     $atom->setProperty('return', $return_spec);
 }
Esempio n. 5
0
 private function parseReturnType(DivinerAtom $atom, XHPASTNode $decl)
 {
     $return_spec = array();
     $metadata = $atom->getDocblockMeta();
     $return = idx($metadata, 'return');
     if (!$return) {
         $return = idx($metadata, 'returns');
         if ($return) {
             $atom->addWarning(pht('Documentation uses `@returns`, but should use `@return`.'));
         }
     }
     if ($atom->getName() == '__construct' && $atom->getType() == 'method') {
         $return_spec = array('doctype' => 'this', 'docs' => '//Implicit.//');
         if ($return) {
             $atom->addWarning('Method __construct() has explicitly documented @return. The ' . '__construct() method always returns $this. Diviner documents ' . 'this implicitly.');
         }
     } else {
         if ($return) {
             $split = preg_split('/\\s+/', trim($return), $limit = 2);
             if (!empty($split[0])) {
                 $type = $split[0];
             }
             if ($decl->getChildByIndex(1)->getTypeName() == 'n_REFERENCE') {
                 $type = $type . ' &';
             }
             $docs = null;
             if (!empty($split[1])) {
                 $docs = $split[1];
             }
             $return_spec = array('doctype' => $type, 'docs' => $docs);
         } else {
             $return_spec = array('type' => 'wild');
         }
     }
     $atom->setProperty('return', $return_spec);
 }