Bug 143212 - IAE in log
Summary: IAE in log
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.3 M1   Edit
Assignee: David Audel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on: 147877
Blocks:
  Show dependency tree
 
Reported: 2006-05-23 09:56 EDT by Darin Wright CLA
Modified: 2006-08-04 11:16 EDT (History)
4 users (show)

See Also:


Attachments
Proposed fix (3.14 KB, patch)
2006-05-24 04:32 EDT, David Audel CLA
no flags Details | Diff
Regression test (7.06 KB, patch)
2006-05-24 04:33 EDT, David Audel CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Darin Wright CLA 2006-05-23 09:56:17 EDT
From bug 142473 - someone found these exceptions in their log.

!ENTRY org.eclipse.jdt.ui 4 2 2006-05-23 11:07:11.376
!MESSAGE Problems occurred when invoking code from plug-in:
"org.eclipse.jdt.ui".
!STACK 0
java.lang.IllegalArgumentException
        at org.eclipse.jdt.core.dom.ASTNode.setSourceRange(ASTNode.java:2599)
        at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:891)
        at
org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:2353)
        at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:511)
        at
org.eclipse.jdt.core.dom.ASTConverter.buildBodyDeclarations(ASTConverter.java:179)
        at
org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:2637)
        at
org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:1236)
        at org.eclipse.jdt.core.dom.AST.convertCompilationUnit(AST.java:270)
        at
org.eclipse.jdt.internal.core.CompilationUnit.buildStructure(CompilationUnit.java:187)
        at
org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:229)
        at
org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:505)
        at
org.eclipse.jdt.internal.core.CompilationUnit.makeConsistent(CompilationUnit.java:993)
        at
org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.makeConsistent(ReconcileWorkingCopyOperation.java:131)
        at
org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation(ReconcileWorkingCopyOperation.java:71)
        at
org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:720)
        at
org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:779)
        at
org.eclipse.jdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1123)
        at
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy$1.run(JavaReconcilingStrategy.java:97)
        at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
        at
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:82)
        at
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:145)
        at
org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.reconcile(CompositeReconcilingStrategy.java:86)
        at
org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.reconcile(JavaCompositeReconcilingStrategy.java:94)
        at
org.eclipse.jface.text.reconciler.MonoReconciler.process(MonoReconciler.java:75)
        at
org.eclipse.jdt.internal.ui.text.JavaReconciler.process(JavaReconciler.java:342)
        at
org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run(AbstractReconciler.java:204)

!ENTRY org.eclipse.jdt.ui 4 0 2006-05-23 11:07:11.376
!MESSAGE Error in JDT Core during reconcile
!STACK 0
java.lang.IllegalArgumentException
        at org.eclipse.jdt.core.dom.ASTNode.setSourceRange(ASTNode.java:2599)
        at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:891)
        at
org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:2353)
        at org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:511)
        at
org.eclipse.jdt.core.dom.ASTConverter.buildBodyDeclarations(ASTConverter.java:179)
        at
org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:2637)
        at
org.eclipse.jdt.core.dom.ASTConverter.convert(ASTConverter.java:1236)
        at org.eclipse.jdt.core.dom.AST.convertCompilationUnit(AST.java:270)
        at
org.eclipse.jdt.internal.core.CompilationUnit.buildStructure(CompilationUnit.java:187)
        at
org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:229)
        at
org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:505)
        at
org.eclipse.jdt.internal.core.CompilationUnit.makeConsistent(CompilationUnit.java:993)
        at
org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.makeConsistent(ReconcileWorkingCopyOperation.java:131)
        at
org.eclipse.jdt.internal.core.ReconcileWorkingCopyOperation.executeOperation(ReconcileWorkingCopyOperation.java:71)
        at
org.eclipse.jdt.internal.core.JavaModelOperation.run(JavaModelOperation.java:720)
        at
org.eclipse.jdt.internal.core.JavaModelOperation.runOperation(JavaModelOperation.java:779)
        at
org.eclipse.jdt.internal.core.CompilationUnit.reconcile(CompilationUnit.java:1123)
        at
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy$1.run(JavaReconcilingStrategy.java:97)
        at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
        at
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:82)
        at
org.eclipse.jdt.internal.ui.text.java.JavaReconcilingStrategy.reconcile(JavaReconcilingStrategy.java:145)
        at
org.eclipse.jdt.internal.ui.text.CompositeReconcilingStrategy.reconcile(CompositeReconcilingStrategy.java:86)
        at
org.eclipse.jdt.internal.ui.text.JavaCompositeReconcilingStrategy.reconcile(JavaCompositeReconcilingStrategy.java:94)
        at
org.eclipse.jface.text.reconciler.MonoReconciler.process(MonoReconciler.java:75)
        at
org.eclipse.jdt.internal.ui.text.JavaReconciler.process(JavaReconciler.java:342)
        at
org.eclipse.jface.text.reconciler.AbstractReconciler$BackgroundThread.run(AbstractReconciler.java:204)
Comment 1 Olivier Thomann CLA 2006-05-23 10:02:40 EDT
Misja,

Would it be possible to get a test case?
Is the code syntactically correct when the error occurs?
Comment 2 David Audel CLA 2006-05-23 11:09:46 EDT
I found a test case to reproduce the same exception

public class X {
  void bar() {
    #
    assert 0 == 1 : a[0; // ] is missing
  }
}

But these following test cases don't cause the exception

public class X {
  void bar() {
    #
    assert 0 == 1 : a[0];
  }
}

public class X {
  void bar() {
    #
    assert 0 == 1 : a[0 ; // ] is missing and there is space after '0'
  }
}
Comment 3 David Audel CLA 2006-05-23 15:08:29 EDT
The problem is inside statements recovery.

With 'assert 0 == 1 : a[0;' statement recovery add a fake token ']' just after '0'.
The position of this fake token is the position of the end of the previous real token + 1. It is also the location of the real token ';'.
When the ASTConverter convert the assert statement, it try to retreive the location of the ';' by starting just after the end of the expression. In this case it is also just after the ';', that's why the ';' isn't found and the end of the assert statement is wrongly considered as -1.

Instead of set the position of the fake token just after the end of the previous real token there, in some case like this one we could set the position of the fake token at the same location of the end of the previous real token. Indeed the ']' belongs to the expression and not to the next or enclosing node.

However do such change for 3.2 would be to risky because this could change slightly the general behavior of the statement recovery and add some new unknown instabilities.
Thats why if we don't want to throw the exception in 3.2 it would be better to only add a workaround in the ASTConverter.

I am going to write a patch with a workaround. I will attach it to this bug when it will be ready.

Comment 4 David Audel CLA 2006-05-23 15:55:01 EDT
The same bug occurs with the following test case but our internal behavior is not exactly the same.

public class X {
  void bar() {
    #
    assert 0 == 1 : foo(; // ) is missing
  }
}

The end of the ast node 'foo(' is the 'currentPosition-1' of the fake token ).
The end of the ast node 'a[0' is the 'startPosition' of the fake token ].
Inserted fake tokens 'currentPosition' and 'startPosition' are equals.
Comment 5 David Audel CLA 2006-05-23 17:30:34 EDT
Another test case with some differences

public class X {
  void bar() {
    #
    assert 0 == 1 : ("aa"; // ) is missing
  }
}
Comment 6 David Audel CLA 2006-05-24 04:32:50 EDT
Created attachment 42377 [details]
Proposed fix
Comment 7 David Audel CLA 2006-05-24 04:33:11 EDT
Created attachment 42378 [details]
Regression test
Comment 8 David Audel CLA 2006-05-24 04:50:22 EDT
This fix is not only a workaround.

The exception can occurs for two reasons:
1) The end position of the last expression of the assert statement contains the ';'.This end position is used to start the search of the ending semicolon so the semicolon is never found.
eg: 'assert 0 == 0 : a[0;'
2) The last token of the last expression of the assert statement ends with a fake ) or ] or }. As semicolon is take into account only if the parenthesis count is 0, then the semicolon is never found.
eg: 'assert 0 == 0 : foo(;'

The case 2) is fixed by the proposed patch. This patch remove the parenthesis count and use the end of the last DOM expression node instead of the end of the last compiler expression node. That's because the DOM position are corrected and are always correct so we don't need to count parenthesis.
The case 1) would require to change the end position of the last expresion as explain in comment 3. This change would be to risky, and the patch add a workaround instead. The workaround is to use directly the end of the last expression when we fail to retreive the semicolon location.
Comment 9 David Audel CLA 2006-05-24 04:57:04 EDT
Olivier - the proposed patch isn't exactly the patch you send me.
In the proposed fix 'retrieveSemiColonPosition()' initialize the scanner to 'int end = start + length' as it is in the current code instead of 'int end = start + length - 1'.
If we do not use this location the start position if the sanner is inside the string literal with the following test case: assert 0 == 1 : ("aa";.
Comment 10 David Audel CLA 2006-05-24 05:36:52 EDT
This problem isn't highly critical as it concerns only assert statements. Therefore it's probably too late to add this fix for 3.2 but this is a good candidate for 3.2.1.
Comment 11 David Audel CLA 2006-06-21 07:48:38 EDT
Inlike i thought the problem with array access isn't a problem of recovery. The problem is caused by a bug in the Parser (see bug 147877). The diagnosis of case 2) is still correct.
Comment 12 David Audel CLA 2006-06-22 04:35:36 EDT
Fix released and tests added
  ASTConverterRecoveryTest#test0015() -> test0017()

Released for 3.3 M1.
Comment 13 Frederic Fusier CLA 2006-08-04 11:16:25 EDT
Verified for 3.3 M1 using build I20060804-0010.