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

Should PhpStorm complete in foreach? #83

Closed
pupitooo opened this issue Sep 23, 2021 · 3 comments
Closed

Should PhpStorm complete in foreach? #83

pupitooo opened this issue Sep 23, 2021 · 3 comments
Labels

Comments

@pupitooo
Copy link

PhpStorm 2021.2 support for generics in PHP. But when I use foreach above collection PhpStomr does not recognize correct element type.

Should PhpStorm autocomplete inner types in foreach?

It is important when I want to change method names.

Example code

use Ramsey\Collection\AbstractCollection;

/**
 * @extends AbstractCollection<Specific>
 */
class SpecificCollection extends AbstractCollection
{
	public function getType(): string
	{
		return Specific::class;
	}
}


class Specific
{
	public function __construct(private string $code)
	{}


	public function getCode(): string
	{
		return $this->code;
	}
}


class Test {

	public function test1(): void
	{
		$collection = new SpecificCollection([new Specific('code1')]);

		foreach ($collection as $item) {
			$item->getCode(); // IDE do not recognize
		}
	}


	/**
	 * @param SpecificCollection<Specific> $collection
	 */
	public function test2(SpecificCollection $collection): void
	{
		foreach ($collection as $item) {
			$item->getCode(); // IDE do not recognize
		}
	}


	/**
	 * @param SpecificCollection<Specific>|array<Specific> $collection
	 */
	public function test3(SpecificCollection $collection): void
	{
		foreach ($collection as $item) {
			$item->getCode(); // IDE do not recognize
		}
	}


	public function test4(SpecificCollection $collection): void
	{
		foreach ($collection as $item) {
			/** @var Specific $item */
			$item->getCode(); // Only this IDE recognize
		}
	}


	public function test5(SpecificCollection $collection): void
	{
		foreach ($collection as $item) {
			\assert($item instanceof Specific);
			$item->getCode(); // Only this IDE recognize
		}
	}
}
@ramsey
Copy link
Owner

ramsey commented Oct 10, 2021

Thanks for calling attention to this!

The support for generics in PhpStorm is limited right now, but it looks like they added support for this in 2021.2.1 (see the release notes here; it's the note "Support inference based on IteratorAggregate<User>"). I just upgraded to 2021.2.2 to see if I can get this to work.

It works when I change SpecificCollection to the following:

/**
 * @extends AbstractCollection<Specific>
 * @implements IteratorAggregate<Specific>
 */
class SpecificCollection extends AbstractCollection implements IteratorAggregate
{
    public function getType(): string
    {
        return Specific::class;
    }
}

However, this should work without making this change because Ramsey\Collection\ArrayInterface uses the annotation @extends IteratorAggregate<array-key, T>, but it seems PhpStorm isn't picking this up, or maybe I have something incorrect in the annotations.

I'll do some more digging around to see if I can figure out whether I need to change something in the library or whether this is a limitation in PhpStorm.

@apeschar
Copy link

PhpStorm 2021.3 has the same issue.

Adding @implements \IteratorAggregate<array-key, T> directly on AbstractCollection doesn't change anything, and neither does using @implements \IteratorAggregate<Specific>. It looks like @implements \IteratorAggregate<ClassName> only works on the concrete class, not the abstract.

I'm fairly sure this is a PhpStorm limitation and relates to these issues:

  1. https://youtrack.jetbrains.com/issue/WI-63612
  2. https://youtrack.jetbrains.com/issue/WI-63261

@ramsey
Copy link
Owner

ramsey commented Dec 31, 2022

It looks like this is now working in PhpStorm, especially after I did an audit of all the type annotations and updated them in version 2.0.0. I'm closing this issue now, but if you still have problems, let me know.

@ramsey ramsey closed this as completed Dec 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants