Bug 99978 - MalformedTreeException on Inline Method
Summary: MalformedTreeException on Inline Method
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1 RC3   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 100494 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-06-14 11:16 EDT by David Saff CLA
Modified: 2005-06-17 03:26 EDT (History)
2 users (show)

See Also:


Attachments
The file that generates the error (6.32 KB, text/x-java)
2005-06-14 11:17 EDT, David Saff CLA
no flags Details
Change in BindingComparator (1.41 KB, patch)
2005-06-15 12:17 EDT, Jerome Lanneluc CLA
no flags Details | Diff
Regression test (1.89 KB, patch)
2005-06-15 12:18 EDT, Jerome Lanneluc CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Saff CLA 2005-06-14 11:16:26 EDT
In RC2.  Take SayTests.java (attached).  Select the method methodNameFor on line
240, and Inline Method > All Invocations.  The refactoring fails, and the
following is logged:

java.lang.reflect.InvocationTargetException
at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:327)
at
org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.run(RefactoringWizardDialog2.java:293)
at
org.eclipse.ltk.ui.refactoring.RefactoringWizard.internalPerformFinish(RefactoringWizard.java:547)
at
org.eclipse.ltk.ui.refactoring.UserInputWizardPage.performFinish(UserInputWizardPage.java:153)
at
org.eclipse.ltk.ui.refactoring.RefactoringWizard.performFinish(RefactoringWizard.java:613)
at
org.eclipse.ltk.internal.ui.refactoring.RefactoringWizardDialog2.okPressed(RefactoringWizardDialog2.java:417)
at org.eclipse.jface.dialogs.Dialog.buttonPressed(Dialog.java:409)
at org.eclipse.jface.dialogs.Dialog$2.widgetSelected(Dialog.java:556)
at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:89)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:844)
at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3058)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2691)
at org.eclipse.jface.window.Window.runEventLoop(Window.java:809)
at org.eclipse.jface.window.Window.open(Window.java:787)
at
org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation$1.run(RefactoringWizardOpenOperation.java:125)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:69)
at
org.eclipse.ltk.ui.refactoring.RefactoringWizardOpenOperation.run(RefactoringWizardOpenOperation.java:138)
at
org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter.activate(RefactoringStarter.java:40)
at
org.eclipse.jdt.internal.corext.refactoring.RefactoringExecutionStarter.startInlineMethodRefactoring(RefactoringExecutionStarter.java:251)
at
org.eclipse.jdt.internal.ui.refactoring.actions.InlineMethodAction.run(InlineMethodAction.java:133)
at
org.eclipse.jdt.internal.ui.refactoring.actions.InlineMethodAction.run(InlineMethodAction.java:126)
at
org.eclipse.jdt.internal.ui.refactoring.actions.InlineMethodAction.tryInlineMethod(InlineMethodAction.java:142)
at org.eclipse.jdt.ui.actions.InlineAction.run(InlineAction.java:114)
at
org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun(SelectionDispatchAction.java:226)
at
org.eclipse.jdt.ui.actions.SelectionDispatchAction.run(SelectionDispatchAction.java:198)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:996)
at org.eclipse.ui.commands.ActionHandler.execute(ActionHandler.java:182)
at
org.eclipse.ui.internal.handlers.LegacyHandlerWrapper.execute(LegacyHandlerWrapper.java:108)
at org.eclipse.core.commands.Command.execute(Command.java:311)
at
org.eclipse.core.commands.ParameterizedCommand.execute(ParameterizedCommand.java:396)
at
org.eclipse.ui.internal.keys.WorkbenchKeyboard.executeCommand(WorkbenchKeyboard.java:459)
at org.eclipse.ui.internal.keys.WorkbenchKeyboard.press(WorkbenchKeyboard.java:781)
at
org.eclipse.ui.internal.keys.WorkbenchKeyboard.processKeyEvent(WorkbenchKeyboard.java:828)
at
org.eclipse.ui.internal.keys.WorkbenchKeyboard.filterKeySequenceBindings(WorkbenchKeyboard.java:550)
at
org.eclipse.ui.internal.keys.WorkbenchKeyboard.access$3(WorkbenchKeyboard.java:493)
at
org.eclipse.ui.internal.keys.WorkbenchKeyboard$KeyDownFilter.handleEvent(WorkbenchKeyboard.java:117)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
at org.eclipse.swt.widgets.Display.filterEvent(Display.java:910)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:843)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:868)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:853)
at org.eclipse.swt.widgets.Control.traverse(Control.java:2778)
at org.eclipse.swt.widgets.Control.translateMnemonic(Control.java:2619)
at org.eclipse.swt.widgets.Composite.translateMnemonic(Composite.java:827)
at org.eclipse.swt.widgets.Control.translateMnemonic(Control.java:2637)
at org.eclipse.swt.widgets.Display.translateMnemonic(Display.java:3490)
at org.eclipse.swt.widgets.Display.filterMessage(Display.java:924)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2687)
at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:1716)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:1680)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:365)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:143)
at org.eclipse.ui.internal.ide.IDEApplication.run(IDEApplication.java:103)
at
org.eclipse.core.internal.runtime.PlatformActivator$1.run(PlatformActivator.java:226)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:376)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:163)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.eclipse.core.launcher.Main.invokeFramework(Main.java:334)
at org.eclipse.core.launcher.Main.basicRun(Main.java:278)
at org.eclipse.core.launcher.Main.run(Main.java:973)
at org.eclipse.core.launcher.Main.main(Main.java:948)
Caused by: org.eclipse.text.edits.MalformedTreeException: Overlapping text edits
at org.eclipse.text.edits.TextEdit$InsertionComparator.compare(TextEdit.java:118)
at java.util.Collections.indexedBinarySearch(Collections.java:322)
at java.util.Collections.binarySearch(Collections.java:310)
at org.eclipse.text.edits.TextEdit.computeInsertionIndex(TextEdit.java:757)
at org.eclipse.text.edits.TextEdit.internalAdd(TextEdit.java:742)
at org.eclipse.text.edits.TextEdit.addChild(TextEdit.java:332)
at
org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility.insert(TextChangeCompatibility.java:78)
at
org.eclipse.jdt.internal.corext.refactoring.code.InlineMethodRefactoring.createChange(InlineMethodRefactoring.java:291)
at
org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:117)
at
org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:189)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1719)
at
org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:86)
at
org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:113)
Root exception:
org.eclipse.text.edits.MalformedTreeException: Overlapping text edits
at org.eclipse.text.edits.TextEdit$InsertionComparator.compare(TextEdit.java:118)
at java.util.Collections.indexedBinarySearch(Collections.java:322)
at java.util.Collections.binarySearch(Collections.java:310)
at org.eclipse.text.edits.TextEdit.computeInsertionIndex(TextEdit.java:757)
at org.eclipse.text.edits.TextEdit.internalAdd(TextEdit.java:742)
at org.eclipse.text.edits.TextEdit.addChild(TextEdit.java:332)
at
org.eclipse.jdt.internal.corext.refactoring.changes.TextChangeCompatibility.insert(TextChangeCompatibility.java:78)
at
org.eclipse.jdt.internal.corext.refactoring.code.InlineMethodRefactoring.createChange(InlineMethodRefactoring.java:291)
at
org.eclipse.ltk.core.refactoring.CreateChangeOperation.run(CreateChangeOperation.java:117)
at
org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:189)
at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:1719)
at
org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:86)
at
org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:113)
Comment 1 David Saff CLA 2005-06-14 11:17:06 EDT
Created attachment 23061 [details]
The file that generates the error
Comment 2 Dirk Baeumer CLA 2005-06-14 18:02:48 EDT
The problem comes from the fact that JDT/Core considers two bindings as equal
although the aren't. The bindings are: 

The method binding representing the method declaration of 

java.lang.String methodNameFor(java.lang.String) 

and the binding representing the method invocation methodNameFor(sline) inside
of the following method:

private Object evaluateLine(String line,ArithmeticContext context) throws
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
  SayTestLine sline=new SayTestLine(line);
  String methodName=methodNameFor(sline);
  Method[] methods=getClass().getMethods();
  for (  Method method : methods) {
    if (method.getName().equals(methodName)) {
      return method.invoke(this,argsArray(context,method,sline));
    }
  }
  return null;
}

Both method bindings are first "normalized" using
IMethodBinding#getMethodDeclaration. 

The binding key of the method declaration is

Lp/SayTests;.methodNameFor(Ljava/lang/String;)Ljava/lang/String;

and for the method invocation

Lp/SayTests;.methodNameFor(Lp/SayTests$SayTestLine;)Ljava/lang/String;

So the keys aren't equal.

Moving to JDT/Core.

Philippe, can you consider this for RC3 since UI is relying on isEqualTo now and
not on the keys anymore.
Comment 3 Dirk Baeumer CLA 2005-06-14 18:14:59 EDT
Other invocations to String methodNameFor(SayTestLine sline) are consider equal
as well. The invocation that leads to the malformed tree exception is the one
inside of methodNameFor(String line) which is the method to be inlined.
Comment 4 Dirk Baeumer CLA 2005-06-14 18:27:39 EDT
To reproduce:

- create a 1.5 project
- add the attached source
- set a conditional break point at TargetProvider line 306. As condition
  use Bindings.equals(fBinding, ((IMethodBinding)binding).getMethodDeclaration())
  (e.g the same as the return method)
- select the method java.lang.String methodNameFor(java.lang.String) in the editor
  and call Inline
- press Next or OK on the wizard.
Comment 5 Dirk Baeumer CLA 2005-06-14 18:32:33 EDT
When the breakpoint is hit the third and forth time the bindings shouldn't be equal.
Comment 6 Jerome Lanneluc CLA 2005-06-15 07:13:29 EDT
The test case requires a version of JUnit that I don't have. Where could I get
it from ?
Comment 7 David Saff CLA 2005-06-15 09:31:52 EDT
Jerome,

I'll send a jar of my JUnit version to you by private e-mail.  Sorry for the
oversight.
Comment 8 Jerome Lanneluc CLA 2005-06-15 12:17:32 EDT
Created attachment 23211 [details]
Change in BindingComparator

Fix for bug 93408 was not quite right. All traversed types were added to the
know types. In the case of this bug, String was added, and we would not compare
it to SayTestLine.

However the recursion the vistedTypes HashSet is trying to prevent can only
occur on a type variable (its declaring element can contain the type variable).


The fix consists in adding type variables only to the visitedTypes.
Comment 9 Jerome Lanneluc CLA 2005-06-15 12:18:01 EDT
Created attachment 23212 [details]
Regression test
Comment 10 Philipe Mulet CLA 2005-06-15 12:52:04 EDT
+1 for RC3.

Dirk - pls vote.
Comment 11 Dirk Baeumer CLA 2005-06-15 13:32:18 EDT
+1 for RC3.
Comment 12 Jerome Lanneluc CLA 2005-06-16 04:40:41 EDT
Thanks Dirk.
Released fix and test.
Comment 13 Olivier Thomann CLA 2005-06-16 14:10:06 EDT
Verified using N20050616-0010 + JDT/Core HEAD
Comment 14 Jerome Lanneluc CLA 2005-06-17 03:26:03 EDT
*** Bug 100494 has been marked as a duplicate of this bug. ***