From 410ce227d8a59e9f22548b4edd08bd10e3cd8d22 Mon Sep 17 00:00:00 2001 From: azerr Date: Wed, 5 Oct 2022 16:41:05 +0200 Subject: [PATCH] Report only XML syntax error for *.exsd files Signed-off-by: azerr --- .../settings/XMLValidationRootSettings.java | 5 +- .../xsd/participants/XSDErrorCode.java | 44 +++++---- .../XSDDiagnosticsParticipant.java | 30 +++++- .../contentmodel/XMLValidationFilterTest.java | 99 +++++++++++++++---- 4 files changed, 135 insertions(+), 43 deletions(-) diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/settings/XMLValidationRootSettings.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/settings/XMLValidationRootSettings.java index be43b206a..a48d66ef9 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/settings/XMLValidationRootSettings.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/contentmodel/settings/XMLValidationRootSettings.java @@ -118,7 +118,10 @@ private static XMLValidationFilter[] createDefaultFilters() { List filters = new ArrayList<>(); // Ignore validation for Eclipse '*.exsd' files XMLValidationFilter filter = new XMLValidationFilter(); - filter.setEnabled(false); + filter.setNoGrammar("ignore"); + XMLSchemaSettings schema = new XMLSchemaSettings(); + schema.setEnabled(SchemaEnabled.never); + filter.setSchema(schema); filter.setPattern("**.exsd"); filters.add(filter); // Don't warn that XML file have no grammar for Eclipse '.project', diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/participants/XSDErrorCode.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/participants/XSDErrorCode.java index 4496b1373..eb62f6e11 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/participants/XSDErrorCode.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/participants/XSDErrorCode.java @@ -34,34 +34,36 @@ * * @see https://wiki.xmldation.com/Support/Validator * - * All error code types and messages can be found in the Xerces library - * https://github.com/apache/xerces2-j/blob/trunk/src/org/apache/xerces/impl/msg/XMLSchemaMessages.properties + * All error code types and messages can be found in the Xerces library + * https://github.com/apache/xerces2-j/blob/trunk/src/org/apache/xerces/impl/msg/XMLSchemaMessages.properties * */ public enum XSDErrorCode implements IXMLErrorCode { - cos_all_limited_2("cos-all-limited.2"), - ct_props_correct_3("ct-props-correct.3"), - p_props_correct_2_1("p-props-correct.2.1"), + cos_all_limited_2("cos-all-limited.2"), // + ct_props_correct_3("ct-props-correct.3"), // + p_props_correct_2_1("p-props-correct.2.1"), // s4s_elt_invalid_content_1("s4s-elt-invalid-content.1"), // s4s_elt_must_match_1("s4s-elt-must-match.1"), // - s4s_elt_must_match_2("s4s-elt-must-match.2"), + s4s_elt_must_match_2("s4s-elt-must-match.2"), // s4s_att_must_appear("s4s-att-must-appear"), // s4s_elt_invalid_content_2("s4s-elt-invalid-content.2"), // s4s_att_not_allowed("s4s-att-not-allowed"), // s4s_att_invalid_value("s4s-att-invalid-value"), // s4s_elt_character("s4s-elt-character"), // s4s_elt_invalid_content_3("s4s-elt-invalid-content.3"), // - sch_props_correct_2("sch-props-correct.2"), + sch_props_correct_2("sch-props-correct.2"), // schema_reference_4("schema_reference.4"), // - src_ct_1("src-ct.1"), - src_import_1_2("src-import.1.2"), - src_element_3("src-element.3"), + src_ct_1("src-ct.1"), // + src_import_1_2("src-import.1.2"), // + src_element_3("src-element.3"), // src_resolve_4_2("src-resolve.4.2"), // - src_resolve("src-resolve"), src_element_2_1("src-element.2.1"), - EmptyTargetNamespace("EmptyTargetNamespace"), - src_import_3_1("src-import.3.1"), - src_import_3_2("src-import.3.2"); + src_resolve("src-resolve"), // + src_element_2_1("src-element.2.1"), // + EmptyTargetNamespace("EmptyTargetNamespace"), // + src_import_3_1("src-import.3.1"), // + src_import_3_2("src-import.3.2"), // + src_annotation("src-annotation"); private final String code; @@ -166,20 +168,24 @@ public static Range toLSPRange(XMLLocator location, XSDErrorCode code, Object[] case schema_reference_4: { return XMLPositionUtility.selectAttributeValueAt(XSDUtils.SCHEMA_LOCATION_ATTR, offset, true, document); } - case EmptyTargetNamespace : + case EmptyTargetNamespace: return XMLPositionUtility.selectAttributeValueAt(XSDUtils.TARGET_NAMESPACE_ATTR, offset, document); case src_import_3_1: { - // If the imported file of `schemaLocation` contains at least a doctype and 'xs:schema' with at least one `xs:element`, - // then the `xs:import` line will be highlighted, otherwise the `xs:schema` line will be highlighted + // If the imported file of `schemaLocation` contains at least a doctype and + // 'xs:schema' with at least one `xs:element`, + // then the `xs:import` line will be highlighted, otherwise the `xs:schema` line + // will be highlighted DOMNode elementHighlighted = document.findNodeAt(offset); if (elementHighlighted.getNodeName().equals(XSDUtils.XS_SCHEMA_TAG)) { // `xs:schema` line is highlighted - return XMLPositionUtility.selectChildNodeAttributeValueFromGivenNameAt(XSDUtils.XS_IMPORT_TAG, XSDUtils.NAMESPACE_ATTR, offset, document); + return XMLPositionUtility.selectChildNodeAttributeValueFromGivenNameAt(XSDUtils.XS_IMPORT_TAG, + XSDUtils.NAMESPACE_ATTR, offset, document); } else { // `xs:import` line is highlighted return XMLPositionUtility.selectAttributeValueAt(XSDUtils.NAMESPACE_ATTR, offset, document); } } case src_import_3_2: - return XMLPositionUtility.selectChildNodeAttributeValueFromGivenNameAt(XSDUtils.XS_IMPORT_TAG, XSDUtils.SCHEMA_LOCATION_ATTR, offset, document); + return XMLPositionUtility.selectChildNodeAttributeValueFromGivenNameAt(XSDUtils.XS_IMPORT_TAG, + XSDUtils.SCHEMA_LOCATION_ATTR, offset, document); } return null; diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/participants/diagnostics/XSDDiagnosticsParticipant.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/participants/diagnostics/XSDDiagnosticsParticipant.java index b18af46dc..7c7b63709 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/participants/diagnostics/XSDDiagnosticsParticipant.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/participants/diagnostics/XSDDiagnosticsParticipant.java @@ -16,6 +16,10 @@ import org.apache.xerces.xni.parser.XMLEntityResolver; import org.eclipse.lemminx.dom.DOMDocument; +import org.eclipse.lemminx.extensions.contentmodel.model.ContentModelManager; +import org.eclipse.lemminx.extensions.contentmodel.participants.diagnostics.XMLValidator; +import org.eclipse.lemminx.extensions.contentmodel.settings.SchemaEnabled; +import org.eclipse.lemminx.extensions.contentmodel.settings.XMLSchemaSettings; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationSettings; import org.eclipse.lemminx.extensions.xerces.LSPXMLEntityResolver; import org.eclipse.lemminx.extensions.xsd.XSDPlugin; @@ -39,20 +43,40 @@ public XSDDiagnosticsParticipant(XSDPlugin xsdPlugin) { @Override public void doDiagnostics(DOMDocument xmlDocument, List diagnostics, - XMLValidationSettings validationSettings, CancelChecker cancelChecker) { + XMLValidationSettings validationSettings, CancelChecker monitor) { if (!DOMUtils.isXSD(xmlDocument)) { // Don't use the XSD validator, if the XML document is not a XML Schema. return; } + // Get entity resolver (XML catalog resolver, XML schema from the file // associations settings., ...) XMLEntityResolver entityResolver = xmlDocument.getResolverExtensionManager(); LSPXMLEntityResolver entityResolverWrapper = new LSPXMLEntityResolver(entityResolver, (DiagnosticsResult) diagnostics); + ContentModelManager contentModelManager = xsdPlugin.getContentModelManager(); + if (!isSchemaEnabled(validationSettings)) { + // Validate only XML syntax for XSD + // Process validation + XMLValidator.doDiagnostics(xmlDocument, entityResolverWrapper, diagnostics, validationSettings, + contentModelManager, monitor); + return; + } - // Process validation + // Process XSD validation XSDValidator.doDiagnostics(xmlDocument, entityResolverWrapper, diagnostics, validationSettings, - xsdPlugin.getContentModelManager(), cancelChecker); + xsdPlugin.getContentModelManager(), monitor); + } + + private static boolean isSchemaEnabled(XMLValidationSettings validationSettings) { + if (validationSettings == null) { + return true; + } + XMLSchemaSettings schemaSettings = validationSettings.getSchema(); + if (schemaSettings == null) { + return true; + } + return !SchemaEnabled.never.equals(schemaSettings.getEnabled()); } } diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLValidationFilterTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLValidationFilterTest.java index 33b51364d..7570a6d74 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLValidationFilterTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLValidationFilterTest.java @@ -20,8 +20,11 @@ import org.eclipse.lemminx.AbstractCacheBasedTest; import org.eclipse.lemminx.XMLAssert; import org.eclipse.lemminx.extensions.contentmodel.participants.XMLSyntaxErrorCode; +import org.eclipse.lemminx.extensions.contentmodel.settings.SchemaEnabled; +import org.eclipse.lemminx.extensions.contentmodel.settings.XMLSchemaSettings; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationFilter; import org.eclipse.lemminx.extensions.contentmodel.settings.XMLValidationRootSettings; +import org.eclipse.lemminx.extensions.xsd.participants.XSDErrorCode; import org.eclipse.lemminx.services.XMLLanguageService; import org.eclipse.lsp4j.Diagnostic; import org.eclipse.lsp4j.DiagnosticSeverity; @@ -58,26 +61,6 @@ public void disableValidationFilter() throws Exception { XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI)); } - @Test - public void defaultDisableValidationFilter() throws Exception { - - String xml = "\r\n" + // + " \r\n" + // + " \r\n" + // <-- XSD error here, it should be appinfo + " \r\n" + // + " \r\n" + // + ""; + + XMLValidationRootSettings validation = new XMLValidationRootSettings(); + XMLValidationFilter filter = new XMLValidationFilter(); + filter.setEnabled(true); + filter.setNoGrammar("ignore"); + XMLSchemaSettings schemaSettings = new XMLSchemaSettings(); + schemaSettings.setEnabled(SchemaEnabled.never); + filter.setSchema(schemaSettings); + filter.setPattern("**.myxsd"); + validation.setFilters(Arrays.asList(filter).toArray(new XMLValidationFilter[0])); + XMLLanguageService ls = new XMLLanguageService(); + + String fileURI = "file:///home/test.xsd"; + // test.xsd doesn't matches the validation filter + XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI, // + // XML schema error code + new Diagnostic(r(2, 15, 2, 15), + "src-annotation: elements can only contain and elements, but 'appInfo' was found.", + DiagnosticSeverity.Error, "xsd", XSDErrorCode.src_annotation.getCode()))); + + // test.exsd matches the validation filter + // XSD error should not reported + fileURI = "file:///home/test.myxsd"; + XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI)); + + // Only XML syntax error must be reported + xml = "\r\n" + // + " \r\n" + // <-- annotation is not closed + ""; + XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI, // + new Diagnostic(r(1, 5, 1, 15), + "The element type \"annotation\" must be terminated by the matching end-tag \"\".", + DiagnosticSeverity.Error, "xml", XMLSyntaxErrorCode.ETagRequired.getCode()))); + } + + @Test + public void defaultDisableXMLSchemaValidationFilter() throws Exception { + String xml = "\r\n" + // + " \r\n" + // + " \r\n" + // <-- XSD error here, it should be appinfo + " \r\n" + // + " \r\n" + // + ""; + XMLValidationRootSettings validation = new XMLValidationRootSettings(); + XMLLanguageService ls = new XMLLanguageService(); + + String fileURI = "file:///home/test.xsd"; + // test.xsd doesn't matches the validation filter + XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI, // + // XML schema error code + new Diagnostic(r(2, 15, 2, 15), + "src-annotation: elements can only contain and elements, but 'appInfo' was found.", + DiagnosticSeverity.Error, "xsd", XSDErrorCode.src_annotation.getCode()))); + + // test.exsd matches the validation filter + // XSD error should not reported for *.exsd files + fileURI = "file:///home/test.exsd"; + XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI)); + // Only XML syntax error must be reported for *.exsd files + xml = "\r\n" + // + " \r\n" + // <-- annotation is not closed + ""; + XMLAssert.testPublishDiagnosticsFor(xml, fileURI, validation, ls, pd(fileURI, // + new Diagnostic(r(1, 5, 1, 15), + "The element type \"annotation\" must be terminated by the matching end-tag \"\".", + DiagnosticSeverity.Error, "xml", XMLSyntaxErrorCode.ETagRequired.getCode()))); } }