Skip to content

Commit

Permalink
Make sure models from vendor are properly documented (#651)
Browse files Browse the repository at this point in the history
* make sure null is not returned

* Fix styling

---------

Co-authored-by: romalytvynenko <[email protected]>
  • Loading branch information
romalytvynenko and romalytvynenko authored Dec 4, 2024
1 parent 7140369 commit 51aa306
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
1 change: 1 addition & 0 deletions dictionaries/classMap.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?php

/*
* Do not change! This file is generated via scripts/generate.php.
*/
Expand Down
21 changes: 20 additions & 1 deletion src/Support/InferExtensions/ModelExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Throwable;

class ModelExtension implements MethodReturnTypeExtension, PropertyTypeExtension
{
Expand Down Expand Up @@ -153,7 +154,7 @@ public function getMethodReturnType(MethodCallEvent $event): ?Type
return null;
}

if ($event->methodDefiningClassName !== Model::class) {
if ($this->getRealToArrayMethodDefinitionClassName($event) !== Model::class) {
return null;
}

Expand Down Expand Up @@ -204,4 +205,22 @@ private function getProtectedValue($obj, $name)

return $array[$prefix.$name];
}

/**
* Due to vendor classes being not analyzed for now, we may have a situation when defining class name in event is not
* truly represents the location of the method. But we want to make sure to get it right.
*/
private function getRealToArrayMethodDefinitionClassName(MethodCallEvent $event)
{
$className = $event->methodDefiningClassName ?: $event->getInstance()->name;

try {
$reflectionMethod = new \ReflectionMethod($className, 'toArray');

return $reflectionMethod->getDeclaringClass()->getName();
} catch (Throwable) {
}

return $event->methodDefiningClassName;
}
}
9 changes: 6 additions & 3 deletions src/Support/Type/ObjectType.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function getMethodDefinition(string $methodName, Scope $scope = new Globa
return $classDefinition?->getMethodDefinition($methodName, $scope);
}

public function getMethodReturnType(string $methodName, array $arguments = [], Scope $scope = new GlobalScope): ?Type
public function getMethodReturnType(string $methodName, array $arguments = [], Scope $scope = new GlobalScope): Type
{
$classDefinition = $scope->index->getClassDefinition($this->name);

Expand All @@ -60,13 +60,16 @@ public function getMethodReturnType(string $methodName, array $arguments = [], S
name: $methodName,
scope: $scope,
arguments: $arguments,
methodDefiningClassName: $classDefinition ? $classDefinition->getMethodDefiningClassName($methodName, $scope->index) : $this->name,
methodDefiningClassName: $definingClassName = $classDefinition ? $classDefinition->getMethodDefiningClassName($methodName, $scope->index) : $this->name,
))) {
return $returnType;
}

/*
* For now, when parent class is in `vendor`, we may do not know that certain definition exists.
*/
if (! $methodDefinition = $this->getMethodDefinition($methodName)) {
return null;
return new UnknownType("No method {$definingClassName}@{$methodName} definition found, it may be located in `vendor` which is not analyzed.");
}

$returnType = $methodDefinition->type->getReturnType();
Expand Down

0 comments on commit 51aa306

Please sign in to comment.