Bug 112366 - elementChanged doesn't get called with the changed element delta after refactoring
Summary: elementChanged doesn't get called with the changed element delta after refact...
Status: RESOLVED FIXED
Alias: None
Product: CDT
Classification: Tools
Component: cdt-core (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows 2000
: P3 major (vote)
Target Milestone: 3.1.1   Edit
Assignee: Markus Schorn CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
: 147220 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-10-12 13:15 EDT by Mohamed Badr CLA
Modified: 2008-06-19 13:56 EDT (History)
4 users (show)

See Also:


Attachments
Patch :: Solution with IWorkingCopy to IDocument Adapter (27.24 KB, patch)
2006-06-23 06:42 EDT, Janees Elamkulam CLA
no flags Details | Diff
modified patch (22.05 KB, patch)
2006-06-27 07:02 EDT, Markus Schorn CLA
no flags Details | Diff
modified patch (28.07 KB, patch)
2006-06-28 11:22 EDT, Markus Schorn CLA
no flags Details | Diff
Patch respecting most of the refactoring framework (32.69 KB, patch)
2006-07-04 05:42 EDT, Markus Schorn CLA
bjorn.freeman-benson: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Mohamed Badr CLA 2005-10-12 13:15:50 EDT
This problem happens only in CDT 3.0 and it was working fine in older version.

I have implemented IElementChangedListener and I handle all elementChanged 
called to synchronize the C++ Viz with any changed in CDT. the problem is 
1-from the c++ project view, right click in a class and choose refactor. 
2-rename the class 
3-click ok.
result: the code is refactored, elementChanged is fired with event of type 
POST_CHANGE and the changed delta doesn't have anything about the class.

expected: as in earlier version, expecting elementChanged is called first with 
a delta (old class, new class) then the POST_CHANGE is received.

No there is no way to synchronize the changes in the code with the visualizer
Comment 1 Markus Schorn CLA 2006-06-19 03:06:54 EDT
*** Bug 147220 has been marked as a duplicate of this bug. ***
Comment 2 Janees Elamkulam CLA 2006-06-19 09:56:40 EDT
please see bug 147220 for some more comments.

the changes to the file is being made by TextEdit classes, InsertEdit, ReplaceEdit etc. and controlled by TextFileChnage. These are final class, and works only on IDocument.

So inorder to allow textedits to work with IWorkingCopy, i propose to implement an adapter class which implements IDocument interface and has an association with IWorkingCopy. The adapter will implement only the function required for the TextEdits to work like replace(), get() get(int, int), getLength() etc. 

Any sugessions or concerns ?

- Janees

Comment 3 Markus Schorn CLA 2006-06-20 04:49:34 EDT
The events you are looking for are generated by the CModel only in case a workingcopy has been created for the translation unit. This is for instance the
case when the file is opened in the CDT-Editor.

Creating the working copies for the rename refactoring implies that when 
applying the refactoring, all the files involved have to be parsed for an
additional two times. I am not sure how bad the performance impact of this
would be. If it is affordable, we should do it.

To some extent you cannot rely on the CModel events, because there will
always be operations that change the source-code without creating working 
copies, I can think of:
* Replacements via the local history,
* Text Replace across files,
* Updates of source code via team support.

For the rename refactoring you can consider to use a RenameRefactoringParticipant as an alternative to get informed about the operation.


Comment 4 Janees Elamkulam CLA 2006-06-23 06:42:52 EDT
Created attachment 45159 [details]
Patch :: Solution with IWorkingCopy to IDocument Adapter

Attaching a patch that allow modification through IWOrkingCopy.

I dont think perfomace will be a hit, since refactoring is a stand alone operation.

Can you please comment on this patch ?
Comment 5 Markus Schorn CLA 2006-06-27 07:00:01 EDT
Thanks for the patch! I have changed it to fully make use of the TextFileChange base class. Please check if this satisfies your needs.
Comment 6 Markus Schorn CLA 2006-06-27 07:02:54 EDT
Created attachment 45376 [details]
modified patch
Comment 7 Janees Elamkulam CLA 2006-06-28 01:34:58 EDT
This does not seems to work properly in my case. 

We are receiving deltas, but the problem is it is just POST_RECONCILE deltas, but does not receive any POST_CHANGE deltas. We need POST_CHANGE detlas to know the change has been commited. I added fWorkingCopy.commit() in commit function, then i get the POST_CHANGE delta for tu, but resource change kind is not know (see the [?] appended to TRANSLATION_UNIT in below delta . With this i was able to get know the change, but i end up with invalid element, even thought name is same (some thing similar to the browser right click defect #147694). 
With the first patch, i get proper delta, note the [*] sign appended to TRANSLATION_UNIT indicating the change.

Here are sample deltas i received (just the header file deltas while renaming a class) :

With modified patch:
~~~~~~~~~~~~~~~~~~~~~
Event Type : 4
Delat : I2.h  :  I2.h WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	I2343234 C_CLASS [+]: {}
	I2343 C_CLASS [-]: {}  :  4
Event Type : 1
Delat :   :   CMODEL [*]: {CHILDREN | FINE GRAINED}
	CdtVizSREProject CPROJECT [*]: {CHILDREN | FINE GRAINED}
		CdtVizSREProject SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			I2.h WORKING_UNIT [-]: {}  :  4

modified patch + workingcopy commit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Event Type : 4
Delat : I2.h  :  I2.h WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	I2343234 C_CLASS [+]: {}
	I2343 C_CLASS [-]: {}  :  4
Event Type : 1
Delat :   :   CMODEL [*]: {CHILDREN | FINE GRAINED}
	CdtVizSREProject CPROJECT [*]: {CHILDREN | FINE GRAINED}
		CdtVizSREProject SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			I2.h TRANSLATION_UNIT [?]: {FINE GRAINED}
			I2.h WORKING_UNIT [-]: {}  :  4

With the first patch
~~~~~~~~~~~~~~~~~~~~~
Event Type : 4
Delat : I2343.h  :  I2343.h WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	I2343234 C_CLASS [+]: {}
	I2343 C_CLASS [-]: {}  :  4
Event Type : 1
Delat :   :   CMODEL [*]: {CHILDREN | FINE GRAINED}
	testCProject CPROJECT [*]: {CHILDREN | FINE GRAINED}
		testCProject SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			I2343.h TRANSLATION_UNIT [*]: {CHILDREN | FINE GRAINED}
				I2343234 C_CLASS [+]: {}
				I2343 C_CLASS [-]: {}
			I2343.h WORKING_UNIT [-]: {}  :  4
Comment 8 Markus Schorn CLA 2006-06-28 02:35:26 EDT
Hmm, I think you did not copy all the notifications you get. 

Note that the commit() was ommited by intention, as the buffer is commited by the TextFileChange. This is the same procedure that the editor is following. Therefore you get the same notifications for the rename refactoring and overtyping the name in the editor.


Rename a global variable without having an editor open:
=======================================================

Preview:
--------
ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	mmcc CPROJECT [*]: {CHILDREN | FINE GRAINED}
		mmcc SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			testListener.cpp WORKING_UNIT [-]: {}]
ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	mmcc CPROJECT [*]: {CHILDREN | FINE GRAINED}
		mmcc SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			testListener.cpp WORKING_UNIT [-]: {}]
ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	mmcc CPROJECT [*]: {CHILDREN | FINE GRAINED}
		mmcc SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			testListener.cpp WORKING_UNIT [-]: {}]

The actual rename:
------------------
ElementChangedEvent[source=testListener.cpp WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	f C_VARIABLE [+]: {}
	g C_VARIABLE [-]: {}]
ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	mmcc CPROJECT [*]: {CHILDREN | FINE GRAINED}
		mmcc SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			testListener.cpp WORKING_UNIT [-]: {}]
ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	mmcc CPROJECT [*]: {CHILDREN | FINE GRAINED}
		mmcc SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			testListener.cpp TRANSLATION_UNIT [*]: {CONTENT}]

Overtyping the global variable in the editor:
=============================================

After typing 'g' over 'f'
-------------------------
ElementChangedEvent[source=testListener.cpp WORKING_UNIT [*]: {CHILDREN | FINE GRAINED}
	g C_VARIABLE [+]: {}
	f C_VARIABLE [-]: {}]
	
Save the editor:
----------------
ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
	mmcc CPROJECT [*]: {CHILDREN | FINE GRAINED}
		mmcc SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
			testListener.cpp TRANSLATION_UNIT [*]: {CONTENT}]

Comment 9 Janees Elamkulam CLA 2006-06-28 05:36:06 EDT
yes, i copied only one case, to highlight the difference.

The problem is we get working copy destroy, before tu change message.

ElementChangedEvent[source= CMODEL [*]: {CHILDREN | FINE GRAINED}
        mmcc CPROJECT [*]: {CHILDREN | FINE GRAINED}
                mmcc SOURCE_ROOT [*]: {CHILDREN | FINE GRAINED}
                        testListener.cpp WORKING_UNIT [-]: {}]

This says working copy has been destroyed. => changes received so far from this copy not to be commited. This happens when user does not save the changes, and destroys the working copy.
Comment 10 Markus Schorn CLA 2006-06-28 11:22:31 EDT
Created attachment 45469 [details]
modified patch

I understand. The real problem behind all of this is that the WorkingCopy stuff was never modified to work well with the TextFileBuffers (jdt has reworked their working copies). Until this is fixed in CDT, the notifications will be messy. If you are happy with your patch, then I will apply it, it does not make things worse then they are.

I have just changed your version of the CTextFileChange such that it complies to the API-contract of TextFileChange and also works with files that are no translation units.
Comment 11 Janees Elamkulam CLA 2006-06-29 02:55:08 EDT
Do you think the ideal soultion is to fix the working copy? Are you aware of this problem before?. Is there any other known issues with working copy ?

Also, can CTextFileChange be moved to org.eclipse.cdt.refactoring from org.eclipse.cdt.refactoring from org.eclipse.cdt.*internal*.refactoring, so that this class can be used by extenders. I have a couple of functionality that uses the ltk refactoring infrastructure to update/preview change.
Comment 12 Markus Schorn CLA 2006-06-29 03:18:58 EDT
(In reply to comment #11)
> Do you think the ideal soultion is to fix the working copy? Are you aware of
> this problem before?. Is there any other known issues with working copy ?
Yes, the working copies should be fixed. I was not aware of this, just found out yesterday. It looks like the CDT working copies are a copy of an earlier version of the JDT working copies. I got the feeling that the only reason why we do not have more problems with them is, that they are just used in a very few places.

> Also, can CTextFileChange be moved to org.eclipse.cdt.refactoring from
> org.eclipse.cdt.refactoring from org.eclipse.cdt.*internal*.refactoring, so
> that this class can be used by extenders. I have a couple of functionality that
> uses the ltk refactoring infrastructure to update/preview change.
The current implementation of CTextFileChange is somehow hacky. This is ok for internal usage, but I am reluctant to make this an API we have to support. [The base class allows for smart handling of dirty buffers, CTextFileChange does not. The document provided potentially throws exceptions on you.]
Comment 13 Janees Elamkulam CLA 2006-06-30 10:55:04 EDT
Thanks Markus, are you going to apply this ?
Comment 14 Markus Schorn CLA 2006-07-03 13:59:51 EDT
I am still looking for a better solution (one that does not work around the text buffers) and I am close to it. I'll supply a patch before commiting the stuff, so you can have a look at it before.
Comment 15 Markus Schorn CLA 2006-07-04 05:42:50 EDT
Created attachment 45697 [details]
Patch respecting most of the refactoring framework

I think I found a decent solution to the problem, it's not 100% clean, but it does respect most of the refactoring framework, especially:
   * it applies the changes without replacing the full content of the file
   * delta notifications are sent for the translation unit, rather than the 
     working copy.

I filed bug 149540 to further improve the situation.
Comment 16 Janees Elamkulam CLA 2006-07-06 02:24:51 EDT
Thanks Markus, this patch works fine for me.

Any plan to make CTextFileChange public ?
Comment 17 Markus Schorn CLA 2006-07-06 05:19:22 EDT
Fixed > 20060706 for CDT 3.1.1 and CDT 4.0.

I have made this a provisional API.