public function parse(Project $project, $callback = null) { $step = 0; $steps = iterator_count($this->iterator); $context = $this->parser->getContext(); $transaction = new Transaction($project); $toStore = new \SplObjectStorage(); foreach ($this->iterator as $file) { ++$step; $code = file_get_contents($file); $hash = sha1($code); if ($transaction->hasHash($hash)) { continue; } $context->enterFile((string) $file, $hash); $this->parser->parse($code); if (null !== $callback) { call_user_func($callback, Message::PARSE_ERROR, $context->getErrors()); } foreach ($context->leaveFile() as $class) { if (null !== $callback) { call_user_func($callback, Message::PARSE_CLASS, array(floor($step / $steps * 100), $class)); } $project->addClass($class); $transaction->addClass($class); $toStore->attach($class); $class->notFromCache(); } } // cleanup foreach ($transaction->getRemovedClasses() as $class) { $project->removeClass(new LazyClassReflection($class)); $this->store->removeClass($project, $class); } // visit each class for stuff that can only be done when all classes are parsed $toStore->addAll($this->traverser->traverse($project)); foreach ($toStore as $class) { $this->store->writeClass($project, $class); } return $transaction; }