Bug 108378 - [1.5][compiler] NPE on type hierarchy with complex generics
Summary: [1.5][compiler] NPE on type hierarchy with complex generics
Status: RESOLVED DUPLICATE of bug 101456
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-08-30 11:23 EDT by Eric Inman CLA
Modified: 2005-08-30 13:40 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Inman CLA 2005-08-30 11:23:23 EDT
Given:

interface A<T extends A<T>> {}
interface B<T extends A<T>> {}
interface C extends B<D> {}
interface D extends A<D>, C {}

creating a type hierarchy (F4) for D produces a null pointer exception on a 
superInterfaces reference in ReferenceBinding.implementsInterface. The problem 
is due to ClassScope performing checkParameterizedTypeBounds() before the 
hierarchy is finished being connected. ClassScope.connectTypeHierarchy() 
defers calling checkParameterizedTypeBounds() until after connections are 
made, but this does not account for recursive calls to connectTypeHierarchy(). 
In this example, connectTypeHierarchy() is called for D, which recursively 
calls itself for C, where checkParameterizedTypeBounds() checks if D 
implements A<D> before D is finished being connected. Therefore, 
connectTypeHierarchy() should not call checkParameterizedTypeBounds() if it is 
being called recursively, but rather should save the scopes where 
checkParameterizedTypeBounds() is needed and perform it on all them in the 
outermost connectTypeHierarchy() call. For example:

public final class TypeBoundsChecker {
	private static final TypeBoundsChecker CHECKER =
            new TypeBoundsChecker();
	private final Stack<ClassScope> stack = new Stack<ClassScope>();
	private int nestingLevel = 0;

	private TypeBoundsChecker() {}
	
	private final void nest(final ClassScope scope) {
		stack.push(scope);
		nestingLevel++;}
	
	private final void unnest() {
		nestingLevel--;
		if (nestingLevel == 0) checkBounds();}
	
	private final void checkBounds() {
		while (!stack.isEmpty())
                    stack.pop().checkParameterizedTypeBounds();}
	
	public static final void nestScope(final ClassScope scope) {
		CHECKER.nest(scope);}
	
	public static final void unnestScope() {CHECKER.unnest();}
}

with connectTypeHierarchy() calling nestScope() and unnestScope() at the 
beginning and end of the hierarchy connection process seems to be one way to 
fix the problem.
Comment 1 Olivier Thomann CLA 2005-08-30 11:26:36 EDT
This might be a duplicate of bug 101456.
Difficult to say without a stack trace.
Could you please check if it works for 3.2M1?
Thanks.
Comment 2 Eric Inman CLA 2005-08-30 13:37:56 EDT
(In reply to comment #1)
> This might be a duplicate of bug 101456.
> Difficult to say without a stack trace.
> Could you please check if it works for 3.2M1?
> Thanks.

Yes, it works for 3.2M1. Thanks.

Also, the stack trace for 101456 was similar, so it does seem to be a 
duplicate.
Comment 3 Olivier Thomann CLA 2005-08-30 13:40:47 EDT

*** This bug has been marked as a duplicate of 101456 ***