From defe68c9124c82f7585ba3a07b3fc257fbca89db Mon Sep 17 00:00:00 2001 From: Nikolas Date: Tue, 12 Mar 2019 14:30:28 -0400 Subject: [PATCH] Error ranges fixed Fixes #321, #318, #317 Signed-off-by: Nikolas --- .../participants/XMLSchemaErrorCode.java | 9 +++- .../participants/XMLSyntaxErrorCode.java | 11 +++- .../xsd/participants/XSDErrorCode.java | 2 +- .../diagnostics/LSPMessageFormatter.java | 4 +- .../lsp4xml/utils/XMLPositionUtility.java | 54 ++++++++++++++----- .../XMLSchemaDiagnosticsTest.java | 38 ++++++++++++- .../XMLSyntaxDiagnosticsTest.java | 19 +++++++ .../src/test/resources/xsd/invoice.xsd | 2 +- 8 files changed, 117 insertions(+), 22 deletions(-) diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/XMLSchemaErrorCode.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/XMLSchemaErrorCode.java index b153d7d578..a01d0a457b 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/XMLSchemaErrorCode.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/XMLSchemaErrorCode.java @@ -46,8 +46,10 @@ public enum XMLSchemaErrorCode implements IXMLErrorCode { cvc_datatype_valid_1_2_1("cvc-datatype-valid.1.2.1"), // https://wiki.xmldation.com/Support/Validator/cvc-datatype-valid-1-2-1 cvc_elt_1_a("cvc-elt.1.a"), // https://wiki.xmldation.com/Support/Validator/cvc-elt-1 cvc_elt_3_1("cvc-elt.3.1"), // https://wiki.xmldation.com/Support/Validator/cvc-elt-3-1 + cvc_elt_3_2_1("cvc-elt.3.2.1"), //https://wiki.xmldation.com/Support/Validator/cvc-elt-3-2-1 cvc_elt_4_2("cvc-elt.4.2"), // https://wiki.xmldation.com/Support/Validator/cvc-elt-4-2 cvc_type_3_1_1("cvc-type.3.1.1"), // https://wiki.xmldation.com/Support/Validator/cvc-type-3-1-1 + cvc_type_3_1_2("cvc-type.3.1.2"), // https://wiki.xmldation.com/Support/Validator/cvc-type-3-1-2 cvc_type_3_1_3("cvc-type.3.1.3"), // https://wiki.xmldation.com/Support/Validator/cvc-type-3-1-3, cvc_attribute_3("cvc-attribute.3"), // https://wiki.xmldation.com/Support/Validator/cvc-attribute-3 cvc_enumeration_valid("cvc-enumeration-valid"), // https://wiki.xmldation.com/Support/Validator/cvc-enumeration-valid @@ -148,7 +150,8 @@ public static Range toLSPRange(XMLLocator location, XMLSchemaErrorCode code, Obj return XMLPositionUtility.selectAllAttributes(offset, document); case cvc_complex_type_2_1: case cvc_type_3_1_3: - return XMLPositionUtility.selectText(offset, document); + case cvc_elt_3_2_1: + return XMLPositionUtility.selectContent(offset, document); case cvc_enumeration_valid: case cvc_datatype_valid_1_2_1: case cvc_maxlength_valid: @@ -165,9 +168,11 @@ public static Range toLSPRange(XMLLocator location, XMLSchemaErrorCode code, Obj return range; } else { // Try with text - return XMLPositionUtility.selectText(offset, document); + return XMLPositionUtility.selectContent(offset, document); } } + case cvc_type_3_1_2: + return XMLPositionUtility.selectStartTag(offset, document); default: } return null; diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/XMLSyntaxErrorCode.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/XMLSyntaxErrorCode.java index c5805285c4..ccea5db4d4 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/XMLSyntaxErrorCode.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/participants/XMLSyntaxErrorCode.java @@ -127,7 +127,16 @@ public static Range toLSPRange(XMLLocator location, XMLSyntaxErrorCode code, Obj return XMLPositionUtility.selectAttributeValueByGivenValueAt(attrValue, offset, document); } case ETagUnterminated: - return XMLPositionUtility.selectPreviousEndTag(offset - 1, document); + /** + * Cases: + * + * + * + * + * + * This will include the tag it starts in if the offset is within a tag's content:

+ *

+ * {@code | } , will give {@code } + *

+ * + * or within an unclosed end tag: + * + *

+ * {@code } , will give {@code } + *

+ * + * + *

+ * {@code } , will give {@code } + *

* - * eg: - * | , will give 'b' - * , will give 'a' */ - public static Range selectPreviousEndTag(int offset, DOMDocument document) { + public static Range selectPreviousNodesEndTag(int offset, DOMDocument document) { + + DOMNode node = null; + DOMNode nodeAt = document.findNodeAt(offset); + if(nodeAt != null && nodeAt.isElement()) { + node = nodeAt; + } else { + DOMNode nodeBefore = document.findNodeBefore(offset); + if(nodeBefore != null && nodeBefore.isElement()) { + node = nodeBefore; + } + } + if(node != null) { + DOMElement element = (DOMElement) node; + if(element.isClosed() && element.getEndTagCloseOffset() == null) { + return selectEndTag(element.getEnd(), document); + } + } + // boolean firstBracket = false; int i = offset; char c = document.getText().charAt(i); @@ -337,18 +366,15 @@ public static Range createRange(int startOffset, int endOffset, DOMDocument docu } } - public static Range selectText(int offset, DOMDocument document) { + public static Range selectContent(int offset, DOMDocument document) { DOMNode node = document.findNodeAt(offset); if (node != null) { - if (node.hasChildNodes()) { - // BAD TEXT - for (DOMNode child : node.getChildren()) { - if (child.isText()) { - return createRange(child.getStart(), child.getEnd(), document); - } + if (node.isElement()) { + DOMElement element = (DOMElement) node; + if(node.hasChildNodes()) { + return createRange(element.getStartTagCloseOffset() + 1, element.getEndTagOpenOffset(), document); } - } else if (node.isElement()) { - // node has NONE text (ex: , select the start tag + // node has NO content (ex: , select the start tag return selectStartTag(node); } } diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/extensions/contentmodel/XMLSchemaDiagnosticsTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/extensions/contentmodel/XMLSchemaDiagnosticsTest.java index 151b5bf868..58f9045e3c 100644 --- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/extensions/contentmodel/XMLSchemaDiagnosticsTest.java +++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/extensions/contentmodel/XMLSchemaDiagnosticsTest.java @@ -19,7 +19,6 @@ import org.eclipse.lsp4xml.XMLAssert; import org.eclipse.lsp4xml.extensions.contentmodel.participants.XMLSchemaErrorCode; import org.eclipse.lsp4xml.extensions.contentmodel.settings.ContentModelSettings; -import org.junit.Ignore; import org.junit.Test; /** @@ -315,6 +314,43 @@ public void cvc_elt_3_1() throws Exception { } + @Test + public void cvc_type_3_2_1() throws Exception { + String xml = "\r\n" + // + "\r\n" + // + " 2017-11-30\r\n" + // <- error + " 0\r\n" + // + " \r\n" + // + " \r\n" + // + " \r\n" + // + " \r\n" + // + " \r\n" + // + " \r\n" + // + ""; + testDiagnosticsFor(xml, d(3, 23, 3, 33, XMLSchemaErrorCode.cvc_elt_3_2_1)); + } + + @Test + public void cvc_type_3_1_2() throws Exception { + String xml = "\r\n" + // + "\r\n" + // + " 2017-11-30\r\n" + // + " \r\n" + //<- error + " \r\n" + // + " \r\n" + // + " \r\n" + // + " \r\n" + // + " \r\n" + // + " \r\n" + // + ""; + testDiagnosticsFor(xml, + d(4, 3, 4, 9, XMLSchemaErrorCode.cvc_type_3_1_2), + d(4,10,4,17, XMLSchemaErrorCode.cvc_datatype_valid_1_2_1), + d(4,10,4,17, XMLSchemaErrorCode.cvc_type_3_1_3)); + } + private static void testDiagnosticsFor(String xml, Diagnostic... expected) { XMLAssert.testDiagnosticsFor(xml, "src/test/resources/catalogs/catalog.xml", expected); } diff --git a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/extensions/contentmodel/XMLSyntaxDiagnosticsTest.java b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/extensions/contentmodel/XMLSyntaxDiagnosticsTest.java index 69b1694ad5..5c457dbf6d 100644 --- a/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/extensions/contentmodel/XMLSyntaxDiagnosticsTest.java +++ b/org.eclipse.lsp4xml/src/test/java/org/eclipse/lsp4xml/extensions/contentmodel/XMLSyntaxDiagnosticsTest.java @@ -190,6 +190,25 @@ public void testETagUnterminated() throws Exception { testDiagnosticsFor(xml, d(0, 26, 0, 31, XMLSyntaxErrorCode.ETagUnterminated)); } + /** + * Test ETagUnterminated + * + * @see https://wiki.xmldation.com/Support/Validator/ETagUnterminated + * @throws Exception + */ + @Test + public void testETagUnterminated2() throws Exception { + String xml = + "\r\n" + // + " \r\n" + // + " \r\n" + // + " "; + testDiagnosticsFor(xml, d(3, 4, 3, 5, XMLSyntaxErrorCode.ETagUnterminated)); + } + + + @Test public void testIllegalQName() throws Exception { String xml = "100"; diff --git a/org.eclipse.lsp4xml/src/test/resources/xsd/invoice.xsd b/org.eclipse.lsp4xml/src/test/resources/xsd/invoice.xsd index 5340aef938..90c751070c 100644 --- a/org.eclipse.lsp4xml/src/test/resources/xsd/invoice.xsd +++ b/org.eclipse.lsp4xml/src/test/resources/xsd/invoice.xsd @@ -8,7 +8,7 @@ An invoice type... - +