Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 354731

Summary: An Xtext language without special refactoring support can break Java rename refactoring
Product: [Modeling] TMF Reporter: Vladimir Piskarev <vpiskarov>
Component: XtextAssignee: Jan Koehnlein <jan>
Status: CLOSED DUPLICATE QA Contact:
Severity: normal    
Priority: P3 CC: jan, sven.efftinge, tmf.xtext-inbox
Version: 2.0.0Flags: sven.efftinge: indigo+
Target Milestone: SR2   
Hardware: All   
OS: All   
Whiteboard:
Attachments:
Description Flags
Sample language projects
none
'example' project none

Description Vladimir Piskarev CLA 2011-08-15 09:45:01 EDT
Build Identifier: I20110613-1736

When attempting to rename a Java type which is referenced from an Xtext language configured without the experimental refactoring support, the Java refactoring fails with the following message: 'Error during refactoring: java.net.MalformedURLException: unknown protocol: java'.

Reproducible: Always

Steps to Reproduce:
1. Import the attached 'org.xtext.example.domainmodel' and
'org.xtext.example.domainmodel.ui' projects into the workspace. Note that the project were created using Generator Configuration 'Use Stable API only' (in particular, without RefactorElementNameFragment)

2. Run the runtime workbench and import the attached 'example' project into the
runtime workspace

3. Open 'Foo.java' and rename 'Foo' to 'Bar' using Java rename refactoring. Note the dialog with 'Error during refactoring: java.net.MalformedURLException: unknown protocol: java'

It appears, that the problem is caused by the Xtend2RenameParticipant willing to update references in 'Foo.dmodel', the language of which is completely unrelated to Xtend2. 

This bug may be relative to bug 351189.
Comment 1 Vladimir Piskarev CLA 2011-08-15 09:46:38 EDT
Created attachment 201494 [details]
Sample language projects
Comment 2 Vladimir Piskarev CLA 2011-08-15 09:47:52 EDT
Created attachment 201495 [details]
'example' project
Comment 3 Jan Koehnlein CLA 2011-08-16 06:20:16 EDT
Thanks for the report.

Debugging reveals two issues here:

1) The JDTRenameParticipant that is registered for each langugae with RefactorElementNameFragment and useJdtRfactoring==true calls the ReferenceUpdaterDispatcher. This one will rename all references from all Xtext based languages instead of just using the the references from the language of the participant. This causes duplicate reference updates as well as the triggering of the plain ReferenceUpdater of your language, even though you did not register as a JDT rename participant. We should use the IReferenceUpdater of the langugae instead of the dispatcher.

2) The exception is thrown in the IReferenceUpdater of your language, as it uses a RefactoringResourceSetProvider that does not configure the resource set for "java:/" URIs. This is expected, as you id not generate your language with JDT refactoring participation.
Comment 4 Jan Koehnlein CLA 2011-08-26 09:40:58 EDT
Committed an intermediate fix: There is a single JdtRenameParticipant know that delegates to the refactoring of the Xtext source element of a JvmElement if there is one. That way, the index is only traversed once.

Going to write tests now...
Comment 5 Jan Koehnlein CLA 2011-08-30 10:38:55 EDT
Fix pushed to master. Also added a couple of tests.

Moved major parts of the JvmTypes related refatoring code to org.eclipse.xtext.common.types.ui, such that languages refering to JvmTypes can use them. You can now choose between different levels of JDT refactoring integration foryour language:

1) No integration 
   -> don't use RefactorElementNameFragment
2) Allow refactoring of non JVM elements and update references on JDT refactorings
   -> RefactorElementNameFragment {}
3) As 2) but trigger JDT refactoring when the user starts refactoring on a x-reference to a JVM element
   -> RefactorElementNameFragment { useJdtRefactoring = true }
4) As 3) but with Xbase and your own EClasses inheriting from JvmIdentifiableElements. JDT's refactorings will trigger refactoring of the source element
   -> RefactorElementNameFragment { useJdtRefactoring = true }
      XbaseFragment {}
5) As 4) but using an inferred JvmModel. JDT's refactorings will trigger refactoring of the source element and the inferred element
   -> RefactorElementNameFragment { useJdtRefactoring = true }
      XbaseFragment { useInferredJvmModel = true }
Comment 6 Vladimir Piskarev CLA 2011-08-31 04:27:06 EDT
Thanks a lot for the hard work, Jan! It looks so much better now. Some minor notes, if it will be allowed.

* With refactoring configurations #2 and #3 (i.e. RefactorElementNameFragment {} or RefactorElementNameFragment { useJdtRefactoring = true }) attempting to rename an x-reference to a JVM element fails with an InvocationTargetException thrown directly on the user. The reason is

	Caused by: java.lang.IllegalArgumentException: Cannot find a rename strategy for java:/Objects/example.Foo#example.Foo
		at org.eclipse.xtext.ui.refactoring.ui.SimpleLinkedPositionGroupCalculator.getLinkedPositionGroup(SimpleLinkedPositionGroupCalculator.java:96)
		at org.eclipse.xtext.ui.refactoring.ui.RenameLinkedMode.start(RenameLinkedMode.java:67)
		at org.eclipse.xtext.ui.refactoring.ui.RenameRefactoringController$1.run(RenameRefactoringController.java:105)
		at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
		... 51 more

(steps to reproduce: attempt to rename 'example.Foo' reference from 'Foo.dmodel' file of the attached 'example' project for the appropriately re-configured 'sample language' projects)

That's may be expected for refactoring configuration #2, but could it fail a bit more gracefully (e.g. just log the error in Eclipse error log). It seems to be a bug for refactoring configuration #3.

* With refactoring configuration #5 there is a similar issue. Steps to reproduce:

  1) Import the standard 'domainmodel' projects from Xtext git repository
  2) Create an Xtext Java project with a 'dmodel' file with the following contents: entity A { foo : example.Foo }, where 'example.Foo' is a Java class in the same project
  3) Attemp to rename 'example.Foo' reference. It fails with an InvocationTargetException. The reason is

	Caused by: java.lang.NullPointerException
		at org.eclipse.emf.ecore.util.EcoreSwitch.doSwitch(EcoreSwitch.java:74)
		at org.eclipse.xtext.resource.DefaultLocationInFileProvider.getTextRegion(DefaultLocationInFileProvider.java:85)
		at org.eclipse.xtext.resource.DefaultLocationInFileProvider.getFullTextRegion(DefaultLocationInFileProvider.java:65)
		at org.eclipse.xtext.xbase.jvmmodel.JvmLocationInFileProvider.getFullTextRegion(JvmLocationInFileProvider.java:32)
		at org.eclipse.xtext.ui.refactoring.impl.DefaultRenameStrategy$Provider.getOriginalNameRegion(DefaultRenameStrategy.java:53)
		at org.eclipse.xtext.example.domainmodel.ui.refactoring.DomainmodelRenameStrategy$Provider.get(DomainmodelRenameStrategy.java:38)
		at org.eclipse.xtext.ui.refactoring.ui.SimpleLinkedPositionGroupCalculator.getLinkedPositionGroup(SimpleLinkedPositionGroupCalculator.java:94)
		at org.eclipse.xtext.ui.refactoring.ui.RenameLinkedMode.start(RenameLinkedMode.java:67)
		at org.eclipse.xtext.ui.refactoring.ui.RenameRefactoringController$1.run(RenameRefactoringController.java:105)
		at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
		... 51 more

* When renaming a JVM element, the refactoring preview change reports 'Changes from participant: Java'. Would 'Changes from participant: Xtext' be more appropriate?

* I noticed a small typo in JDT rename participant name (both Java class and extension id) - missing "i".

Thanks again for the fix! By the way, bug 351189 seems to be also fixed by your changes.
Comment 7 Jan Koehnlein CLA 2011-08-31 10:39:21 EDT
Wow, thanks for the elaborate feedback. 

Once again it shows that everytime I bypass some component of the refactoring in the tests, it's gonna be exactly that component that has errors. In this case, it was the linked position calculation...

I've committed fixes for all bugs, except for the misleading error message, which is continued in the separate bug 356342.
Comment 8 Vladimir Piskarev CLA 2011-09-01 04:21:37 EDT
Jan, many thanks for the fixes. I can imagine what amount of hard work went into implementing this refactoring - I can say it from some (admittedly little) experience I have. These refactorings can be pretty tricky indeed.

Maybe you already discovered it yourself, but I encountered the following error when attempting to rename the pesky 'example.Foo' reference in refactoring configuration #3 (I have not tried it in other configurations):

Caused by: java.lang.IllegalStateException: Current selection is not within any linked editing position
	at org.eclipse.xtext.ui.refactoring.ui.RenameLinkedMode.start(RenameLinkedMode.java:82)
	at org.eclipse.xtext.ui.refactoring.ui.RenameRefactoringController$1.run(RenameRefactoringController.java:105)
	at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
	... 51 more

The cursor was inside 'example'. After that failure, other attempts give me

java.lang.NullPointerException
	at org.eclipse.xtext.ui.refactoring.ui.RenameRefactoringController.startRefactoring(RenameRefactoringController.java:66)
	at org.eclipse.xtext.ui.refactoring.ui.RenameRefactoringController.startLinkedEditing(RenameRefactoringController.java:94)
	at org.eclipse.xtext.ui.refactoring.ui.RenameRefactoringController.startRefactoring(RenameRefactoringController.java:57)
	at org.eclipse.xtext.ui.refactoring.ui.DefaultRenameElementHandler.startRenameElement(DefaultRenameElementHandler.java:80)
	at org.eclipse.xtext.ui.refactoring.ui.DefaultRenameElementHandler.execute(DefaultRenameElementHandler.java:59)
Comment 9 Vladimir Piskarev CLA 2011-09-01 04:58:56 EDT
Clarification: NPE is thrown when the cursor is inside the 'Foo' region (after the first attempt - in the 'example' region - failed with the IllegalStateException)
Comment 10 Jan Koehnlein CLA 2011-09-01 05:20:04 EDT
Thanks again! It seems that with your help we will soon eliminate all remaining refactoring bugs :-)

This issue seems to be related to a wider range of languages, so I'll continue it in a separate bug 356444.
Comment 11 Jan Koehnlein CLA 2011-09-01 05:20:24 EDT

*** This bug has been marked as a duplicate of bug 356444 ***
Comment 12 Vladimir Piskarev CLA 2011-09-01 06:04:39 EDT
Refactoring is one of the Xtext miracles. Glad if I was of any help. Now I must try to shut up and do my own work :-)