From 256d42cb07ba1c2206d66bc7516ee3d3e3e9f0b2 Mon Sep 17 00:00:00 2001 From: Martin Rademacher Date: Fri, 3 May 2024 09:36:00 +1200 Subject: [PATCH] Ensure all annotations added to `Analysis` have a root context (#1586) --- src/Analysis.php | 4 ++-- src/Annotations/AbstractAnnotation.php | 2 +- src/Context.php | 24 ++++++++++++++++++++++-- src/Generator.php | 2 ++ tests/ContextTest.php | 18 ++++++++++++++++++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/src/Analysis.php b/src/Analysis.php index 85b506ba4..6ba3a081d 100644 --- a/src/Analysis.php +++ b/src/Analysis.php @@ -72,12 +72,12 @@ public function __construct(array $annotations = [], ?Context $context = null) public function addAnnotation(object $annotation, Context $context): void { - assert(!Generator::isDefault($context->version)); - if ($this->annotations->contains($annotation)) { return; } + $context->ensureRoot($this->context); + if ($annotation instanceof OA\OpenApi) { $this->openapi = $this->openapi ?: $annotation; } else { diff --git a/src/Annotations/AbstractAnnotation.php b/src/Annotations/AbstractAnnotation.php index 822ede8a3..c9bf2f322 100644 --- a/src/Annotations/AbstractAnnotation.php +++ b/src/Annotations/AbstractAnnotation.php @@ -100,7 +100,7 @@ public function __construct(array $properties) } elseif (Generator::$context) { $this->_context = Generator::$context; } else { - $this->_context = Context::detect(1); + $this->_context = new Context(['generated' => true]); } if ($this->_context->is('annotations') === false) { diff --git a/src/Context.php b/src/Context.php index aae2f014b..6fcffcfd1 100644 --- a/src/Context.php +++ b/src/Context.php @@ -51,6 +51,9 @@ class Context */ private $parent; + /** + * @deprecated + */ public function clone() { return new Context(get_object_vars($this), $this->parent); @@ -70,6 +73,25 @@ public function __construct(array $properties = [], ?Context $parent = null) } } + /** + * Ensure this context is part of the context tree. + */ + public function ensureRoot(?Context $rootContext): void + { + if ($rootContext === $this) { + return; + } + + if (!$this->parent) { + // use root fallback for these... + foreach (['logger', 'version'] as $property) { + unset($this->{$property}); + } + + $this->parent = $rootContext; + } + } + /** * Check if a property is set directly on this context and not its parent context. * @@ -194,8 +216,6 @@ public function __debugInfo() */ public static function detect(int $index = 0): Context { - trigger_deprecation('zircote/swagger-php', '4.9', 'Context detecting is deprecated'); - $context = new Context(); $backtrace = debug_backtrace(); $position = $backtrace[$index]; diff --git a/src/Generator.php b/src/Generator.php index b399600ee..fb6ae3623 100644 --- a/src/Generator.php +++ b/src/Generator.php @@ -446,7 +446,9 @@ public function generate(iterable $sources, ?Analysis $analysis = null, bool $va 'version' => $this->getVersion(), 'logger' => $this->getLogger(), ]); + $analysis = $analysis ?: new Analysis([], $rootContext); + $analysis->context = $analysis->context ?: $rootContext; $this->configStack->push($this); try { diff --git a/tests/ContextTest.php b/tests/ContextTest.php index 4604b8679..229ee243a 100644 --- a/tests/ContextTest.php +++ b/tests/ContextTest.php @@ -6,9 +6,11 @@ namespace OpenApi\Tests; +use OpenApi\Annotations as OA; use OpenApi\Analysers\TokenAnalyser; use OpenApi\Context; use OpenApi\Generator; +use Psr\Log\NullLogger; class ContextTest extends OpenApiTestCase { @@ -43,4 +45,20 @@ public function testFullyQualifiedName(): void $this->assertSame('\\OpenApi\\Generator', $context->fullyQualifiedName('OpenApiGenerator')); $this->assertSame('\\OpenApi\\Annotations\\QualifiedAlias', $context->fullyQualifiedName('OA\\QualifiedAlias')); } + + public function testEnsureRoot(): void + { + $root = new Context(['logger' => new NullLogger(), 'version' => OA\OpenApi::VERSION_3_1_0]); + $context = new Context(['logger' => $this->getTrackingLogger()]); + + // assert defaults set + $this->assertNotInstanceOf(NullLogger::class, $context->logger); + $this->assertEquals(OA\OpenApi::VERSION_3_0_0, $context->version); + + $context->ensureRoot($root); + + // assert inheriting from root + $this->assertInstanceOf(NullLogger::class, $context->logger); + $this->assertEquals(OA\OpenApi::VERSION_3_1_0, $context->version); + } }