diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/XMLSyntaxErrorCode.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/XMLSyntaxErrorCode.java index 62950abcf..3ee0fff04 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/XMLSyntaxErrorCode.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/participants/XMLSyntaxErrorCode.java @@ -167,8 +167,23 @@ public static Range toLSPRange(XMLLocator location, XMLSyntaxErrorCode code, Obj return XMLPositionUtility.selectChildEndTag(tag, offset, document); } case ContentIllegalInProlog: { - int endOffset = document.getText().indexOf("<"); int startOffset = offset + 1; + int endOffset = 0; + int errorOffset = offset + 1; + String text = document.getText(); + int startPrologOffset = text.indexOf("<"); + if (errorOffset < startPrologOffset) { + // Invalid content given before prolog. Prolog should be the first thing in the + // file if given. + startOffset = errorOffset; + endOffset = startPrologOffset; + } else { + // Invalid content given after prolog. Either root tag or comment should be + // present + int firstStartTagOffset = text.indexOf("<", errorOffset); + startOffset = errorOffset; + endOffset = firstStartTagOffset != -1 ? firstStartTagOffset : text.length(); + } return XMLPositionUtility.createRange(startOffset, endOffset, document); } case DashDashInComment: { diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSyntaxDiagnosticsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSyntaxDiagnosticsTest.java index 64a1b0202..73915904a 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSyntaxDiagnosticsTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSyntaxDiagnosticsTest.java @@ -85,11 +85,35 @@ public void testAttributePrefixUnbound() throws Exception { * @throws Exception */ @Test - public void testContentIllegalInProlog() throws Exception { + public void testBeforeContentIllegalInProlog() throws Exception { String xml = " ab?"; testDiagnosticsFor(xml, d(0, 1, 0, 4, XMLSyntaxErrorCode.ContentIllegalInProlog)); } + /** + * ContentIllegalInProlog tests + * + * @see https://wiki.xmldation.com/Support/Validator/ContentIllegalInProlog + * @throws Exception + */ + @Test + public void testAfterContentIllegalInProlog() throws Exception { + String xml = "ab\ncd"; + testDiagnosticsFor(xml, d(0, 54, 1, 2, XMLSyntaxErrorCode.ContentIllegalInProlog)); + } + + /** + * ContentIllegalInProlog tests + * + * @see https://wiki.xmldation.com/Support/Validator/ContentIllegalInProlog + * @throws Exception + */ + @Test + public void testAfterContentIllegalInProlog2() throws Exception { + String xml = "ab\ncd"; + testDiagnosticsFor(xml, d(0, 54, 1, 2, XMLSyntaxErrorCode.ContentIllegalInProlog)); + } + @Test public void testEncodingUTF_16() throws Exception { String xml = "";