Bug 320633

Summary: [DOM/AST] Missing types inside parameterized type reference stops AST creation
Product: [Eclipse Project] JDT Reporter: Olivier Thomann <Olivier_Thomann>
Component: CoreAssignee: Olivier Thomann <Olivier_Thomann>
Status: CLOSED DUPLICATE QA Contact:
Severity: normal    
Priority: P3    
Version: 3.6   
Target Milestone: 3.7 M1   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Olivier Thomann CLA 2010-07-22 10:11:20 EDT
From the JDT Eclipse forum. Message #548143.

The following source code:

Map<MissingType1,MissingType2> map = ...

causes the problem. In case ASTParser is asked to resolve bindings and MissingType1 and MissingType2 are not on the classpath, above source code will silently stop parsing operation.

The reason is (line numbers from Eclipse 3.6):

SingleNameReference.resolveType(BlockScope) line 876:

scope.problemReporter().invalidType(this, variableType);

problemReporter() call causes problem reporter instance to be initialized with reference context, so problem (missing type) is processed and reported properly:

public ProblemReporter problemReporter() {
	MethodScope outerMethodScope;
	if ((outerMethodScope = outerMostMethodScope()) == this) {
		ProblemReporter problemReporter = referenceCompilationUnit().problemReporter;
		problemReporter.referenceContext = this.referenceContext;
		return problemReporter;
	}
	return outerMethodScope.problemReporter();
}



Then missing parametrized type are enumerated in ProblemReported.invalidType(...) line 3742:

public void invalidType(ASTNode location, TypeBinding type) {
...
	if (type.isParameterizedType()) {
		List missingTypes = type.collectMissingTypes(null);
		if (missingTypes != null) {
			for (Iterator iterator = missingTypes.iterator(); iterator.hasNext(); ) {
                                // recursive call
				invalidType(location, (TypeBinding) iterator.next());
                              // this.referenceContext now null!
			}
			return;
		}
	}
        ....
	this.handle(
		id,
		new String[] {new String(type.leafComponentType().readableName()) },
		new String[] {new String(type.leafComponentType().shortReadableName())},
		location.sourceStart,
		end);
}



The very last this.handle(...) call sets ProblemReporter.referecenContext to null:

private void handle(
	int problemId,
	String[] problemArguments,
	String[] messageArguments,
	int problemStartPosition,
	int problemEndPosition){

	this.handle(
			problemId,
			problemArguments,
			messageArguments,
			problemStartPosition,
			problemEndPosition,
			this.referenceContext,
			this.referenceContext == null ? null : this.referenceContext.compilationResult());
	this.referenceContext = null;
}



So second missing parametrized type is never reported and instead AbortException is thrown which stops whole ongoing parsing and bindings resolving.

The solution might be to save referenceContext before recursive call and restore after it:

for (Iterator iterator = missingTypes.iterator(); iterator.hasNext(); ) {
    // recursive call
    RefereceContext savedContext = this.referenceContext;
    invalidType(location, (TypeBinding) iterator.next());
    this.referenceContext = savedContext;
}
What is the best way to make this bug being fixed?
Comment 1 Olivier Thomann CLA 2010-08-05 18:35:46 EDT

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