modelRegistry = $modelRegistry; } public function __invoke(Analysis $analysis) { $modelsRegistered = []; foreach ($analysis->annotations as $annotation) { if ($annotation instanceof Response) { $annotationClass = Schema::class; } elseif ($annotation instanceof Parameter) { if ('array' === $annotation->type) { $annotationClass = Items::class; } else { $annotationClass = Schema::class; } } elseif ($annotation instanceof Schema) { $annotationClass = Items::class; } else { continue; } $model = null; foreach ($annotation->_unmerged as $unmerged) { if ($unmerged instanceof ModelAnnotation) { $model = $unmerged; break; } } if (null === $model || !$model instanceof ModelAnnotation) { continue; } if (!is_string($model->type)) { // Ignore invalid annotations, they are validated later continue; } $ref = $this->modelRegistry->register(new Model($this->createType($model->type), $model->groups)); $parts = explode('/', $ref); $modelsRegistered[end($parts)] = true; $annotation->merge([new $annotationClass([ 'ref' => $ref, ])]); // It is no longer an unmerged annotation foreach ($annotation->_unmerged as $key => $unmerged) { if ($unmerged === $model) { unset($annotation->_unmerged[$key]); break; } } $analysis->annotations->detach($model); } foreach ($modelsRegistered as $model => $v) { $analysis->annotations->attach(new Definition(['definition' => $model])); } } private function createType(string $type): Type { if ('[]' === substr($type, -2)) { return new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, null, $this->createType(substr($type, 0, -2))); } return new Type(Type::BUILTIN_TYPE_OBJECT, false, $type); } }