|renaming of "declaration-by-reference-objects" [message #1420569]
||Wed, 10 September 2014 06:40
| Knut Wannheden
Registered: July 2009
This is basically a success story of using Xtext's rename refactoring in
a slightly complicated setup. Maybe it is useful to someone, as the
Xtext rename refactoring framework is quite complex.
I have two DSLs between which I have cross-references and where I would
like to support rename refactorings for some declarations. The two DSLs
can be compared to a DSL for the SQL "CREATE TABLE" DDL statement and
another DSL for the "CREATE VIEW" statement. So I could have something
create table foo(
create view foo_v as
select id, val
where val is not null;
A simplified view of my Ecore models:
- EClass table::Column with an attribute "name"
- EClass view::Column with an attribute "alias" and a containment
reference "expression" of type view::FeatureCall
- EClass view::FeatureCall with a cross-reference "ref" of type EObject
In the example above I would then have an instance of table::Column for
the "val" column in FOO.TABLE, an instance of view::Column for the "val"
column in FOO_V.VIEW (in this case there is no explicit alias) which
contains an instance of view::FeatureCall cross-referencing the
table::Column object, and a second view::FeatureCall object now
cross-referencing the view::Column object. I hope that still makes sense.
Now I want to support rename refactorings for table::Column. Obviously,
renaming "val" to "value" in the example should replace all three
occurrences of "val" with "value". (An alternative would be to keep the
last one as "val" and add an alias to the view::Column as in "value as
This is what I had to do to implement this in Xtext:
1. The out-of-the-box renaming would correctly rename the table::Column
and adjust the reference of the first view::FeatureCall. But the second
FeatureCall reference would not get renamed. To solve this I implemented
a custom IReferenceUpdater (for the view DSL) which in this case in
createReferenceUpdate() also adjusts all local references to the
view::Column. It does this by using an injected IReferenceFinder and
Provider<EditorResourceAccess> to find all references and then calls the
createReferenceUpdate() method for those.
2. Trying to rename the table::Column by invoking the rename on the
second FeatureCall (referencing the view::Column) doesn't work
out-of-the-box. Here I was able to override the IRenameContextFactory
(for the view DSL) to instead delegate the rename to the corresponding
Thanks for the very customizable rename refactoring framework!
Powered by FUDForum
. Page generated in 0.02409 seconds