Bug 104065 [quick fix] No Quick Fixes for marker with IMarker.LINE_NUMBER and no IMarker.CHAR_START and IMarker.CHAR_END
I'm creating (problem) markers for a java file and I only have a line number available when I create the marker. I add the IMarker.LINE_NUMBER attribute to the marker attributes, but do not specify a CHAR_START or CHAR_END. The marker shows up in the file, but there are no Quick Fixes available for it (using Ctrl+1 or right click on the marker). When I click on the marker in the problems view, however, I get the quick fixes that are possible. (This used to work in 3.0, doesnt now in 3.1) I traced through the code and found that the markers with a line number get their end and start range set to be the same in: AbstractMarkerAnnotationModel.createPositionFromMarker(IMarker marker). Because the start and end are both -1 coming into the method, end = start. In JavaCorrectionAssistant.collectQuickFixableAnnotations(), there is a check to see if the Position for the offset is within the range -- its a call to JavaCorrectionAssistant.isInside(). isInside has the following body: private static boolean isInside(int offset, int start, int end) { return offset >= start && offset < end; } BUT, because the start and end are set to be the same, its NEVER inside. The net effect: any markers with a position set via LINE_NUMBER will not get a quick fix.
org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/text/correction/JavaCorrectionAssistant.java
if (goToClosest) {
			IRegion lineInfo= getRegionOfInterest(editor, invocationLocation);
			if (lineInfo == null) {
				return invocationLocation;
			}
			int rangeStart= lineInfo.getOffset();
			int rangeEnd= rangeStart + lineInfo.getLength();
			
			ArrayList allAnnotations= new ArrayList();
			ArrayList allPositions= new ArrayList();
			int bestOffset= Integer.MAX_VALUE;
			while (iter.hasNext()) {
				Annotation annot= (Annotation) iter.next();
				if (JavaCorrectionProcessor.isQuickFixableType(annot)) {
					Position pos= model.getPosition(annot);
					if (pos != null && isInside(pos.offset, rangeStart, rangeEnd)) { 
						allAnnotations.add(annot);
						allPositions.add(pos);
						bestOffset= processAnnotation(annot, pos, invocationLocation, bestOffset);
					}
				}
			}
			if (bestOffset == Integer.MAX_VALUE) {
				return invocationLocation;
			}
			for (int i= 0; i < allPositions.size(); i++) {
				Position pos= (Position) allPositions.get(i);
				if (isInside(bestOffset, pos.offset, pos.offset + pos.length)) {
					resultingAnnotations.add(allAnnotations.get(i));
				}