diff --git a/src/Plugin.php b/src/Plugin.php index ff501dd..7cde4b2 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -2,6 +2,7 @@ namespace Phabel; +use Phabel\PluginGraph\PackageContext; use PhpParser\Node; use PhpParser\Node\Arg; use PhpParser\Node\Expr; @@ -20,6 +21,10 @@ abstract class Plugin implements PluginInterface * Configuration array. */ private array $config = []; + /** + * Package context + */ + private PackageContext $ctx; /** * Set configuration array. * @@ -30,6 +35,48 @@ abstract class Plugin implements PluginInterface { $this->config = $config; } + /** + * Set package context + * + * @param PackageContext $ctx Ctx + * + * @return void + */ + public function setPackageContext(PackageContext $ctx): void + { + $this->ctx = $ctx; + } + /** + * Get package context + * + * @return PackageContext + */ + public function getPackageContext(): PackageContext + { + return $this->ctx; + } + /** + * Check if plugin should run + * + * @param string $package Package name + * + * @return boolean + */ + public function shouldRun(string $package): bool + { + return $this->ctx->has($package); + } + /** + * Check if plugin should run + * + * @param string $file File name + * + * @return boolean + */ + public function shouldRunFile(string $file): bool + { + return true; + } /** * Replace node of one type with another. * diff --git a/src/Plugin/Memoization.php b/src/Plugin/Memoization.php index 5527399..2f03f0b 100644 --- a/src/Plugin/Memoization.php +++ b/src/Plugin/Memoization.php @@ -122,7 +122,7 @@ class Memoization public function leaveFunctionLike(FunctionLike $fun): void { $this->cache->pop(); - \array_unshift($fun->stmts, $this->stmts->pop()); + $fun->stmts = \array_merge($this->stmts->pop(), $fun->stmts); } /** diff --git a/src/PluginGraph/GraphInternal.php b/src/PluginGraph/GraphInternal.php index a26dc06..fa2675d 100644 --- a/src/PluginGraph/GraphInternal.php +++ b/src/PluginGraph/GraphInternal.php @@ -59,12 +59,6 @@ class GraphInternal */ public function addPlugin(string $plugin, array $config, PackageContext $ctx): array { - if ($config === ['*']) { - if (isset($this->plugins[$plugin])) { - return \array_map(fn (Node $node) => $node->addPackageContext($ctx), $this->plugins[$plugin]); - } - $config = []; - } $configs = $plugin::splitConfig($config); $nodes = []; foreach ($configs as $config) { @@ -87,11 +81,11 @@ class GraphInternal { $configStr = \var_export($config, true); if (isset($this->plugins[$plugin][$configStr])) { - return $this->plugins[$plugin][$configStr]->addPackageContext($ctx); + return $this->plugins[$plugin][$configStr]; } - $this->plugins[$plugin][$configStr] = $node = new Node($this); + $this->plugins[$plugin][$configStr] = $node = new Node($this, $ctx); $this->unlinkedNodes->attach($node); - return $node->init($plugin, $config, $ctx); + return $node->init($plugin, $config); } /** @@ -115,6 +109,7 @@ class GraphInternal public function flatten(): \SplQueue { if (!$this->plugins) { + /** @var SplQueue> */ return new \SplQueue; } if ($this->unlinkedNodes->count()) { diff --git a/src/PluginGraph/Node.php b/src/PluginGraph/Node.php index 1f5d07a..fff1ceb 100644 --- a/src/PluginGraph/Node.php +++ b/src/PluginGraph/Node.php @@ -27,11 +27,11 @@ class Node private string $name; /** - * Associated package contexts. + * Associated package context. * - * @var SplObjectStorage + * @var PackageContext */ - private SplObjectStorage $packageContexts; + private PackageContext $packageContext; /** * Nodes that this node requires. * @@ -80,10 +80,10 @@ class Node * * @param GraphInternal $graph Graph instance */ - public function __construct(GraphInternal $graph) + public function __construct(GraphInternal $graph, PackageContext $ctx) { + $this->packageContext = $ctx; $this->graph = $graph; - $this->packageContexts = new SplObjectStorage; $this->requiredBy = new SplObjectStorage; $this->extendedBy = new SplObjectStorage; $this->requires = new SplObjectStorage; @@ -100,30 +100,29 @@ class Node * * @return self */ - public function init(string $plugin, array $config, PackageContext $ctx): self + public function init(string $plugin, array $config): self { $this->name = $plugin; $this->plugin = new Plugins($plugin, $config); - $this->packageContexts->attach($ctx); $this->canBeRequired = PluginCache::canBeRequired($plugin); foreach (PluginCache::runAfter($plugin) as $class => $config) { - foreach ($this->graph->addPlugin($class, $config, $ctx) as $node) { + foreach ($this->graph->addPlugin($class, $config, $this->packageContext) as $node) { $this->require($node); } } foreach (PluginCache::runBefore($plugin) as $class => $config) { - foreach ($this->graph->addPlugin($class, $config, $ctx) as $node) { + foreach ($this->graph->addPlugin($class, $config, $this->packageContext) as $node) { $node->require($this); } } foreach (PluginCache::runWithAfter($plugin) as $class => $config) { - foreach ($this->graph->addPlugin($class, $config, $ctx) as $node) { + foreach ($this->graph->addPlugin($class, $config, $this->packageContext) as $node) { $this->extend($node); } } foreach (PluginCache::runWithBefore($plugin) as $class => $config) { - foreach ($this->graph->addPlugin($class, $config, $ctx) as $node) { + foreach ($this->graph->addPlugin($class, $config, $this->packageContext) as $node) { $node->extend($this); } } @@ -171,28 +170,6 @@ class Node $this->graph->linkNode($this); } - /** - * Add package context. - * - * @param PackageContext $ctx Context - * - * @return self - */ - public function addPackageContext(PackageContext $ctx): self - { - if ($this->packageContexts->contains($ctx)) { - return $this; - } - $this->packageContexts->attach($ctx); - foreach ($this->requires as $node) { - $node->addPackageContext($ctx); - } - foreach ($this->extends as $node) { - $node->addPackageContext($ctx); - } - return $this; - } - /** * Merge node with another node. * @@ -202,6 +179,7 @@ class Node */ public function merge(self $other): Node { + $this->packageContext->merge($other->packageContext); $this->plugin->merge($other->plugin); foreach ($other->requiredBy as $node) { $node->require($this); @@ -234,7 +212,7 @@ class Node return $queue; } /** - * Look for circular references. + * Look for circular references, while merging package contexts. * * @return self */ @@ -253,10 +231,10 @@ class Node $this->visitedCircular = true; foreach ($this->requiredBy as $node) { - $node->circular(); + $this->packageContext->merge($node->circular()->packageContext); } foreach ($this->extendedBy as $node) { - $node->circular(); + $this->packageContext->merge($node->circular()->packageContext); } $this->visitedCircular = false; @@ -273,7 +251,7 @@ class Node private function flattenInternal(SplQueue $splQueue): void { $queue = $splQueue->top(); - $this->plugin->enqueue($queue); + $this->plugin->enqueue($queue, $this->packageContext); /** @var SplQueue */ $extendedBy = new SplQueue; @@ -309,6 +287,8 @@ class Node $requiredBy->enqueue($prevNode); } + + foreach ($extendedBy as $node) { $node->extends->detach($this); if (\count($node->extends) + \count($node->requires) === 0) { diff --git a/src/PluginGraph/PackageContext.php b/src/PluginGraph/PackageContext.php index 2255dd6..e7d2b02 100644 --- a/src/PluginGraph/PackageContext.php +++ b/src/PluginGraph/PackageContext.php @@ -37,6 +37,18 @@ class PackageContext return $this; } + /** + * Check if a package is present in the package context + * + * @param string $package Package + * + * @return boolean + */ + public function has(string $package): bool + { + return isset($this->packages[$package]); + } + /** * Get package list. * diff --git a/src/PluginGraph/Plugins.php b/src/PluginGraph/Plugins.php index e368efc..ab37534 100644 --- a/src/PluginGraph/Plugins.php +++ b/src/PluginGraph/Plugins.php @@ -53,12 +53,13 @@ class Plugins * * @return void */ - public function enqueue(SplQueue $queue): void + public function enqueue(SplQueue $queue, PackageContext $ctx): void { foreach ($this->plugins as $plugin => $configs) { foreach ($plugin::mergeConfigs(...$configs) as $config) { $pluginObj = new $plugin; $pluginObj->setConfigArray($config); + $pluginObj->setPackageContext($ctx); $queue->enqueue($pluginObj); } } diff --git a/src/PluginInterface.php b/src/PluginInterface.php index d889656..6451236 100644 --- a/src/PluginInterface.php +++ b/src/PluginInterface.php @@ -2,6 +2,8 @@ namespace Phabel; +use Phabel\PluginGraph\PackageContext; + interface PluginInterface { /** @@ -59,6 +61,36 @@ interface PluginInterface * @return void */ public function setConfigArray(array $config): void; + /** + * Set package context + * + * @param PackageContext $ctx Ctx + * + * @return void + */ + public function setPackageContext(PackageContext $ctx): void; + /** + * Get package context + * + * @return PackageContext + */ + public function getPackageContext(): PackageContext; + /** + * Check if plugin should run + * + * @param string $package Package name + * + * @return boolean + */ + public function shouldRun(string $package): bool; + /** + * Check if plugin should run + * + * @param string $file File name + * + * @return boolean + */ + public function shouldRunFile(string $file): bool; /** * Get configuration key. *