diff --git a/src/MutableConfigurable.php b/src/MutableConfigurable.php new file mode 100644 index 0000000..ecf3cb2 --- /dev/null +++ b/src/MutableConfigurable.php @@ -0,0 +1,44 @@ +State = $StateBearer->state(); + $this->State = $StateBearer->state()->isolatedCopy(); } /** @@ -42,7 +42,7 @@ final class Parsedown { list($StateRenderables, $State) = self::lines( Lines::fromTextLines($markdown, 0), - $this->State + $this->State->isolatedCopy() ); $Renderables = $State->applyTo($StateRenderables); diff --git a/src/State.php b/src/State.php index 4ca3eb2..b48d401 100644 --- a/src/State.php +++ b/src/State.php @@ -15,7 +15,7 @@ final class State implements StateBearer /** * @var array, Configurable> */ - private static $initialCache; + private static $initialCache = []; /** * @param Configurable[] $Configurables @@ -56,6 +56,22 @@ final class State implements StateBearer */ public function get($className) { + if ( + ! isset($this->state[$className]) + && \is_subclass_of($className, MutableConfigurable::class, true) + ) { + if (! isset(self::$initialCache[$className])) { + /** @var T */ + self::$initialCache[$className] = $className::initial(); + } + + /** + * @var T + * @psalm-suppress PossiblyUndefinedMethod + */ + $this->state[$className] = self::$initialCache[$className]->isolatedCopy(); + } + /** @var T */ return ( $this->state[$className] @@ -93,4 +109,14 @@ final class State implements StateBearer { return $this; } + + public function isolatedCopy(): self + { + return new self(\array_map( + function ($C) { + return $C instanceof MutableConfigurable ? $C->isolatedCopy() : $C; + }, + $this->state + )); + } }