Skip to content

Summary of last fortnight's hacking on KDevelop

Sunday, 3 September 2006  |  Blackarrow

Firstly, thanks to clee for adding me to the Planet. When I left Trysil I planned to blog more often, and now you too can read about it :)

So, for the last 2 weeks I've been on annual leave, and have had the fortune to be "on a roll" with my coding. I'm currently concentrating on KDevelop 4. We're privileged to have a new parser framework by Roberto Raggi and Jakob Petsovits. I've been working on extending this good work with a new type system and definition-use chain.

The definition-use chain is a sequence of scopes in a code file, and the associated definitions which occur in those scopes. These are created on the first pass after parsing to an AST (abstract syntax tree), along with the data types. On the second pass, we search for a definition which corresponds to every variable use, and complete the chain. This work is now nearing completion; remaining issues are template support, and better forward declaration and typedef support. I also have to reconsider the use of shared pointers in the type system, because as Roberto pointed out, C++ allows recursive types (which don't work well with shared pointers). Here's a look at some of the highlighting possible with the definition-use chain: (please ignore the bugs ;)

On Thursday, I implemented code completion. This is the first real use of the new model-based code completion that I wrote for Kate. By expressing the possible completions in a model, and properties associated with each (eg. public/protected/private, etc), Kate can then perform some advanced functions such as sorting, filtering, and grouping. I'll post a screenshot when I can undo some recent breakage.

On Friday I implemented a symbol table, which contains a reference to every definition currently in memory (from all files). I should have done this a week ago - it turned out to be quite simple. Now, hopefully the definition searching will scale up to handle the load when we have all includes parsed in.

[Side note: did you know that Print Screen invokes KSnapshot? a neat trick I learned by accident]

Some work has also gone into performance of this new system, which has paid handsome dividends thanks to valgrind/callgrind/KCachegrind. Parsing speed was increased by 80%, thanks to the removal of dependance on QTextStream in the preprocessor, an unused symbol table in the parser, and KUrl comparisons in the definition-use chain (which I was surprised about... I thought it would be much quicker given that they should be implicitly shared). More recently, I've optimised the most heavily used paths in the definition searching algorithms, and was pleasantly surprised at the performance increase when switching a critical foreach loop into a const iterator style. Also, I've discovered QVarLengthArray in optimising our QualifiedIdentifier class; as they are created and destroyed very often, reducing the list overhead was important (note to self: maybe making them implicitly shared would help even more).

So, where to from now? We're reaching a fairly stable api, and one which allows for code refactoring, intelligent navigation, improved automatic code generation (eg. I'm looking forward to "create switch statement"), context-sensitive code completion, integration of documentation, debugger integration, a code structure view, call graph, static code analysis etc. If you're interested in helping, we'd love to hear from you :) [as manyoso would say, especially if you have QGraphicsView mad skillz].