Skip to content

Commit

Permalink
Merge pull request #306 from lptn/model-accessors
Browse files Browse the repository at this point in the history
Optimize property check
  • Loading branch information
lptn committed Jan 29, 2023
2 parents dd16593 + 096aca4 commit 93ff966
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 6 deletions.
8 changes: 2 additions & 6 deletions src/Handlers/Eloquent/ModelMethodHandler.php
Expand Up @@ -68,12 +68,8 @@ public static function getMethodReturnType(MethodReturnTypeProviderEvent $event)
return null;
}

/**
* @param FileManipulation[] $file_replacements
*
* @return void
*/
public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event)
/** @inheritDoc */
public static function afterClassLikeVisit(AfterClassLikeVisitEvent $event): void
{
$storage = $event->getStorage();
if (
Expand Down
24 changes: 24 additions & 0 deletions src/Handlers/Eloquent/ModelPropertyAccessorHandler.php
Expand Up @@ -32,6 +32,10 @@ public static function doesPropertyExist(PropertyExistenceProviderEvent $event):
return null;
}

if (self::hasNativeProperty($event->getFqClasslikeName(), $event->getPropertyName())) {
return true;
}

$codebase = $source->getCodebase();

if (self::accessorExists($codebase, $event->getFqClasslikeName(), $event->getPropertyName())) {
Expand All @@ -47,6 +51,10 @@ public static function isPropertyVisible(PropertyVisibilityProviderEvent $event)
return null;
}

if (self::hasNativeProperty($event->getFqClasslikeName(), $event->getPropertyName())) {
return null;
}

$codebase = $event->getSource()->getCodebase();

if (self::accessorExists($codebase, $event->getFqClasslikeName(), $event->getPropertyName())) {
Expand All @@ -64,6 +72,11 @@ public static function getPropertyType(PropertyTypeProviderEvent $event): ?Type\
return null;
}

// skip for real properties like $hidden, $casts
if (self::hasNativeProperty($event->getFqClasslikeName(), $event->getPropertyName())) {
return null;
}

$codebase = $source->getCodebase();
$fq_classlike_name = $event->getFqClasslikeName();
$property_name = $event->getPropertyName();
Expand All @@ -76,6 +89,17 @@ public static function getPropertyType(PropertyTypeProviderEvent $event): ?Type\
return null;
}

private static function hasNativeProperty(string $fqcn, string $property_name): bool
{
try {
new \ReflectionProperty($fqcn, $property_name);
} catch (\ReflectionException $exception) {
return false;
}

return true;
}

private static function accessorExists(Codebase $codebase, string $fq_classlike_name, string $property_name): bool
{
return $codebase->methodExists($fq_classlike_name . '::get' . str_replace('_', '', $property_name) . 'Attribute');
Expand Down
5 changes: 5 additions & 0 deletions tests/Models/User.php
Expand Up @@ -60,4 +60,9 @@ public function scopeActive($query)
{
return $query->where('active', 1);
}

public function getFirstNameUsingLegacyAccessorAttribute(): string
{
return $this->name;
}
}
11 changes: 11 additions & 0 deletions tests/acceptance/EloquentModelPropertyTypes.feature
Expand Up @@ -57,3 +57,14 @@ Feature: Eloquent Model property types
"""
When I run Psalm
Then I see no errors

Scenario: Legacy Attribute accessor
Given I have the following code
"""
function test(User $user): string
{
return $user->first_name_using_legacy_accessor;
}
"""
When I run Psalm
Then I see no errors

0 comments on commit 93ff966

Please sign in to comment.