/**
  * Defines a type
  *
  * @param  string $declaration
  * @param  string[] $extends
  * @return lang.XPClass
  */
 protected function define($declaration, $extends = [Object::class])
 {
     if (!isset(self::$fixtures[$declaration])) {
         $definition = ['kind' => 'class', 'extends' => $extends, 'implements' => [], 'use' => [], 'imports' => [Identity::class => null]];
         self::$fixtures[$declaration] = ClassLoader::defineType(nameof($this) . sizeof(self::$fixtures), $definition, $declaration);
     }
     return self::$fixtures[$declaration];
 }
 /**
  * Defines an anonymous type
  *
  * @param  string $decl Type declaration
  * @param  int $modifiers
  * @return lang.XPClass
  */
 protected function type($decl = null, $modifiers = '')
 {
     if (!isset(self::$fixtures[$decl])) {
         $definition = ['modifiers' => $modifiers, 'kind' => 'class', 'extends' => [Object::class], 'implements' => [], 'use' => [CompareTo::class], 'imports' => [Value::class => null]];
         self::$fixtures[$decl] = ClassLoader::defineType(get_class($this) . sizeof(self::$fixtures), $definition, $decl);
     }
     return self::$fixtures[$decl];
 }
 public function anonymous_instance_from_abstract_base_class()
 {
     \lang\ClassLoader::defineType('net.xp_lang.tests.Command', ['kind' => 'abstract class', 'extends' => ['lang.Object'], 'implements' => ['lang.Runnable'], 'use' => []], []);
     $command = $this->run('return new net.xp_lang.tests.Command() {
   public void run() {
     throw new lang.MethodNotImplementedException("run");
   }
 };');
     $this->assertAnonymousInstanceOf('net.xp_lang.tests.Command', $command);
 }
Example #4
0
function newinstance($spec, $args, $def = null)
{
    static $u = 0;
    if ('#' === $spec[0]) {
        $p = strrpos($spec, ' ');
        $annotations = substr($spec, 0, $p) . ' ';
        $spec = substr($spec, $p + 1);
    } else {
        $annotations = '';
    }
    // Create unique name
    $n = "ยท" . ++$u;
    if (0 === strncmp($spec, 'php.', 4)) {
        $spec = substr($spec, 4);
    } else {
        if (false === strpos($spec, '.')) {
            $spec = \lang\XPClass::nameOf($spec);
        }
    }
    // Handle generics, PHP types and all others.
    if (strstr($spec, '<')) {
        $class = \lang\Type::forName($spec);
        $type = $class->literal();
        $generic = xp::$meta[$class->getName()]['class'][DETAIL_GENERIC];
    } else {
        if (false === strpos($spec, '.')) {
            $type = $spec;
            $generic = null;
        } else {
            try {
                $type = xp::$loader->loadClass0($spec);
            } catch (\lang\ClassLoadingException $e) {
                xp::error($e->getMessage());
            }
            $generic = null;
        }
    }
    $name = strtr($type, '\\', '.') . $n;
    if (interface_exists($type)) {
        $decl = ['kind' => 'class', 'extends' => ['lang.Object'], 'implements' => ['\\' . $type], 'use' => []];
    } else {
        if (trait_exists($type)) {
            $decl = ['kind' => 'class', 'extends' => ['lang.Object'], 'implements' => [], 'use' => ['\\' . $type]];
        } else {
            $decl = ['kind' => 'class', 'extends' => ['\\' . $type], 'implements' => [], 'use' => []];
        }
    }
    $defined = \lang\ClassLoader::defineType($annotations . $name, $decl, $def);
    if (false === strpos($type, '\\')) {
        xp::$cn[$type . $n] = $spec . $n;
    }
    if ($generic) {
        \lang\XPClass::detailsForClass($name);
        xp::$meta[$name]['class'][DETAIL_GENERIC] = $generic;
    }
    if ($defined->hasConstructor()) {
        return $defined->getConstructor()->newInstance($args);
    } else {
        return $defined->newInstance();
    }
}
Example #5
0
 /**
  * Creates a type from a given type body
  *
  * @param  string[] $interfaces
  * @param  string $body The string `<T>` is replaced by the unique type name
  * @return lang.XPClass
  */
 protected function declareType($interfaces, $body)
 {
     $declaration = ['kind' => 'class', 'extends' => ['\\lang\\Object'], 'implements' => $interfaces, 'use' => []];
     $unique = typeof($this)->getSimpleName() . '_' . $this->name;
     return ClassLoader::defineType($unique, $declaration, strtr($body, ['<T>' => $unique]));
 }
 public static function defineImplementation()
 {
     $implementation = static::implementation();
     self::$fixture = ClassLoader::defineType($implementation . 'Instance', ['kind' => 'class', 'extends' => [], 'implements' => [], 'use' => [$implementation]], '{ public $buffer; public function __construct($initial) { $this->buffer= (string)$initial; }}');
 }