Jump to content

IDE support for hooks


mindplay.dk
 Share

Recommended Posts

I wrote my first PW module this week-end, and I was generally pleased - in about 5-6 hours through the day, I was able to learn (from the ground up) how to use the hooks and input-fields APIs, as well as writing a small but functional plug-in. If I had to compare this experience with my Drupal or WordPress module-writing experience in the past, I would say this is about 10 times easier to learn and do!

One thing I find in general about PW however, is the IDE support is lacking - this is natural and expected, due to the nature of the PHP language, but I like to push the limits, so if you're interested... Help me brainstorm for ideas to implement IDE support for hooks?

Of course, the obvious route is to implement IDE support in the IDE - this is the route that more IDEs seem to choose lately, for example Yii and Symfony has IDE support in a couple of IDEs by now.

That's all well and good, but I would strongly prefer to find an approach enables static analysis - IDEs already parse and inspect code and PHP-DOC annotations, and in modern IDEs this ties in with powerful features like auto-completion, parameter/type-hints, documentation, diagramming, automated refactoring, and so forth. There must be some way we can leverage that existing IDE power?

A couple of random ideas and hocus-pocus off the top of my head:

- thin run-time code-generation in "autoloaders" - things like eval('class '.$magic.' extends '.$static.' { use '.$trait.' }') execute quickly.

- static code-generation via stream-wrappers or autoloaders, modifying or generating code.

- inline code-generation (via autoloaders) - altering sectioned areas in source-code (relies on eager saving and auto-refresh in IDEs/editors, e.g. PhpStorm)

- class-name aliasing: use x as y... I actually attempted eval('use Foo\Bar as Fudge;') and I can report that it executes, but doesn't work - still worth pondering though, could work in combination with inline code generation.

- PHP 5.4 traits can implement __call(), __get() and __set() ... doesn't provide any IDE support off-hand, but perhaps in combination with something else?

- parsing PHP and/or PHP-DOC: could lead to interesting results in combination with another hocus-pocus technique.

Please add to the list, if you're interested!

  • Like 2
Link to comment
Share on other sites

I had to click like because this all sounds pretty cool. But you also lost me after "A couple of random ideas and hocus-pocus off the top of my head". Perhaps it's because I don't use an IDE, or maybe because it's the end of the day here… but other than parsing PHPDoc and traits, I have no idea what any of this is. :) I still need to try PhpStorm (and SlimeText)… but too much work going through the studio right now to experiment. I'm guessing this would all make sense if I had that same IDE context. Anyway, nice for some cool sounding stuff regardless. :) I'm hoping someone else here knows what you are talking about better than me and can chime in.

Link to comment
Share on other sites

I think working on ProcessWire in PhpStorm would teach you some things about your own codebase - static analysis currently cannot do much to help with ProcessWire development at all, and that's educational... as I'm hoping you will discover, when static analysis doesn't work on a codebase, that usually indicates that the codebase is not as easy to understand, or as well-documented, as it could be. When static analysis doesn't work, that means we have to interpret code, and memorize code structure - I would rather use my clockcycles on solving practical problems :)

I imagine not many people will have anything to say in this discussion, or they probably would have already. But I did an interesting experiment with synthetic classes tonight, and will post some results once I have a working prototype...

Link to comment
Share on other sites

I appreciate your point of view, but understand we're coming from different preferences in this regard. As you know I'm not an IDE fan and my focus is on code best practices, not IDE navigation. I care more about program comprehension, design and code review than static analysis. I veer towards putting my time towards the practices and documentation that best serve and maintain the code base quality, as opposed to accommodating one or another automated tool for static analysis. To put it another way and use the same term you did: I would rather put my clock cycles towards the things that best help code review and overall quality than the things that maximize someone else's static analysis and IDEs. But don't get me wrong, I have nothing against supporting these tools and maximizing the experience with them. As you know, almost every class and function in PW is documented, and most with phpdoc. If time were unlimited, I would take full advantage of communicating above and beyond to everything that PhpStorm (or another IDE or tool) could want, even if it doesn't help me. And over time and within resources, I support this (@interrobang has helped out a lot recently in this area). If there are things that would be beneficial to you in PhpStorm (and you think woud be valuable to others), call them out more specifically so we can get them on paper and make it part of the roadmap and collaborate on implementation.

Link to comment
Share on other sites

I don't think we're really coming from very different perspectives at all - I only recently (within a couple of months) became an IDE devout. Over the years, I have tried every PHP IDE there is - typical life-span: one week. Nothing I ever tried helped with best code practices, which is all I was after.

Static analysis and automated code inspection is about program comprehension and design - and automated code-review, it's a start, and it really goes deeper than you might think. It can save yourself and others a lot of tired hours that you could spend solving more interesting problems.

You define the code-standards yourself through a series of very detailed dialogs, and you choose from 100+ configurable code inspections what you think is right and wrong. So it's not about living up to some IDE's code standards or "someone else's" static analysis - you set your own standards, and the IDE just lets you know when you're not living up to your own goals. It's not about communicating to the IDE - it's about communicating completely and consistently to the person looking at the source-code. And sure, you can have a person do that - but not with the same degree of consistency as a machine, and not without getting tired ;)

I think you have have to try it to see what I'm talking about.

Mind you, this comes from someone who used plain text editors for more than 25 years. I didn't suddenly change my mind for no reason ;)

Link to comment
Share on other sites

I think you have have to try it to see what I'm talking about.

No doubt, and I intend to. But you mentioned you've tried every IDE that there is, so clearly you've been trying to fill a need or desire that you have. I do not share this need or desire, and I come from a background of using IDEs... but I used them (at work) because I had no choice. Give me a choice and I'm far more creative and productive when there's nothing between me and the code I'm trying to read or write. Yes that means there's more to think about, but perhaps the creative juices just don't flow for me unless I cross that threshold (must be ADD). The only reason I will even look at StormyPHP and SlimeText is because it'll make you guys happy. I'll congratulate you on your decision, and enjoy the opportunity to play, but won't become a convert. I'm quite happy with the environment I work in and don't have any needs, desires or bottlenecks I'm looking to solve. Otherwise I'd be deeply invested in trying lots of IDEs too. Instead, what I'm interested in is learning how to make the code as accessible as possible to people that do use these tools and want to browse from above rather than within, provide them with the context they may be missing, and prevent them from going down the wrong path. I fully support anything that aids in understanding for as broad of a group as possible. So if there are some specific things that I can do, I'm hoping you can help to point them out. What specifically would make your experience better when viewing ProcessWire code from PhpStorm (or SlimeText, etc.)?

Link to comment
Share on other sites

I think, partially, you view this from the point of someone who knows the codebase inside and out - which is natural, since you wrote the thing. It's a relatively small codebase, and it's well-documented, so it's far from inaccessible to others. But someone who uses an IDE would be able to get up to speed much faster with better IDE support.

What specifically would make your experience better when viewing ProcessWire code from PhpStorm (or SlimeText, etc.)?

Whatever enables static analysis - mostly more complete PHP-DOC annotations. It would eliminate a lot of code-browsing to learn about hidden/invisible properties.

I know there's a lot of dynamics (magic) in PW, so not everything can be documented - but generally, anything that uses __get() and __set() could be completed, to the extend that this makes sense... for example, the "fuel" type could define properties for the built-in standard "fuel" objects.

As we've discussed previously, class/file-name mapping also could be more consistent.

Basically, open PW in Storm, and you will pretty quickly see countless things light up in orange or red scribble throughout the codebase - basically, where static analysis fails, the reader's analysis will fail too.

For things that are indeterminate and can't be documented, you can often document with function-level annotations in the consumer-code what you're expecting - for example, in my code you can see me doing this consistently; in this particular example, it's pretty obvious what comes out of $this->modules->get('InputfieldText') but often class-names do not match property-names, and you have to dig to learn what comes out of this or that property...

  • Like 1
Link to comment
Share on other sites

Great suggestions, thank you for this.

Whatever enables static analysis - mostly more complete PHP-DOC annotations. It would eliminate a lot of code-browsing to learn about hidden/invisible properties.

You are right, those hidden/invisible properties are not well covered at present. Largely because this was one aspect of phpdoc I wasn't aware of until recently. @Interrobang actually added the appropriate property/method tags in /wire/core/Page.php a couple months ago, and I expanded upon them. Do you think this is a good model to carry through in other core files?

for example, the "fuel" type could define properties for the built-in standard "fuel" objects.

This is a good point as well. I want to mention though that "fuel" is more of a old and now redundant thing (for backwards compatibility with the original PW 2.0). It's now preferable to use the wire('...') function to access API variables (rather than $this->fuel()). Technically they achieve the exact same thing. But I like wire() because it works anywhere (template files, bootstrapped shell scripts, modules, core) ... code examples are portable no matter where they come from or are going. Whereas $this->fuel only translates to within 'Wire' derived classes. But I'm not planning on deprecating $this->fuel() either. I'm just avoiding it in my own code and examples (only new stuff) so as not to confuse people studying code. But perhaps there is some way I can signal that $this->fuel() is an alias of wire() with phpdoc, to better clarify it for people in an IDE.

As we've discussed previously, class/file-name mapping also could be more consistent.

I think PSR-0 will take care of this one and I'm anxious to move forward with that but need to resolve some questions about how it will affect language translation.

Link to comment
Share on other sites

Definitely, documentation should carry through to other files, same as for Page.

As for Fuel, maybe you should deprecate it? Getting rid of existing usages in the PW codebase is probably a simple search-and-replace? ... use @deprecated on the old member, and @see to link to the new member - having two supported API points for exactly the same thing isn't good for comprehension.

To the original subject, I've tinkering with a module that writes out stub PHP classes like this one:

<?php

namespace templates;

/**
* @property mixed $title Title (FieldtypePageTitle)
* @property mixed $link Link URL (FieldtypeURL)
* @property mixed $published Date Published (FieldtypeDatetime)
* @property mixed $icon Icon (FieldtypeImage)
* @property mixed $body Body (FieldtypeTextarea)
*/
class Post extends Page
{}

The module will write one of these to a designated folder whenever you save a template - in your template files, you can then use @var annotations to fake out your IDE, which will then be able to auto-complete for fields.

I know this isn't very useful or interesting to someone who doesn't use an IDE, but working with others on a team, this will save time - since you'll be able to open up a template-file and know about all it's fields without digging through an admin-screen :)

This is very experimental and too incomplete to post yet, but the stub above was generated with this module...

  • Like 1
Link to comment
Share on other sites

As for Fuel, maybe you should deprecate it? Getting rid of existing usages in the PW codebase is probably a simple search-and-replace? ... use @deprecated on the old member, and @see to link to the new member - having two supported API points for exactly the same thing isn't good for comprehension.

It's easy enough for me to search/replace, but I'm reluctant to remove it entirely (at least for awhile) as I don't like to risk breaking anyone else's code. But indicating that its deprecated is a good idea.

I know this isn't very useful or interesting to someone who doesn't use an IDE, but working with others on a team, this will save time - since you'll be able to open up a template-file and know about all it's fields without digging through an admin-screen

Very nice, I like it. And actually think it is still useful even outside of an IDE. But I'm confused by the last line: "class Post extends Page" -- is this what you mean by fake-out the IDE, or does the Post class have a purpose beyond it?

Link to comment
Share on other sites

It's easy enough for me to search/replace, but I'm reluctant to remove it entirely (at least for awhile) as I don't like to risk breaking anyone else's code.

Absolutely - removing it was not at all what I was suggesting. It should be there for backwards compatibility.

I'm confused by the last line: "class Post extends Page" -- is this what you mean by fake-out the IDE, or does the Post class have a purpose beyond it?

The Post class is solely for IDE reflection - it will never be loaded. It's declared as "extends Page" in order to also provide IDE reflection for inherited Page methods and properties.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...