Table of Contents
Code Recommenders uses an event bus to get rid of all kind of listener interfaces. Although considered to be used internally mostly, the bus may be used by other subscribers (such as usage data collectors, indexing services etc.) to respond to events such as compilation unit changes, project creations or deletions etc.
To subscribe to the event bus one has to obtain an instance of
using Code Recommenders' injection service (or Guice Injector).
Event providers using the workspace event bus:
JavaElementEventsProvider: a provider that sends events such as project open/close or compilation unit added/removed/changed/saved events. See the section called “JavaElement Events Provider” for more details on this provider.
Code Recommenders offers an AST caching service that can be used by completion engines to get the last know ast of a compilation unit.
Do we still need that? Why not use the AST that is send with the compilation unit?
sends events such as project open/close or compilation unit added/removed/changed/saved events. This list
is incomplete and is expected to grow quickly for 1.0. Look at the corresponding class to learn which events it
posts to the event bus.
This example briefly illustrates the graph structure used to create call chains by a simple example:
ExecutorService pool = Executors.newCachedThreadPool(); Future future = $
CallChainCompletionProposalComputer: Extracts the available information about accessible locals, fields and methods to find all potential entry-points for the
CallChainCompletionProposal: The proposal that gets executed when the user selects the proposal from code completion window. It internally relies on a (jdt)
Templatebuilt by the
CompletionTemplateBuilder: builds, as the name suggests, the Java template. It does quite a lot JDT internal magic and is considered unclean and yet incomplete (!).
GraphBuilder: Creates the call chain graph. Uses a thread pool internally for building the graph (but not for creating the call chains). This might change?
TypeNode: represents the class node in a call chain. It stores the incoming edges which are later used to travers the graph and build the call chains.
MemberEdge: represents a transition from one type to another, typically an IMethod, IType, or ILocalVariable (for entry points only).
central controller; manages the registering and unregistering of
all components on the
listens for selection events and delegates them to the
to persist the width of the
(vertical separator between overview and content).
Manages the subscriptions for specific java selections of all
Can be queried to return a matching
for a given provider that should be called for the selection. No
guarantees are provided
which method is returned if multiple
methods of a provider overlap.
Manages the multithreaded execution of all providers. To indicate
the status of
the execution corresponding execution events are
posted to the
Extdoc providers are the entities of the extdoc view that bring
the real content. Providers are registered via the extension point
The content is provided through methods that are annotated with a
annotation. More details on
this and an example provider is given
to access their
is injected to all entities that need to know the providers.
darstellung des status aktivierung / deaktivierung order change insb. das management in der liste
manages the displayed content. A new (background) rendering
can be created and the corresponding
can be accessed for each provider.
Helper class for the visualization of the providers. Mainly
accessed by the
it can be used to set a status or to show the contents of
provider when it is completely rendered.
This entity is left out in the diagram. It is registered on the
and used to persist the provider configuration to disc on change.
The provider configuration consists of the order of all providers
and of a list of all disabled providers.
This entity is left out in the diagram. It directly accesses Eclipses singletons to be able to load and save preferences. A low-level API is provided to load/store:
order of the providers
position of the sash in the Extdoc view
This entity is mainly used to increase the testability of all entities that make use of it as they do not need to access Eclipses singletons and this class can be exchanged with a mock for testing.
is posted to the extdoc view.
is created and the old one is disposed.
is used to identify the providers that are interested in the
A new (hidden) rendering panel is created in the
For each provider the new content area is requested and used as a
parameter for the provider execution. This is done by the
in multiple threads.
updates the provider icons according to the posted execution events
of all providers.
listen for the resulting events and update their displayed data
accordingly. On finish events the hidden content area of the
provider is shown, delay and fail events lead to a status message.
listens for the
and switches the rendering panel to the new foreground panel if it
This example is a conceptual view onto the events that are posted during the provider execution. For this example it is assumed that three providers are registered:
P1 is a fast provider that terminates correctly.
P2 is a provider that crashes on execution with an exception.
P3 is a provider that terminates correctly but takes very long.
The entry point is the
call from the extdoc view. The current selection is provided as a
parameter and a
is posted. Based on the selection
all subscribed provider methods are
queried from the
is posted for each provider and the execution is started in separate
threads. Additionally a timeout is started to be able to guarantee a
maximum rendering time for the Extdoc view.
P1 finishes first and the successful execution triggers the posting
. The event contains the corresponding provider. P2 crashes on
execution and the caught exception triggers a
. Also P3 is not finished yet the render timeout is reached so the
next event is a
s for all still running providers.
. P3 terminaes successfully after
this and a
In addition to the normal execution events it is possible that a provider is not interested in a selection. This is possible in two different ways:
If a provider is not subscribed to a selection the
does not find a suitable method.
A provider might detect during the execution that no data is
available to successfully process the selection. In this case a
can be returned.
In both cases a
is posted for the provider.
Several other events exist:
: indicates a reordering of the providers
: posted if providers are enabled/disabled. Both are consumed by
. Activation events lead to the execution of the provider with the
last selection, deactivation events cancel the running provider.
: if providers are selected in the overview the content shuld
"jump" to their positions in the content. This event is
used to indicate such a selection and is irrelevant for the
All these are posted from the UI components and not from the scheduler.
Description of the Layout
ExtdocView: Central view that is registered with Eclipse and container for all sub content parts.
ProviderOverviewPart: Manages an overview of all available Extdoc providers in a table. Each provider can be de-/activated by un-/checking the associated
ProviderItem. The order of the providers can be changed through drag and drop.
: Manages a scrolling stack of content panes. Allows to create a
new (background) rendering
s for all providers.
is registered on the
and subscribes all provider related events.
Depending on the
execution status a providers area is shown or the status is set.
ContentPane (Composite)simple composite that contains all rendered content for a selection
ProviderArea: area that is associated with an Extdoc provider. Allows to set an (optionally clickable) status and to show the rendered content. All sub elements are plain SWT components and with the exception of the content that is provided to the
ExtdocProviderall are hidden to the outside. Renders a title for the associated provider.
TitleArea (Composite)status for a providers. It is used at the moment to show delay in execution or to show execution failures.
StatusArea (Composite)status for a providers. It is used at the moment to show delay in execution or to show execution failures.
ContentArea (Composite)Composite that contains the rendered results of the corresponding provider.
is registered on the
To be recognized as an provider its methods need to be annotated
annotation. The parameter list of such methods is fixed:
(or a subclass of it)
defines for which elements this methods
provides some content.
into which the contents should be rendered
Three examples are shown in the following diagram.
The simplest case is shown in the method
. The annotation indicates that it is interested in all
. Because the first parameter is an
(the super class of all selectable java elements) the method is
executed for all possible events.
It is possible to use the annotation and the
as a filter
to be able to write more specialized provider methods. An
example of this is given in method
The annotation take optional arguments to specify locations for
which a selection should be processed.
It is possible to provide
multiple locations, i.e.:
The events are also matched by the selected java element so it is
possible to only subscribe for
selections if it is used as the first parameter.
Word of caution: if method subscriptions overlap (like it is in this example) only on method is called on an event. No guarantees are given which one.
The providers are executed in their own thread so it is
switch to the UI thread for the rendering.
Take a look on the two
parts of the
All non-UI related information gathering should be done in the
After that a
can be executed with the helper method
. By doing so exceptions that are thrown in the runnable are bubbled
out of the
and rethrown in the provider thread.
The execution is run sync so that
the providers does not finish until the rendering is complete.
A provider can return an
to indicate its processing status.
A normal execution returns
If it is not possible to process the current selection (i.e. because
the provider has no data available), it is possible to return
The provider status is then handled by the UI as if it is not
subscribed even if it has already started processing.
It is feasible to throw an exception in a provider as shown in method
In this case the provider is shown as failed in the UI and a link is
shown that opens a dialog with a stacktrace and the message from the