From 728f6e0018908205761d9f09d784a048cd86032c Mon Sep 17 00:00:00 2001 From: angelozerr Date: Fri, 19 Oct 2018 12:35:28 +0200 Subject: [PATCH] Support XML Schema substitutionGroup for completion to fix #165 --- .../contentmodel/xsd/XSDDocument.java | 44 ++++++++++++++++--- .../xsd/XSDElementDeclaration.java | 7 +-- .../xsl/XSLCompletionExtensionsTest.java | 5 ++- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/xsd/XSDDocument.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/xsd/XSDDocument.java index a1d1f5c2d..dc3050189 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/xsd/XSDDocument.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/xsd/XSDDocument.java @@ -23,6 +23,8 @@ import org.apache.xerces.xs.XSElementDeclaration; import org.apache.xerces.xs.XSModel; import org.apache.xerces.xs.XSNamedMap; +import org.apache.xerces.xs.XSObject; +import org.apache.xerces.xs.XSObjectList; import org.apache.xerces.xs.XSSimpleTypeDefinition; import org.eclipse.lsp4xml.dom.Element; import org.eclipse.lsp4xml.extensions.contentmodel.model.CMDocument; @@ -47,21 +49,49 @@ public XSDDocument(XSModel model) { @Override public Collection getElements() { + elements = null; if (elements == null) { elements = new ArrayList<>(); XSNamedMap map = model.getComponents(XSConstants.ELEMENT_DECLARATION); for (int j = 0; j < map.getLength(); j++) { XSElementDeclaration elementDeclaration = (XSElementDeclaration) map.item(j); - CMElementDeclaration cmElement = getXSDElement(elementDeclaration); - // check element declaration is not already added (ex: xs:annotation) - if (!elements.contains(cmElement)) { - elements.add(cmElement); - } + collectElement(elementDeclaration, elements); } } return elements; } + /** + * Fill the given elements list from the given Xerces elementDeclaration + * + * @param elementDeclaration + * @param elements + */ + void collectElement(XSElementDeclaration elementDeclaration, Collection elements) { + if (elementDeclaration.getAbstract()) { + // element declaration is marked as abstract + // ex with xsl: + XSObjectList list = model.getSubstitutionGroup(elementDeclaration); + if (list != null) { + // it exists elements list bind with this abstract declaration with substitutionGroup + // ex xsl : + for (int i = 0; i < list.getLength(); i++) { + XSObject object = list.item(i); + if (object.getType() == XSConstants.ELEMENT_DECLARATION) { + XSElementDeclaration subElementDeclaration = (XSElementDeclaration) object; + collectElement(subElementDeclaration, elements); + } + } + } + } else { + CMElementDeclaration cmElement = getXSDElement(elementDeclaration); + // check element declaration is not already added (ex: xs:annotation) + if (!elements.contains(cmElement)) { + elements.add(cmElement); + } + } + } + @Override public CMElementDeclaration findCMElement(Element node, String namespace) { List paths = new ArrayList<>(); @@ -102,7 +132,7 @@ CMElementDeclaration getXSDElement(XSElementDeclaration elementDeclaration) { } return element; } - + static Collection getEnumerationValues(XSSimpleTypeDefinition typeDefinition) { if (typeDefinition != null) { if (isBooleanType(typeDefinition)) { @@ -118,7 +148,7 @@ static Collection getEnumerationValues(XSSimpleTypeDefinition typeDefini } return Collections.emptyList(); } - + static boolean isBooleanType(XSSimpleTypeDefinition typeDefinition) { if (typeDefinition instanceof XSSimpleType) { return ((XSSimpleType) typeDefinition).getPrimitiveKind() == XSSimpleType.PRIMITIVE_BOOLEAN; diff --git a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/xsd/XSDElementDeclaration.java b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/xsd/XSDElementDeclaration.java index d283e1685..18936927d 100644 --- a/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/xsd/XSDElementDeclaration.java +++ b/org.eclipse.lsp4xml/src/main/java/org/eclipse/lsp4xml/extensions/contentmodel/xsd/XSDElementDeclaration.java @@ -118,6 +118,7 @@ private void collectAttributesDeclaration(XSComplexTypeDefinition typeDefinition @Override public Collection getElements() { + elements = null; if (elements == null) { elements = new ArrayList<>(); collectElementsDeclaration(elementDeclaration, elements); @@ -158,11 +159,7 @@ private void collectElementsDeclaration(XSTerm term, Collection\r\n" + // "|"; testCompletionFor(xml, - c("xsl:declaration", te(2, 0, 2, 0, ""), "xsl:declaration"), // - c("xsl:import", te(2, 0, 2, 0, ""), "xsl:import")); + c("xsl:template", te(2, 0, 2, 0, ""), "xsl:template"), // <-- coming from substition group of xsl:declaration + c("xsl:output", te(2, 0, 2, 0, ""), "xsl:output"), // <-- coming from substition group of xsl:declaration + c("xsl:import", te(2, 0, 2, 0, ""), "xsl:import")); // coming from stylesheet children } private void testCompletionFor(String xml, CompletionItem... expectedItems) throws BadLocationException {