public function willParseFiles(array $file_map)
 {
     $root = dirname(phutil_get_library_root('javelin-diviner'));
     $bin = $root . '/jsast/jsast';
     if (!Filesystem::pathExists($bin)) {
         throw new Exception("You must build the 'jsast' binary before you can generate " . "Javelin documentation.");
     }
     $futures = array();
     foreach ($file_map as $file => $data) {
         $future = new ExecFuture($bin);
         $future->write($data);
         $futures[$file] = $future;
     }
     foreach (Futures($futures)->limit(8) as $file => $future) {
         $this->trees[$file] = $future->resolveJSON();
     }
 }
 public function willLintPaths(array $paths)
 {
     if (!xhpast_is_available()) {
         throw new Exception(xhpast_get_build_instructions());
     }
     // NOTE: For now, we completely ignore paths and just lint every library in
     // its entirety. This is simpler and relatively fast because we don't do any
     // detailed checks and all the data we need for this comes out of module
     // caches.
     $bootloader = PhutilBootloader::getInstance();
     $libs = $bootloader->getAllLibraries();
     // Load the up-to-date map for each library, without loading the library
     // itself. This means lint results will accurately reflect the state of
     // the working copy.
     $arc_root = dirname(phutil_get_library_root('arcanist'));
     $bin = "{$arc_root}/scripts/phutil_rebuild_map.php";
     $symbols = array();
     foreach ($libs as $lib) {
         // Do these one at a time since they individually fanout to saturate
         // available system resources.
         $future = new ExecFuture('%s --show --quiet --ugly -- %s', $bin, phutil_get_library_root($lib));
         $symbols[$lib] = $future->resolveJSON();
     }
     $all_symbols = array();
     foreach ($symbols as $library => $map) {
         // Check for files which declare more than one class/interface in the same
         // file, or mix function definitions with class/interface definitions. We
         // must isolate autoloadable symbols to one per file so the autoloader
         // can't end up in an unresolvable cycle.
         foreach ($map as $file => $spec) {
             $have = idx($spec, 'have', array());
             $have_classes = idx($have, 'class', array()) + idx($have, 'interface', array());
             $have_functions = idx($have, 'function');
             if ($have_functions && $have_classes) {
                 $function_list = implode(', ', array_keys($have_functions));
                 $class_list = implode(', ', array_keys($have_classes));
                 $this->raiseLintInLibrary($library, $file, end($have_functions), self::LINT_ONE_CLASS_PER_FILE, "File '{$file}' mixes function ({$function_list}) and " . "class/interface ({$class_list}) definitions in the same file. " . "A file which declares a class or an interface MUST " . "declare nothing else.");
             } else {
                 if (count($have_classes) > 1) {
                     $class_list = implode(', ', array_keys($have_classes));
                     $this->raiseLintInLibrary($library, $file, end($have_classes), self::LINT_ONE_CLASS_PER_FILE, "File '{$file}' declares more than one class or interface " . "({$class_list}). A file which declares a class or interface MUST " . "declare nothing else.");
                 }
             }
         }
         // Check for duplicate symbols: two files providing the same class or
         // function.
         foreach ($map as $file => $spec) {
             $have = idx($spec, 'have', array());
             foreach (array('class', 'function', 'interface') as $type) {
                 $libtype = $type == 'interface' ? 'class' : $type;
                 foreach (idx($have, $type, array()) as $symbol => $offset) {
                     if (empty($all_symbols[$libtype][$symbol])) {
                         $all_symbols[$libtype][$symbol] = array('library' => $library, 'file' => $file, 'offset' => $offset);
                         continue;
                     }
                     $osrc = $all_symbols[$libtype][$symbol]['file'];
                     $olib = $all_symbols[$libtype][$symbol]['library'];
                     $this->raiseLintInLibrary($library, $file, $offset, self::LINT_DUPLICATE_SYMBOL, "Definition of {$type} '{$symbol}' in '{$file}' in library " . "'{$library}' duplicates prior definition in '{$osrc}' in " . "library '{$olib}'.");
                 }
             }
         }
     }
     foreach ($symbols as $library => $map) {
         // Check for unknown symbols: uses of classes, functions or interfaces
         // which are not defined anywhere. We reference the list of all symbols
         // we built up earlier.
         foreach ($map as $file => $spec) {
             $need = idx($spec, 'need', array());
             foreach (array('class', 'function', 'interface') as $type) {
                 $libtype = $type == 'interface' ? 'class' : $type;
                 foreach (idx($need, $type, array()) as $symbol => $offset) {
                     if (!empty($all_symbols[$libtype][$symbol])) {
                         // Symbol is defined somewhere.
                         continue;
                     }
                     $this->raiseLintInLibrary($library, $file, $offset, self::LINT_UNKNOWN_SYMBOL, "Use of unknown {$type} '{$symbol}'. This symbol is not defined " . "in any loaded phutil library.");
                 }
             }
         }
     }
 }
Exemplo n.º 3
0
 public static function newFromArcBundle($path)
 {
     $path = Filesystem::resolvePath($path);
     $future = new ExecFuture('tar tfO %s', $path);
     list($stdout, $file_list) = $future->resolvex();
     $file_list = explode("\n", trim($file_list));
     if (in_array('meta.json', $file_list)) {
         $future = new ExecFuture('tar xfO %s meta.json', $path);
         $meta_info = $future->resolveJSON();
         $version = idx($meta_info, 'version', 0);
         $project_name = idx($meta_info, 'projectName');
         $base_revision = idx($meta_info, 'baseRevision');
         $revision_id = idx($meta_info, 'revisionID');
         $encoding = idx($meta_info, 'encoding');
         $author_name = idx($meta_info, 'authorName');
         $author_email = idx($meta_info, 'authorEmail');
     } else {
         // this arc bundle was probably made before we started storing meta info
         $version = 0;
         $project_name = null;
         $base_revision = null;
         $revision_id = null;
         $encoding = null;
         $author = null;
     }
     $future = new ExecFuture('tar xfO %s changes.json', $path);
     $changes = $future->resolveJSON();
     foreach ($changes as $change_key => $change) {
         foreach ($change['hunks'] as $key => $hunk) {
             list($hunk_data) = execx('tar xfO %s hunks/%s', $path, $hunk['corpus']);
             $changes[$change_key]['hunks'][$key]['corpus'] = $hunk_data;
         }
     }
     foreach ($changes as $change_key => $change) {
         $changes[$change_key] = ArcanistDiffChange::newFromDictionary($change);
     }
     $obj = new ArcanistBundle();
     $obj->changes = $changes;
     $obj->diskPath = $path;
     $obj->setProjectID($project_name);
     $obj->setBaseRevision($base_revision);
     $obj->setRevisionID($revision_id);
     $obj->setEncoding($encoding);
     return $obj;
 }
Exemplo n.º 4
0
 private function liberateGetChangedPaths($path)
 {
     $mapper = $this->getPhutilMapperLocation();
     $future = new ExecFuture('%s %s --find-paths-for-liberate', $mapper, $path);
     return $future->resolveJSON();
 }