NuSphere Forums Forum Index
NuSphere Forums
Reply to topic
Question - Trait and code completion


Joined: 09 Feb 2017
Posts: 23
Reply with quote
Hello everyone,

Due to PHP not having multiple inheritance, I am using Trait for complex class composition where final interfaces for composed classes bring up features of many traits composed.

Alas in PHPEd editing trait does not allow you to see code completion from other classes (like possible parent class(es) for composed class) and their traits, code completion shows nothing from them for $this / self::

Thus the question, is there any way in PHPEd to hint classes and traits related to specific trait so they can be assumed local inside that trait for code completion? Maybe there's some specific comment hints syntax for that?

I.e.

Code:
class X {
  use Y;

  function someX($x, $y)
  {
      $this->someY($x, $y);
  }
}

trait Y {
  function someY($a, $b)
  {
    $this->someX($a, $b);
  }
}


When I edit class X, I obviously can see $this->someY() in code completion as trait Y is included.
But when I edit trait Y, I want to also see $this->someX() from class X, as trait is intended to be composed into X (or parent of X, or possibly with other traits that also need to be seen), but alas, I am missing a way for code completion to see it.
Thus I have to track calls that are supposed to exist in other levels of composition manually, and that's frustrating Smile
View user's profileFind all posts by Alex/ATSend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8366
Reply with quote
the problem is -- when you define class X using trait Y, the Y's methods are copied to the X tables, but not in the opposite way. The Y is still not aware of what classes are using it.
I think it's not a very clean code when you call method of the client class without defining it.
How about the following code?
Code:

<?php
class X {
  use Y;

  function someX($x, $y)
  {
      self::someY($this, $x, $y);
  }
}

trait Y {
  static function someY(X $client, $a, $b)
  {   
    $client->someX($a, $b);
  }
}
?>

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website


Joined: 09 Feb 2017
Posts: 23
Reply with quote
Yes, this is indeed not exactly clean but alas there is no other way to compose complex classes, there's no multiple inheritance in PHP yet Sad
Basically, this is more a cosmetic/usability request, it's of course possible to do this all without code completion - and code completion will work for *final* client as all traits are included, but it makes it hard to split complex classes into cross-reusable traits internally.

The adjustment mentioned is indeed possible, but it creates need to pass $this explicitly and making it of static type means not being able to reuse traits in anything but X (or need to derive everything using traits from X which includes all other side traits possible...).
I.e. with two traits (Y and Z) this will allow completion to know about X itself, but will not allow completion between each other. In theory their internals can be added to X via interfaces, but this alas does not solve strict parenting/nesting issue where traits are to be composed variably.

Some easy change with possibility of using something like

/** @uses X */
(just a quick imagined sample, where X is class/trait/interface)

inside class/trait definitiion would be much appreciated, as it is not introducing a lot of work / big change for PHPEd.
Basically it is a combination of already existing 'use' / 'extends' handling but just for code completion, not being a real PHP construct.
Can also cover some other non-trivial cases of where completion cannot detect proper inheritance potentially.
View user's profileFind all posts by Alex/ATSend private message
Site Admin

Joined: 13 Jul 2003
Posts: 8366
Reply with quote
That's exactly what clean code is about. It makes it immediately clear what you're calling. In my example, X could be replaced with an interface that the X would have to implement (how about IYInterface?) -- specific for Y trait, like hey X. you want to use Y trait? -- you have to implement my interface IYInterface. Unlike class inheritance, php supports multiple interfaces for a class.
Alternatively, if multiple implementations are valid, you could declare them explicitly, e.g. ...(X|X1|X2 $client.... in the arguments.
No, static method is not required. I used static just to skip passing implicit $this.

This makes the code safer because it avoids blind method calls that can otherwise end up with an "unknown method" runtime error.

As for your point -- I agree it's technically doable with hints. The question is: what does the alternative buy us? A hint in a comment isn't really any better than expressing the requirement in the parameter type. The difference is that the parameter type is enforced by the language, while a comment is not. That's an advantage because the contract becomes explicit, verifiable, and much harder to violate accidentally. And hints in the arguments are already supported by PhpED.

_________________
The PHP IDE team
View user's profileFind all posts by dmitriSend private messageVisit poster's website
Question - Trait and code completion
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
All times are GMT - 5 Hours  
Page 1 of 1  

  
  
 Reply to topic