Reduce complexity of package context

This commit is contained in:
Daniil Gentili 2020-08-09 16:23:01 +02:00
parent 6ca8ebe0c1
commit 3cd8d11ebf
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
7 changed files with 115 additions and 48 deletions

View File

@ -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.
*

View File

@ -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);
}
/**

View File

@ -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<SplQueue<Plugin>> */
return new \SplQueue;
}
if ($this->unlinkedNodes->count()) {

View File

@ -27,11 +27,11 @@ class Node
private string $name;
/**
* Associated package contexts.
* Associated package context.
*
* @var SplObjectStorage<PackageContext, void>
* @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<Node> */
$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) {

View File

@ -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.
*

View File

@ -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);
}
}

View File

@ -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.
*