Bug 134345

Summary: Problems from CompilationParticipants do not get cleaned up unless there are Java errors
Product: [Eclipse Project] JDT Reporter: Jess Garms <jgarms>
Component: CoreAssignee: Philipe Mulet <philippe_mulet>
Status: VERIFIED FIXED QA Contact:
Severity: critical    
Priority: P3 CC: jerome_lanneluc
Version: 3.2   
Target Milestone: 3.2 RC1   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Jess Garms CLA 2006-03-31 18:29:07 EST
In IncrementalImageBuilder.updateProblemsFor(), the following code exists:

protected void updateProblemsFor(SourceFile sourceFile, CompilationResult result) throws CoreException {
	IMarker[] markers = JavaBuilder.getProblemsFor(sourceFile.resource);
	CategorizedProblem[] problems = result.getProblems();
	if (problems == null && markers.length == 0) return;

	notifier.updateProblemCounts(markers, problems);
	JavaBuilder.removeProblemsFor(sourceFile.resource);
	storeProblemsFor(sourceFile, problems);
}

Before updating the problems, JavaBuilder.getProblemsFor() is called, and the update is short-circuited if no problems are found. But this only returns Java problems, not contributed problems, so if there are none, this code returns early before processing the contributed problems from compilation participants.
Comment 1 Philipe Mulet CLA 2006-03-31 18:34:01 EST
Patch would look like:

public static IMarker[] getProblemsFor(IResource resource) {
	try {
		if (resource != null && resource.exists()) {
			IMarker[] markers = resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			Set markerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
			if (markerTypes.isEmpty()) return markers;
			ArrayList markerList = new ArrayList(5);
			Iterator iterator = markerTypes.iterator();
			do {
				for (int i = 0, length = markers.length; i < length; i++) {
					markerList.add(markers[i]);
				}
				markers = resource.findMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
			} while (iterator.hasNext());
			IMarker[] result;
			markerList.toArray(result = new IMarker[markerList.size()]);
			return result;
		}
	} catch (CoreException e) {
		// assume there are no problems
	}
	return new IMarker[0];
}
Comment 2 Philipe Mulet CLA 2006-03-31 18:49:06 EST
Actually, this should be better:

public static IMarker[] getProblemsFor(IResource resource) {
	try {
		if (resource != null && resource.exists()) {
			IMarker[] markers = resource.findMarkers(IJavaModelMarker.JAVA_MODEL_PROBLEM_MARKER, false, IResource.DEPTH_INFINITE);
			Set markerTypes = JavaModelManager.getJavaModelManager().compilationParticipants.managedMarkerTypes();
			if (markerTypes.isEmpty()) return markers;
			ArrayList markerList = new ArrayList(5);
			for (int i = 0, length = markers.length; i < length; i++) {
				markerList.add(markers[i]);
			}
			Iterator iterator = markerTypes.iterator();
			while (iterator.hasNext()) {
				markers = resource.findMarkers((String) iterator.next(), false, IResource.DEPTH_INFINITE);
				for (int i = 0, length = markers.length; i < length; i++) {
					markerList.add(markers[i]);
				}
			}
			IMarker[] result;
			markerList.toArray(result = new IMarker[markerList.size()]);
			return result;
		}
	} catch (CoreException e) {
		// assume there are no problems
	}
	return new IMarker[0];
}
Comment 3 Philipe Mulet CLA 2006-03-31 18:58:58 EST
Jerome - pls add a testcase, and optimize all other iterator creations near manager marker types, to check for emptyness before allocating iterator.
Comment 4 Jerome Lanneluc CLA 2006-04-03 10:46:29 EDT
Added ParticipantBuildTests#testParticipantProblems().

Changed JavaBuilder#removeProblemsAndTasksFor(IResource) and removeProblemsFor(IResource) to first check for the empty managed marker list case.
Comment 5 Maxime Daniel CLA 2006-04-13 15:14:22 EDT
Verified for 3.2 RC1 using Build id: I20060413-0010.