Zwabel’s Weblog

November 27, 2008

++codeCompletion, and Signals/Slots in KDevelop4

Filed under: KDevelop — zwabel @ 2:27 am

It’s quite a while since my last blog now. I’m still planning to present all the essential C++ support features in KDevelop4, but my plan is to polish each feature up a bit before I actually blog about it. This also serves as a nice motivation. 🙂

In the last weeks, I have mainly worked on DUChain backend stuff, especially making it more efficient. Some important coneceptual scalability problems have been solved, although I have yet quite a few tricks in line to make the actual parsing faster. Temporarily I lost my motivation a little on this boring backend stuff, but in the last days I regained it, and implemented some long planned nice features that I’m going to present to you now. 🙂

Signals/Slots
Most Qt programmers love the signals and slots, since they allow getting stuff up and running really fast. But there is also some annoying things about them. For example that they are managed through simple strings, where Qt doesn’t even know about the real scope of the involved types, which leads to simple string-matching instead of comparing the real types. Also you need to write the complete function signature whenever you use a singal/slot, and me personally, I tend to do little mistakes while doing that, which can lead to really annoying little bugs, that aren’t catched by the compiler. It becomes even worse when you try to do refactoring like renaming signals, slots, or some of the involved types. Since the SIGNAL and SLOT macros translate the signatures to strings, grep is until now the only thing that can be of assistance here.

Now, KDevelop4 is coming to rescue. 🙂

The first thing needed was additionally recording the signatures of signals/slots in exactly the same way Qt sees them. This way, we can theoretically do exactly the same matching Qt does. But then there’s the problem of the SIGNAL/SLOT macros. With a correctly working preprocessor, those will leave relatively useless strings to the C++ parser. I have completely blocked these macros and internally replaced them with new macros, a new token, and some new structures in the parsing infrastructure, to _not_ do the same thing the compiler does. Instead, our C++ parser now completely processes the signature, and allows building uses for all involved types, and of course for the signals/slots themselves.

Together with these uses, now KDevelop4 allows you to see all places where a signal/slot is connected, intelligently rename it, and to intelligently rename any types involved in the signature. Of course, the uses are only built if a signal/slot with the given exact signature actually exists. Together with highlighting, this already now gives you an excellent tool to detect broken connections.

Essentially, this makes signal/slot connections a real well-understood first-class citizen of the DUChain.

Since people like screenshots, here you see how the uses of a slot are shown, and can be renamed.
Renaming

Signal/Slot Completion
Now the duchain integration allows excellent tracking of already existing connections. But the annoyance of actually writing the connections remains. In KDevelop3, there already was a quite cool code-completion for signals/slots, that inserted the correct complete signature four you, and thus saved you from typing. In KDevelop4 I had this thing on my list for a long time, and now finally I’ve implemented it. However since KDevelop4 is aiming a lot higher then the earlier version, this feature of course needed to be improved as well. 🙂

So here you see the new Signal/Slot completion, with complete realistic signature-matching, which helps you conveniently connecting only fitting signals/slots to each other. As you see I’ve also worked a bit on the completion-widget. The highlighting colors are much softer now. This picture doesn’t show the interesting “matching” part yet, since every signal matches the connect(..) function.
signal completion

In this picture, you see how the correct signature was inserted, and a new completion-list was opened, this time asking for the slot that he signal should be connected to. As you see, the only 2 perfectly matching slots are shown directly at the top. Since you can connect signals to slots with less arguments, the argument-less slots are shown as matches too, although with lower match-quality.
slot completion

That’s it with signals/slots for now.

Builtin Operator Completion
One more thing that has been on my list for a long time, and that I’ve finally implemented, is completion for all builtin operators in C++, not only the overloaded ones. By completion I mean mainly getting the match-quality highlighted, and getting the “Best Matches” list at top. You will be wondering how often you use some kind of builtin operator, from my experience this saves from a _lot_ of typing, since in many cases the wanted item is right at the top.

Builtin operator completion

Also I have added argument-hinting for the “return” keyword, which means you can also get best matches when returning a value from a function:
return completion

And that’s it for today. Hope you like the stuff, and as always, if you want KDevelop4 to get ready faster, consider getting your hands dirty. 😉

Advertisements

November 11, 2008

C++ Code Completion rethought: KDevelop4 in action

Filed under: Uncategorized — zwabel @ 3:25 am

From all the discussions I have had, I have learnt that there is two different types of users for Code Completion. For the first type, the code-completion is only there to speed up their typing. They think they don’t need to know what kind of items they are actually dealing with, because they think they know the library they’re working with. Then there is the second type: They want to use code-completion as a kind of inline documentation, for checking along the way that what they’re writing is actually correct, and additionally to speed up their writing.

I count myself to the second group. I want all the useful information I can get. If I’m not interested, I can still ignore it, but in most cases even if you’re knowing exactly what you’re working with, it’s still a better feeling to not only assume that what you’re writing is correct, but to know and see it.

KDevelop4 code-completion is here to fulfill these extended needs. Right when I started working on it more than a year ago, I had the vision: I want _all_ the information, wherever I am. When I’m watching something in the completion-list and wonder what that strange return-type is, I want to be able to find out easily, no rocks in my way please.

So one of the first things I did to the completion-list was allowing to embed arbitrary widgets into it, and to allow interacting with those widgets using the keyboard.
Additionally to that, the completion-list can always show some additional minimal information with each selected item. The place that information is shown follows the selection in a way that keeps the annoyance to a minimum, by never letting the item you’re currently focussing with your eye change its position.

Another advanced feature that I wanted to have was automatic matching of completion-items to the argument-hints. Using this, KDevelop should in many cases be able to predict what item the user is going to pick, and further speed up his writing. Since I had already implemented a C++ type-conversion framework based on the DUChain following the C++ standard in KDevelop, this mainly just needed a nice way of being presented. In the completion-widget each visible item in the completion-list is matched against each overloaded version of the called function, and the match-quality is indicated by blending the background-color between dark blue(worst) and light green(best). Additionally the list of best matches is shown at the top of the list.

But there’s more to kate’s completion-widget that have made it a really complicated yet powerful beast. When there is such an amount of information as you can show in C++ code completion, then you need a special way of presenting that information to get a usable result. Some items in the list are extremely long, some are very small. Still you want to be able to see all the information of all items. There was no way around making the completion-widget dynamically resizing itself and its columns, based on the currently presented content. This has been a problem for a long time, causing all kinds of flickering and uglyness.

During the last days I have taken an exact look at he actual code-completion again, trying to fix it’s most visible problems, give it some polish, and fixing pure bugs on it. Now I’d say that the code-completion is in a good shape, so here come the screenshots that might motivate you to try it out. 🙂

In this screenshot you can see how the type-matching automatically suggests the values of an enum while calling a function that takes that enum. Above you see the overloads of the function currently called, and how well the item selected in the completion list matches each of them.
Code completion and enum suggestion

Next you can see another case of argument-matching. Since KUrl has a constructor that takes QString, QString values are highlighted in dark green, while KUrl values that don’t require a conversion are highlighted in light green. Here you can also see the embedded navigation-widget in action. To show it, just push the “shift” button while the completion-list is open. Then you can navigate within it using SHIFT+(left/right/up/down/return).
Operator matching and embedded widget

This is a new feature I’ve implemented in the last days, and it’s a real life-saver, although probably quite common in IDEs: Code-completion within a class-body shows all virtual functions of parent-classes that have not been overridden yet. When the item is executed, a full virtual function declaration is created.
Override

Here you see the previous feature’s brother in action. When code-completion is invoked within a file, and that file’s header-file contains function-declarations that don’t have a definition yet, “Implement …” actions are shown at top of the completion-list. If such an action is executed, a complete implementation body is inserted.
Implement

The code-completion is really feature-rich. It works well with templates, and since it’s built on the duchain, it shares an architecture that is going to be improved permanently, so it can only become better. It may still contain some bugs, but it’s already far ahead of what KDevelop3 or many other C++ IDEs can deliver. It also contains some special goodies that I might cover in another blog. 🙂

Last but not least, since I told you earlier about the 2 user types, and to prevent bitching from purists, I’ve added an option a few days ago to get a “simple” completion, that approximately matches what you get from Qt Creator, here you see it in action:
Simple Completion
As you see the item currently selected in the completion-list is also highlighted in the document, which creates a visual connection between the list and the editor.

Btw. implementing this simple mode needed changing about 15 lines of code, so this is not a reason to create an own IDE. 😉

Notice: If you want to try out, use the most recent kdelibs and the most recent kdevplatform and kdevelop, since I checked in some important fixes right before writing this blog entry, after breaking some stuff yesterday.

November 5, 2008

KDevelop4: Now with refactoring!

Filed under: Uncategorized — zwabel @ 3:48 am

When I started hacking on KDevelop4 one and a half years ago the goal was clear: Use the duchain architecture, together with my previous code-completion programming experience, to build excellent C++ code-completion in KDevelop4. At that point I thought the duchain was a good representation of the C++ code, and only the user-interface part was missing. I didn’t know that it was still far away from that.

So after some time, it showed that all these goals were very ambitious:
1. Code-completion
2. Intelligent code-highlighting
3. Make it efficient, make the editor usable while the parser is working(A hard task in its own)
4. Simple local refactoring
5. Real Project-wide quickopen
6. Project-wide refactoring

The problem is that the duchain is a very detailed and expensive to compute code-representation. Just a year ago, if you would have let KDevelop4 parse the whole KDevplatform project into duchain, you would have had at a memory-usage of about 3 GB, and it would have taken a sheer endless amount of time. During this year’s summer of code project I tried changing that. The basic “theoretical” structure and API have stayed similar, but the whole backend is nearly rewritten in a way that now allows the duchain to at some point become more efficient than what we had in KDevelop3, and much more efficient than anything a java-IDE like Eclipse could ever get. 🙂

Anyway, given the fact that together with KDevelop4’s C++ support, an overwhelmingly big architecture had to be pulled, my plan for KDevelop release 4.0 was at least finishing goal 1, 2, 3, and 4. Due to the computational expense of the duchain, I thought 5 and 6 were just not realistic. Those were ment for KDevelop 4.1 at best.

During the last months or even just weeks, things have changed dramatically. The key was the idea to allow different processing-levels in the duchain. With a very low processing level, KDevelop will not process anything that is within a function-body, which takes away a large part of the complexity. Interested entities can now just tell the duchain that they want the data for specific files at a specific processing level, and the duchain will check whether the data is available, up-to-data, etc., if it’s not lets the background-parser crunch through the data once again using the correct processing level, and notifies the entity of the completely processed data. Since even in the lowest processing level, we always have the both way #include structure available, this enabled KDevelop to do complex use-searching or refactoring, based on a project that was only processed with the lowest processing level. The refactoring component just needs to walk the inclusion-path back to see all files from where the declarations are visible, then requests the duchain to return all those files in the highest processing-level which includes uses, and then perform whatever action is desired on those.

A few days ago I presented you the use-searching component, which was the first part that profitted from that architecture. Today I’ve spent my whole day creating a duchain based project-wide declaration rename functionality. This is a great feeling, because right from the beginning, this has always been the point farthest away. It requires a high level of precision and reliability from the duchain, which it finally actually seems to deliver. Don’t expect it to be perfect yet, since it’s largely untested, but expect it to be there. 🙂 One great thing about this is that this whole thing is language-independent, so it may work with any language that builds a DUChain, although we aren’t planning to ship anything else than C++ in the near future.

So here we go:
The functionality is accessibe through the context-menu, or through any other many that handles a Declaration. Just right-click the name of a Declaration in the editor window, and click “Rename …”.

pic1

pic2

pic3

Now you see a dialog that has two tabs. In the left tab, you see the uses-widget that I’ve presented last time, somewhat polished using ideas from a mockup posted as a comment to my last blog entry. It allows you getting an overview of the actions that will be performed, since it exactly shows the places that will be changed. In the second-tab there’s a html navigation-widget, that allows you seeing and navigating all kinds of informations about the declaration you are just renaming. At the top you see a line-edit, into which you can just write the new name, hit “replace”, and KDevelop gets going.

Currently you should not try this on your most central classes, because the computation may become very slow.

So now the most demanding tasks on C++ support are finally done. In the next time I’m going to try making it faster, fix bugs, and add a few yet missing smal code-completion features. So this area is on target for the 4.0 release.

Since my last blog touched off a lot of discussions about the UI, I’ve got enough of that, so please no comments about that area. Just one thing: We will try find a balance between feature discoverability, feature richness, and simpleness. Be sure that the count of menu-entries will be lower than on the screenshot, the count of default docks will probably be about the same. Now the real problems we still have to fix is project-management, building, debugging, etc. so if anyone wants to help, jump right on board. 🙂

In my next blogs, I will present more C++ features that are available in KDevelop4, and that I could not live without. 🙂

November 3, 2008

KDevelop4: Find all uses of “…”

Filed under: Uncategorized — zwabel @ 4:11 am

Hi planet! I’ve been registered a long time ago, but sadly this is my first post here. I’ve been too busy with getting “real” stuff done on KDevelop.

One short statement about Qt Creator: Imo they seem to have nearly the same goals KDevelop4 has: Modularized, platform-independent, light-weight, C++ oriented, with good Qt support.. why do they have to re-invent everything? I would have preferred them putting some resources into KDevelop4 instead. One thing is for sure: Their app may be stable, but feature-wise they are far behind, although I am biased to see this mainly from a C++ support perspective.

But now to KDevelop:

In KDevelop4, we have a language-independent structure for abstract code-representation called Definition-Use-Chain, that has been invented by Hamish Rodda a few years ago. When I started hacking on it soon 2 years ago for my Google Summer of Code project, he had stopped hacking on it for quite some time, and it was in a state you can call “experimental” at best. Nearly 2 years of hacking have passed, which were really hard years of instability, without the target visible on the horizon, without even knowing whether this stuff I’m working on even just “can” work out. Hamish came back about a year ago, and since then has been a pushing force on KDevelop4 again, also helping me with the kate problems that I really didn’t have any insight to. Anyway it was a monster-task. I often had to work on 3 places at the same time: kate, kdevplatform(duchain), and kdevelop(C++ support), all with tons of code that was until then exclusively used by KDevelop’s until then unfunctional C++ support, which means that lots of this code was unfinished and unstable.

The good news: All the pain is starting to pay off. 🙂 This April we had our Developer meeting in Munich, and since then the development has heated up, and I think we’re on track to get a stable release out within the next half year.

I have very high demands in the C++ support, and now they are starting to be satisfied. KDevelop4 has reached a state now, that I actually finally can suggest interested people to try it out. It’s important that you have recent kdelibs + kdevplatform + kdevelop, because all of them have seen some quite important changes in this area in the last weeks.

Since we got new competition from a direction from where I actually would have expected support instead, I feel motivated now to present you some of the nice features KDevelop4 has, so we don’t lose too much of the public interest.

The last days I have worked hard on finishing the basics for refactoring and use-searching, aka “find all calls of this function”, and got that ready. I’ve put it into a re-usable base-class, so functionalities that need this backward-searching are very easy to implement now. What mainly comes into mind is intelligent renaming/refactoring and call-graphs, which is just a matter of writing a user-interface for it with this in place.

Also I’ve continued polishing the widget to show this information.
Here you’ve got a nice screenshot:
Screenshot of KDevelop4 with the uses-widget

At the top you see the editor-window, and at the bottom the code-browser which currently shows the uses of KDevelop::DUContext. The buttons are used to expand/unexpand the uses in the file. Then each file is split up into “Contexts”, which are functions or class-declarations. This allows you to get a fast overview in what place the use occurs. A tooltip over the line shows also the surrounding lines of eeach use, and clicking on the link on the left side jumps to the use directly in the editor window.

Next time I’m going to present you another nice feature of KDevelop4. 🙂

Create a free website or blog at WordPress.com.