diff --git a/src/applications/diviner/atomizer/DivinerAtomizer.php b/src/applications/diviner/atomizer/DivinerAtomizer.php index 5ee949ad86..700399e256 100644 --- a/src/applications/diviner/atomizer/DivinerAtomizer.php +++ b/src/applications/diviner/atomizer/DivinerAtomizer.php @@ -10,8 +10,8 @@ abstract class DivinerAtomizer { private $atomContext; /** - * If you make a significant change to an atomizer, you can bump this - * version to drop all the old atom caches. + * If you make a significant change to an atomizer, you can bump this version + * to drop all the old atom caches. */ public static function getAtomizerVersion() { return 1; @@ -22,7 +22,7 @@ abstract class DivinerAtomizer { $this->atomContext = $context; $atoms = $this->executeAtomize($file_name, $file_data); - // Promote the "@group" special to a property. If there's no "@group" on + // Promote the `@group` special to a property. If there's no `@group` on // an atom but the file it's in matches a group pattern, associate it with // the right group. foreach ($atoms as $atom) { diff --git a/src/applications/diviner/atomizer/DivinerPHPAtomizer.php b/src/applications/diviner/atomizer/DivinerPHPAtomizer.php index 948baa4f2d..d6ddc16c86 100644 --- a/src/applications/diviner/atomizer/DivinerPHPAtomizer.php +++ b/src/applications/diviner/atomizer/DivinerPHPAtomizer.php @@ -6,7 +6,6 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { return parent::newAtom($type)->setLanguage('php'); } - protected function executeAtomize($file_name, $file_data) { $future = xhpast_get_parser_future($file_data); $tree = XHPASTTree::newFromDataAndResolvedExecFuture( @@ -14,12 +13,10 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { $future->resolve()); $atoms = array(); - $root = $tree->getRootNode(); $func_decl = $root->selectDescendantsOfType('n_FUNCTION_DECLARATION'); foreach ($func_decl as $func) { - $name = $func->getChildByIndex(2); // Don't atomize closures @@ -33,7 +30,6 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { ->setFile($file_name); $this->findAtomDocblock($atom, $func); - $this->parseParams($atom, $func); $this->parseReturnType($atom, $func); @@ -46,6 +42,7 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { ); foreach ($class_types as $atom_type => $node_type) { $class_decls = $root->selectDescendantsOfType($node_type); + foreach ($class_decls as $class) { $name = $class->getChildByIndex(1, 'n_CLASS_NAME'); @@ -54,13 +51,13 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { ->setFile($file_name) ->setLine($class->getLineNumber()); - // This parses "final" and "abstract". + // This parses `final` and `abstract`. $attributes = $class->getChildByIndex(0, 'n_CLASS_ATTRIBUTES'); foreach ($attributes->selectDescendantsOfType('n_STRING') as $attr) { $atom->setProperty($attr->getConcreteString(), true); } - // If this exists, it is n_EXTENDS_LIST. + // If this exists, it is `n_EXTENDS_LIST`. $extends = $class->getChildByIndex(2); $extends_class = $extends->selectDescendantsOfType('n_CLASS_NAME'); foreach ($extends_class as $parent_class) { @@ -70,7 +67,7 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { $parent_class->getConcreteString())); } - // If this exists, it is n_IMPLEMENTS_LIST. + // If this exists, it is `n_IMPLEMENTS_LIST`. $implements = $class->getChildByIndex(3); $iface_names = $implements->selectDescendantsOfType('n_CLASS_NAME'); foreach ($iface_names as $iface_name) { @@ -193,7 +190,6 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { $atom->setProperty('parameters', $param_spec); } - private function findAtomDocblock(DivinerAtom $atom, XHPASTNode $node) { $token = $node->getDocblockToken(); if ($token) { @@ -218,11 +214,12 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { pht( 'Atom "%s" is preceded by a comment containing "@%s", but the '. 'comment is not a documentation comment. Documentation '. - 'comments must begin with "/**", followed by a newline. Did '. + 'comments must begin with "%s", followed by a newline. Did '. 'you mean to use a documentation comment? (As the comment is '. 'not a documentation comment, it will be ignored.)', $atom->getName(), - $matches[1])); + $matches[1], + '/**')); } } } @@ -234,7 +231,7 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { protected function parseParamDoc(DivinerAtom $atom, $doc, $name) { $dict = array(); - $split = preg_split('/\s+/', trim($doc), $limit = 2); + $split = preg_split('/\s+/', trim($doc), 2); if (!empty($split[0])) { $dict['doctype'] = $split[0]; } @@ -242,7 +239,7 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { if (!empty($split[1])) { $docs = $split[1]; - // If the parameter is documented like "@param int $num Blah blah ..", + // If the parameter is documented like `@param int $num Blah blah ..`, // get rid of the `$num` part (which Diviner considers optional). If it // is present and different from the declared name, raise a warning. $matches = null; @@ -276,7 +273,10 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { $return = idx($metadata, 'returns'); if ($return) { $atom->addWarning( - pht('Documentation uses `@returns`, but should use `@return`.')); + pht( + 'Documentation uses `%s`, but should use `%s`.', + '@returns', + '@return')); } } @@ -288,12 +288,16 @@ final class DivinerPHPAtomizer extends DivinerAtomizer { if ($return) { $atom->addWarning( - 'Method __construct() has explicitly documented @return. The '. - '__construct() method always returns $this. Diviner documents '. - 'this implicitly.'); + 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('/(?