Bug 540448 - Fix end-of-line code minings for CRLF

Also-By: Thomas Wolf <thomas.wolf@paranor.ch>
Change-Id: I8371007a2b90c9b63c06daad8d868d381fea3bee
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.text/+/190801
Tested-by: Mickael Istria <mistria@redhat.com>
Reviewed-by: Mickael Istria <mistria@redhat.com>
Reviewed-by: Thomas Wolf <thomas.wolf@paranor.ch>
diff --git a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/codemining/CodeMiningDemo.java b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/codemining/CodeMiningDemo.java
index ef74891..20236a6 100644
--- a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/codemining/CodeMiningDemo.java
+++ b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/codemining/CodeMiningDemo.java
@@ -53,7 +53,15 @@
 						+ "// Empty lines show a header annotating they're empty.\n"
 						+ "// The word `echo` is echoed.\n"
 						+ "// Lines containing `end` get an annotation at their end\n\n"
-						+ "class A\n" + "new A\n" + "new A\n\n" + "class 5\n" + "new 5\n" + "new 5\n" + "new 5"),
+						+ "class A\n" //
+						+ "new A\n" //
+						+ "new A\n\n" //
+						+ "code mining at end here\n"
+						+ "code mining at end here with CRLF\r\n"
+						+ "class 5\n" //
+						+ "new 5\n" //
+						+ "new 5\n" //
+						+ "new 5\n"),
 				new AnnotationModel());
 		// Add AnnotationPainter (required by CodeMining)
 		addAnnotationPainter(sourceViewer);
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/LineEndCodeMining.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/LineEndCodeMining.java
index 2386173..e52786f 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/LineEndCodeMining.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/codemining/LineEndCodeMining.java
@@ -27,10 +27,10 @@
 
 	private static Position getLineEndPosition(IDocument document, int line) throws BadLocationException {
 		int lastCharOffset= document.getLineOffset(line) + document.getLineLength(line);
-		if (lastCharOffset < document.getLength()) {
-			lastCharOffset--; // place on the newline \n char, not on 1st char of next line
-		}
-		return new Position(lastCharOffset);
+		String delimiter= document.getLineDelimiter(line);
+		return delimiter == null ? // last line of document
+				new Position(document.getLength(), 0) : //
+				new Position(lastCharOffset - delimiter.length(), delimiter.length());
 	}
 
 }
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
index 2b28b01..7a4ba95 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java
@@ -143,7 +143,9 @@
 			annotation.draw(gc, textWidget, widgetOffset, length, color, 0, 0);
 		} else {
 			int line= textWidget.getLineAtOffset(widgetOffset);
-			int lineEndOffset= widgetOffset < textWidget.getCharCount() ? widgetOffset : textWidget.getCharCount() - 1;
+			int lineEndOffset= (line == textWidget.getLineCount() - 1) ? //
+					textWidget.getCharCount() - 1 : //
+					textWidget.getOffsetAtLine(line + 1) - 1;
 			Rectangle bounds= textWidget.getTextBounds(lineEndOffset, lineEndOffset);
 			int lineEndX= bounds.x + bounds.width + gc.stringExtent("   ").x; //$NON-NLS-1$
 			annotation.setLocation(lineEndX, textWidget.getLinePixel(line) + textWidget.getLineVerticalIndent(line));
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java
index 62a1752..0c10b8a 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java
@@ -159,8 +159,14 @@
 	}
 
 	boolean isEndOfLine(int widgetOffset) {
-		return getTextWidget().getCharCount() == 0 || getTextWidget().getCharCount() <= widgetOffset ||
-				"\n".equals(getTextWidget().getText(widgetOffset, widgetOffset)); //$NON-NLS-1$
+		StyledText text= getTextWidget();
+		if (text.getCharCount() <= widgetOffset) { // Assuming widgetOffset >= 0
+			return true;
+		}
+		int line= text.getLineAtOffset(widgetOffset);
+		int startOfLine= text.getOffsetAtLine(line);
+		int offsetInLine= widgetOffset - startOfLine;
+		return offsetInLine >= text.getLine(line).length();
 	}
 
 }