annotate vendor/psy/psysh/src/Command/DocCommand.php @ 19:fa3358dc1485 tip

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