Skip to content

Commit

Permalink
POC: add support for immutable functions
Browse files Browse the repository at this point in the history
  • Loading branch information
theofidry committed May 18, 2017
1 parent d055e71 commit 3bb41ed
Show file tree
Hide file tree
Showing 18 changed files with 420 additions and 9 deletions.
8 changes: 8 additions & 0 deletions fixtures/Definition/Object/ImmutableByCloneObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ public function getInstance()
return $this->instance;
}

/**
* @inheritdoc
*/
public function withInstance($newInstance)
{
return new self($this->id, $newInstance);
}

public function __clone()
{
$this->instance = clone $this->instance;
Expand Down
8 changes: 8 additions & 0 deletions fixtures/Definition/Object/ImmutableObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,12 @@ public function getInstance()
{
return deep_clone($this->instance);
}

/**
* @inheritdoc
*/
public function withInstance($newInstance)
{
return new self($this->id, $newInstance);
}
}
8 changes: 8 additions & 0 deletions fixtures/Definition/Value/FakeObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,12 @@ public function getInstance()
{
$this->__call(__METHOD__, func_get_args());
}

/**
* @inheritdoc
*/
public function withInstance($newInstance)
{
$this->__call(__METHOD__, func_get_args());
}
}
34 changes: 34 additions & 0 deletions fixtures/Entity/DummyWithImmutableFunction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/*
* This file is part of the Alice package.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Nelmio\Alice\Entity;

class DummyWithImmutableFunction
{
private $val;

public function __construct(string $val)
{
$this->val = $val;
}

public function withVal(string $val): self
{
return new self($val);
}

public function getVal(): string
{
return $this->val;
}
}
27 changes: 27 additions & 0 deletions src/Definition/Flag/ConfiguratorFlag.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

/*
* This file is part of the Alice package.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Nelmio\Alice\Definition\Flag;

use Nelmio\Alice\Definition\FlagInterface;

final class ConfiguratorFlag implements FlagInterface
{
/**
* @inheritdoc
*/
public function __toString(): string
{
return 'configurator';
}
}
81 changes: 81 additions & 0 deletions src/Definition/MethodCall/ConfiguratorMethodCall.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

/*
* This file is part of the Alice package.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Nelmio\Alice\Definition\MethodCall;

use Nelmio\Alice\Definition\Flag\OptionalFlag;
use Nelmio\Alice\Definition\MethodCallInterface;

/**
* Represents a method call that is a configurator, i.e. for which the results should be kept.
*/
final class ConfiguratorMethodCall implements MethodCallInterface
{
/**
* @var MethodCallInterface
*/
private $methodCall;

public function __construct(MethodCallInterface $methodCall)
{
$this->methodCall = $methodCall;
}

/**
* @inheritdoc
*/
public function withArguments(array $arguments = null): self
{
$clone = clone $this;
$clone->methodCall = $clone->methodCall->withArguments($arguments);

return $clone;
}

/**
* @inheritdoc
*/
public function getCaller()
{
return $this->methodCall->getCaller();
}

/**
* @inheritdoc
*/
public function getMethod(): string
{
return $this->methodCall->getMethod();
}

/**
* @inheritdoc
*/
public function getArguments()
{
return $this->methodCall->getArguments();
}

public function getOriginalMethodCall(): MethodCallInterface
{
return $this->methodCall;
}

/**
* @inheritdoc
*/
public function __toString(): string
{
return $this->methodCall->__toString();
}
}
8 changes: 8 additions & 0 deletions src/Definition/Object/CompleteObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ public function getInstance()
return $this->object->getInstance();
}

/**
* @inheritdoc
*/
public function withInstance($newInstance)
{
throw new \LogicException('TODO');
}

public function __clone()
{
$this->object = clone $this->object;
Expand Down
4 changes: 1 addition & 3 deletions src/Definition/Object/SimpleObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,7 @@ public function __construct(string $id, $instance)
}

/**
* @param object $newInstance
*
* @return self
* @inheritdoc
*/
public function withInstance($newInstance): self
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

/*
* This file is part of the Alice package.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Nelmio\Alice\FixtureBuilder\Denormalizer\Fixture\SpecificationBagDenormalizer\Calls\MethodFlagHandler;

use Nelmio\Alice\Definition\Flag\ConfiguratorFlag;
use Nelmio\Alice\Definition\Flag\OptionalFlag;
use Nelmio\Alice\Definition\FlagInterface;
use Nelmio\Alice\Definition\MethodCall\ConfiguratorMethodCall;
use Nelmio\Alice\Definition\MethodCall\OptionalMethodCall;
use Nelmio\Alice\Definition\MethodCallInterface;
use Nelmio\Alice\FixtureBuilder\Denormalizer\Fixture\SpecificationBagDenormalizer\Calls\MethodFlagHandler;
use Nelmio\Alice\IsAServiceTrait;

final class ConfiguratorFlagHandler implements MethodFlagHandler
{
use IsAServiceTrait;

/**
* @inheritdoc
*/
public function handleMethodFlags(MethodCallInterface $methodCall, FlagInterface $flag): MethodCallInterface
{
if ($flag instanceof ConfiguratorFlag) {
return new ConfiguratorMethodCall($methodCall);
}

return $methodCall;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

/*
* This file is part of the Alice package.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Nelmio\Alice\FixtureBuilder\Denormalizer\FlagParser\Chainable;

use Nelmio\Alice\Definition\Flag\ConfiguratorFlag;
use Nelmio\Alice\Definition\Flag\UniqueFlag;
use Nelmio\Alice\Definition\FlagBag;
use Nelmio\Alice\FixtureBuilder\Denormalizer\FlagParser\ChainableFlagParserInterface;
use Nelmio\Alice\IsAServiceTrait;

final class ConfiguratorFlagParser implements ChainableFlagParserInterface
{
use IsAServiceTrait;

/**
* @inheritdoc
*/
public function canParse(string $element): bool
{
return 'configurator' === $element;
}

/**
* @inheritdoc
*/
public function parse(string $element): FlagBag
{
return (new FlagBag(''))->withFlag(new ConfiguratorFlag());
}
}
94 changes: 94 additions & 0 deletions src/Generator/Caller/Chainable/ConfiguratorMethodCallProcessor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

/*
* This file is part of the Alice package.
*
* (c) Nelmio <hello@nelm.io>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Nelmio\Alice\Generator\Caller\Chainable;

use Nelmio\Alice\Definition\MethodCall\ConfiguratorMethodCall;
use Nelmio\Alice\Definition\MethodCall\SimpleMethodCall;
use Nelmio\Alice\Definition\MethodCallInterface;
use Nelmio\Alice\Definition\Object\SimpleObject;
use Nelmio\Alice\Definition\ValueInterface;
use Nelmio\Alice\FixtureInterface;
use Nelmio\Alice\Generator\Caller\CallProcessorAwareInterface;
use Nelmio\Alice\Generator\Caller\CallProcessorInterface;
use Nelmio\Alice\Generator\Caller\ChainableCallProcessorInterface;
use Nelmio\Alice\Generator\CallerInterface;
use Nelmio\Alice\Generator\GenerationContext;
use Nelmio\Alice\Generator\ResolvedFixtureSet;
use Nelmio\Alice\Generator\ValueResolverAwareInterface;
use Nelmio\Alice\Generator\ValueResolverInterface;
use Nelmio\Alice\IsAServiceTrait;
use Nelmio\Alice\ObjectInterface;
use Nelmio\Alice\Throwable\Exception\Generator\Resolver\ResolverNotFoundExceptionFactory;
use Nelmio\Alice\Throwable\Exception\Generator\Resolver\UnresolvableValueDuringGenerationExceptionFactory;
use Nelmio\Alice\Throwable\InstantiationThrowable;
use Nelmio\Alice\Throwable\ResolutionThrowable;

final class ConfiguratorMethodCallProcessor implements ChainableCallProcessorInterface, CallProcessorAwareInterface
{
use IsAServiceTrait;

/**
* @var CallProcessorInterface|null
*/
private $processor;

public function __construct(CallProcessorInterface $processor = null)
{
$this->processor = $processor;
}

/**
* @inheritdoc
*/
public function withProcessor(CallProcessorInterface $processor): self
{
return new self($processor);
}

/**
* @inheritdoc
*/
public function canProcess(MethodCallInterface $methodCall): bool
{
return $methodCall instanceof ConfiguratorMethodCall;
}

/**
* @inheritdoc
*/
public function process(
ObjectInterface $object,
ResolvedFixtureSet $fixtureSet,
GenerationContext $context,
MethodCallInterface $methodCall
): ResolvedFixtureSet
{
if (null === $this->processor) {
throw new \LogicException('TODO');
}

$context->markRetrieveCallResult();

$fixtureSet = $this->processor->process(
$object,
$fixtureSet,
$context,
$methodCall->getOriginalMethodCall()
);

$context->unmarkRetrieveCallResult();

return $fixtureSet;
}
}
Loading

0 comments on commit 3bb41ed

Please sign in to comment.