Пример #1
0
 /**
  * Find first classloader responsible for a given path
  *
  * @param   string path
  * @return  lang.IClassLoader
  */
 protected function findLoaderFor($path)
 {
     foreach (\lang\ClassLoader::getLoaders() as $cl) {
         if ($cl instanceof \lang\FileSystemClassLoader && 0 === strncmp($cl->path, $path, strlen($cl->path))) {
             return $cl;
         }
     }
     return null;
 }
Пример #2
0
 /**
  * Main
  *
  * @param   string[] args
  * @return  int
  */
 public static function main(array $args)
 {
     Console::writeLinef('XP %s { PHP %s & ZE %s } @ %s', \xp::version(), phpversion(), zend_version(), php_uname());
     Console::writeLine('Copyright (c) 2001-2015 the XP group');
     foreach (\lang\ClassLoader::getLoaders() as $delegate) {
         Console::writeLine($delegate->toString());
     }
     return 1;
 }
Пример #3
0
 /** @return php.Generator */
 public function sources()
 {
     $name = $this->package->name();
     foreach (ClassLoader::getLoaders() as $loader) {
         if ($loader->providesPackage($name)) {
             (yield $loader);
         }
     }
 }
Пример #4
0
 /**
  * Constructor
  *
  * @param  io.Folder $folder
  * @throws lang.IllegalArgumentException if the given folder does not exist or isn't in class path
  */
 public function __construct(Folder $folder)
 {
     $path = $folder->getURI();
     foreach (ClassLoader::getLoaders() as $cl) {
         if ($cl instanceof FileSystemClassLoader && 0 === strncmp($cl->path, $path, strlen($cl->path))) {
             $this->loader = $cl;
             return;
         }
     }
     throw new IllegalArgumentException($folder->toString() . ($folder->exists() ? ' is not in class path' : ' does not exist'));
 }
 /**
  * Creates a new directory information instance
  *
  * @param  string|io.Folder $folder
  */
 public function __construct($folder)
 {
     $this->folder = $folder instanceof Folder ? $folder : new Folder($folder);
     $uri = $this->folder->getURI();
     foreach (ClassLoader::getLoaders() as $loader) {
         if (0 === strncmp($uri, $loader->path, $l = strlen($loader->path)) && $loader->providesPackage($package = strtr(substr($uri, $l, -1), DIRECTORY_SEPARATOR, '.'))) {
             $this->loader = $loader;
             $this->package = new Package($package);
             return;
         }
     }
     throw new IllegalArgumentException('Cannot find ' . $uri . ' in class path');
 }
Пример #6
0
 /**
  * Serve requests
  *
  * @param  string $source
  * @param  string $profile
  * @param  io.Path $webroot
  * @param  io.Path $docroot
  * @param  string[] $config
  */
 public function serve($source, $profile, $webroot, $docroot, $config)
 {
     $runtime = Runtime::getInstance();
     $startup = $runtime->startupOptions();
     $backing = typeof($startup)->getField('backing')->setAccessible(true)->get($startup);
     // PHP doesn't start with a nonexistant document root
     if (!$docroot->exists()) {
         $docroot = getcwd();
     }
     // Start `php -S`, the development webserver
     $arguments = ['-S', $this->host . ':' . $this->port, '-t', $docroot];
     $options = newinstance(RuntimeOptions::class, [$backing], ['asArguments' => function () use($arguments) {
         return array_merge($arguments, parent::asArguments());
     }]);
     $options->withSetting('user_dir', $source . PATH_SEPARATOR . implode(PATH_SEPARATOR, $config));
     // Pass classpath (TODO: This is fixed in XP 7.6.0, remove once
     // this becomes minimum dependency)
     $cp = [];
     foreach (ClassLoader::getLoaders() as $delegate) {
         if ($delegate instanceof FileSystemClassLoader || $delegate instanceof ArchiveClassLoader) {
             $cp[] = $delegate->path;
         }
     }
     set_include_path('');
     $options->withClassPath($cp);
     // Export environment
     putenv('DOCUMENT_ROOT=' . $docroot);
     putenv('WEB_ROOT=' . $webroot);
     putenv('SERVER_PROFILE=' . $profile);
     Console::writeLine("@", $this, "");
     Console::writeLine("Serving ", (new Source($source, new Config($config)))->layout());
     Console::writeLine("", str_repeat('═', 72), "");
     Console::writeLine();
     with($runtime->newInstance($options, 'web', '', []), function ($proc) {
         $proc->in->close();
         Console::writeLine("> Server started: ", $this->url, " (", date('r'), ')');
         Console::writeLine('  PID ', $proc->getProcessId(), '; press Ctrl+C to exit');
         Console::writeLine();
         while (is_string($line = $proc->err->readLine())) {
             Console::writeLine("  ", $line, "");
         }
     });
 }
Пример #7
0
 /**
  * Main
  *
  * @param   string[] $args
  * @return  int
  */
 public static function main(array $args)
 {
     if (empty($args)) {
         Console::writeLinef('XP %s { PHP %s & ZE %s } @ %s', \xp::version(), phpversion(), zend_version(), php_uname());
         Console::writeLine('Copyright (c) 2001-2016 the XP group');
         foreach (\lang\ClassLoader::getLoaders() as $delegate) {
             Console::writeLine($delegate->toString());
         }
         return 1;
     } else {
         foreach ($args as $arg) {
             $method = $arg . 'Version';
             if (is_callable(['self', $method])) {
                 Console::writeLine(self::$method());
             } else {
                 Console::$err->writeLinef('Unkown version argument `%s\'', $arg);
             }
         }
         return 0;
     }
 }
Пример #8
0
 /**
  * Main
  *
  * @param   string[] args
  */
 public static function main(array $args)
 {
     if (sizeof($args) < 1 || '' == $args[0]) {
         Console::$err->writeLine('*** No class or package name given');
         return 2;
     }
     // Check whether a file, class or a package directory or name is given
     $cl = \lang\ClassLoader::getDefault();
     if (strstr($args[0], \xp::CLASS_FILE_EXT)) {
         $class = $cl->loadUri(realpath($args[0]));
     } else {
         if ($cl->providesClass($args[0])) {
             $class = XPClass::forName($args[0], $cl);
         } else {
             if (strcspn($args[0], '\\/') < strlen($args[0])) {
                 $package = self::findPackageBy(new Folder($args[0]));
             } else {
                 $package = $args[0];
             }
             $provided = false;
             foreach (\lang\ClassLoader::getLoaders() as $loader) {
                 if (!$loader->providesPackage($package)) {
                     continue;
                 }
                 Console::writeLine('@', $loader);
                 $provided = true;
             }
             if ($provided) {
                 self::printPackage(\lang\reflect\Package::forName($package));
                 return 0;
             }
             // Not found
             Console::$err->writeLine('*** Failed to locate either a class or a package named "', $args[0], '", tried all of {');
             foreach (\lang\ClassLoader::getLoaders() as $loader) {
                 Console::$err->writeLine('  ', $loader);
             }
             Console::$err->writeLine('}');
             return 1;
         }
     }
     Console::writeLine('@', $class->getClassLoader());
     if ($class->isInterface()) {
         self::printInterface($class);
     } else {
         if ($class->isEnum()) {
             self::printEnum($class);
         } else {
             self::printClass($class);
         }
     }
     return 0;
 }
Пример #9
0
 public function after_via_inspect()
 {
     $loader = $this->track(ClassLoader::registerPath('.', null));
     $loaders = ClassLoader::getLoaders();
     $this->assertEquals($loader, $loaders[sizeof($loaders) - 1]);
 }
Пример #10
0
 /**
  * Entry point method
  *
  * @param   string[] args
  */
 public static function main(array $args)
 {
     if (empty($args)) {
         return self::usage();
     }
     foreach (ClassLoader::getLoaders() as $loader) {
         if ($loader instanceof JitClassLoader) {
             ClassLoader::removeLoader($loader);
         }
     }
     // Set up compiler
     $compiler = new Compiler();
     $manager = new FileManager();
     $manager->setSourcePaths(\xp::$classpath);
     // Handle arguments
     $profiles = ['default'];
     $emitter = 'php5.5';
     $result = function ($success) {
         return $success ? 0 : 1;
     };
     $files = [];
     $listener = new DefaultDiagnosticListener(Console::$out);
     for ($i = 0, $s = sizeof($args); $i < $s; $i++) {
         if ('-?' === $args[$i] || '--help' === $args[$i]) {
             return self::usage();
         } else {
             if ('-cp' === $args[$i]) {
                 \lang\ClassLoader::registerPath($args[++$i]);
             } else {
                 if ('-sp' === $args[$i]) {
                     $manager->addSourcePath($args[++$i]);
                 } else {
                     if ('-v' === $args[$i]) {
                         $listener = new VerboseDiagnosticListener(Console::$out);
                     } else {
                         if ('-q' === $args[$i]) {
                             $listener = new QuietDiagnosticListener(Console::$out);
                         } else {
                             if ('-t' === $args[$i]) {
                                 $levels = LogLevel::NONE;
                                 foreach (explode(',', $args[++$i]) as $level) {
                                     $levels |= LogLevel::named($level);
                                 }
                                 $compiler->setTrace(create(new LogCategory('xcc'))->withAppender(new ConsoleAppender(), $levels));
                             } else {
                                 if ('-E' === $args[$i]) {
                                     $emitter = $args[++$i];
                                 } else {
                                     if ('-p' === $args[$i]) {
                                         $profiles = explode(',', $args[++$i]);
                                     } else {
                                         if ('-o' === $args[$i]) {
                                             $output = $args[++$i];
                                             $folder = new Folder($output);
                                             $folder->exists() || $folder->create();
                                             $manager->setOutput($folder);
                                         } else {
                                             if ('-N' === $args[$i]) {
                                                 $dir = $args[++$i];
                                                 $manager->addSourcePath($dir);
                                                 $files = array_merge($files, self::fromFolder($dir, false));
                                             } else {
                                                 if (is_dir($args[$i])) {
                                                     $dir = $args[$i];
                                                     $manager->addSourcePath($dir);
                                                     $files = array_merge($files, self::fromFolder($dir, true));
                                                 } else {
                                                     $files[] = new FileSource(new File($args[$i]));
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     // Check
     if (empty($files)) {
         Console::$err->writeLine('*** No files given (-? will show usage)');
         return 2;
     }
     // Setup emitter
     sscanf($emitter, '%[^0-9]%d.%d', $language, $major, $minor);
     try {
         $emit = \lang\XPClass::forName('xp.compiler.emit.Emitter')->cast(Package::forName('xp.compiler.emit')->getPackage($language)->loadClass(($major ? 'V' . $major . $minor : '') . 'Emitter')->newInstance());
     } catch (\lang\ClassCastException $e) {
         Console::$err->writeLine('*** Not an emitter implementation: ', $e->compoundMessage());
         return 4;
     } catch (\lang\IllegalAccessException $e) {
         Console::$err->writeLine('*** Cannot use emitter named "', $emitter, '": ', $e->compoundMessage());
         return 4;
     } catch (\lang\Throwable $e) {
         Console::$err->writeLine('*** No emitter named "', $emitter, '": ', $e->compoundMessage());
         return 4;
     }
     // Load compiler profile configurations
     try {
         $reader = new CompilationProfileReader();
         foreach ($profiles as $configuration) {
             $reader->addSource(new Properties('res://xp/compiler/' . $configuration . '.xcp.ini'));
         }
         $emit->setProfile($reader->getProfile());
     } catch (\lang\Throwable $e) {
         Console::$err->writeLine('*** Cannot load profile configuration(s) ' . implode(',', $profiles) . ': ' . $e->getMessage());
         return 3;
     }
     // Compile files and pass return value to result handler
     return $result($compiler->compile($files, $listener, $manager, $emit), array_slice($args, $i + 1));
 }
Пример #11
0
 /**
  * Create a new runtime instance.
  *
  * @param   lang.RuntimeOptions options default NULL
  * @param   string bootstrap default 'class'
  * @param   string class default NULL entry point class
  * @param   string[] arguments default []
  * @param   string cwd default NULL the working directory
  * @param   [:string] default NULL the environment
  * @return  lang.Process
  */
 public function newInstance(RuntimeOptions $options = null, $bootstrap = 'class', $class = null, $arguments = [], $cwd = null, $env = null)
 {
     // Use unmodified startup options if none are passed
     if (null === $options) {
         $options = $this->startupOptions();
     }
     // Inherit all currently loaded paths acceptable to bootstrapping
     $include = '.';
     foreach (ClassLoader::getLoaders() as $delegate) {
         if ($delegate instanceof FileSystemClassLoader || $delegate instanceof ArchiveClassLoader) {
             $include .= PATH_SEPARATOR . $delegate->path;
         }
     }
     // If a bootstrap script is given, it will expect the include_path setting to be
     // in the form `[MODULES];;[CLASSPATH]` (both starting with a dot).
     if (null !== $bootstrap) {
         $include = '.' . PATH_SEPARATOR . PATH_SEPARATOR . $include;
     }
     // Append extra class path elements
     if ($cp = $options->getClassPath()) {
         $include .= PATH_SEPARATOR . implode(PATH_SEPARATOR, $cp);
     }
     $cmdline = array_merge($options->withSetting('include_path', $include)->withSetting('encoding', null)->asArguments(), $bootstrap ? [$this->bootstrapScript($bootstrap)] : [], $class ? [$class] : []);
     // Pass XP_CMDLINE via environment - part 2 of workaround from above,
     // see inline comment in startup() method for details
     if ($this->startup('env')) {
         putenv('XP_CMDLINE=' . implode('|', $cmdline));
     }
     // Finally, fork executable
     $pass = array_map(function ($arg) {
         return iconv(\xp::ENCODING, 'utf-7', $arg);
     }, $arguments);
     return $this->getExecutable()->newInstance(array_merge($cmdline, $pass), $cwd, $env);
 }