[handly-dev] On the way to non-breaking evolution
A major feature of the 0.6 release is the introduction of contexts 
as a means of facilitating future evolution of Handly.
Fundamentally, a context supplies values (data objects or services)
associated with keys. When used as a method parameter or return value,
it enables a more loosely coupled functional interaction and therefore
allows for more independent variability of the participants of the
interaction (a caller and a callee).
Composite contexts can emulate a 'dynamic scope' or 'dynamic binding'
available in some programming languages and used to a great effect in such
extensible systems as EMACS .
The interface org.eclipse.handly.context.IContext enables such
context-facilitated functional interactions to remain type-safe
by supporting two kinds of keys: org.eclipse.handly.util.Property
and java.lang.Class. The Property class has been moved from the
org.eclipse.handly.model package  and generalized to retain
type information at runtime  and to be able to provide a default value .
As a first application of contexts in Handly, the org.eclipse.handly.model.ToStringStyle
class has been replaced with a context . I quite liked the result, which I think is
a more general and evolvable design, so I decided to try and extrapolate it
right to the core by making some of the other methods in the Element hierarchy
Again, a goal here is to enable non-breaking evolution in the future.
However, such re-design does come with an immediate cost:
* It introduces a bit of additional complexity, as is typical with a more loosely
coupled designs (see, for example, )
* It requires a number of significant breaking changes in existing model
My judgement is that the complexity is manageable and the cost is justified,
but adopters may think otherwise.
That's why I'd like to draw your attention to the patch in Gerrit
before I merge it.
This is a rather large patch, but the most relevent changes are in
the classes Element and SourceFile.
Specifically, Element#hBuildStructure signature has changed to take a context
instead of the 'body' and 'newElements' arguments. Implementations are supposed
to create and initialize the necessary bodies and put them in the NEW_ELEMENTS
map in the given context. Besides making for a very simple and generic method
signature, such design makes it very easy to introduce additional parameters
(i.e. new context properties) and allows to deprecate and replace existing ones
(e.g. introduce an element requestor in place of the NEW_ELEMENTS map,
if deemed necessary) in a non-breaking fashion.
Similarly, the abstract method SourceFile#hBuildStructure takes an AST
(represented generically as an Object) and a context. The AST is created
with #hCreateAst method that takes a source string and a context, which may
contain parser options. The reconciling infrastructure ensures that a context
passed to the #hReconcile method is propagated (in an augmented form) to
#hCreateAst and, through ReconcileOperation#reconcile, to #hBuildStructure.
In particular, this makes it possible to specify parser options in the #hReconcile
method's context (see org.eclipse.handly.internal.examples.javamodel.CompilationUnit
#reconcile for an example).
There are other changes as well, but those listed above seem to be the most
affecting ones. It may be instructive to take a look at the patch and see how
these changes affect the example model implementations.
I would appreciate any feedback. Please let me know if there are
any questions or concerns.