Bug 194979 - [refactoring] MoveTest reveals AFE in RefactoringHistoryManager
Summary: [refactoring] MoveTest reveals AFE in RefactoringHistoryManager
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.3   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.4 M1   Edit
Assignee: Markus Keller CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on:
Blocks:
 
Reported: 2007-06-29 19:07 EDT by Markus Keller CLA
Modified: 2007-07-11 12:01 EDT (History)
1 user (show)

See Also:


Attachments
Patch (36.37 KB, patch)
2007-07-03 11:20 EDT, Karsten Becker CLA
no flags Details | Diff
Finalised patch (36.52 KB, patch)
2007-07-03 12:20 EDT, Karsten Becker CLA
no flags Details | Diff
Updated (6.60 KB, patch)
2007-07-04 12:13 EDT, Karsten Becker CLA
no flags Details | Diff
Final patch (45.91 KB, patch)
2007-07-09 08:47 EDT, Karsten Becker CLA
no flags Details | Diff
IntroduceParameterObjectDescriptor update (25.23 KB, patch)
2007-07-09 09:22 EDT, Karsten Becker CLA
no flags Details | Diff
javadoc... (45.06 KB, patch)
2007-07-10 11:09 EDT, Karsten Becker CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Keller CLA 2007-06-29 19:07:43 EDT
HEAD

Running the MoveTests writes AFEs like the one below to the log. The problem is that the MoveDescriptor is validated too early here:

Thread [main] (Suspended)	
MoveDescriptor.validateDescriptor() line: 373	
MoveDescriptor(JavaRefactoringDescriptor).populateArgumentMap() line: 328	
MoveDescriptor.populateArgumentMap() line: 166	
MoveDescriptor(JavaRefactoringDescriptor).getArguments() line: 319	
MoveRefactoringContribution(JavaRefactoringContribution).retrieveArgumentMap(RefactoringDescriptor) line: 40	

We should remove the Assert or make it less stupid by adding the actual validation problem to the message.


!ENTRY org.eclipse.core.commands 4 2 2007-06-30 00:48:22.390
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.core.commands".
!STACK 0
org.eclipse.core.runtime.AssertionFailedException: assertion failed: Validation returns a fatal error status.
	at org.eclipse.core.runtime.Assert.isTrue(Assert.java:109)
	at org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor.populateArgumentMap(JavaRefactoringDescriptor.java:328)
	at org.eclipse.jdt.core.refactoring.descriptors.MoveDescriptor.populateArgumentMap(MoveDescriptor.java:166)
	at org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringDescriptor.getArguments(JavaRefactoringDescriptor.java:319)
	at org.eclipse.jdt.core.refactoring.descriptors.JavaRefactoringContribution.retrieveArgumentMap(JavaRefactoringContribution.java:40)
	at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryManager.getArgumentMap(RefactoringHistoryManager.java:190)
	at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService$RefactoringDescriptorStack.checkDescriptor(RefactoringHistoryService.java:176)
	at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService$RefactoringDescriptorStack.push(RefactoringHistoryService.java:284)
	at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService$RefactoringDescriptorStack.access$0(RefactoringHistoryService.java:281)
	at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService$RefactoringOperationHistoryListener.historyNotification(RefactoringHistoryService.java:449)
	at org.eclipse.core.commands.operations.DefaultOperationHistory$2.run(DefaultOperationHistory.java:929)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
	at org.eclipse.core.commands.operations.DefaultOperationHistory.notifyListeners(DefaultOperationHistory.java:918)
	at org.eclipse.core.commands.operations.DefaultOperationHistory.notifyDone(DefaultOperationHistory.java:992)
	at org.eclipse.core.commands.operations.DefaultOperationHistory.closeOperation(DefaultOperationHistory.java:1359)
	at org.eclipse.ltk.internal.core.refactoring.UndoManager2.changePerformed(UndoManager2.java:149)
	at org.eclipse.ltk.core.refactoring.PerformChangeOperation$1.run(PerformChangeOperation.java:265)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1797)
	at org.eclipse.ltk.core.refactoring.PerformChangeOperation.executeChange(PerformChangeOperation.java:306)
	at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:218)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1797)
	at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1779)
	at org.eclipse.jdt.ui.tests.refactoring.RefactoringTest.executePerformOperation(RefactoringTest.java:288)
	at org.eclipse.jdt.ui.tests.refactoring.RefactoringTest.performRefactoring(RefactoringTest.java:266)
	at org.eclipse.jdt.ui.tests.refactoring.ccp.MoveTest.performRefactoring(MoveTest.java:87)
	at org.eclipse.jdt.ui.tests.refactoring.ccp.MoveTest.testDestination_yes_cuToOtherPackage(MoveTest.java:977)
Comment 1 Martin Aeschlimann CLA 2007-07-02 08:29:10 EDT
Markus, can you fix this?
Comment 2 Markus Keller CLA 2007-07-02 08:36:15 EDT
Will look into it.
Comment 3 Markus Keller CLA 2007-07-03 06:52:16 EDT
This is a problem for all refactoring descriptors that set the arguments map directly by calling
JavaRefactoringDescriptor(String, String, String, String, Map, int). Their validateDescriptor() method validates the refactoring-specific typed fields, but those are all null in this case.

Karsten, what's the plan here? Where will these descriptors be validated?
Comment 4 Karsten Becker CLA 2007-07-03 07:03:40 EDT
I'm already working on that. In fact I will create a patch later. The problem is that the fields are currently not used for reading. I'm rewriting those few ones that already have fields and initialize those in the constructor. Which leads to another problem.
It is for a contribution not allowed to return null on the createDescriptor stuff whith arguments and it is not allowed to throw an exception. So basically it is impossible to handle invalid argument maps. I rewrote it such that an IllegalArgumentException is thrown in such a case and check that it is handled carefully. At the moment it is not specified that a IllegalArgumentException could be thrown.
Comment 5 Markus Keller CLA 2007-07-03 10:41:39 EDT
As I see it, RefactoringContribution.createDescriptor(..) should not do any checks other than the syntactic checks mentioned in the Javadoc. It should just create a RefactoringDescriptor whose validateDescriptor() will fail if the arguments were not OK.

I guess some of the checks in current validateDescriptor() methods can be dropped (e.g. checks for null or emptiness of new name string). We just have to make sure that a valid descriptor is able to create and initialize its refactoring. A successfully validated descriptor does not necessarily have to pass Refactoring#checkInitialConditions(..).
Comment 6 Karsten Becker CLA 2007-07-03 11:19:38 EDT
The question is, what to do when an attribute is missing, or it's values are invalid. Like a "yes" in a attribute that is expected to be boolean. Imho it would be bad practice to accept it during creation of the descriptor as it might be non trivial to see where this error originated from if the yes would be stored, or even worse silently ignored.
Some checks like IJavaElement.exists() may be deffered to the validateDescriptor method. But an invalid Map should not be accepted.
Also consistency checks are not meant for construction time.
I'll now attach a patch that is work in progress and currently fails on the RenameTypeParameterTests because < is not allowed in a xml attribute...
Comment 7 Karsten Becker CLA 2007-07-03 11:20:19 EDT
Created attachment 72961 [details]
Patch
Comment 8 Karsten Becker CLA 2007-07-03 12:20:27 EDT
Created attachment 72964 [details]
Finalised patch

fixed the failing testcase for renameTypeParameterTest
At the moment a very extensive RefactoringDescriptor is enabled. Maybe it should not be enabled in the HEAD
Comment 9 Karsten Becker CLA 2007-07-04 12:13:52 EDT
Created attachment 73038 [details]
Updated

This patch is an update for the IntroduceParameterObjectDescriptor to be less restrictive if the method is invalid in some way.
Comment 10 Karsten Becker CLA 2007-07-09 08:47:16 EDT
Created attachment 73310 [details]
Final patch
Comment 11 Karsten Becker CLA 2007-07-09 09:22:38 EDT
Created attachment 73314 [details]
IntroduceParameterObjectDescriptor update
Comment 12 Markus Keller CLA 2007-07-10 02:47:26 EDT
Released patch 4 and 5 with a few changes:

IntroduceParameterObjectDescriptor.validateDescriptor(..) still failed when running IPO tests. Resolved by removing this check:
	if (!fMethod.exists()) {
		result.addFatalError("The method must exist"); //$NON-NLS-1$
		return result;
	}
This happens when the history service asks the descriptor to populate the argument map *after* the refactoring has been executed. At that time, fMethod indeed does not have to exist any more.

Also fixed problems in MoveDescriptor(..):
- read fMovePolicy from map (don't write it)
- fDestination can be ATTRIBUTE_DESTINATION or ATTRIBUTE_TARGET
- callers passed empty map and filled it only afterwards (see all IReorgPolicy.getDescriptor())

Did not release unused DescriptorMessages.RenameJavaElementDescriptor_reference_constraint.

TODO:
- All methods in JavaRefactoringDescriptorUtil need Javadoc, especially complex queries like getIntArray(Map map, String countAttribute, String arrayAttribute).
- Methods that throw IllegalArgumentException must declare the thrown exception and explain when that happens (in @throws).

- IPO tests still write to the log because RefactoringHistoryManager.checkArgumentMap(Map) is too restrictive. The mentioned rules (in RefactoringContribution, not RefactoringDescriptor) force map values to be non-empty, although empty value strings can make perfect sense for some usages (e.g. the name of the default package). Fix Javadocs and implementation in RefactoringContribution and all dependencies.
Comment 13 Karsten Becker CLA 2007-07-10 11:09:05 EDT
Created attachment 73431 [details]
javadoc...
Comment 14 Markus Keller CLA 2007-07-11 12:01:02 EDT
Released patch 'javadoc...' with all these fixes:

* IntroduceParameterObjectDescriptor:
- improved performance and robustness of createParameters(IMethod) by avoiding element access through IMethod#getParameterNames()
- restored readable if-else formatting in populateArgumentMap() (if-else always needs {}s)
- added 'throws IllegalArgumentException' where necessary

* JavaRefactoringDescriptorUtil
- fixed NLS warnings
- fixed messages (use ', not '')
- removed unsed getSelection(..) (the anonymous ISourceRange was a bad idea anyway)
- Retrieves *a* String/boolean (not 'an')

* RefactoringContribution:
- fixed Javadoc of createDescriptor(..) (value string can be empty)

* RefactoringHistoryManager:
- non-NLSd string
- last Status in checkArgumentMap(..) is bad

- RefactoringHistorySerializationTests.testWriteDescriptor8() failed