Bug 320633 - [DOM/AST] Missing types inside parameterized type reference stops AST creation
Summary: [DOM/AST] Missing types inside parameterized type reference stops AST creation
Status: CLOSED DUPLICATE of bug 320802
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.6   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.7 M1   Edit
Assignee: Olivier Thomann CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-07-22 10:11 EDT by Olivier Thomann CLA
Modified: 2010-08-05 18:35 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 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 ***