inconsistent inspector type identification

So I have a test class with a couple member variables that are the same class (the class under test). One of them is consistently correctly hinted and error checked, the other is consistently missed (type appears to be null). I'm at a loss as to why... and no amount of additional PHPDocs are helping.

HQ = new Address();         $this->HQAva = new Address();     }     public function testFoo() {         //this is erroneously flagged as "Method 'foo' not found in class"         $this->assertEquals(42, $this->HQ->foo(), 'HQ->foo()');         //this correctly knows that HQAva isa Address         $this->assertEquals(42, $this->HQAva->foo(), 'HQAva->foo()');     } }


Bug? Anything I can do to workaround it?

3 comments

bah, you'd think pasting a code block into this forum would be easier than it has proven for me.

<?php

class Address {
    public function foo() {
        return 42;
    }
}

class AddressTest extends PHPUnit_Framework_TestCase {

    var $HQ;    /** @var $HQ Address */
    var $HQAva; /** @var $HQAva Address */

    public function setUp() {
        $this->HQ = new Address();
        $this->HQAva = new Address();
    }

    public function testFoo() {
        //this is erroneously flagged as "Method 'foo' not found in class"
        $this->assertEquals(42, $this->HQ->foo(), 'HQ->foo()');
        //this correctly knows that HQAva isa Address
        $this->assertEquals(42, $this->HQAva->foo(), 'HQAva->foo()');
    }
}

0

Hi Chris,

1. PHPDoc must preceed property/method/class/etc declaration (except, maybe, inline @var, for typehinting ordinary variables, not class one).

With your current style:

  • /** @var $HQAva Address */ is treated as PHPDoc for public function setUp();
  • /** @var $HQ Address */ as PHPDoc for var $HQAva;
  • and var $HQ; has no PHPDoc


2. Wrong @var syntax for class variable (property) -- that's as far as I'm aware. Such syntax is used for inline variables and not for class variables. The more correct approach would be

class AddressTest extends PHPUnit_Framework_TestCase
{

    /** @var Address Optional description here */
    var $HQ;


    /** @var Address Optional description here */
    var $HQAva;


public function setUp() {
...


P.S.
Is your code still needs to be compatible with PHP v4? If not, then I think it's better to use public/protected/private instead of var when declaring class variabled/properties.

Anyway -- that's final code:

<?php
class Address
{
    /**
     * @return int
     */
    public function foo()
    {
        return 42;
    }
}


class AddressTest extends PHPUnit_Framework_TestCase
{
    /** @var Address */
    protected $HQ;
    /** @var Address */
    protected $HQAva;


    public function setUp()
    {
        $this->HQ = new Address();
        $this->HQAva = new Address();
    }


    public function testFoo()
    {
        //this is erroneously flagged as "Method 'foo' not found in class"
        $this->assertEquals(42, $this->HQ->foo(), 'HQ->foo()');
        //this correctly knows that HQAva isa Address
        $this->assertEquals(42, $this->HQAva->foo(), 'HQAva->foo()');
    }
}

0

Hmm... I didn't know class scoped @var was that different. I think I'm going to go re-RTFM on phpdocs!

And no, it doesn't need to be compatible with php4, that's just old code influencing lazy engineers to copy/paste. :)  Now, THERE is a "code smell" inspector that's missing in phpStorm: "Smells like php v4" flags on use of var declarations.

Thanks again Andriy!

0

Please sign in to leave a comment.