Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Refactoring with importedNamespace and qualified name
Refactoring with importedNamespace and qualified name [message #874222] Sun, 20 May 2012 07:37 Go to next message
CRASNIER Stéphane is currently offline CRASNIER StéphaneFriend
Messages: 13
Registered: May 2012
Junior Member
Hi all,

I try to use the refactoring functionality with importedNamespace.

I have the following error :
org.eclipse.xtext.conversion.ValueConverterException: ID 'BA00012.DOBA002' contains invalid characters: '.' (0x2e)


It is thrown in the getCrossReferenceNameFromScope method of org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer here :
String unconverted = qualifiedNameConverter.toString(desc.getName());
try {
    return valueConverter.toString(unconverted, ruleName);
} catch (ValueConverterException e) {


It seems that the refactor try to replace the fully qualified name of the cross reference instead of the last segment of the qualified name so that the ID rule from the Terminals is violated. It's OK without using importedNamespace but it's not my case.

While debugging, I've found the following comment in the org.eclipse.xtext.ui.refactoring.impl.DefaultReferenceUpdater class :
				
if (newReferenceText != null) 
					// TODO: add import hook
					TextEdit referenceEdit = new ReplaceEdit(referenceTextRegion.getOffset(),
							referenceTextRegion.getLength(), newReferenceText);
					updateAcceptor.accept(referringResourceURI, referenceEdit);
				}


Please, does it mean that the refactoring with importedNamespace is not supported yet ? I may have missed something...
If it's the case, what would be the best way to do it ?
I was thinking of overloading the CrossReferenceSerializer to prevent from the errors but it seems simplier to add the import hook where it is said in the comment code, retrieving the last segment of the qualified name ? What about the error in this case ?

Thank you very much in advance for your replies !

Stéphane
Re: Refactoring with importedNamespace and qualified name [message #875129 is a reply to message #874222] Tue, 22 May 2012 07:45 Go to previous messageGo to next message
CRASNIER Stéphane is currently offline CRASNIER StéphaneFriend
Messages: 13
Registered: May 2012
Junior Member
Hi all,

Finally, here is my ugly but cheap "solution".

I have injected my own IDValueConverter (inheriting from the IDValueConverter class). It overloads the toString method in order to return the last segment of the ID in case of a "." character (my qualified name delimiter) is encountered. Indeed, qualified names are not allowed in my grammar for cross reference name.

May be it could help somebody else...

Stéphane
Re: Refactoring with importedNamespace and qualified name [message #875131 is a reply to message #874222] Tue, 22 May 2012 07:49 Go to previous messageGo to next message
Jan Koehnlein is currently offline Jan KoehnleinFriend
Messages: 658
Registered: July 2009
Senior Member
Refactoring should work with importedNamespace, too. But it should
create the FQN by default if there is no matching importedNamespace. The
- in the meantime removed - comment refers to changing/adding import
statements to keep the code lean. We have that up and working for Xtend
now, but not yet backported to plain Xtext, as it makes strict
assumptions on where and how imports are specified.

How does the respective cross reference look in your grammar?

Am 20.05.12 09:37, schrieb CRASNIER Stéphane:
> Hi all,
>
> I try to use the refactoring functionality with importedNamespace.
>
> I have the following error :
> org.eclipse.xtext.conversion.ValueConverterException: ID
> 'BA00012.DOBA002' contains invalid characters: '.' (0x2e)
>
>
> It is thrown in the getCrossReferenceNameFromScope method of
> org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer here :
>
> String unconverted = qualifiedNameConverter.toString(desc.getName());
> try {
> return valueConverter.toString(unconverted, ruleName);
> } catch (ValueConverterException e) {
>
>
> It seems that the refactor try to replace the fully qualified name of
> the cross reference instead of the last segment of the qualified name so
> that the ID rule from the Terminals is violated. It's OK without using
> importedNamespace but it's not my case.
>
> While debugging, I've found the following comment in the
> org.eclipse.xtext.ui.refactoring.impl.DefaultReferenceUpdater class :
>
> if (newReferenceText != null) // TODO: add import hook
> TextEdit referenceEdit = new ReplaceEdit(referenceTextRegion.getOffset(),
> referenceTextRegion.getLength(), newReferenceText);
> updateAcceptor.accept(referringResourceURI, referenceEdit);
> }
>
>
> Please, does it mean that the refactoring with importedNamespace is not
> supported yet ? I may have missed something...
> If it's the case, what would be the best way to do it ?
> I was thinking of overloading the CrossReferenceSerializer to prevent
> from the errors but it seems simplier to add the import hook where it is
> said in the comment code, retrieving the last segment of the qualified
> name ? What about the error in this case ?
>
> Thank you very much in advance for your replies !
>
> Stéphane


--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: Refactoring with importedNamespace and qualified name [message #875152 is a reply to message #875131] Tue, 22 May 2012 08:32 Go to previous messageGo to next message
CRASNIER Stéphane is currently offline CRASNIER StéphaneFriend
Messages: 13
Registered: May 2012
Junior Member
Hi Jan !

Thank you for your reply...and for the rename refactoring article from your blog, an excellent enrty point.

OK : wrong way for the comment. Thanks for the complete explanation.

My cross references looks "as usual" in my grammar (extending Terminals). Here is a summarized example for the State "entity" :
StateRef:
    'refState:' reference=[State|ID] ';';

State:
    ('interface')? 'state' name=ID  '{'
        [...]
        (arcs+=StateNodes)*
    '}';

StateNodes:
    'arc' '{'        
        StateNode
    '}'    
;

StateNode:
    entite=(State| StateRef)
;


There are multiple types of entities embedding Nodes. A Node can itself refer to these different types of entities depending on the parent entity type (... I'm not so sure to be clear... Basically, it's a recursive tree structure).

But my Fqn declaration is different from the usual one. May be my problem comes from here :
Use: 'use:' importedNamespace=Fqn';';

Fqn:ID('.'ID)*('.'ID_P)?;

terminal ID_P : 'p'('0'..'9')('0'..'9')*;    


Thanks again Jan !

Stéphane


Re: Refactoring with importedNamespace and qualified name [message #875187 is a reply to message #875152] Tue, 22 May 2012 09:24 Go to previous messageGo to next message
Jan Koehnlein is currently offline Jan KoehnleinFriend
Messages: 658
Registered: July 2009
Senior Member
Allowing FQNs to refer to States should solve the problem:

StateRef:
'refState:' reference=[State|Fqn] ';';

Am 22.05.12 10:32, schrieb CRASNIER Stéphane:
> Hi Jan !
>
> Thank you for your reply...and for the rename refactoring article from
> your blog, an excellent enrty point.
>
> OK : wrong way for the comment. Thanks for the complete explanation.
>
> My cross references looks "as usual" in my grammar (extending
> Terminals). Here is a summarized example for the State "entity" :
>
> StateRef:
> 'refState:' reference=[State|ID] ';';
>
> State:
> ('interface')? 'state' name=ID '{'
> [...]
> (arcs+=StateNodes)*
> '}';
>
> StateNodes:
> 'arc' '{' StateNode
> '}' ;
>
> StateNode:
> entite=(State| StateRef)
> ;
>
>
> There are multiple types of entities embedding Nodes. A Node can itself
> refer to these different types of entities depending on the parent
> entity type (... I'm not so sure to be clear... Basically, it's a
> recursive tree structure).
>
> But my Fqn declaration is different from the usual one. May be my
> problem comes from here :
>
> Use: 'use:' importedNamespace=Fqn';';
>
> Fqn:ID('.'ID)*('.'ID_P)?;
>
> terminal ID_P : 'p'('0'..'9')('0'..'9')*;
>
> Thanks again Jan !
>
> Stéphane
>
>
>


--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: Refactoring with importedNamespace and qualified name [message #875377 is a reply to message #875187] Tue, 22 May 2012 16:18 Go to previous messageGo to next message
CRASNIER Stéphane is currently offline CRASNIER StéphaneFriend
Messages: 13
Registered: May 2012
Junior Member
That's right Jan

... But, in my case, the user will not have to be able to use the Fqn notation for a reference but only the "short" name.

That's why I wanted to force the name format for a reference through the grammar...

... But you show me the way that would have prevented me from losing so much time:) I just have to validate the name through the validator... Thank you !

Dammmit ! I have to learn to fall before walking:)

Stéphane
Re: Refactoring with importedNamespace and qualified name [message #875703 is a reply to message #875377] Wed, 23 May 2012 07:47 Go to previous messageGo to next message
Jan Koehnlein is currently offline Jan KoehnleinFriend
Messages: 658
Registered: July 2009
Senior Member
The refactoring uses the (cross reference) serializer which in term uses
the scope provider of your language to determine the new text for a
cross reference. See
DefaultReferenceUpdater.createReferenceUpdate(EObject, URI,
EReference, int, EObject, IRefactoringUpdateAcceptor)

It may be worth checking these components in your case, as they are
used in other contexts, too.

Am 22.05.12 18:18, schrieb CRASNIER Stéphane:
> That's right Jan
>
> .. But, in my case, the user will not have to be able to use the Fqn
> notation for a reference but only the "short" name.
>
> That's why I wanted to force the name format for a reference through the
> grammar...
>
> .. But you show me the way that would have prevented me from losing so
> much time:) I just have to validate the name through the validator...
> Thank you !
>
> Dammmit ! I have to learn to fall before walking:)
>
> Stéphane


--
Need professional support for Eclipse Modeling?
Go visit: http://xtext.itemis.com
Re: Refactoring with importedNamespace and qualified name [message #876942 is a reply to message #875703] Fri, 25 May 2012 15:02 Go to previous messageGo to next message
CRASNIER Stéphane is currently offline CRASNIER StéphaneFriend
Messages: 13
Registered: May 2012
Junior Member
Hi Jan,

Thanks !

For those who have the same requirement, here is what I've done.

As you showed me, I've finally overloaded the DefaultReferenceUpdater.createReferenceUpdate(EObject, URI,
EReference, int, EObject, IRefactoringUpdateAcceptor) and createReferenceUpdate(IReferenceDescription, URI, ElementRenameArguments, ResourceSet, IRefactoringUpdateAcceptor) methods.

The first is responsible of generating the text changes through the accept method of the IRefactoringUpdateAcceptor class. So that they can be viewed in the wizard.

With the second one, the original name can be retrieved through the elementRenameArguments.getRenameStrategy().getOriginalName().

It's cleaner (... an cheaper:) than before... The thing that can be improved is the way the replacement string is managed, spliting the return of the crossReferenceSerializerFacade.serializeCrossRef method thank to the qualified name service.

Thanks again !

Stéphane
Re: Refactoring with importedNamespace and qualified name [message #1064105 is a reply to message #876942] Mon, 17 June 2013 16:23 Go to previous message
Stephan Herrmann is currently offline Stephan HerrmannFriend
Messages: 1035
Registered: July 2009
Senior Member
I have a similar problem, showing the same exception, but not in the context of rename, but while computing default quick fixes for unresolved names.

Unfortunately, DefaultReferenceUpdater is not used prior to the exception, so the suggested solution from the previous comment doesn't help.

My next attempt was to provide a QualifiedNameProvider that returns simple names for certain kinds of elements, but that way my grammar cannot mix simple ID and qualified names to refer to the same element type. Unfortunately, I need both in different contexts.

In the quick fix case it looks like the exception were actually acceptable, if it were caught inside the loops of org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider$1.fixUnresolvedReference, which would simply mean: objects that are advertised by a qualified name where a simple ID is expected cannot be proposed as corrections, which is exactly the semantics I'd expect.

Unfortunately, overriding the method containing that local class doesn't seem to be possible (due to references to private fields & methods). Performing that adaption using Object Teams provided indeed the desired behavior.

Should I file an RFE to add corresponding try-catches into DefaultQuickfixProvider?

cheers,
Stephan
Previous Topic:CTRL+SPACE action
Next Topic:Call Java class(pure java code) in the Xtend Code
Goto Forum:
  


Current Time: Wed Nov 26 18:59:33 GMT 2014

Powered by FUDForum. Page generated in 0.01871 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software