Skip to content

Commit

Permalink
No completion on attributes with xs:union (XSD)
Browse files Browse the repository at this point in the history
  • Loading branch information
angelozerr authored and datho7561 committed Nov 4, 2020
1 parent 744d724 commit c9c0a42
Show file tree
Hide file tree
Showing 13 changed files with 444 additions and 139 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public interface CMAttributeDeclaration {
* @return formatted documentation of the declared
* attribute according to settings defined in <code>request</code>
*/
String getDocumentation(ISharedSettingsRequest request);
String getAttributeNameDocumentation(ISharedSettingsRequest request);

/**
* Returns formatted documentation about <code>value</code>,
Expand All @@ -52,7 +52,7 @@ public interface CMAttributeDeclaration {
* @return formatted documentation about <code>value</code>,
* according to settings defined in <code>request</code>
*/
String getValueDocumentation(String value, ISharedSettingsRequest request);
String getAttributeValueDocumentation(String value, ISharedSettingsRequest request);

/**
* Returns true if the attribute is required and false otherwise.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,12 +100,12 @@ default String getName(String prefix) {
CMAttributeDeclaration findCMAttribute(String attributeName);

/**
* Returns formatted documentation of the declared element,
* according to settings defined in <code>request</code>.
* Returns formatted documentation of the declared element, according to
* settings defined in <code>request</code>.
*
* @param request the request containing settings
* @return formatted documentation of the declared element,
* according to settings defined in <code>request</code>.
* @return formatted documentation of the declared element, according to
* settings defined in <code>request</code>.
*/
String getDocumentation(ISharedSettingsRequest request);

Expand All @@ -128,10 +128,12 @@ default String getName(String prefix) {
/**
* Returns the documentation for the given enumeration value and null otherwise.
*
* @param value the enumeration value.
* @param value the enumeration value.
* @param request the shared settings.
*
* @return the documentation for the given enumeration value and null otherwise.
*/
String getValueDocumentation(String value);
String getTextDocumentation(String value, ISharedSettingsRequest request);

/**
* Returns the owner document URI where the element is declared.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ public void onXMLContent(ICompletionRequest request, ICompletionResponse respons
values.forEach(value -> {
CompletionItem item = new CompletionItem();
item.setLabel(value);
String insertText = value; // request.getInsertAttrValue(value);
String insertText = value;
item.setLabel(value);
item.setKind(CompletionItemKind.Value);
item.setFilterText(tokenStart + insertText);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.eclipse.lemminx.dom.DOMAttr;
import org.eclipse.lemminx.dom.DOMElement;
import org.eclipse.lemminx.dom.DOMText;
import org.eclipse.lemminx.extensions.contentmodel.model.CMAttributeDeclaration;
import org.eclipse.lemminx.extensions.contentmodel.model.CMDocument;
import org.eclipse.lemminx.extensions.contentmodel.model.CMElementDeclaration;
Expand Down Expand Up @@ -138,6 +139,36 @@ public Hover onAttributeValue(IHoverRequest hoverRequest) throws Exception {
}
}

@Override
public Hover onText(IHoverRequest hoverRequest) throws Exception {
DOMText text = (DOMText) hoverRequest.getNode();
DOMElement element = text.getParentElement();
try {
ContentModelManager contentModelManager = hoverRequest.getComponent(ContentModelManager.class);
Collection<CMDocument> cmDocuments = contentModelManager.findCMDocument(element);
if (cmDocuments.isEmpty()) {
// no bound grammar -> no documentation
return null;
}
String textContent = text.getTextContent();
if (textContent != null) {
textContent = textContent.trim();
}
// Compute attribute name declaration documentation from bound grammars
List<MarkupContent> contentValues = new ArrayList<>();
for (CMDocument cmDocument : cmDocuments) {
CMElementDeclaration cmElement = cmDocument.findCMElement(element);
if (cmElement != null) {
MarkupContent content = XMLGenerator.createMarkupContent(cmElement, textContent, hoverRequest);
fillHoverContent(content, contentValues);
}
}
return createHover(contentValues);
} catch (CacheResourceDownloadingException e) {
return getCacheWarningHover(e, hoverRequest);
}
}

private static Hover getCacheWarningHover(CacheResourceDownloadingException e, ISharedSettingsRequest support) {
// Here cache is enabled and some XML Schema, DTD, etc are loading
MarkupContent content = MarkupContentFactory.createMarkupContent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public static MarkupContent createMarkupContent(CMElementDeclaration cmElement,
*/
public static MarkupContent createMarkupContent(CMAttributeDeclaration cmAttribute,
CMElementDeclaration ownerElement, ISharedSettingsRequest request) {
String documentation = XMLGenerator.generateDocumentation(cmAttribute.getDocumentation(request),
String documentation = XMLGenerator.generateDocumentation(cmAttribute.getAttributeNameDocumentation(request),
ownerElement.getDocumentURI(), request.canSupportMarkupKind(MarkupKind.MARKDOWN));
if (documentation != null) {
return MarkupContentFactory.createMarkupContent(documentation, MarkupKind.MARKDOWN, request);
Expand All @@ -318,7 +318,7 @@ public static MarkupContent createMarkupContent(CMAttributeDeclaration cmAttribu
*/
public static MarkupContent createMarkupContent(CMAttributeDeclaration cmAttribute, String attributeValue,
CMElementDeclaration ownerElement, ISharedSettingsRequest support) {
String documentation = XMLGenerator.generateDocumentation(cmAttribute.getValueDocumentation(attributeValue, support),
String documentation = XMLGenerator.generateDocumentation(cmAttribute.getAttributeValueDocumentation(attributeValue, support),
ownerElement.getDocumentURI(), support.canSupportMarkupKind(MarkupKind.MARKDOWN));
if (documentation != null) {
return MarkupContentFactory.createMarkupContent(documentation, MarkupKind.MARKDOWN, support);
Expand All @@ -337,7 +337,7 @@ public static MarkupContent createMarkupContent(CMAttributeDeclaration cmAttribu
*/
public static MarkupContent createMarkupContent(CMElementDeclaration cmElement, String textContent,
ISharedSettingsRequest support) {
String documentation = XMLGenerator.generateDocumentation(cmElement.getValueDocumentation(textContent),
String documentation = XMLGenerator.generateDocumentation(cmElement.getTextDocumentation(textContent, support),
cmElement.getDocumentURI(), support.canSupportMarkupKind(MarkupKind.MARKDOWN));
if (documentation != null) {
return MarkupContentFactory.createMarkupContent(documentation, MarkupKind.MARKDOWN, support);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public Collection<String> getEnumerationValues() {
}

@Override
public String getDocumentation(ISharedSettingsRequest request) {
public String getAttributeNameDocumentation(ISharedSettingsRequest request) {
if (documentation != null) {
return documentation;
}
Expand All @@ -68,7 +68,7 @@ public boolean isRequired() {
}

@Override
public String getValueDocumentation(String value, ISharedSettingsRequest settings) {
public String getAttributeValueDocumentation(String value, ISharedSettingsRequest request) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public Collection<String> getEnumerationValues() {
}

@Override
public String getValueDocumentation(String textContent) {
public String getTextDocumentation(String value, ISharedSettingsRequest request) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,15 @@
import java.util.HashMap;
import java.util.Map;

import org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl;
import org.apache.xerces.impl.xs.XSComplexTypeDecl;
import org.apache.xerces.xs.XSAttributeDeclaration;
import org.apache.xerces.xs.XSAttributeUse;
import org.apache.xerces.xs.XSMultiValueFacet;
import org.apache.xerces.xs.XSObjectList;
import org.apache.xerces.xs.XSSimpleTypeDefinition;
import org.apache.xerces.xs.XSTypeDefinition;
import org.apache.xerces.xs.XSValue;
import org.eclipse.lemminx.extensions.contentmodel.model.CMAttributeDeclaration;
import org.eclipse.lemminx.services.extensions.ISharedSettingsRequest;
import org.eclipse.lemminx.settings.SchemaDocumentationType;
import org.eclipse.lemminx.utils.StringUtils;
import org.eclipse.lsp4j.MarkupKind;

/**
Expand All @@ -39,15 +36,14 @@ public class CMXSDAttributeDeclaration implements CMAttributeDeclaration {

private final XSAttributeUse attributeUse;

private final Map<String, String> valuesDocumentation;
private Map<String, String> valuesDocumentation;

private String attrDocumentation;

private SchemaDocumentationType docStrategy;

public CMXSDAttributeDeclaration(XSAttributeUse attributeUse) {
this.attributeUse = attributeUse;
this.valuesDocumentation = new HashMap<>();
}

@Override
Expand All @@ -67,136 +63,109 @@ public String getDefaultValue() {
}

@Override
public String getDocumentation(ISharedSettingsRequest request) {
SchemaDocumentationType currStrategy = request.getSharedSettings().getPreferences().getShowSchemaDocumentationType();
public String getAttributeNameDocumentation(ISharedSettingsRequest request) {
SchemaDocumentationType currStrategy = request.getSharedSettings().getPreferences()
.getShowSchemaDocumentationType();
if (this.docStrategy != currStrategy) {
clearDocumentation();
} else if (this.attrDocumentation != null) {
return this.attrDocumentation;
}
this.docStrategy = currStrategy;
// Try get xs:annotation from the element declaration or type
XSObjectList annotations = getAnnotations();
XSObjectList annotations = getAttributeNameAnnotations();
boolean markdownSupported = request.canSupportMarkupKind(MarkupKind.MARKDOWN);
this.attrDocumentation = new XSDDocumentation(annotations, docStrategy, !markdownSupported)
.getFormattedDocumentation(markdownSupported);
return this.attrDocumentation;
}

@Override
public String getValueDocumentation(String value, ISharedSettingsRequest request) {
SchemaDocumentationType currStrategy = request.getSharedSettings().getPreferences().getShowSchemaDocumentationType();
if (this.docStrategy != currStrategy) {
clearDocumentation();
}
String documentation = valuesDocumentation.get(value);
if (documentation != null) {
return documentation;
}
this.docStrategy = currStrategy;
// Try get xs:annotation from the element declaration or type
XSObjectList annotations = getValueAnnotations();
boolean markdownSupported = request.canSupportMarkupKind(MarkupKind.MARKDOWN);
documentation = new XSDDocumentation(annotations, value, docStrategy, !markdownSupported)
.getFormattedDocumentation(markdownSupported);
valuesDocumentation.put(value, documentation);
return documentation;
}

private void clearDocumentation() {
this.valuesDocumentation.clear();
this.attrDocumentation = null;
}

/**
* Returns list of xs:annotation from the element declaration or type
* Returns list of xs:annotation from the attribute declaration or type
* declaration.
*
* @return list of xs:annotation from the element declaration or type
* @return list of xs:annotation from the attribute declaration or type
* declaration.
*/
private XSObjectList getAnnotations() {
// Try get xs:annotation from the element declaration
private XSObjectList getAttributeNameAnnotations() {
// Try get xs:annotation from the attribute declaration
XSAttributeDeclaration attributeDeclaration = getAttrDeclaration();
XSObjectList annotation = attributeDeclaration.getAnnotations();

if (annotation != null && annotation.getLength() > 0) {
return annotation;
}
// Try get xs:annotation from the type of element declaration
XSTypeDefinition typeDefinition = attributeDeclaration.getTypeDefinition();
if (typeDefinition == null) {
return null;
// Try get xs:annotation from the type of attribute declaration
XSSimpleTypeDefinition typeDefinition = attributeDeclaration.getTypeDefinition();
return typeDefinition != null ? typeDefinition.getAnnotations() : null;
}

@Override
public String getAttributeValueDocumentation(String value, ISharedSettingsRequest request) {
SchemaDocumentationType currStrategy = request.getSharedSettings().getPreferences()
.getShowSchemaDocumentationType();
if (this.docStrategy != currStrategy) {
clearDocumentation();
}
if (typeDefinition.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
return ((XSComplexTypeDecl) typeDefinition).getAnnotations();
} else if (typeDefinition.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
return ((XSSimpleTypeDecl) typeDefinition).getAnnotations();
valuesDocumentation = null;
this.docStrategy = currStrategy;
if (valuesDocumentation == null) {
valuesDocumentation = createValuesDocumentation(request);
}
return null;
return valuesDocumentation.get(value);
}

private Map<String, String> createValuesDocumentation(ISharedSettingsRequest request) {
boolean markdownSupported = request.canSupportMarkupKind(MarkupKind.MARKDOWN);
Map<String, String> valuesDocumentation = new HashMap<>();
// loop for each enumeration values and update the values documentation map with
// documentation
getEnumerationValues().forEach(value -> {
String documentation = null;
XSObjectList annotations = getAttributeValueAnnotations(value);
if (annotations != null) {
documentation = new XSDDocumentation(annotations, value, docStrategy, !markdownSupported)
.getFormattedDocumentation(markdownSupported);
}
if (StringUtils.isBlank(documentation)) {
// The documentation is blank or not defined, try to get the documentation from
// the attribute
// name
documentation = getAttributeNameDocumentation(request);
}
valuesDocumentation.put(value, documentation);
});
return valuesDocumentation;
}

/**
* Returns list of xs:annotation from the element declaration or type
* Returns list of xs:annotation from the attribute declaration or type
* declaration.
*
* Indicated by:
* https://msdn.microsoft.com/en-us/library/ms256143(v=vs.110).aspx
* xs:attribute tags have content of either an xs:annotation or xs:simpleType
* https://msdn.microsoft.com/en-us/library/ms256143(v=vs.110).aspx xs:attribute
* tags have content of either an xs:annotation or xs:simpleType
*
* @return list of xs:annotation from the element declaration or type
* @param value
*
* @return list of xs:annotation from the attribute declaration or type
* declaration.
*/
private XSObjectList getValueAnnotations() {
// Try get xs:annotation from the element declaration
private XSObjectList getAttributeValueAnnotations(String value) {
// Try get xs:annotation from the xs:enumeration declaration
XSAttributeDeclaration attributeDeclaration = getAttrDeclaration();
XSSimpleTypeDefinition simpleTypeDefinition = attributeDeclaration.getTypeDefinition();
XSSimpleTypeDecl simpleTypeDecl;


XSObjectList annotation = null; // The XSD tag that holds the documentation tag

if(simpleTypeDefinition instanceof XSSimpleTypeDecl) {
simpleTypeDecl = (XSSimpleTypeDecl) simpleTypeDefinition;
XSObjectList multiFacets = simpleTypeDecl.getMultiValueFacets();
if(!multiFacets.isEmpty()) {
XSMultiValueFacet facet = (XSMultiValueFacet) multiFacets.get(0);
multiFacets = facet.getAnnotations();
Object[] annotationArray = multiFacets.toArray();
if(!onlyContainsNull(annotationArray)) { // if multiValueFacets has annotations
annotation = simpleTypeDecl.getMultiValueFacets();
}
}
}
if(annotation == null){ // There was no specific documentation for the value, so use the general attribute documentation
annotation = attributeDeclaration.getAnnotations();
}
XSObjectList annotation = CMXSDDocument.getEnumerationAnnotations(simpleTypeDefinition, value);
if (annotation != null && annotation.getLength() > 0) {
return annotation;
}
// Try get xs:annotation from the type of element declaration
XSTypeDefinition typeDefinition = attributeDeclaration.getTypeDefinition();
if (typeDefinition == null) {
return null;
}
if (typeDefinition.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
return ((XSComplexTypeDecl) typeDefinition).getAnnotations();
} else if (typeDefinition.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
return ((XSSimpleTypeDecl) typeDefinition).getAnnotations();
}
return null;
// There was no specific documentation for the value, so use the general
// attribute documentation
return getAttributeNameAnnotations();
}

private boolean onlyContainsNull(Object[] arr) {
if(arr == null || arr.length == 0) {
return true;
}
for (Object o : arr) {
if(o != null) {
return false;
}
}
return true;
private void clearDocumentation() {
this.valuesDocumentation = null;
this.attrDocumentation = null;
}

@Override
Expand Down
Loading

0 comments on commit c9c0a42

Please sign in to comment.