[handly-dev] Initial API and implementation for the model object
Another major feature I'm planning for the 0.6 release is the initial API and
implementation for the model object .
Currently, the concept of the model as the owner of elements is not reified --
there is no object with a corresponding API that would represent the model
as a whole.
I think that having an object representing the model in a generic way would
be useful for several reasons:
* Testing whether two elements belong to the same model or whether an element
belongs to a specific model;
* Accessing information and services pertaining to the model as a whole;
* Checking the Handly API level supported by a model.
We should not make an assumption that the model object is the root element --
in general, it might be a separate entity, like IWorkspace (vs. IWorkspaceRoot)
or AST (vs. ASTNode) exemplify.
The above requirements can be addressed by:
* Making it possible to navigate from an element to the owning model and
use the equals method to compare the models;
* Letting the model provide a context object (the model's context);
* Having model implementations specify the Handly API level they support.
(Usually, the API level corresponds to the version of Handly the model was
Please see bug 500653  for more details.
I have pushed a proposed patch to Gerrit:
A reason why I'd like to draw your attention to this patch is that it affects
existing model implementations in a breaking way. The Elements are now
supposed to return an IModelManager. It is through the model manager
an Element is going to access things like ElementManager and the model object
(IModel) itself. In other words, IModelManager is the Element's central access point
for all information and services pertaining to the model as a whole.
It may be instructive to take a look at the patch and see how
these changes affect the example model implementations.
I'd also like to discuss a specific decision I've come to with respect to IModel API.
For the model, I decided against following the pattern of having a marker interface,
an extension interface, an impl interface, and a "static facade" class, as currently
used for elements and element deltas. My judgement is that it would be an overkill
in this case for the following reasons:
* I expect IModel to be stable. Other model-related funtionality (services
or data objects) can always be introduced through the model's context.
* There is no requirement for IModel to be an element. It may be implemented
by any model-specific singleton. Therefore, source compatibility issues
(method conflicts), if they do arise, can always be solved by implementing
IModel in a separate, dedicated class. For this to work, however, you should
not extend IModel in your API (e.g. IFooModel should NOT extend IModel).
I don't think this to be a serious limitation because:
* IModel is intended to be a meta-level API. One can always navigate from
any element to its model generically with Elements.getModel(IElement).
However, if you would like to expose a subset of the IModel functionality
(e.g. the ability to provide the model's context) in your API (e.g. in IFooModel),
you can always implement it by delegating to the model object, as singletons
are easily composable. Besides, although it is not recommended to *extend*
IModel, you may *implement* it in a model element such as the FooModel class.
In fact, the example model implementations in Handly follow this very tactic.
I would appreciate any comments. By default, I'm planning to rebase this patch
on the patch discussed earlier and push them both to the master branch
some time next week, if there are no concerns raised. If you need more time
for a review, please let me know.