Bug 64750 - NPE in Java AST Creation - editing some random file
Summary: NPE in Java AST Creation - editing some random file
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.0 RC2   Edit
Assignee: Jerome Lanneluc CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-05-31 11:12 EDT by Jean-Michel Lemieux CLA
Modified: 2004-06-11 10:07 EDT (History)
1 user (show)

See Also:


Attachments
Use these preferences to reproduce the problem (330.00 KB, text/plain)
2004-06-04 16:50 EDT, Olivier Thomann CLA
no flags Details
Proposed patch (3.52 KB, patch)
2004-06-07 11:41 EDT, Jerome Lanneluc CLA
no flags Details | Diff
Regression tests (1.72 KB, patch)
2004-06-07 11:42 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 Jean-Michel Lemieux CLA 2004-05-31 11:12:47 EDT
RC1 test candidate:
I was editing a file and an error dialog appeared. This was the stack dump for
the exception:

An internal error occurred during: "Java AST creation".
java.lang.NullPointerException
org.eclipse.jdt.core.dom.DefaultBindingResolver.resolveWellKnownType(DefaultBindingResolver.java:425)
org.eclipse.jdt.core.dom.AST.resolveWellKnownType(AST.java:1076)
org.eclipse.jdt.internal.corext.refactoring.code.flow.ReturnFlowInfo.getReturnFlag(ReturnFlowInfo.java:31)
org.eclipse.jdt.internal.corext.refactoring.code.flow.ReturnFlowInfo.<init>(ReturnFlowInfo.java:19)
org.eclipse.jdt.internal.corext.refactoring.code.flow.FlowAnalyzer.createReturn(FlowAnalyzer.java:152)
org.eclipse.jdt.internal.corext.refactoring.code.flow.FlowAnalyzer.endVisit(FlowAnalyzer.java:649)
org.eclipse.jdt.core.dom.ReturnStatement.accept0(ReturnStatement.java:135)
org.eclipse.jdt.core.dom.ASTNode.accept(ASTNode.java:2454)
org.eclipse.jdt.internal.corext.refactoring.code.flow.InOutFlowAnalyzer.perform(InOutFlowAnalyzer.java:39)
org.eclipse.jdt.internal.ui.search.MethodExitsFinder.markReferences(MethodExitsFinder.java:100)
org.eclipse.jdt.internal.ui.search.MethodExitsFinder.perform(MethodExitsFinder.java:80)
org.eclipse.jdt.internal.ui.javaeditor.JavaEditor.updateOccurrenceAnnotations(JavaEditor.java:3638)
org.eclipse.jdt.internal.ui.javaeditor.JavaEditor$7.selectionChanged(JavaEditor.java:3690)
org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$PartListenerGroup.calculateASTandInform(SelectionListenerWithASTManager.java:130)
org.eclipse.jdt.internal.ui.viewsupport.SelectionListenerWithASTManager$1.run(SelectionListenerWithASTManager.java:102)
org.eclipse.core.internal.jobs.Worker.run(Worker.java:66)
Comment 1 Olivier Thomann CLA 2004-05-31 12:25:02 EDT
Would you have some steps to reproduce?
Comment 2 Jean-Michel Lemieux CLA 2004-05-31 14:03:41 EDT
Wasn;t able to reproduce again. But note that I got this error twice when it
happened. Of course once I fixed the compile errors, things were fine.
Comment 3 Olivier Thomann CLA 2004-06-01 09:05:37 EDT
OK, this seems to be a case where compile errors prevents a compilation unit
scope to be created. Then there is no compilation unit scope around to retrieve
the well-known types. I will investigate to see how this could be fixed.
Comment 4 Olivier Thomann CLA 2004-06-02 09:14:38 EDT
Could you please provide a test case with compiler errors? Looking at the code I
don't see how it is possible not to have a compilation unit scope.

Thanks.
Comment 5 Jean-Michel Lemieux CLA 2004-06-02 10:41:51 EDT
I forget the class that I was editing, but as the traceback shows - it is
possible :)
Comment 6 Olivier Thomann CLA 2004-06-04 16:33:00 EDT
I reproduced the problem.
It comes from the line 152 in org.eclipse.jdt.internal.core.CompilationUnit. The
DOM/AST is created with a compilation unit declaration that has no scopes. It
wasn't even resolved. So in this case we either don't ask to resolve bindings or
we provide a compilation unit that contains bindings and scopes.
Jerome,

Any idea why this compilation unit declaration has been created without being
resolved?
Comment 7 Olivier Thomann CLA 2004-06-04 16:49:34 EDT
The problem is in there:
		if (info instanceof ASTHolderCUInfo) {
			int astLevel = ((ASTHolderCUInfo) info).astLevel;
			org.eclipse.jdt.core.dom.CompilationUnit cu =
AST.convertCompilationUnit(astLevel, unit, contents, options, pm);
			((ASTHolderCUInfo) info).ast = cu;
		}

The unit passed to that call doesn't have any scope. Therefore the DOM/AST
should not be created requesting the bindings or the compilation unit
declaration should contain scopes and bindings. Otherwise this is inconsistent
and leads to the NPE.

I will attach the preferences I am using. It doesn't seem to happen with default
preferences.
Comment 8 Olivier Thomann CLA 2004-06-04 16:50:03 EDT
Created attachment 11616 [details]
Use these preferences to reproduce the problem
Comment 9 Olivier Thomann CLA 2004-06-04 16:55:55 EDT
I used this test case in a Java project.

"public class Foo {	
	public static void main(String[] args) {
		System.out.println((int) 's');
	}
}"

Simply add '}' at the end of the file and you should see the problem. The scope
passed to the DefaultBindingResolver is null. Therefore it is not possible to
ask for well known type bindings.
Comment 10 Jerome Lanneluc CLA 2004-06-07 06:26:16 EDT
Olivier, even with your preferences I cannot reproduce. Do you have detail 
steps ?

To answer your question in comment #6, UI drives the ast resolution by asking 
for problems. In your case it looks like UI was not interested in problems. It 
usually doesn't ask for well known types in this case. So we need to 
understand what is the case where it doesn't ask for problems, but it asks for 
well known types. Without steps I don't understand how this can happen.
Comment 11 Olivier Thomann CLA 2004-06-07 09:24:31 EDT
The problem is that once a DefaultBindingResolver has been created with a null
compilation unit scope, all request to get a well known binding will fail with
NPE. This is what the PR is reporting.
If you put a breakpoint in the constructor of DefaultBindingResolver that takes
a compilation unit scope, you will see that in some cases the scope is null.
This should NEVER be null.
The problem comes from the piece of code in comment 7. The compilation unit
declaration used to create the DOM/AST compilation unit has not been resolved
yet. Therefore there are no scopes or bindings available. If this is the case,
then the DOM/AST compilation unit should be created without bindings. The other
solution is to resolve the compilation unit declaration prior to convert it to a
DOM/AST.
For the steps, I could reproduce the problem with the Foo class in comment 9.
1) Create an empty workspace
2) Create a java project with the class Foo
3) Edit quickly the class Foo by adding syntax errors (extra '}' at the end)
4) Save/edit etc.

You should get a null scope inside the DefaultBindingResolver constructor.

I replaced it code with:
DefaultBindingResolver(CompilationUnitScope scope) {
	this();
	this.scope = scope;
	if (scope == null) {
		System.out.println("NULL SCOPE"); //$NON-NLS-1$ BREAKPOINT HERE
	}
}
Comment 12 Jerome Lanneluc CLA 2004-06-07 11:41:42 EDT
Created attachment 11668 [details]
Proposed patch

Changed AST#convertCompilationUnit(...) to take a 'isResolved' boolean. If not
resolved, creates a BindingResolver instead (that returns null to
resolveWellKnownType() as spec'ed).
Comment 13 Jerome Lanneluc CLA 2004-06-07 11:42:38 EDT
Created attachment 11669 [details]
Regression tests

Added regression test ASTConverterTests2#test0538h()
Comment 14 Olivier Thomann CLA 2004-06-07 12:32:45 EDT
Steps to reproduce:

1) Load org.eclipse.team.cvs.ui from HEAD on dev.eclipse.org
2) Go to org.eclipse.team.internal.ccvs.ui.subscriber.ChangeLogModelProvider
3) Go to the method getSyncInfoComment(SyncInfo[] infos, IProgressMonitor monitor)
4) Change the return type to be void

5) After few seconds (next reconcile), you should get an error dialog.
Comment 15 Olivier Thomann CLA 2004-06-07 12:39:11 EDT
I forgot to mention that you need to have:
Preferences>Java>Editor>Mark Occurrences>Mark occurrences in file checked (also
check all options except sticky).
Comment 16 Jerome Lanneluc CLA 2004-06-07 13:29:30 EDT
Fix and test released.
Comment 17 Olivier Thomann CLA 2004-06-11 10:07:32 EDT
Verified in 200406110010