Ejemplo n.º 1
0
 /**
  * Instantiates the {@see Resolve} class.
  *
  * @param InputInterface $input The command-line input.
  * @param string $configPath The path to the config definition.
  */
 public function __construct(InputInterface $input, $configPath)
 {
     $this->input = $input;
     $this->formatter = ConsoleUtil::formatters();
     $this->variable_map = array();
     $this->config_path = $configPath;
 }
Ejemplo n.º 2
0
 /**
  * {@inheritdoc}
  */
 public function process($elongate = false)
 {
     $return = parent::process(true);
     if (isset($return['type'])) {
         $return['entity'] = $return['type'];
         unset($return['type']);
     }
     // Property
     if (preg_match('/(\\w+::)?\\$\\w+/', $return['entity'])) {
         $return['entity_hint'] = 'property';
     } elseif (preg_match('/(\\w+::)?[\\w_]+(\\(\\))/', $return['entity'])) {
         $return['entity_hint'] = 'method';
     } elseif (preg_match('/[\\w_]+/', $return['entity'])) {
         $return['entity_hint'] = 'class';
     } elseif (preg_match('/https?:/', $return['entity'])) {
         // Used @see when @link was more appropriate
         $formatter = ConsoleUtil::formatters();
         Inconsistency::add('Used @' . $this->tag . ' when @link was more appropriate. => ' . $formatter->gold->apply(SystemStore::get('_.current')));
         $return['entity_hint'] = 'uri';
     }
     // Do we need to resolve?
     if (strpos($return['entity'], '::') !== false) {
         list($class, $entity) = explode('::', $return['entity']);
         $class = $this->ancestry->resolveNamespace($class);
         $return['entity'] = implode('::', array($class, $entity));
     } elseif ($return['entity_hint'] === 'method' || $return['entity_hint'] === 'property') {
         $class = $this->ancestry->getClass();
         $return['entity'] = implode('::', array($class, $return['entity']));
     }
     return $return;
 }
Ejemplo n.º 3
0
 /**
  * {@inheritdoc}
  */
 public function process($elongate = false)
 {
     // Used @var, which is deprecated
     if (strtolower($this->tag) === 'var') {
         $formatter = ConsoleUtil::formatters();
         Inconsistency::add('The @var keyword is deprecated. Use @type instead. => ' . $formatter->gold->apply(SystemStore::get('_.current')));
     }
     return parent::process(true);
 }
Ejemplo n.º 4
0
 /**
  * Renders a backtrace message as a string.
  *
  * @param  array  $backtrace The result of `debug_backtrace()`.
  * @return string            A stringified backtrace message for printing to the console.
  */
 public static function render(array $backtrace)
 {
     $messages = array();
     $output = array();
     $formatter = ConsoleUtil::formatters();
     foreach ($backtrace as $trace) {
         @($messages[$trace['file'] . ':' . $trace['line']] = $trace['class'] . $trace['type'] . $trace['function'] . '()');
     }
     $padding = ConsoleUtil::tablify($messages);
     foreach ($messages as $code => $line) {
         $output[] = implode(' @ ', array(str_pad($code, $padding, ' ', STR_PAD_RIGHT), $formatter->gold->apply($line)));
     }
     return PHP_EOL . TAB . TAB . implode(PHP_EOL . TAB . TAB, $output);
 }
Ejemplo n.º 5
0
 /**
  * The command-line arguments and options.
  *
  * @return void
  */
 protected function configure()
 {
     $this->setName('fetch')->setDescription('Fetches a copy of the latest PHP API Reference from PHP.net. Useful when extending PHP\'s base classes.');
     $options = (include __DIR__ . '/fetch_configs.php');
     $options = ConfigStore::convert($options);
     foreach ($options as $option => $details) {
         list($type, $description, $default) = $details;
         if (!is_null($default)) {
             if (is_bool($default)) {
                 $default = $default ? 'true' : 'false';
             }
             $description .= ConsoleUtil::formatters()->gold->apply(' (default: ' . $default . ')');
         }
         $this->addOption($option, null, $type, $description);
     }
 }
Ejemplo n.º 6
0
 /**
  * The command-line arguments and options.
  *
  * @return void
  */
 protected function configure()
 {
     $this->setName('parse')->setDescription('Parse the content of the source code and docblocks and produce JSON documents to be used for the project\'s API Reference.');
     $options = (include __DIR__ . '/parse_configs.php');
     $options = ConfigStore::convert($options);
     foreach ($options as $option => $details) {
         list($type, $description, $default) = $details;
         if (!is_null($default)) {
             if (is_bool($default)) {
                 $default = $default ? 'true' : 'false';
             }
             $description .= ConsoleUtil::formatters()->gold->apply(' (default: ' . $default . ')');
         }
         $this->addOption($option, null, $type, $description);
     }
 }
Ejemplo n.º 7
0
 /**
  * The command-line arguments and options.
  *
  * @return void
  */
 protected function configure()
 {
     $this->setName('generate')->setDescription('Generate the documentation output from JSON source definitions.');
     $options = (include __DIR__ . '/generate_configs.php');
     $options = ConfigStore::convert($options);
     foreach ($options as $option => $details) {
         list($type, $description, $default) = $details;
         if (!is_null($default)) {
             if (is_bool($default)) {
                 $default = $default ? 'true' : 'false';
             }
             $description .= ConsoleUtil::formatters()->gold->apply(' (default: ' . (is_array($default) ? ParseUtils::unwrapArray($default) : $default) . ')');
         }
         $this->addOption($option, null, $type, $description);
     }
 }
Ejemplo n.º 8
0
<?php

use Vanity\Console\Utilities;
// Assist PSR-0 autoloading
if (!file_exists(dirname(dirname(__DIR__)) . '/vendor/composer/autoload_namespaces.php')) {
    $formatters = Utilities::formatters();
    echo $formatters->warning->apply(' You must run Composer\'s `install` task before generating documentation. ') . PHP_EOL . PHP_EOL;
    exit(1);
}
Ejemplo n.º 9
0
 /**
  * Executes all of the event handlers.
  *
  * @return void
  */
 public static function events()
 {
     $self = get_called_class();
     // vanity.command.complete event
     Dispatcher::get()->addListener('vanity.command.complete', function (Event $event) {
         $formatter = ConsoleUtil::formatters();
         $stop_time = Timer::stop();
         echo PHP_EOL;
         echo $formatter->pending->apply(' Completed in ' . ConsoleUtil::timeHMS(round($stop_time)) . ' (' . $stop_time . ') | Peak memory usage: ' . ConsoleUtil::formatSize(memory_get_peak_usage()) . ' (' . number_format(memory_get_peak_usage()) . ' bytes) ') . PHP_EOL;
     });
     // vanity.command.log_path event
     Dispatcher::get()->addListener('vanity.command.log_path', function (EventStore $event) {
         $finder = new Finder();
         $formatter = ConsoleUtil::formatters();
         $log_path = $event->get('log_path');
         $time = $event->get('time');
         echo PHP_EOL;
         echo $formatter->yellow->apply('LOG FILES FOR THIS RUN') . PHP_EOL;
         $files = $finder->files()->name("vanity-run-{$time}-*.log")->depth(0)->in($log_path);
         $count = 0;
         foreach ($files as $file) {
             $count++;
             echo TAB . $formatter->green->apply('-> ') . $file->getRealpath() . PHP_EOL;
         }
         // Count the classes
         echo PHP_EOL;
         echo 'Found ' . $formatter->info->apply(" {$count} ") . ' log ' . ConsoleUtil::pluralize($count, 'file', 'files') . '.' . PHP_EOL;
     });
     // vanity.command.parse.report.dependencies event
     Dispatcher::get()->addListener('vanity.command.parse.report.dependencies', function (Event $event) {
         // jsonify!
         $json = ConsoleUtil::json_encode(self::getDependencies());
         // Make sure the directory is created
         $filesystem = new Filesystem();
         $filesystem->mkdir(ConfigStore::get('vanity.reports'));
         file_put_contents(ConfigStore::get('vanity.reports') . '/dependencies.json', $json);
     });
     // vanity.command.parse.warn.dependencies event
     Dispatcher::get()->addListener('vanity.command.parse.warn.dependencies', function (Event $event) use(&$self) {
         $formatter = ConsoleUtil::formatters();
         $dependencies = $self::getDependencies();
         echo PHP_EOL;
         echo $formatter->yellow->apply('REPORT: DEPENDENCIES ON EXTENSIONS') . PHP_EOL;
         foreach ($dependencies as $dependency) {
             echo TAB . $formatter->green->apply('-> ') . $dependency . PHP_EOL;
         }
         // Count the classes
         echo PHP_EOL;
         $count = count($dependencies);
         echo 'Found ' . $formatter->info->apply(" {$count} ") . ' ' . ConsoleUtil::pluralize($count, 'dependency', 'dependencies') . '.' . PHP_EOL;
     });
     // vanity.command.parse.warn.inconsistencies event
     Dispatcher::get()->addListener('vanity.command.parse.warn.inconsistencies', function (Event $event) {
         $formatter = ConsoleUtil::formatters();
         $inconsistencies = DocumentationInconsistencyCollector::read();
         echo PHP_EOL;
         echo $formatter->yellow->apply('REPORT: DOCBLOCK INCONSISTENCIES') . PHP_EOL;
         // We really need \Array->apply(), don't we?
         echo 'Tags where type is inferred: ' . implode(', ', array_map(function ($w) use($formatter) {
             return $formatter->green->apply($w);
         }, explode(', ', '@param, @return, @returns, @see, @throw, @throws, @uses, @used-by, @type, @var'))) . '.' . PHP_EOL;
         foreach ($inconsistencies as $inconsistency) {
             echo TAB . $formatter->green->apply('-> ') . $inconsistency['message'] . PHP_EOL;
         }
         // Count the classes
         echo PHP_EOL;
         $count = count($inconsistencies);
         echo 'Found ' . $formatter->info->apply(" {$count} ") . ' ' . ConsoleUtil::pluralize($count, 'inconsistency', 'inconsistencies') . '.' . PHP_EOL;
     });
     // Handle default HTML template
     DesktopHTMLTemplate::register('default-html');
 }
Ejemplo n.º 10
0
 public static function resolve($reflected)
 {
     $is_method = false;
     $is_property = false;
     // Are we working with a property or a method?
     if ($reflected instanceof ReflectionMethod) {
         $is_method = true;
     } elseif ($reflected instanceof ReflectionProperty) {
         $is_property = true;
     } else {
         throw new Exception('Only methods and properties can be reflected with ' . get_called_class());
     }
     // Parse the docblock
     $docblock = new DocBlock($reflected->getDocComment());
     $found_description = false;
     $return = $reflected;
     // Save these for messaging
     $__class = $reflected->getDeclaringClass()->getName();
     $__kind = $reflected->getName();
     // Can we just do a straight-up inherit?
     // @todo: Do a better job of handling {@inheritdoc} according to the spec.
     try {
         while (!$found_description && strpos($docblock->getShortDescription(), '{@inheritdoc}') !== false) {
             // Start over...
             $found_description = false;
             // Log that we're starting...
             Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} Starting resolution:', array(sprintf("{$__class}%s{$__kind}%s", $is_method ? '::' : '::$', $is_method ? '()' : '')));
             // Grab a reference to the class containing the entity with the {@inheritdoc} tag
             $klass = $reflected->getDeclaringClass();
             // Is this an Interface?
             if ($klass->isInterface()) {
                 throw new InheritdocInInterfaceException('The {@inheritdoc} tag is not resolvable from within Interfaces. Methods and properties should ' . 'be fully-documented.');
             } elseif (SystemStore::get('_.php54') && $klass->isTrait()) {
                 throw new InheritdocInTraitException('The {@inheritdoc} tag is not resolvable from within Traits. Methods and properties should ' . 'be fully-documented.');
             }
             // Are we using Interfaces?
             if (!$found_description && ($interface_count = count($klass->getInterfaces())) > 0) {
                 $count = 1;
                 foreach ($klass->getInterfaces() as $rinterface) {
                     Logger::get()->{ConfigStore::get('log.info')}("{@inheritdoc} Checking Interface {$count}/{$interface_count}:", array($rinterface->getName()));
                     try {
                         $return = $rinterface->getMethod($reflected->getName());
                         Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} Match!', array($rinterface->getName(), $reflected->getName(), 'Method'));
                         $found_description = true;
                         break 2;
                     } catch (Exception $e) {
                         try {
                             $return = $rinterface->getProperty($reflected->getName());
                             Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} Match!', array($rinterface->getName(), $reflected->getName(), 'Property'));
                             $found_description = true;
                             break 2;
                         } catch (Exception $e) {
                             Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} No match. Will keep looking...', array($rinterface->getName(), $reflected->getName()));
                         }
                     }
                     $count++;
                 }
             }
             // Are we using Traits?
             if (!$found_description && SystemStore::get('_.php54') && ($trait_count = count($klass->getTraits())) > 0) {
                 $count = 1;
                 foreach ($klass->getTraits() as $rtrait) {
                     Logger::get()->{ConfigStore::get('log.info')}("{@inheritdoc} Checking Trait {$count}/{$trait_count}:", array($rtrait->getName()));
                     try {
                         $return = $rtrait->getMethod($reflected->getName());
                         Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} Match!', array($rtrait->getName(), $reflected->getName(), 'Method'));
                         $found_description = true;
                         break 2;
                     } catch (Exception $e) {
                         try {
                             $return = $rtrait->getProperty($reflected->getName());
                             Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} Match!', array($rtrait->getName(), $reflected->getName(), 'Property'));
                             $found_description = true;
                             break 2;
                         } catch (Exception $e) {
                             Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} No match. Will keep looking...', array($rtrait->getName(), $reflected->getName()));
                         }
                     }
                     $count++;
                 }
             }
             // Are we extending a class?
             if ($klass->getParentClass()) {
                 // Continue climbing up the ancestry as necessary
                 while (!$found_description && $klass->getParentClass()) {
                     // Rewrite the reference to $klass
                     $klass = $klass->getParentClass();
                     Logger::get()->{ConfigStore::get('log.info')}("{@inheritdoc} Checking the parent class:", array($klass->getName()));
                     try {
                         $return = $klass->getMethod($reflected->getName());
                         Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} Match!', array($klass->getName(), $reflected->getName(), 'Method'));
                         $found_description = true;
                         break 2;
                     } catch (Exception $e) {
                         try {
                             $return = $klass->getProperty($reflected->getName());
                             Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} Match!', array($klass->getName(), $reflected->getName(), 'Property'));
                             $found_description = true;
                             break 2;
                         } catch (Exception $e) {
                             Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} No match. Will keep looking...', array($klass->getName(), $reflected->getName()));
                         }
                     }
                 }
             }
             // We couldn't find anything
             throw new CouldNotResolveInheritdocException('Leaving as-is. The tag will be viewable in the ' . 'resulting documentation.');
         }
     } catch (InheritdocInInterfaceException $e) {
         $message = sprintf("{$__class}%s{$__kind}%s", $is_method ? '::' : '::$', $is_method ? '()' : '');
         // Log that we're starting...
         Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} ' . $e->getMessage(), array($message));
         $formatter = ConsoleUtil::formatters();
         Inconsistency::add($message . $formatter->gold->apply(' => Could not resolve {@inheritdoc}. ' . $e->getMessage()));
     } catch (InheritdocInTraitException $e) {
         $message = sprintf("{$__class}%s{$__kind}%s", $is_method ? '::' : '::$', $is_method ? '()' : '');
         // Log that we're starting...
         Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} ' . $e->getMessage(), array($message));
         $formatter = ConsoleUtil::formatters();
         Inconsistency::add($message . $formatter->gold->apply(' => Could not resolve {@inheritdoc}. ' . $e->getMessage()));
     } catch (CouldNotResolveInheritdocException $e) {
         $message = sprintf("{$__class}%s{$__kind}%s", $is_method ? '::' : '::$', $is_method ? '()' : '');
         // Log that we're starting...
         Logger::get()->{ConfigStore::get('log.info')}('{@inheritdoc} ' . $e->getMessage(), array($message));
         $formatter = ConsoleUtil::formatters();
         Inconsistency::add($message . $formatter->gold->apply(' => Could not resolve {@inheritdoc}. ' . $e->getMessage()));
     } catch (VanityException $e) {
     } catch (Exception $e) {
     }
     return $return;
 }
Ejemplo n.º 11
0
 /**
  * Resolves a namespace alias into a fully-qualified namespace.
  *
  * @param  string $short A shortened namespace alias.
  * @return string        The fully-qualified namespace, if available.
  */
 public function resolveNamespace($short)
 {
     if (isset($this->aliases[$short])) {
         Logger::get()->{ConfigStore::get('log.aliases')}('Aliases: Matched in the list of known aliases.', array($short, $this->aliases[$short]));
         return $this->aliases[$short];
     } else {
         // Handle implicit aliases in the same namespace.
         try {
             $namespace = $this->class->getNamespaceName() . '\\' . $short;
             new ReflectionClass($namespace);
             Logger::get()->{ConfigStore::get('log.aliases')}('Aliases: Matched in the current namespace.', array($short, $namespace));
             // If we didn't throw an exception, we're good.
             return $namespace;
         } catch (ReflectionException $e) {
             // Handle implicit namespaces in an extended/implemented namespace.
             try {
                 foreach ($this->namespaces as $ns) {
                     try {
                         $namespace = $ns . '\\' . $short;
                         new ReflectionClass($namespace);
                         Logger::get()->{ConfigStore::get('log.aliases')}('Aliases: Matched in an extended/implemented namespace.', array($short, $namespace));
                         // If we didn't throw an exception, we're good.
                         return $namespace;
                     } catch (ReflectionException $e) {
                     }
                 }
                 throw new ReflectionException();
             } catch (ReflectionException $e) {
                 // Try removing the beginning '\' to see if we find a match.
                 try {
                     $class = preg_replace('/^\\\\/', '', $short);
                     new ReflectionClass($class);
                     Logger::get()->{ConfigStore::get('log.aliases')}('Aliases: Matched by stripping the \\ prefix.', array($short, $class));
                     // If we didn't throw an exception, we're good.
                     return $class;
                 } catch (ReflectionException $e) {
                     $formatter = ConsoleUtil::formatters();
                     Inconsistency::add($class . $formatter->gold->apply(' => No match found for ' . $short . ' (' . SystemStore::get('_.current') . ')'));
                     Logger::get()->{ConfigStore::get('log.aliases')}('Aliases: No match found.', array($short));
                     // No match. Return it as-is (without any starting backslash).
                     return $class;
                 }
             }
         }
     }
 }
Ejemplo n.º 12
0
 /**
  * Log the number of files that were written to the console.
  *
  * @param  integer $count The number of files that were written.
  * @return void
  */
 public static function wroteFileCount($count)
 {
     $formatter = ConsoleUtil::formatters();
     echo PHP_EOL;
     echo 'Matched ' . $formatter->info->apply(" {$count} ") . ' ' . ConsoleUtil::pluralize($count, 'file', 'files') . '.' . PHP_EOL;
 }
Ejemplo n.º 13
0
 /**
  * Instantiate options for all Vanity-specific commands.
  */
 public function __construct()
 {
     parent::__construct();
     $this->formatter = ConsoleUtil::formatters();
 }
Ejemplo n.º 14
0
 /**
  * Constructs a new instance of this class.
  *
  * @param string $class The class name to reflect.
  */
 public function __construct($class)
 {
     $this->class_name = $class;
     $this->rclass = new ReflectionClass($class);
     $this->ancestry = new AncestryHandler($this->rclass);
     $this->inheritance = $this->ancestry->getInheritance();
     $this->implements = $this->ancestry->getImplementations();
     $this->traits = $this->ancestry->getTraits();
     $this->aliases = $this->ancestry->getNamespaces();
     $this->constants = new ConstantHandler($this->rclass, $this->ancestry);
     $this->properties = new PropertyHandler($this->rclass, $this->ancestry);
     $this->methods = new MethodHandler($this->rclass, $this->ancestry);
     $this->class_tags = new TagHandler($this->rclass->getDocComment(), $this->ancestry);
     $this->formatter = ConsoleUtil::formatters();
 }
Ejemplo n.º 15
0
 /**
  * Constructs a new instance of this class.
  *
  * @param array  $classes      The list of classes to reflect.
  * @param string $path_pattern The path pattern to handle.
  */
 public function __construct(array $classes, $path_pattern)
 {
     $this->path_pattern = $path_pattern;
     $this->formatter = ConsoleUtil::formatters();
     $this->classes = $classes;
 }