[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kdevelop-devel
Subject:    KDevelop4 architecture overview
From:       Alexander Dymo <dymo () ukrpost ! ua>
Date:       2007-03-16 20:28:10
Message-ID: 200703162228.11219.dymo () ukrpost ! ua
[Download RAW message or body]

Hi!
There was a lot of work done recently restructuring, refactoring and improving
KDevelop4 architecture during January and February. This means that a lot of
things were changed and now I'd like to give a little overview of what 
happened and what KDevelop4 architecture looks like now to keep 
everyone here up-to-date.

This large rework is almost over, there're a few bits not yet ported
(like DocumentController) but that will come soon. Since now I do not
expect any revolutional changes in the architecture, only additions
and improvements as usual.

The main goal of the rework completed by yours trully and Andreas was to
transfer good things from KDevelop3 into KDevelop4 while keeping
all the cool KDevelop4-only stuff done by Hamish, Adam, Roberto and Matt.

What was done:
- the interfaces are separated from shell classes
- plugins no longer link to the shell that loads them
- directory hierarchy was cleaned up and reorganized
- project management and language support infrastructure
  underwent a major rework
- the new Sublime UI is in place

What is pending:
- document controller
- profile support (code is there, it's just not used)

What is planned (only major arch changes):
- unification of DUChain with the goal to extract common du-chain
  code useful for all language supports

What does that mean to you:
I do hope that means that KDevelop4 now is a relatively stable platform
to develop against. You can write plugins or fix/improve the shell
without worrying that your work will be obsolete tomorrow.

Hope the attached document helps. By all means, please bug me if something
is wrong/missing/unclear in the document.

PS: if you're still hacking on 3.4, give up! KDevelop4 is waiting for you ;)

["kdev4_arch_design" (text/x-java)]

The brief explanation of current KDevelop4 architecture and its differences from \
KDevelop3.

1. Platform VS Others

The idea is that platform code (currently in lib/) contains:
a) everything to create platform plugins
b) everything to create platform applications
c) commonly used/important plugins



2. Platform Code Layout

Platform consists of
a) lib/interfaces
    interfaces that expose everything necessary for plugins
b) lib/shell
    shell that implements interfaces and basically provides a ready-to-use and extend \
application c) lib/sublime
    the user interface library
d) lib/project and lib/language
    additional libraries for project managers and language supports (usable for other \
plugins as well) e) lib/config, lib/editor, etc.
    additional libraries usable for both shell and plugins



3. What to Use in Plugins

a) plugins need to link to interfaces
b) plugins shall never link to shell
c) plugins need not to link to sublime library
c) plugins can optionally link to other helper libraries in platform when necessary



4. Current Platform Coding Conventions

a) preferred coding style is \
http://www.kdevelop.org/mediawiki/index.php/Coding_Guidelines b) all platform classes \
shall be in KDevelop namespace c) all files have to be named without kdev* prefix
d) all files have to be installed in subdirectories under \
${INCLUDE_INSTALL_DIR}/kdevelop/ e) all interfaces are named KDevelop::IFoo and their \
files ifoo.h/cpp g) all interface implementations are named KDevelop::Foo and their \
files foo.h/cpp


5. Platform Overview

5.1 ICore/Core

As in KDevelop3, the central object that gives access to all shell functionality is \
Core. There's a ICore interface and Core implementation. ICore interface gives access \
to all controllers exposed via interfaces. Each plugin is initialized with ICore \
pointer so it always has access to core via IPlugin::core() method. There's no need \
for something like KDevelop3's KDevAPI class anymore.

Core is a singleton that needs to be manually initialized by platform application \
using Core::initialize() right after the KApplication object is created and \
ShellExtension is initialized. ShellExtension is the same thing as in KDevelop3 - the \
way to platform application to tell which UI configuration files are used and what is \
the default profile. KDevelop4 shell extension's only difference is defaultArea() \
method which shall return the name of default UI area (see below for more information \
about areas).


5.2 IPlugin

Just like in KDevelop3, IPlugin is what all plugins need to inherit. But unlike \
KDevelop3 IPlugin is not meant to be subclassed via other interfaces. In KDevelop3 \
several interfaces were called "extension interfaces" (like KDevMakeFrontend, \
KDevCreateFile and others) and they subclassed KDevPlugin and provided their own \
.desktop files with servicetypes. This is not necessary anymore in KDevelop4. We have \
another extension framework in place (see below).

It was necessary to create KDevPluginInfo instance to instantiate any KDevPlugin \
implementation in KDevelop3. This is also not needed in KDevelop4. It is sufficient \
                to write plugin information to plugin's
.desktop file as described in KPluginInfo class documentation.


5.3 Extension Interfaces and Plugins

The idea behind extension interfaces is to provide following features:
- To allow plugins to expose their functionality via abstract interfaces
  and at the same time do not care about BC and do not force other plugins to link \
with them.  Documentation plugin would be a good example of non-core but still \
sometimes useful functionality  that might be exported via IDocumentation extension \
interface with methods like  lookupInDocumentation(const QString &) and others.
  KDevelop4's outputview plugin with IOutputView interface is also a good and \
actually working  example of such use-case.

- To have implementations of important functionality not in a shell, but in plugins.
  Good examples are buildsystem managers, builders and language supports in \
KDevelop4.  When a project is opened, a buildsystem manager plugin (that implements \
either  IBuildSystemManager interface or IProjectFileManager) is looked for by the \
shell an loaded.

- To forget about BC issues of dependent plugins. In case the plugin has something \
new to expose,  the new version of extension interface has to be defined. All other \
plugins will either  continue using old interface or ask for the new one.

The extension interfaces framework is implemented with QExtensionManager and Co. See \
the Qt documentation for reference.

5.3.1 To declare extension interface:
- Create an abstract class
- Include <iextension.h>
- Add following macroses to the header file with a class:
    KDEV_DECLARE_EXTENSION_INTERFACE( KDevelop, IMyInterface, \
"org.kdevelop.IMyInterface")  Q_DECLARE_INTERFACE( KDevelop::IMyInterface, \
"org.kdevelop.IMyInterface" )

5.3.2 To implement extension interface:
- Create a plugin as usual
- Subclass it from your interface
- Use Q_INTERFACES macro in class declaration
- reimplement QStringList IPlugin::extensions() method
- declare in plugin's .desktop file:
    X-KDevelop-Interfaces=IMyInterface

Code Example:
class MyPlugin: public KDevelop::IPlugin, public KDevelop::IMyInterface {
    Q_OBJECT
    Q_INTERFACES(KDevelop::IMyInterface)
public:
    QStringList extensions() const { return QStringList() << "IMyInterface" }
};

5.3.3 To load a plugin that supports extension interface:
- Use IPluginController::pluginForExtension() method if you have only one possible
  plugin implementing the extension interface
- Or use IPluginController::allPluginsForExtension() method to return a list of \
plugins.  Note, that those methods will load plugins if they are not yet loaded
- Once IPlugin pointer is returned by one of two methods above, it can be asked for \
an  extension using IPlugin::extension<>() method ( like \
plugin->extension<IMyInterface>() )

5.3.4 To set a dependency between plugins:
- Set the list of required interfaces in plugin's .desktop file
    X-KDevelop-IRequired=IMyInterface,IMyOtherInterface
It is not possible to set direct inter-plugin dependencies. The plugin shall never \
expect another plugin, it shall only expect an interface.


5.4 IProject, IProjectController and Project Management Infrastructure

Unlike KDevelop3, KDevelop4 can load many projects at the same time.

The project management infrastructure can be represented with following diagram (use \
fixed font to see it):

                              |----------|       |---------------------|
                        |---->| IProject |------>| IProjectFileManager |
                        |     |----------|       |---------------------|
                        |
> --------------------|  |     |----------|       |---------------------|
> IProjectController |------->| IProject |------>| IProjectFileManager |
> --------------------|  |     |----------|       |---------------------|
          |             |
          |             |     |----------|       |---------------------|
          |             |---->| IProject |------>| IProjectFileManager |
          |                   |----------|       |---------------------|
          |
          |    |--------------|
          |--->| ProjectModel |
               |--------------|

Project controller is a container for projects (IProject interface). Each project \
contributes its contents (files, folders, targets, etc.) to the ProjectModel. Each \
project also have a "project file manager" associated with it.
Project file manager is the plugin which implements either IProjectFileManager or \
IBuildSystemManager and provides all actual project management facilities.
This way KDevelop4 is able to load as many projects as desired and each of the \
project can have different build system. Every plugin that wants to display whatever \
is in projects can use ProjectModel.

KDevelop supports the notion of "current project" (the one which is currently \
selected) in the project management view). But plugins are encouraged to not depend \
on it. The selection might be empty or project management view might be closed at any \
time.

KDevelop Platform provides by default "GenericProjectManager" which just threats all \
files and subdirectories under project directory as project items and currently \
provides no building facilities.

The project file (<projectname>.kdev4) controls which project file manager will be \
loaded. For example, this .kdev4 file will load Generic manager:
    [General Options]
    Manager=KDevGenericManager


5.5 ILanguage, ILanguageController and Language Support Infrastructure

The language support infrastructure is designed to be similar to project management.
Its goals are:
- use as many language supports as necessary at the same time
- be able to load several language supports for one source file
  good examples are mixed-source files like .php (php+html), .rhtml (ruby + html)
- be not dependent on projects

The language support infrastructure can be represented with following diagram (use \
fixed font to see it):

                                                      |------------------|
                                                |---->| ILanguageSupport |
                               |-----------|    |     |------------------|
                         |---->| ILanguage |----|
                         |     |-----------|    |     |------------------|
                         |                      |---->| BackgroundParser |
> ---------------------|  |                            |------------------|
> ILanguageController |--|
> ---------------------|  |                            |------------------|
                         |                      |---->| ILanguageSupport |
                         |     |-----------|    |     |------------------|
                         |---->| ILanguage |----|
                               |-----------|    |     |------------------|
                                                |---->| BackgroundParser |
                                                      |------------------|

LanguageController holds the set of already loaded languages and provides means to \
load more. For each language (defined by its "name") Language object exists. Each \
such language has a background parser and a actual support plugin that implements \
ILanguageSupport. This way the basic shell functionality (like language loading \
algorithm and background parser) is separated from language-specific stuff (like \
parsing).

Unlike KDevelop3, language support plugin is loaded not among with a project. \
Instead, when the source file is opened, the language controller asks plugin \
controller whether there are any language plugins (those that implement \
ILanguageSupport) that support a mime type of the file (those who set \
X-KDevelop-SupportedMimeTypes=...).

For each language support plugin found, the Language object (that implements \
ILanguage interface) is created and language support plugin is associated with it. \
Then each language is asked to return a ParseJob to process the file. This way \
several language supports are able to parse one file.

If Language object for given mimetype already exists, it is used and no plugin \
loading is performed.


5.6 IUiController

UiController is closely connected to the Sublime UI and basically is an subclass of \
Sublime::Controller which will be explained later.

The main job of UiController is to allow plugins to manager their views and \
toolviews. Currently only toolviews can be added and removed.

Sublime UI wants plugins to add and remove not actual toolviews, but factories to \
create them. This is because user can request from Sublime UI to show a new toolview \
at any time. For example, it is possible to have more than one Konsole toolviews. The \
user just have to ask for them. Automatically factory will be used only once, when UI \
controller is asked to add a toolview. This means for example that only one Konsole \
toolview will be opened automatically.

To create a factory, a plugin needs to subclass KDevelop::IToolViewFactory and \
                implement two methods:
- virtual QWidget* create(QWidget *parent = 0)
  where the actual toolview widget will be created
- virtual Qt::DockWidgetArea defaultPosition(const QString &areaName)
  which will give the UI a hint on where to place the toolview

Once the factory is ready, it has to be added to the UiController using
IUiController::addToolView() method.
It is not absolutely necessary for a plugin to remove or delete toolview factory. \
UiController will delete them all upon unload.

NOTE: temporarily, IUiController has openUrl() method which is the only way to open \
files in KDevelop until DocumentController is ported.



6. Sublime UI

6.1 Modus Operandi

- UI provides support for "areas" (alike Eclipse's perspectives)
- The basic set of areas is:
  - code editing area with splitted editor windows
    (with kate/konqueror-like splitting)
  - debugging area
    (Xcode-like debugger window with only one editor view by default but with \
                possiblility to show more)
  - profiling area
    (like KCacheGrind)
  - user interface design area
    (like Qt designer)
- Area configuration includes code editor windows (unlike eclipse)
- Each area can be displayed in usual Qt mainwindow with toolviews in dockwidgets
- Areas are shown in separate mainwindows so that multiple-monitor setups become the \
                best supported
- One area can be shown in two and more mainwindows by "cloning" the area
  (unlike Eclipse that pretends that two mainwindows show the same area)
- Optionally areas can be switched inside the same mainwindow without opening new \
ones  (like in Eclipse), but this mode of operation is currently not implemented.
  Also Sublime was not optimized for this use-case. See wiki pages for a detailed \
discussion and  explanation of possible problems.
- It is possible to open as many similar toolviews as necessary (for example, several \
                konsole's)
- It is possible to open several views for the same file in code editor view (unlike \
                KDevelop 3.x)
- Instead of tabs for editor windows a "switcher" is provided.
  Currently the switcher is a combobox but that will change for sure.


6.2 Brief Architecture Overview

Sublime::Controller is the central point of the whole Sublime infrastructure. It \
contains areas, documents and controlls mainwindows.
Sublime::Controller::showArea() is the only way to show an area in the mainwindow.

Sublime::MainWindow is just a KParts::MainWindow which just knows how to \
"reconstruct" the area, react on area changes. Additionally it knows which view and \
toolview is "active" (i.e. last focused).

Sublime::Area is the object that controls views, toolviews and defines their \
placement inside the mainwindow. Provides varous view management (e.g. \
add/remove/etc.) methods and signals. Also Area is responsible to store/restore view \
layout (on-disk storage is not implemented currently).

Area is identified by its name. Each KDevelop platform application, for example, has \
to define a concept of "default area" in ShellExtension so that UiController can load \
it by default.

While areas operate on views, the Sublime Controller deals with Sublime::Document's \
only. Sublime::View is only a thin wrapper around actual QWidget.

Document is what provides views. Sublime::Document::createView() is the only way to \
get a view. When createView() is called, the protected \
Sublime::Document::createViewWidget() is called to return the actual widget for a \
view.

There is an abstract Sublime::Document class with no createViewWidget() \
implementation and there's a convenience class Sublime::ToolDocument that can create \
widgets of user-specified type.

KDevelop currently uses Sublime::PartDocument which is subclassed by \
KDevelop::PartDocument. This PartDocument creates a view by loading a part and then \
asking a part about its widget.



_______________________________________________
KDevelop-devel mailing list
KDevelop-devel@kdevelop.org
https://barney.cs.uni-potsdam.de/mailman/listinfo/kdevelop-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic