Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion phpstan.dist.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ includes:
- vendor/phpstan/phpstan-strict-rules/rules.neon

parameters:
level: 9
level: 10
paths:
- src
tmpDir: .phpstan-cache
checkBenevolentUnionTypes: true
1 change: 1 addition & 0 deletions rector.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
instanceOf: true,
earlyReturn: true,
strictBooleans: true,
naming: true,
)
->withFluentCallNewLine();
24 changes: 12 additions & 12 deletions src/Converters/ClassConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ public function __construct(

public function convert(): ObjectSchema
{
$schema = new ObjectSchema();
$objectSchema = new ObjectSchema();

// Get the description from the doc parser
$description = $this->getDocParser($this->reflection)?->description() ?? null;

// Add the description to the schema if it exists
if ($description !== null) {
$schema->description($description);
$objectSchema->description($description);
}

$properties = $this->reflection->getProperties(
Expand All @@ -52,26 +52,26 @@ public function convert(): ObjectSchema

// Add the properties to the object schema
foreach ($properties as $property) {
$schema->properties(self::getSchemaFromReflectionProperty($property));
$objectSchema->properties(self::getSchemaFromReflectionProperty($property));
}

return $schema;
return $objectSchema;
}

/**
* Create a schema from a given type.
*/
protected function getSchemaFromReflectionProperty(
ReflectionProperty $property,
ReflectionProperty $reflectionProperty,
): Schema {
$type = $property->getType();
$type = $reflectionProperty->getType();

// @phpstan-ignore argument.type
$schema = self::getSchemaFromReflectionType($type);

$schema->title($property->getName());
$schema->title($reflectionProperty->getName());

$variable = $this->getDocParser($property)?->variable();
$variable = $this->getDocParser($reflectionProperty)?->variable();

// Add the description to the schema if it exists
if ($variable?->description !== null) {
Expand All @@ -82,8 +82,8 @@ protected function getSchemaFromReflectionProperty(
$schema->nullable();
}

if ($property->hasDefaultValue()) {
$defaultValue = $property->getDefaultValue();
if ($reflectionProperty->hasDefaultValue()) {
$defaultValue = $reflectionProperty->getDefaultValue();

// If the default value is a backed enum, use its value
if ($defaultValue instanceof BackedEnum) {
Expand All @@ -100,9 +100,9 @@ protected function getSchemaFromReflectionProperty(
$typeName = $type->getName();

if (enum_exists($typeName)) {
$reflection = new ReflectionEnum($typeName);
$reflectionEnum = new ReflectionEnum($typeName);

if ($reflection->isBacked()) {
if ($reflectionEnum->isBacked()) {
/** @var non-empty-array<int, string|int> $values */
$values = array_column($typeName::cases(), 'value');
$schema->enum($values);
Expand Down
30 changes: 15 additions & 15 deletions src/Converters/ClosureConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,44 +31,44 @@ public function __construct(

public function convert(): ObjectSchema
{
$schema = new ObjectSchema();
$objectSchema = new ObjectSchema();

// Get the description from the doc parser
$description = $this->getDocParser()?->description() ?? null;

// Add the description to the schema if it exists
if ($description !== null) {
$schema->description($description);
$objectSchema->description($description);
}

// Get the parameters from the doc parser
$params = $this->getDocParser()?->params();

// Add the parameters to the objectschema
foreach ($this->reflection->getParameters() as $parameter) {
$schema->properties(self::getSchemaFromReflectionParameter($parameter, $params));
$objectSchema->properties(self::getSchemaFromReflectionParameter($parameter, $params));
}

return $schema;
return $objectSchema;
}

/**
* Create a schema from a given type.
*
* @param \Cortex\JsonSchema\Support\NodeCollection<array-key, \Cortex\JsonSchema\Support\NodeData> $docParams
* @param \Cortex\JsonSchema\Support\NodeCollection<array-key, \Cortex\JsonSchema\Support\NodeData> $nodeCollection
*/
protected function getSchemaFromReflectionParameter(
ReflectionParameter $parameter,
?NodeCollection $docParams = null,
ReflectionParameter $reflectionParameter,
?NodeCollection $nodeCollection = null,
): Schema {
$type = $parameter->getType();
$type = $reflectionParameter->getType();

// @phpstan-ignore argument.type
$schema = self::getSchemaFromReflectionType($type);

$schema->title($parameter->getName());
$schema->title($reflectionParameter->getName());

$docParam = $docParams?->get($parameter->getName());
$docParam = $nodeCollection?->get($reflectionParameter->getName());

// Add the description to the schema if it exists
if ($docParam?->description !== null) {
Expand All @@ -79,8 +79,8 @@ protected function getSchemaFromReflectionParameter(
$schema->nullable();
}

if ($parameter->isDefaultValueAvailable() && ! $parameter->isDefaultValueConstant()) {
$defaultValue = $parameter->getDefaultValue();
if ($reflectionParameter->isDefaultValueAvailable() && ! $reflectionParameter->isDefaultValueConstant()) {
$defaultValue = $reflectionParameter->getDefaultValue();

// If the default value is a backed enum, use its value
if ($defaultValue instanceof BackedEnum) {
Expand All @@ -90,7 +90,7 @@ protected function getSchemaFromReflectionParameter(
$schema->default($defaultValue);
}

if (! $parameter->isOptional()) {
if (! $reflectionParameter->isOptional()) {
$schema->required();
}

Expand All @@ -99,9 +99,9 @@ protected function getSchemaFromReflectionParameter(
$typeName = $type->getName();

if (enum_exists($typeName)) {
$reflection = new ReflectionEnum($typeName);
$reflectionEnum = new ReflectionEnum($typeName);

if ($reflection->isBacked()) {
if ($reflectionEnum->isBacked()) {
/** @var non-empty-array<int, string|int> $values */
$values = array_column($typeName::cases(), 'value');
$schema->enum($values);
Expand Down
14 changes: 8 additions & 6 deletions src/Converters/Concerns/InteractsWithTypes.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ protected static function getSchemaFromReflectionType(
$schemaTypes = match (true) {
$type instanceof ReflectionUnionType, $type instanceof ReflectionIntersectionType => array_map(
// @phpstan-ignore argument.type
fn(ReflectionNamedType $t): SchemaType => self::resolveSchemaType($t),
fn(ReflectionNamedType $reflectionNamedType): SchemaType => self::resolveSchemaType(
$reflectionNamedType,
),
$type->getTypes(),
),
// If the parameter is not typed or explicitly typed as mixed, we use all schema types
Expand All @@ -40,16 +42,16 @@ protected static function getSchemaFromReflectionType(
/**
* Resolve the schema type from the given reflection type.
*/
protected static function resolveSchemaType(ReflectionNamedType $type): SchemaType
protected static function resolveSchemaType(ReflectionNamedType $reflectionNamedType): SchemaType
{
$typeName = $type->getName();
$typeName = $reflectionNamedType->getName();

if (enum_exists($typeName)) {
$reflection = new ReflectionEnum($typeName);
$typeName = $reflection->getBackingType()?->getName();
$reflectionEnum = new ReflectionEnum($typeName);
$typeName = $reflectionEnum->getBackingType()?->getName();

if ($typeName === null) {
throw new SchemaException('Enum type has no backing type: ' . $reflection->getName());
throw new SchemaException('Enum type has no backing type: ' . $reflectionEnum->getName());
}
}

Expand Down
19 changes: 12 additions & 7 deletions src/Exceptions/SchemaException.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ class SchemaException extends Exception
{
protected ValidationError $error;

public static function failedValidation(ValidationError $error): self
public static function failedValidation(ValidationError $validationError): self
{
$exception = new self(
(new ErrorFormatter())->formatErrorMessage($error),
(new ErrorFormatter())->formatErrorMessage($validationError),
);

$exception->setError($error);
$exception->setError($validationError);

return $exception;
}

public function setError(ValidationError $error): void
public function setError(ValidationError $validationError): void
{
$this->error = $error;
$this->error = $validationError;
}

public function getError(): ValidationError
Expand All @@ -34,10 +34,15 @@ public function getError(): ValidationError
}

/**
* @return array<string, string>
* @return array<string, string|array<string, string>>
*/
public function getErrors(): array
{
return (new ErrorFormatter())->format($this->error);
$errorFormatter = new ErrorFormatter();

/** @var array<string, string|array<string, string>> $errors */
$errors = $errorFormatter->format($this->error);

return $errors;
}
}
20 changes: 10 additions & 10 deletions src/Support/DocParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ public function params(): NodeCollection
public function variable(): ?NodeData
{
$vars = array_map(
static fn(VarTagValueNode $var): NodeData => new NodeData(
name: ltrim($var->variableName, '$'),
types: self::mapValueNodeToTypes($var),
description: $var->description === '' ? null : $var->description,
static fn(VarTagValueNode $varTagValueNode): NodeData => new NodeData(
name: ltrim($varTagValueNode->variableName, '$'),
types: self::mapValueNodeToTypes($varTagValueNode),
description: $varTagValueNode->description === '' ? null : $varTagValueNode->description,
),
$this->parse()->getVarTagValues(),
);
Expand All @@ -91,7 +91,7 @@ protected static function mapValueNodeToTypes(

return match (true) {
$param->type instanceof UnionTypeNode => array_map(
fn(TypeNode $type): string => (string) $type,
fn(TypeNode $typeNode): string => (string) $typeNode,
$param->type->types,
),
$param->type instanceof NullableTypeNode => [
Expand All @@ -114,11 +114,11 @@ protected function parse(): PhpDocNode

protected function getParser(): PhpDocParser
{
$config = $this->getConfig();
$constExprParser = new ConstExprParser($config);
$typeParser = new TypeParser($config, $constExprParser);
$parserConfig = $this->getConfig();
$constExprParser = new ConstExprParser($parserConfig);
$typeParser = new TypeParser($parserConfig, $constExprParser);

return new PhpDocParser($config, $typeParser, $constExprParser);
return new PhpDocParser($parserConfig, $typeParser, $constExprParser);
}

protected function getConfig(): ParserConfig
Expand All @@ -140,7 +140,7 @@ protected function getTextNodes(array $children): array
{
return array_filter(
$children,
static fn(PhpDocChildNode $child): bool => $child instanceof PhpDocTextNode,
static fn(PhpDocChildNode $phpDocChildNode): bool => $phpDocChildNode instanceof PhpDocTextNode,
);
}
}
7 changes: 6 additions & 1 deletion src/Support/NodeCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ public function __construct(

public function get(string $name): ?NodeData
{
$nodes = array_values(array_filter($this->nodes, fn(NodeData $node): bool => $node->name === $name));
$nodes = array_values(
array_filter(
$this->nodes,
fn(NodeData $nodeData): bool => $nodeData->name === $name,
),
);

return $nodes[0] ?? null;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Support/NodeData.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class NodeData
{
/**
* @param array<int, string> $types
* @param array<array-key, string> $types
*/
public function __construct(
public string $name,
Expand Down
6 changes: 3 additions & 3 deletions src/Types/AbstractSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ abstract class AbstractSchema implements Schema
protected string $schemaVersion = 'http://json-schema.org/draft-07/schema#';

/**
* @param \Cortex\JsonSchema\Enums\SchemaType|array<int, \Cortex\JsonSchema\Enums\SchemaType> $type
* @param \Cortex\JsonSchema\Enums\SchemaType|array<array-key, \Cortex\JsonSchema\Enums\SchemaType> $type
*/
public function __construct(
protected SchemaType|array $type,
Expand All @@ -56,7 +56,7 @@ public function nullable(): static
}

if (is_array($this->type)) {
$this->type[] = SchemaType::Null;
$this->type[] = SchemaType::Null; // @phpstan-ignore assign.propertyType
} else {
$this->type = [
$this->type,
Expand All @@ -76,7 +76,7 @@ public function toArray(bool $includeSchemaRef = true, bool $includeTitle = true
{
$schema = [
'type' => is_array($this->type)
? array_map(static fn(SchemaType $type) => $type->value, $this->type)
? array_map(static fn(SchemaType $schemaType) => $schemaType->value, $this->type)
: $this->type->value,
];

Expand Down
2 changes: 1 addition & 1 deletion src/Types/ArraySchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use Cortex\JsonSchema\Types\Concerns\HasItems;
use Cortex\JsonSchema\Exceptions\SchemaException;

class ArraySchema extends AbstractSchema
final class ArraySchema extends AbstractSchema
{
use HasItems;

Expand Down
2 changes: 1 addition & 1 deletion src/Types/BooleanSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Cortex\JsonSchema\Enums\SchemaType;

class BooleanSchema extends AbstractSchema
final class BooleanSchema extends AbstractSchema
{
public function __construct(?string $title = null)
{
Expand Down
6 changes: 3 additions & 3 deletions src/Types/Concerns/HasConditionals.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,21 +134,21 @@ protected function addConditionalsToSchema(array $schema): array

if ($this->allOf !== []) {
$schema['allOf'] = array_map(
static fn(Schema $s): array => $s->toArray(includeSchemaRef: false),
static fn(Schema $schema): array => $schema->toArray(includeSchemaRef: false),
$this->allOf,
);
}

if ($this->anyOf !== []) {
$schema['anyOf'] = array_map(
static fn(Schema $s): array => $s->toArray(includeSchemaRef: false),
static fn(Schema $schema): array => $schema->toArray(includeSchemaRef: false),
$this->anyOf,
);
}

if ($this->oneOf !== []) {
$schema['oneOf'] = array_map(
static fn(Schema $s): array => $s->toArray(includeSchemaRef: false),
static fn(Schema $schema): array => $schema->toArray(includeSchemaRef: false),
$this->oneOf,
);
}
Expand Down
Loading
Loading