1

Is there anything I can do to get PhpStorm (2016.1) to recognize types outside the "new X()" scope?

SomeClass.php:

class SomeClass
{    
  public function DoMagic()
  {
    echo "doing magic";
  }

}

DummyClass.php:

class DummyClass
{
  protected $mParamsList;

  function __construct()
  {
    $this->mParamsList = array();
  }

  public function InitParamsList()
  {
    $this->mParamsList[] = new SomeClass();
  }

  public function GetParamsList()
  {
    return $this->mParamsList;
  }

}

UserClass.php - no suggestions:

class UserClass
{
  public function DoMagic()
  {

    $dummy2 = new DummyClass();

    $params = $dummy2->GetParamsList(); 

    foreach ($params as $param)
    {
      $param-> * nothing happens *
    }
  }

}
?>

I found adding this hack works, but it's getting frustrating to employ it:

if (false) { $param = new SomeClass(); }

So the full working example would be:

class UserClass
{
  public function DoMagic()
  {
    $dummy = new DummyClass();

    $params = $dummy->GetParamsList(); 

    foreach ($params as $param)
    {
      if (false)
      {
        $param = new SomeClass();
      }

      $param-> * suggestions pop up * 
    }
  }

}
Buffalo
  • 3,861
  • 8
  • 44
  • 69
  • Please provide self-contained complete sample code that would illustrate the issue. My simple tests show that it works just fine .. so it must be some your local issue (be it real code .. or maybe something else). – LazyOne Jan 04 '17 at 15:40
  • http://postimg.org/image/nekslhcwj/ -- as you can see not even extra PHPDoc is required (although having docs is always useful). – LazyOne Jan 04 '17 at 15:46
  • Sorry, I'd provided a overly simplified version which did work. Updated the question with a broken sample. My classes are defined in separate files, if that makes any difference. – Buffalo Jan 05 '17 at 12:13
  • 1
    If you take @Saliery's answer and adapt so that `DummyClass::GetParamsList()` has `@return SomeClass[]` in its doc block, does that not work? – Dezza Jan 05 '17 at 12:16
  • @Buffalo Few possible (but easy) solutions: 1) Place `/** @var SomeClass[] */` on a line before before `protected $mParamsList;` 2) Do what Dezza suggested (same affect in the end -- for your code sample alone, of course): proper PHPDoc for `GetParamsList()` method where it will have `@return SomeClass[]`; 3) Alternative - inline PHPDoc -- place `/** @var SomeClass $param */` before or just inside that `forech` cycle (not as good as first 2 as it has to be repeated in every foreach cycle; but can be used in complex projects to clarify actual type locally) . – LazyOne Jan 05 '17 at 12:27
  • 1
    @Buffalo Here is a screenshot with all 3 PHPDoc comments in place: https://postimg.org/image/pv0stvtwv/ **P.S.** Some link to read: https://github.com/phpDocumentor/fig-standards/blob/master/proposed/phpdoc.md **Conclusion:** use PHPDoc -- it helps other people to read your code, yourself (1 year later .. when you forget what it does exactly) as well as IDE (better code completion and code analysis) – LazyOne Jan 05 '17 at 12:28
  • @LazyOne: thanks! can I generate it automatically somehow? I tried using it and didn't see a behavior like eclipse does (render it above the method when typing it), so I ditched it. I'm also trying to write code that only needs comments as a last resort. It's a terrible overhead when looking through a source file and should only be used for 3d party closed source libraries IMO. – Buffalo Jan 05 '17 at 12:35
  • @Buffalo It's up to you .. but keep in mind what other people may think when they deal with your code later. I suggest to check open source projects/frameworks like Doctrine, Symfony, Laravel, Yii2 etc and see the amount of PHPDoc they use. I'm not saying that it must be done in the same way/amount of comments .. but basic ones -- for sure. In any case: 1) http://www.phptherightway.com/#documenting 2) http://softwareengineering.stackexchange.com/questions/156601/is-it-recommended-to-use-docblock-even-if-im-not-using-phpdocumentor – LazyOne Jan 05 '17 at 12:41
  • @LazyOne: I get what you're saying, but we're a small company that produces inhouse software for our smallish project and spamming trivial comments would do nothing but hurt our productivity and our eyes when skimming through the files :(. Bad code for which we'd need comments for deciphering is typically taken care of via code reviews. There's a book I really enjoyed (although centered on Java) - Clean Code by Robert C. Martins which speaks along the lines of being able to ditch comments altogether: https://s23.postimg.org/w1com2cob/comments.png – Buffalo Jan 05 '17 at 12:55
  • @Buffalo *"I tried using it and didn't see a behavior like eclipse does (render it above the method when typing it)"* I'm not Eclipse user .. but I guess you are talking about documentation that shows when you typing class/function/method. Try `Ctrl+Q` (on Windows/Linux using Default keymap) -- or whatever you have there for `View | Quick Documentation` – LazyOne Jan 05 '17 at 13:25
  • @Buffalo As for amount of comments and where to use them -- it's all up to you, especially if it's inhouse software. Those comments that I have suggested are minimum that you need in your case for IDE to understand your code (either #1 or #2 (or better both) -- depends on the rest of the code. PhpStorm is limited in its static analysis (too much of it -- and IDE is slow or may produce wrong results for overly clever code). Hence some manual type hinting here and there with PHPDoc helps a lot .. as it's assumed that user knows better what type it is/should be compared to what IDE can deduct. – LazyOne Jan 05 '17 at 13:31
  • @Buffalo From IDE point of view (with current static analysis implementation) `$mParamsList` is just an ordinary array (array of elements of any type) .. hence the code completion issues in foreach statement. But when you add PHPDoc that states that it's an array of specific type ... IDE now knows that `$param` has specific type instead of generic `mixed` with no such comments. How to document such moment -- via #1 or #2 -- depends on the rest of your code, but #1 seems more "global" as it is used in multiple methods so you may have another method that returns the same stuff – LazyOne Jan 05 '17 at 13:34
  • Awesome. Thanks again. – Buffalo May 15 '17 at 12:14

1 Answers1

4

You should use doc-type comments before your function:

/**
 * @return \MyObject
 */
public function GetMyObject()
{
    return new MyObject();
}
Saliery
  • 119
  • 5