Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code with attributes causes missing class error on method return type #10563

Closed
jimbo2150 opened this issue Jan 17, 2024 · 4 comments
Closed

Comments

@jimbo2150
Copy link

I have a Symfony entity class with various attributes attached to the class and properties. When using a template generic, psalm appears to recognize the template on the class property, but not on the return value of a class method. It says it is an undefined class.

Here is the example code: https://psalm.dev/r/6cb02178be
In the above example you can ignore all other errors except for the docblocks and specifically the @return value on the getValue() method. The other errors are just because of the referenced classes do not exist within the test environment.

However, when I remove the attributes, the error disappears. It seems to recognize the template generic variable and no longer has an issue with it.

Here is the same code with attributes removed: https://psalm.dev/r/ba05c5fb24
The above example has all the attributes removed and it now seems to recognize the @template generic on the method return type.

Copy link

I found these snippets:

https://psalm.dev/r/6cb02178be
<?php

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use app\Repository\ObjectPropertyRepository;

#[ORM\Entity(repositoryClass: ObjectPropertyRepository::class)]
#[ORM\Table(name: 'object_properties')]
/**
 * @template T
 */
class ObjectProperty
{
	#[ORM\ManyToOne(targetEntity: stdClass::class, inversedBy: 'properties')]
	private ?stdClass $object = null;

	#[ORM\Id()]
	#[ORM\GeneratedValue()]
	#[ORM\Column(type: Types::BIGINT)]
	private int|string|null $id = null;

	#[ORM\Column(type: Types::BIGINT)]
	private int|string|null $object_id = null;

	#[ORM\Column(type: Types::STRING)]
	private string|null $name = null;

	#[ORM\Column(type: Types::JSON)]
	/** @var T */
	private int|float|string|array|null $value = null;

	#[ORM\Column(type: Types::DATETIME_IMMUTABLE)]
	private \DateTimeInterface|null $created = null;

	public function getName(): string|null
	{
		return $this->name;
	}

	/**
	 * @return T
	 */
	public function getValue(): int|float|string|array|null
	{
		return $this->value;
	}

	public function getCreationDate(): ?\DateTimeInterface
	{
		return $this->created;
	}

	public function getId(): int|string|null
	{
		return $this->id;
	}

	public function getObject(): ?stdClass
	{
		return $this->object;
	}
}
Psalm output (using commit 67c7be3):

INFO: UndefinedAttributeClass - 7:3 - Attribute class Doctrine\ORM\Mapping\Entity does not exist

ERROR: UndefinedClass - 7:31 - Class, interface or enum named app\Repository\ObjectPropertyRepository does not exist

INFO: UndefinedAttributeClass - 8:3 - Attribute class Doctrine\ORM\Mapping\Table does not exist

ERROR: UndefinedDocblockClass - 41:13 - Docblock-defined class, interface or enum named T does not exist

INFO: UndefinedAttributeClass - 14:4 - Attribute class Doctrine\ORM\Mapping\ManyToOne does not exist

INFO: UndefinedAttributeClass - 17:4 - Attribute class Doctrine\ORM\Mapping\Id does not exist

INFO: UndefinedAttributeClass - 18:4 - Attribute class Doctrine\ORM\Mapping\GeneratedValue does not exist

INFO: UndefinedAttributeClass - 19:4 - Attribute class Doctrine\ORM\Mapping\Column does not exist

ERROR: UndefinedClass - 19:21 - Class, interface or enum named Doctrine\DBAL\Types\Types does not exist

INFO: UndefinedAttributeClass - 22:4 - Attribute class Doctrine\ORM\Mapping\Column does not exist

ERROR: UndefinedClass - 22:21 - Class, interface or enum named Doctrine\DBAL\Types\Types does not exist

INFO: UndefinedAttributeClass - 25:4 - Attribute class Doctrine\ORM\Mapping\Column does not exist

ERROR: UndefinedClass - 25:21 - Class, interface or enum named Doctrine\DBAL\Types\Types does not exist

INFO: UndefinedAttributeClass - 28:4 - Attribute class Doctrine\ORM\Mapping\Column does not exist

ERROR: UndefinedClass - 28:21 - Class, interface or enum named Doctrine\DBAL\Types\Types does not exist

INFO: UndefinedAttributeClass - 32:4 - Attribute class Doctrine\ORM\Mapping\Column does not exist

ERROR: UndefinedClass - 32:21 - Class, interface or enum named Doctrine\DBAL\Types\Types does not exist
https://psalm.dev/r/ba05c5fb24
<?php

/**
 * @template T of int|float|string|array|null
 */
class ObjectProperty
{
	private ?stdClass $object = null;

    private int|string|null $id = null;

	private int|string|null $object_id = null;

	private string|null $name = null;

	/** @var T */
	private int|float|string|array|null $value = null;

    private \DateTimeInterface|null $created = null;

	public function getName(): string|null
	{
		return $this->name;
	}

	/**
	 * @return T
	 */
	public function getValue(): int|float|string|array|null
	{
		return $this->value;
	}

	public function getCreationDate(): ?\DateTimeInterface
	{
		return $this->created;
	}

	public function getId(): int|string|null
	{
		return $this->id;
	}

	public function getObject(): ?stdClass
	{
		return $this->object;
	}
}
Psalm output (using commit 67c7be3):

No issues!

@weirdan
Copy link
Collaborator

weirdan commented Feb 5, 2024

Minimal reproducer: https://psalm.dev/r/b85c3cd814

Copy link

I found these snippets:

https://psalm.dev/r/b85c3cd814
<?php

/**
 * @template T
 */
class ObjectProperty
{
	#[A]
	/** @var T */
	private int|null $value = null;

	/**
	 * @return T
	 */
	public function getValue(): int|null
	{
		return $this->value;
	}
}
Psalm output (using commit 4b2c698):

ERROR: InvalidReturnStatement - 17:10 - The inferred type 'int|null' does not match the declared return type 'T:ObjectProperty as mixed' for ObjectProperty::getValue

ERROR: InvalidReturnType - 13:13 - The declared return type 'T:ObjectProperty as mixed' for ObjectProperty::getValue is incorrect, got 'int|null'

INFO: UndefinedAttributeClass - 8:4 - Attribute class A does not exist

@weirdan
Copy link
Collaborator

weirdan commented Feb 5, 2024

The issue is with the underlying parser library we use: nikic/PHP-Parser#762. Nothing can be done here unless that issue is fixed first.

@weirdan weirdan closed this as not planned Won't fix, can't repro, duplicate, stale Feb 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants