/** * Build graph from provided sources */ public function build() { $context = new Context(); $global = $context->time('compiler'); $timer = $context->time('compiler:parse'); $ast = (new ArrayTreeBuilder())->parse($this->buildRawArray($context)); $timer->stop(); // We have a "naked" AST with no business meaning whatsover, now we // need to process low level and meaningless transformations, such // as macro processing $context->setGraph($ast); // First, macro processing, this will deeply change the graph, so it // needs to happen first and alone, prior to anything else $timer = $context->time('compiler:macro'); $visitor = new Visitor(); $visitor->addProcessor(new MacroPass()); $visitor->execute($ast, $context); $timer->stop(); // Same goes for inheritance, it is business-free and low level $timer = $context->time('compiler:inheritance'); $visitor = new Visitor(); $visitor->addProcessor(new InheritancePass()); $visitor->execute($ast, $context); $timer->stop(); // Then, we need to have a business mean-something graph, so let's // apply path map conversion, so let's go! $timer = $context->time('compiler:conversion'); $visitor = new Visitor(); $visitor->addProcessor(new BusinessConversionPass()); $visitor->execute($ast, $context); $timer->stop(); // From this point, graph should not be modified anymore, which means // we can safely count nodes from this point $timer = $context->time('compiler:attributes'); $visitor = new Visitor(); $visitor->addProcessor(new CountPass()); $visitor->addProcessor(new ExpressionProcessor()); $visitor->addProcessor(new DrupalAttributesProcessor()); $visitor->execute($ast, $context); $timer->stop(); $global->stop(); return $context; }
/** * Extract meaningfull objects from the graph, and apply dependency sort * * @param Context $context * @param LoaderInterface[] $loaders */ protected function extractObjects(Context $context, array $loaders) { $dependencyMap = []; $timer = $context->time('loader:extract'); $visitor = new Visitor(); $visitor->addProcessor(function (NodeInterface $node, Context $context) use($loaders, &$dependencyMap) { $path = $node->getPath(); foreach ($loaders as $loader) { if ($loader->canProcess($node)) { $dependencyMap[$path] = []; foreach ($loader->getDependencies($node, $context) as $dependency) { $dependencyMap[$path][] = $dependency; } } } }); $visitor->execute($context->getGraph(), $context); $timer->stop(); return $this->resolveDependencies($dependencyMap, $context); }