Skip to content

Commit

Permalink
Merge annotation _aux property with context generated (#1333)
Browse files Browse the repository at this point in the history
  • Loading branch information
DerManoMann authored Oct 27, 2022
1 parent 9a8b960 commit a69d91d
Show file tree
Hide file tree
Showing 13 changed files with 58 additions and 69 deletions.
2 changes: 1 addition & 1 deletion src/Analysis.php
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ public function getSchemaForSource(string $fqdn): ?OA\Schema
$definition = $definitions[$fqdn];
if (is_iterable($definition['context']->annotations)) {
foreach (array_reverse($definition['context']->annotations) as $annotation) {
if (in_array(get_class($annotation), [OA\Schema::class, OAT\Schema::class]) && !$annotation->_aux) {
if (in_array(get_class($annotation), [OA\Schema::class, OAT\Schema::class]) && !$annotation->_context->is('generated')) {
return $annotation;
}
}
Expand Down
89 changes: 43 additions & 46 deletions src/Annotations/AbstractAnnotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ abstract class AbstractAnnotation implements \JsonSerializable
*/
public $attachables = Generator::UNDEFINED;

/**
* @var bool
*/
public $_aux = false;

/**
* @var Context|null
*/
Expand Down Expand Up @@ -94,7 +89,7 @@ abstract class AbstractAnnotation implements \JsonSerializable
*
* @var array<string>
*/
public static $_blacklist = ['_context', '_unmerged', '_analysis', '_aux', 'attachables'];
public static $_blacklist = ['_context', '_unmerged', '_analysis', 'attachables'];

public function __construct(array $properties)
{
Expand All @@ -115,16 +110,16 @@ public function __construct(array $properties)
$nestedContext = new Context(['nested' => $this], $this->_context);
foreach ($properties as $property => $value) {
if (property_exists($this, $property)) {
$this->$property = $value;
$this->{$property} = $value;
if (is_array($value)) {
foreach ($value as $key => $annotation) {
if (is_object($annotation) && $annotation instanceof AbstractAnnotation) {
$this->$property[$key] = $this->nested($annotation, $nestedContext);
if ($annotation instanceof AbstractAnnotation) {
$this->{$property}[$key] = $this->nested($annotation, $nestedContext);
}
}
}
} elseif ($property !== 'value') {
$this->$property = $value;
$this->{$property} = $value;
} elseif (is_array($value)) {
$annotations = [];
foreach ($value as $annotation) {
Expand Down Expand Up @@ -170,7 +165,7 @@ public function __set(string $property, $value): void
unset($fields[$_property]);
}
$this->_context->logger->warning('Unexpected field "' . $property . '" for ' . $this->identity() . ', expecting "' . implode('", "', array_keys($fields)) . '" in ' . $this->_context);
$this->$property = $value;
$this->{$property} = $value;
}

/**
Expand All @@ -194,14 +189,14 @@ public function merge(array $annotations, bool $ignore = false): array
$property = $details->value;
if (is_array($property)) {
$property = $property[0];
if (Generator::isDefault($this->$property)) {
$this->$property = [];
if (Generator::isDefault($this->{$property})) {
$this->{$property} = [];
}
$this->$property[] = $this->nested($annotation, $nestedContext);
$this->{$property}[] = $this->nested($annotation, $nestedContext);
$mapped = true;
} elseif (Generator::isDefault($this->$property)) {
} elseif (Generator::isDefault($this->{$property})) {
// ignore duplicate nested if only one expected
$this->$property = $this->nested($annotation, $nestedContext);
$this->{$property} = $this->nested($annotation, $nestedContext);
$mapped = true;
}
}
Expand Down Expand Up @@ -233,7 +228,7 @@ public function mergeProperties($object): void
continue;
}
if ($currentValues[$property] === $defaultValues[$property]) { // Overwrite default values
$this->$property = $value;
$this->{$property} = $value;
continue;
}
if ($property === '_unmerged') {
Expand All @@ -247,8 +242,8 @@ public function mergeProperties($object): void
$identity = method_exists($object, 'identity') ? $object->identity() : get_class($object);
$context1 = $this->_context;
$context2 = property_exists($object, '_context') ? $object->_context : 'unknown';
if (is_object($this->$property) && $this->{$property} instanceof AbstractAnnotation) {
$context1 = $this->$property->_context;
if (is_object($this->{$property}) && $this->{$property} instanceof AbstractAnnotation) {
$context1 = $this->{$property}->_context;
}
$this->_context->logger->error('Multiple definitions for ' . $identity . '->' . $property . "\n Using: " . $context1 . "\n Skipping: " . $context2);
}
Expand Down Expand Up @@ -302,19 +297,19 @@ public function jsonSerialize()
// Strip undefined values.
foreach (get_object_vars($this) as $property => $value) {
if (!Generator::isDefault($value)) {
$data->$property = $value;
$data->{$property} = $value;
}
}

// Strip properties that are for internal (swagger-php) use.
foreach (static::$_blacklist as $property) {
unset($data->$property);
unset($data->{$property});
}

// Correct empty array to empty objects.
foreach (static::$_types as $property => $type) {
if ($type === 'object' && is_array($data->$property) && empty($data->$property)) {
$data->$property = new \stdClass();
if ($type === 'object' && is_array($data->{$property}) && empty($data->{$property})) {
$data->{$property} = new \stdClass();
}
}

Expand All @@ -323,7 +318,7 @@ public function jsonSerialize()
if (is_array($this->x)) {
foreach ($this->x as $property => $value) {
$prefixed = 'x-' . $property;
$data->$prefixed = $value;
$data->{$prefixed} = $value;
}
}

Expand All @@ -333,27 +328,27 @@ public function jsonSerialize()
continue;
}
$property = $nested[0];
if (Generator::isDefault($this->$property)) {
if (Generator::isDefault($this->{$property})) {
continue;
}
$keyField = $nested[1];
$object = new \stdClass();
foreach ($this->$property as $key => $item) {
foreach ($this->{$property} as $key => $item) {
if (is_numeric($key) === false && is_array($item)) {
$object->$key = $item;
$object->{$key} = $item;
} else {
$key = $item->$keyField;
if (!Generator::isDefault($key) && empty($object->$key)) {
$key = $item->{$keyField};
if (!Generator::isDefault($key) && empty($object->{$key})) {
if ($item instanceof \JsonSerializable) {
$object->$key = $item->jsonSerialize();
$object->{$key} = $item->jsonSerialize();
} else {
$object->$key = $item;
$object->{$key} = $item;
}
unset($object->$key->$keyField);
unset($object->{$key}->{$keyField});
}
}
}
$data->$property = $object;
$data->{$property} = $object;
}

// $ref
Expand All @@ -364,8 +359,8 @@ public function jsonSerialize()
$defaultValues = get_class_vars(get_class($this));
foreach (['summary', 'description'] as $prop) {
if (property_exists($this, $prop)) {
if ($this->$prop !== $defaultValues[$prop]) {
$ref[$prop] = $data->$prop;
if ($this->{$prop} !== $defaultValues[$prop]) {
$ref[$prop] = $data->{$prop};
}
}
}
Expand Down Expand Up @@ -409,13 +404,14 @@ public function validate(array $stack = [], array $skip = [], string $ref = '',
break;
}

/** @var class-string<AbstractAnnotation> $class */
$class = get_class($annotation);
if ($details = static::matchNested($class)) {
$property = $details->value;
if (is_array($property)) {
$this->_context->logger->warning('Only one ' . Util::shorten(get_class($annotation)) . '() allowed for ' . $this->identity() . ' multiple found, skipped: ' . $annotation->_context);
} else {
$this->_context->logger->warning('Only one ' . Util::shorten(get_class($annotation)) . '() allowed for ' . $this->identity() . " multiple found in:\n Using: " . $this->$property->_context . "\n Skipped: " . $annotation->_context);
$this->_context->logger->warning('Only one ' . Util::shorten(get_class($annotation)) . '() allowed for ' . $this->identity() . " multiple found in:\n Using: " . $this->{$property}->_context . "\n Skipped: " . $annotation->_context);
}
} elseif ($annotation instanceof AbstractAnnotation) {
$message = 'Unexpected ' . $annotation->identity();
Expand All @@ -433,26 +429,26 @@ public function validate(array $stack = [], array $skip = [], string $ref = '',
continue;
}
$property = $nested[0];
if (Generator::isDefault($this->$property)) {
if (Generator::isDefault($this->{$property})) {
continue;
}
$keys = [];
$keyField = $nested[1];
foreach ($this->$property as $key => $item) {
foreach ($this->{$property} as $key => $item) {
if (is_array($item) && is_numeric($key) === false) {
$this->_context->logger->warning($this->identity() . '->' . $property . ' is an object literal, use nested ' . Util::shorten($annotationClass) . '() annotation(s) in ' . $this->_context);
$keys[$key] = $item;
} elseif (Generator::isDefault($item->$keyField)) {
} elseif (Generator::isDefault($item->{$keyField})) {
$this->_context->logger->error($item->identity() . ' is missing key-field: "' . $keyField . '" in ' . $item->_context);
} elseif (isset($keys[$item->$keyField])) {
$this->_context->logger->error('Multiple ' . $item->_identity([]) . ' with the same ' . $keyField . '="' . $item->$keyField . "\":\n " . $item->_context . "\n " . $keys[$item->$keyField]->_context);
} elseif (isset($keys[$item->{$keyField}])) {
$this->_context->logger->error('Multiple ' . $item->_identity([]) . ' with the same ' . $keyField . '="' . $item->{$keyField} . "\":\n " . $item->_context . "\n " . $keys[$item->{$keyField}]->_context);
} else {
$keys[$item->$keyField] = $item;
$keys[$item->{$keyField}] = $item;
}
}
}

if (property_exists($this, 'ref') && !Generator::isDefault($this->ref) && $this->ref !== null) {
if (property_exists($this, 'ref') && !Generator::isDefault($this->ref) && is_string($this->ref)) {
if (substr($this->ref, 0, 2) === '#/' && count($stack) > 0 && $stack[0] instanceof OpenApi) {
// Internal reference
try {
Expand All @@ -464,7 +460,7 @@ public function validate(array $stack = [], array $skip = [], string $ref = '',
} else {
// Report missing required fields (when not a $ref)
foreach (static::$_required as $property) {
if (Generator::isDefault($this->$property)) {
if (Generator::isDefault($this->{$property})) {
$message = 'Missing required field "' . $property . '" for ' . $this->identity() . ' in ' . $this->_context;
foreach (static::$_nested as $class => $nested) {
$nestedProperty = is_array($nested) ? $nested[0] : $nested;
Expand All @@ -486,7 +482,7 @@ public function validate(array $stack = [], array $skip = [], string $ref = '',

// Report invalid types
foreach (static::$_types as $property => $type) {
$value = $this->$property;
$value = $this->{$property};
if (Generator::isDefault($value) || $value === null) {
continue;
}
Expand Down Expand Up @@ -554,6 +550,7 @@ public function identity(): string
{
$class = get_class($this);
$properties = [];
/** @var class-string<AbstractAnnotation> $parent */
foreach (static::$_parents as $parent) {
foreach ($parent::$_nested as $annotationClass => $entry) {
if ($annotationClass === $class && is_array($entry) && !Generator::isDefault($this->{$entry[1]})) {
Expand Down Expand Up @@ -597,7 +594,7 @@ protected function _identity(array $properties): string
{
$fields = [];
foreach ($properties as $property) {
$value = $this->$property;
$value = $this->{$property};
if ($value !== null && !Generator::isDefault($value)) {
$fields[] = $property . '=' . (is_string($value) ? '"' . $value . '"' : $value);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Annotations/OpenApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ private static function resolveRef(string $ref, string $resolved, $container, ar
}
foreach ($mapping as $nestedClass => $keyField) {
foreach ($container as $key => $item) {
if (is_numeric($key) && is_object($item) && $item instanceof $nestedClass && (string) $item->$keyField === $property) {
if (is_numeric($key) && is_object($item) && $item instanceof $nestedClass && (string) $item->{$keyField} === $property) {
return self::resolveRef($ref, $unresolved, $item, []);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Context
public function __construct(array $properties = [], ?Context $parent = null)
{
foreach ($properties as $property => $value) {
$this->$property = $value;
$this->{$property} = $value;
}
$this->parent = $parent;

Expand Down Expand Up @@ -166,7 +166,7 @@ public function getDebugLocation(): string
public function __get(string $property)
{
if ($this->parent !== null) {
return $this->parent->$property;
return $this->parent->{$property};
}

return null;
Expand Down
7 changes: 2 additions & 5 deletions src/Processors/AugmentProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,7 @@ protected function augmentType(Analysis $analysis, OA\Property $property, Contex
$property->oneOf = [
$schema = new OA\Schema([
'ref' => $refs[$refKey],
'_context' => $property->_context,
'_aux' => true,
'_context' => new Context(['generated' => true], $property->_context),
]),
];
$analysis->addAnnotation($schema, $schema->_context);
Expand All @@ -114,7 +113,6 @@ protected function augmentType(Analysis $analysis, OA\Property $property, Contex
[
'type' => $property->type,
'_context' => new Context(['generated' => true], $context),
'_aux' => true,
]
);
$analysis->addAnnotation($items, $items->_context);
Expand Down Expand Up @@ -182,8 +180,7 @@ protected function applyRef(Analysis $analysis, OA\Property $property, string $r
$property->oneOf = [
$schema = new OA\Schema([
'ref' => $ref,
'_context' => $property->_context,
'_aux' => true,
'_context' => new Context(['generated' => true], $property->_context),
]),
];
$analysis->addAnnotation($schema, $schema->_context);
Expand Down
7 changes: 3 additions & 4 deletions src/Processors/AugmentSchemas.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use OpenApi\Analysis;
use OpenApi\Annotations as OA;
use OpenApi\Context;
use OpenApi\Generator;

/**
Expand Down Expand Up @@ -68,8 +69,7 @@ public function __invoke(Analysis $analysis)

if ($schema === null) {
$schema = new OA\Schema([
'_context' => $annotation->_context,
'_aux' => true,
'_context' => new Context(['generated' => true], $annotation->_context),
]);
$analysis->addAnnotation($schema, $schema->_context);
$annotation->allOf[] = $schema;
Expand Down Expand Up @@ -121,8 +121,7 @@ public function __invoke(Analysis $analysis)
if (!$allOfPropertiesSchema) {
$allOfPropertiesSchema = new OA\Schema([
'properties' => [],
'_context' => $schema->_context,
'_aux' => true,
'_context' => new Context(['generated' => true], $schema->_context),
]);
$analysis->addAnnotation($allOfPropertiesSchema, $allOfPropertiesSchema->_context);
$schema->allOf[] = $allOfPropertiesSchema;
Expand Down
1 change: 0 additions & 1 deletion src/Processors/BuildPaths.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ public function __invoke(Analysis $analysis)
[
'path' => $operation->path,
'_context' => new Context(['generated' => true], $operation->_context),
'_aux' => true,
]
);
$analysis->addAnnotation($pathItem, $pathItem->_context);
Expand Down
3 changes: 1 addition & 2 deletions src/Processors/Concerns/MergeTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ protected function inheritFrom(Analysis $analysis, OA\Schema $schema, OA\Schema
// merging other properties into allOf is done in the AugmentSchemas processor
$schema->allOf[] = $refSchema = new OA\Schema([
'ref' => OA\Components::ref($refPath),
'_context' => $context,
'_aux' => true,
'_context' => new Context(['generated' => true], $context),
]);
$analysis->addAnnotation($refSchema, $refSchema->_context);
}
Expand Down
1 change: 0 additions & 1 deletion src/Processors/MergeJsonContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public function __invoke(Analysis $analysis)
'example' => $jsonContent->example,
'examples' => $jsonContent->examples,
'_context' => new Context(['generated' => true], $jsonContent->_context),
'_aux' => true,
]);
$analysis->addAnnotation($mediaType, $mediaType->_context);
if (!$parent instanceof OA\Parameter) {
Expand Down
1 change: 0 additions & 1 deletion src/Processors/MergeXmlContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ public function __invoke(Analysis $analysis)
'example' => $xmlContent->example,
'examples' => $xmlContent->examples,
'_context' => new Context(['generated' => true], $xmlContent->_context),
'_aux' => true,
]);
$analysis->addAnnotation($mediaType, $mediaType->_context);
if (!$parent instanceof OA\Parameter) {
Expand Down
Loading

0 comments on commit a69d91d

Please sign in to comment.