From fffafd991d71cd021c05df485974b4e7ff07e611 Mon Sep 17 00:00:00 2001 From: azerr Date: Tue, 26 Jul 2022 18:52:49 +0200 Subject: [PATCH] Autocompletion of attribute values won't display documentation Fixes https://github.com/redhat-developer/vscode-xml/issues/736 Signed-off-by: azerr --- .../xsd/contentmodel/XSDAnnotationModel.java | 92 ++++++++++--------- .../XMLSchemaCompletionExtensionsTest.java | 20 ++++ .../XMLSchemaHoverExtensionsTest.java | 28 ++++++ .../src/test/resources/xsd/attr-enum.xsd | 25 +++++ 4 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 org.eclipse.lemminx/src/test/resources/xsd/attr-enum.xsd diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/contentmodel/XSDAnnotationModel.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/contentmodel/XSDAnnotationModel.java index d01091820..f29b51c21 100644 --- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/contentmodel/XSDAnnotationModel.java +++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/extensions/xsd/contentmodel/XSDAnnotationModel.java @@ -95,17 +95,19 @@ public static List getDocumentation(XSObjectList annotations, String val List result = new ArrayList<>(); for (Object object : annotations) { XSAnnotation annotation = getXSAnnotation((XSObject) object, value); - XSDAnnotationModel annotationModel = XSDAnnotationModel.load(annotation); - if (annotationModel != null) { - List documentation = annotationModel.getDocumentation(); - if (documentation.size() > 0) { - result.addAll(documentation); - } else { - String annotationString = annotation.getAnnotationString(); - if (!isEmpty(annotationString)) { - String docFromPattern = getDocumentation(annotationString); - if (!isEmpty(docFromPattern)) { - result.add(docFromPattern); + if (annotation != null) { + XSDAnnotationModel annotationModel = XSDAnnotationModel.load(annotation); + if (annotationModel != null) { + List documentation = annotationModel.getDocumentation(); + if (documentation.size() > 0) { + result.addAll(documentation); + } else { + String annotationString = annotation.getAnnotationString(); + if (!isEmpty(annotationString)) { + String docFromPattern = getDocumentation(annotationString); + if (!isEmpty(docFromPattern)) { + result.add(docFromPattern); + } } } } @@ -138,9 +140,11 @@ public static List getAppInfo(XSObjectList annotations, String value) { List appinfo = new ArrayList<>(); for (Object object : annotations) { XSAnnotation annotation = getXSAnnotation((XSObject) object, value); - XSDAnnotationModel annotationModel = XSDAnnotationModel.load(annotation); - if (annotationModel != null) { - appinfo.addAll(annotationModel.getAppInfo()); + if (annotation != null) { + XSDAnnotationModel annotationModel = XSDAnnotationModel.load(annotation); + if (annotationModel != null) { + appinfo.addAll(annotationModel.getAppInfo()); + } } } return appinfo; @@ -159,8 +163,8 @@ public static String getPrefix(XSObjectList annotations) { /** * Returns the prefix (ie. xs) from the provided collection of annotations * - * Prerequisite: value should be provided if annotations - * is a collection of attribute value annotations + * Prerequisite: value should be provided if + * annotations is a collection of attribute value annotations * * @param annotations the collection of annotations * @param value the attribute value @@ -172,16 +176,17 @@ public static String getPrefix(XSObjectList annotations, String value) { } for (Object object : annotations) { XSAnnotation annotation = getXSAnnotation((XSObject) object, value); - String content = annotation.getAnnotationString(); - int index = content.indexOf(":"); - if (index != -1) { - return content.substring(1, index); + if (annotation != null) { + String content = annotation.getAnnotationString(); + int index = content.indexOf(":"); + if (index != -1) { + return content.substring(1, index); + } } } return ""; } - public static XSDAnnotationModel load(XSAnnotation annotation) { try { SAXParserFactory factory = DOMUtils.newSAXParserFactory(); @@ -193,39 +198,39 @@ public static XSDAnnotationModel load(XSAnnotation annotation) { return null; } } - + /** - * Returns the XSAnnotation instance for the - * provided annotation + * Returns the XSAnnotation instance for the provided + * annotation * - * If value is provided, the XSAnnotation for - * an attribute value will be searched for + * If value is provided, the XSAnnotation for an + * attribute value will be searched for * - * If not provided, the XSAnnotation for - * an attribute or element will be searched for + * If not provided, the XSAnnotation for an attribute or element + * will be searched for * - * @param annotation the annotation object + * @param annotation the annotation object * @param value the attribute value - * @return the XSAnnotation instance for the - * provided annotation + * @return the XSAnnotation instance for the provided + * annotation */ private static XSAnnotation getXSAnnotation(XSObject annotation, String value) { if (annotation instanceof XSMultiValueFacet && value != null) { XSMultiValueFacet multiValueFacet = (XSMultiValueFacet) annotation; - ObjectList enumerationValues = multiValueFacet.getEnumerationValues(); - XSObjectList annotationValues = multiValueFacet.getAnnotations(); - for (int i = 0; i < enumerationValues.getLength(); i++) { - Object enumValue = enumerationValues.get(i); + ObjectList enumerationValues = multiValueFacet.getEnumerationValues(); + XSObjectList annotationValues = multiValueFacet.getAnnotations(); + for (int i = 0; i < enumerationValues.getLength(); i++) { + Object enumValue = enumerationValues.get(i); - // Assuming always ValidatedInfo - String enumString = ((ValidatedInfo) enumValue).stringValue(); + // Assuming always ValidatedInfo + String enumString = ((ValidatedInfo) enumValue).stringValue(); - if (value.equals(enumString)) { - return (XSAnnotation) annotationValues.get(i); - } + if (value.equals(enumString)) { + return (XSAnnotation) annotationValues.get(i); } + } } else if (annotation instanceof XSAnnotation) { - return (XSAnnotation) annotation; + return (XSAnnotation) annotation; } return null; } @@ -247,7 +252,8 @@ public XSDAnnotationModel getModel() { } @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { super.startElement(uri, localName, qName, attributes); if (qName.endsWith(DOCUMENTATION_ELEMENT) || qName.endsWith(APPINFO_ELEMENT)) { current = new StringBuilder(); @@ -285,7 +291,7 @@ private static void addIfNonEmptyString(List list, String str) { public static String getDocumentation(String xml) { Matcher m = DOCUMENTATION_CONTENT.matcher(xml); - if(m.find()) { + if (m.find()) { return m.group(1); } return null; diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaCompletionExtensionsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaCompletionExtensionsTest.java index 14cd3cb17..53ac5e99b 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaCompletionExtensionsTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaCompletionExtensionsTest.java @@ -1492,4 +1492,24 @@ public void completionWithCatalogAndWebApp() throws BadLocationException { 31, // c("servlet", te(4, 4, 4, 4, ""), "servlet", null, null)); } + + @Test + public void completionWithAttrEnum() throws BadLocationException { + String xml = ""; + XMLAssert.testCompletionFor(xml, null, "src/test/resources/attr-enum.xml", 2, // + c("value1", te(2, 17, 2, 17, "value1"), "value1", // + "Documentation for attribute value1" + // + System.lineSeparator() + // + System.lineSeparator() + // + "Source: attr-enum.xsd", + MarkupKind.PLAINTEXT), // + c("value2", te(2, 17, 2, 17, "value2"), "value2", // + "Documentation for attribute" + // + System.lineSeparator() + // + System.lineSeparator() + // + "Source: attr-enum.xsd", + MarkupKind.PLAINTEXT)); + } } \ No newline at end of file diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaHoverExtensionsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaHoverExtensionsTest.java index 032d211ff..aa2a2e132 100644 --- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaHoverExtensionsTest.java +++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/extensions/contentmodel/XMLSchemaHoverExtensionsTest.java @@ -315,6 +315,34 @@ public void hoverTextWithUnion3() throws BadLocationException, MalformedURIExcep r(2, 52, 3, 9)); } + @Test + public void attrValueEnumWithDoc() throws BadLocationException, MalformedURIException { + String schemaURI = getXMLSchemaFileURI("attr-enum.xsd"); + String xml = ""; + XMLAssert.assertHover(new XMLLanguageService(), xml, null, "src/test/resources/attr-enum.xml", // + "Documentation for attribute value1" + // + System.lineSeparator() + // + System.lineSeparator() + // + "Source: [attr-enum.xsd](" + schemaURI + ")", + r(2, 16, 2, 24)); + } + + @Test + public void attrValueEnumWithNoDoc() throws BadLocationException, MalformedURIException { + String schemaURI = getXMLSchemaFileURI("attr-enum.xsd"); + String xml = ""; + XMLAssert.assertHover(new XMLLanguageService(), xml, null, "src/test/resources/attr-enum.xml", // + "Documentation for attribute" + // + System.lineSeparator() + // + System.lineSeparator() + // + "Source: [attr-enum.xsd](" + schemaURI + ")", + r(2, 16, 2, 24)); + } + @Test public void hoverWithNullParentNode() throws Exception { ContentModelHoverParticipant hoverParticipant = new ContentModelHoverParticipant(); diff --git a/org.eclipse.lemminx/src/test/resources/xsd/attr-enum.xsd b/org.eclipse.lemminx/src/test/resources/xsd/attr-enum.xsd new file mode 100644 index 000000000..68877f35c --- /dev/null +++ b/org.eclipse.lemminx/src/test/resources/xsd/attr-enum.xsd @@ -0,0 +1,25 @@ + + + + + Documentation for root element + + + + + Documentation for attribute + + + + + + Documentation for attribute value1 + + + + + + + + + \ No newline at end of file