/** * Get parse tree for a given qualified class name by looking it * up in the source path. * * @param string qualified * @return xp.compiler.io.Source */ public function findClass($qualified) { $name = DIRECTORY_SEPARATOR . strtr($qualified, '.', DIRECTORY_SEPARATOR); foreach ($this->sourcePaths as $path) { foreach (Syntax::available() as $ext => $syntax) { if (!file_exists($uri = $path . $name . '.' . $ext)) { continue; } return new FileSource(new File($uri), $syntax); // FIXME: Use class loader / resources } } return null; }
/** * Returns file targets from a folder * * @param string uri * @param bool recursive * @return xp.compiler.io.FileSource[] */ protected static function fromFolder($uri, $recursive) { static $filter = null; if (null === $filter) { $filter = new AnyOfFilter(); foreach (Syntax::available() as $ext => $syntax) { $filter->add(new ExtensionEqualsFilter($ext)); } } $files = []; $it = new FilteredIOCollectionIterator(new FileCollection($uri), $filter, $recursive); foreach ($it as $element) { $files[] = new FileSource(new File($element->getURI())); } return $files; }
/** * Returns a given package's contents * * @param string $package * @return string[] */ public function packageContents($package) { static $syntaxes = ''; // Calculate syntax regex for matching on files if (!$syntaxes) { foreach (Syntax::available() as $syntax) { $syntaxes .= '|' . $syntax->name(); } $syntaxes = '/\\.(' . substr($syntaxes, 1) . ')$/'; } // List directory contents, replacing compileable source files with // class file names. These of course don't exist yet, but will be // compiled on demand $return = []; $dir = strtr($package, '.', DIRECTORY_SEPARATOR); foreach ($this->files->getSourcePaths() as $path) { if (!is_dir($d = $path . $dir . DIRECTORY_SEPARATOR)) { continue; } $handle = opendir($d); while ($e = readdir($handle)) { if ('.' === $e || '..' === $e) { continue; } else { if (is_dir($d . $e)) { $return[] = $e . '/'; } else { if (strstr($e, \xp::CLASS_FILE_EXT)) { $return[] = $e; } else { if ('module.xp' === $e) { $return[] = $e; } else { $return[] = preg_replace($syntaxes, \xp::CLASS_FILE_EXT, $e); } } } } } closedir($handle); } return $return; }
/** * Returns a subtask (overloaded) * * @param var arg either a xp.compiler.io.Source or a fully qualified class name * @return xp.compiler.task.CompilationTask * @throws lang.IllegalArgumentException for argument type mismatches * @throws lang.ElementNotFoundException if class given and class cannot be found */ public function newSubTask($arg) { if ($arg instanceof Source) { $source = $arg; } else { if (is_string($arg)) { if (!($source = $this->manager->findClass($arg))) { throw new ElementNotFoundException(sprintf("Cannot find class %s, tried {*.%s} in [\n %s\n]", $arg, implode(', *.', array_keys(Syntax::available())), implode("\n ", $this->manager->getSourcePaths()))); } } else { throw new \lang\IllegalArgumentException('Expected either a string or a Source object'); } } return new self($source, $this->listener, $this->manager, $this->emitter, $this->done); }