<?php
/* Test script for the new reflection API
 *
 * Usage:
 * - Test Reflection_Function
 *   php5 reflection.php -f counter
 *
 * - Test Reflection_Class
 *   php5 reflection.php -c counter
 *   php5 reflection.php -c object
 *   php5 reflection.php -c storage
 *   php5 reflection.php -c string
 *   php5 reflection.php -c serializable
 *
 * - Test isInstance()
 *   reflection.php -i string
 *   reflection.php -i object
 *
 * - Test newInstance()
 *   php5 reflection.php -n storageimpl [ arg [, arg [ ... ]]]
 *
 */
 
  /**
   * A simple counter
   *
   * @return    int
   */
  function counter() {
    static $c= 0;
    
    return $c++;
  }
  
  /**
   * Serializable interface
   *
   */
  interface Serializable {
    // TBI
  }
  
  /**
   * Base class
   *
   */
  class Object {
  }
  
  /**
   * A counter class
   *
   * Example:
   * <code>
   *   $c= Counter::count();    // $c is now 0
   *   $c= Counter::count();    // $c is now 1
   * </code>
   */
  class Counter extends Object implements Serializable {
    const START= 0;
    private static $c= Counter::START;
    
    /**
     * Invoke counter
     *
     * @access  public
     * @return  int
     */
    public static function count() {
      return self::$c++;
    }
  }
  
  /**
   * A final class
   *
   */
  final class String {
    // TBI
  }

  /**
   * An abstract class
   *
   */  
  abstract class Storage {
    // TBI
  }

  /**
   * An abstract class
   *
   */  
  class StorageImpl extends Storage {
    function __construct() {
      $a= func_get_args();
      printf("%s(%s)\n", __METHOD__, var_export($a, 1));
    }
  }
  
  // {{{ main
  switch ($argv[1]) {
    case '-f':
      try {
        $func= new Reflection_Function($argv[2]);
      } catch (Exception $e) {
        var_dump($e);
        exit(-1);
      }

      var_dump($func);

      printf(
        "===> The %s function '%s'\n".
        "     declared in %s\n".
        "     lines %d to %d\n",
        $func->isInternal() ? 'internal' : 'user-defined',
        $func->getName(),
        var_export($func->getFileName(), 1),
        $func->getStartLine(),
        $func->getEndline()
      );

      printf("---> Documentation:\n %s\n", var_export($func->getDocComment(), 1));

      if ($statics= $func->getStaticVariables()) {
        printf("---> Static variables: %s\n", var_export($statics, 1));
      }

      printf("---> Invokation results in: ");
      var_dump($func->invoke());
      break;
    
    case '-i':
      try {
        $class= new Reflection_Class($argv[2]);
      } catch (Exception $e) {
        var_dump($e);
        exit(-1);
      }
      var_dump($class->isInstance(new String()));
      break;

    case '-n':
      try {
        $class= new Reflection_Class($argv[2]);
      } catch (Exception $e) {
        var_dump($e);
        exit(-1);
      }
      var_dump($class->newInstance(array_slice($argv, 3)));
      break;
          
    case '-c':
      try {
        $class= new Reflection_Class($argv[2]);
      } catch (Exception $e) {
        var_dump($e);
        exit(-1);
      }

      var_dump($class);

      printf(
        "===> The %s%s%s %s '%s' [extends %s]\n".
        "     declared in %s\n".
        "     lines %d to %d\n",
        $class->isInternal() ? 'internal' : 'user-defined',
        $class->isAbstract() ? ' abstract' : '',
        $class->isFinal() ? ' final' : '',
        $class->isInterface() ? 'interface' : 'class',
        $class->getName(),
        var_export($class->getParentClass(), 1),
        var_export($class->getFileName(), 1),
        $class->getStartLine(),
        $class->getEndline()
      );

      printf("---> Documentation:\n %s\n", var_export($class->getDocComment(), 1));
      
      if (!$class->isInterface()) {
        printf("---> Implements:\n %s\n", var_export($class->getInterfaces(), 1));
      }

      if ($constants= $class->getConstants()) {
        printf("---> Constants: %s\n", var_export($constants, 1));
      }

      break;
  }
  // }}}
?>
