[Feature request] need to support more PHPDoc tags #1385

Closed
pattisahusiwa opened this Issue Aug 21, 2016 · 16 comments

Projects

None yet

2 participants

@eranif
Owner
eranif commented Aug 30, 2016

How would you suggest to add them? i.e. what does CodeLite should do when it encounter these tags.
For example, the @property tag?

@pattisahusiwa
pattisahusiwa commented Aug 31, 2016 edited

The bug in the last PR that I've sent is found when I'm trying to implement @property tag. But, currently I don't have more free time to dig into the code.
@property is similar to @var, so you can implement the same logic. Also, @method is similar to a function definition in class or interface.

<?php
/** @property $foobar */
class foo
{
    /** @var $bar */
    public $bar;

    public function __get()
    {
    }
}

By using this example, when a user type

$f = new foo();
$f->

editor can suggest that $f have 2 properties foobar and bar.

@eranif
Owner
eranif commented Sep 1, 2016 edited

Ok, thanks. So, property will add new members to the class/interface completion list
FYI: you don't need to add @var to get it listed in the completion list, the @var <type> <name> provide an easy way for the IDE to get a typehint for the variable

@pattisahusiwa

Ok, thanks for the info. I prefer to add @var for documentation stuff :).

@eranif
Owner
eranif commented Sep 1, 2016

Ofc, I mentioned what CodeLite does with it:

  • Uses it for better code completion
  • Shows a tooltip
@pattisahusiwa

I need your opinion about this problem. Consider I have code like this

<?php
class StructA{public $a;}
class StructB extends StructA{public $b;}
class ClassA
{
    protected $struct;
    public function __construct(StructA $a)
    {
        $this->struct = $a;
    }
}
class ClassB extends ClassA
{
    public function __construct(StructB $b)
    {
        $this->struct = $b;
    }
}

Any idea how to make codelite knows that $this->struct in ClassB is StructB?

@eranif
Owner
eranif commented Sep 1, 2016 edited

This is a problem. In the symbol lookup table, we only keep one instance of ClassA - this means that protected $struct can only be "commented" once.

But this can be an enhancement for the @property feature (which I have not yet implemented):
By adding @property StructB $struct for ClassB, CodeLite will create a new "instance" in the lookup symbol for ClassB for $struct

What do you think?

@pattisahusiwa

It'll work. But, according to the doc, @property and @method have special job to serve magic method __get, __set, and __call. I don't know whether it will break the convention or not.

Another approach is keep parsing every @var tags. Little hack shows that this approach is working perfectly. In the image, the last record is added manually with DOC_COMMENT=/** @var StructB */ and it works.

@eranif
Owner
eranif commented Sep 1, 2016 edited

The problem is that CodeLite will not add the last entry 9999 by itself, since the struct is a member of ClassA and only one struct exist. So we cant keep both in the database. Personally, I think that the @property approach is the fastest and easiest solution, but I am not sure how it will affect the phpdoc conventions.

The full solution should be:

  • Add new table to the database PHPDOC_OVERRIDE_TABLE (maybe we go with a different name....)
  • Each @var <type> <name> defined in the class body (not in functions) are kept in this table
  • When CodeLite loads a variable from the lookup table, it will perform a quick search on this table to replace the typehint based on this table.

So to get what you want, your code will look like this:

<?php
class StructA{public $a;}
class StructB extends StructA{public $b;}
class ClassA
{
    /** @var StrcutA $struct */
    protected $struct;
    public function __construct(StructA $a)
    {
        $this->struct = $a;
    }
}
class ClassB extends ClassA
{
    /// adding the below line will tell CodeLite that $struct is of type StructB when used from ClassB
    /** @var StrcutB $struct */

    public function __construct(StructB $b)
    {
        $this->struct = $b;
    }
}
@pattisahusiwa
pattisahusiwa commented Sep 1, 2016 edited

Yes, exactly. You can look at the image, ID 9996 and 9999 exactly pointed to the same variable but with different scope so they can't violate any SQL constraint. I mean you don't need to add another table. As in your code and mine (in the image), users MUST put @var tag before the variable, eq. inside a function, in order this approach to works.

@eranif
Owner
eranif commented Sep 2, 2016 edited

You initial hack duplicated the entry in the database - something I really prefer not to do.
Using an additional table is just another way of adding an additional information for the real entry, its not about "SQL constraints" its about correctness.

I have implemented my method of adding new table (see commit: 9efb2bc):

php-extends-with-diff-type

@pattisahusiwa

Ok, this will work for both editor and documentation

/**
* for codelite purpose
* @var \StructB $struct
*/
/**
* for documentation purpose
*
* @param \StructB $b
* @return void
*/
public function __construct(StructB $b)
{
    $this->struct = $b;
}
@eranif
Owner
eranif commented Sep 3, 2016

Just an FYI: the second comment is also used by CodeLite

@pattisahusiwa

Yes thank you. Second comment only works for $b.

Latest commit breaks something.

Codelite 9.2.0
good

Latest code
error

it fails to parse

namespace phpseclib\Net;

/**
 * Pure-PHP implementations of SFTP.
 *
 * @package SFTP
 * @author  Jim Wigginton <terrafrost@php.net>
 * @access  public
 */
class SFTP extends SSH2
{

and breaks code completion.

btw, your latest code can't be compiled without add algorithm in PHPLookupTable and PHPEntityClass files (std::reverse and std::for_each).

@eranif
Owner
eranif commented Sep 3, 2016 edited

This is now fixed (both missing headers and the broken parsing)

@pattisahusiwa

Ok, confirmed.

@eranif eranif closed this Sep 5, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment