Bug 31289 - StringIndexOutOfBoundsException is ASTRewrite
Summary: StringIndexOutOfBoundsException is ASTRewrite
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.1   Edit
Hardware: PC Windows 2000
: P3 normal (vote)
Target Milestone: 2.1 RC1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 30880 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-02-07 09:25 EST by Martin Aeschlimann CLA
Modified: 2003-03-11 11:33 EST (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Aeschlimann CLA 2003-02-07 09:25:34 EST
20030206

1. select CUCorrectionProposal.createCompilationUnitChange
 pull up

java.lang.reflect.InvocationTargetException: 
java.lang.StringIndexOutOfBoundsException: String index out of range: 122
	at java.lang.String.substring(String.java(Compiled Code))
	at org.eclipse.jdt.internal.corext.dom.ASTRewriteAnalyzer.doTextInsert
(ASTRewriteAnalyzer.java:681)
	at org.eclipse.jdt.internal.corext.dom.ASTRewriteAnalyzer.rewriteList
(ASTRewriteAnalyzer.java:531)
	at 
org.eclipse.jdt.internal.corext.dom.ASTRewriteAnalyzer.rewriteParagraphList
(ASTRewriteAnalyzer.java:355)
	at org.eclipse.jdt.internal.corext.dom.ASTRewriteAnalyzer.visit
(ASTRewriteAnalyzer.java:887)
	at org.eclipse.jdt.core.dom.TypeDeclaration.accept0
(TypeDeclaration.java:154)
	at org.eclipse.jdt.internal.corext.dom.ASTRewriteAnalyzer.visitList
(ASTRewriteAnalyzer.java(Compiled Code))
	at org.eclipse.jdt.internal.corext.dom.ASTRewriteAnalyzer.visitList
(ASTRewriteAnalyzer.java(Compiled Code))
	at 
org.eclipse.jdt.internal.corext.dom.ASTRewriteAnalyzer.rewriteParagraphList
(ASTRewriteAnalyzer.java:350)
	at org.eclipse.jdt.internal.corext.dom.ASTRewriteAnalyzer.visit
(ASTRewriteAnalyzer.java:806)
	at org.eclipse.jdt.core.dom.CompilationUnit.accept0
(CompilationUnit.java:155)
	at org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java(Compiled Code))
	at org.eclipse.jdt.internal.corext.dom.ASTRewrite.rewriteNode
(ASTRewrite.java:120)
	at 
org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoring.fillWith
RewriteEdits(PullUpRefactoring.java:1573)
	at 
org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoring.createCh
angeManager(PullUpRefactoring.java:1171)
	at 
org.eclipse.jdt.internal.corext.refactoring.structure.PullUpRefactoring.checkInp
ut(PullUpRefactoring.java:688)
	at org.eclipse.jdt.internal.ui.refactoring.CheckConditionsOperation.run
(CheckConditionsOperation.java:59)
	at org.eclipse.jdt.internal.ui.refactoring.CreateChangeOperation.run
(CreateChangeOperation.java:94)
	at org.eclipse.jdt.internal.ui.refactoring.PerformChangeOperation.run
(PerformChangeOperation.java:138)
	at org.eclipse.jface.operation.ModalContext.runInCurrentThread
(ModalContext.java:296)
	at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:246)
	at org.eclipse.jface.wizard.WizardDialog.run(WizardDialog.java:716)
	at 
org.eclipse.jdt.internal.ui.refactoring.PerformRefactoringUtil.performRefactorin
g(PerformRefactoringUtil.java:43)
	at 
org.eclipse.jdt.internal.ui.refactoring.RefactoringWizard.performFinish
(RefactoringWizard.java:366)
	at 
org.eclipse.jdt.internal.ui.refactoring.UserInputWizardPage.performFinish
(UserInputWizardPage.java:113)
	at 
org.eclipse.jdt.internal.ui.refactoring.PullUpInputPage2.performFinish
(PullUpInputPage2.java:373)
	at 
org.eclipse.jdt.internal.ui.refactoring.RefactoringWizard.performFinish
(RefactoringWizard.java:429)
	at org.eclipse.jface.wizard.WizardDialog.finishPressed
(WizardDialog.java:570)
	at 
org.eclipse.jdt.internal.ui.refactoring.RefactoringWizardDialog.finishPressed
(RefactoringWizardDialog.java:73)
	at org.eclipse.jface.wizard.WizardDialog.buttonPressed
(WizardDialog.java:308)
	at org.eclipse.jface.dialogs.Dialog$1.widgetSelected(Dialog.java:417)
	at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java
(Compiled Code))
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java
(Compiled Code))
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java
(Compiled Code))
	at org.eclipse.jface.window.Window.runEventLoop(Window.java(Compiled 
Code))
	at org.eclipse.jface.window.Window.open(Window.java:541)
	at 
org.eclipse.jdt.internal.ui.refactoring.actions.RefactoringStarter.activate
(RefactoringStarter.java:59)
	at org.eclipse.jdt.ui.actions.PullUpAction.startRefactoring
(PullUpAction.java:177)
	at org.eclipse.jdt.ui.actions.PullUpAction.run(PullUpAction.java:100)
	at org.eclipse.jdt.ui.actions.SelectionDispatchAction.dispatchRun
(SelectionDispatchAction.java:191)
	at org.eclipse.jdt.ui.actions.SelectionDispatchAction.run
(SelectionDispatchAction.java:169)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:804)
	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection
(ActionContributionItem.java:450)
	at 
org.eclipse.jface.action.ActionContributionItem$ActionListener.handleEvent
(ActionContributionItem.java(Compiled Code))
	at 
org.eclipse.jface.action.ActionContributionItem$ActionListener.handleEvent
(ActionContributionItem.java(Compiled Code))
	at 
org.eclipse.jface.action.ActionContributionItem$ActionListener.handleEvent
(ActionContributionItem.java(Compiled Code))
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java
(Compiled Code))
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java
(Compiled Code))
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java
(Compiled Code))
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java
(Compiled Code))
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java
(Compiled Code))
	at org.eclipse.ui.internal.Workbench.run(Workbench.java:1272)
	at org.eclipse.core.internal.boot.InternalBootLoader.run
(InternalBootLoader.java:845)
	at org.eclipse.core.boot.BootLoader.run(BootLoader.java:461)
	at java.lang.reflect.Method.invoke(Native Method)
	at org.eclipse.core.launcher.Main.basicRun(Main.java:247)
	at org.eclipse.core.launcher.Main.run(Main.java:703)
	at org.eclipse.core.launcher.Main.main(Main.java:539)
Comment 1 Martin Aeschlimann CLA 2003-02-07 09:50:23 EST
Bug in the code formatter, positiosn retruned are greater than the length of 
the string.

public void testBug31289() throws Exception {
	// str-len == 100
	String str= "protected X createCompilationUnitChange(int MISSING,int 
MISSING,int MISSING) throws CoreException {}");

	int[] pos=  {10, 10, 40, 50, 52, 62, 64, 74, 98, 99 };

	ICodeFormatter formatter= ToolFactory.createDefaultCodeFormatter(null);
	String formatted= formatter.format(str, 1, pos, "\r\n");
	
	int len= formatted.length();
	
	for (int i= 0; i < pos.length; i++) {
		assertTrue(pos[i] < len);
	}
}

Comment 2 Martin Aeschlimann CLA 2003-02-07 09:53:05 EST
*** Bug 30880 has been marked as a duplicate of this bug. ***
Comment 3 Olivier Thomann CLA 2003-02-07 11:26:54 EST
I tried your test case.
When you format: 
	String str= "protected X createCompilationUnitChange(int MISSING,int 
MISSING,int MISSING) throws CoreException {}");

I end up with:
"protected X createCompilationUnitChange(int MISSING, int MISSING, int MISSING)
	throws CoreException {
}"

which is 106 character long.
The positions are mapped to:
[10, 10, 40, 50, 53, 63, 66, 76, 102, 105]

98 and 99 are the positions of the '{' and '}' in the original source. They are
mapped to 102 and 105 which are the corresponding positions in the formatted source.

So I see no problem. Let me know what are your settings for the formatter. I
might not test the same thing.

Let me know what are the mapped positions you get and the formatted string.
Comment 4 Olivier Thomann CLA 2003-02-07 11:55:13 EST
Without further information, I cannot fix it. What I get looks ok to me.
Comment 5 Martin Aeschlimann CLA 2003-02-07 12:03:28 EST
public class DeclTest extends TestCase {
	public DeclTest(String name) {
		super(name);
	}
	public static Test suite() {
		return new DeclTest("testBug31289");
	}
	public void testBug31289() throws Exception {
		Hashtable options= JavaCore.getDefaultOptions();
		options.put(JavaCore.FORMATTER_TAB_CHAR, JavaCore.SPACE);
		options.put(JavaCore.FORMATTER_TAB_SIZE, "4");
		JavaCore.setOptions(options);				
		
		// str-len == 100
		String str= "protected X createCompilationUnitChange(" +
			"int MISSING,int MISSING,int MISSING) throws" +
			" CoreException {}";
		System.out.println("orig-length: " + str.length());

		int[] pos=  {10, 10, 40, 50, 52, 62, 64, 74, 98, 99 };

		ICodeFormatter formatter= 
			ToolFactory.createDefaultCodeFormatter(null);
		String formatted= formatter.format(str, 1, pos, "\r\n");
	
		int len= formatted.length();
		boolean isTooBig= false;
		System.out.println("length: " + len + "\ncontent:\n" + 
formatted);
		for (int i= 0; i < pos.length; i++) {
			System.out.print(", " + pos[i]);
			isTooBig= isTooBig || (pos[i] < len);
		}
		assertFalse(isTooBig);
	}
}

The output is
orig-length: 100
length: 149
content:
    protected X createCompilationUnitChange(
        int MISSING,
        int MISSING,
        int MISSING)
        throws CoreException {
    }
, 14, 14, 54, 64, 76, 86, 98, 108, 149, 152
Comment 6 Olivier Thomann CLA 2003-02-07 12:37:54 EST
Ok, I reproduced it. I will investigate.
Comment 7 Olivier Thomann CLA 2003-02-07 13:00:19 EST
The bug is located in the mapping of positions during the line splitting. We
know that this doesn't work very well. So you have two solutions:
1) don't try to map positions
2) don't try to split (increase the line split value).

It is clearly to risky to change that code now. This code will disappear anyway
as soon as the new code formatter is ready.
Comment 8 Martin Aeschlimann CLA 2003-02-07 13:43:51 EST
I'm required to get the positions (have to replace certain pieces in the code), 
so I will disable the splitting. 

Kai, you might want to make sure that the editor can add a guard for the wrong 
positions out of range.

fixed > 200302
Comment 9 Olivier Thomann CLA 2003-03-11 11:33:16 EST
Could you please verify this one as you fixed it?
Thanks.