Skip to content

Commit

Permalink
Set nullable true when default value is null
Browse files Browse the repository at this point in the history
When reflection shows that the default parameter of a a property is
null, then the `nullable` parameter is set to `true` for that property.

Currently that needs to be set via the attribute but that is a bit
redundant as the information is already available from reflection

This change only does that for properties and for setter methods.

Right now getter methods that allow a null value to be returned are not
taken into account for setting the `nullable` property.
  • Loading branch information
heiglandreas committed Nov 11, 2024
1 parent c431718 commit 318d00d
Showing 1 changed file with 60 additions and 11 deletions.
71 changes: 60 additions & 11 deletions src/ModelDescriber/Annotations/ReflectionReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,26 @@ public function updateProperty(
if ($reflection instanceof \ReflectionMethod) {
$methodDefault = $this->getDefaultFromMethodReflection($reflection);
if (Generator::UNDEFINED !== $methodDefault) {
if (null === $methodDefault) {
$property->nullable = true;

return;
}
$property->default = $methodDefault;

return;
}
}

if ($reflection instanceof \ReflectionProperty) {
$methodDefault = $this->getDefaultFromPropertyReflection($reflection);
if (Generator::UNDEFINED !== $methodDefault) {
$property->default = $methodDefault;
$propertyDefault = $this->getDefaultFromPropertyReflection($reflection);
if (Generator::UNDEFINED !== $propertyDefault) {
if (Generator::UNDEFINED === $property->nullable && null === $propertyDefault) {
$property->nullable = true;

return;
}
$property->default = $propertyDefault;

return;
}
Expand All @@ -77,6 +87,7 @@ public function updateProperty(
if ($parameter->name !== $serializedName) {
continue;
}

if (!$parameter->isDefaultValueAvailable()) {
continue;
}
Expand All @@ -89,7 +100,12 @@ public function updateProperty(
continue;
}

$property->default = $parameter->getDefaultValue();
$default = $parameter->getDefaultValue();
if (Generator::UNDEFINED === $property->nullable && null === $default) {
$property->nullable = true;
}

$property->default = $default;
}
}

Expand Down Expand Up @@ -117,10 +133,6 @@ private function getDefaultFromMethodReflection(\ReflectionMethod $reflection)
return Generator::UNDEFINED;
}

if (null === $param->getDefaultValue()) {
return Generator::UNDEFINED;
}

return $param->getDefaultValue();
}

Expand All @@ -134,12 +146,49 @@ public function getDefaultFromPropertyReflection(\ReflectionProperty $reflection
return Generator::UNDEFINED;
}

$defaultValue = $reflection->getDeclaringClass()->getDefaultProperties()[$propertyName] ?? null;
if (PHP_VERSION_ID < 80000) {
return $reflection->getDeclaringClass()->getDefaultProperties()[$propertyName] ?? Generator::UNDEFINED;

Check warning on line 150 in src/ModelDescriber/Annotations/ReflectionReader.php

View check run for this annotation

Codecov / codecov/patch

src/ModelDescriber/Annotations/ReflectionReader.php#L150

Added line #L150 was not covered by tests
}

if (!$reflection->hasDefaultValue()) {
return Generator::UNDEFINED;
}

if (null === $defaultValue) {
if ($this->hasImplicitNullDefaultValue($reflection)) {
return Generator::UNDEFINED;
}

return $defaultValue;
return $reflection->getDefaultValue();
}

/**
* Check whether the default value is an implicit null.
*
* An implicit null would be any null value that is not explicitly set and
* contradicts a set DocBlock @ var annotation
*
* So a property without an explicit value but an `@var int` docblock
* would be considered as not having an implicit null default value as
* that contradicts the annotation.
*
* A property without a default value and no docblock would be considered
* to have an explicit NULL default value to be set though.
*/
private function hasImplicitNullDefaultValue(\ReflectionProperty $reflection): bool
{
if (null !== $reflection->getDefaultValue()) {
return false;
}

if (false === $reflection->getDocComment()) {
return true;
}

$docComment = $reflection->getDocComment();
if (!preg_match('/@var\s+([^\s]+)/', $docComment, $matches)) {
return true;
}

return false === strpos(strtolower($matches[1]), 'null');
}
}

0 comments on commit 318d00d

Please sign in to comment.