annotate vendor/psy/psysh/src/Command/DocCommand.php @ 16:c2387f117808

Routine composer update
author Chris Cannam
date Tue, 10 Jul 2018 15:07:59 +0100
parents 5fb285c0d0e3
children 129ea1e6d783
rev   line source
Chris@13 1 <?php
Chris@13 2
Chris@13 3 /*
Chris@13 4 * This file is part of Psy Shell.
Chris@13 5 *
Chris@13 6 * (c) 2012-2018 Justin Hileman
Chris@13 7 *
Chris@13 8 * For the full copyright and license information, please view the LICENSE
Chris@13 9 * file that was distributed with this source code.
Chris@13 10 */
Chris@13 11
Chris@13 12 namespace Psy\Command;
Chris@13 13
Chris@13 14 use Psy\Formatter\DocblockFormatter;
Chris@13 15 use Psy\Formatter\SignatureFormatter;
Chris@13 16 use Psy\Input\CodeArgument;
Chris@16 17 use Psy\Reflection\ReflectionClassConstant;
Chris@13 18 use Psy\Reflection\ReflectionLanguageConstruct;
Chris@13 19 use Symfony\Component\Console\Input\InputInterface;
Chris@13 20 use Symfony\Component\Console\Output\OutputInterface;
Chris@13 21
Chris@13 22 /**
Chris@13 23 * Read the documentation for an object, class, constant, method or property.
Chris@13 24 */
Chris@13 25 class DocCommand extends ReflectingCommand
Chris@13 26 {
Chris@13 27 /**
Chris@13 28 * {@inheritdoc}
Chris@13 29 */
Chris@13 30 protected function configure()
Chris@13 31 {
Chris@13 32 $this
Chris@13 33 ->setName('doc')
Chris@13 34 ->setAliases(['rtfm', 'man'])
Chris@13 35 ->setDefinition([
Chris@13 36 new CodeArgument('target', CodeArgument::REQUIRED, 'Function, class, instance, constant, method or property to document.'),
Chris@13 37 ])
Chris@13 38 ->setDescription('Read the documentation for an object, class, constant, method or property.')
Chris@13 39 ->setHelp(
Chris@13 40 <<<HELP
Chris@13 41 Read the documentation for an object, class, constant, method or property.
Chris@13 42
Chris@13 43 It's awesome for well-documented code, not quite as awesome for poorly documented code.
Chris@13 44
Chris@13 45 e.g.
Chris@13 46 <return>>>> doc preg_replace</return>
Chris@13 47 <return>>>> doc Psy\Shell</return>
Chris@13 48 <return>>>> doc Psy\Shell::debug</return>
Chris@13 49 <return>>>> \$s = new Psy\Shell</return>
Chris@13 50 <return>>>> doc \$s->run</return>
Chris@13 51 HELP
Chris@13 52 );
Chris@13 53 }
Chris@13 54
Chris@13 55 /**
Chris@13 56 * {@inheritdoc}
Chris@13 57 */
Chris@13 58 protected function execute(InputInterface $input, OutputInterface $output)
Chris@13 59 {
Chris@13 60 $value = $input->getArgument('target');
Chris@13 61 if (ReflectionLanguageConstruct::isLanguageConstruct($value)) {
Chris@13 62 $reflector = new ReflectionLanguageConstruct($value);
Chris@13 63 $doc = $this->getManualDocById($value);
Chris@13 64 } else {
Chris@13 65 list($target, $reflector) = $this->getTargetAndReflector($value);
Chris@13 66 $doc = $this->getManualDoc($reflector) ?: DocblockFormatter::format($reflector);
Chris@13 67 }
Chris@13 68
Chris@13 69 $db = $this->getApplication()->getManualDb();
Chris@13 70
Chris@13 71 $output->page(function ($output) use ($reflector, $doc, $db) {
Chris@13 72 $output->writeln(SignatureFormatter::format($reflector));
Chris@13 73 $output->writeln('');
Chris@13 74
Chris@13 75 if (empty($doc) && !$db) {
Chris@13 76 $output->writeln('<warning>PHP manual not found</warning>');
Chris@13 77 $output->writeln(' To document core PHP functionality, download the PHP reference manual:');
Chris@13 78 $output->writeln(' https://github.com/bobthecow/psysh/wiki/PHP-manual');
Chris@13 79 } else {
Chris@13 80 $output->writeln($doc);
Chris@13 81 }
Chris@13 82 });
Chris@13 83
Chris@13 84 // Set some magic local variables
Chris@13 85 $this->setCommandScopeVariables($reflector);
Chris@13 86 }
Chris@13 87
Chris@13 88 private function getManualDoc($reflector)
Chris@13 89 {
Chris@13 90 switch (get_class($reflector)) {
Chris@13 91 case 'ReflectionClass':
Chris@13 92 case 'ReflectionObject':
Chris@13 93 case 'ReflectionFunction':
Chris@13 94 $id = $reflector->name;
Chris@13 95 break;
Chris@13 96
Chris@13 97 case 'ReflectionMethod':
Chris@13 98 $id = $reflector->class . '::' . $reflector->name;
Chris@13 99 break;
Chris@13 100
Chris@13 101 case 'ReflectionProperty':
Chris@13 102 $id = $reflector->class . '::$' . $reflector->name;
Chris@13 103 break;
Chris@13 104
Chris@16 105 case 'ReflectionClassConstant':
Chris@16 106 case 'Psy\Reflection\ReflectionClassConstant':
Chris@16 107 // @todo this is going to collide with ReflectionMethod ids
Chris@16 108 // someday... start running the query by id + type if the DB
Chris@16 109 // supports it.
Chris@16 110 $id = $reflector->class . '::' . $reflector->name;
Chris@16 111 break;
Chris@16 112
Chris@16 113 case 'Psy\Reflection\ReflectionConstant_':
Chris@16 114 $id = $reflector->name;
Chris@16 115 break;
Chris@16 116
Chris@13 117 default:
Chris@13 118 return false;
Chris@13 119 }
Chris@13 120
Chris@13 121 return $this->getManualDocById($id);
Chris@13 122 }
Chris@13 123
Chris@13 124 private function getManualDocById($id)
Chris@13 125 {
Chris@13 126 if ($db = $this->getApplication()->getManualDb()) {
Chris@13 127 return $db
Chris@13 128 ->query(sprintf('SELECT doc FROM php_manual WHERE id = %s', $db->quote($id)))
Chris@13 129 ->fetchColumn(0);
Chris@13 130 }
Chris@13 131 }
Chris@13 132 }